aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore12
-rwxr-xr-xderivation.nix2
-rw-r--r--dub.json36
-rw-r--r--flake.lock6
-rw-r--r--flake.nix8
-rw-r--r--makefile36
-rw-r--r--meson.build2
-rw-r--r--nix-overlays/dtools/disabled-tests.diff2
-rw-r--r--nix-overlays/dtools/fix-ldc-arm64.diff8
-rw-r--r--org/COPYRIGHT6
-rw-r--r--org/compile_time_info.org14
-rw-r--r--org/config_d_cfte.org10
-rw-r--r--org/config_dub.org44
-rw-r--r--org/config_env.org10
-rw-r--r--org/config_git.org22
-rw-r--r--org/config_make.org45
-rw-r--r--org/config_meson.org10
-rw-r--r--org/config_misc.org10
-rw-r--r--org/config_nix.org12
-rw-r--r--org/default_imports.org28
-rw-r--r--org/default_misc.org18
-rw-r--r--org/default_paths.org24
-rw-r--r--org/default_regex.org34
-rw-r--r--org/default_shared_snippets.org24
-rw-r--r--org/in_source_files.org54
-rw-r--r--org/in_zip_pod.org14
-rw-r--r--org/meta_conf_make_meta.org58
-rw-r--r--org/meta_debugs.org18
-rw-r--r--org/nix-develop-dlang-shared.org10
-rw-r--r--org/nixpkgs_overlays_d_related.org22
-rw-r--r--org/ocda.org99
-rw-r--r--org/ocda_functions.org15
-rw-r--r--org/ocda_obj_setter.org14
-rw-r--r--org/out_curate_metadata.org40
-rw-r--r--org/out_latex.org40
-rw-r--r--org/out_metadata.org20
-rw-r--r--org/out_odt.org37
-rw-r--r--org/out_skel.org18
-rw-r--r--org/out_sqlite.org48
-rw-r--r--org/out_src_abstraction_ocda_ssp.org (renamed from org/out_src_abstraction_peg_text.org)24
-rw-r--r--org/out_src_abstraction_sqlite_db.org16
-rw-r--r--org/out_src_pod.org81
-rw-r--r--org/out_text.org23
-rw-r--r--org/out_xmls.org56
-rw-r--r--org/out_xmls_css.org74
-rw-r--r--org/out_zip.org14
-rw-r--r--org/output_hub.org60
-rw-r--r--org/output_show.org30
-rw-r--r--org/sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org12
-rw-r--r--org/spine.org94
-rw-r--r--org/spine_info.org45
-rw-r--r--org/spine_markup_sample.org10
-rw-r--r--org/test_shell_script_ssp_document_abstraction.org18
-rw-r--r--org/util_editors.org976
-rw-r--r--org/util_spine_markup_conversion_from_sisu.org18
-rw-r--r--package.nix4
-rw-r--r--src/sisudoc/io_out/cgi_sqlite_search_form.d1959
-rw-r--r--src/sisudoc/ocda/abstraction/package.d86
-rw-r--r--src/sisudoc/ocda/abstraction/ssp.d (renamed from src/sisudoc/io_out/create_abstraction_txt.d)12
-rw-r--r--src/sisudoc/ocda/io_in/paths_source.d (renamed from src/sisudoc/io_in/paths_source.d)6
-rw-r--r--src/sisudoc/ocda/io_in/read_config_files.d (renamed from src/sisudoc/io_in/read_config_files.d)30
-rw-r--r--src/sisudoc/ocda/io_in/read_source_files.d (renamed from src/sisudoc/io_in/read_source_files.d)10
-rw-r--r--src/sisudoc/ocda/io_in/read_zip_pod.d (renamed from src/sisudoc/io_in/read_zip_pod.d)2
-rw-r--r--src/sisudoc/ocda/meta/conf_make_meta_json.d (renamed from src/sisudoc/meta/conf_make_meta_json.d)10
-rw-r--r--src/sisudoc/ocda/meta/conf_make_meta_structs.d (renamed from src/sisudoc/meta/conf_make_meta_structs.d)8
-rw-r--r--src/sisudoc/ocda/meta/conf_make_meta_yaml.d (renamed from src/sisudoc/meta/conf_make_meta_yaml.d)22
-rw-r--r--src/sisudoc/ocda/meta/defaults.d (renamed from src/sisudoc/meta/defaults.d)2
-rw-r--r--src/sisudoc/ocda/meta/doc_debugs.d (renamed from src/sisudoc/meta/doc_debugs.d)6
-rw-r--r--src/sisudoc/ocda/meta/metadoc.d (renamed from src/sisudoc/meta/metadoc.d)24
-rw-r--r--src/sisudoc/ocda/meta/metadoc_from_src.d (renamed from src/sisudoc/meta/metadoc_from_src.d)14
-rw-r--r--src/sisudoc/ocda/meta/metadoc_from_src_functions.d (renamed from src/sisudoc/meta/metadoc_from_src_functions.d)3
-rw-r--r--src/sisudoc/ocda/meta/metadoc_object_setter.d (renamed from src/sisudoc/meta/metadoc_object_setter.d)2
-rw-r--r--src/sisudoc/ocda/meta/metadoc_show_config.d (renamed from src/sisudoc/meta/metadoc_show_config.d)10
-rw-r--r--src/sisudoc/ocda/meta/metadoc_show_make.d (renamed from src/sisudoc/meta/metadoc_show_make.d)6
-rw-r--r--src/sisudoc/ocda/meta/metadoc_show_metadata.d (renamed from src/sisudoc/meta/metadoc_show_metadata.d)6
-rw-r--r--src/sisudoc/ocda/meta/metadoc_show_summary.d (renamed from src/sisudoc/meta/metadoc_show_summary.d)6
-rw-r--r--src/sisudoc/ocda/meta/package.d (renamed from src/sisudoc/meta/package.d)4
-rw-r--r--src/sisudoc/ocda/meta/rgx.d (renamed from src/sisudoc/meta/rgx.d)2
-rw-r--r--src/sisudoc/ocda/meta/rgx_files.d (renamed from src/sisudoc/meta/rgx_files.d)2
-rw-r--r--src/sisudoc/ocda/meta/rgx_yaml.d (renamed from src/sisudoc/meta/rgx_yaml.d)2
-rw-r--r--src/sisudoc/ocda/package.d68
-rw-r--r--src/sisudoc/outputs/conf/compile_time_info.d (renamed from src/sisudoc/conf/compile_time_info.d)2
-rw-r--r--src/sisudoc/outputs/io_out/create_abstraction_db.d (renamed from src/sisudoc/io_out/create_abstraction_db.d)4
-rw-r--r--src/sisudoc/outputs/io_out/create_zip_file.d (renamed from src/sisudoc/io_out/create_zip_file.d)2
-rw-r--r--src/sisudoc/outputs/io_out/curate/metadoc_curate.d (renamed from src/sisudoc/meta/metadoc_curate.d)8
-rw-r--r--src/sisudoc/outputs/io_out/curate/metadoc_curate_authors.d (renamed from src/sisudoc/meta/metadoc_curate_authors.d)8
-rw-r--r--src/sisudoc/outputs/io_out/curate/metadoc_curate_topics.d (renamed from src/sisudoc/meta/metadoc_curate_topics.d)8
-rw-r--r--src/sisudoc/outputs/io_out/defaults.d (renamed from src/sisudoc/io_out/defaults.d)2
-rw-r--r--src/sisudoc/outputs/io_out/epub3.d (renamed from src/sisudoc/io_out/epub3.d)16
-rw-r--r--src/sisudoc/outputs/io_out/html.d (renamed from src/sisudoc/io_out/html.d)22
-rw-r--r--src/sisudoc/outputs/io_out/html_snippet.d (renamed from src/sisudoc/io_out/html_snippet.d)8
-rw-r--r--src/sisudoc/outputs/io_out/hub.d (renamed from src/sisudoc/io_out/hub.d)58
-rw-r--r--src/sisudoc/outputs/io_out/latex.d (renamed from src/sisudoc/io_out/latex.d)24
-rw-r--r--src/sisudoc/outputs/io_out/metadata.d (renamed from src/sisudoc/io_out/metadata.d)8
-rw-r--r--src/sisudoc/outputs/io_out/odt.d (renamed from src/sisudoc/io_out/odt.d)37
-rw-r--r--src/sisudoc/outputs/io_out/package.d (renamed from src/sisudoc/io_out/package.d)10
-rw-r--r--src/sisudoc/outputs/io_out/paths_output.d (renamed from src/sisudoc/io_out/paths_output.d)4
-rw-r--r--src/sisudoc/outputs/io_out/rgx.d (renamed from src/sisudoc/io_out/rgx.d)2
-rw-r--r--src/sisudoc/outputs/io_out/rgx_latex.d (renamed from src/sisudoc/io_out/rgx_latex.d)2
-rw-r--r--src/sisudoc/outputs/io_out/rgx_xhtml.d (renamed from src/sisudoc/io_out/rgx_xhtml.d)2
-rw-r--r--src/sisudoc/outputs/io_out/skel.d (renamed from src/sisudoc/io_out/skel.d)6
-rw-r--r--src/sisudoc/outputs/io_out/source_pod.d (renamed from src/sisudoc/io_out/source_pod.d)69
-rw-r--r--src/sisudoc/outputs/io_out/sqlite.d (renamed from src/sisudoc/io_out/sqlite.d)36
-rw-r--r--src/sisudoc/outputs/io_out/text.d (renamed from src/sisudoc/io_out/text.d)10
-rw-r--r--src/sisudoc/outputs/io_out/xmls.d (renamed from src/sisudoc/io_out/xmls.d)16
-rw-r--r--src/sisudoc/outputs/io_out/xmls_css.d (renamed from src/sisudoc/io_out/xmls_css.d)202
-rw-r--r--src/sisudoc/outputs/share/defaults.d (renamed from src/sisudoc/share/defaults.d)2
-rw-r--r--[-rwxr-xr-x]src/sisudoc/spine.d70
-rw-r--r--sundry/editor-syntax-etc/emacs/sisu-spine-mode-autoloads.el24
-rw-r--r--sundry/editor-syntax-etc/emacs/sisu-spine-ts-mode.el296
-rw-r--r--sundry/editor-syntax-etc/nvim/README.md87
-rw-r--r--sundry/editor-syntax-etc/nvim/ftdetect/sisu.lua7
-rw-r--r--sundry/editor-syntax-etc/nvim/ftplugin/sisu.lua13
-rw-r--r--sundry/editor-syntax-etc/nvim/lua/sisu-spine/init.lua43
-rw-r--r--sundry/editor-syntax-etc/nvim/queries/sisu/folds.scm23
-rw-r--r--sundry/editor-syntax-etc/nvim/queries/sisu/highlights.scm189
-rw-r--r--sundry/editor-syntax-etc/nvim/queries/sisu/indents.scm48
-rw-r--r--sundry/editor-syntax-etc/nvim/queries/sisu/injections.scm16
-rw-r--r--sundry/editor-syntax-etc/nvim/queries/sisu/textobjects.scm140
-rw-r--r--sundry/editor-syntax-etc/vim/syntax/sisu-spine.vim14
-rw-r--r--sundry/editor-syntax-etc/vim/templates/ssi.tpl30
-rw-r--r--sundry/editor-syntax-etc/vim/templates/ssm.tpl30
-rw-r--r--sundry/editor-syntax-etc/vim/templates/sst.tpl30
-rw-r--r--test/reference/abstraction/not_without_help.austin_amissah.en.ssp4
-rw-r--r--test/reference/abstraction/the_autonomous_contract.ralph_amissah.en.ssp4
-rwxr-xr-xtest/test-abstraction-ssp.sh7
-rw-r--r--views/version.txt2
127 files changed, 3506 insertions, 2926 deletions
diff --git a/.gitignore b/.gitignore
index cbdcd6b..85cdddc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -76,6 +76,18 @@
!sundry/editor-syntax-etc/vim/ftplugin/*.vim
!sundry/editor-syntax-etc/vim/syntax
!sundry/editor-syntax-etc/vim/syntax/*.vim
+!sundry/editor-syntax-etc/vim/templates
+!sundry/editor-syntax-etc/vim/templates/*.tpl
+!sundry/editor-syntax-etc/nvim
+!sundry/editor-syntax-etc/nvim/*.md
+!sundry/editor-syntax-etc/nvim/ftdetect
+!sundry/editor-syntax-etc/nvim/ftdetect/*.lua
+!sundry/editor-syntax-etc/nvim/ftplugin
+!sundry/editor-syntax-etc/nvim/ftplugin/*.lua
+!sundry/editor-syntax-etc/nvim/queries
+!sundry/editor-syntax-etc/nvim/queries/sisu
+!sundry/editor-syntax-etc/nvim/queries/sisu/*.scm
+!sundry/editor-syntax-etc/nvim/**
!sundry/editor-syntax-etc/emacs
!sundry/editor-syntax-etc/emacs/*.el
!sundry/editor-syntax-etc/emacs/README
diff --git a/derivation.nix b/derivation.nix
index f7bcad7..593e0db 100755
--- a/derivation.nix
+++ b/derivation.nix
@@ -88,7 +88,7 @@ with (
);
mkDubDerivation rec {
pname = "spine";
- version = "0.19.0";
+ version = "0.22.0";
src = ./.;
nativeBuildInputs = with pkgs; [dub ldc];
buildInputs = with pkgs; [nixVersions.latest sqlite];
diff --git a/dub.json b/dub.json
index d6ede62..7ae3419 100644
--- a/dub.json
+++ b/dub.json
@@ -4,50 +4,68 @@
],
"copyright": "Copyright © 2015 - 2026 Ralph Amissah",
"name": "spine",
- "version": "0.19.0",
+ "version": "0.22.0",
"description": "an object-centric sisu-like document parser",
"homepage": "https://sisudoc.org",
"license": "AGPL-3.0+",
"targetPath": "./bin",
"sourcePaths": [ "./src/sisudoc" ],
+ "excludedSourceFiles": [ "./src/sisudoc/ocda/*" ],
"importPaths": [ "./views" ],
"stringImportPaths": [ "./views" ],
"buildRequirements": [ "allowWarnings" ],
"targetType": "executable",
"buildTypes": {
"dmd": {
- "dflags": [ "-O", "-J=views", "-I=src/sisudoc" ],
+ "dflags": [ "-O", "-J=views", "-I=src" ],
"buildOptions": [ "inline", "verbose" ],
"buildRequirements": [ "allowWarnings" ]
},
"ldc2": {
- "lflags": [ "-O2", "-I=src/sisudoc" ],
+ "lflags": [ "-O2", "-I=src" ],
"buildOptions": [ "optimize", "inline", "verbose" ],
"buildRequirements": [ "allowWarnings" ]
},
"ldmd2": {
- "dflags": [ "-O", "-J=views", "-I=src/sisudoc" ],
+ "dflags": [ "-O", "-J=views", "-I=src" ],
"buildOptions": [ "optimize", "inline", "verbose" ],
"buildRequirements": [ "allowWarnings" ]
},
"gdc": {
- "lflags": [ "-O2", "-J=views", "-I=src/sisudoc" ],
+ "lflags": [ "-O2", "-J=views", "-I=src" ],
"buildOptions": [ "optimize", "inline" ],
"buildRequirements": [ "allowWarnings" ]
},
"gdmd": {
- "dflags": [ "-O", "-J=views", "-I=src/sisudoc" ],
+ "dflags": [ "-O", "-J=views", "-I=src" ],
"buildOptions": [ "optimize", "inline" ],
"buildRequirements": [ "allowWarnings" ]
}
},
"dependencies": {
+ "spine:abstraction": "*",
"spine:d2sqlite3": "*",
"spine:imageformats": "*",
"spine:dyaml": "*"
},
"subPackages": [
{
+ "name": "abstraction",
+ "description": "sisudoc-abstraction: in-memory document object model + .ssp serialisation (markup -> abstraction stage, independent of output formats)",
+ "homepage": "https://sisudoc.org",
+ "authors": [ "Ralph Amissah" ],
+ "copyright": "Copyright © 2015 - 2026 Ralph Amissah",
+ "license": "AGPL-3.0+",
+ "targetType": "library",
+ "sourcePaths": [ "./src/sisudoc/ocda" ],
+ "importPaths": [ "./src" ],
+ "buildRequirements": [ "allowWarnings" ],
+ "dependencies": {
+ "spine:dyaml": "*",
+ "spine:imageformats": "*"
+ }
+ },
+ {
"name": "d2sqlite3",
"description": "A thin wrapper around SQLite 3",
"homepage": "https://github.com/dlang-community/d2sqlite3",
@@ -92,9 +110,9 @@
"./src/ext_depends/D-YAML/source",
"./src/ext_depends/tinyendian/source"
],
- "preGenerateCommands": [
- "rm -rf ./src/ext_depends/D-YAML/examples",
- "rm -rf ./src/ext_depends/D-YAML/testsuite"
+ "excludedSourceFiles": [
+ "./src/ext_depends/D-YAML/examples/**",
+ "./src/ext_depends/D-YAML/testsuite/**"
]
}
],
diff --git a/flake.lock b/flake.lock
index c17b46f..1c785f9 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
- "lastModified": 1777395829,
- "narHash": "sha256-HposVFZcsBCevgqLR73w/BpSe8J1lMgw5kASnnxO3A4=",
+ "lastModified": 1779593580,
+ "narHash": "sha256-le3WvQyzAQjBZnb7q2c8C5Fk2c9LgN/Oq+b0KiD4fM4=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "e75f25705c2934955ee5075e62530d74aca973c6",
+ "rev": "d849bb215dcdf71bce3e686839ccdb4219e84b2f",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index 8492215..3c5f0d9 100644
--- a/flake.nix
+++ b/flake.nix
@@ -7,7 +7,7 @@
...
}@inputs: let
pname = "spine";
- version = "0.19.0";
+ version = "0.22.0";
supportedSystems = ["x86_64-linux"]; # [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
nixpkgsFor = forAllSystems (system: import nixpkgs {inherit system;}); # nixpkgs instantiated for supported system types
@@ -143,7 +143,7 @@
#default = import ./shell.nix {pkgs = pkgs-nix; flake = self;};
dsh-overlay = mkDevShell {
pkgs = pkgs-ovl;
- # "spine-0.19.0 base dev shell, ldc-1.42.0, dub-1.40.0 - dtools-2.110.0";
+ # "spine-0.22.0 base dev shell, ldc-1.42.0, dub-1.40.0 - dtools-2.110.0";
name = "spine-${version} dev shell (overlay ldc)";
compiler = pkgs-ovl.ldc;
};
@@ -161,13 +161,13 @@
};
dsh-overlay-dmd = mkDevShell {
pkgs = pkgs-ovl;
- # "spine-0.19.0 base dev shell, dmd-2.111.0, dub-1.40.0 - dtools-2.110.0";
+ # "spine-0.22.0 base dev shell, dmd-2.111.0, dub-1.40.0 - dtools-2.110.0";
name = "spine-${version} dev shell (overlay dmd)";
compiler = pkgs-ovl.dmd;
};
dsh-overlay-ldc = mkDevShell {
pkgs = pkgs-ovl;
- # "spine-0.19.0 base dev shell, ldc-1.42.0, dub-1.40.0 - dtools-2.110.0";
+ # "spine-0.22.0 base dev shell, ldc-1.42.0, dub-1.40.0 - dtools-2.110.0";
name = "spine-${version} dev shell (overlay ldc)";
compiler = pkgs-ovl.ldc;
};
diff --git a/makefile b/makefile
index b91d722..f1f8b6e 100644
--- a/makefile
+++ b/makefile
@@ -642,14 +642,14 @@ skel:
mkdir -p build; \
mkdir -p views; \
mkdir -p data; \
- mkdir -p sundry/misc/util/d/cgi/search/cgi-bin/src; \
- mkdir -p sundry/misc/util/d/tools/markup_conversion; \
- mkdir -p sundry/misc/editor-syntax-etc/emacs; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/syntax; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/colors; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/ftplugin; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/rc; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/templates; \
+ mkdir -p sundry/util/d/cgi/search/cgi-bin/src; \
+ mkdir -p sundry/util/d/tools/markup_conversion; \
+ mkdir -p sundry/editor-syntax-etc/emacs; \
+ mkdir -p sundry/editor-syntax-etc/vim/syntax; \
+ mkdir -p sundry/editor-syntax-etc/vim/colors; \
+ mkdir -p sundry/editor-syntax-etc/vim/ftplugin; \
+ mkdir -p sundry/editor-syntax-etc/vim/rc; \
+ mkdir -p sundry/editor-syntax-etc/vim/templates; \
mkdir -p $(PRG_SRCDIR)/$(PRG_NAME_DIR)/conf; \
mkdir -p $(PRG_SRCDIR)/$(PRG_NAME_DIR)/io_in; \
mkdir -p $(PRG_SRCDIR)/$(PRG_NAME_DIR)/io_out; \
@@ -685,14 +685,14 @@ distclean: expunge
distclean_and_init: expunge
mkdir -p views; \
- mkdir -p sundry/misc/util/d/cgi/search/cgi-bin/src; \
- mkdir -p sundry/misc/util/d/tools/markup_conversion; \
- mkdir -p sundry/misc/editor-syntax-etc/emacs; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/syntax; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/colors; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/ftplugin; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/rc; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/templates; \
+ mkdir -p sundry/util/d/cgi/search/cgi-bin/src; \
+ mkdir -p sundry/util/d/tools/markup_conversion; \
+ mkdir -p sundry/editor-syntax-etc/emacs; \
+ mkdir -p sundry/editor-syntax-etc/vim/syntax; \
+ mkdir -p sundry/editor-syntax-etc/vim/colors; \
+ mkdir -p sundry/editor-syntax-etc/vim/ftplugin; \
+ mkdir -p sundry/editor-syntax-etc/vim/rc; \
+ mkdir -p sundry/editor-syntax-etc/vim/templates; \
mkdir -p $(PRG_SRCDIR)/$(PRG_NAME_DIR); \
mkdir -p $(PRG_BINDIR);
@@ -1301,8 +1301,8 @@ gitsnapshot: distclean tangle
git commit -a
version_tag:
- echo "DRV=0.19.0; git tag -f sisudoc-spine_v$$\{DRV} -m\"doc-reform sisudoc spine-$$\{DRV}\" HEAD"; \
- echo "git tag -f sisudoc-spine_v0.19.0 -m\"doc-reform sisudoc spine-0.19.0\" HEAD"
+ echo "DRV=0.22.0; git tag -f sisudoc-spine_v$$\{DRV} -m\"doc-reform sisudoc spine-$$\{DRV}\" HEAD"; \
+ echo "git tag -f sisudoc-spine_v0.22.0 -m\"doc-reform sisudoc spine-0.22.0\" HEAD"
.PHONY : all build rebuild release \
distclean init \
diff --git a/meson.build b/meson.build
index e0432d0..ad11749 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
project('spine', 'd',
license: 'AGPL-3',
- version: '0.19.0',
+ version: '0.22.0',
meson_version: '>=0.46'
)
#if meson.get_compiler('d').get_id() == 'gcc'
diff --git a/nix-overlays/dtools/disabled-tests.diff b/nix-overlays/dtools/disabled-tests.diff
index a22825a..79eb1cb 100644
--- a/nix-overlays/dtools/disabled-tests.diff
+++ b/nix-overlays/dtools/disabled-tests.diff
@@ -3,7 +3,7 @@
@@ -616,7 +616,7 @@ void runTests(string rdmdApp, string compiler, string model)
enforce(res.status == 1, res.output);
}
-
+
- version (Posix)
+ version (none)
{
diff --git a/nix-overlays/dtools/fix-ldc-arm64.diff b/nix-overlays/dtools/fix-ldc-arm64.diff
index 66eaa22..1c650a6 100644
--- a/nix-overlays/dtools/fix-ldc-arm64.diff
+++ b/nix-overlays/dtools/fix-ldc-arm64.diff
@@ -82,21 +82,21 @@ Adapted from https://github.com/dlang/tools/commit/6c6a042d1b08e3ec1790bd07a7f69
@@ -9,9 +9,8 @@ DUB=dub
WITH_DOC = no
DOC = ../dlang.org
-
+
-# Load operating system $(OS) (e.g. linux, osx, ...) and $(MODEL) (e.g. 32, 64) detection Makefile from dmd
-$(shell [ ! -d $(DMD_DIR) ] && git clone --depth=1 https://github.com/dlang/dmd $(DMD_DIR))
-include $(DMD_DIR)/compiler/src/osmodel.mak
+# Load operating system $(OS) (e.g. linux, osx, ...) and $(MODEL) (e.g. 32, 64) detection Makefile
+include osmodel.mak
-
+
ifeq (windows,$(OS))
DOTEXE:=.exe
@@ -30,7 +29,7 @@ DFLAGS = $(MODEL_FLAG) $(if $(findstring windows,$(OS)),,-fPIC) -preview=dip1000
DFLAGS += $(WARNINGS)
-
+
# Default DUB flags (DUB uses a different architecture format)
-DUBFLAGS = --arch=$(subst 32,x86,$(subst 64,x86_64,$(MODEL)))
+DUBFLAGS = --arch=$(ARCH)
-
+
TOOLS = \
$(ROOT)/catdoc$(DOTEXE) \
diff --git a/org/COPYRIGHT b/org/COPYRIGHT
index 1678968..249a68a 100644
--- a/org/COPYRIGHT
+++ b/org/COPYRIGHT
@@ -1,10 +1,10 @@
- Name: spine - SiSU Spine, Doc Reform
- Description: documents, structuring, processing, publishing, search
- static content generator
-
+
- Author: Ralph Amissah
[ralph.amissah@gmail.com]
-
+
- Copyright: (C) 2015 - 2026 Ralph Amissah
- Spine, Doc Reform (related to SiSU) uses standard:
@@ -13,7 +13,7 @@
modifications
- docReform object numbering (based on SiSU object citation numbering)
- standard SiSU document object numbering
-
+
- Homepages:
[https://www.sisudoc.org]
diff --git a/org/compile_time_info.org b/org/compile_time_info.org
index 0739030..676f061 100644
--- a/org/compile_time_info.org
+++ b/org/compile_time_info.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -27,14 +27,14 @@ version(Windows) {} else { ... }
** _module template_ :module:compile_time_info:
-#+HEADER: :tangle "../src/sisudoc/conf/compile_time_info.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/conf/compile_time_info.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
compile_time_info
+/
-module sisudoc.conf.compile_time_info;
+module sisudoc.outputs.conf.compile_time_info;
@safe:
template CompileTimeInfo() {
<<spine_compile_time_info_0>>
diff --git a/org/config_d_cfte.org b/org/config_d_cfte.org
index ae20abb..8bbf8d6 100644
--- a/org/config_d_cfte.org
+++ b/org/config_d_cfte.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[../org/][org/]]
diff --git a/org/config_dub.org b/org/config_dub.org
index a584adf..10dd6e5 100644
--- a/org/config_dub.org
+++ b/org/config_dub.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -47,44 +47,62 @@
"license": "AGPL-3.0+",
"targetPath": "./bin",
"sourcePaths": [ "./src/sisudoc" ],
+ "excludedSourceFiles": [ "./src/sisudoc/ocda/*" ],
"importPaths": [ "./views" ],
"stringImportPaths": [ "./views" ],
"buildRequirements": [ "allowWarnings" ],
"targetType": "executable",
"buildTypes": {
"dmd": {
- "dflags": [ "-O", "-J=views", "-I=src/sisudoc" ],
+ "dflags": [ "-O", "-J=views", "-I=src" ],
"buildOptions": [ "inline", "verbose" ],
"buildRequirements": [ "allowWarnings" ]
},
"ldc2": {
- "lflags": [ "-O2", "-I=src/sisudoc" ],
+ "lflags": [ "-O2", "-I=src" ],
"buildOptions": [ "optimize", "inline", "verbose" ],
"buildRequirements": [ "allowWarnings" ]
},
"ldmd2": {
- "dflags": [ "-O", "-J=views", "-I=src/sisudoc" ],
+ "dflags": [ "-O", "-J=views", "-I=src" ],
"buildOptions": [ "optimize", "inline", "verbose" ],
"buildRequirements": [ "allowWarnings" ]
},
"gdc": {
- "lflags": [ "-O2", "-J=views", "-I=src/sisudoc" ],
+ "lflags": [ "-O2", "-J=views", "-I=src" ],
"buildOptions": [ "optimize", "inline" ],
"buildRequirements": [ "allowWarnings" ]
},
"gdmd": {
- "dflags": [ "-O", "-J=views", "-I=src/sisudoc" ],
+ "dflags": [ "-O", "-J=views", "-I=src" ],
"buildOptions": [ "optimize", "inline" ],
"buildRequirements": [ "allowWarnings" ]
}
},
"dependencies": {
+ "spine:abstraction": "*",
"spine:d2sqlite3": "*",
"spine:imageformats": "*",
"spine:dyaml": "*"
},
"subPackages": [
{
+ "name": "abstraction",
+ "description": "sisudoc-abstraction: in-memory document object model + .ssp serialisation (markup -> abstraction stage, independent of output formats)",
+ "homepage": "https://sisudoc.org",
+ "authors": [ "Ralph Amissah" ],
+ "copyright": "Copyright © 2015 - 2026 Ralph Amissah",
+ "license": "AGPL-3.0+",
+ "targetType": "library",
+ "sourcePaths": [ "./src/sisudoc/ocda" ],
+ "importPaths": [ "./src" ],
+ "buildRequirements": [ "allowWarnings" ],
+ "dependencies": {
+ "spine:dyaml": "*",
+ "spine:imageformats": "*"
+ }
+ },
+ {
"name": "d2sqlite3",
"description": "A thin wrapper around SQLite 3",
"homepage": "https://github.com/dlang-community/d2sqlite3",
@@ -129,9 +147,9 @@
"./src/ext_depends/D-YAML/source",
"./src/ext_depends/tinyendian/source"
],
- "preGenerateCommands": [
- "rm -rf ./src/ext_depends/D-YAML/examples",
- "rm -rf ./src/ext_depends/D-YAML/testsuite"
+ "excludedSourceFiles": [
+ "./src/ext_depends/D-YAML/examples/**",
+ "./src/ext_depends/D-YAML/testsuite/**"
]
}
],
diff --git a/org/config_env.org b/org/config_env.org
index 98b6eb8..52e72c3 100644
--- a/org/config_env.org
+++ b/org/config_env.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[../org/][org/]]
- [[./config_nix.org][config_nix.org]]
diff --git a/org/config_git.org b/org/config_git.org
index 7f0a98c..42959df 100644
--- a/org/config_git.org
+++ b/org/config_git.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -100,6 +100,18 @@
!sundry/editor-syntax-etc/vim/ftplugin/*.vim
!sundry/editor-syntax-etc/vim/syntax
!sundry/editor-syntax-etc/vim/syntax/*.vim
+!sundry/editor-syntax-etc/vim/templates
+!sundry/editor-syntax-etc/vim/templates/*.tpl
+!sundry/editor-syntax-etc/nvim
+!sundry/editor-syntax-etc/nvim/*.md
+!sundry/editor-syntax-etc/nvim/ftdetect
+!sundry/editor-syntax-etc/nvim/ftdetect/*.lua
+!sundry/editor-syntax-etc/nvim/ftplugin
+!sundry/editor-syntax-etc/nvim/ftplugin/*.lua
+!sundry/editor-syntax-etc/nvim/queries
+!sundry/editor-syntax-etc/nvim/queries/sisu
+!sundry/editor-syntax-etc/nvim/queries/sisu/*.scm
+!sundry/editor-syntax-etc/nvim/**
!sundry/editor-syntax-etc/emacs
!sundry/editor-syntax-etc/emacs/*.el
!sundry/editor-syntax-etc/emacs/README
diff --git a/org/config_make.org b/org/config_make.org
index 17b5986..86688c3 100644
--- a/org/config_make.org
+++ b/org/config_make.org
@@ -6,13 +6,14 @@
#+EMAIL: [[mailto:ralph.amissah@gmail.com][ralph.amissah@gmail.com]]
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
-#+STARTUP: show4levels hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+STARTUP: content hideblocks hidestars noindent entitiespretty
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
+#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[../org/][org/]]
@@ -683,14 +684,14 @@ skel:
mkdir -p build; \
mkdir -p views; \
mkdir -p data; \
- mkdir -p sundry/misc/util/d/cgi/search/cgi-bin/src; \
- mkdir -p sundry/misc/util/d/tools/markup_conversion; \
- mkdir -p sundry/misc/editor-syntax-etc/emacs; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/syntax; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/colors; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/ftplugin; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/rc; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/templates; \
+ mkdir -p sundry/util/d/cgi/search/cgi-bin/src; \
+ mkdir -p sundry/util/d/tools/markup_conversion; \
+ mkdir -p sundry/editor-syntax-etc/emacs; \
+ mkdir -p sundry/editor-syntax-etc/vim/syntax; \
+ mkdir -p sundry/editor-syntax-etc/vim/colors; \
+ mkdir -p sundry/editor-syntax-etc/vim/ftplugin; \
+ mkdir -p sundry/editor-syntax-etc/vim/rc; \
+ mkdir -p sundry/editor-syntax-etc/vim/templates; \
mkdir -p $(PRG_SRCDIR)/$(PRG_NAME_DIR)/conf; \
mkdir -p $(PRG_SRCDIR)/$(PRG_NAME_DIR)/io_in; \
mkdir -p $(PRG_SRCDIR)/$(PRG_NAME_DIR)/io_out; \
@@ -726,14 +727,14 @@ distclean: expunge
distclean_and_init: expunge
mkdir -p views; \
- mkdir -p sundry/misc/util/d/cgi/search/cgi-bin/src; \
- mkdir -p sundry/misc/util/d/tools/markup_conversion; \
- mkdir -p sundry/misc/editor-syntax-etc/emacs; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/syntax; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/colors; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/ftplugin; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/rc; \
- mkdir -p sundry/misc/editor-syntax-etc/vim/templates; \
+ mkdir -p sundry/util/d/cgi/search/cgi-bin/src; \
+ mkdir -p sundry/util/d/tools/markup_conversion; \
+ mkdir -p sundry/editor-syntax-etc/emacs; \
+ mkdir -p sundry/editor-syntax-etc/vim/syntax; \
+ mkdir -p sundry/editor-syntax-etc/vim/colors; \
+ mkdir -p sundry/editor-syntax-etc/vim/ftplugin; \
+ mkdir -p sundry/editor-syntax-etc/vim/rc; \
+ mkdir -p sundry/editor-syntax-etc/vim/templates; \
mkdir -p $(PRG_SRCDIR)/$(PRG_NAME_DIR); \
mkdir -p $(PRG_BINDIR);
diff --git a/org/config_meson.org b/org/config_meson.org
index 60b434e..f268ff6 100644
--- a/org/config_meson.org
+++ b/org/config_meson.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
diff --git a/org/config_misc.org b/org/config_misc.org
index 670f4ba..64670e5 100644
--- a/org/config_misc.org
+++ b/org/config_misc.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
* sundry misc
** sh script to batch process _emacs org babel tangle_ :shell_script:tangle:
diff --git a/org/config_nix.org b/org/config_nix.org
index 0fef79d..83b26d3 100644
--- a/org/config_nix.org
+++ b/org/config_nix.org
@@ -6,14 +6,14 @@
#+EMAIL: [[mailto:ralph.amissah@gmail.com][ralph.amissah@gmail.com]]
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
-#+STARTUP: show4levels hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+STARTUP: content hideblocks hidestars noindent entitiespretty
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
* nix :nix:
** flake.nix :flake:
diff --git a/org/default_imports.org b/org/default_imports.org
index 370f48f..4f03212 100644
--- a/org/default_imports.org
+++ b/org/default_imports.org
@@ -7,24 +7,24 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
* imports for _meta_ :meta:
** package dir
-#+HEADER: :tangle "../src/sisudoc/meta/package.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/package.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.meta;
+module sisudoc.ocda.meta;
<<imports_for_meta_general>>
#+END_SRC
@@ -32,7 +32,7 @@ module sisudoc.meta;
#+NAME: imports_for_meta_general
#+BEGIN_SRC d
-public import sisudoc.meta.defaults;
+public import sisudoc.ocda.meta.defaults;
/+ std +/
public import std.array;
public import std.exception;
@@ -49,11 +49,11 @@ public import std.conv : to;
* imports for _output_ :output:
** package dir
-#+HEADER: :tangle "../src/sisudoc/io_out/package.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/package.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out;
+module sisudoc.outputs.io_out;
<<imports_for_output_general>>
#+END_SRC
@@ -74,10 +74,10 @@ public import std.string;
public import std.typecons;
// public import std.uni;
public import std.utf;
-public import sisudoc.share.defaults;
-public import sisudoc.io_in.paths_source;
-public import sisudoc.io_out.defaults;
-public import sisudoc.io_out.paths_output;
+public import sisudoc.outputs.share.defaults;
+public import sisudoc.ocda.io_in.paths_source;
+public import sisudoc.outputs.io_out.defaults;
+public import sisudoc.outputs.io_out.paths_output;
#+END_SRC
* org includes
diff --git a/org/default_misc.org b/org/default_misc.org
index ad53155..87ca048 100644
--- a/org/default_misc.org
+++ b/org/default_misc.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -21,14 +21,14 @@
** _module template_
#+NAME: tangle_defaults
-#+HEADER: :tangle "../src/sisudoc/meta/defaults.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/defaults.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
default settings
+/
-module sisudoc.meta.defaults;
+module sisudoc.ocda.meta.defaults;
@safe:
<<meta_defaults_template_node>>
<<meta_defaults_template_curate_metadata>>
@@ -172,14 +172,14 @@ template spineBiblio() {
** _module template_
#+NAME: tangle_defaults
-#+HEADER: :tangle "../src/sisudoc/io_out/defaults.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/defaults.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
default settings
+/
-module sisudoc.io_out.defaults;
+module sisudoc.outputs.io_out.defaults;
@safe:
<<defaults_template_init_flags>>
<<defaults_template_markup>>
diff --git a/org/default_paths.org b/org/default_paths.org
index 958acfd..a6cf19a 100644
--- a/org/default_paths.org
+++ b/org/default_paths.org
@@ -7,20 +7,20 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
* source paths
** _module template_ :module:paths_source:
-#+HEADER: :tangle "../src/sisudoc/io_in/paths_source.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/io_in/paths_source.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
@@ -29,7 +29,7 @@
- read config files<BR>
meta_config_files.d
+/
-module sisudoc.io_in.paths_source;
+module sisudoc.ocda.io_in.paths_source;
@safe:
import std.array;
import std.file;
@@ -37,8 +37,8 @@ import std.path;
import std.regex;
import std.stdio;
import std.conv : to;
-import sisudoc.meta.defaults;
-import sisudoc.meta.rgx_files;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.meta.rgx_files;
<<template_paths_src_0>>
<<template_paths_src_1>>
<<template_paths_src_2>>
@@ -979,20 +979,20 @@ template spinePathsPods() {
* output paths
** _module template_ :module:paths_output:
-#+HEADER: :tangle "../src/sisudoc/io_out/paths_output.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/paths_output.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
default settings
+/
-module sisudoc.io_out.paths_output;
+module sisudoc.outputs.io_out.paths_output;
@safe:
import std.array;
import std.path;
import std.regex;
import std.stdio;
-import sisudoc.meta.rgx_files;
+import sisudoc.ocda.meta.rgx_files;
<<template_paths_out_0>>
<<template_paths_out_1>>
<<template_paths_url>>
diff --git a/org/default_regex.org b/org/default_regex.org
index 8e2e695..430828b 100644
--- a/org/default_regex.org
+++ b/org/default_regex.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -34,14 +34,14 @@ https://dlang.org/phobos/std_regex.html
** _module template_ :module:
-#+HEADER: :tangle "../src/sisudoc/meta/rgx.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/rgx.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.meta.rgx;
+module sisudoc.ocda.meta.rgx;
@safe:
static template spineRgxIn() {
static struct RgxI {
@@ -472,14 +472,14 @@ https://dlang.org/phobos/std_regex.html
** _module template_ :module:output:
-#+HEADER: :tangle "../src/sisudoc/io_out/rgx.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/rgx.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.io_out.rgx;
+module sisudoc.outputs.io_out.rgx;
@safe:
static template spineRgxOut() {
static struct RgxO {
@@ -678,14 +678,14 @@ static table_delimiter_row = ctRegex!("[ ]*\n", "mg");
** files filename (& path) (including insert file) :insert:file:path:filename:
-#+HEADER: :tangle "../src/sisudoc/meta/rgx_files.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/rgx_files.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.meta.rgx_files;
+module sisudoc.ocda.meta.rgx_files;
@safe:
static template spineRgxFiles() {
static struct RgxFiles {
@@ -712,14 +712,14 @@ static src_formalised_file_path_parts = ctRegex!(`(?P<pth>(?:[/a-zA-Z0
** _module template yaml tags
-#+HEADER: :tangle "../src/sisudoc/meta/rgx_yaml.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/rgx_yaml.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.meta.rgx_yaml;
+module sisudoc.ocda.meta.rgx_yaml;
@safe:
static template spineRgxYamlTags() {
static struct RgxYaml {
@@ -739,14 +739,14 @@ static yaml_tag_is_seq = ctRegex!(`:seq$`);
** special characters
*** xhtml special characters template
-#+HEADER: :tangle "../src/sisudoc/io_out/rgx_xhtml.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/rgx_xhtml.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.io_out.rgx_xhtml;
+module sisudoc.outputs.io_out.rgx_xhtml;
@safe:
static template spineRgxXHTML() {
static struct RgxXHTML {
@@ -768,14 +768,14 @@ static line_break = ctRegex!(` [\\]{2}`, "m"); //
*** LaTeX special characters template
-#+HEADER: :tangle "../src/sisudoc/io_out/rgx_latex.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/rgx_latex.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.io_out.rgx_latex;
+module sisudoc.outputs.io_out.rgx_latex;
@safe:
static template spineRgxLSC() {
static struct RgxLSC {
diff --git a/org/default_shared_snippets.org b/org/default_shared_snippets.org
index ce13a75..a4a09cc 100644
--- a/org/default_shared_snippets.org
+++ b/org/default_shared_snippets.org
@@ -7,24 +7,24 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
* html snippet
** _module template_ :module:
-#+HEADER: :tangle "../src/sisudoc/io_out/html_snippet.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/html_snippet.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.html_snippet;
+module sisudoc.outputs.io_out.html_snippet;
@safe:
template htmlSnippet() {
import std.file;
@@ -32,9 +32,9 @@ template htmlSnippet() {
import std.format;
import std.uri;
import std.conv : to;
- import sisudoc.io_out.rgx;
- import sisudoc.meta.rgx_files;
- import sisudoc.io_out.rgx_xhtml;
+ import sisudoc.outputs.io_out.rgx;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.outputs.io_out.rgx_xhtml;
auto format_html_blank_page_guide_home()(
string css_style,
string home_url,
@@ -81,14 +81,14 @@ template htmlSnippet() {
* shared
** _module template_ :module:shared:
-#+HEADER: :tangle "../src/sisudoc/share/defaults.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/share/defaults.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
shared default settings
+/
-module sisudoc.share.defaults;
+module sisudoc.outputs.share.defaults;
@safe:
<<shared_messages>>
#+END_SRC
diff --git a/org/in_source_files.org b/org/in_source_files.org
index 478e0b9..1aab3a7 100644
--- a/org/in_source_files.org
+++ b/org/in_source_files.org
@@ -7,20 +7,20 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
* A. get _config file_, read in (.readText) [#A]
** _module template_ :module:config_files:
-#+HEADER: :tangle "../src/sisudoc/io_in/read_config_files.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/io_in/read_config_files.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
@@ -29,14 +29,14 @@
- read config files<BR>
meta_config_files.d
+/
-module sisudoc.io_in.read_config_files;
+module sisudoc.ocda.io_in.read_config_files;
@safe:
import std.file;
import std.path;
-import sisudoc.meta;
-import sisudoc.io_in.paths_source;
-import sisudoc.meta.rgx_files;
-import sisudoc.meta.rgx;
+import sisudoc.ocda.meta;
+import sisudoc.ocda.io_in.paths_source;
+import sisudoc.ocda.meta.rgx_files;
+import sisudoc.ocda.meta.rgx;
<<meta_config_file_hub_read_site_config>>
<<meta_config_file_hub_read_document_config>>
<<meta_config_file_hub_read_site_yaml>>
@@ -186,10 +186,10 @@ webserv:
static template readConfigDoc() {
import std.file;
import std.path;
- import sisudoc.meta;
- import sisudoc.io_in.paths_source;
- import sisudoc.meta.rgx_files;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta;
+ import sisudoc.ocda.io_in.paths_source;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.ocda.meta.rgx;
@system final auto readConfigDoc(M,E)(M _manifested, E _env) {
mixin spineRgxIn;
static auto rgx = RgxI();
@@ -247,10 +247,10 @@ static template readConfigDoc() {
static template configReadSiteYAML() {
import std.file;
import std.path;
- import sisudoc.meta;
- import sisudoc.io_in.paths_source;
- import sisudoc.meta.rgx_files;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta;
+ import sisudoc.ocda.io_in.paths_source;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.ocda.meta.rgx;
final YAMLDocument configReadSiteYAML(M,E)(M _manifested, E _env) {
string _configuration = configReadInSiteYAML!()(_manifested, _env);
auto _conf_file_details = configFilePaths!()(_manifested, _env);
@@ -262,8 +262,8 @@ static template configReadSiteYAML() {
static template configReadDocYAML() {
import std.file;
import std.path;
- import sisudoc.meta;
- import sisudoc.io_in.paths_source;
+ import sisudoc.ocda.meta;
+ import sisudoc.ocda.io_in.paths_source;
final YAMLDocument configReadDocYAML(M,E)(M _manifested, E _env) {
string _configuration = configReadInDocYAML!()(_manifested, _env);
auto _conf_file_details = configFilePaths!()(_manifested, _env);
@@ -277,7 +277,7 @@ static template configReadDocYAML() {
* B. get _markup source_, read file (.readText) [#A]:module:source_files:
** _module template_
-#+HEADER: :tangle "../src/sisudoc/io_in/read_source_files.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/io_in/read_source_files.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
@@ -286,16 +286,16 @@ static template configReadDocYAML() {
- open markup files<BR>
- if master file scan for addional files to import/insert
+/
-module sisudoc.io_in.read_source_files;
+module sisudoc.ocda.io_in.read_source_files;
@safe:
template spineRawMarkupContent() {
import std.digest.sha;
import std.file;
import std.path;
- import sisudoc.meta;
- import sisudoc.io_in.paths_source;
- import sisudoc.meta.rgx_files;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta;
+ import sisudoc.ocda.io_in.paths_source;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.ocda.meta.rgx;
mixin spineRgxIn;
static auto rgx = RgxI();
mixin spineRgxFiles;
diff --git a/org/in_zip_pod.org b/org/in_zip_pod.org
index e44b10e..9beae6e 100644
--- a/org/in_zip_pod.org
+++ b/org/in_zip_pod.org
@@ -7,19 +7,19 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
* read zip
-#+HEADER: :tangle "../src/sisudoc/io_in/read_zip_pod.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/io_in/read_zip_pod.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
@@ -28,7 +28,7 @@
- extract pod zip archives to temp directory for processing<BR>
- validate zip entries for security (path traversal, size limits)
+/
-module sisudoc.io_in.read_zip_pod;
+module sisudoc.ocda.io_in.read_zip_pod;
@safe:
template spineExtractZipPod() {
import std.algorithm : canFind;
diff --git a/org/meta_conf_make_meta.org b/org/meta_conf_make_meta.org
index 1cae84f..f9c13ef 100644
--- a/org/meta_conf_make_meta.org
+++ b/org/meta_conf_make_meta.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :noweb yes
-#+PROPERTY: header-args+ :exports code
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -214,16 +214,16 @@ import std.typecons;
import std.uni;
import std.utf;
import std.conv : to;
-import sisudoc.meta.conf_make_meta_structs;
+import sisudoc.ocda.meta.conf_make_meta_structs;
#+END_SRC
** struct ConfComposite
-#+HEADER: :tangle "../src/sisudoc/meta/conf_make_meta_structs.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/conf_make_meta_structs.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.meta.conf_make_meta_structs;
+module sisudoc.ocda.meta.conf_make_meta_structs;
@safe:
<<meta_defaults_template_structs_init>>
<<meta_defaults_template_structs_setup>>
@@ -247,9 +247,9 @@ import std.string;
import std.typecons;
import std.utf;
import std.conv : to;
-import sisudoc.meta.defaults;
-import sisudoc.meta.rgx_yaml;
-import sisudoc.meta.rgx;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.meta.rgx_yaml;
+import sisudoc.ocda.meta.rgx;
mixin spineRgxIn;
static auto rgx = RgxI();
mixin spineRgxYamlTags;
@@ -607,7 +607,7 @@ string check_input_markup()(
** _module template_
-#+HEADER: :tangle "../src/sisudoc/meta/conf_make_meta_yaml.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/conf_make_meta_yaml.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
@@ -615,7 +615,7 @@ string check_input_markup()(
yaml headers<BR>
extract yaml header return struct
+/
-module sisudoc.meta.conf_make_meta_yaml;
+module sisudoc.ocda.meta.conf_make_meta_yaml;
@safe:
template contentYAMLtoSpineStruct() {
import std.algorithm;
@@ -628,10 +628,10 @@ template contentYAMLtoSpineStruct() {
import std.typecons;
import std.utf;
import std.conv : to;
- import sisudoc.meta.conf_make_meta_structs;
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx_yaml;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.conf_make_meta_structs;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx_yaml;
+ import sisudoc.ocda.meta.rgx;
ConfComposite _struct_composite;
@system ConfComposite contentYAMLtoSpineStruct(C,Y,M,O,Cfg)(
C _struct_composite,
@@ -1432,7 +1432,7 @@ if ("rights" in _yaml
* JSON to spineStruct :module:conf_make_meta:json:
** _module template_
-#+HEADER: :tangle "../src/sisudoc/meta/conf_make_meta_json.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/conf_make_meta_json.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
@@ -1440,7 +1440,7 @@ if ("rights" in _yaml
json headers<BR>
extract json header return json
+/
-module sisudoc.meta.conf_make_meta_json;
+module sisudoc.ocda.meta.conf_make_meta_json;
@safe:
static template contentJSONtoSpineStruct() {
import std.algorithm;
@@ -1452,10 +1452,10 @@ static template contentJSONtoSpineStruct() {
import std.typecons;
import std.utf;
import std.conv : to;
- import sisudoc.meta.conf_make_meta_structs;
- import sisudoc.meta.conf_make_meta_json;
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.conf_make_meta_structs;
+ import sisudoc.ocda.meta.conf_make_meta_json;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
ConfComposite _struct_composite;
auto contentJSONtoSpineStruct(C,J,M)(C _struct_composite, J _json, M _manifested, string _identifier) {
mixin spineRgxIn;
@@ -2109,8 +2109,8 @@ if ("rights" in _json.object) {
#+BEGIN_SRC d
template configParseYAMLreturnSpineStruct() {
import dyaml;
- import sisudoc.meta.conf_make_meta_structs;
- import sisudoc.meta.conf_make_meta_json;
+ import sisudoc.ocda.meta.conf_make_meta_structs;
+ import sisudoc.ocda.meta.conf_make_meta_json;
mixin contentYAMLtoSpineStruct;
@system ConfComposite configParseYAMLreturnSpineStruct(T,M,O,Cfg)(
T _document_struct,
@@ -2154,10 +2154,10 @@ template docHeaderMakeAndMetaTupYamlExtractAndConvertToStruct() {
import std.utf;
import std.conv : to;
import dyaml;
- import sisudoc.meta.conf_make_meta_structs;
- import sisudoc.meta.conf_make_meta_json;
- import sisudoc.meta.rgx_yaml;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.conf_make_meta_structs;
+ import sisudoc.ocda.meta.conf_make_meta_json;
+ import sisudoc.ocda.meta.rgx_yaml;
+ import sisudoc.ocda.meta.rgx;
mixin spineRgxIn;
mixin contentJSONtoSpineStruct;
static auto rgx = RgxI();
diff --git a/org/meta_debugs.org b/org/meta_debugs.org
index 26410bb..9604825 100644
--- a/org/meta_debugs.org
+++ b/org/meta_debugs.org
@@ -7,27 +7,27 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
* abstraction debugs :module:spine:meta_doc_debugs:
** _module template_
-#+HEADER: :tangle "../src/sisudoc/meta/doc_debugs.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/doc_debugs.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
output debugs
+/
-module sisudoc.meta.doc_debugs;
+module sisudoc.ocda.meta.doc_debugs;
template spineDebugs() {
<<debug_imports>>
auto spineDebugs(S,T)(
@@ -52,8 +52,8 @@ template spineDebugs() {
#+NAME: debug_imports
#+BEGIN_SRC d
-import sisudoc.meta.defaults;
-import sisudoc.meta.rgx_files;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.meta.rgx_files;
import std.algorithm;
import std.array;
import std.container;
diff --git a/org/nix-develop-dlang-shared.org b/org/nix-develop-dlang-shared.org
index d11b752..e971677 100644
--- a/org/nix-develop-dlang-shared.org
+++ b/org/nix-develop-dlang-shared.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :noweb yes
-#+PROPERTY: header-args+ :exports code
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
* nix
** direnv
diff --git a/org/nixpkgs_overlays_d_related.org b/org/nixpkgs_overlays_d_related.org
index 53210eb..d166bbf 100644
--- a/org/nixpkgs_overlays_d_related.org
+++ b/org/nixpkgs_overlays_d_related.org
@@ -7,14 +7,14 @@
#+COPYRIGHT: Copyright (C) 2020 Ralph Amissah
#+LICENSE: Boost Software License 1.0
#+LANGUAGE: en
-#+STARTUP: show3levels hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+STARTUP: content hideblocks hidestars noindent entitiespretty
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:nil @:t ::t |:t ^:nil _:nil -:t f:t *:t <:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
* nix ( written to ./dlang-nix-flakes/ )
** check updates CHECK
@@ -1407,7 +1407,7 @@ stdenv.mkDerivation (finalAttrs: {
@@ -616,7 +616,7 @@ void runTests(string rdmdApp, string compiler, string model)
enforce(res.status == 1, res.output);
}
-
+
- version (Posix)
+ version (none)
{
@@ -1501,22 +1501,22 @@ Adapted from https://github.com/dlang/tools/commit/6c6a042d1b08e3ec1790bd07a7f69
@@ -9,9 +9,8 @@ DUB=dub
WITH_DOC = no
DOC = ../dlang.org
-
+
-# Load operating system $(OS) (e.g. linux, osx, ...) and $(MODEL) (e.g. 32, 64) detection Makefile from dmd
-$(shell [ ! -d $(DMD_DIR) ] && git clone --depth=1 https://github.com/dlang/dmd $(DMD_DIR))
-include $(DMD_DIR)/compiler/src/osmodel.mak
+# Load operating system $(OS) (e.g. linux, osx, ...) and $(MODEL) (e.g. 32, 64) detection Makefile
+include osmodel.mak
-
+
ifeq (windows,$(OS))
DOTEXE:=.exe
@@ -30,7 +29,7 @@ DFLAGS = $(MODEL_FLAG) $(if $(findstring windows,$(OS)),,-fPIC) -preview=dip1000
DFLAGS += $(WARNINGS)
-
+
# Default DUB flags (DUB uses a different architecture format)
-DUBFLAGS = --arch=$(subst 32,x86,$(subst 64,x86_64,$(MODEL)))
+DUBFLAGS = --arch=$(ARCH)
-
+
TOOLS = \
$(ROOT)/catdoc$(DOTEXE) \
#+END_SRC
diff --git a/org/ocda.org b/org/ocda.org
index f822f8d..d5651cc 100644
--- a/org/ocda.org
+++ b/org/ocda.org
@@ -8,13 +8,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :noweb yes
-#+PROPERTY: header-args+ :exports code
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -22,16 +22,89 @@
- Process markup document, create document abstraction
+** library templates
+*** ocda package.d
+
+#+HEADER: :tangle "../src/sisudoc/ocda/package.d"
+#+HEADER: :noweb yes
+#+BEGIN_SRC d
+<<doc_header_including_copyright_and_license>>
+/++
+ sisudoc.ocda - canonical entry point of the document-abstraction
+ library.
+
+ Pipeline position: markup -> abstraction -> output. This package is
+ the abstraction stage; the output stage lives in
+ sisudoc.outputs.io_out and consumes the values produced here.
+
+ This file re-exports sisudoc.ocda.abstraction (the documented public
+ API surface) so that consumers can write
+ import sisudoc.ocda;
+ and reach the entry points (spineAbstraction!(), docAbstraction!(),
+ spineAbstractionTxt) without depending on spine's directory layout.
+
+ No logic lives here.
++/
+module sisudoc.ocda;
+@safe:
+public import sisudoc.ocda.abstraction;
+#+END_SRC
+
+*** ocda/abstraction package.d
+
+#+HEADER: :tangle "../src/sisudoc/ocda/abstraction/package.d"
+#+HEADER: :noweb yes
+#+BEGIN_SRC d
+<<doc_header_including_copyright_and_license>>
+/++
+ sisudoc.ocda.abstraction - public surface of the document-abstraction
+ library.
+
+ Pipeline position: markup -> abstraction -> output.
+ This package is the abstraction stage. The output stage lives in
+ sisudoc.outputs.io_out and consumes the values produced here.
+
+ Entry points:
+ - spineAbstraction!() (from sisudoc.ocda.meta.metadoc) - A-layer:
+ builds the in-memory document object model from a manifest
+ (pod path, .sst path). Reads the document body, parses YAML
+ headers, returns a struct with .abstraction (the object
+ model) and .matters (the conf/meta/src wrapper).
+ - docAbstraction!() (from sisudoc.ocda.meta.metadoc_from_src) -
+ B-layer: builds the abstraction from already-loaded body
+ text plus a pre-built ConfComposite. Pure, no file I/O.
+
+ The A-layer is a thin wrapper over the B-layer; consumers that
+ want a minimal-dependency entry should use docAbstraction!()
+ directly.
+
+ Serialisation:
+ - sisudoc.ocda.abstraction.ssp - PEG-parsable text serialisation of
+ the abstraction (the .ssp format). See specs/doc-abstraction-
+ format/ for the format reference.
+
+ This file is a re-export-only surface. No logic lives here; it
+ exists so external consumers can `import sisudoc.ocda.abstraction;` and
+ reach the entry points without depending on spine's directory
+ layout.
++/
+module sisudoc.ocda.abstraction;
+@safe:
+public import sisudoc.ocda.meta.metadoc; // spineAbstraction (A-layer)
+public import sisudoc.ocda.meta.metadoc_from_src; // docAbstraction (B-layer)
+public import sisudoc.ocda.abstraction.ssp; // spineAbstractionTxt (.ssp)
+#+END_SRC
+
** _module template_ :module:metadoc_from_src:
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc_from_src.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/metadoc_from_src.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
// document abstraction:
// abstraction of sisu markup for downstream processing
// metadoc_from_src.d
-module sisudoc.meta.metadoc_from_src;
+module sisudoc.ocda.meta.metadoc_from_src;
@safe:
template docAbstraction() {
<<docInitialize>>
@@ -59,12 +132,12 @@ import std.digest.sha;
import std.file;
import std.json;
import std.path;
-import sisudoc.meta;
-import sisudoc.meta.defaults;
-import sisudoc.meta.rgx;
-import sisudoc.meta.metadoc_object_setter;
-import sisudoc.meta.rgx;
-public import sisudoc.meta.metadoc_from_src_functions;
+import sisudoc.ocda.meta;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.meta.rgx;
+import sisudoc.ocda.meta.metadoc_object_setter;
+import sisudoc.ocda.meta.rgx;
+public import sisudoc.ocda.meta.metadoc_from_src_functions;
mixin docAbstractionFunctions;
#+END_SRC
diff --git a/org/ocda_functions.org b/org/ocda_functions.org
index 371b094..5970a06 100644
--- a/org/ocda_functions.org
+++ b/org/ocda_functions.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :noweb yes
-#+PROPERTY: header-args+ :exports code
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -22,14 +22,14 @@ Process markup document, create document abstraction.
** _module + templates_ :module:metadoc_from_src:
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc_from_src_functions.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/metadoc_from_src_functions.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
// document abstraction:
// abstraction of sisu markup for downstream processing
// metadoc_from_src.d
-module sisudoc.meta.metadoc_from_src_functions;
+module sisudoc.ocda.meta.metadoc_from_src_functions;
@safe:
template docAbstractionFunctions() {
<<docInitialize>>
@@ -1106,7 +1106,6 @@ ST_flow_table_array_munge flow_table_array_munge()(
#+NAME: ocdaFunc_block_line_empty
#+HEADER: :noweb yes
#+BEGIN_SRC d
-
@system ST_flow_block_flag_line_empty flow_block_flag_line_empty_(B,CMM,Ts)(
char[] line,
string[string] an_object,
diff --git a/org/ocda_obj_setter.org b/org/ocda_obj_setter.org
index 3da8b1d..3427c6b 100644
--- a/org/ocda_obj_setter.org
+++ b/org/ocda_obj_setter.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :noweb yes
-#+PROPERTY: header-args+ :exports code
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -23,7 +23,7 @@ set abstracted objects for downstream processing
** _module template_
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc_object_setter.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/metadoc_object_setter.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
@@ -32,7 +32,7 @@ set abstracted objects for downstream processing
setting of sisu objects for downstream processing
metadoc_object_setter.d
+/
-module sisudoc.meta.metadoc_object_setter;
+module sisudoc.ocda.meta.metadoc_object_setter;
@safe:
template ObjectSetter() {
/+ structs +/
diff --git a/org/out_curate_metadata.org b/org/out_curate_metadata.org
index eda8194..e2cec7a 100644
--- a/org/out_curate_metadata.org
+++ b/org/out_curate_metadata.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -26,11 +26,11 @@
** _module template_ metadoc curate
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc_curate.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/curate/metadoc_curate.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.meta.metadoc_curate;
+module sisudoc.outputs.io_out.curate.metadoc_curate;
@safe:
template spineMetaDocCurate() {
auto spineMetaDocCurate(T,H)(
@@ -50,8 +50,8 @@ template spineMetaDocCurate() {
#+NAME: metadoc_curate_imports
#+BEGIN_SRC d
-import sisudoc.meta.defaults;
-import sisudoc.meta.rgx;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.meta.rgx;
import std.array;
import std.exception;
import std.regex;
@@ -95,7 +95,7 @@ writefln(
#+NAME: meta_metadoc_curate
#+BEGIN_SRC d
-import sisudoc.io_out.paths_output;
+import sisudoc.outputs.io_out.paths_output;
auto pth_html_abs = spinePathsHTML!()(doc_matters.output_path, doc_matters.src.language);
auto pth_html_rel = spineDocRootTreeHTML!()(doc_matters.src.language);
hvst.curate.title = doc_matters.conf_make_meta.meta.title_full;
@@ -119,11 +119,11 @@ return hvst.curate;
** _module template_ metadoc curate topics
*** _module template_ metadoc curate topics template
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc_curate_topics.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/curate/metadoc_curate_topics.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.meta.metadoc_curate_topics;
+module sisudoc.outputs.io_out.curate.metadoc_curate_topics;
@safe:
import std.algorithm;
import std.array;
@@ -132,8 +132,8 @@ module sisudoc.meta.metadoc_curate_topics;
import std.stdio;
import std.string;
import std.conv : to;
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
mixin spineCurateMetadata;
mixin InternalMarkup;
template spineMetaDocCuratesTopics() {
@@ -447,7 +447,7 @@ foreach(k0;
#+NAME: curated_topics_html_write
#+BEGIN_SRC d
-import sisudoc.io_out.paths_output;
+import sisudoc.outputs.io_out.paths_output;
auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
try {
auto f = File(out_pth.curate("topics.html"), "w");
@@ -462,11 +462,11 @@ try {
** _module template_ metadoc curates authors
*** _module template_ metadoc curate authors
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc_curate_authors.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/curate/metadoc_curate_authors.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.meta.metadoc_curate_authors;
+module sisudoc.outputs.io_out.curate.metadoc_curate_authors;
@safe:
import std.algorithm;
import std.array;
@@ -475,8 +475,8 @@ module sisudoc.meta.metadoc_curate_authors;
import std.stdio;
import std.string;
import std.conv : to;
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
mixin spineCurateMetadata;
mixin InternalMarkup;
template spineMetaDocCuratesAuthors() {
@@ -608,7 +608,7 @@ template spineMetaDocCuratesAuthors() {
#+NAME: curated_authors_html_write
#+BEGIN_SRC d
-import sisudoc.io_out.paths_output;
+import sisudoc.outputs.io_out.paths_output;
auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
try {
auto f = File(out_pth.curate("authors.html"), "w");
diff --git a/org/out_latex.org b/org/out_latex.org
index bf80bac..88a409a 100644
--- a/org/out_latex.org
+++ b/org/out_latex.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./output_hub.org][output_hub]]
@@ -22,11 +22,11 @@
** _module template_ :latex:pdf:module:
*** latex.d module & templates
-#+HEADER: :tangle "../src/sisudoc/io_out/latex.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/latex.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.latex;
+module sisudoc.outputs.io_out.latex;
@safe:
<<Template_paper_latex>>
<<Template_output_latex>>
@@ -134,7 +134,7 @@ template outputLaTeX() {
#+HEADER: :noweb yes
#+BEGIN_SRC d
template outputLaTeXstyInit() {
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
auto paper = paperLaTeX;
<<Function_output_style_write>>
<<Function_output_stylesheets_get_each_written>>
@@ -218,7 +218,7 @@ void writeOutputLaTeX(T,M)(
}
}
if (!exists(pth_latex.latex_path_stuff ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_latex.latex_path_stuff ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -232,7 +232,7 @@ void writeOutputLaTeX(T,M)(
}
// should be in latex init and done just once, doc_matters not passed there though
if (!exists(pth_latex.base ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_latex.base ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -244,7 +244,7 @@ void writeOutputLaTeX(T,M)(
));
}
if (!exists(pth_latex.base_sty ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_latex.base_sty ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -403,14 +403,14 @@ void outputLaTeXstyInit()(
fonts to try:
#+BEGIN_SRC latex
-\usepackage[scaled]{dejavu}
+\usepackage{dejavu}
\renewcommand*\familydefault{\sfdefault}
\usepackage{inconsolata}
\usepackage[T1]{fontenc}
#+END_SRC
#+BEGIN_SRC latex
-\usepackage[scaled]{dejavu}
+\usepackage{dejavu}
\usepackage[scaled]{tgheros}
\usepackage[scaled]{quattrocento}
\usepackage[scaled]{cmbright}
@@ -431,7 +431,7 @@ fonts to try:
\usepackage{multicol}
\setlength{\marginparsep}{4mm}
\setlength{\marginparwidth}{8mm}
-\usepackage[scaled]{dejavu}
+\usepackage{dejavu}
\renewcommand*\familydefault{\sfdefault}
\usepackage{inconsolata}
\usepackage[T1]{fontenc}
@@ -595,8 +595,8 @@ fonts to try:
}
\newcommand{\spaces}[1]{{\hspace*{#1ex}}}
\newcommand{\s}{\hspace*{1ex}}
-\renewcommand{\hardspace}{\hspace*{1ex}}
-\newcommand{\-}{\hspace*{1ex}}
+\newcommand{\hardspace}{\hspace*{1ex}}
+\renewcommand{\-}{\hspace*{1ex}}
\newcommand{\caret}{{\^{~}}}
\newcommand{\pipe}{{\textbar}}
\newcommand{\curlyOpen}{{}
@@ -669,9 +669,9 @@ import std.file;
import std.outbuffer;
import std.uri;
import std.conv : to;
-import sisudoc.io_out;
-import sisudoc.io_out.rgx;
-import sisudoc.io_out.rgx_latex;
+import sisudoc.outputs.io_out;
+import sisudoc.outputs.io_out.rgx;
+import sisudoc.outputs.io_out.rgx_latex;
mixin spineRgxOut;
static auto rgx = RgxO();
mixin spineRgxLSC;
@@ -1465,7 +1465,7 @@ string bullets_and_indentation(O)(
\pagenumbering{alph}
\setcounter{page}{1}
\markboth{%s}{%s}
-\br\linebreak Copyright {\begin{small}{\copyright\end{small}} %s \br\linebreak
+\br\linebreak Copyright \begin{small}\copyright\end{small} %s \br\linebreak
%s
\clearpage┃";
_txt = format(_tex_para,
diff --git a/org/out_metadata.org b/org/out_metadata.org
index 92455a0..dcd7c51 100644
--- a/org/out_metadata.org
+++ b/org/out_metadata.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -21,11 +21,11 @@
** _module template_ metadoc document metadata
-#+HEADER: :tangle "../src/sisudoc/io_out/metadata.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/metadata.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.metadata;
+module sisudoc.outputs.io_out.metadata;
// @safe:
template outputMetadata() {
void outputMetadata(T)(T doc_matters) {
@@ -51,7 +51,7 @@ import std.digest.crc;
import std.digest.sha;
import std.file;
import std.format;
-import sisudoc.io_out;
+import sisudoc.outputs.io_out;
mixin InternalMarkup;
char[] metadata_;
#+END_SRC
@@ -61,7 +61,7 @@ char[] metadata_;
#+NAME: output_metadata
#+BEGIN_SRC d
static auto mkup = InlineMarkup();
-import sisudoc.io_out.html_snippet;
+import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
if (doc_matters.opt.action.debug_do) {
writeln(doc_matters.src.filename_base);
@@ -309,7 +309,7 @@ void metadata_write_output(M)(M doc_matters, char[] metadata_) {
}
}
if (!exists(pth_html.base ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_html.base ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
diff --git a/org/out_odt.org b/org/out_odt.org
index 916341e..25feda2 100644
--- a/org/out_odt.org
+++ b/org/out_odt.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./output_hub.org][output_hub]]
@@ -46,11 +46,11 @@
** _module template_ :odf:odt:module:
-#+HEADER: :tangle "../src/sisudoc/io_out/odt.d" :noweb yes
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/odt.d" :noweb yes
#+HEADER: :noweb yes
#+BEGIN_SRC org
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.odt;
+module sisudoc.outputs.io_out.odt;
@safe:
template formatODT() {
<<output_imports>>
@@ -105,7 +105,7 @@ template outputODT() {
<<output_odt_variable_content_xml_8>>
<<output_odt_variable_content_xml_9>>
<<output_odt_variable_content_xml_10>>
- <<output_odt_variable_content_xml_11>>
+ <<output_odt_variable_content_xml_11>>;
<<output_odt_variable_content_xml_12>>
<<output_odt_variable_content_xml_13>>
<<output_odt_variable_manifest_xml_0>>
@@ -974,7 +974,7 @@ string table(O,M)(
}
}
if (!exists(pth_odt.base_pth ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_odt.base_pth ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -993,7 +993,6 @@ string table(O,M)(
pth_odt.manifest_rdf("fs"); /+ (manifest.rdf) +/
pth_odt.settings_xml("fs"); /+ (settings.xml) +/
pth_odt.styles_xml("fs"); /+ (styles_xml) +/
-
pth_odt.content_xml("fs");
pth_odt.manifest_xml("fs");
pth_odt.meta_xml("fs");
@@ -1041,17 +1040,17 @@ void outputODT(D,I)(
#+NAME: output_imports
#+BEGIN_SRC d
-import sisudoc.io_out;
-import sisudoc.io_out.rgx;
-import sisudoc.io_out.rgx_xhtml;
+import sisudoc.outputs.io_out;
+import sisudoc.outputs.io_out.rgx;
+import sisudoc.outputs.io_out.rgx_xhtml;
import std.file;
import std.outbuffer;
import std.uri;
import std.zip;
import std.conv : to;
-import sisudoc.io_out.create_zip_file;
-import sisudoc.io_out.xmls;
-import sisudoc.io_out.xmls_css;
+import sisudoc.outputs.io_out.create_zip_file;
+import sisudoc.outputs.io_out.xmls;
+import sisudoc.outputs.io_out.xmls_css;
#+END_SRC
*** make directory tree
@@ -1061,7 +1060,7 @@ import sisudoc.io_out.xmls_css;
void dirtree(I)(
I doc_matters,
) {
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto pth_odt = spinePathsODT!()(doc_matters);
if (doc_matters.opt.action.debug_do) { /+ (dir tree) +/
if (!exists(pth_odt.meta_inf_dir("fs"))) {
@@ -1075,7 +1074,7 @@ void dirtree(I)(
pth_odt.base_pth.mkdirRecurse;
}
if (!exists(pth_odt.base_pth ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_odt.base_pth ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -2580,7 +2579,7 @@ void images_cp(M)(
auto ref M doc_matters,
) {
{ /+ (copy odt images) +/
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto pth_odt = spinePathsODT!()(doc_matters);
foreach (image; doc_matters.srcs.image_list) {
auto fn_src_in = doc_matters.src.image_dir_path ~ "/" ~ image;
diff --git a/org/out_skel.org b/org/out_skel.org
index be7a5b8..63ae481 100644
--- a/org/out_skel.org
+++ b/org/out_skel.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./output_hub.org][output_hub]]
@@ -21,11 +21,11 @@
* Skel
** outputSkel template
-#+HEADER: :tangle "../src/sisudoc/io_out/skel.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/skel.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.skel;
+module sisudoc.outputs.io_out.skel;
@safe:
template outputSkel() {
<<munge>>
@@ -35,7 +35,7 @@ template outputSkel() {
M doc_matters,
) {
import std.stdio;
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
<<skel_out>>
skel_out(doc_abstraction, doc_matters);
}
@@ -87,7 +87,7 @@ void skel_out(D,M)(
#+BEGIN_SRC d
template theDocument() {
import std.stdio;
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
<<skel_head>>
<<skel_body_assign_munge>>
<<skel_tail>>
diff --git a/org/out_sqlite.org b/org/out_sqlite.org
index 06d4a9f..fb19908 100644
--- a/org/out_sqlite.org
+++ b/org/out_sqlite.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./output_hub.org][output_hub]]
@@ -41,11 +41,11 @@ sudo chown ralph:ralph /var/www
** _module, templates_ :module:
*** template
-#+HEADER: :tangle "../src/sisudoc/io_out/sqlite.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/sqlite.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.sqlite;
+module sisudoc.outputs.io_out.sqlite;
<<sqlite_imports>>
<<sqlite_common>>
<<sqlite_collection>>
@@ -87,7 +87,12 @@ template SQLiteHubBuildTablesAndPopulate() {
} else {
try {
pth_sqlite.base.mkdirRecurse;
- } catch (FileException ex) { }
+ } catch (FileException ex) {
+ stderr.writeln("FATAL: cannot create --sqlite-db-path directory: ", pth_sqlite.base);
+ stderr.writeln(" (", ex.msg, ")");
+ import core.runtime;
+ core.runtime.Runtime.terminate();
+ }
}
template SQLiteDbStatementComposite() {
void SQLiteDbStatementComposite(Db,D)(
@@ -144,7 +149,12 @@ template SQLiteHubDiscreteBuildTablesAndPopulate() {
} else {
try {
pth_sqlite.base.mkdirRecurse;
- } catch (FileException ex) { }
+ } catch (FileException ex) {
+ stderr.writeln("FATAL: cannot create --sqlite-db-path directory: ", pth_sqlite.base);
+ stderr.writeln(" (", ex.msg, ")");
+ import core.runtime;
+ core.runtime.Runtime.terminate();
+ }
}
auto db = Database(pth_sqlite.sqlite_file(doc.matters.src.filename));
template SQLiteDiscreteDbStatementComposite() {
@@ -449,7 +459,12 @@ if (opt_action.sqlite_db_create) {
} else {
try {
pth_sqlite.base.mkdirRecurse;
- } catch (FileException ex) { }
+ } catch (FileException ex) {
+ stderr.writeln("FATAL: cannot create --sqlite-db-path directory: ", pth_sqlite.base);
+ stderr.writeln(" (", ex.msg, ")");
+ import core.runtime;
+ core.runtime.Runtime.terminate();
+ }
}
auto db = Database(pth_sqlite.sqlite_file);
{
@@ -512,7 +527,12 @@ if ((doc.matters.opt.action.sqlite_db_create)) {
} else {
try {
pth_sqlite.base.mkdirRecurse;
- } catch (FileException ex) { }
+ } catch (FileException ex) {
+ stderr.writeln("FATAL: cannot create --sqlite-db-path directory: ", pth_sqlite.base);
+ stderr.writeln(" (", ex.msg, ")");
+ import core.runtime;
+ core.runtime.Runtime.terminate();
+ }
}
_db_statement ~= SQLiteTablesReCreate!()();
SQLiteDbRun!()(db, _db_statement, doc.matters.opt.action, "TABLE RE-CREATE");
@@ -560,9 +580,9 @@ db.close;
#+NAME: sqlite_imports
#+BEGIN_SRC d
-import sisudoc.io_out;
-import sisudoc.io_out.rgx;
-import sisudoc.io_out.rgx_xhtml;
+import sisudoc.outputs.io_out;
+import sisudoc.outputs.io_out.rgx;
+import sisudoc.outputs.io_out.rgx_xhtml;
import std.file;
import std.uri;
// import std.digest.sha;
diff --git a/org/out_src_abstraction_peg_text.org b/org/out_src_abstraction_ocda_ssp.org
index 7b7b600..d44db04 100644
--- a/org/out_src_abstraction_peg_text.org
+++ b/org/out_src_abstraction_ocda_ssp.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -25,11 +25,11 @@
rename source_abstraction_peg_txt.d
-#+HEADER: :tangle "../src/sisudoc/io_out/create_abstraction_txt.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/abstraction/ssp.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.create_abstraction_txt;
+module sisudoc.ocda.abstraction.ssp;
@safe:
/+ ↓ write document abstraction as human-readable .ssp text file +/
@@ -41,7 +41,6 @@ template spineAbstractionTxt() {
import std.stdio;
import std.string;
import std.array;
- import sisudoc.io_out.paths_output;
void spineAbstractionTxt(D)(D doc) {
auto doc_abstraction = doc.abstraction;
@@ -390,9 +389,12 @@ template spineAbstractionTxt() {
}
/+ ↓ write to file +/
- auto out_pth = spineOutPaths!()(doc_matters.output_path, doc_matters.src.language);
- string base_dir = "abstraction";
- string base_pth = ((out_pth.output_base.chainPath(base_dir)).asNormalizedPath).array;
+ /+ path: <output_path>/<language>/abstraction/<doc_uid_out>.ssp +/
+ string out_root = (doc_matters.output_path.length > 0)
+ ? doc_matters.output_path : "";
+ string base_pth = (out_root
+ .chainPath(doc_matters.src.language, "abstraction")
+ .asNormalizedPath).array;
try {
if (!exists(base_pth)) {
base_pth.mkdirRecurse;
diff --git a/org/out_src_abstraction_sqlite_db.org b/org/out_src_abstraction_sqlite_db.org
index a048934..daf4fb0 100644
--- a/org/out_src_abstraction_sqlite_db.org
+++ b/org/out_src_abstraction_sqlite_db.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -25,11 +25,11 @@
rename source_abstraction_peg_txt.d
-#+HEADER: :tangle "../src/sisudoc/io_out/create_abstraction_db.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/create_abstraction_db.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.create_abstraction_db;
+module sisudoc.outputs.io_out.create_abstraction_db;
/+ ↓ write document abstraction as per-document sqlite3 database +/
template spineAbstractionDb() {
@@ -40,7 +40,7 @@ template spineAbstractionDb() {
import std.string;
import std.array;
import d2sqlite3;
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
void spineAbstractionDb(D)(D doc) {
auto doc_abstraction = doc.abstraction;
diff --git a/org/out_src_pod.org b/org/out_src_pod.org
index e1076c2..678d5ac 100644
--- a/org/out_src_pod.org
+++ b/org/out_src_pod.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./output_hub.org][output_hub]]
@@ -21,11 +21,11 @@
* pod
** _module template_ :module:
-#+HEADER: :tangle "../src/sisudoc/io_out/source_pod.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/source_pod.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.source_pod;
+module sisudoc.outputs.io_out.source_pod;
@system: // is not @safe: use: @system: or @trusted:
template spinePod() {
<<output_imports>>
@@ -83,10 +83,10 @@ import std.file;
import std.outbuffer;
import std.zip;
import std.conv : to;
-import sisudoc.meta.rgx_files;
-import sisudoc.io_out;
-import sisudoc.io_out.create_zip_file;
-import sisudoc.io_out.xmls;
+import sisudoc.ocda.meta.rgx_files;
+import sisudoc.outputs.io_out;
+import sisudoc.outputs.io_out.create_zip_file;
+import sisudoc.outputs.io_out.xmls;
#+END_SRC
*** init
@@ -156,29 +156,38 @@ auto pod_zipMakeReady(M,P,S)(M doc_matters, P pths_pod, S _st) {
}
} { // bundle abstraction .ssp file (only for --pod2)
if (doc_matters.opt.action.pod2) {
- import sisudoc.io_out.paths_output;
- auto out_pth = spineOutPaths!()(doc_matters.output_path, doc_matters.src.language);
- string abstraction_dir = ((out_pth.output_base.chainPath("abstraction")).asNormalizedPath).array;
- string ssp_filename = doc_matters.src.doc_uid_out ~ ".ssp";
- string fn_src_in = ((abstraction_dir.chainPath(ssp_filename)).asNormalizedPath).array.to!string;
- auto fn_src_out_pod_zip_base
- = pths_pod.abstraction_root(doc_matters.src.filename).zpod.to!string
- ~ "/" ~ ssp_filename;
- auto fn_src_out_filesystem
- = pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod.to!string
- ~ "/" ~ ssp_filename;
- if (exists(fn_src_in)) {
- debug(io) { writeln("(io debug) src out found: ", fn_src_in); }
- { // take DIGEST write to pod file digests.txt
- auto data = (cast(byte[]) (fn_src_in).read);
- _digests[doc_matters.src.language]["ssp"] ~= data.sha256Of.toHexString
- ~ "::" ~ data.length.to!string ~ " - " ~ ssp_filename ~ "\n";
- }
- fn_src_in.copy(fn_src_out_filesystem);
- zip = podArchive("file_path_text", fn_src_in, fn_src_out_pod_zip_base, zip);
- } else {
- if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt_2) {
- writeln("WARNING (io) src out NOT found (abstraction): ", fn_src_in);
+ if (doc_matters.src.language == doc_matters.pod.manifest_list_of_languages[$-1]) { // wait until all language versions of .ssp generated
+ import sisudoc.outputs.io_out.paths_output;
+ /+ doc_uid_out for any language follows the same pattern, differing
+ only in the trailing ".{lng}". Strip the current language to
+ reuse the base across all languages. +/
+ string _doc_uid_base
+ = doc_matters.src.doc_uid_out[0 .. $ - doc_matters.src.lng.length];
+ foreach (_lang; doc_matters.pod.manifest_list_of_languages) { // do for all language versions
+ auto out_pth_lng = spineOutPaths!()(doc_matters.output_path, _lang);
+ string abstraction_dir = ((out_pth_lng.output_base.chainPath("abstraction")).asNormalizedPath).array;
+ string ssp_filename = _doc_uid_base ~ _lang ~ ".ssp";
+ string fn_src_in = ((abstraction_dir.chainPath(ssp_filename)).asNormalizedPath).array.to!string;
+ auto fn_src_out_pod_zip_base
+ = pths_pod.abstraction_root(doc_matters.src.filename).zpod.to!string
+ ~ "/" ~ ssp_filename;
+ auto fn_src_out_filesystem
+ = pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod.to!string
+ ~ "/" ~ ssp_filename;
+ if (exists(fn_src_in)) {
+ debug(io) { writeln("(io debug) src out found: ", fn_src_in); }
+ { // take DIGEST write to pod file digests.txt
+ auto data = (cast(byte[]) (fn_src_in).read);
+ _digests[_lang]["ssp"] ~= data.sha256Of.toHexString
+ ~ "::" ~ data.length.to!string ~ " - " ~ ssp_filename ~ "\n";
+ }
+ fn_src_in.copy(fn_src_out_filesystem);
+ zip = podArchive("file_path_text", fn_src_in, fn_src_out_pod_zip_base, zip);
+ } else {
+ if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt_2) {
+ writeln("WARNING (io) src out NOT found (abstraction): ", fn_src_in);
+ }
+ }
}
}
}
@@ -438,7 +447,7 @@ void podArchive_directory_tree(M,P)(M doc_matters, P pths_pod) { // create direc
}
}
if (!exists(pths_pod.pod_dir_() ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pths_pod.pod_dir_() ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -507,7 +516,7 @@ void zipArchive(M,F,Z)(M doc_matters, F fn_pod, Z zip) {
#+NAME: pod_source_files_digests
#+BEGIN_SRC d
void zipArchiveDigest(M,F,D)(M doc_matters, F fn_pod, D _digests) {
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto pths_pod = spinePathsPods!()(doc_matters);
char[] _zip_digest;
try {
diff --git a/org/out_text.org b/org/out_text.org
index a441276..5d0e77d 100644
--- a/org/out_text.org
+++ b/org/out_text.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./output_hub.org][output_hub]]
@@ -21,11 +21,11 @@
* Text
** outputText template
-#+HEADER: :tangle "../src/sisudoc/io_out/text.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/text.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.text;
+module sisudoc.outputs.io_out.text;
@safe:
template outputText() {
<<munge>>
@@ -35,7 +35,7 @@ template outputText() {
M doc_matters,
) {
import std.stdio;
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
<<text_out>>
text_out(doc_abstraction, doc_matters);
}
@@ -87,7 +87,7 @@ void text_out(D,M)(
#+BEGIN_SRC d
template theDocument() {
import std.stdio;
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
<<text_head>>
<<text_body_assign_munge>>
<<text_tail>>
@@ -197,8 +197,8 @@ string text_tail(M)(
#+HEADER: :noweb yes
#+BEGIN_SRC d
template munge() {
- import sisudoc.io_out;
- import sisudoc.io_out.rgx;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.rgx;
import std.stdio;
import std.conv;
import std.conv : to;
@@ -562,4 +562,3 @@ DONE
- blurb
- inline_link /[┥┝┤├]
#+END_SRC
-
diff --git a/org/out_xmls.org b/org/out_xmls.org
index 976b7c1..36d4b78 100644
--- a/org/out_xmls.org
+++ b/org/out_xmls.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./output_hub.org][output_hub]]
@@ -22,11 +22,11 @@
** format xhtml objects :format:
*** _module template_ :module:
-#+HEADER: :tangle "../src/sisudoc/io_out/xmls.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/xmls.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.xmls;
+module sisudoc.outputs.io_out.xmls;
@safe:
template outputXHTMLs() {
<<output_imports_xml>>
@@ -90,13 +90,13 @@ import std.file;
import std.outbuffer;
import std.uri;
import std.conv : to;
-import sisudoc.io_out;
-import sisudoc.io_out.rgx;
-import sisudoc.meta.rgx_files;
-import sisudoc.io_out.rgx_xhtml;
-import sisudoc.io_out.create_zip_file;
-import sisudoc.io_out.xmls;
-import sisudoc.io_out.xmls_css;
+import sisudoc.outputs.io_out;
+import sisudoc.outputs.io_out.rgx;
+import sisudoc.ocda.meta.rgx_files;
+import sisudoc.outputs.io_out.rgx_xhtml;
+import sisudoc.outputs.io_out.create_zip_file;
+import sisudoc.outputs.io_out.xmls;
+import sisudoc.outputs.io_out.xmls_css;
#+END_SRC
**** epub3
@@ -108,12 +108,12 @@ import std.outbuffer;
import std.uri;
import std.zip;
import std.conv : to;
-import sisudoc.io_out;
-import sisudoc.io_out.rgx;
-import sisudoc.io_out.rgx_xhtml;
-import sisudoc.io_out.create_zip_file;
-import sisudoc.io_out.xmls;
-import sisudoc.io_out.xmls_css;
+import sisudoc.outputs.io_out;
+import sisudoc.outputs.io_out.rgx;
+import sisudoc.outputs.io_out.rgx_xhtml;
+import sisudoc.outputs.io_out.create_zip_file;
+import sisudoc.outputs.io_out.xmls;
+import sisudoc.outputs.io_out.xmls_css;
#+END_SRC
*** misc
@@ -1748,11 +1748,11 @@ string table(O,M)(
* _html_ [#A] :html:
** _module template_ :module:
-#+HEADER: :tangle "../src/sisudoc/io_out/html.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/html.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.html;
+module sisudoc.outputs.io_out.html;
@safe:
template outputHTML() {
<<output_imports_xml>>
@@ -2007,7 +2007,7 @@ scroll_write_output(doc_out, doc.matters);
}
}
if (!exists(pth_html.base ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_html.base ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -2381,7 +2381,7 @@ void css(M)(M doc_matters) {
f.writeln(css.html_scroll);
}
if (!exists(pth_html.css ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_html.css ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -2423,7 +2423,7 @@ void css(M)(M doc_matters) {
}
}
if (!exists(pth_html.image ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_html.image ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -2458,11 +2458,11 @@ void css(M)(M doc_matters) {
** _module template_ :module:
-#+HEADER: :tangle "../src/sisudoc/io_out/epub3.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/epub3.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.epub3;
+module sisudoc.outputs.io_out.epub3;
@safe:
template outputEPub3() {
<<output_imports_epub>>
@@ -3163,7 +3163,7 @@ zip -0 file.epub mimetype && zip -r -9 file.epub META-INF OEBPS
pth_epub3.base.mkdirRecurse;
}
if (!exists(pth_epub3.base ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_epub3.base ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
diff --git a/org/out_xmls_css.org b/org/out_xmls_css.org
index 95c5145..3a55def 100644
--- a/org/out_xmls_css.org
+++ b/org/out_xmls_css.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./output_hub.org][output_hub]]
@@ -21,14 +21,14 @@
* output css defaults :module:spine:output_xmls_css:
** _module template_
-#+HEADER: :tangle "../src/sisudoc/io_out/xmls_css.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/xmls_css.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
/++
default css settings
+/
-module sisudoc.io_out.xmls_css;
+module sisudoc.outputs.io_out.xmls_css;
@safe:
template spineCss() {
import std.format;
@@ -50,6 +50,7 @@ template spineCss() {
<<css_light_html_seg_previous_next>>
<<css_light_html_seg_flex>>
<<css_light_html_seg_grid>>
+<<css_homepage_extra>>
┃",
_color_ocn_light,
_css_indent,
@@ -70,6 +71,7 @@ template spineCss() {
<<css_dark_html_seg_previous_next>>
<<css_dark_html_seg_flex>>
<<css_dark_html_seg_grid>>
+<<css_homepage_extra>>
┃",
_color_ocn_dark,
_css_indent,
@@ -89,6 +91,7 @@ template spineCss() {
<<css_shared_search_form>>
<<css_light_html_scroll_flex>>
<<css_light_html_scroll_grid>>
+<<css_homepage_extra>>
┃",
_color_ocn_light,
_css_indent,
@@ -108,6 +111,7 @@ template spineCss() {
<<css_shared_search_form>>
<<css_dark_html_scroll_flex>>
<<css_dark_html_scroll_grid>>
+<<css_homepage_extra>>
┃",
_color_ocn_dark,
_css_indent,
@@ -2502,6 +2506,62 @@ p[indent="h9i9"] {
┃");
#+END_SRC
+*** homepage extra
+
+#+NAME: css_homepage_extra
+#+BEGIN_SRC css
+/* ------------------------------------------------------------------ */
+/* Homepage / body-flow HTML5 markup */
+/* <ul>/<li> and <details>/<summary> aligned with <p> and headings. */
+/* Scoped to direct body children to avoid affecting div.toc lists. */
+/* ------------------------------------------------------------------ */
+body > ul,
+body > ol {
+ margin-left : 5%%;
+ margin-right : 2em;
+ margin-top : 0.8em;
+ margin-bottom : 0.8em;
+ padding-left : 1.5em;
+ list-style-position : outside;
+}
+body > ul { list-style-type : disc; }
+body > ol { list-style-type : decimal; }
+body > ul li,
+body > ol li {
+ margin-left : 0;
+ margin-right : 0;
+ margin-top : 0.3em;
+ margin-bottom : 0.3em;
+ line-height : 133%%;
+ background : none;
+ text-align : left;
+ text-indent : 0;
+}
+details {
+ margin-top : 1em;
+ margin-bottom : 0.5em;
+}
+summary {
+ margin-left : 5%%;
+ margin-right : 2em;
+ padding-left : 0.2em;
+ padding-top : 0.4em;
+ padding-bottom : 0.4em;
+ font-size : 1.6rem;
+ line-height : 133%%;
+ cursor : pointer;
+}
+details > ul,
+details > ol {
+ margin-left : 5%%;
+ padding-left : 1.5em;
+}
+details > ul li,
+details > ol li {
+ margin-left : 0;
+}
+#+END_SRC
+
* org includes
** year
diff --git a/org/out_zip.org b/org/out_zip.org
index a3204ed..7cde8a7 100644
--- a/org/out_zip.org
+++ b/org/out_zip.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./output_hub.org][output_hub]]
@@ -21,11 +21,11 @@
* _zip_ :module:spine:create_zip_file:
** module template
-#+HEADER: :tangle "../src/sisudoc/io_out/create_zip_file.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/create_zip_file.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.io_out.create_zip_file;
+module sisudoc.outputs.io_out.create_zip_file;
@safe:
template createZipFile() {
import std.file;
diff --git a/org/output_hub.org b/org/output_hub.org
index dde92d8..88e28c1 100644
--- a/org/output_hub.org
+++ b/org/output_hub.org
@@ -7,20 +7,20 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
* output hub [#A]
** _module template_ :module:
-#+HEADER: :tangle "../src/sisudoc/io_out/hub.d"
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/hub.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
@@ -28,7 +28,7 @@
output hub<BR>
check & generate output types requested
+/
-module sisudoc.io_out.hub;
+module sisudoc.outputs.io_out.hub;
@safe:
template outputHub() {
<<output_imports>>
@@ -66,9 +66,9 @@ template outputHub() {
}
template outputHubInitialize() {
import std.file;
- import sisudoc.io_out,
- sisudoc.io_out.metadata,
- sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.metadata;
+ import sisudoc.outputs.io_out.paths_output;
string _bespoke_homepage = "./spine-bespoke-output/html/homepage.index.html";
@system void outputHubInitialize(O,I)(
O opt_action,
@@ -93,7 +93,7 @@ template outputHubInitialize() {
&& opt_action.output_dir_set.length > 0
&& !(isValidPath(opt_action.output_dir_set ~ "/latex/sty")))
) { // .sty need to be produced only once (if unchanged per output-dir of which there usually will be only one)
- import sisudoc.io_out.latex;
+ import sisudoc.outputs.io_out.latex;
outputLaTeXstyInit!()(
opt_action.output_dir_set,
opt_action.generated_by,
@@ -117,11 +117,11 @@ template outputHubOp() {
#+NAME: output_imports
#+BEGIN_SRC d
-import sisudoc.io_out,
- sisudoc.io_out.metadata,
- sisudoc.io_out.xmls,
- sisudoc.io_out.create_zip_file,
- sisudoc.io_out.paths_output;
+import sisudoc.outputs.io_out;
+import sisudoc.outputs.io_out.metadata;
+import sisudoc.outputs.io_out.xmls;
+import sisudoc.outputs.io_out.create_zip_file;
+import sisudoc.outputs.io_out.paths_output;
#+END_SRC
** outputs
@@ -134,7 +134,7 @@ import sisudoc.io_out,
if (sched == outTask.source_or_pod) {
msg.v("spine (doc reform) source processing... ");
if (doc.matters.opt.action.pod) { msg.v("spine (doc reform) source pod processing... "); }
- import sisudoc.io_out.source_pod;
+ import sisudoc.outputs.io_out.source_pod;
spinePod!()(doc.matters);
if (doc.matters.opt.action.source) { msg.vv("spine (doc reform) source done"); }
if (doc.matters.opt.action.pod) { msg.vv("spine (doc reform) source pod done"); }
@@ -147,7 +147,7 @@ if (sched == outTask.source_or_pod) {
#+BEGIN_SRC d
if (sched == outTask.epub) {
msg.v("epub3 processing... ");
- import sisudoc.io_out.epub3;
+ import sisudoc.outputs.io_out.epub3;
doc.outputEPub3!();
msg.vv("epub3 done");
}
@@ -170,7 +170,7 @@ if (sched == outTask.html_stuff) {
#+BEGIN_SRC d
if (sched == outTask.html_scroll) {
msg.v("html scroll processing... ");
- import sisudoc.io_out.html;
+ import sisudoc.outputs.io_out.html;
outputHTML!().scroll(doc);
msg.vv("html scroll done");
}
@@ -182,7 +182,7 @@ if (sched == outTask.html_scroll) {
#+BEGIN_SRC d
if (sched == outTask.html_seg) {
msg.v("html seg processing... ");
- import sisudoc.io_out.html;
+ import sisudoc.outputs.io_out.html;
outputHTML!().seg(doc);
msg.vv("html seg done");
}
@@ -193,7 +193,7 @@ if (sched == outTask.html_seg) {
#+NAME: output_scheduled_task_html_out
#+BEGIN_SRC d
if (sched == outTask.html_stuff) {
- import sisudoc.io_out.html;
+ import sisudoc.outputs.io_out.html;
outputHTML!().css(doc.matters);
outputHTML!().images_cp(doc.matters);
msg.vv("html css & images done");
@@ -215,7 +215,7 @@ if (sched == outTask.html_stuff) {
#+BEGIN_SRC d
if (sched == outTask.latex) {
msg.v("latex processing... (available for downstream processing & pdf output");
- import sisudoc.io_out.latex;
+ import sisudoc.outputs.io_out.latex;
import std.file;
if ((isValidPath(doc.matters.output_path ~ "/latex/sty"))
&& (!(exists(doc.matters.output_path ~ "/latex/sty")))
@@ -238,7 +238,7 @@ if (sched == outTask.latex) {
#+BEGIN_SRC d
if (sched == outTask.text) {
msg.v("text processing... ");
- import sisudoc.io_out.text;
+ import sisudoc.outputs.io_out.text;
outputText!()(doc.abstraction, doc.matters);
msg.vv("text done");
}
@@ -250,7 +250,7 @@ if (sched == outTask.text) {
#+BEGIN_SRC d
if (sched == outTask.odt) {
msg.v("odf:odt processing... ");
- import sisudoc.io_out.odt;
+ import sisudoc.outputs.io_out.odt;
outputODT!()(doc.abstraction, doc.matters);
msg.vv("odf:odt done");
}
@@ -262,7 +262,7 @@ if (sched == outTask.odt) {
#+BEGIN_SRC d
if (sched == outTask.skel) {
msg.v("skel processing... ");
- import sisudoc.io_out.skel;
+ import sisudoc.outputs.io_out.skel;
outputSkel!()(doc.abstraction, doc.matters);
msg.vv("skel done");
}
@@ -274,7 +274,7 @@ if (sched == outTask.skel) {
#+BEGIN_SRC d
if (sched == outTask.sqlite) {
msg.v("sqlite processing... ");
- import sisudoc.io_out.sqlite;
+ import sisudoc.outputs.io_out.sqlite;
doc.SQLiteHubDiscreteBuildTablesAndPopulate!();
msg.vv("sqlite done");
}
@@ -288,12 +288,12 @@ if (sched == outTask.sqlite) {
#+BEGIN_SRC d
if (doc.matters.opt.action.sqlite_update) {
msg.v("sqlite update processing...");
- import sisudoc.io_out.sqlite;
+ import sisudoc.outputs.io_out.sqlite;
doc.SQLiteHubBuildTablesAndPopulate!();
msg.vv("sqlite update done");
} else if (doc.matters.opt.action.sqlite_delete) {
msg.v("sqlite delete processing...");
- import sisudoc.io_out.sqlite;
+ import sisudoc.outputs.io_out.sqlite;
doc.SQLiteHubBuildTablesAndPopulate!();
msg.vv("sqlite delete done");
}
@@ -308,7 +308,7 @@ if ((opt_action.sqlite_db_drop)) {
if ((opt_action.vox_gt_2)) {
writeln("sqlite drop db...");
}
- import sisudoc.io_out.sqlite;
+ import sisudoc.outputs.io_out.sqlite;
SQLiteDbDrop!()(opt_action, config);
if ((opt_action.vox_gt_3)) {
writeln("sqlite drop db done");
@@ -325,7 +325,7 @@ if ((opt_action.sqlite_db_create)) {
auto pth_sqlite_db = spinePathsSQLite!()(opt_action.cgi_sqlite_search_filename, opt_action.output_dir_set);
writeln("sqlite create table...");
}
- import sisudoc.io_out.sqlite;
+ import sisudoc.outputs.io_out.sqlite;
SQLiteTablesCreate!()(env, opt_action, config);
if ((opt_action.vox_gt_3)) {
writeln("sqlite create table done");
diff --git a/org/output_show.org b/org/output_show.org
index f3b1dcb..eb881f1 100644
--- a/org/output_show.org
+++ b/org/output_show.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -21,11 +21,11 @@
** _module template_ metadoc summary
- document summary from abstraction
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc_show_summary.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/metadoc_show_summary.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.meta.metadoc_show_summary;
+module sisudoc.ocda.meta.metadoc_show_summary;
@safe:
template spineMetaDocSummary() {
void spineMetaDocSummary(D)(D doc) {
@@ -143,7 +143,7 @@ writefln(
** _module template_ show config
*** _show config tangle
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc_show_config.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/metadoc_show_config.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
@@ -157,7 +157,7 @@ writefln(
#+NAME: spine_show_site_config
#+HEADER: :noweb yes
#+BEGIN_SRC d
-module sisudoc.meta.metadoc_show_config;
+module sisudoc.ocda.meta.metadoc_show_config;
@safe:
template spineShowSiteConfig() {
void spineShowSiteConfig(O,T)(
@@ -337,11 +337,11 @@ writefln(
** _module template_ show make
--show-make (show document make)
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc_show_make.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/metadoc_show_make.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.meta.metadoc_show_make;
+module sisudoc.ocda.meta.metadoc_show_make;
@safe:
template spineShowMake() {
void spineShowMake(T)(T doc_matters) {
@@ -409,11 +409,11 @@ writefln(
** _module template_ show metadata
--show-metadata (show document metadata)
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc_show_metadata.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/metadoc_show_metadata.d"
#+HEADER: :noweb yes
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.meta.metadoc_show_metadata;
+module sisudoc.ocda.meta.metadoc_show_metadata;
@safe:
template spineShowMetaData() {
void spineShowMetaData(T)(T doc_matters) {
@@ -549,8 +549,8 @@ import std.conv : to;
#+NAME: metadoc_show_summary_imports
#+BEGIN_SRC d
-import sisudoc.meta.defaults;
-import sisudoc.meta.rgx;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.meta.rgx;
#+END_SRC
*** initialize :report:
diff --git a/org/sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org b/org/sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org
index 8473590..dc3c339 100644
--- a/org/sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org
+++ b/org/sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :noweb yes
-#+PROPERTY: header-args+ :exports code
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -98,7 +98,7 @@
#+NAME: spine_project_version_part_minor
#+BEGIN_SRC org
-19
+22
#+END_SRC
*** patch
diff --git a/org/spine.org b/org/spine.org
index e140bd2..6d67e3b 100644
--- a/org/spine.org
+++ b/org/spine.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./spine_build_scaffold.org][make/build]] VERSION
@@ -105,7 +105,7 @@ string program_name = "spine";
spineMetaDocCuratesAuthors!()(hvst.curates, _make_and_meta_struct, _opt_action);
}
if (_opt_action.vox_gt_1) {
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
if (_opt_action.curate_authors) {
writeln("- ", out_pth.curate("authors.html"));
@@ -139,25 +139,25 @@ import std.getopt;
import std.file;
import std.path;
import std.process;
-import sisudoc.conf.compile_time_info;
-import sisudoc.meta;
-import sisudoc.meta.metadoc;
-import sisudoc.meta.metadoc_curate;
-import sisudoc.meta.metadoc_curate_authors;
-import sisudoc.meta.metadoc_curate_topics;
-import sisudoc.meta.metadoc_from_src;
-import sisudoc.meta.conf_make_meta_structs;
-import sisudoc.meta.conf_make_meta_json;
-import sisudoc.meta.defaults;
-import sisudoc.meta.doc_debugs;
-import sisudoc.meta.rgx;
-import sisudoc.meta.rgx_yaml;
-import sisudoc.meta.rgx_files;
-import sisudoc.io_in.paths_source;
-import sisudoc.io_in.read_config_files;
-import sisudoc.io_in.read_source_files;
-import sisudoc.io_in.read_zip_pod;
-import sisudoc.io_out.hub;
+import sisudoc.outputs.conf.compile_time_info;
+import sisudoc.ocda.meta;
+import sisudoc.ocda.meta.metadoc;
+import sisudoc.outputs.io_out.curate.metadoc_curate;
+import sisudoc.outputs.io_out.curate.metadoc_curate_authors;
+import sisudoc.outputs.io_out.curate.metadoc_curate_topics;
+import sisudoc.ocda.meta.metadoc_from_src;
+import sisudoc.ocda.meta.conf_make_meta_structs;
+import sisudoc.ocda.meta.conf_make_meta_json;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.meta.doc_debugs;
+import sisudoc.ocda.meta.rgx;
+import sisudoc.ocda.meta.rgx_yaml;
+import sisudoc.ocda.meta.rgx_files;
+import sisudoc.ocda.io_in.paths_source;
+import sisudoc.ocda.io_in.read_config_files;
+import sisudoc.ocda.io_in.read_source_files;
+import sisudoc.ocda.io_in.read_zip_pod;
+import sisudoc.outputs.io_out.hub;
#+END_SRC
***** spine metadoc :spine:
@@ -167,15 +167,14 @@ import sisudoc.io_out.hub;
import std.datetime;
import std.digest.crc;
import std.digest.sha;
-import sisudoc.meta;
-import sisudoc.meta.metadoc_from_src;
-import sisudoc.meta.conf_make_meta_structs;
-import sisudoc.meta.conf_make_meta_json;
-import sisudoc.meta.defaults;
-import sisudoc.io_in.paths_source;
-import sisudoc.io_in.read_config_files;
-import sisudoc.io_in.read_source_files;
-import sisudoc.io_out.hub;
+import sisudoc.ocda.meta;
+import sisudoc.ocda.meta.metadoc_from_src;
+import sisudoc.ocda.meta.conf_make_meta_structs;
+import sisudoc.ocda.meta.conf_make_meta_json;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.io_in.paths_source;
+import sisudoc.ocda.io_in.read_config_files;
+import sisudoc.ocda.io_in.read_source_files;
#+END_SRC
****** notes
@@ -236,7 +235,6 @@ mixin outputHub;
#+NAME: spine_metadoc_mixin
#+BEGIN_SRC d
mixin spineBiblio;
-mixin outputHub;
#+END_SRC
**** init :init:
@@ -1129,7 +1127,7 @@ if (
{ /+ local site config +/
_conf_file_details = configFilePaths!()(_manifested, _env, _opt_action.config_path_set);
auto _config_local_site_struct = readConfigSite!()(_conf_file_details, _opt_action, _cfg);
- import sisudoc.meta.conf_make_meta_yaml;
+ import sisudoc.ocda.meta.conf_make_meta_yaml;
_siteConfig = _config_local_site_struct.configParseYAMLreturnSpineStruct!()(_siteConfig, _manifested, _opt_action, _cfg); // - get local site config
break;
}
@@ -1137,11 +1135,11 @@ if (
}
} else { /+ local site config +/
auto _config_local_site_struct = readConfigSite!()(_conf_file_details, _opt_action, _cfg);
- import sisudoc.meta.conf_make_meta_yaml;
+ import sisudoc.ocda.meta.conf_make_meta_yaml;
_siteConfig = _config_local_site_struct.configParseYAMLreturnSpineStruct!()(_siteConfig, _manifested, _opt_action, _cfg); // - get local site config
}
if (_opt_action.show_config) {
- import sisudoc.meta.metadoc_show_config;
+ import sisudoc.ocda.meta.metadoc_show_config;
spineShowSiteConfig!()(_opt_action, _siteConfig);
}
#+END_SRC
@@ -1494,7 +1492,7 @@ foreach(arg; _resolved_args) {
#+BEGIN_SRC d
{ /+ document config/make file +/
auto _config_document_struct = readConfigDoc!()(_manifest, _env);
- import sisudoc.meta.conf_make_meta_yaml;
+ import sisudoc.ocda.meta.conf_make_meta_yaml;
_make_and_meta_struct = _config_document_struct.configParseYAMLreturnSpineStruct!()(_make_and_meta_struct, _manifest, _opt_action, _cfg);
}
#+END_SRC
@@ -1568,7 +1566,7 @@ if ((doc.matters.opt.action.debug_do)
#+BEGIN_SRC d
/+ ↓ debugs +/
if (doc.matters.opt.action.show_summary) {
- import sisudoc.meta.metadoc_show_summary;
+ import sisudoc.ocda.meta.metadoc_show_summary;
spineMetaDocSummary!()(doc);
}
#+END_SRC
@@ -1580,7 +1578,7 @@ if (doc.matters.opt.action.show_summary) {
#+BEGIN_SRC d
/+ ↓ debugs +/
if (doc.matters.opt.action.show_metadata) {
- import sisudoc.meta.metadoc_show_metadata;
+ import sisudoc.ocda.meta.metadoc_show_metadata;
spineShowMetaData!()(doc.matters);
}
#+END_SRC
@@ -1592,7 +1590,7 @@ if (doc.matters.opt.action.show_metadata) {
#+BEGIN_SRC d
/+ ↓ debugs +/
if (doc.matters.opt.action.show_make) {
- import sisudoc.meta.metadoc_show_make;
+ import sisudoc.ocda.meta.metadoc_show_make;
spineShowMake!()(doc.matters);
}
#+END_SRC
@@ -1604,7 +1602,7 @@ if (doc.matters.opt.action.show_make) {
#+BEGIN_SRC d
/+ ↓ debugs +/
if (doc.matters.opt.action.show_config) {
- import sisudoc.meta.metadoc_show_config;
+ import sisudoc.ocda.meta.metadoc_show_config;
spineShowConfig!()(doc.matters);
}
#+END_SRC
@@ -1616,7 +1614,7 @@ if (doc.matters.opt.action.show_config) {
#+BEGIN_SRC d
/+ ↓ document abstraction text representation +/
if (doc.matters.opt.action.show_abstraction) {
- import sisudoc.io_out.create_abstraction_txt;
+ import sisudoc.ocda.abstraction.ssp;
spineAbstractionTxt!()(doc);
}
#+END_SRC
@@ -1628,7 +1626,7 @@ if (doc.matters.opt.action.show_abstraction) {
#+BEGIN_SRC d
/+ ↓ document abstraction sqlite database +/
if (doc.matters.opt.action.show_abstraction_db) {
- import sisudoc.io_out.create_abstraction_db;
+ import sisudoc.outputs.io_out.create_abstraction_db;
spineAbstractionDb!()(doc);
}
#+END_SRC
@@ -1721,10 +1719,10 @@ break; // terminate, stop
*** 0 module template
- abstraction template
-#+HEADER: :tangle "../src/sisudoc/meta/metadoc.d"
+#+HEADER: :tangle "../src/sisudoc/ocda/meta/metadoc.d"
#+BEGIN_SRC d
<<doc_header_including_copyright_and_license>>
-module sisudoc.meta.metadoc;
+module sisudoc.ocda.meta.metadoc;
@safe:
template spineAbstraction() {
<<imports_spine_metadoc>>
@@ -1842,7 +1840,7 @@ if ((_opt_action.debug_do)
) {
writeln("step2 commence → (read document header (yaml) return struct) [", _manifest.src.filename, "]");
}
-import sisudoc.meta.conf_make_meta_yaml;
+import sisudoc.ocda.meta.conf_make_meta_yaml;
_make_and_meta_struct =
docHeaderMakeAndMetaTupYamlExtractAndConvertToStruct!()(
_header_body_insertfilelist_imagelist.header_raw,
diff --git a/org/spine_info.org b/org/spine_info.org
index cd7ea11..3fecf1a 100644
--- a/org/spine_info.org
+++ b/org/spine_info.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
- [[./spine_build_scaffold.org][spine_build_scaffold.org]]
@@ -865,7 +865,7 @@ webserv:
** notices
*** project (project root) ./
-#+HEADER: :tangle "../COPYRIGHT"
+#+HEADER: :tangle-NO "../COPYRIGHT"
#+HEADER: :noweb yes
#+BEGIN_SRC text
- Name: spine - SiSU Spine, Doc Reform
@@ -882,26 +882,25 @@ webserv:
*** code org ./org
-#+HEADER: :tangle "../org/COPYRIGHT"
+- .org literate programming:
+ - copyright asserted
+ - omitted
+ - license
+ - dependency information
+
+#+HEADER: :tangle-NO "../org/COPYRIGHT"
#+HEADER: :noweb yes
#+BEGIN_SRC text
- Name: spine - SiSU Spine, Doc Reform
<<sisudoc_spine_copyright>>
- <<sisudoc_spine_license_agpl3>>
-
<<sisudoc_spine_summary>>
<<sisudoc_spine_markup_samples>>
-
-<<sisudoc_spine_dependencies>>
#+END_SRC
-*** code source ./src
-#+HEADER: :tangle "../src/COPYRIGHT"
#+HEADER: :noweb yes
-#+BEGIN_SRC text
- Name: spine - SiSU Spine, Doc Reform
<<sisudoc_spine_copyright>>
@@ -914,9 +913,9 @@ webserv:
<<sisudoc_spine_dependencies>>
#+END_SRC
-*** code source ./src/sisudoc
+*** code source ./src
-#+HEADER: :tangle "../src/sisudoc/COPYRIGHT"
+#+HEADER: :tangle-NO "../src/COPYRIGHT"
#+HEADER: :noweb yes
#+BEGIN_SRC text
- Name: spine - SiSU Spine, Doc Reform
@@ -931,23 +930,21 @@ webserv:
<<sisudoc_spine_dependencies>>
#+END_SRC
-*** org files ./org
-
-- .org literate programming:
- - copyright asserted
- - omitted
- - license
- - dependency information
+*** code source ./src/sisudoc
-#+HEADER: :tangle "./COPYRIGHT"
+#+HEADER: :tangle-NO "../src/sisudoc/COPYRIGHT"
#+HEADER: :noweb yes
#+BEGIN_SRC text
- Name: spine - SiSU Spine, Doc Reform
<<sisudoc_spine_copyright>>
+ <<sisudoc_spine_license_agpl3>>
+
<<sisudoc_spine_summary>>
<<sisudoc_spine_markup_samples>>
+
+<<sisudoc_spine_dependencies>>
#+END_SRC
*** doc (markup samples) ./doc
diff --git a/org/spine_markup_sample.org b/org/spine_markup_sample.org
index a6bb361..f6747c2 100644
--- a/org/spine_markup_sample.org
+++ b/org/spine_markup_sample.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
diff --git a/org/test_shell_script_ssp_document_abstraction.org b/org/test_shell_script_ssp_document_abstraction.org
index 5d25f5b..18b04ef 100644
--- a/org/test_shell_script_ssp_document_abstraction.org
+++ b/org/test_shell_script_ssp_document_abstraction.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
* test shell script ssp document abstraction test/test-abstraction-ssp.sh
@@ -44,7 +44,12 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SPINE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
-SAMPLES_DIR="$SPINE_DIR/../sisudoc-spine-samples/markup/pod-samples/pod"
+SAMPLES_RAW="$SPINE_DIR/$SpinePOD"
+if [ -d "$SAMPLES_RAW" ]; then
+ SAMPLES_DIR="$(cd "$SAMPLES_RAW" && pwd)"
+else
+ SAMPLES_DIR="$SAMPLES_RAW"
+fi
REF_DIR="$SCRIPT_DIR/reference/abstraction"
TMP_DIR="$SCRIPT_DIR/current/abstraction"
@@ -152,4 +157,3 @@ else
exit 1
fi
#+END_SRC
-
diff --git a/org/util_editors.org b/org/util_editors.org
index d07de15..f88e9d1 100644
--- a/org/util_editors.org
+++ b/org/util_editors.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -333,15 +333,25 @@ unlet s:cpo_save
#+HEADER: :tangle "../sundry/editor-syntax-etc/vim/syntax/sisu-spine.vim"
#+BEGIN_SRC text
-" SiSU Vim syntax file (sisu-spine)
+" SiSU Vim syntax file (sisu-spine) - Vim 8 fallback (regex)
" SiSU Maintainer: Ralph Amissah <ralph.amissah@gmail.com>
" SiSU Markup: SiSU (sisu-5.6.7)
" sisu-spine Markup: sisu-spine
-" Last Change: 2017-06-22, 2025-02-21
+" Last Change: 2017-06-22, 2025-02-21, 2026-05-09
" URL: <https://git.sisudoc.org/projects/sisudoc-spine/tree/sundry/editor-syntax-etc/vim/syntax/sisu-spine.vim>
" <https://git.sisudoc.org/projects/sisudoc-spine/tree/sundry/editor-syntax-etc/vim/syntax/sisu.vim>
" <https://sisudoc.org/>
"(originally looked at Ruby Vim by Mirko Nasato)
+"
+" Status: This is the regex-based Vim 8 fallback. For Neovim users, the
+" tree-sitter-sisu grammar provides structural highlighting, folding and
+" textobjects with strictly better behaviour on nested markup, multi-line
+" footnotes, block bodies, and segmented headings; see
+" sundry/editor-syntax-etc/nvim/README.md
+" Emacs 29+ users have an equivalent treesit-based mode at
+" sundry/editor-syntax-etc/emacs/sisu-spine-ts-mode.el
+" This file remains the supported path for classic Vim, where tree-sitter
+" is not available without third-party plugins.
if version < 600
syntax clear
@@ -1897,8 +1907,630 @@ make:
1~ #___#
#+END_SRC
-* Emacs Syntax highlighting
+* NVim tree-sitter Syntax highlighting
+** README.md
+
+#+HEADER: :tangle "../sundry/editor-syntax-etc/nvim/README.md"
+#+BEGIN_SRC markdown
+# Neovim integration for SiSU spine markup
+
+Tree-sitter-backed syntax highlighting, folding, and structural
+navigation for `.sst` / `.ssm` / `.ssi` files in Neovim (>= 0.9).
+
+## What is in this directory
+
+```
+nvim/
+ ftdetect/sisu.lua - register .sst/.ssm/.ssi as filetype "sisu"
+ ftplugin/sisu.lua - per-buffer settings (commentstring, conceal)
+ lua/sisu-spine/init.lua - entry point: registers parser config
+ queries/sisu/ - tree-sitter queries (mirrors tree-sitter-sisu/queries/)
+ highlights.scm
+ folds.scm
+ injections.scm
+ textobjects.scm
+ indents.scm
+```
+
+## Install (manual)
+
+1. Symlink or copy this directory into your Neovim runtime path:
+
+ ```sh
+ ln -s /path/to/sisudoc-spine/sundry/editor-syntax-etc/nvim \
+ ~/.config/nvim/pack/sisu/start/sisu-spine
+ ```
+
+2. Tell `nvim-treesitter` how to fetch the parser. Add to your config
+ (`init.lua`):
+
+ ```lua
+ require("sisu-spine").setup()
+ require("nvim-treesitter.configs").setup({
+ ensure_installed = { "sisu" },
+ highlight = { enable = true },
+ indent = { enable = true },
+ fold = { enable = true },
+ textobjects = { select = { enable = true, lookahead = true } },
+ })
+ ```
+
+3. Build the parser:
+
+ ```vim
+ :TSInstall sisu
+ ```
+
+That is it. Open a `.sst` file - highlighting, folding, and textobject
+selection should all work.
+
+## Install (lazy.nvim)
+
+```lua
+{
+ dir = "/path/to/sisudoc-spine/sundry/editor-syntax-etc/nvim",
+ name = "sisu-spine",
+ ft = { "sisu" },
+ dependencies = { "nvim-treesitter/nvim-treesitter" },
+ config = function()
+ require("sisu-spine").setup()
+ end,
+}
+```
+
+## Sync queries from upstream
+
+The query files are duplicated from `tree-sitter-sisu/queries/` so that
+this Neovim drop-in works without depending on the parser repo's
+checkout layout. To refresh them after grammar changes:
+
+```sh
+cp ../../../sisudoc-spine-tools/tree-sitter-sisu/queries/*.scm \
+ queries/sisu/
+```
+
+(Path is relative to this README.)
+
+## Upstreaming the parser
+
+When the parser is publicly hosted under a stable URL it is worth
+submitting a config to `nvim-treesitter` so users can run `:TSInstall
+sisu` without the local `setup()` call. The required fields are in
+`lua/sisu-spine/init.lua` (`install_info` table); send a PR to
+<https://github.com/nvim-treesitter/nvim-treesitter> patching
+`lua/nvim-treesitter/parsers.lua`.
+#+END_SRC
+
+** lua
+*** init
+
+#+HEADER: :tangle "../sundry/editor-syntax-etc/nvim/lua/sisu-spine/init.lua"
+#+BEGIN_SRC lua
+-- Entry point for the SiSU spine markup Neovim integration.
+--
+-- Registers a tree-sitter parser config so users can run
+-- :TSInstall sisu
+-- to fetch and build the parser via nvim-treesitter.
+--
+-- The parser source lives can be found under the
+-- `projects/` namespace on git.sisudoc.org.
+
+local M = {}
+
+--- Register the `sisu` parser with nvim-treesitter and ensure that
+--- `.sst` / `.ssm` / `.ssi` are detected as filetype "sisu".
+---
+--- Call once from your init.lua before invoking `:TSInstall sisu`.
+function M.setup()
+ local ok, parsers = pcall(require, "nvim-treesitter.parsers")
+ if not ok then
+ vim.notify(
+ "sisu-spine: nvim-treesitter is not installed; "
+ .. "syntax highlighting will not be available.",
+ vim.log.levels.WARN
+ )
+ return
+ end
+
+ local parser_config = parsers.get_parser_configs()
+ parser_config.sisu = {
+ install_info = {
+ url = "https://git.sisudoc.org/projects/tree-sitter-sisu",
+ files = {
+ "src/parser.c",
+ "src/scanner.c",
+ },
+ branch = "main",
+ generate_requires_npm = false,
+ requires_generate_from_grammar = false,
+ },
+ filetype = "sisu",
+ }
+end
+
+return M
+#+END_SRC
+
+*** ftdetect
+
+#+HEADER: :tangle "../sundry/editor-syntax-etc/nvim/ftdetect/sisu.lua"
+#+BEGIN_SRC lua
+vim.filetype.add({
+ extension = {
+ sst = "sisu",
+ ssm = "sisu",
+ ssi = "sisu",
+ },
+})
+#+END_SRC
+
+*** ftplugin
+
+#+HEADER: :tangle "../sundry/editor-syntax-etc/nvim/ftplugin/sisu.lua"
+#+BEGIN_SRC lua
+-- Buffer-local settings for SiSU spine markup.
+
+vim.bo.commentstring = "%% %s"
+vim.bo.comments = ":%"
+
+-- Soft wrap suits prose.
+vim.wo.wrap = true
+vim.wo.linebreak = true
+
+-- Conceal inline-formatting delimiters when the user opts in
+-- (`:set conceallevel=2`). See queries/sisu/highlights.scm for
+-- @conceal captures.
+vim.wo.conceallevel = vim.wo.conceallevel
+#+END_SRC
+
+** queries
+*** folds
+
+#+HEADER: :tangle "../sundry/editor-syntax-etc/nvim/queries/sisu/folds.scm"
+#+BEGIN_SRC vimrc
+; Code folding queries for SiSU Spine markup
+
+; Block elements are foldable
+(code_block_curly) @fold
+(code_block_tic) @fold
+(poem_block_curly) @fold
+(poem_block_tic) @fold
+(block_block_curly) @fold
+(block_block_tic) @fold
+(group_block_curly) @fold
+(group_block_tic) @fold
+(table_block_curly) @fold
+(table_block_tic) @fold
+(quote_block_tic) @fold
+
+; Multi-line book index entries are foldable
+(book_index) @fold
+
+; Pipe tables are foldable
+(pipe_table) @fold
+
+; Header fields with continuations are foldable
+(header_field) @fold
+#+END_SRC
+*** highlights
+
+#+HEADER: :tangle "../sundry/editor-syntax-etc/nvim/queries/sisu/highlights.scm"
+#+BEGIN_SRC vimrc
+; Syntax highlighting queries for SiSU Spine markup
+; Compatible with tree-sitter highlight capture names from
+; https://tree-sitter.github.io/tree-sitter/syntax-highlighting
+
+; =================================================================
+; Comments
+; =================================================================
+(version_comment) @comment.documentation
+(header_comment) @comment
+(body_comment) @comment
+
+; =================================================================
+; Header (document metadata)
+; =================================================================
+(header_field
+ key: (header_key) @keyword)
+
+(header_field
+ value: (header_value) @string)
+
+(header_continuation) @string
+
+; =================================================================
+; Headings
+; =================================================================
+(part_marker) @keyword.directive
+(segment_marker) @keyword.directive
+
+(heading_part
+ content: (heading_content) @markup.heading)
+
+(heading_segment
+ content: (heading_content) @markup.heading)
+
+(segment_name) @label
+(suppress_marker) @punctuation.special
+
+; Heading levels for more specific styling
+(heading_part
+ marker: (part_marker) @markup.heading.1
+ (#match? @markup.heading.1 "^:A~$"))
+
+(heading_part
+ marker: (part_marker) @markup.heading.2
+ (#match? @markup.heading.2 "^:B~$"))
+
+(heading_part
+ marker: (part_marker) @markup.heading.3
+ (#match? @markup.heading.3 "^:C~$"))
+
+(heading_part
+ marker: (part_marker) @markup.heading.4
+ (#match? @markup.heading.4 "^:D~$"))
+
+(heading_segment
+ marker: (segment_marker) @markup.heading.5
+ (#match? @markup.heading.5 "^1~$"))
+
+(heading_segment
+ marker: (segment_marker) @markup.heading.6
+ (#match? @markup.heading.6 "^2~$"))
+
+; =================================================================
+; Inline formatting
+; =================================================================
+(emphasis) @markup.italic
+(bold) @markup.bold
+(italic) @markup.italic
+(underline) @markup.underline
+(citation_mark) @markup.quote
+(superscript) @markup.superscript
+(subscript) @markup.subscript
+(inserted) @markup.underline
+(strikethrough) @markup.strikethrough
+(monospace_inline) @markup.raw
+
+; Formatting delimiters
+["*{" "}*"] @punctuation.special
+["!{" "}!"] @punctuation.special
+["/{" "}/"] @punctuation.special
+["_{" "}_"] @punctuation.special
+["\"{" "}\""] @punctuation.special
+["^{" "}^"] @punctuation.special
+[",{" "},"] @punctuation.special
+["+{" "}+"] @punctuation.special
+["-{" "}-"] @punctuation.special
+["#{" "}#"] @punctuation.special
+
+; =================================================================
+; Footnotes and editor notes
+; =================================================================
+(footnote) @markup.link
+(footnote_marker) @punctuation.special
+(editor_note) @markup.link
+
+["~{" "}~"] @punctuation.special
+; Editor-note channel selector: ~[* (asterisk set) or ~[+ (plus set).
+; A distinct capture lets themes colour the two channels separately
+; from the generic footnote delimiters above.
+(editor_note_marker) @attribute
+["]~"] @punctuation.special
+
+; =================================================================
+; Links and images
+; =================================================================
+(link
+ text: (link_text) @markup.link.label)
+
+(link
+ target: (url) @markup.link.url)
+
+(link
+ target: (anchor_ref) @markup.link.url)
+
+(link
+ target: (collection_path) @markup.link.url)
+
+(auto_footnote_marker) @punctuation.special
+
+(image
+ spec: (image_spec) @markup.link.label)
+
+(url) @markup.link.url
+
+(inline_anchor) @label
+(anchor_name) @label
+
+; =================================================================
+; Block elements
+; =================================================================
+(block_open) @keyword.directive
+(block_close) @keyword.directive
+(raw_content) @markup.raw
+
+; Code blocks get more specific highlighting
+(code_block_curly
+ open: (block_open) @keyword.directive)
+(code_block_curly
+ content: (raw_content) @markup.raw.block)
+(code_block_curly
+ close: (block_close) @keyword.directive)
+
+(code_block_tic
+ open: (block_open) @keyword.directive)
+(code_block_tic
+ content: (raw_content) @markup.raw.block)
+(code_block_tic
+ close: (block_close) @keyword.directive)
+
+; =================================================================
+; Book index
+; =================================================================
+(book_index) @markup.list
+(index_content) @string
+
+; =================================================================
+; Paragraph prefixes
+; =================================================================
+(paragraph_prefix) @punctuation.special
+
+; =================================================================
+; Special markers
+; =================================================================
+(ocn_suppress) @comment
+(ocn_suppress_open) @comment
+(ocn_suppress_close) @comment
+
+(page_break) @punctuation.special
+(horizontal_rule) @punctuation.special
+
+; =================================================================
+; Composite includes
+; =================================================================
+(composite_include) @keyword.import
+(include_path) @string.special.path
+
+; =================================================================
+; Pipe table
+; =================================================================
+(table_spec) @keyword.directive
+(table_row) @markup.raw
+
+; =================================================================
+; Text
+; =================================================================
+(text) @spell
+
+; Line break
+(line_break) @punctuation.special
+#+END_SRC
+
+*** indents
+
+#+HEADER: :tangle "../sundry/editor-syntax-etc/nvim/queries/sisu/indents.scm"
+#+BEGIN_SRC vimrc
+; Indentation queries for SiSU Spine markup.
+;
+; SiSU markup is largely flat: paragraphs and headings live at column 0,
+; block bodies preserve their author-supplied indentation verbatim, and
+; nesting is by markers rather than by indent. So indents.scm is mostly a
+; no-op - the goal is to ensure that auto-indent on <CR> stays at column 0
+; for normal lines and respects existing indentation inside header
+; continuations and blocks.
+
+; Tree-sitter indent semantics (per nvim-treesitter and treesit):
+; @indent.begin - increases indent for the following line
+; @indent.end - matches the @indent.begin and decreases indent
+; @indent.zero - resets indent to column 0
+; @indent.align - aligns following lines with this node
+; @indent.branch - same level as the parent (for else/elif-style joins)
+
+; Top-level structures live at column 0 - reset to zero on the next line.
+(heading_part) @indent.zero
+(heading_segment) @indent.zero
+(paragraph) @indent.zero
+(book_index) @indent.zero
+(composite_include) @indent.zero
+(page_break) @indent.zero
+(horizontal_rule) @indent.zero
+(ocn_suppress_open) @indent.zero
+(ocn_suppress_close) @indent.zero
+(body_comment) @indent.zero
+
+; Block elements: opening line increases indent for the body, closing
+; line returns to zero. Editors that respect this will visually indent
+; raw content one step from the delimiter line, which is conventional.
+(code_block_curly) @indent.align
+(code_block_tic) @indent.align
+(poem_block_curly) @indent.align
+(poem_block_tic) @indent.align
+(block_block_curly) @indent.align
+(block_block_tic) @indent.align
+(group_block_curly) @indent.align
+(group_block_tic) @indent.align
+(table_block_curly) @indent.align
+(table_block_tic) @indent.align
+(quote_block_tic) @indent.align
+
+; Header continuation lines are indented by two spaces from column 0;
+; mark continuations as align so a host that chooses to auto-indent the
+; next continuation line matches the previous one.
+(header_field) @indent.align
+(header_continuation) @indent.align
+#+END_SRC
+
+*** injections
+
+#+HEADER: :tangle "../sundry/editor-syntax-etc/nvim/queries/sisu/injections.scm"
+#+BEGIN_SRC vimrc
+; Language injection queries for SiSU Spine markup
+;
+; Code blocks could potentially inject language-specific highlighting,
+; but SiSU code blocks don't specify language. These queries are
+; provided as a starting point for future extension.
+
+; Code block content could be injected with a specific language
+; if the block type or context provides a hint.
+; For now, raw content in code blocks is left unhighlighted.
+
+; Example: if code blocks specified a language, e.g. code(d){
+; ((code_block_curly
+; open: (block_open) @_open
+; content: (raw_content) @injection.content)
+; (#match? @_open "code\\(d\\)")
+; (#set! injection.language "d"))
+#+END_SRC
+
+*** textobjects
+
+#+HEADER: :tangle "../sundry/editor-syntax-etc/nvim/queries/sisu/textobjects.scm"
+#+BEGIN_SRC vimrc
+; Text-object queries for SiSU Spine markup.
+;
+; Capture conventions follow nvim-treesitter/textobjects:
+; @<thing>.outer -> select including delimiters / surrounding whitespace
+; @<thing>.inner -> select content only
+;
+; Hosts that consume these (Neovim's nvim-treesitter-textobjects, Helix,
+; Emacs treesit) bind keys such as `af` / `if` to .outer / .inner.
+
+; =================================================================
+; Headings (sectioning units)
+; =================================================================
+; A whole heading line is a "section header" object. Heading sections
+; (the heading plus its body content up to the next heading of equal or
+; higher level) are not directly expressible in tree-sitter without
+; additional grammar work; hosts can synthesise that from these captures.
+
+(heading_part) @class.outer
+(heading_part
+ content: (heading_content) @class.inner)
+
+(heading_segment) @class.outer
+(heading_segment
+ content: (heading_content) @class.inner)
+
+; =================================================================
+; Block elements (code / poem / block / group / table / quote)
+; =================================================================
+; Whole block including delimiters; raw_content is the inner.
+
+(code_block_curly) @function.outer
+(code_block_curly
+ content: (raw_content) @function.inner)
+
+(code_block_tic) @function.outer
+(code_block_tic
+ content: (raw_content) @function.inner)
+
+(poem_block_curly) @function.outer
+(poem_block_curly
+ content: (raw_content) @function.inner)
+
+(poem_block_tic) @function.outer
+(poem_block_tic
+ content: (raw_content) @function.inner)
+
+(block_block_curly) @function.outer
+(block_block_curly
+ content: (raw_content) @function.inner)
+
+(block_block_tic) @function.outer
+(block_block_tic
+ content: (raw_content) @function.inner)
+
+(group_block_curly) @function.outer
+(group_block_curly
+ content: (raw_content) @function.inner)
+
+(group_block_tic) @function.outer
+(group_block_tic
+ content: (raw_content) @function.inner)
+
+(table_block_curly) @function.outer
+(table_block_curly
+ content: (raw_content) @function.inner)
+
+(table_block_tic) @function.outer
+(table_block_tic
+ content: (raw_content) @function.inner)
+
+(quote_block_tic) @function.outer
+(quote_block_tic
+ content: (raw_content) @function.inner)
+
+(pipe_table) @function.outer
+
+; =================================================================
+; Footnotes and editor notes
+; =================================================================
+; Both share the same outer/inner shape; the inner skips the markers and
+; closing delimiters.
+
+(footnote) @comment.outer
+(footnote
+ (_)+ @comment.inner)
+
+(editor_note) @comment.outer
+(editor_note
+ (_)+ @comment.inner)
+
+; =================================================================
+; Links and images
+; =================================================================
+
+(link) @parameter.outer
+(link
+ text: (link_text) @parameter.inner)
+
+(image) @parameter.outer
+(image
+ spec: (image_spec) @parameter.inner)
+
+; =================================================================
+; Paragraph / inline-formatting runs
+; =================================================================
+
+(paragraph) @block.outer
+(paragraph
+ (_)+ @block.inner)
+
+; Inline formatting pairs - useful as fine-grained text objects.
+; The same delimiter character pattern (e.g. `*{` / `}*`) opens and
+; closes each, so .inner is everything between them.
+
+(emphasis) @assignment.outer
+(bold) @assignment.outer
+(italic) @assignment.outer
+(underline) @assignment.outer
+(citation_mark) @assignment.outer
+(superscript) @assignment.outer
+(subscript) @assignment.outer
+(inserted) @assignment.outer
+(strikethrough) @assignment.outer
+(monospace_inline) @assignment.outer
+
+; =================================================================
+; Book index entries
+; =================================================================
+
+(book_index) @attribute.outer
+(book_index
+ (index_content) @attribute.inner)
+
+; =================================================================
+; Header fields
+; =================================================================
+
+(header_field) @assignment.outer
+(header_field
+ value: (header_value) @assignment.inner)
+#+END_SRC
+
+* Emacs Syntax highlighting
** README
#+HEADER: :tangle "../sundry/editor-syntax-etc/emacs/README"
@@ -1914,18 +2546,36 @@ make:
#+HEADER: :tangle "../sundry/editor-syntax-etc/emacs/sisu-spine-mode-autoloads.el"
#+BEGIN_SRC elisp
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
+;; Regex / font-lock major mode. Fallback for Emacs < 29 and for users
+;; who have not installed the tree-sitter-sisu parser.
(autoload 'sisu-spine-mode "sisu-spine-mode" "\
Major mode for editing SiSU (spine) markup files.
SiSU (https://www.sisudoc.org/) document structuring, publishing
and search.
\(fn)" t nil)
-(add-to-list 'auto-mode-alist '("\\.sst\\'" . sisu-spine-mode))
-(add-to-list 'auto-mode-alist '("\\.ssm\\'" . sisu-spine-mode))
-(add-to-list 'auto-mode-alist '("\\.ssi\\'" . sisu-spine-mode))
+
+;; Tree-sitter major mode (Emacs 29+). When the parser is installed it
+;; is selected by `auto-mode-alist'; otherwise the regex mode is used.
+(autoload 'sisu-spine-ts-mode "sisu-spine-ts-mode" "\
+Tree-sitter major mode for editing SiSU (spine) markup files.
+
+\(fn)" t nil)
+(autoload 'sisu-spine-ts-install-grammar "sisu-spine-ts-mode" "\
+Install the tree-sitter-sisu grammar for `sisu-spine-ts-mode'.
+\(fn)" t nil)
+(defun sisu-spine-auto-mode ()
+ "Choose `sisu-spine-ts-mode' if the parser is installed, else fall back."
+ (if (and (fboundp 'treesit-ready-p) (treesit-ready-p 'sisu t))
+ (sisu-spine-ts-mode)
+ (sisu-spine-mode)))
+
+(add-to-list 'auto-mode-alist '("\\.sst\\'" . sisu-spine-auto-mode))
+(add-to-list 'auto-mode-alist '("\\.ssm\\'" . sisu-spine-auto-mode))
+(add-to-list 'auto-mode-alist '("\\.ssi\\'" . sisu-spine-auto-mode))
#+END_SRC
-** mode sisu-spine-mode.el
+** mode sisu-spine-mode.el (regex)
#+HEADER: :tangle "../sundry/editor-syntax-etc/emacs/sisu-spine-mode.el"
#+BEGIN_SRC elisp
@@ -2432,3 +3082,305 @@ URL `https://www.sisudoc.org/'"
;;; sisu-spine-mode.el ends here
#+END_SRC
+
+** mode sisu-spine-ts-mode.el (tree-sitter)
+
+#+HEADER: :tangle "../sundry/editor-syntax-etc/emacs/sisu-spine-ts-mode.el"
+#+BEGIN_SRC elisp
+;;; sisu-spine-ts-mode.el --- Tree-sitter major mode for SiSU spine markup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Free Software Foundation, Inc.
+
+;; Author: Ralph Amissah <ralph.amissah@gmail.com>
+;; Maintainer: Ralph Amissah <ralph.amissah@gmail.com>
+;; Keywords: text, syntax, processes, tools
+;; Version: 1.0.0
+;; URL: https://git.sisudoc.org/projects/sisudoc-spine/tree/sundry/editor-syntax-etc/emacs/sisu-spine-ts-mode.el
+;; https://sisudoc.org/
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;;; Commentary:
+
+;; Tree-sitter-backed major mode for SiSU spine markup (.sst / .ssm /
+;; .ssi). Sibling to `sisu-spine-mode' (regex / font-lock); requires
+;; Emacs 29 or newer with `treesit' built in and the tree-sitter-sisu
+;; parser installed.
+;;
+;; To install the parser inside Emacs:
+;;
+;; M-x sisu-spine-ts-install-grammar RET
+;;
+;; or, equivalently:
+;;
+;; (add-to-list 'treesit-language-source-alist
+;; '(sisu "https://git.sisudoc.org/projects"
+;; :source-dir "tree-sitter-sisu/src"))
+;; M-x treesit-install-language-grammar RET sisu RET
+;;
+;; The mode is auto-enabled for .sst / .ssm / .ssi files when the parser
+;; is available. When it is not, `sisu-spine-mode' (the regex variant)
+;; remains available as a fallback.
+
+;;; Code:
+
+(require 'treesit nil t)
+
+(defgroup sisu-spine-ts nil
+ "Tree-sitter mode for SiSU spine markup."
+ :group 'text
+ :prefix "sisu-spine-ts-")
+
+;; ---------------------------------------------------------------------
+;; Faces (mirror the structural categories the highlights.scm assigns)
+;; ---------------------------------------------------------------------
+
+(defface sisu-spine-ts-heading-1-face
+ '((t (:inherit outline-1 :weight bold)))
+ "Face for :A~ headings."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-heading-2-face
+ '((t (:inherit outline-2 :weight bold)))
+ "Face for :B~ headings."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-heading-3-face
+ '((t (:inherit outline-3 :weight bold)))
+ "Face for :C~ / :D~ headings."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-heading-segment-face
+ '((t (:inherit outline-4)))
+ "Face for 1~ / 2~ / 3~ segment headings."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-block-delimiter-face
+ '((t (:inherit font-lock-keyword-face)))
+ "Face for block opening/closing delimiters."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-raw-content-face
+ '((t (:inherit font-lock-string-face)))
+ "Face for raw block content (code, table, etc.)."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-footnote-face
+ '((t (:inherit font-lock-doc-face)))
+ "Face for footnote and editor-note bodies."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-link-face
+ '((t (:inherit link)))
+ "Face for link text and target URLs."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-book-index-face
+ '((t (:inherit font-lock-preprocessor-face)))
+ "Face for book-index entries (={...})."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-marker-face
+ '((t (:inherit font-lock-builtin-face)))
+ "Face for inline-formatting delimiters and other punctuation markers."
+ :group 'sisu-spine-ts)
+
+;; ---------------------------------------------------------------------
+;; Font-lock rules
+;; ---------------------------------------------------------------------
+
+(defvar sisu-spine-ts--font-lock-settings
+ (when (fboundp 'treesit-font-lock-rules)
+ (treesit-font-lock-rules
+ :language 'sisu
+ :feature 'comment
+ '((version_comment) @font-lock-doc-face
+ (header_comment) @font-lock-comment-face
+ (body_comment) @font-lock-comment-face)
+
+ :language 'sisu
+ :feature 'header
+ '((header_field key: (header_key) @font-lock-keyword-face)
+ (header_field value: (header_value) @font-lock-string-face)
+ (header_continuation) @font-lock-string-face)
+
+ :language 'sisu
+ :feature 'heading
+ '(((heading_part marker: (part_marker) @m
+ content: (heading_content) @sisu-spine-ts-heading-1-face)
+ (:match "^:A~$" @m))
+ ((heading_part marker: (part_marker) @m
+ content: (heading_content) @sisu-spine-ts-heading-2-face)
+ (:match "^:B~$" @m))
+ ((heading_part marker: (part_marker) @m
+ content: (heading_content) @sisu-spine-ts-heading-3-face)
+ (:match "^:[CD]~$" @m))
+ (heading_part marker: (part_marker) @sisu-spine-ts-marker-face)
+ (heading_segment marker: (segment_marker) @sisu-spine-ts-marker-face
+ content: (heading_content) @sisu-spine-ts-heading-segment-face)
+ (segment_name) @font-lock-function-name-face
+ (suppress_marker) @sisu-spine-ts-marker-face)
+
+ :language 'sisu
+ :feature 'block
+ '((block_open) @sisu-spine-ts-block-delimiter-face
+ (block_close) @sisu-spine-ts-block-delimiter-face
+ (raw_content) @sisu-spine-ts-raw-content-face
+ (table_spec) @sisu-spine-ts-block-delimiter-face)
+
+ :language 'sisu
+ :feature 'inline
+ '((emphasis) @italic
+ (bold) @bold
+ (italic) @italic
+ (underline) @underline
+ (citation_mark) @font-lock-string-face
+ (superscript) @font-lock-type-face
+ (subscript) @font-lock-type-face
+ (inserted) @underline
+ (strikethrough) @shadow
+ (monospace_inline) @font-lock-constant-face)
+
+ :language 'sisu
+ :feature 'note
+ '((footnote) @sisu-spine-ts-footnote-face
+ (footnote_marker) @sisu-spine-ts-marker-face
+ (editor_note) @sisu-spine-ts-footnote-face)
+
+ :language 'sisu
+ :feature 'link
+ '((link text: (link_text) @sisu-spine-ts-link-face)
+ (link target: (url) @sisu-spine-ts-link-face)
+ (link target: (anchor_ref) @sisu-spine-ts-link-face)
+ (link target: (collection_path) @sisu-spine-ts-link-face)
+ (image spec: (image_spec) @sisu-spine-ts-link-face)
+ (auto_footnote_marker) @sisu-spine-ts-marker-face
+ (inline_anchor) @font-lock-function-name-face
+ (anchor_name) @font-lock-function-name-face)
+
+ :language 'sisu
+ :feature 'index
+ '((book_index) @sisu-spine-ts-book-index-face
+ (index_content) @font-lock-string-face)
+
+ :language 'sisu
+ :feature 'misc
+ '((paragraph_prefix) @sisu-spine-ts-marker-face
+ (page_break) @sisu-spine-ts-marker-face
+ (horizontal_rule) @sisu-spine-ts-marker-face
+ (line_break) @sisu-spine-ts-marker-face
+ (ocn_suppress) @font-lock-comment-face
+ (ocn_suppress_open) @font-lock-comment-face
+ (ocn_suppress_close) @font-lock-comment-face
+ (composite_include) @font-lock-preprocessor-face
+ (include_path) @font-lock-string-face)))
+ "Tree-sitter font-lock rules for `sisu-spine-ts-mode'.")
+
+;; ---------------------------------------------------------------------
+;; Imenu / navigation / things
+;; ---------------------------------------------------------------------
+
+(defvar sisu-spine-ts--imenu-settings
+ '(("Part headings"
+ "\\`heading_part\\'"
+ nil
+ sisu-spine-ts--imenu-name-part)
+ ("Segment headings"
+ "\\`heading_segment\\'"
+ nil
+ sisu-spine-ts--imenu-name-segment))
+ "`treesit-simple-imenu-settings' for `sisu-spine-ts-mode'.")
+
+(defun sisu-spine-ts--imenu-name-part (node)
+ "Return display name for a heading_part NODE."
+ (let ((c (treesit-node-child-by-field-name node "content"))
+ (m (treesit-node-child-by-field-name node "marker")))
+ (concat (and m (treesit-node-text m t)) " "
+ (and c (treesit-node-text c t)))))
+
+(defun sisu-spine-ts--imenu-name-segment (node)
+ "Return display name for a heading_segment NODE."
+ (let ((c (treesit-node-child-by-field-name node "content"))
+ (m (treesit-node-child-by-field-name node "marker")))
+ (concat (and m (treesit-node-text m t)) " "
+ (and c (treesit-node-text c t)))))
+
+(defvar sisu-spine-ts--thing-settings
+ '((sisu
+ (defun "\\`heading_\\(part\\|segment\\)\\'")
+ (sentence "\\`paragraph\\'")
+ (text "\\`\\(text\\|raw_content\\|heading_content\\)\\'")))
+ "`treesit-thing-settings' for `sisu-spine-ts-mode'.")
+
+;; ---------------------------------------------------------------------
+;; Grammar install helper
+;; ---------------------------------------------------------------------
+
+;;;###autoload
+(defun sisu-spine-ts-install-grammar ()
+ "Register and install the tree-sitter-sisu grammar.
+Convenience wrapper around `treesit-install-language-grammar' with the
+upstream URL and source directory pre-filled."
+ (interactive)
+ (unless (boundp 'treesit-language-source-alist)
+ (user-error "treesit not available; Emacs 29+ required"))
+ (add-to-list 'treesit-language-source-alist
+ '(sisu "https://git.sisudoc.org/projects"
+ :source-dir "tree-sitter-sisu/src"))
+ (treesit-install-language-grammar 'sisu))
+
+;; ---------------------------------------------------------------------
+;; Major mode
+;; ---------------------------------------------------------------------
+
+;;;###autoload
+(define-derived-mode sisu-spine-ts-mode text-mode "SiSU-Spine[ts]"
+ "Major mode for SiSU spine markup, backed by tree-sitter."
+ (unless (and (fboundp 'treesit-ready-p) (treesit-ready-p 'sisu))
+ (user-error
+ "tree-sitter-sisu parser not installed; run M-x sisu-spine-ts-install-grammar"))
+ (treesit-parser-create 'sisu)
+
+ ;; Comments
+ (setq-local comment-start "% "
+ comment-end ""
+ comment-start-skip "%[ \t]+")
+
+ ;; Font-lock
+ (setq-local treesit-font-lock-settings sisu-spine-ts--font-lock-settings)
+ (setq-local treesit-font-lock-feature-list
+ '((comment header heading)
+ (block inline note link index)
+ (misc)
+ ()))
+
+ ;; Imenu / navigation
+ (setq-local treesit-simple-imenu-settings sisu-spine-ts--imenu-settings)
+ (setq-local treesit-thing-settings sisu-spine-ts--thing-settings)
+ (setq-local treesit-defun-type-regexp "\\`heading_\\(part\\|segment\\)\\'")
+ (setq-local treesit-defun-name-function
+ (lambda (node)
+ (let ((c (treesit-node-child-by-field-name node "content")))
+ (and c (treesit-node-text c t)))))
+
+ (treesit-major-mode-setup))
+
+;;;###autoload
+(when (fboundp 'treesit-ready-p)
+ (dolist (ext '("\\.sst\\'" "\\.ssm\\'" "\\.ssi\\'"))
+ ;; Prefer the ts mode iff the parser is installed; otherwise fall
+ ;; back to `sisu-spine-mode'.
+ (add-to-list 'auto-mode-alist
+ (cons ext
+ (lambda ()
+ (if (treesit-ready-p 'sisu t)
+ (sisu-spine-ts-mode)
+ (sisu-spine-mode)))))))
+
+(provide 'sisu-spine-ts-mode)
+
+;;; sisu-spine-ts-mode.el ends here
+#+END_SRC
diff --git a/org/util_spine_markup_conversion_from_sisu.org b/org/util_spine_markup_conversion_from_sisu.org
index 42bdbe1..a4bcb5b 100644
--- a/org/util_spine_markup_conversion_from_sisu.org
+++ b/org/util_spine_markup_conversion_from_sisu.org
@@ -7,13 +7,13 @@
#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
#+LANGUAGE: en
#+STARTUP: content hideblocks hidestars noindent entitiespretty
-#+PROPERTY: header-args :exports code
-#+PROPERTY: header-args+ :noweb yes
-#+PROPERTY: header-args+ :results silent
-#+PROPERTY: header-args+ :cache no
-#+PROPERTY: header-args+ :padline no
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
#+PROPERTY: header-args+ :mkdirp yes
#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
@@ -21,14 +21,14 @@
** README
-#+HEADER: :tangle "../sundry/misc/util/d/tools/markup_conversion/README"
+#+HEADER: :tangle "../sundry/util/d/tools/markup_conversion/README"
#+BEGIN_SRC text
#+END_SRC
** endnotes, inline from binary
*** tangle
-#+HEADER: :tangle "../sundry/misc/util/d/tools/markup_conversion/endnotes_inline_from_binary.d"
+#+HEADER: :tangle "../sundry/util/d/tools/markup_conversion/endnotes_inline_from_binary.d"
#+HEADER: :tangle-mode (identity #o755)
#+HEADER: :shebang #!/usr/bin/env rdmd
#+BEGIN_SRC d
@@ -208,7 +208,7 @@ if (endnotes.length == endnote_ref_count) {
** conversion from sisu (sisu bespoke headers) any binary to inline notes TODO
*** tangle
-#+HEADER: :tangle "../sundry/misc/util/d/tools/markup_conversion/markup_conversion_from_sisu_ruby_to_sisu_spine.d"
+#+HEADER: :tangle "../sundry/util/d/tools/markup_conversion/markup_conversion_from_sisu_ruby_to_sisu_spine.d"
#+HEADER: :tangle-mode (identity #o755)
#+HEADER: :shebang #!/usr/bin/env rdmd
#+BEGIN_SRC d
@@ -669,7 +669,7 @@ foreach (paragraph; paragraphs) {
** conversion from sisu and multiple headers (sisu bespoke, sdlang, toml) incomplete
*** tangle
-#+HEADER: :tangle "../sundry/misc/util/d/tools/markup_conversion/markup_changes_header_and_content.d"
+#+HEADER: :tangle "../sundry/util/d/tools/markup_conversion/markup_changes_header_and_content.d"
#+HEADER: :tangle-mode (identity #o755)
#+HEADER: :shebang #!/usr/bin/env rdmd
#+BEGIN_SRC d
diff --git a/package.nix b/package.nix
index 5aac02d..d0beef9 100644
--- a/package.nix
+++ b/package.nix
@@ -27,7 +27,7 @@
}:
stdenv.mkDerivation {
pname = "spine";
- version = "0.19.0";
+ version = "0.22.0";
src = lib.cleanSource ./.;
buildInputs = [ sqlite ];
nativeBuildInputs = [ dub compilerPkg gnumake ];
@@ -57,7 +57,7 @@ stdenv.mkDerivation {
'';
postInstall = ''
echo `ls -la $out/bin/spine`
- echo "❯❯ spine-v0.19.0 (rev: ${rev})"
+ echo "❯❯ spine-v0.22.0 (rev: ${rev})"
$out/bin/spine -v
'';
meta = {
diff --git a/src/sisudoc/io_out/cgi_sqlite_search_form.d b/src/sisudoc/io_out/cgi_sqlite_search_form.d
deleted file mode 100644
index e835b07..0000000
--- a/src/sisudoc/io_out/cgi_sqlite_search_form.d
+++ /dev/null
@@ -1,1959 +0,0 @@
-/+
-- Name: Spine, Doc Reform [a part of]
- - Description: documents, structuring, processing, publishing, search
- - static content generator
-
- - Author: Ralph Amissah
- [ralph.amissah@gmail.com]
-
- - Copyright: (C) 2015 - 2022 Ralph Amissah, All Rights
- Reserved.
-
- - License: AGPL 3 or later:
-
- Spine (SiSU), a framework for document structuring, publishing and
- search
-
- Copyright (C) Ralph Amissah
-
- This program is free software: you can redistribute it and/or modify it
- under the terms of the GNU AFERO General Public License as published by the
- Free Software Foundation, either version 3 of the License, or (at your
- option) any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program. If not, see [https://www.gnu.org/licenses/].
-
- If you have Internet connection, the latest version of the AGPL should be
- available at these locations:
- [https://www.fsf.org/licensing/licenses/agpl.html]
- [https://www.gnu.org/licenses/agpl.html]
-
- - Spine (by Doc Reform, related to SiSU) uses standard:
- - docReform markup syntax
- - standard SiSU markup syntax with modified headers and minor modifications
- - docReform object numbering
- - standard SiSU object citation numbering & system
-
- - Homepages:
- [https://www.doc_reform.org]
- [https://www.sisudoc.org]
-
- - Git
- [https://git.sisudoc.org/projects/?p=software/spine.git;a=summary]
-
-+/
-module doc_reform.io_out.cgi_sqlite_search_form;
-template CGIsearchSQLite() {
- void CGIsearchSQLite(E,O,M)(E env, O opt_action, M make_and_meta_struct) {
- import
- std.file,
- std.format;
- import doc_reform.io_out;
- string _sqlite_db_fn = (opt_action.sqliteDB_filename.empty)
- ? make_and_meta_struct.conf.w_srv_db_sqlite_filename
- : opt_action.sqliteDB_filename;
- string _cgi_search_script = (opt_action.cgi_sqlite_search_filename.empty)
- ? make_and_meta_struct.conf.w_srv_cgi_search_script
- : opt_action.cgi_sqlite_search_filename;
- string _cgi_search_script_raw_fn_d = (opt_action.cgi_sqlite_search_filename_d.empty)
- ? make_and_meta_struct.conf.w_srv_cgi_search_script_raw_fn_d
- : opt_action.cgi_sqlite_search_filename_d;
- string get_doc_collection_subroot(string output_path) {
- string web_doc_root_path = environment.get("DOCUMENT_ROOT", "/var/www/html");
- auto m = output_path.matchFirst(regex("^(" ~ web_doc_root_path ~ ")"));
- return m.post;
- }
- string the_cgi_search_form = format(q"≓
-/+ dub.sdl
- name "spine search"
- description "spine cgi search"
-+/
-import std.format;
-import std.range;
-import std.regex;
-import arsd.cgi;
-import d2sqlite3;
-import std.process : environment;
-void cgi_function_intro(Cgi cgi) {
- string header;
- string table;
- string form;
- struct Config {
- string http_request_type;
- string http_host;
- // string server_name;
- string web_doc_root_path;
- string doc_collection_subroot;
- string cgi_root;
- string cgi_script;
- string data_path_html;
- string db_path;
- string query_string;
- string http_url;
- string request_method;
- }
- auto conf = Config();
- conf.http_request_type = environment.get("REQUEST_SCHEME", "http");
- conf.http_host = environment.get("HTTP_HOST", "localhost");
- // conf.server_name = environment.get("SERVER_NAME", "localhost");
- conf.web_doc_root_path = environment.get("DOCUMENT_ROOT", "/var/www/html");
- conf.doc_collection_subroot = "%s"; // (output_path - web_doc_root_path)
- conf.cgi_root = environment.get("CONTEXT_DOCUMENT_ROOT", "/usr/lib/cgi-bin/");
- // conf.cgi_script = environment.get("SCRIPT_NAME", "/cgi-bin/spine-search");
- conf.query_string = environment.get("QUERY_STRING", "");
- conf.http_url = environment.get("HTTP_REFERER", conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ conf.query_string);
- conf.db_path = "%s"; // (output_path + /sqlite)
- conf.request_method = environment.get("REQUEST_METHOD", "POST");
- struct CGI_val {
- string db_selected = "";
- string sql_match_limit = ""; // radio: ( 1000 | 2500 )
- string sql_match_offset = "";
- string search_text = "";
- string results_type = ""; // index
- bool checked_echo = false;
- bool checked_stats = false;
- bool checked_url = false;
- bool checked_searched = false;
- bool checked_tip = false;
- bool checked_sql = false;
- }
- auto cv = CGI_val();
- cv.db_selected = "%s";
- auto text_fields() {
- string canned_query_str = environment.get("QUERY_STRING", "");
- if ("query_string" in cgi.post) {
- canned_query_str = environment.get("QUERY_STRING", "");
- }
- string[string] canned_query;
- if (conf.request_method == "POST") {
- } else if (conf.request_method == "GET") {
- foreach (pair_str; canned_query_str.split("&")) {
- // cgi.write(pair_str ~ "<br>");
- string[] pair = pair_str.split("=");
- canned_query[pair[0]] = pair[1];
- }
- // foreach (field, content; canned_query) {
- // cgi.write(field ~ ": " ~ content ~ "<br>");
- // }
- }
- static struct Rgx {
- // static canned_query = ctRegex!(`\A(?P<matched>.+)\Z`, "m");
- static search_text_area = ctRegex!(`\A(?P<matched>.+)\Z`, "m");
- // static fulltext = ctRegex!(`\A(?P<matched>.+)\Z`, "m");
- static line = ctRegex!(`^(?P<matched>.+?)(?: ~|$)`, "m");
- static text = ctRegex!(`(?:^|\s~\s*)text:\s+(?P<matched>.+?)(?: ~|$)`, "m");
- static author = ctRegex!(`(?:^|\s~\s*)author:\s+(?P<matched>.+)$`, "m");
- static title = ctRegex!(`(?:^|\s~\s*)title:\s+(?P<matched>.+)$`, "m");
- static uid = ctRegex!(`(?:^|\s~\s*)uid:\s+(?P<matched>.+)$`, "m");
- static fn = ctRegex!(`(?:^|\s~\s*)fn:\s+(?P<matched>.+)$`, "m");
- static keywords = ctRegex!(`(?:^|\s~\s*)keywords:\s+(?P<matched>.+)$`, "m");
- static topic_register = ctRegex!(`(?:^|\s~\s*)topic_register:\s+(?P<matched>.+)$`, "m");
- static subject = ctRegex!(`(?:^|\s~\s*)subject:\s+(?P<matched>.+)$`, "m");
- static description = ctRegex!(`(?:^|\s~\s*)description:\s+(?P<matched>.+)$`, "m");
- static publisher = ctRegex!(`(?:^|\s~\s*)publisher:\s+(?P<matched>.+)$`, "m");
- static editor = ctRegex!(`(?:^|\s~\s*)editor:\s+(?P<matched>.+)$`, "m");
- static contributor = ctRegex!(`(?:^|\s~\s*)contributor:\s+(?P<matched>.+)$`, "m");
- static date = ctRegex!(`(?:^|\s~\s*)date:\s+(?P<matched>.+)$`, "m");
- static results_type = ctRegex!(`(?:^|\s~\s*)type:\s+(?P<matched>.+)$`, "m");
- static format = ctRegex!(`(?:^|\s~\s*)format:\s+(?P<matched>.+)$`, "m");
- static source = ctRegex!(`(?:^|\s~\s*)source:\s+(?P<matched>.+)$`, "m");
- static language = ctRegex!(`(?:^|\s~\s*)language:\s+(?P<matched>.+)$`, "m");
- static relation = ctRegex!(`(?:^|\s~\s*)relation:\s+(?P<matched>.+)$`, "m");
- static coverage = ctRegex!(`(?:^|\s~\s*)coverage:\s+(?P<matched>.+)$`, "m");
- static rights = ctRegex!(`(?:^|\s~\s*)rights:\s+(?P<matched>.+)$`, "m");
- static comment = ctRegex!(`(?:^|\s~\s*)comment:\s+(?P<matched>.+)$`, "m");
- // static abstract_ = ctRegex!(`(?:^|\s~\s*)abstract:\s+(?P<matched>.+)$`, "m");
- static src_filename_base = ctRegex!(`^src_filename_base:\s+(?P<matched>.+)$`, "m");
- }
- struct searchFields {
- string canned_query = ""; // GET canned_query == cq
- string search_text_area = ""; // POST search_text_area == tsa
- string text = ""; // text == txt
- string author = ""; // author == au
- string title = ""; // title == ti
- string uid = ""; // uid == uid
- string fn = ""; // fn == fn
- string keywords = ""; // keywords == kw
- string topic_register = ""; // topic_register == tr
- string subject = ""; // subject == su
- string description = ""; // description == de
- string publisher = ""; // publisher == pb
- string editor = ""; // editor == ed
- string contributor = ""; // contributor == ct
- string date = ""; // date == dt
- string format = ""; // format == fmt
- string source = ""; // source == src sfn
- string language = ""; // language == lng
- string relation = ""; // relation == rl
- string coverage = ""; // coverage == cv
- string rights = ""; // rights == rgt
- string comment = ""; // comment == cmt
- // string abstract = "";
- string src_filename_base = ""; // src_filename_base == bfn
- string results_type = ""; // results_type == rt radio
- string sql_match_limit = ""; // sql_match_limit == sml radio
- string sql_match_offset = ""; // sql_match_offset == smo
- string stats = ""; // stats == sts checked
- string echo = ""; // echo == ec checked
- string url = ""; // url == url checked
- string searched = ""; // searched == se checked
- string sql = ""; // sql == sql checked
- }
- auto rgx = Rgx();
- auto got = searchFields();
- if (environment.get("REQUEST_METHOD", "POST") == "POST") {
- if ("sf" in cgi.post) {
- got.search_text_area = cgi.post["sf"];
- if (auto m = got.search_text_area.matchFirst(rgx.text)) {
- got.text = m["matched"];
- got.canned_query ~= "sf=" ~ m["matched"];
- } else if (auto m = got.search_text_area.matchFirst(rgx.line)) {
- if (
- !(m["matched"].matchFirst(rgx.author))
- && !(m["matched"].matchFirst(rgx.title))
- ) {
- got.text = m["matched"];
- got.canned_query ~= "sf=" ~ m["matched"];
- }
- }
- if (auto m = got.search_text_area.matchFirst(rgx.author)) {
- got.author = m["matched"];
- got.canned_query ~= "&au=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.title)) {
- got.title = m["matched"];
- got.canned_query ~= "&ti=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.uid)) {
- got.uid = m["matched"];
- got.canned_query ~= "&uid=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.fn)) {
- got.fn = m["matched"];
- got.canned_query ~= "&fn=" ~ m["matched"];
- } else if ("fn" in cgi.post) {
- got.search_text_area ~= "\nfn: " ~ cgi.post["fn"] ~ "\n";
- }
- if (auto m = got.search_text_area.matchFirst(rgx.keywords)) {
- got.keywords = m["matched"];
- got.canned_query ~= "&kw=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.topic_register)) {
- got.topic_register = m["matched"];
- got.canned_query ~= "&tr=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.subject)) {
- got.subject = m["matched"];
- got.canned_query ~= "&su=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.description)) {
- got.description = m["matched"];
- got.canned_query ~= "&de=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.publisher)) {
- got.publisher = m["matched"];
- got.canned_query ~= "&pb=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.editor)) {
- got.editor = m["matched"];
- got.canned_query ~= "&ed=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.contributor)) {
- got.contributor = m["matched"];
- got.canned_query ~= "&ct=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.date)) {
- got.date = m["matched"];
- got.canned_query ~= "&dt=" ~ m["matched"];
- }
- // if (auto m = got.search_text_area.matchFirst(rgx.results_type)) {
- // got.results_type = m["matched"];
- // got.canned_query ~= "&rt=" ~ m["matched"];
- // }
- if (auto m = got.search_text_area.matchFirst(rgx.format)) {
- got.format = m["matched"];
- got.canned_query ~= "&fmt=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.source)) {
- got.source = m["matched"];
- got.canned_query ~= "&src=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.language)) {
- got.language = m["matched"];
- got.canned_query ~= "&lng=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.relation)) {
- got.relation = m["matched"];
- got.canned_query ~= "&rl=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.coverage)) {
- got.coverage = m["matched"];
- got.canned_query ~= "&cv=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.rights)) {
- got.rights = m["matched"];
- got.canned_query ~= "&rgt=" ~ m["matched"];
- }
- if (auto m = got.search_text_area.matchFirst(rgx.comment)) {
- got.comment = m["matched"];
- got.canned_query ~= "&cmt=" ~ m["matched"];
- }
- // if (auto m = search_text_area.matchFirst(rgx.abstract)) {
- // got.abstract = m["matched"];
- // }
- if (auto m = got.search_text_area.matchFirst(rgx.src_filename_base)) {
- got.src_filename_base = m["matched"];
- got.canned_query ~= "&bfn=" ~ m["matched"];
- }
- }
- if ("fn" in cgi.post) {
- got.fn = cgi.post["fn"];
- got.canned_query ~= "&fn=" ~ cgi.post["fn"];
- }
- if ("rt" in cgi.post) {
- got.results_type = cgi.post["rt"];
- got.canned_query ~= "&rt=" ~ cgi.post["rt"];
- }
- if ("sts" in cgi.post) {
- got.stats = cgi.post["sts"];
- got.canned_query ~= "&sts=" ~ cgi.post["sts"];
- }
- if ("ec" in cgi.post) {
- got.echo = cgi.post["ec"];
- got.canned_query ~= "&ec=" ~ cgi.post["ec"];
- }
- if ("url" in cgi.post) {
- got.url = cgi.post["url"];
- got.canned_query ~= "&url=" ~ cgi.post["url"];
- }
- if ("se" in cgi.post) {
- got.searched = cgi.post["se"];
- got.canned_query ~= "&se=" ~ cgi.post["se"];
- }
- if ("sql" in cgi.post) {
- got.sql = cgi.post["sql"];
- got.canned_query ~= "&sql=" ~ cgi.post["sql"];
- }
- if ("sml" in cgi.post) {
- got.sql_match_limit = cgi.post["sml"];
- got.canned_query ~= "&sml=" ~ cgi.post["sml"];
- }
- if ("smo" in cgi.post) {
- got.sql_match_offset = "0"; // cgi.post["smo"];
- got.canned_query ~= "&smo=0"; // ~ cgi.post["smo"];
- }
- got.canned_query = got.canned_query.strip.split(" ").join("%%20");
- conf.query_string = got.canned_query;
- // cgi.write("f.canned_query: " ~ got.canned_query ~ "<br>");
- } else if (environment.get("REQUEST_METHOD", "POST") == "GET") {
- got.canned_query = environment.get("QUERY_STRING", "");
- // cgi.write("f.canned_query: " ~ got.canned_query ~ "<br>");
- got.search_text_area = "";
- if ("sf" in canned_query && !(canned_query["sf"]).empty) {
- got.text = canned_query["sf"].split("%%20").join(" ");
- got.search_text_area ~= "text: " ~ got.text ~ "\n";
- }
- if ("au" in canned_query && !(canned_query["au"]).empty) {
- got.author = canned_query["au"].split("%%20").join(" ");
- got.search_text_area ~= "author: " ~ got.author ~ "\n";
- }
- if ("ti" in canned_query && !(canned_query["ti"]).empty) {
- got.title = canned_query["ti"].split("%%20").join(" ");
- got.search_text_area ~= "title: " ~ got.title ~ "\n";
- }
- if ("uid" in canned_query && !(canned_query["uid"]).empty) {
- got.uid = canned_query["uid"].split("%%20").join(" ");
- got.search_text_area ~= "uid: " ~ got.uid ~ "\n";
- }
- if ("fn" in canned_query && !(canned_query["fn"]).empty) {
- got.fn = canned_query["fn"].split("%%20").join(" ");
- got.search_text_area ~= "fn: " ~ got.fn ~ "\n";
- }
- if ("kw" in canned_query && !(canned_query["kw"]).empty) {
- got.keywords = canned_query["kw"].split("%%20").join(" ");
- got.search_text_area ~= "keywords: " ~ got.keywords ~ "\n";
- }
- if ("tr" in canned_query && !(canned_query["tr"]).empty) {
- got.topic_register = canned_query["tr"].split("%%20").join(" ");
- got.search_text_area ~= "topic_register: " ~ got.topic_register ~ "\n";
- }
- if ("su" in canned_query && !(canned_query["su"]).empty) {
- got.subject = canned_query["su"].split("%%20").join(" ");
- got.search_text_area ~= "subject: " ~ got.subject ~ "\n";
- }
- if ("de" in canned_query && !(canned_query["de"]).empty) {
- got.description = canned_query["de"].split("%%20").join(" ");
- got.search_text_area ~= "description: " ~ got.description ~ "\n";
- }
- if ("pb" in canned_query && !(canned_query["pb"]).empty) {
- got.publisher = canned_query["pb"].split("%%20").join(" ");
- got.search_text_area ~= "publisher: " ~ got.publisher ~ "\n";
- }
- if ("ed" in canned_query && !(canned_query["ed"]).empty) {
- got.editor = canned_query["ed"].split("%%20").join(" ");
- got.search_text_area ~= "editor: " ~ got.editor ~ "\n";
- }
- if ("ct" in canned_query && !(canned_query["ct"]).empty) {
- got.contributor = canned_query["ct"].split("%%20").join(" ");
- got.search_text_area ~= "contributor: " ~ got.contributor ~ "\n";
- }
- if ("dt" in canned_query && !(canned_query["dt"]).empty) {
- got.date = canned_query["dt"].split("%%20").join(" ");
- got.search_text_area ~= "date: " ~ got.date ~ "\n";
- }
- if ("rt" in canned_query && !(canned_query["rt"]).empty) {
- got.results_type = canned_query["rt"].split("%%20").join(" ");
- // got.search_text_area ~= "results_type: " ~ got.results_type ~ "\n";
- }
- if ("fmt" in canned_query && !(canned_query["fmt"]).empty) {
- got.format = canned_query["fmt"].split("%%20").join(" ");
- got.search_text_area ~= "format: " ~ got.format ~ "\n";
- }
- if ("src" in canned_query && !(canned_query["src"]).empty) {
- got.source = canned_query["src"].split("%%20").join(" ");
- got.search_text_area ~= "source: " ~ got.source ~ "\n";
- }
- if ("lng" in canned_query && !(canned_query["lng"]).empty) {
- got.language = canned_query["lng"].split("%%20").join(" ");
- got.search_text_area ~= "language: " ~ got.language ~ "\n";
- }
- if ("rl" in canned_query && !(canned_query["rl"]).empty) {
- got.relation = canned_query["rl"].split("%%20").join(" ");
- got.search_text_area ~= "relation: " ~ got.relation ~ "\n";
- }
- if ("cv" in canned_query && !(canned_query["cv"]).empty) {
- got.coverage = canned_query["cv"].split("%%20").join(" ");
- got.search_text_area ~= "coverage: " ~ got.coverage ~ "\n";
- }
- if ("rgt" in canned_query && !(canned_query["rgt"]).empty) {
- got.rights = canned_query["rgt"].split("%%20").join(" ");
- got.search_text_area ~= "rights: " ~ got.rights ~ "\n";
- }
- if ("cmt" in canned_query && !(canned_query["cmt"]).empty) {
- got.comment = canned_query["cmt"].split("%%20").join(" ");
- got.search_text_area ~= "comment: " ~ got.comment ~ "\n";
- }
- // if ("abstract" in canned_query && !(canned_query["abstract"]).empty) {
- // got.abstract = canned_query["abstract"];
- // }
- if ("bfn" in canned_query && !(canned_query["bfn"]).empty) { // search_field
- got.src_filename_base = canned_query["bfn"].split("%%20").join(" ");
- got.search_text_area ~= "src_filename_base: " ~ got.src_filename_base ~ "\n";
- }
- if ("sml" in canned_query && !(canned_query["sml"]).empty) {
- got.sql_match_limit = canned_query["sml"].split("%%20").join(" ");
- // got.search_text_area ~= "sql_match_limit: " ~ got.sql_match_limit ~ "\n";
- }
- // cgi.write("f.search_text_area: " ~ got.search_text_area ~ "<br>");
- }
- return got;
- }
- auto tf = text_fields; //
- struct SQL_select {
- string the_body = "";
- string the_range = "";
- }
- auto sql_select = SQL_select();
- string canned_url () {
- string _url = "";
- if (environment.get("REQUEST_METHOD", "POST") == "POST") {
- _url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ tf.canned_query;
- } else if (environment.get("REQUEST_METHOD", "POST") == "GET") {
- _url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ environment.get("QUERY_STRING", "");
- }
- return _url;
- }
- auto regex_canned_search () {
- static struct RgxCS {
- static track_offset = ctRegex!(`(?P<offset_key>[&]smo=)(?P<offset_val>[0-9]+)`);
- static results_type = ctRegex!(`[&]rt=(?P<results_type>idx|txt)`);
- static results_type_index = ctRegex!(`[&]rt=idx`);
- static results_type_text = ctRegex!(`[&]rt=txt`);
- static fn = ctRegex!(`[&]fn=(?P<fn>[^&]+)`);
- }
- return RgxCS();
- }
- string show_matched_objects (string fn) {
- auto rgx = regex_canned_search;
- string _matched_objects_text = "";
- string _url = canned_url;
- string _url_new = "";
- string _matches_show_text = "&rt=txt";
- string _matches_show_index = "&rt=idx";
- string _fn = "&fn=" ~ fn;
- _url_new = _url;
- if (_url_new.match(rgx.results_type_index)) {
- _url_new = _url_new.replace(rgx.results_type_index, _matches_show_text);
- } else if (_url.match(rgx.results_type_text)) {
- _url_new = _url_new.replace(rgx.results_type_text, _matches_show_index);
- } else {
- if (!(_url.match(rgx.results_type))) {
- _url_new = _url ~ _matches_show_text;
- }
- }
- if (!(_url_new.match(rgx.fn))) {
- _url_new = _url_new ~ _fn;
- }
- _matched_objects_text =
- "<font size=\"2\" color=\"#666666\">"
- ~ "<a href=\""
- ~ _url_new
- ~ "\">"
- ~ "※"
- ~ "</a></font>";
- return _matched_objects_text;
- }
- string base ; // = "";
- string tip ; // = "";
- string search_note ; // = "";
- uint sql_match_offset_count = 0;
- string previous_next () {
- auto rgx = regex_canned_search;
- string _previous_next = "";
- int _current_offset_value = 0;
- string _set_offset_next = "";
- string _set_offset_previous = "";
- string _url = canned_url;
- string _url_previous = "";
- string _url_next = "";
- string arrow_previous = "";
- string arrow_next = "";
- if (auto m = _url.matchFirst(rgx.track_offset)) {
- _current_offset_value = m.captures["offset_val"].to!int;
- _set_offset_next = m.captures["offset_key"] ~ ((m.captures["offset_val"]).to!int + cv.sql_match_limit.to!int).to!string;
- _url_next = _url.replace(rgx.track_offset, _set_offset_next);
- if (_current_offset_value < cv.sql_match_limit.to!int) {
- _url_previous = "";
- } else {
- _url_previous = "";
- _set_offset_previous = m.captures["offset_key"] ~ ((m.captures["offset_val"]).to!int - cv.sql_match_limit.to!int).to!string;
- _url_previous = _url.replace(rgx.track_offset, _set_offset_previous);
- }
- } else {// _current_offset_value = 0;
- _url_next = _url ~= "&smo=" ~ cv.sql_match_limit.to!string;
- }
- if (_url_previous.empty) {
- arrow_previous = "";
- } else {
- arrow_previous =
- "<font size=\"2\" color=\"#666666\">"
- ~ "<a href=\""
- ~ _url_previous
- ~ "\">"
- ~ "&lt;&lt prev"
- ~ "</a> || </font>";
- }
- arrow_next =
- "<font size=\"2\" color=\"#666666\">"
- ~ "<a href=\""
- ~ _url_next
- ~ "\">"
- ~ "next &gt;&gt"
- ~ "</a></font>";
- _previous_next = "<hr>" ~ arrow_previous ~ arrow_next;
- return _previous_next;
- }
- {
- header = format(q"┃
-<!DOCTYPE html>
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>
- %s
- </title>
- <meta name="sourcefile" content="SiSU.sst">
- <link rel="generator" href="sisudoc.org">
- <link rel="shortcut icon" href="https://%%s/image_sys/spine.ico">
- <style media = "all">
- *{
- padding : 0px;
- margin : 2px;
- }
- body {
- height : 100vh;
- background-color : #%s;
- }
- body {
- color : #%s;
- background : #%s;
- background-color : #%s;
- }
- a:link {
- color : #%s;
- text-decoration : none;
- }
- a:visited {
- color : #%s;
- text-decoration : none;
- }
- a:hover {
- color : #%s;
- background-color : #%s;
- }
- a.lnkocn:link {
- color : #%s;
- text-decoration : none;
- }
- a.lnkocn:visited {
- color : #%s;
- text-decoration : none;
- }
- a.lnkocn:hover {
- color : #%s;
- font-size : 15px;
- }
- a:hover img {
- background-color : #%s;
- }
- a:active {
- color : #%s;
- text-decoration : underline;
- }
- .flex-container {
- display : flex;
- }
- div.publication {
- margin-top : 2px;
- margin-bottom : 4px;
- margin-left : 0%%%%;
- margin-right : 0%%%%;
- }
- div.textview_ocn {
- margin-left : 0%%%%;
- margin-right : 1%%%%;
- }
- div.textview_found {
- margin-left : 1%%%%;
- margin-right : 1%%%%;
- }
- textarea {
- color : #%s;
- background-color : #%s;
- }
- span.match {
- color : #%s;
- background-color : #%s;
- }
- p.norm { }
- p.center { text-align : center; }
- p.i1 { padding-left : 1em; }
- p.i2 { padding-left : 2em; }
- p.i3 { padding-left : 3em; }
- p.i4 { padding-left : 4em; }
- p.i5 { padding-left : 5em; }
- p.i6 { padding-left : 6em; }
- p.i7 { padding-left : 7em; }
- p.i8 { padding-left : 8em; }
- p.i9 { padding-left : 9em; }
- /* hanging indent */
- p[indent="h0i0"] {
- padding-left : 0em;
- text-indent : 0em;
- }
- p.publication {
- font-size : 100%%%%;
- margin-left : 0em;
- margin-top : 0px;
- margin-bottom : 0px;
- margin-right : 6px;
- text-align : left;
- }
- p.ocn_is {
- font-size : 100%%%%;
- display : inline-block;
- }
- p.matched_ocn {
- font-size : 90%%%%;
- margin-left : 2em;
- margin-top : 0px;
- margin-bottom : 0px;
- margin-right : 6px;
- text-align : left;
- }
- p[indent="h0i1"] {
- padding-left : 1em;
- text-indent : -1em;
- }
- p[indent="h0i2"] {
- padding-left : 2em;
- text-indent : -2em;
- }
- p[indent="h0i3"] {
- padding-left : 3em;
- text-indent : -3em;
- }
- p[indent="h0i4"] {
- padding-left : 4em;
- text-indent : -4em;
- }
- p[indent="h0i5"] {
- padding-left : 5em;
- text-indent : -5em;
- }
- p[indent="h0i6"] {
- padding-left : 6em;
- text-indent : -6em;
- }
- p[indent="h0i7"] {
- padding-left : 7em;
- text-indent : -7em;
- }
- p[indent="h0i8"] {
- padding-left : 8em;
- text-indent : -8em;
- }
- p[indent="h0i9"] {
- padding-left : 9em;
- text-indent : -9em;
- }
- p[indent="h1i0"] {
- padding-left : 0em;
- text-indent : 1em;
- }
- p[indent="h1i1"] {
- padding-left : 1em;
- text-indent : 0em;
- }
- p[indent="h1i2"] {
- padding-left : 2em;
- text-indent : -1em;
- }
- p[indent="h1i3"] {
- padding-left : 3em;
- text-indent : -2em;
- }
- p[indent="h1i4"] {
- padding-left : 4em;
- text-indent : -3em;
- }
- p[indent="h1i5"] {
- padding-left : 5em;
- text-indent : -4em;
- }
- p[indent="h1i6"] {
- padding-left : 6em;
- text-indent : -5em;
- }
- p[indent="h1i7"] {
- padding-left : 7em;
- text-indent : -6em;
- }
- p[indent="h1i8"] {
- padding-left : 8em;
- text-indent : -7em;
- }
- p[indent="h1i9"] {
- padding-left : 9em;
- text-indent : -8em;
- }
- p[indent="h2i0"] {
- padding-left : 0em;
- text-indent : 2em;
- }
- p[indent="h2i1"] {
- padding-left : 1em;
- text-indent : 1em;
- }
- p[indent="h2i2"] {
- padding-left : 2em;
- text-indent : 0em;
- }
- p[indent="h2i3"] {
- padding-left : 3em;
- text-indent : -1em;
- }
- p[indent="h2i4"] {
- padding-left : 4em;
- text-indent : -2em;
- }
- p[indent="h2i5"] {
- padding-left : 5em;
- text-indent : -3em;
- }
- p[indent="h2i6"] {
- padding-left : 6em;
- text-indent : -4em;
- }
- p[indent="h2i7"] {
- padding-left : 7em;
- text-indent : -5em;
- }
- p[indent="h2i8"] {
- padding-left : 8em;
- text-indent : -6em;
- }
- p[indent="h2i9"] {
- padding-left : 9em;
- text-indent : -7em;
- }
- p[indent="h3i0"] {
- padding-left : 0em;
- text-indent : 3em;
- }
- p[indent="h3i1"] {
- padding-left : 1em;
- text-indent : 2em;
- }
- p[indent="h3i2"] {
- padding-left : 2em;
- text-indent : 1em;
- }
- p[indent="h3i3"] {
- padding-left : 3em;
- text-indent : 0em;
- }
- p[indent="h3i4"] {
- padding-left : 4em;
- text-indent : -1em;
- }
- p[indent="h3i5"] {
- padding-left : 5em;
- text-indent : -2em;
- }
- p[indent="h3i6"] {
- padding-left : 6em;
- text-indent : -3em;
- }
- p[indent="h3i7"] {
- padding-left : 7em;
- text-indent : -4em;
- }
- p[indent="h3i8"] {
- padding-left : 8em;
- text-indent : -5em;
- }
- p[indent="h3i9"] {
- padding-left : 9em;
- text-indent : -6em;
- }
- p[indent="h4i0"] {
- padding-left : 0em;
- text-indent : 4em;
- }
- p[indent="h4i1"] {
- padding-left : 1em;
- text-indent : 3em;
- }
- p[indent="h4i2"] {
- padding-left : 2em;
- text-indent : 2em;
- }
- p[indent="h4i3"] {
- padding-left : 3em;
- text-indent : 1em;
- }
- p[indent="h4i4"] {
- padding-left : 4em;
- text-indent : 0em;
- }
- p[indent="h4i5"] {
- padding-left : 5em;
- text-indent : -1em;
- }
- p[indent="h4i6"] {
- padding-left : 6em;
- text-indent : -2em;
- }
- p[indent="h4i7"] {
- padding-left : 7em;
- text-indent : -3em;
- }
- p[indent="h4i8"] {
- padding-left : 8em;
- text-indent : -4em;
- }
- p[indent="h4i9"] {
- padding-left : 9em;
- text-indent : -5em;
- }
- p[indent="h5i0"] {
- padding-left : 0em;
- text-indent : 5em;
- }
- p[indent="h5i1"] {
- padding-left : 1em;
- text-indent : 4em;
- }
- p[indent="h5i2"] {
- padding-left : 2em;
- text-indent : 3em;
- }
- p[indent="h5i3"] {
- padding-left : 3em;
- text-indent : 2em;
- }
- p[indent="h5i4"] {
- padding-left : 4em;
- text-indent : 1em;
- }
- p[indent="h5i5"] {
- padding-left : 5em;
- text-indent : 0em;
- }
- p[indent="h5i6"] {
- padding-left : 6em;
- text-indent : -1em;
- }
- p[indent="h5i7"] {
- padding-left : 7em;
- text-indent : -2em;
- }
- p[indent="h5i8"] {
- padding-left : 8em;
- text-indent : -3em;
- }
- p[indent="h5i9"] {
- padding-left : 9em;
- text-indent : -4em;
- }
- p[indent="h6i0"] {
- padding-left : 0em;
- text-indent : 6em;
- }
- p[indent="h6i1"] {
- padding-left : 1em;
- text-indent : 5em;
- }
- p[indent="h6i2"] {
- padding-left : 2em;
- text-indent : 4em;
- }
- p[indent="h6i3"] {
- padding-left : 3em;
- text-indent : 3em;
- }
- p[indent="h6i4"] {
- padding-left : 4em;
- text-indent : 2em;
- }
- p[indent="h6i5"] {
- padding-left : 5em;
- text-indent : 1em;
- }
- p[indent="h6i6"] {
- padding-left : 6em;
- text-indent : 0em;
- }
- p[indent="h6i7"] {
- padding-left : 7em;
- text-indent : -1em;
- }
- p[indent="h6i8"] {
- padding-left : 8em;
- text-indent : -2em;
- }
- p[indent="h6i9"] {
- padding-left : 9em;
- text-indent : -3em;
- }
- p[indent="h7i0"] {
- padding-left : 0em;
- text-indent : 7em;
- }
- p[indent="h7i1"] {
- padding-left : 1em;
- text-indent : 6em;
- }
- p[indent="h7i2"] {
- padding-left : 2em;
- text-indent : 5em;
- }
- p[indent="h7i3"] {
- padding-left : 3em;
- text-indent : 4em;
- }
- p[indent="h7i4"] {
- padding-left : 4em;
- text-indent : 3em;
- }
- p[indent="h7i5"] {
- padding-left : 5em;
- text-indent : 2em;
- }
- p[indent="h7i6"] {
- padding-left : 6em;
- text-indent : 1em;
- }
- p[indent="h7i7"] {
- padding-left : 7em;
- text-indent : 0em;
- }
- p[indent="h7i8"] {
- padding-left : 8em;
- text-indent : -1em;
- }
- p[indent="h7i9"] {
- padding-left : 9em;
- text-indent : -2em;
- }
- p[indent="h8i0"] {
- padding-left : 0em;
- text-indent : 8em;
- }
- p[indent="h8i1"] {
- padding-left : 1em;
- text-indent : 7em;
- }
- p[indent="h8i2"] {
- padding-left : 2em;
- text-indent : 6em;
- }
- p[indent="h8i3"] {
- padding-left : 3em;
- text-indent : 5em;
- }
- p[indent="h8i4"] {
- padding-left : 4em;
- text-indent : 4em;
- }
- p[indent="h8i5"] {
- padding-left : 5em;
- text-indent : 3em;
- }
- p[indent="h8i6"] {
- padding-left : 6em;
- text-indent : 2em;
- }
- p[indent="h8i7"] {
- padding-left : 7em;
- text-indent : 1em;
- }
- p[indent="h8i8"] {
- padding-left : 8em;
- text-indent : 0em;
- }
- p[indent="h8i9"] {
- padding-left : 9em;
- text-indent : -1em;
- }
- p[indent="h9i0"] {
- padding-left : 0em;
- text-indent : 9em;
- }
- p[indent="h9i1"] {
- padding-left : 1em;
- text-indent : 8em;
- }
- p[indent="h9i2"] {
- padding-left : 2em;
- text-indent : 7em;
- }
- p[indent="h9i3"] {
- padding-left : 3em;
- text-indent : 6em;
- }
- p[indent="h9i4"] {
- padding-left : 4em;
- text-indent : 5em;
- }
- p[indent="h9i5"] {
- padding-left : 5em;
- text-indent : 4em;
- }
- p[indent="h9i6"] {
- padding-left : 6em;
- text-indent : 3em;
- }
- p[indent="h9i7"] {
- padding-left : 7em;
- text-indent : 2em;
- }
- p[indent="h9i8"] {
- padding-left : 8em;
- text-indent : 1em;
- }
- p[indent="h9i9"] {
- padding-left : 9em;
- text-indent : 0em;
- }
- p.spaced { white-space : pre; }
- p.block {
- white-space : pre;
- }
- p.group { }
- p.alt { }
- p.verse {
- white-space : pre;
- margin-bottom : 6px;
- }
- p.caption {
- text-align : left;
- font-size : 80%%%%;
- display : inline;
- }
- p.endnote {
- font-size : 96%%%%;
- line-height : 120%%%%;
- text-align : left;
- margin-right : 15mm;
- padding-left : 1em;
- text-indent : -1em;
- }
- p.center {
- text-align : center;
- }
- p.bold {
- font-weight : bold;
- }
- p.bold_left {
- font-weight : bold;
- text-align : left;
- }
- p.centerbold {
- text-align : center;
- font-weight : bold;
- }
- p.em {
- font-weight : bold;
- font-style : normal;
- background : #FFF3B6;
- }
- p.small {
- font-size : 80%%%%;
- margin-top : 0px;
- margin-bottom : 0px;
- margin-right : 6px;
- text-align : left;
- }
- .tiny, .tiny_left, .tiny_right, .tiny_center {
- font-size : 10px;
- margin-top : 0px;
- margin-bottom : 0px;
- color : #EEEEEE;
- margin-right : 6px;
- text-align : left;
- }
- p.tiny { }
- p.tiny_left {
- margin-left : 0px;
- margin-right : 0px;
- text-align : left;
- }
- p.tiny_right {
- margin-right : 1em;
- text-align : right;
- }
- p.tiny_center {
- margin-left : 0px;
- margin-right : 0px;
- text-align : center;
- }
- p.book_index_lev1 {
- line-height : 100%%%%;
- margin-top : 4px;
- margin-bottom : 1px;
- }
- p.book_index_lev2 {
- line-height : 100%%%%;
- text-align : left;
- margin-left : 3em;
- margin-top : 1px;
- margin-bottom : 3px;
- }
- tt {
- font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace;
- background-color : #555555;
- color : #DDDDDD;
- }
- pre {
- width : auto;
- display : block;
- clear : both;
- color : #555555;
- }
- pre.codeline {
- display : table;
- clear : both;
- table-layout : fixed;
- margin-left : 5%%%%;
- margin-right : 5%%%%;
- width : 90%%%%;
- white-space : pre-wrap;
- border-style : none;
- border-radius : 5px 5px 5px 5px;
- box-shadow : 0 2px 5px #AAAAAA inset;
- margin-bottom : 1em;
- padding : 0.5em 1em;
- page-break-inside : avoid;
- word-wrap : break-word;
- font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace;
- white-space : pre;
- white-space : pre-wrap;
- white-space : -moz-pre-wrap;
- white-space : -o-pre-wrap;
- background-color : #555555;
- color : #DDDDDD;
- font-size : 95%%%%;
- line-height : 100%%%%;
- }
- pre.codeline::before {
- counter-reset : linenum;
- }
- pre.codeline span.tr {
- display : table-row;
- counter-increment : linenum;
- }
- pre.codeline span.th {
- display : table-cell;
- user-select : none;
- -moz-user-select : none;
- -webkit-user-select : none;
- padding : 0.5em 0.5em;
- }
- pre.codeline span.th::before {
- content : counter(linenum) ".";
- color : #999999;
- text-align : right;
- display : block;
- }
- pre.codeline span.th {
- width : 4em;
- }
- pre.codeline code {
- display : table-cell;
- }
- p.code {
- border-style : none;
- }
- note { white-space : pre; }
- em {
- font-weight : bold;
- font-style : italic;
- }
- p.left,th.left,td.left {
- text-align : left;
- }
- p.small_left,th.small_left,td.small_left {
- text-align : left;
- font-size : 80%%%%;
- }
- p.right,th.right,td.right {
- text-align : right;
- }
- ul, li {
- list-style-type : none;
- list-style : none;
- padding-left : 20px;
- font-weight : normal;
- line-height : 150%%%%;
- text-align : left;
- text-indent : 0mm;
- margin-left : 1em;
- margin-right : 2em;
- margin-top : 3px;
- margin-bottom : 3px;
- }
- li {
- background : (../image_sys/bullet_09.png) no-repeat 0px 6px;
- }
- ul { }
- h0, h1, h2, h3, h4, h5, h6, h7 {
- font-weight : bold;
- line-height : 120%%%%;
- text-align : left;
- margin-top : 20px;
- margin-bottom : 10px;
- }
- h4.norm, h5.norm, h6.norm, h7.norm {
- margin-top : 10px;
- margin-bottom : 0px;
- }
- h0 { font-size : 125%%%%; }
- h1 { font-size : 120%%%%; }
- h2 { font-size : 115%%%%; }
- h3 { font-size : 110%%%%; }
- h4 { font-size : 105%%%%; }
- h5 { font-size : 100%%%%; }
- h6 { font-size : 100%%%%; }
- h7 { font-size : 100%%%%; }
- h0, h1, h2, h3, h4, h5, h6, h7 {
- text-shadow : .2em .2em .3em #999999;
- }
- h1.i { margin-left : 2em; }
- h2.i { margin-left : 3em; }
- h3.i { margin-left : 4em; }
- h4.i { margin-left : 5em; }
- h5.i { margin-left : 6em; }
- h6.i { margin-left : 7em; }
- h7.i { margin-left : 8em; }
- h8.i { margin-left : 9em; }
- h9.i { margin-left : 10em; }
- .toc {
- font-weight : normal;
- margin-top : 6px;
- margin-bottom : 6px;
- }
- h0.toc {
- margin-left : 1em;
- font-size : 120%%%%;
- line-height : 150%%%%;
- }
- h1.toc {
- margin-left : 1em;
- font-size : 115%%%%;
- line-height : 150%%%%;
- }
- h2.toc {
- margin-left : 2em;
- font-size : 110%%%%;
- line-height : 140%%%%;
- }
- h3.toc {
- margin-left : 3em;
- font-size : 105%%%%;
- line-height : 120%%%%;
- }
- h4.toc {
- margin-left : 4em;
- font-size : 100%%%%;
- line-height : 120%%%%;
- }
- h5.toc {
- margin-left : 5em;
- font-size : 95%%%%;
- line-height : 110%%%%;
- }
- h6.toc {
- margin-left : 6em;
- font-size : 90%%%%;
- line-height : 110%%%%;
- }
- h7.toc {
- margin-left : 7em;
- font-size : 85%%%%;
- line-height : 100%%%%;
- }
- .subtoc {
- margin-right : 34%%%%;
- font-weight : normal;
- }
- h5.subtoc {
- margin-left : 2em;
- font-size : 80%%%%;
- margin-top : 2px;
- margin-bottom : 2px;
- }
- h6.subtoc {
- margin-left : 3em;
- font-size : 75%%%%;
- margin-top : 0px;
- margin-bottom : 0px;
- }
- h7.subtoc {
- margin-left : 4em;
- font-size : 70%%%%;
- margin-top : 0px;
- margin-bottom : 0px;
- }
- hr {
- display : block;
- height : 1px;
- width : 100%%%%;
- border : 0;
- border-top : 1px solid #AAAAAA;
- border-color : #AAAAAA
- background-color : #AAAAAA
- margin-left : 0%%%%;
- margin-right : 0em;
- margin-top : 0.5em;
- margin-bottom : 0.5em;
- padding : 0;
- }
-</style>
-</head>
-<body lang="en" xml:lang="en">
-┃",
- conf.http_host,
- );
- }
- {
- table = format(q"┃
-<table summary="band" border="0" cellpadding="2" cellspacing="0">
-<tr><td width="20%%%%">
- <table summary="home button / home information" border="0" cellpadding="2" cellspacing="0">
- <tr><td align="left">
- %s
- </td></tr>
- </table>
-</td>
-<td>
-</td></tr>
-</table>
-┃");
- }
- {
- string post_value(string field_name, string type="box", string set="on") {
- string val = "";
- switch (type) {
- case "field":
- val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
- ? cgi.post[field_name]
- : (field_name in cgi.get)
- ? cgi.get[field_name]
- : "");
- val = tf.search_text_area;
- break;
- case "box": // generic for checkbox or radio; checkbox set == "on" radio set == "name set"
- val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
- ? (cgi.post[field_name] == set ? "checked" : "off")
- : (field_name in cgi.get)
- ? (cgi.get[field_name] == set ? "checked" : "off")
- : "off");
- break;
- case "radio": // used generic bo
- val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
- ? (cgi.post[field_name] == set ? "checked" : "off")
- : (field_name in cgi.get)
- ? (cgi.get[field_name] == set ? "checked" : "off")
- : "checked");
- break;
- case "checkbox": // used generic bo
- val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
- ? (cgi.post[field_name] == set ? "checked" : "off")
- : (field_name in cgi.get)
- ? (cgi.get[field_name] == set ? "checked" : "off")
- : "checked");
- break;
- default:
- }
- return val;
- }
- string the_can(string fv) {
- string show_the_can = post_value("url");
- string _the_can = "";
- if (show_the_can == "checked") {
- tf = text_fields;
- string method_get_url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ environment.get("QUERY_STRING", "");
- string method_post_url_construct = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ tf.canned_query;
- // assert(method_get_url == environment.get("HTTP_REFERER", conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ conf.query_string));
- if (conf.request_method == "POST") {
- _the_can =
- "<font size=\"2\" color=\"#666666\">"
- ~ "POST:&nbsp;"
- ~ "<a href=\""
- ~ method_post_url_construct
- ~ "\">"
- ~ method_post_url_construct
- ~ "</a></font>"
- ~ "<br>";
- } else if (conf.request_method == "GET") {
- _the_can =
- "<font size=\"2\" color=\"#666666\">"
- ~ "GET:&nbsp;&nbsp;"
- ~ "<a href=\""
- ~ method_get_url
- ~ "\">"
- ~ method_get_url
- ~ "</a></font>";
- }
- conf.http_url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ tf.canned_query;
- }
- return _the_can;
- }
- string provide_tip() {
- string searched_tip = post_value("se");
- string tip = "";
- if (searched_tip == "checked") {
- string search_field = post_value("sf", "field");
- tf = text_fields;
- tip = format(q"┃
-<font size="2" color="#666666">
-<b>database:</b> <font size="2" color="#004000">%%s</font>; <b>selected view:</b> <font size="2" color="#004000">index</font>
-<b>search string:</b> %%s %%s %%s %%s %%s %%s<br>
-%%s %%s %%s %%s %%s %%s
-</font>
-┃",
- cv.db_selected,
- (tf.text.empty ? "" : "\"text: <font size=\"2\" color=\"#004000\">" ~ tf.text ~ "</font>; "),
- (tf.title.empty ? "" : "\"title: <font size=\"2\" color=\"#004000\">" ~ tf.title ~ "</font>; "),
- (tf.author.empty ? "" : "\"author: <font size=\"2\" color=\"#004000\">" ~ tf.author ~ "</font>; "),
- (tf.date.empty ? "" : "\"date <font size=\"2\" color=\"#004000\">" ~ tf.date ~ "</font>; "),
- (tf.uid.empty ? "" : "\"uid: <font size=\"2\" color=\"#004000\">" ~ tf.uid ~ "</font>; "),
- (tf.fn.empty ? "" : "\"fn: <font size=\"2\" color=\"#004000\">" ~ tf.fn ~ "</font>; "),
- (tf.text.empty ? "" : "text: <font size=\"2\" color=\"#004000\">" ~ tf.text ~ "</font><br>"),
- (tf.title.empty ? "" : "title: <font size=\"2\" color=\"#004000\">" ~ tf.title ~ "</font><br>"),
- (tf.author.empty ? "" : "author: <font size=\"2\" color=\"#004000\">" ~ tf.author ~ "</font><br>"),
- (tf.date.empty ? "" : "date: <font size=\"2\" color=\"#004000\">" ~ tf.date ~ "</font><br>"),
- (tf.uid.empty ? "" : "\"uid: <font size=\"2\" color=\"#004000\">" ~ tf.uid ~ "</font>; "),
- (tf.fn.empty ? "" : "\"fn: <font size=\"2\" color=\"#004000\">" ~ tf.fn ~ "</font>; "),
- );
- }
- return tip;
- }
- form = format(q"┃
-<form action="%%s" id="SubmitForm" method="post" accept-charset="UTF-8">
- <table cellpadding="2">
- <tr><td valign=\"top\">
- <textarea id="find" name="sf" type="text" rows="6" cols="40" maxlength="256" wrap="virtual">%%s</textarea>
- </td>
- <td valign=\"top\">
- %%s
- %%s
- %%s
- </td></tr></table>
- <td valign=\"top\"><tr><td>
- <font size="2" color="#%s">
- <input type="hidden" name="db" value="%%s">
- <input type="submit" value="SiSU search">
- <input type="radio" name="rt" id="results_type_index" value="idx" %%s> index
- <input type="radio" name="rt" id="results_type_text" value="txt" %%s> text / grep;
- match limit:
- <input type="radio" name="sml" id="sql_match_limit_1000" value="1000" %%s> 1,000
- <input type="radio" name="sml" id="sql_match_limit_2500" value="2500" %%s> 2,500
- <br>
- <input type="checkbox" name="ec" %%s> echo query
- <input type="checkbox" name="url" %%s> search url
- <input type="checkbox" name="se" %%s> searched
- <input type="checkbox" name="sql" %%s> sql statement
- <input type="hidden" name="smo" value="0">
- <br>
- </font>
- </td></tr>
- </table>
-</form>
-┃",
- "%s",
- (post_value("ec") == "checked") ? post_value("sf", "field") : "",
- provide_tip,
- search_note,
- the_can(post_value("sf", "field")),
- cv.db_selected,
- post_value("rt", "box", "idx"),
- post_value("rt", "box", "txt"),
- post_value("sml", "box", "1000"),
- post_value("sml", "box", "2500"),
- post_value("ec"),
- post_value("url"),
- post_value("se"),
- post_value("sql"),
- );
- {
- string set_value(string field_name, string default_val) {
- string val;
- if (field_name in cgi.post) {
- val = cgi.post[field_name];
- } else if (field_name in cgi.get) {
- val = cgi.get[field_name];
- } else { val = default_val; }
- return val;
- }
- bool set_bool(string field_name) {
- bool val;
- if (field_name in cgi.post
- && cgi.post[field_name] == "on") {
- val = true;
- } else if (field_name in cgi.get
- && cgi.get[field_name] == "on") {
- val = true;
- } else { val = false; }
- return val;
- }
- cv.db_selected = set_value("selected_db", "%s"); // selected_db_name == db (spine.search.db or whatever)
- cv.sql_match_limit = set_value("sml", "1000");
- cv.sql_match_offset = set_value("smo", "0");
- cv.search_text = set_value("sf", "");
- cv.results_type = set_value("rt", "idx");
- cv.checked_echo = set_bool("ec");
- cv.checked_stats = set_bool("sts");
- cv.checked_url = set_bool("url");
- cv.checked_searched = set_bool("se");
- cv.checked_tip = set_bool("tip");
- cv.checked_sql = set_bool("sql");
- tf = text_fields;
- }
- }
- {
- cgi.write(header);
- cgi.write(table);
- cgi.write(form);
- // cgi.write(previous_next);
- { // debug environment
- // foreach (k, d; environment.toAA) {
- // cgi.write(k ~ ": " ~ d ~ "<br>");
- // }
- }
- { // debug cgi info
- // cgi.write("db_selected: " ~ cv.db_selected ~ "<br>\n");
- // cgi.write("search_text: " ~ cv.search_text ~ "<br>\n");
- // cgi.write("sql_match_limit: " ~ cv.sql_match_limit ~ ";\n");
- // cgi.write("sql_match_offset: " ~ cv.sql_match_offset ~ ";\n");
- // cgi.write("results_type: " ~ cv.results_type ~ "<br>\n");
- // cgi.write("cv.checked_echo: " ~ (cv.checked_echo ? "checked" : "off") ~ "; \n");
- // cgi.write("cv.checked_stats: " ~ (cv.checked_stats ? "checked" : "off") ~ "; \n");
- // cgi.write("cv.checked_url: " ~ (cv.checked_url ? "checked" : "off") ~ "; \n");
- // cgi.write("cv.checked_searched: " ~ (cv.checked_searched ? "checked" : "off") ~ ";<br>\n");
- // cgi.write("cv.checked_tip: " ~ (cv.checked_tip ? "checked" : "off") ~ "; \n");
- // cgi.write("cv.checked_sql: " ~ (cv.checked_sql ? "checked" : "off") ~ "<br>\n");
- }
- }
- auto db = Database(conf.db_path ~ cv.db_selected);
- {
- uint sql_match_offset_counter(T)(T cv) {
- sql_match_offset_count += cv.sql_match_limit.to!uint;
- return sql_match_offset_count;
- }
- void sql_search_query() {
- string highlight_text_matched(string _txt, string search_field) {
- string _mark_open = "┤";
- string _mark_close = "├";
- string _span_match = "<span class=\"match\">";
- string _span_close = "</span>";
- string _sf_str = search_field.strip.split("%%20").join(" ").strip;
- string[] _sf_arr = _sf_str.split(regex(r"\s+AND\s+|\s+OR\s+"));
- auto rgx_url = regex(r"<a href=[^>]+?>");
- foreach (_sf; _sf_arr) {
- auto rgx_matched_text = regex(_sf, "i");
- auto rgx_marked_pair = regex(r"┤(?P<keep>" ~ _sf ~ ")├", "i");
- if (auto m = _txt.matchFirst(rgx_url)) {
- _txt = replaceAll!(m =>
- _mark_open
- ~ m.captures[0]
- ~ _mark_close
- )(_txt, rgx_matched_text);
- _txt = replaceAll!(m =>
- replaceAll!(u =>
- u["keep"]
- )(m.hit, rgx_marked_pair)
- )(_txt, rgx_url);
- _txt = replaceAll!(m =>
- _span_match
- ~ m["keep"]
- ~ _span_close
- )(_txt, rgx_marked_pair);
- } else {
- _txt = replaceAll!(m =>
- _span_match
- ~ m.captures[0]
- ~ _span_close
- )(_txt, rgx_matched_text);
- }
- }
- return _txt;
- }
- string select_field_like(string db_field, string search_field) {
- string where_ = "";
- if (!(search_field.empty)) {
- string _sf = search_field.strip.split("%%20").join(" ");
- if (_sf.match(r" OR ")) {
- _sf = _sf.split(" OR ").join("%%' OR " ~ db_field ~ " LIKE '%%");
- }
- if (_sf.match(r" AND ")) {
- _sf = _sf.split(" AND ").join("%%' AND " ~ db_field ~ " LIKE '%%");
- }
- _sf = "( " ~ db_field ~ " LIKE\n '%%" ~ _sf ~ "%%' )";
- where_ ~= format(q"┃
- %%s
-┃",
- _sf
- );
- }
- return where_;
- }
- string[] _fields;
- _fields ~= select_field_like("doc_objects.clean", tf.text);
- _fields ~= select_field_like("metadata_and_text.title", tf.title);
- _fields ~= select_field_like("metadata_and_text.creator_author", tf.author);
- _fields ~= select_field_like("metadata_and_text.uid", tf.uid);
- _fields ~= select_field_like("metadata_and_text.src_filename_base", tf.fn);
- _fields ~= select_field_like("metadata_and_text.src_filename_base", tf.src_filename_base);
- _fields ~= select_field_like("metadata_and_text.language_document_char", tf.language);
- _fields ~= select_field_like("metadata_and_text.date_published", tf.date);
- _fields ~= select_field_like("metadata_and_text.classify_keywords", tf.keywords);
- _fields ~= select_field_like("metadata_and_text.classify_topic_register", tf.topic_register);
- string[] fields;
- foreach (f; _fields) {
- if (!(f.empty)) { fields ~= f; }
- }
- string fields_str = "";
- fields_str ~= fields.join(" AND ");
- sql_select.the_body ~= format(q"┃
-SELECT
- metadata_and_text.uid,
- metadata_and_text.title,
- metadata_and_text.creator_author_last_first,
- metadata_and_text.creator_author,
- metadata_and_text.src_filename_base,
- metadata_and_text.language_document_char,
- metadata_and_text.date_published,
- metadata_and_text.classify_keywords,
- metadata_and_text.classify_topic_register,
- doc_objects.body,
- doc_objects.seg_name,
- doc_objects.ocn,
- metadata_and_text.uid
-FROM
- doc_objects,
- metadata_and_text
-WHERE (
- %%s
- )
-AND
- doc_objects.uid_metadata_and_text = metadata_and_text.uid
-ORDER BY
- metadata_and_text.creator_author_last_first,
- metadata_and_text.date_published DESC,
- metadata_and_text.title,
- metadata_and_text.language_document_char,
- metadata_and_text.src_filename_base,
- doc_objects.ocn
-LIMIT %%s OFFSET %%s
-;┃",
- fields_str,
- cv.sql_match_limit,
- cv.sql_match_offset,
- );
- (cv.checked_sql)
- ? cgi.write(previous_next
- ~ "<hr><font size=\"2\" color=\"#666666\">"
- ~ sql_select.the_body.strip.split("\n ").join(" ").split("\n").join("<br>")
- ~ "</font>\n"
- )
- : "";
- cgi.write(previous_next);
- auto select_query_results = db.execute(sql_select.the_body).cached;
- string _old_uid = "";
- if (!select_query_results.empty) {
- string _date_published = "0000";
- string _close_para = "";
- string _matched_ocn_open = "";
- foreach (idx, row; select_query_results) {
- if (row["uid"].as!string != _old_uid) {
- _close_para = (idx == 1) ? "" : "</p>";
- _matched_ocn_open = (idx == 1) ? "" : "<p class=\"matched_ocn\">";
- _old_uid = row["uid"].as!string;
- _date_published = (row["date_published"].as!string.match(regex(r"^([0-9]{4})")))
- ? row["date_published"].as!string : "0000"; // used in regex that breaks if no match
- auto m = _date_published.match(regex(r"^([0-9]{4})"));
- string _date = (m.hit == "0000") ? "(year?) " : "(" ~ m.hit ~ ") ";
- cgi.write(
- _close_para
- ~ "<hr><div class=\"publication\">"
- ~ "<p class=\"publication\"><a href=\""
- ~ "https://" ~ conf.http_host ~ conf.doc_collection_subroot ~ "/"
- ~ row["language_document_char"].as!string ~ "/html/"
- ~ row["src_filename_base"].as!string ~ "/"
- ~ "toc.html"
- ~ "\">\""
- ~ row["title"].as!string ~ "\""
- ~ "</a> "
- ~ _date
- ~ "[" ~ row["language_document_char"].as!string ~ "] "
- ~ row["creator_author_last_first"].as!string
- ~ " "
- ~ show_matched_objects(row["src_filename_base"].as!string)
- ~ "</p>"
- ~ "</div>"
- );
- }
- if (cv.results_type == "txt") {
- if (row["ocn"].as!string != "0") {
- cgi.write(
- "<div class=\"flex-container\">"
- ~ "<div class=\"textview_ocn\" style=\"flex: 0 0 1.2em\">"
- ~ "<p class=\"ocn_is\"><a href=\""
- ~ "https://" ~ conf.http_host ~ conf.doc_collection_subroot ~ "/"
- ~ row["language_document_char"].as!string ~ "/html/"
- ~ row["src_filename_base"].as!string ~ "/"
- ~ row["seg_name"].as!string ~ ".html#" ~ row["ocn"].as!string
- ~ "\">"
- ~ row["ocn"].as!string
- ~ "</a>:</p>"
- ~ "</div>"
- ~ "<div class=\"textview_found\">"
- ~ highlight_text_matched(row["body"].as!string, tf.text)
- ~ "</div>"
- ~ "</div>"
- );
- } else {
- cgi.write(
- "<div class=\"flex-container\">"
- ~ "<div class=\"textview_ocn\" style=\"flex: 0 0 1.2em\">"
- ~ "<p class=\"ocn_is\"><a href=\""
- ~ "https://" ~ conf.http_host ~ conf.doc_collection_subroot ~ "/"
- ~ row["language_document_char"].as!string ~ "/html/"
- ~ row["src_filename_base"].as!string ~ "/toc.html"
- ~ "\">"
- ~ row["ocn"].as!string
- ~ "</a>:</p>"
- ~ "</div>"
- ~ "<div class=\"textview_found\">"
- ~ highlight_text_matched(row["body"].as!string, tf.text)
- ~ "</div>"
- ~ "</div>"
- );
- }
- } else {
- if (row["ocn"].as!string != "0") {
- cgi.write(
- _matched_ocn_open
- ~ "<a href=\""
- ~ "https://" ~ conf.http_host ~ conf.doc_collection_subroot ~ "/"
- ~ row["language_document_char"].as!string ~ "/html/"
- ~ row["src_filename_base"].as!string ~ "/"
- ~ row["seg_name"].as!string ~ ".html#" ~ row["ocn"].as!string
- ~ "\">"
- ~ row["ocn"].as!string
- ~ "</a>, "
- );
- } else {
- cgi.write(
- _matched_ocn_open
- ~ "<a href=\""
- ~ "https://" ~ conf.http_host ~ conf.doc_collection_subroot ~ "/"
- ~ row["language_document_char"].as!string ~ "/html/"
- ~ row["src_filename_base"].as!string ~ "/toc.html"
- ~ "\">"
- ~ row["ocn"].as!string
- ~ "</a>, "
- );
- }
- _matched_ocn_open = "";
- }
- }
- cgi.write( previous_next);
-
- } else { // offset_not_beyond_limit = false;
- cgi.write("select_query_results empty<p>\n");
- }
- cgi.write("<br><p class=\"center\"><a href=\"https://sisudoc.org/\" target=\"_top\">
-<label for=\"find\"><b>≅ SiSU spine</b></label>
-</a> <label for=\"find\">(generated) search form</label>
-<br><a href=\"https://git.sisudoc.org/\" target=\"_top\">
- git</a>
-</p>
-");
- }
- sql_search_query;
- }
- {
- db.close;
- }
- {
- string tail = format(q"┃
-</body>
-┃");
- cgi.write(tail);
- }
-}
-mixin GenericMain!cgi_function_intro;
-≓",
- get_doc_collection_subroot(make_and_meta_struct.conf.output_path),
- make_and_meta_struct.conf.output_path ~ "/sqlite/",
- _sqlite_db_fn,
- (opt_action.cgi_search_title.empty)
- ? make_and_meta_struct.conf.w_srv_cgi_search_form_title
- : opt_action.cgi_search_title,
- (opt_action.css_theme_default) ? "FFFFFF" : "000000",
- (opt_action.css_theme_default) ? "000000" : "CCCCCC",
- (opt_action.css_theme_default) ? "FFFFFF" : "000000",
- (opt_action.css_theme_default) ? "FFFFFF" : "000000",
- (opt_action.css_theme_default) ? "003399" : "FFFFFF",
- (opt_action.css_theme_default) ? "003399" : "999999",
- "000000",
- (opt_action.css_theme_default) ? "F9F9AA" : "555555",
- (opt_action.css_theme_default) ? "777777" : "BBBBBB",
- (opt_action.css_theme_default) ? "32CD32" : "9ACD32",
- (opt_action.css_theme_default) ? "777777" : "BBBBBB",
- (opt_action.css_theme_default) ? "FFFFFF" : "000000",
- (opt_action.css_theme_default) ? "003399" : "888888",
- (opt_action.css_theme_default) ? "000000" : "FFFFFF",
- (opt_action.css_theme_default) ? "FFFFFF" : "777777",
- (opt_action.css_theme_default) ? "000000" : "FFFF48",
- (opt_action.css_theme_default) ? "FFFF48" : "777748",
- (opt_action.cgi_search_title.empty)
- ? make_and_meta_struct.conf.w_srv_cgi_search_form_title
- : opt_action.cgi_search_title,
- (opt_action.css_theme_default) ? "222222" : "AAAAAA",
- _cgi_search_script,
- _sqlite_db_fn,
-).strip;
- string _cgi_path = (opt_action.output_dir_set.length > 0)
- ? opt_action.output_dir_set
- : (make_and_meta_struct.conf.w_srv_data_root_path.length > 0)
- ? make_and_meta_struct.conf.w_srv_data_root_path
- : "";
- auto pth_sqlite_cgi = spinePathsSQLiteCGI!()(_cgi_search_script_raw_fn_d, _cgi_search_script, _cgi_path);
- { // cgi-bin search form src d
- try {
- if (!exists(pth_sqlite_cgi.src)) {
- pth_sqlite_cgi.src.mkdirRecurse;
- }
- if (!exists(pth_sqlite_cgi.cgi_bin)) {
- pth_sqlite_cgi.cgi_bin.mkdirRecurse;
- }
- auto f = File(pth_sqlite_cgi.search_form_path_out, "w");
- f.write(the_cgi_search_form);
- // foreach (o; metadata_) {
- // f.writeln(o);
- // }
- } catch (ErrnoException ex) {
- // Handle error
- }
- // if (!(opt_action.quiet)) {
- // writeln(" ", pth_sqlite_cgi.search_form);
- // }
- }
- string the_dub_sdl = format(q"≓
-name "spine_cgi_sqlite_search"
-description "spine cgi sqlite search"
-authors "Ralph Amissah"
-copyright "Copyright © 2022, Ralph Amissah"
-license "GPL-3.0+"
-dependency "d2sqlite3" version="%s"
-dependency "arsd-official:cgi" version="%s"
- subConfiguration "arsd-official:cgi" "cgi"
-targetType "executable"
-targetPath "./cgi-bin"
-mainSourceFile "%s"
-configuration "default" {
- targetType "executable"
- targetName "%s"
- postGenerateCommands "notify-send -t 0 'D executable ready' 'spine cgi sqlite search d'"
-}
-≓",
- "~>0.18.3", // d2sqlite3 dependency version
- "~>7.2.0", // arsd-official:cgi dependency version
- "src/" ~ _cgi_search_script_raw_fn_d,
- _cgi_search_script
-).strip;
- { // dub.sdl
- try {
- auto f = File(pth_sqlite_cgi.dub_sdl_path_out, "w");
- f.write(the_dub_sdl);
- // foreach (o; metadata_) {
- // f.writeln(o);
- // }
- } catch (ErrnoException ex) {
- // Handle error
- }
- }
- // { // get cgi.d
- // // import std.net.curl, std.stdio;
- // // char[] cgi_d;
- // // if (opt_action.allow_downloads) {
- // // try {
- // // cgi_d = get!HTTP("https://raw.githubusercontent.com/adamdruppe/arsd/master/cgi.d");
- // // } catch (ErrnoException ex) {
- // // // Handle error
- // // // CurlCode perform(ThrowOnError throwOnError = Yes.throwOnError);
- // // CurlCode perform(ThrowOnError throwOnError = No.throwOnError);
- // // }
- // // if (cgi_d && cgi_d.length > 0) {
- // // try {
- // // auto f = File(pth_sqlite_cgi.cgi_d_path_out, "w");
- // // f.write(cgi_d);
- // // } catch (ErrnoException ex) {
- // // // Handle error
- // // }
- // // }
- // // }
- // }
- }
-}
diff --git a/src/sisudoc/ocda/abstraction/package.d b/src/sisudoc/ocda/abstraction/package.d
new file mode 100644
index 0000000..4b34b3a
--- /dev/null
+++ b/src/sisudoc/ocda/abstraction/package.d
@@ -0,0 +1,86 @@
+/+
+- Name: SisuDoc Spine, Doc Reform [a part of]
+ - Description: documents, structuring, processing, publishing, search
+ - static content generator
+
+ - Author: Ralph Amissah
+ [ralph.amissah@gmail.com]
+
+ - Copyright: (C) 2015 (continuously updated, current 2026) Ralph Amissah, All Rights Reserved.
+
+ - License: AGPL 3 or later:
+
+ Spine (SiSU), a framework for document structuring, publishing and
+ search
+
+ Copyright (C) Ralph Amissah
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU AFERO General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program. If not, see [https://www.gnu.org/licenses/].
+
+ If you have Internet connection, the latest version of the AGPL should be
+ available at these locations:
+ [https://www.fsf.org/licensing/licenses/agpl.html]
+ [https://www.gnu.org/licenses/agpl.html]
+
+ - Spine (by Doc Reform, related to SiSU) uses standard:
+ - docReform markup syntax
+ - standard SiSU markup syntax with modified headers and minor modifications
+ - docReform object numbering
+ - standard SiSU object citation numbering & system
+
+ - Homepages:
+ [https://www.sisudoc.org]
+ [https://www.doc-reform.org]
+
+ - Git
+ [https://git.sisudoc.org/]
+
++/
+/++
+ sisudoc.ocda.abstraction - public surface of the document-abstraction
+ library.
+
+ Pipeline position: markup -> abstraction -> output.
+ This package is the abstraction stage. The output stage lives in
+ sisudoc.outputs.io_out and consumes the values produced here.
+
+ Entry points:
+ - spineAbstraction!() (from sisudoc.ocda.meta.metadoc) - A-layer:
+ builds the in-memory document object model from a manifest
+ (pod path, .sst path). Reads the document body, parses YAML
+ headers, returns a struct with .abstraction (the object
+ model) and .matters (the conf/meta/src wrapper).
+ - docAbstraction!() (from sisudoc.ocda.meta.metadoc_from_src) -
+ B-layer: builds the abstraction from already-loaded body
+ text plus a pre-built ConfComposite. Pure, no file I/O.
+
+ The A-layer is a thin wrapper over the B-layer; consumers that
+ want a minimal-dependency entry should use docAbstraction!()
+ directly.
+
+ Serialisation:
+ - sisudoc.ocda.abstraction.ssp - PEG-parsable text serialisation of
+ the abstraction (the .ssp format). See specs/doc-abstraction-
+ format/ for the format reference.
+
+ This file is a re-export-only surface. No logic lives here; it
+ exists so external consumers can `import sisudoc.ocda.abstraction;` and
+ reach the entry points without depending on spine's directory
+ layout.
++/
+module sisudoc.ocda.abstraction;
+@safe:
+public import sisudoc.ocda.meta.metadoc; // spineAbstraction (A-layer)
+public import sisudoc.ocda.meta.metadoc_from_src; // docAbstraction (B-layer)
+public import sisudoc.ocda.abstraction.ssp; // spineAbstractionTxt (.ssp)
diff --git a/src/sisudoc/io_out/create_abstraction_txt.d b/src/sisudoc/ocda/abstraction/ssp.d
index af98f61..cb3747b 100644
--- a/src/sisudoc/io_out/create_abstraction_txt.d
+++ b/src/sisudoc/ocda/abstraction/ssp.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.create_abstraction_txt;
+module sisudoc.ocda.abstraction.ssp;
@safe:
/+ ↓ write document abstraction as human-readable .ssp text file +/
@@ -59,7 +59,6 @@ template spineAbstractionTxt() {
import std.stdio;
import std.string;
import std.array;
- import sisudoc.io_out.paths_output;
void spineAbstractionTxt(D)(D doc) {
auto doc_abstraction = doc.abstraction;
@@ -408,9 +407,12 @@ template spineAbstractionTxt() {
}
/+ ↓ write to file +/
- auto out_pth = spineOutPaths!()(doc_matters.output_path, doc_matters.src.language);
- string base_dir = "abstraction";
- string base_pth = ((out_pth.output_base.chainPath(base_dir)).asNormalizedPath).array;
+ /+ path: <output_path>/<language>/abstraction/<doc_uid_out>.ssp +/
+ string out_root = (doc_matters.output_path.length > 0)
+ ? doc_matters.output_path : "";
+ string base_pth = (out_root
+ .chainPath(doc_matters.src.language, "abstraction")
+ .asNormalizedPath).array;
try {
if (!exists(base_pth)) {
base_pth.mkdirRecurse;
diff --git a/src/sisudoc/io_in/paths_source.d b/src/sisudoc/ocda/io_in/paths_source.d
index 41353ed..9cacdf0 100644
--- a/src/sisudoc/io_in/paths_source.d
+++ b/src/sisudoc/ocda/io_in/paths_source.d
@@ -52,7 +52,7 @@
- read config files<BR>
meta_config_files.d
+/
-module sisudoc.io_in.paths_source;
+module sisudoc.ocda.io_in.paths_source;
@safe:
import std.array;
import std.file;
@@ -60,8 +60,8 @@ import std.path;
import std.regex;
import std.stdio;
import std.conv : to;
-import sisudoc.meta.defaults;
-import sisudoc.meta.rgx_files;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.meta.rgx_files;
template PodManifest() {
mixin spineRgxFiles;
static auto rgx_files = RgxFiles();
diff --git a/src/sisudoc/io_in/read_config_files.d b/src/sisudoc/ocda/io_in/read_config_files.d
index d3a3f45..849705a 100644
--- a/src/sisudoc/io_in/read_config_files.d
+++ b/src/sisudoc/ocda/io_in/read_config_files.d
@@ -52,14 +52,14 @@
- read config files<BR>
meta_config_files.d
+/
-module sisudoc.io_in.read_config_files;
+module sisudoc.ocda.io_in.read_config_files;
@safe:
import std.file;
import std.path;
-import sisudoc.meta;
-import sisudoc.io_in.paths_source;
-import sisudoc.meta.rgx_files;
-import sisudoc.meta.rgx;
+import sisudoc.ocda.meta;
+import sisudoc.ocda.io_in.paths_source;
+import sisudoc.ocda.meta.rgx_files;
+import sisudoc.ocda.meta.rgx;
template readConfigSite() {
@system final auto readConfigSite(Cf,O,Cfg)(Cf _conf_file_details, O _opt_action, Cfg _cfg) {
mixin spineRgxIn;
@@ -190,10 +190,10 @@ webserv:
static template readConfigDoc() {
import std.file;
import std.path;
- import sisudoc.meta;
- import sisudoc.io_in.paths_source;
- import sisudoc.meta.rgx_files;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta;
+ import sisudoc.ocda.io_in.paths_source;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.ocda.meta.rgx;
@system final auto readConfigDoc(M,E)(M _manifested, E _env) {
mixin spineRgxIn;
static auto rgx = RgxI();
@@ -244,10 +244,10 @@ static template readConfigDoc() {
static template configReadSiteYAML() {
import std.file;
import std.path;
- import sisudoc.meta;
- import sisudoc.io_in.paths_source;
- import sisudoc.meta.rgx_files;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta;
+ import sisudoc.ocda.io_in.paths_source;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.ocda.meta.rgx;
final YAMLDocument configReadSiteYAML(M,E)(M _manifested, E _env) {
string _configuration = configReadInSiteYAML!()(_manifested, _env);
auto _conf_file_details = configFilePaths!()(_manifested, _env);
@@ -259,8 +259,8 @@ static template configReadSiteYAML() {
static template configReadDocYAML() {
import std.file;
import std.path;
- import sisudoc.meta;
- import sisudoc.io_in.paths_source;
+ import sisudoc.ocda.meta;
+ import sisudoc.ocda.io_in.paths_source;
final YAMLDocument configReadDocYAML(M,E)(M _manifested, E _env) {
string _configuration = configReadInDocYAML!()(_manifested, _env);
auto _conf_file_details = configFilePaths!()(_manifested, _env);
diff --git a/src/sisudoc/io_in/read_source_files.d b/src/sisudoc/ocda/io_in/read_source_files.d
index 31cbd37..720ee63 100644
--- a/src/sisudoc/io_in/read_source_files.d
+++ b/src/sisudoc/ocda/io_in/read_source_files.d
@@ -52,16 +52,16 @@
- open markup files<BR>
- if master file scan for addional files to import/insert
+/
-module sisudoc.io_in.read_source_files;
+module sisudoc.ocda.io_in.read_source_files;
@safe:
template spineRawMarkupContent() {
import std.digest.sha;
import std.file;
import std.path;
- import sisudoc.meta;
- import sisudoc.io_in.paths_source;
- import sisudoc.meta.rgx_files;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta;
+ import sisudoc.ocda.io_in.paths_source;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.ocda.meta.rgx;
mixin spineRgxIn;
static auto rgx = RgxI();
mixin spineRgxFiles;
diff --git a/src/sisudoc/io_in/read_zip_pod.d b/src/sisudoc/ocda/io_in/read_zip_pod.d
index d228f4e..322382d 100644
--- a/src/sisudoc/io_in/read_zip_pod.d
+++ b/src/sisudoc/ocda/io_in/read_zip_pod.d
@@ -52,7 +52,7 @@
- extract pod zip archives to temp directory for processing<BR>
- validate zip entries for security (path traversal, size limits)
+/
-module sisudoc.io_in.read_zip_pod;
+module sisudoc.ocda.io_in.read_zip_pod;
@safe:
template spineExtractZipPod() {
import std.algorithm : canFind;
diff --git a/src/sisudoc/meta/conf_make_meta_json.d b/src/sisudoc/ocda/meta/conf_make_meta_json.d
index c996b12..19ae4ba 100644
--- a/src/sisudoc/meta/conf_make_meta_json.d
+++ b/src/sisudoc/ocda/meta/conf_make_meta_json.d
@@ -51,7 +51,7 @@
json headers<BR>
extract json header return json
+/
-module sisudoc.meta.conf_make_meta_json;
+module sisudoc.ocda.meta.conf_make_meta_json;
@safe:
static template contentJSONtoSpineStruct() {
import std.algorithm;
@@ -63,10 +63,10 @@ static template contentJSONtoSpineStruct() {
import std.typecons;
import std.utf;
import std.conv : to;
- import sisudoc.meta.conf_make_meta_structs;
- import sisudoc.meta.conf_make_meta_json;
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.conf_make_meta_structs;
+ import sisudoc.ocda.meta.conf_make_meta_json;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
ConfComposite _struct_composite;
auto contentJSONtoSpineStruct(C,J,M)(C _struct_composite, J _json, M _manifested, string _identifier) {
mixin spineRgxIn;
diff --git a/src/sisudoc/meta/conf_make_meta_structs.d b/src/sisudoc/ocda/meta/conf_make_meta_structs.d
index 6bfd8fb..e442f9a 100644
--- a/src/sisudoc/meta/conf_make_meta_structs.d
+++ b/src/sisudoc/ocda/meta/conf_make_meta_structs.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.meta.conf_make_meta_structs;
+module sisudoc.ocda.meta.conf_make_meta_structs;
@safe:
import std.exception;
import std.json;
@@ -58,9 +58,9 @@ import std.string;
import std.typecons;
import std.utf;
import std.conv : to;
-import sisudoc.meta.defaults;
-import sisudoc.meta.rgx_yaml;
-import sisudoc.meta.rgx;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.meta.rgx_yaml;
+import sisudoc.ocda.meta.rgx;
mixin spineRgxIn;
static auto rgx = RgxI();
mixin spineRgxYamlTags;
diff --git a/src/sisudoc/meta/conf_make_meta_yaml.d b/src/sisudoc/ocda/meta/conf_make_meta_yaml.d
index f4ee7d9..e73a843 100644
--- a/src/sisudoc/meta/conf_make_meta_yaml.d
+++ b/src/sisudoc/ocda/meta/conf_make_meta_yaml.d
@@ -51,7 +51,7 @@
yaml headers<BR>
extract yaml header return struct
+/
-module sisudoc.meta.conf_make_meta_yaml;
+module sisudoc.ocda.meta.conf_make_meta_yaml;
@safe:
template contentYAMLtoSpineStruct() {
import std.algorithm;
@@ -64,10 +64,10 @@ template contentYAMLtoSpineStruct() {
import std.typecons;
import std.utf;
import std.conv : to;
- import sisudoc.meta.conf_make_meta_structs;
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx_yaml;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.conf_make_meta_structs;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx_yaml;
+ import sisudoc.ocda.meta.rgx;
ConfComposite _struct_composite;
@system ConfComposite contentYAMLtoSpineStruct(C,Y,M,O,Cfg)(
C _struct_composite,
@@ -894,8 +894,8 @@ template contentYAMLtoSpineStruct() {
}
template configParseYAMLreturnSpineStruct() {
import dyaml;
- import sisudoc.meta.conf_make_meta_structs;
- import sisudoc.meta.conf_make_meta_json;
+ import sisudoc.ocda.meta.conf_make_meta_structs;
+ import sisudoc.ocda.meta.conf_make_meta_json;
mixin contentYAMLtoSpineStruct;
@system ConfComposite configParseYAMLreturnSpineStruct(T,M,O,Cfg)(
T _document_struct,
@@ -933,10 +933,10 @@ template docHeaderMakeAndMetaTupYamlExtractAndConvertToStruct() {
import std.utf;
import std.conv : to;
import dyaml;
- import sisudoc.meta.conf_make_meta_structs;
- import sisudoc.meta.conf_make_meta_json;
- import sisudoc.meta.rgx_yaml;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.conf_make_meta_structs;
+ import sisudoc.ocda.meta.conf_make_meta_json;
+ import sisudoc.ocda.meta.rgx_yaml;
+ import sisudoc.ocda.meta.rgx;
mixin spineRgxIn;
mixin contentJSONtoSpineStruct;
static auto rgx = RgxI();
diff --git a/src/sisudoc/meta/defaults.d b/src/sisudoc/ocda/meta/defaults.d
index 53a791e..91df996 100644
--- a/src/sisudoc/meta/defaults.d
+++ b/src/sisudoc/ocda/meta/defaults.d
@@ -50,7 +50,7 @@
/++
default settings
+/
-module sisudoc.meta.defaults;
+module sisudoc.ocda.meta.defaults;
@safe:
template spineNode() {
static string[string] node_metadata_heading_str() {
diff --git a/src/sisudoc/meta/doc_debugs.d b/src/sisudoc/ocda/meta/doc_debugs.d
index 40a0af5..7ff57d7 100644
--- a/src/sisudoc/meta/doc_debugs.d
+++ b/src/sisudoc/ocda/meta/doc_debugs.d
@@ -50,10 +50,10 @@
/++
output debugs
+/
-module sisudoc.meta.doc_debugs;
+module sisudoc.ocda.meta.doc_debugs;
template spineDebugs() {
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx_files;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx_files;
import std.algorithm;
import std.array;
import std.container;
diff --git a/src/sisudoc/meta/metadoc.d b/src/sisudoc/ocda/meta/metadoc.d
index 1ffaca7..624761c 100644
--- a/src/sisudoc/meta/metadoc.d
+++ b/src/sisudoc/ocda/meta/metadoc.d
@@ -47,23 +47,21 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.meta.metadoc;
+module sisudoc.ocda.meta.metadoc;
@safe:
template spineAbstraction() {
import std.datetime;
import std.digest.crc;
import std.digest.sha;
- import sisudoc.meta;
- import sisudoc.meta.metadoc_from_src;
- import sisudoc.meta.conf_make_meta_structs;
- import sisudoc.meta.conf_make_meta_json;
- import sisudoc.meta.defaults;
- import sisudoc.io_in.paths_source;
- import sisudoc.io_in.read_config_files;
- import sisudoc.io_in.read_source_files;
- import sisudoc.io_out.hub;
+ import sisudoc.ocda.meta;
+ import sisudoc.ocda.meta.metadoc_from_src;
+ import sisudoc.ocda.meta.conf_make_meta_structs;
+ import sisudoc.ocda.meta.conf_make_meta_json;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.io_in.paths_source;
+ import sisudoc.ocda.io_in.read_config_files;
+ import sisudoc.ocda.io_in.read_source_files;
mixin spineBiblio;
- mixin outputHub;
enum makeMeta { make, meta }
enum docAbst { doc_abstract_obj, doc_has }
@system auto spineAbstraction(E,P,O,Cfg,M)(
@@ -76,7 +74,7 @@ template spineAbstraction() {
){
{ /+ document config/make file +/
auto _config_document_struct = readConfigDoc!()(_manifest, _env);
- import sisudoc.meta.conf_make_meta_yaml;
+ import sisudoc.ocda.meta.conf_make_meta_yaml;
_make_and_meta_struct = _config_document_struct.configParseYAMLreturnSpineStruct!()(_make_and_meta_struct, _manifest, _opt_action, _cfg);
}
/+ ↓ read file (filename with path) +/
@@ -105,7 +103,7 @@ template spineAbstraction() {
) {
writeln("step2 commence → (read document header (yaml) return struct) [", _manifest.src.filename, "]");
}
- import sisudoc.meta.conf_make_meta_yaml;
+ import sisudoc.ocda.meta.conf_make_meta_yaml;
_make_and_meta_struct =
docHeaderMakeAndMetaTupYamlExtractAndConvertToStruct!()(
_header_body_insertfilelist_imagelist.header_raw,
diff --git a/src/sisudoc/meta/metadoc_from_src.d b/src/sisudoc/ocda/meta/metadoc_from_src.d
index 4967c1f..bc00c49 100644
--- a/src/sisudoc/meta/metadoc_from_src.d
+++ b/src/sisudoc/ocda/meta/metadoc_from_src.d
@@ -50,7 +50,7 @@
// document abstraction:
// abstraction of sisu markup for downstream processing
// metadoc_from_src.d
-module sisudoc.meta.metadoc_from_src;
+module sisudoc.ocda.meta.metadoc_from_src;
@safe:
template docAbstraction() {
// ↓ abstraction imports
@@ -60,12 +60,12 @@ template docAbstraction() {
import std.file;
import std.json;
import std.path;
- import sisudoc.meta;
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
- import sisudoc.meta.metadoc_object_setter;
- import sisudoc.meta.rgx;
- public import sisudoc.meta.metadoc_from_src_functions;
+ import sisudoc.ocda.meta;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
+ import sisudoc.ocda.meta.metadoc_object_setter;
+ import sisudoc.ocda.meta.rgx;
+ public import sisudoc.ocda.meta.metadoc_from_src_functions;
mixin docAbstractionFunctions;
@system auto docAbstraction(CMM,Opt,Mf) (
char[][] markup_sourcefile_content,
diff --git a/src/sisudoc/meta/metadoc_from_src_functions.d b/src/sisudoc/ocda/meta/metadoc_from_src_functions.d
index e633ca1..f5c9bec 100644
--- a/src/sisudoc/meta/metadoc_from_src_functions.d
+++ b/src/sisudoc/ocda/meta/metadoc_from_src_functions.d
@@ -50,7 +50,7 @@
// document abstraction:
// abstraction of sisu markup for downstream processing
// metadoc_from_src.d
-module sisudoc.meta.metadoc_from_src_functions;
+module sisudoc.ocda.meta.metadoc_from_src_functions;
@safe:
template docAbstractionFunctions() {
// ↓ abstraction imports
@@ -1929,7 +1929,6 @@ template docAbstractionFunctions() {
return ret;
}
// ↑ - table
-
@system ST_flow_block_flag_line_empty flow_block_flag_line_empty_(B,CMM,Ts)(
char[] line,
string[string] an_object,
diff --git a/src/sisudoc/meta/metadoc_object_setter.d b/src/sisudoc/ocda/meta/metadoc_object_setter.d
index 018c51b..c5c8b1b 100644
--- a/src/sisudoc/meta/metadoc_object_setter.d
+++ b/src/sisudoc/ocda/meta/metadoc_object_setter.d
@@ -52,7 +52,7 @@
setting of sisu objects for downstream processing
metadoc_object_setter.d
+/
-module sisudoc.meta.metadoc_object_setter;
+module sisudoc.ocda.meta.metadoc_object_setter;
@safe:
template ObjectSetter() {
/+ structs +/
diff --git a/src/sisudoc/meta/metadoc_show_config.d b/src/sisudoc/ocda/meta/metadoc_show_config.d
index c4be08a..771b916 100644
--- a/src/sisudoc/meta/metadoc_show_config.d
+++ b/src/sisudoc/ocda/meta/metadoc_show_config.d
@@ -47,15 +47,15 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.meta.metadoc_show_config;
+module sisudoc.ocda.meta.metadoc_show_config;
@safe:
template spineShowSiteConfig() {
void spineShowSiteConfig(O,T)(
O opt_action,
T config,
) {
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
import std.array;
import std.digest.crc;
import std.digest.sha;
@@ -138,8 +138,8 @@ template spineShowSiteConfig() {
}
template spineShowConfig() {
void spineShowConfig(T)(T doc_matters) {
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
import std.array;
import std.digest.crc;
import std.digest.sha;
diff --git a/src/sisudoc/meta/metadoc_show_make.d b/src/sisudoc/ocda/meta/metadoc_show_make.d
index 4001e15..d039e9d 100644
--- a/src/sisudoc/meta/metadoc_show_make.d
+++ b/src/sisudoc/ocda/meta/metadoc_show_make.d
@@ -47,12 +47,12 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.meta.metadoc_show_make;
+module sisudoc.ocda.meta.metadoc_show_make;
@safe:
template spineShowMake() {
void spineShowMake(T)(T doc_matters) {
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
import std.array;
import std.digest.crc;
import std.digest.sha;
diff --git a/src/sisudoc/meta/metadoc_show_metadata.d b/src/sisudoc/ocda/meta/metadoc_show_metadata.d
index 4159bc3..8b15870 100644
--- a/src/sisudoc/meta/metadoc_show_metadata.d
+++ b/src/sisudoc/ocda/meta/metadoc_show_metadata.d
@@ -47,12 +47,12 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.meta.metadoc_show_metadata;
+module sisudoc.ocda.meta.metadoc_show_metadata;
@safe:
template spineShowMetaData() {
void spineShowMetaData(T)(T doc_matters) {
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
import std.array;
import std.digest.crc;
import std.digest.sha;
diff --git a/src/sisudoc/meta/metadoc_show_summary.d b/src/sisudoc/ocda/meta/metadoc_show_summary.d
index 037b34a..1c52bfa 100644
--- a/src/sisudoc/meta/metadoc_show_summary.d
+++ b/src/sisudoc/ocda/meta/metadoc_show_summary.d
@@ -47,13 +47,13 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.meta.metadoc_show_summary;
+module sisudoc.ocda.meta.metadoc_show_summary;
@safe:
template spineMetaDocSummary() {
void spineMetaDocSummary(D)(D doc) {
auto doc_matters = doc.matters;
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
import std.array;
import std.digest.crc;
import std.digest.sha;
diff --git a/src/sisudoc/meta/package.d b/src/sisudoc/ocda/meta/package.d
index 99de2f3..5858f9b 100644
--- a/src/sisudoc/meta/package.d
+++ b/src/sisudoc/ocda/meta/package.d
@@ -47,8 +47,8 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.meta;
-public import sisudoc.meta.defaults;
+module sisudoc.ocda.meta;
+public import sisudoc.ocda.meta.defaults;
/+ std +/
public import std.array;
public import std.exception;
diff --git a/src/sisudoc/meta/rgx.d b/src/sisudoc/ocda/meta/rgx.d
index db485eb..357df25 100644
--- a/src/sisudoc/meta/rgx.d
+++ b/src/sisudoc/ocda/meta/rgx.d
@@ -50,7 +50,7 @@
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.meta.rgx;
+module sisudoc.ocda.meta.rgx;
@safe:
static template spineRgxIn() {
static struct RgxI {
diff --git a/src/sisudoc/meta/rgx_files.d b/src/sisudoc/ocda/meta/rgx_files.d
index abf6e46..b26422f 100644
--- a/src/sisudoc/meta/rgx_files.d
+++ b/src/sisudoc/ocda/meta/rgx_files.d
@@ -50,7 +50,7 @@
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.meta.rgx_files;
+module sisudoc.ocda.meta.rgx_files;
@safe:
static template spineRgxFiles() {
static struct RgxFiles {
diff --git a/src/sisudoc/meta/rgx_yaml.d b/src/sisudoc/ocda/meta/rgx_yaml.d
index 2d3c20b..2c7cfbb 100644
--- a/src/sisudoc/meta/rgx_yaml.d
+++ b/src/sisudoc/ocda/meta/rgx_yaml.d
@@ -50,7 +50,7 @@
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.meta.rgx_yaml;
+module sisudoc.ocda.meta.rgx_yaml;
@safe:
static template spineRgxYamlTags() {
static struct RgxYaml {
diff --git a/src/sisudoc/ocda/package.d b/src/sisudoc/ocda/package.d
new file mode 100644
index 0000000..7f32dfe
--- /dev/null
+++ b/src/sisudoc/ocda/package.d
@@ -0,0 +1,68 @@
+/+
+- Name: SisuDoc Spine, Doc Reform [a part of]
+ - Description: documents, structuring, processing, publishing, search
+ - static content generator
+
+ - Author: Ralph Amissah
+ [ralph.amissah@gmail.com]
+
+ - Copyright: (C) 2015 (continuously updated, current 2026) Ralph Amissah, All Rights Reserved.
+
+ - License: AGPL 3 or later:
+
+ Spine (SiSU), a framework for document structuring, publishing and
+ search
+
+ Copyright (C) Ralph Amissah
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU AFERO General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program. If not, see [https://www.gnu.org/licenses/].
+
+ If you have Internet connection, the latest version of the AGPL should be
+ available at these locations:
+ [https://www.fsf.org/licensing/licenses/agpl.html]
+ [https://www.gnu.org/licenses/agpl.html]
+
+ - Spine (by Doc Reform, related to SiSU) uses standard:
+ - docReform markup syntax
+ - standard SiSU markup syntax with modified headers and minor modifications
+ - docReform object numbering
+ - standard SiSU object citation numbering & system
+
+ - Homepages:
+ [https://www.sisudoc.org]
+ [https://www.doc-reform.org]
+
+ - Git
+ [https://git.sisudoc.org/]
+
++/
+/++
+ sisudoc.ocda - canonical entry point of the document-abstraction
+ library.
+
+ Pipeline position: markup -> abstraction -> output. This package is
+ the abstraction stage; the output stage lives in
+ sisudoc.outputs.io_out and consumes the values produced here.
+
+ This file re-exports sisudoc.ocda.abstraction (the documented public
+ API surface) so that consumers can write
+ import sisudoc.ocda;
+ and reach the entry points (spineAbstraction!(), docAbstraction!(),
+ spineAbstractionTxt) without depending on spine's directory layout.
+
+ No logic lives here.
++/
+module sisudoc.ocda;
+@safe:
+public import sisudoc.ocda.abstraction;
diff --git a/src/sisudoc/conf/compile_time_info.d b/src/sisudoc/outputs/conf/compile_time_info.d
index e1ae3cf..d7b2d6c 100644
--- a/src/sisudoc/conf/compile_time_info.d
+++ b/src/sisudoc/outputs/conf/compile_time_info.d
@@ -50,7 +50,7 @@
/++
compile_time_info
+/
-module sisudoc.conf.compile_time_info;
+module sisudoc.outputs.conf.compile_time_info;
@safe:
template CompileTimeInfo() {
version(Windows) {
diff --git a/src/sisudoc/io_out/create_abstraction_db.d b/src/sisudoc/outputs/io_out/create_abstraction_db.d
index 20ca074..0b6b633 100644
--- a/src/sisudoc/io_out/create_abstraction_db.d
+++ b/src/sisudoc/outputs/io_out/create_abstraction_db.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.create_abstraction_db;
+module sisudoc.outputs.io_out.create_abstraction_db;
/+ ↓ write document abstraction as per-document sqlite3 database +/
template spineAbstractionDb() {
@@ -58,7 +58,7 @@ template spineAbstractionDb() {
import std.string;
import std.array;
import d2sqlite3;
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
void spineAbstractionDb(D)(D doc) {
auto doc_abstraction = doc.abstraction;
diff --git a/src/sisudoc/io_out/create_zip_file.d b/src/sisudoc/outputs/io_out/create_zip_file.d
index 4063ab5..d0ace54 100644
--- a/src/sisudoc/io_out/create_zip_file.d
+++ b/src/sisudoc/outputs/io_out/create_zip_file.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.create_zip_file;
+module sisudoc.outputs.io_out.create_zip_file;
@safe:
template createZipFile() {
import std.file;
diff --git a/src/sisudoc/meta/metadoc_curate.d b/src/sisudoc/outputs/io_out/curate/metadoc_curate.d
index 32df377..21307f1 100644
--- a/src/sisudoc/meta/metadoc_curate.d
+++ b/src/sisudoc/outputs/io_out/curate/metadoc_curate.d
@@ -47,15 +47,15 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.meta.metadoc_curate;
+module sisudoc.outputs.io_out.curate.metadoc_curate;
@safe:
template spineMetaDocCurate() {
auto spineMetaDocCurate(T,H)(
T doc_matters,
H hvst,
) {
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
import std.array;
import std.exception;
import std.regex;
@@ -67,7 +67,7 @@ template spineMetaDocCurate() {
import std.conv : to;
mixin InternalMarkup;
static auto mkup = InlineMarkup();
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto pth_html_abs = spinePathsHTML!()(doc_matters.output_path, doc_matters.src.language);
auto pth_html_rel = spineDocRootTreeHTML!()(doc_matters.src.language);
hvst.curate.title = doc_matters.conf_make_meta.meta.title_full;
diff --git a/src/sisudoc/meta/metadoc_curate_authors.d b/src/sisudoc/outputs/io_out/curate/metadoc_curate_authors.d
index e8d44c4..45b6d0b 100644
--- a/src/sisudoc/meta/metadoc_curate_authors.d
+++ b/src/sisudoc/outputs/io_out/curate/metadoc_curate_authors.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.meta.metadoc_curate_authors;
+module sisudoc.outputs.io_out.curate.metadoc_curate_authors;
@safe:
import std.algorithm;
import std.array;
@@ -56,8 +56,8 @@ module sisudoc.meta.metadoc_curate_authors;
import std.stdio;
import std.string;
import std.conv : to;
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
mixin spineCurateMetadata;
mixin InternalMarkup;
template spineMetaDocCuratesAuthors() {
@@ -509,7 +509,7 @@ string theme_light_1 = format(q"┃
</body>
</html>
┃") ~ "\n";
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
try {
auto f = File(out_pth.curate("authors.html"), "w");
diff --git a/src/sisudoc/meta/metadoc_curate_topics.d b/src/sisudoc/outputs/io_out/curate/metadoc_curate_topics.d
index 1873666..99ec48d 100644
--- a/src/sisudoc/meta/metadoc_curate_topics.d
+++ b/src/sisudoc/outputs/io_out/curate/metadoc_curate_topics.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.meta.metadoc_curate_topics;
+module sisudoc.outputs.io_out.curate.metadoc_curate_topics;
@safe:
import std.algorithm;
import std.array;
@@ -56,8 +56,8 @@ module sisudoc.meta.metadoc_curate_topics;
import std.stdio;
import std.string;
import std.conv : to;
- import sisudoc.meta.defaults;
- import sisudoc.meta.rgx;
+ import sisudoc.ocda.meta.defaults;
+ import sisudoc.ocda.meta.rgx;
mixin spineCurateMetadata;
mixin InternalMarkup;
template spineMetaDocCuratesTopics() {
@@ -677,7 +677,7 @@ string theme_light_1 = format(q"┃
</body>
</html>
┃") ~ "\n";
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
try {
auto f = File(out_pth.curate("topics.html"), "w");
diff --git a/src/sisudoc/io_out/defaults.d b/src/sisudoc/outputs/io_out/defaults.d
index 290ca89..73a9af1 100644
--- a/src/sisudoc/io_out/defaults.d
+++ b/src/sisudoc/outputs/io_out/defaults.d
@@ -50,7 +50,7 @@
/++
default settings
+/
-module sisudoc.io_out.defaults;
+module sisudoc.outputs.io_out.defaults;
@safe:
template InternalMarkup() {
diff --git a/src/sisudoc/io_out/epub3.d b/src/sisudoc/outputs/io_out/epub3.d
index c715630..f3b4cd7 100644
--- a/src/sisudoc/io_out/epub3.d
+++ b/src/sisudoc/outputs/io_out/epub3.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.epub3;
+module sisudoc.outputs.io_out.epub3;
@safe:
template outputEPub3() {
import std.file;
@@ -55,12 +55,12 @@ template outputEPub3() {
import std.uri;
import std.zip;
import std.conv : to;
- import sisudoc.io_out;
- import sisudoc.io_out.rgx;
- import sisudoc.io_out.rgx_xhtml;
- import sisudoc.io_out.create_zip_file;
- import sisudoc.io_out.xmls;
- import sisudoc.io_out.xmls_css;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.rgx;
+ import sisudoc.outputs.io_out.rgx_xhtml;
+ import sisudoc.outputs.io_out.create_zip_file;
+ import sisudoc.outputs.io_out.xmls;
+ import sisudoc.outputs.io_out.xmls_css;
mixin InternalMarkup;
mixin outputXHTMLs;
static auto rgx = RgxO();
@@ -634,7 +634,7 @@ template outputEPub3() {
pth_epub3.base.mkdirRecurse;
}
if (!exists(pth_epub3.base ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_epub3.base ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
diff --git a/src/sisudoc/io_out/html.d b/src/sisudoc/outputs/io_out/html.d
index a294f30..efdedf8 100644
--- a/src/sisudoc/io_out/html.d
+++ b/src/sisudoc/outputs/io_out/html.d
@@ -47,20 +47,20 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.html;
+module sisudoc.outputs.io_out.html;
@safe:
template outputHTML() {
import std.file;
import std.outbuffer;
import std.uri;
import std.conv : to;
- import sisudoc.io_out;
- import sisudoc.io_out.rgx;
- import sisudoc.meta.rgx_files;
- import sisudoc.io_out.rgx_xhtml;
- import sisudoc.io_out.create_zip_file;
- import sisudoc.io_out.xmls;
- import sisudoc.io_out.xmls_css;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.rgx;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.outputs.io_out.rgx_xhtml;
+ import sisudoc.outputs.io_out.create_zip_file;
+ import sisudoc.outputs.io_out.xmls;
+ import sisudoc.outputs.io_out.xmls_css;
mixin outputXHTMLs;
void scroll(D)(D doc) {
mixin spineRgxOut;
@@ -248,7 +248,7 @@ template outputHTML() {
}
}
if (!exists(pth_html.base ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_html.base ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -563,7 +563,7 @@ template outputHTML() {
f.writeln(css.html_scroll);
}
if (!exists(pth_html.css ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_html.css ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -599,7 +599,7 @@ template outputHTML() {
}
}
if (!exists(pth_html.image ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_html.image ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
diff --git a/src/sisudoc/io_out/html_snippet.d b/src/sisudoc/outputs/io_out/html_snippet.d
index d02cb28..f960cea 100644
--- a/src/sisudoc/io_out/html_snippet.d
+++ b/src/sisudoc/outputs/io_out/html_snippet.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.html_snippet;
+module sisudoc.outputs.io_out.html_snippet;
@safe:
template htmlSnippet() {
import std.file;
@@ -55,9 +55,9 @@ template htmlSnippet() {
import std.format;
import std.uri;
import std.conv : to;
- import sisudoc.io_out.rgx;
- import sisudoc.meta.rgx_files;
- import sisudoc.io_out.rgx_xhtml;
+ import sisudoc.outputs.io_out.rgx;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.outputs.io_out.rgx_xhtml;
auto format_html_blank_page_guide_home()(
string css_style,
string home_url,
diff --git a/src/sisudoc/io_out/hub.d b/src/sisudoc/outputs/io_out/hub.d
index 6ca047a..0aab81d 100644
--- a/src/sisudoc/io_out/hub.d
+++ b/src/sisudoc/outputs/io_out/hub.d
@@ -51,14 +51,14 @@
output hub<BR>
check & generate output types requested
+/
-module sisudoc.io_out.hub;
+module sisudoc.outputs.io_out.hub;
@safe:
template outputHub() {
- import sisudoc.io_out,
- sisudoc.io_out.metadata,
- sisudoc.io_out.xmls,
- sisudoc.io_out.create_zip_file,
- sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.metadata;
+ import sisudoc.outputs.io_out.xmls;
+ import sisudoc.outputs.io_out.create_zip_file;
+ import sisudoc.outputs.io_out.paths_output;
@system void outputHub(D)(D doc) {
mixin Msg;
auto msg = Msg!()(doc.matters);
@@ -68,14 +68,14 @@ template outputHub() {
if (sched == outTask.source_or_pod) {
msg.v("spine (doc reform) source processing... ");
if (doc.matters.opt.action.pod) { msg.v("spine (doc reform) source pod processing... "); }
- import sisudoc.io_out.source_pod;
+ import sisudoc.outputs.io_out.source_pod;
spinePod!()(doc.matters);
if (doc.matters.opt.action.source) { msg.vv("spine (doc reform) source done"); }
if (doc.matters.opt.action.pod) { msg.vv("spine (doc reform) source pod done"); }
}
if (sched == outTask.epub) {
msg.v("epub3 processing... ");
- import sisudoc.io_out.epub3;
+ import sisudoc.outputs.io_out.epub3;
doc.outputEPub3!();
msg.vv("epub3 done");
}
@@ -85,25 +85,25 @@ template outputHub() {
}
if (sched == outTask.html_scroll) {
msg.v("html scroll processing... ");
- import sisudoc.io_out.html;
+ import sisudoc.outputs.io_out.html;
outputHTML!().scroll(doc);
msg.vv("html scroll done");
}
if (sched == outTask.html_seg) {
msg.v("html seg processing... ");
- import sisudoc.io_out.html;
+ import sisudoc.outputs.io_out.html;
outputHTML!().seg(doc);
msg.vv("html seg done");
}
if (sched == outTask.html_stuff) {
- import sisudoc.io_out.html;
+ import sisudoc.outputs.io_out.html;
outputHTML!().css(doc.matters);
outputHTML!().images_cp(doc.matters);
msg.vv("html css & images done");
}
if (sched == outTask.latex) {
msg.v("latex processing... (available for downstream processing & pdf output");
- import sisudoc.io_out.latex;
+ import sisudoc.outputs.io_out.latex;
import std.file;
if ((isValidPath(doc.matters.output_path ~ "/latex/sty"))
&& (!(exists(doc.matters.output_path ~ "/latex/sty")))
@@ -120,25 +120,25 @@ template outputHub() {
}
if (sched == outTask.text) {
msg.v("text processing... ");
- import sisudoc.io_out.text;
+ import sisudoc.outputs.io_out.text;
outputText!()(doc.abstraction, doc.matters);
msg.vv("text done");
}
if (sched == outTask.odt) {
msg.v("odf:odt processing... ");
- import sisudoc.io_out.odt;
+ import sisudoc.outputs.io_out.odt;
outputODT!()(doc.abstraction, doc.matters);
msg.vv("odf:odt done");
}
if (sched == outTask.sqlite) {
msg.v("sqlite processing... ");
- import sisudoc.io_out.sqlite;
+ import sisudoc.outputs.io_out.sqlite;
doc.SQLiteHubDiscreteBuildTablesAndPopulate!();
msg.vv("sqlite done");
}
if (sched == outTask.skel) {
msg.v("skel processing... ");
- import sisudoc.io_out.skel;
+ import sisudoc.outputs.io_out.skel;
outputSkel!()(doc.abstraction, doc.matters);
msg.vv("skel done");
}
@@ -156,12 +156,12 @@ template outputHub() {
}
if (doc.matters.opt.action.sqlite_update) {
msg.v("sqlite update processing...");
- import sisudoc.io_out.sqlite;
+ import sisudoc.outputs.io_out.sqlite;
doc.SQLiteHubBuildTablesAndPopulate!();
msg.vv("sqlite update done");
} else if (doc.matters.opt.action.sqlite_delete) {
msg.v("sqlite delete processing...");
- import sisudoc.io_out.sqlite;
+ import sisudoc.outputs.io_out.sqlite;
doc.SQLiteHubBuildTablesAndPopulate!();
msg.vv("sqlite delete done");
}
@@ -169,9 +169,9 @@ template outputHub() {
}
template outputHubInitialize() {
import std.file;
- import sisudoc.io_out,
- sisudoc.io_out.metadata,
- sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.metadata;
+ import sisudoc.outputs.io_out.paths_output;
string _bespoke_homepage = "./spine-bespoke-output/html/homepage.index.html";
@system void outputHubInitialize(O,I)(
O opt_action,
@@ -196,7 +196,7 @@ template outputHubInitialize() {
&& opt_action.output_dir_set.length > 0
&& !(isValidPath(opt_action.output_dir_set ~ "/latex/sty")))
) { // .sty need to be produced only once (if unchanged per output-dir of which there usually will be only one)
- import sisudoc.io_out.latex;
+ import sisudoc.outputs.io_out.latex;
outputLaTeXstyInit!()(
opt_action.output_dir_set,
opt_action.generated_by,
@@ -208,17 +208,17 @@ template outputHubInitialize() {
}
}
template outputHubOp() {
- import sisudoc.io_out,
- sisudoc.io_out.metadata,
- sisudoc.io_out.xmls,
- sisudoc.io_out.create_zip_file,
- sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.metadata;
+ import sisudoc.outputs.io_out.xmls;
+ import sisudoc.outputs.io_out.create_zip_file;
+ import sisudoc.outputs.io_out.paths_output;
@system void outputHubOp(E,O,C)(E env, O opt_action, C config) {
if ((opt_action.sqlite_db_drop)) {
if ((opt_action.vox_gt_2)) {
writeln("sqlite drop db...");
}
- import sisudoc.io_out.sqlite;
+ import sisudoc.outputs.io_out.sqlite;
SQLiteDbDrop!()(opt_action, config);
if ((opt_action.vox_gt_3)) {
writeln("sqlite drop db done");
@@ -229,7 +229,7 @@ template outputHubOp() {
auto pth_sqlite_db = spinePathsSQLite!()(opt_action.cgi_sqlite_search_filename, opt_action.output_dir_set);
writeln("sqlite create table...");
}
- import sisudoc.io_out.sqlite;
+ import sisudoc.outputs.io_out.sqlite;
SQLiteTablesCreate!()(env, opt_action, config);
if ((opt_action.vox_gt_3)) {
writeln("sqlite create table done");
diff --git a/src/sisudoc/io_out/latex.d b/src/sisudoc/outputs/io_out/latex.d
index 39dc932..8e7b37c 100644
--- a/src/sisudoc/io_out/latex.d
+++ b/src/sisudoc/outputs/io_out/latex.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.latex;
+module sisudoc.outputs.io_out.latex;
@safe:
template paperLaTeX() {
import std.format;
@@ -322,9 +322,9 @@ template outputLaTeX() {
import std.outbuffer;
import std.uri;
import std.conv : to;
- import sisudoc.io_out;
- import sisudoc.io_out.rgx;
- import sisudoc.io_out.rgx_latex;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.rgx;
+ import sisudoc.outputs.io_out.rgx_latex;
mixin spineRgxOut;
static auto rgx = RgxO();
mixin spineRgxLSC;
@@ -679,7 +679,7 @@ template outputLaTeX() {
\pagenumbering{alph}
\setcounter{page}{1}
\markboth{%s}{%s}
-\br\linebreak Copyright {\begin{small}{\copyright\end{small}} %s \br\linebreak
+\br\linebreak Copyright \begin{small}\copyright\end{small} %s \br\linebreak
%s
\clearpage┃";
_txt = format(_tex_para,
@@ -1378,7 +1378,7 @@ template outputLaTeX() {
}
}
if (!exists(pth_latex.latex_path_stuff ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_latex.latex_path_stuff ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -1392,7 +1392,7 @@ template outputLaTeX() {
}
// should be in latex init and done just once, doc_matters not passed there though
if (!exists(pth_latex.base ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_latex.base ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -1404,7 +1404,7 @@ template outputLaTeX() {
));
}
if (!exists(pth_latex.base_sty ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_latex.base_sty ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -1438,7 +1438,7 @@ template outputLaTeX() {
}
}
template outputLaTeXstyInit() {
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
auto paper = paperLaTeX;
void writeOutputLaTeXstyStatic(
string latex_sty,
@@ -1518,7 +1518,7 @@ template outputLaTeXstyStatic() {
\usepackage{multicol}
\setlength{\marginparsep}{4mm}
\setlength{\marginparwidth}{8mm}
-\usepackage[scaled]{dejavu}
+\usepackage{dejavu}
\renewcommand*\familydefault{\sfdefault}
\usepackage{inconsolata}
\usepackage[T1]{fontenc}
@@ -1682,8 +1682,8 @@ template outputLaTeXstyStatic() {
}
\newcommand{\spaces}[1]{{\hspace*{#1ex}}}
\newcommand{\s}{\hspace*{1ex}}
-\renewcommand{\hardspace}{\hspace*{1ex}}
-\newcommand{\-}{\hspace*{1ex}}
+\newcommand{\hardspace}{\hspace*{1ex}}
+\renewcommand{\-}{\hspace*{1ex}}
\newcommand{\caret}{{\^{~}}}
\newcommand{\pipe}{{\textbar}}
\newcommand{\curlyOpen}{{}
diff --git a/src/sisudoc/io_out/metadata.d b/src/sisudoc/outputs/io_out/metadata.d
index 92b3bf9..f951dde 100644
--- a/src/sisudoc/io_out/metadata.d
+++ b/src/sisudoc/outputs/io_out/metadata.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.metadata;
+module sisudoc.outputs.io_out.metadata;
// @safe:
template outputMetadata() {
void outputMetadata(T)(T doc_matters) {
@@ -113,7 +113,7 @@ template outputMetadata() {
import std.digest.sha;
import std.file;
import std.format;
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
mixin InternalMarkup;
char[] metadata_;
string theme_dark_0 = format(q"┃
@@ -378,7 +378,7 @@ string theme_light_1 = format(q"┃
}
}
if (!exists(pth_html.base ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_html.base ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -395,7 +395,7 @@ string theme_light_1 = format(q"┃
if (doc_matters.opt.action.vox_gt_1) { writeln(" ", pth_html.fn_scroll("metadata." ~ doc_matters.src.filename)); }
}
static auto mkup = InlineMarkup();
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
if (doc_matters.opt.action.debug_do) {
writeln(doc_matters.src.filename_base);
diff --git a/src/sisudoc/io_out/odt.d b/src/sisudoc/outputs/io_out/odt.d
index 1d0e647..ed288cb 100644
--- a/src/sisudoc/io_out/odt.d
+++ b/src/sisudoc/outputs/io_out/odt.d
@@ -47,20 +47,20 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.odt;
+module sisudoc.outputs.io_out.odt;
@safe:
template formatODT() {
- import sisudoc.io_out;
- import sisudoc.io_out.rgx;
- import sisudoc.io_out.rgx_xhtml;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.rgx;
+ import sisudoc.outputs.io_out.rgx_xhtml;
import std.file;
import std.outbuffer;
import std.uri;
import std.zip;
import std.conv : to;
- import sisudoc.io_out.create_zip_file;
- import sisudoc.io_out.xmls;
- import sisudoc.io_out.xmls_css;
+ import sisudoc.outputs.io_out.create_zip_file;
+ import sisudoc.outputs.io_out.xmls;
+ import sisudoc.outputs.io_out.xmls_css;
mixin spineRgxOut;
mixin spineRgxXHTML;
struct formatODT {
@@ -642,17 +642,17 @@ template formatODT() {
}
}
template outputODT() {
- import sisudoc.io_out;
- import sisudoc.io_out.rgx;
- import sisudoc.io_out.rgx_xhtml;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.rgx;
+ import sisudoc.outputs.io_out.rgx_xhtml;
import std.file;
import std.outbuffer;
import std.uri;
import std.zip;
import std.conv : to;
- import sisudoc.io_out.create_zip_file;
- import sisudoc.io_out.xmls;
- import sisudoc.io_out.xmls_css;
+ import sisudoc.outputs.io_out.create_zip_file;
+ import sisudoc.outputs.io_out.xmls;
+ import sisudoc.outputs.io_out.xmls_css;
mixin InternalMarkup;
mixin spineRgxOut;
mixin spineRgxXHTML;
@@ -892,7 +892,7 @@ template outputODT() {
}
return doc_odt;
}
-
+ ;
string odt_tail() {
string _odt_tail = format(q"┃<text:p text:style-name="P_normal">spine: &lt;<text:a xl:type="simple" xl:href="https://www.sisudoc.org">www.sisudoc.org</text:a>&gt; and &lt;<text:a xl:type="simple" xl:href="https://www.sisudoc.org">www.sisudoc.org</text:a>&gt;</text:p>
</office:text></office:body></office:document-content>┃",);
@@ -939,7 +939,7 @@ template outputODT() {
auto ref M doc_matters,
) {
{ /+ (copy odt images) +/
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto pth_odt = spinePathsODT!()(doc_matters);
foreach (image; doc_matters.srcs.image_list) {
auto fn_src_in = doc_matters.src.image_dir_path ~ "/" ~ image;
@@ -979,7 +979,7 @@ template outputODT() {
void dirtree(I)(
I doc_matters,
) {
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto pth_odt = spinePathsODT!()(doc_matters);
if (doc_matters.opt.action.debug_do) { /+ (dir tree) +/
if (!exists(pth_odt.meta_inf_dir("fs"))) {
@@ -993,7 +993,7 @@ template outputODT() {
pth_odt.base_pth.mkdirRecurse;
}
if (!exists(pth_odt.base_pth ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_odt.base_pth ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -2098,7 +2098,7 @@ template outputODT() {
}
}
if (!exists(pth_odt.base_pth ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pth_odt.base_pth ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -2117,7 +2117,6 @@ template outputODT() {
pth_odt.manifest_rdf("fs"); /+ (manifest.rdf) +/
pth_odt.settings_xml("fs"); /+ (settings.xml) +/
pth_odt.styles_xml("fs"); /+ (styles_xml) +/
-
pth_odt.content_xml("fs");
pth_odt.manifest_xml("fs");
pth_odt.meta_xml("fs");
diff --git a/src/sisudoc/io_out/package.d b/src/sisudoc/outputs/io_out/package.d
index e0512dc..489137f 100644
--- a/src/sisudoc/io_out/package.d
+++ b/src/sisudoc/outputs/io_out/package.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out;
+module sisudoc.outputs.io_out;
public import std.algorithm;
public import std.array;
public import std.container;
@@ -61,7 +61,7 @@ public import std.string;
public import std.typecons;
// public import std.uni;
public import std.utf;
-public import sisudoc.share.defaults;
-public import sisudoc.io_in.paths_source;
-public import sisudoc.io_out.defaults;
-public import sisudoc.io_out.paths_output;
+public import sisudoc.outputs.share.defaults;
+public import sisudoc.ocda.io_in.paths_source;
+public import sisudoc.outputs.io_out.defaults;
+public import sisudoc.outputs.io_out.paths_output;
diff --git a/src/sisudoc/io_out/paths_output.d b/src/sisudoc/outputs/io_out/paths_output.d
index a9d0928..3d8323d 100644
--- a/src/sisudoc/io_out/paths_output.d
+++ b/src/sisudoc/outputs/io_out/paths_output.d
@@ -50,13 +50,13 @@
/++
default settings
+/
-module sisudoc.io_out.paths_output;
+module sisudoc.outputs.io_out.paths_output;
@safe:
import std.array;
import std.path;
import std.regex;
import std.stdio;
-import sisudoc.meta.rgx_files;
+import sisudoc.ocda.meta.rgx_files;
template spineOutPaths() {
auto spineOutPaths()(
string output_pth_root,
diff --git a/src/sisudoc/io_out/rgx.d b/src/sisudoc/outputs/io_out/rgx.d
index 384222c..c915076 100644
--- a/src/sisudoc/io_out/rgx.d
+++ b/src/sisudoc/outputs/io_out/rgx.d
@@ -50,7 +50,7 @@
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.io_out.rgx;
+module sisudoc.outputs.io_out.rgx;
@safe:
static template spineRgxOut() {
static struct RgxO {
diff --git a/src/sisudoc/io_out/rgx_latex.d b/src/sisudoc/outputs/io_out/rgx_latex.d
index 1ae6147..e40a28e 100644
--- a/src/sisudoc/io_out/rgx_latex.d
+++ b/src/sisudoc/outputs/io_out/rgx_latex.d
@@ -50,7 +50,7 @@
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.io_out.rgx_latex;
+module sisudoc.outputs.io_out.rgx_latex;
@safe:
static template spineRgxLSC() {
static struct RgxLSC {
diff --git a/src/sisudoc/io_out/rgx_xhtml.d b/src/sisudoc/outputs/io_out/rgx_xhtml.d
index b1b1004..a2bf192 100644
--- a/src/sisudoc/io_out/rgx_xhtml.d
+++ b/src/sisudoc/outputs/io_out/rgx_xhtml.d
@@ -50,7 +50,7 @@
/++
regex: regular expressions used in sisu document parser
+/
-module sisudoc.io_out.rgx_xhtml;
+module sisudoc.outputs.io_out.rgx_xhtml;
@safe:
static template spineRgxXHTML() {
static struct RgxXHTML {
diff --git a/src/sisudoc/io_out/skel.d b/src/sisudoc/outputs/io_out/skel.d
index 92e0d52..5331da3 100644
--- a/src/sisudoc/io_out/skel.d
+++ b/src/sisudoc/outputs/io_out/skel.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.skel;
+module sisudoc.outputs.io_out.skel;
@safe:
template outputSkel() {
template munge() {
@@ -187,7 +187,7 @@ template outputSkel() {
}
template theDocument() {
import std.stdio;
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
// static auto rgx = RgxO();
string skel_head(M)(
M doc_matters,
@@ -232,7 +232,7 @@ template outputSkel() {
M doc_matters,
) {
import std.stdio;
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
void skel_out(D,M)(
const D doc_abstraction,
M doc_matters,
diff --git a/src/sisudoc/io_out/source_pod.d b/src/sisudoc/outputs/io_out/source_pod.d
index 138f105..f6c73d6 100644
--- a/src/sisudoc/io_out/source_pod.d
+++ b/src/sisudoc/outputs/io_out/source_pod.d
@@ -47,7 +47,7 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.source_pod;
+module sisudoc.outputs.io_out.source_pod;
@system: // is not @safe: use: @system: or @trusted:
template spinePod() {
import std.digest.sha;
@@ -55,10 +55,10 @@ template spinePod() {
import std.outbuffer;
import std.zip;
import std.conv : to;
- import sisudoc.meta.rgx_files;
- import sisudoc.io_out;
- import sisudoc.io_out.create_zip_file;
- import sisudoc.io_out.xmls;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.create_zip_file;
+ import sisudoc.outputs.io_out.xmls;
void spinePod(T)(T doc_matters) {
debug(asserts) {
// static assert(is(typeof(doc_matters) == tuple));
@@ -136,7 +136,7 @@ template spinePod() {
}
}
if (!exists(pths_pod.pod_dir_() ~ "/index.html")) {
- import sisudoc.io_out.html_snippet;
+ import sisudoc.outputs.io_out.html_snippet;
mixin htmlSnippet;
auto f = File(pths_pod.pod_dir_() ~"/index.html", "w");
f.writeln(format_html_blank_page_guide_home(
@@ -195,29 +195,38 @@ template spinePod() {
}
} { // bundle abstraction .ssp file (only for --pod2)
if (doc_matters.opt.action.pod2) {
- import sisudoc.io_out.paths_output;
- auto out_pth = spineOutPaths!()(doc_matters.output_path, doc_matters.src.language);
- string abstraction_dir = ((out_pth.output_base.chainPath("abstraction")).asNormalizedPath).array;
- string ssp_filename = doc_matters.src.doc_uid_out ~ ".ssp";
- string fn_src_in = ((abstraction_dir.chainPath(ssp_filename)).asNormalizedPath).array.to!string;
- auto fn_src_out_pod_zip_base
- = pths_pod.abstraction_root(doc_matters.src.filename).zpod.to!string
- ~ "/" ~ ssp_filename;
- auto fn_src_out_filesystem
- = pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod.to!string
- ~ "/" ~ ssp_filename;
- if (exists(fn_src_in)) {
- debug(io) { writeln("(io debug) src out found: ", fn_src_in); }
- { // take DIGEST write to pod file digests.txt
- auto data = (cast(byte[]) (fn_src_in).read);
- _digests[doc_matters.src.language]["ssp"] ~= data.sha256Of.toHexString
- ~ "::" ~ data.length.to!string ~ " - " ~ ssp_filename ~ "\n";
- }
- fn_src_in.copy(fn_src_out_filesystem);
- zip = podArchive("file_path_text", fn_src_in, fn_src_out_pod_zip_base, zip);
- } else {
- if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt_2) {
- writeln("WARNING (io) src out NOT found (abstraction): ", fn_src_in);
+ if (doc_matters.src.language == doc_matters.pod.manifest_list_of_languages[$-1]) { // wait until all language versions of .ssp generated
+ import sisudoc.outputs.io_out.paths_output;
+ /+ doc_uid_out for any language follows the same pattern, differing
+ only in the trailing ".{lng}". Strip the current language to
+ reuse the base across all languages. +/
+ string _doc_uid_base
+ = doc_matters.src.doc_uid_out[0 .. $ - doc_matters.src.lng.length];
+ foreach (_lang; doc_matters.pod.manifest_list_of_languages) { // do for all language versions
+ auto out_pth_lng = spineOutPaths!()(doc_matters.output_path, _lang);
+ string abstraction_dir = ((out_pth_lng.output_base.chainPath("abstraction")).asNormalizedPath).array;
+ string ssp_filename = _doc_uid_base ~ _lang ~ ".ssp";
+ string fn_src_in = ((abstraction_dir.chainPath(ssp_filename)).asNormalizedPath).array.to!string;
+ auto fn_src_out_pod_zip_base
+ = pths_pod.abstraction_root(doc_matters.src.filename).zpod.to!string
+ ~ "/" ~ ssp_filename;
+ auto fn_src_out_filesystem
+ = pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod.to!string
+ ~ "/" ~ ssp_filename;
+ if (exists(fn_src_in)) {
+ debug(io) { writeln("(io debug) src out found: ", fn_src_in); }
+ { // take DIGEST write to pod file digests.txt
+ auto data = (cast(byte[]) (fn_src_in).read);
+ _digests[_lang]["ssp"] ~= data.sha256Of.toHexString
+ ~ "::" ~ data.length.to!string ~ " - " ~ ssp_filename ~ "\n";
+ }
+ fn_src_in.copy(fn_src_out_filesystem);
+ zip = podArchive("file_path_text", fn_src_in, fn_src_out_pod_zip_base, zip);
+ } else {
+ if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt_2) {
+ writeln("WARNING (io) src out NOT found (abstraction): ", fn_src_in);
+ }
+ }
}
}
}
@@ -476,7 +485,7 @@ template spinePod() {
}
}
void zipArchiveDigest(M,F,D)(M doc_matters, F fn_pod, D _digests) {
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto pths_pod = spinePathsPods!()(doc_matters);
char[] _zip_digest;
try {
diff --git a/src/sisudoc/io_out/sqlite.d b/src/sisudoc/outputs/io_out/sqlite.d
index b5c0f47..2b0b6d5 100644
--- a/src/sisudoc/io_out/sqlite.d
+++ b/src/sisudoc/outputs/io_out/sqlite.d
@@ -47,10 +47,10 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.sqlite;
-import sisudoc.io_out;
-import sisudoc.io_out.rgx;
-import sisudoc.io_out.rgx_xhtml;
+module sisudoc.outputs.io_out.sqlite;
+import sisudoc.outputs.io_out;
+import sisudoc.outputs.io_out.rgx;
+import sisudoc.outputs.io_out.rgx_xhtml;
import std.file;
import std.uri;
// import std.digest.sha;
@@ -71,7 +71,12 @@ template SQLiteHubBuildTablesAndPopulate() {
} else {
try {
pth_sqlite.base.mkdirRecurse;
- } catch (FileException ex) { }
+ } catch (FileException ex) {
+ stderr.writeln("FATAL: cannot create --sqlite-db-path directory: ", pth_sqlite.base);
+ stderr.writeln(" (", ex.msg, ")");
+ import core.runtime;
+ core.runtime.Runtime.terminate();
+ }
}
template SQLiteDbStatementComposite() {
void SQLiteDbStatementComposite(Db,D)(
@@ -85,7 +90,12 @@ template SQLiteHubBuildTablesAndPopulate() {
} else {
try {
pth_sqlite.base.mkdirRecurse;
- } catch (FileException ex) { }
+ } catch (FileException ex) {
+ stderr.writeln("FATAL: cannot create --sqlite-db-path directory: ", pth_sqlite.base);
+ stderr.writeln(" (", ex.msg, ")");
+ import core.runtime;
+ core.runtime.Runtime.terminate();
+ }
}
_db_statement ~= SQLiteTablesReCreate!()();
SQLiteDbRun!()(db, _db_statement, doc.matters.opt.action, "TABLE RE-CREATE");
@@ -154,7 +164,12 @@ template SQLiteHubDiscreteBuildTablesAndPopulate() {
} else {
try {
pth_sqlite.base.mkdirRecurse;
- } catch (FileException ex) { }
+ } catch (FileException ex) {
+ stderr.writeln("FATAL: cannot create --sqlite-db-path directory: ", pth_sqlite.base);
+ stderr.writeln(" (", ex.msg, ")");
+ import core.runtime;
+ core.runtime.Runtime.terminate();
+ }
}
auto db = Database(pth_sqlite.sqlite_file(doc.matters.src.filename));
template SQLiteDiscreteDbStatementComposite() {
@@ -1671,7 +1686,12 @@ template SQLiteTablesCreate() {
} else {
try {
pth_sqlite.base.mkdirRecurse;
- } catch (FileException ex) { }
+ } catch (FileException ex) {
+ stderr.writeln("FATAL: cannot create --sqlite-db-path directory: ", pth_sqlite.base);
+ stderr.writeln(" (", ex.msg, ")");
+ import core.runtime;
+ core.runtime.Runtime.terminate();
+ }
}
auto db = Database(pth_sqlite.sqlite_file);
{
diff --git a/src/sisudoc/io_out/text.d b/src/sisudoc/outputs/io_out/text.d
index 7c4315a..89e85d9 100644
--- a/src/sisudoc/io_out/text.d
+++ b/src/sisudoc/outputs/io_out/text.d
@@ -47,12 +47,12 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.text;
+module sisudoc.outputs.io_out.text;
@safe:
template outputText() {
template munge() {
- import sisudoc.io_out;
- import sisudoc.io_out.rgx;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.rgx;
import std.stdio;
import std.conv;
import std.conv : to;
@@ -352,7 +352,7 @@ template outputText() {
}
template theDocument() {
import std.stdio;
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
string text_head(M)(
M doc_matters,
) {
@@ -434,7 +434,7 @@ template outputText() {
M doc_matters,
) {
import std.stdio;
- import sisudoc.io_out;
+ import sisudoc.outputs.io_out;
void text_out(D,M)(
const D doc_abstraction,
M doc_matters,
diff --git a/src/sisudoc/io_out/xmls.d b/src/sisudoc/outputs/io_out/xmls.d
index 7b503dd..d63deba 100644
--- a/src/sisudoc/io_out/xmls.d
+++ b/src/sisudoc/outputs/io_out/xmls.d
@@ -47,20 +47,20 @@
[https://git.sisudoc.org/]
+/
-module sisudoc.io_out.xmls;
+module sisudoc.outputs.io_out.xmls;
@safe:
template outputXHTMLs() {
import std.file;
import std.outbuffer;
import std.uri;
import std.conv : to;
- import sisudoc.io_out;
- import sisudoc.io_out.rgx;
- import sisudoc.meta.rgx_files;
- import sisudoc.io_out.rgx_xhtml;
- import sisudoc.io_out.create_zip_file;
- import sisudoc.io_out.xmls;
- import sisudoc.io_out.xmls_css;
+ import sisudoc.outputs.io_out;
+ import sisudoc.outputs.io_out.rgx;
+ import sisudoc.ocda.meta.rgx_files;
+ import sisudoc.outputs.io_out.rgx_xhtml;
+ import sisudoc.outputs.io_out.create_zip_file;
+ import sisudoc.outputs.io_out.xmls;
+ import sisudoc.outputs.io_out.xmls_css;
mixin spineRgxOut;
mixin spineRgxXHTML;
struct outputXHTMLs {
diff --git a/src/sisudoc/io_out/xmls_css.d b/src/sisudoc/outputs/io_out/xmls_css.d
index 2f5c2b1..655b236 100644
--- a/src/sisudoc/io_out/xmls_css.d
+++ b/src/sisudoc/outputs/io_out/xmls_css.d
@@ -50,7 +50,7 @@
/++
default css settings
+/
-module sisudoc.io_out.xmls_css;
+module sisudoc.outputs.io_out.xmls_css;
@safe:
template spineCss() {
import std.format;
@@ -1217,6 +1217,56 @@ p.form {
footer {
background-color : #00704E;
}
+/* ------------------------------------------------------------------ */
+/* Homepage / body-flow HTML5 markup */
+/* <ul>/<li> and <details>/<summary> aligned with <p> and headings. */
+/* Scoped to direct body children to avoid affecting div.toc lists. */
+/* ------------------------------------------------------------------ */
+body > ul,
+body > ol {
+ margin-left : 5%%;
+ margin-right : 2em;
+ margin-top : 0.8em;
+ margin-bottom : 0.8em;
+ padding-left : 1.5em;
+ list-style-position : outside;
+}
+body > ul { list-style-type : disc; }
+body > ol { list-style-type : decimal; }
+body > ul li,
+body > ol li {
+ margin-left : 0;
+ margin-right : 0;
+ margin-top : 0.3em;
+ margin-bottom : 0.3em;
+ line-height : 133%%;
+ background : none;
+ text-align : left;
+ text-indent : 0;
+}
+details {
+ margin-top : 1em;
+ margin-bottom : 0.5em;
+}
+summary {
+ margin-left : 5%%;
+ margin-right : 2em;
+ padding-left : 0.2em;
+ padding-top : 0.4em;
+ padding-bottom : 0.4em;
+ font-size : 1.6rem;
+ line-height : 133%%;
+ cursor : pointer;
+}
+details > ul,
+details > ol {
+ margin-left : 5%%;
+ padding-left : 1.5em;
+}
+details > ul li,
+details > ol li {
+ margin-left : 0;
+}
┃",
_color_ocn_light,
_css_indent,
@@ -1957,6 +2007,56 @@ p.form {
footer {
background-color : #FF704E;
}
+/* ------------------------------------------------------------------ */
+/* Homepage / body-flow HTML5 markup */
+/* <ul>/<li> and <details>/<summary> aligned with <p> and headings. */
+/* Scoped to direct body children to avoid affecting div.toc lists. */
+/* ------------------------------------------------------------------ */
+body > ul,
+body > ol {
+ margin-left : 5%%;
+ margin-right : 2em;
+ margin-top : 0.8em;
+ margin-bottom : 0.8em;
+ padding-left : 1.5em;
+ list-style-position : outside;
+}
+body > ul { list-style-type : disc; }
+body > ol { list-style-type : decimal; }
+body > ul li,
+body > ol li {
+ margin-left : 0;
+ margin-right : 0;
+ margin-top : 0.3em;
+ margin-bottom : 0.3em;
+ line-height : 133%%;
+ background : none;
+ text-align : left;
+ text-indent : 0;
+}
+details {
+ margin-top : 1em;
+ margin-bottom : 0.5em;
+}
+summary {
+ margin-left : 5%%;
+ margin-right : 2em;
+ padding-left : 0.2em;
+ padding-top : 0.4em;
+ padding-bottom : 0.4em;
+ font-size : 1.6rem;
+ line-height : 133%%;
+ cursor : pointer;
+}
+details > ul,
+details > ol {
+ margin-left : 5%%;
+ padding-left : 1.5em;
+}
+details > ul li,
+details > ol li {
+ margin-left : 0;
+}
┃",
_color_ocn_dark,
_css_indent,
@@ -2634,6 +2734,56 @@ p.form {
footer {
background-color : #00704E;
}
+/* ------------------------------------------------------------------ */
+/* Homepage / body-flow HTML5 markup */
+/* <ul>/<li> and <details>/<summary> aligned with <p> and headings. */
+/* Scoped to direct body children to avoid affecting div.toc lists. */
+/* ------------------------------------------------------------------ */
+body > ul,
+body > ol {
+ margin-left : 5%%;
+ margin-right : 2em;
+ margin-top : 0.8em;
+ margin-bottom : 0.8em;
+ padding-left : 1.5em;
+ list-style-position : outside;
+}
+body > ul { list-style-type : disc; }
+body > ol { list-style-type : decimal; }
+body > ul li,
+body > ol li {
+ margin-left : 0;
+ margin-right : 0;
+ margin-top : 0.3em;
+ margin-bottom : 0.3em;
+ line-height : 133%%;
+ background : none;
+ text-align : left;
+ text-indent : 0;
+}
+details {
+ margin-top : 1em;
+ margin-bottom : 0.5em;
+}
+summary {
+ margin-left : 5%%;
+ margin-right : 2em;
+ padding-left : 0.2em;
+ padding-top : 0.4em;
+ padding-bottom : 0.4em;
+ font-size : 1.6rem;
+ line-height : 133%%;
+ cursor : pointer;
+}
+details > ul,
+details > ol {
+ margin-left : 5%%;
+ padding-left : 1.5em;
+}
+details > ul li,
+details > ol li {
+ margin-left : 0;
+}
┃",
_color_ocn_light,
_css_indent,
@@ -3300,6 +3450,56 @@ p.form {
footer {
background-color : #FF704E;
}
+/* ------------------------------------------------------------------ */
+/* Homepage / body-flow HTML5 markup */
+/* <ul>/<li> and <details>/<summary> aligned with <p> and headings. */
+/* Scoped to direct body children to avoid affecting div.toc lists. */
+/* ------------------------------------------------------------------ */
+body > ul,
+body > ol {
+ margin-left : 5%%;
+ margin-right : 2em;
+ margin-top : 0.8em;
+ margin-bottom : 0.8em;
+ padding-left : 1.5em;
+ list-style-position : outside;
+}
+body > ul { list-style-type : disc; }
+body > ol { list-style-type : decimal; }
+body > ul li,
+body > ol li {
+ margin-left : 0;
+ margin-right : 0;
+ margin-top : 0.3em;
+ margin-bottom : 0.3em;
+ line-height : 133%%;
+ background : none;
+ text-align : left;
+ text-indent : 0;
+}
+details {
+ margin-top : 1em;
+ margin-bottom : 0.5em;
+}
+summary {
+ margin-left : 5%%;
+ margin-right : 2em;
+ padding-left : 0.2em;
+ padding-top : 0.4em;
+ padding-bottom : 0.4em;
+ font-size : 1.6rem;
+ line-height : 133%%;
+ cursor : pointer;
+}
+details > ul,
+details > ol {
+ margin-left : 5%%;
+ padding-left : 1.5em;
+}
+details > ul li,
+details > ol li {
+ margin-left : 0;
+}
┃",
_color_ocn_dark,
_css_indent,
diff --git a/src/sisudoc/share/defaults.d b/src/sisudoc/outputs/share/defaults.d
index 4972992..d61a038 100644
--- a/src/sisudoc/share/defaults.d
+++ b/src/sisudoc/outputs/share/defaults.d
@@ -50,7 +50,7 @@
/++
shared default settings
+/
-module sisudoc.share.defaults;
+module sisudoc.outputs.share.defaults;
@safe:
template Msg() {
import std.stdio;
diff --git a/src/sisudoc/spine.d b/src/sisudoc/spine.d
index e710281..c80814e 100755..100644
--- a/src/sisudoc/spine.d
+++ b/src/sisudoc/spine.d
@@ -60,25 +60,25 @@ import std.getopt;
import std.file;
import std.path;
import std.process;
-import sisudoc.conf.compile_time_info;
-import sisudoc.meta;
-import sisudoc.meta.metadoc;
-import sisudoc.meta.metadoc_curate;
-import sisudoc.meta.metadoc_curate_authors;
-import sisudoc.meta.metadoc_curate_topics;
-import sisudoc.meta.metadoc_from_src;
-import sisudoc.meta.conf_make_meta_structs;
-import sisudoc.meta.conf_make_meta_json;
-import sisudoc.meta.defaults;
-import sisudoc.meta.doc_debugs;
-import sisudoc.meta.rgx;
-import sisudoc.meta.rgx_yaml;
-import sisudoc.meta.rgx_files;
-import sisudoc.io_in.paths_source;
-import sisudoc.io_in.read_config_files;
-import sisudoc.io_in.read_source_files;
-import sisudoc.io_in.read_zip_pod;
-import sisudoc.io_out.hub;
+import sisudoc.outputs.conf.compile_time_info;
+import sisudoc.ocda.meta;
+import sisudoc.ocda.meta.metadoc;
+import sisudoc.outputs.io_out.curate.metadoc_curate;
+import sisudoc.outputs.io_out.curate.metadoc_curate_authors;
+import sisudoc.outputs.io_out.curate.metadoc_curate_topics;
+import sisudoc.ocda.meta.metadoc_from_src;
+import sisudoc.ocda.meta.conf_make_meta_structs;
+import sisudoc.ocda.meta.conf_make_meta_json;
+import sisudoc.ocda.meta.defaults;
+import sisudoc.ocda.meta.doc_debugs;
+import sisudoc.ocda.meta.rgx;
+import sisudoc.ocda.meta.rgx_yaml;
+import sisudoc.ocda.meta.rgx_files;
+import sisudoc.ocda.io_in.paths_source;
+import sisudoc.ocda.io_in.read_config_files;
+import sisudoc.ocda.io_in.read_source_files;
+import sisudoc.ocda.io_in.read_zip_pod;
+import sisudoc.outputs.io_out.hub;
mixin(import("version.txt"));
mixin(import("configuration.txt"));
mixin CompileTimeInfo;
@@ -920,7 +920,7 @@ string program_name = "spine";
{ /+ local site config +/
_conf_file_details = configFilePaths!()(_manifested, _env, _opt_action.config_path_set);
auto _config_local_site_struct = readConfigSite!()(_conf_file_details, _opt_action, _cfg);
- import sisudoc.meta.conf_make_meta_yaml;
+ import sisudoc.ocda.meta.conf_make_meta_yaml;
_siteConfig = _config_local_site_struct.configParseYAMLreturnSpineStruct!()(_siteConfig, _manifested, _opt_action, _cfg); // - get local site config
break;
}
@@ -928,11 +928,11 @@ string program_name = "spine";
}
} else { /+ local site config +/
auto _config_local_site_struct = readConfigSite!()(_conf_file_details, _opt_action, _cfg);
- import sisudoc.meta.conf_make_meta_yaml;
+ import sisudoc.ocda.meta.conf_make_meta_yaml;
_siteConfig = _config_local_site_struct.configParseYAMLreturnSpineStruct!()(_siteConfig, _manifested, _opt_action, _cfg); // - get local site config
}
if (_opt_action.show_config) {
- import sisudoc.meta.metadoc_show_config;
+ import sisudoc.ocda.meta.metadoc_show_config;
spineShowSiteConfig!()(_opt_action, _siteConfig);
}
if (!(_opt_action.skip_output)) {
@@ -1306,32 +1306,32 @@ string program_name = "spine";
}
/+ ↓ debugs +/
if (doc.matters.opt.action.show_summary) {
- import sisudoc.meta.metadoc_show_summary;
+ import sisudoc.ocda.meta.metadoc_show_summary;
spineMetaDocSummary!()(doc);
}
/+ ↓ debugs +/
if (doc.matters.opt.action.show_metadata) {
- import sisudoc.meta.metadoc_show_metadata;
+ import sisudoc.ocda.meta.metadoc_show_metadata;
spineShowMetaData!()(doc.matters);
}
/+ ↓ debugs +/
if (doc.matters.opt.action.show_make) {
- import sisudoc.meta.metadoc_show_make;
+ import sisudoc.ocda.meta.metadoc_show_make;
spineShowMake!()(doc.matters);
}
/+ ↓ debugs +/
if (doc.matters.opt.action.show_config) {
- import sisudoc.meta.metadoc_show_config;
+ import sisudoc.ocda.meta.metadoc_show_config;
spineShowConfig!()(doc.matters);
}
/+ ↓ document abstraction text representation +/
if (doc.matters.opt.action.show_abstraction) {
- import sisudoc.io_out.create_abstraction_txt;
+ import sisudoc.ocda.abstraction.ssp;
spineAbstractionTxt!()(doc);
}
/+ ↓ document abstraction sqlite database +/
if (doc.matters.opt.action.show_abstraction_db) {
- import sisudoc.io_out.create_abstraction_db;
+ import sisudoc.outputs.io_out.create_abstraction_db;
spineAbstractionDb!()(doc);
}
if (doc.matters.opt.action.curate) {
@@ -1415,32 +1415,32 @@ string program_name = "spine";
}
/+ ↓ debugs +/
if (doc.matters.opt.action.show_summary) {
- import sisudoc.meta.metadoc_show_summary;
+ import sisudoc.ocda.meta.metadoc_show_summary;
spineMetaDocSummary!()(doc);
}
/+ ↓ debugs +/
if (doc.matters.opt.action.show_metadata) {
- import sisudoc.meta.metadoc_show_metadata;
+ import sisudoc.ocda.meta.metadoc_show_metadata;
spineShowMetaData!()(doc.matters);
}
/+ ↓ debugs +/
if (doc.matters.opt.action.show_make) {
- import sisudoc.meta.metadoc_show_make;
+ import sisudoc.ocda.meta.metadoc_show_make;
spineShowMake!()(doc.matters);
}
/+ ↓ debugs +/
if (doc.matters.opt.action.show_config) {
- import sisudoc.meta.metadoc_show_config;
+ import sisudoc.ocda.meta.metadoc_show_config;
spineShowConfig!()(doc.matters);
}
/+ ↓ document abstraction text representation +/
if (doc.matters.opt.action.show_abstraction) {
- import sisudoc.io_out.create_abstraction_txt;
+ import sisudoc.ocda.abstraction.ssp;
spineAbstractionTxt!()(doc);
}
/+ ↓ document abstraction sqlite database +/
if (doc.matters.opt.action.show_abstraction_db) {
- import sisudoc.io_out.create_abstraction_db;
+ import sisudoc.outputs.io_out.create_abstraction_db;
spineAbstractionDb!()(doc);
}
if (doc.matters.opt.action.curate) {
@@ -1499,7 +1499,7 @@ string program_name = "spine";
spineMetaDocCuratesAuthors!()(hvst.curates, _make_and_meta_struct, _opt_action);
}
if (_opt_action.vox_gt_1) {
- import sisudoc.io_out.paths_output;
+ import sisudoc.outputs.io_out.paths_output;
auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
if (_opt_action.curate_authors) {
writeln("- ", out_pth.curate("authors.html"));
diff --git a/sundry/editor-syntax-etc/emacs/sisu-spine-mode-autoloads.el b/sundry/editor-syntax-etc/emacs/sisu-spine-mode-autoloads.el
index 4cc6332..098a28c 100644
--- a/sundry/editor-syntax-etc/emacs/sisu-spine-mode-autoloads.el
+++ b/sundry/editor-syntax-etc/emacs/sisu-spine-mode-autoloads.el
@@ -1,10 +1,28 @@
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
+;; Regex / font-lock major mode. Fallback for Emacs < 29 and for users
+;; who have not installed the tree-sitter-sisu parser.
(autoload 'sisu-spine-mode "sisu-spine-mode" "\
Major mode for editing SiSU (spine) markup files.
SiSU (https://www.sisudoc.org/) document structuring, publishing
and search.
\(fn)" t nil)
-(add-to-list 'auto-mode-alist '("\\.sst\\'" . sisu-spine-mode))
-(add-to-list 'auto-mode-alist '("\\.ssm\\'" . sisu-spine-mode))
-(add-to-list 'auto-mode-alist '("\\.ssi\\'" . sisu-spine-mode))
+
+;; Tree-sitter major mode (Emacs 29+). When the parser is installed it
+;; is selected by `auto-mode-alist'; otherwise the regex mode is used.
+(autoload 'sisu-spine-ts-mode "sisu-spine-ts-mode" "\
+Tree-sitter major mode for editing SiSU (spine) markup files.
+
+\(fn)" t nil)
+(autoload 'sisu-spine-ts-install-grammar "sisu-spine-ts-mode" "\
+Install the tree-sitter-sisu grammar for `sisu-spine-ts-mode'.
+\(fn)" t nil)
+(defun sisu-spine-auto-mode ()
+ "Choose `sisu-spine-ts-mode' if the parser is installed, else fall back."
+ (if (and (fboundp 'treesit-ready-p) (treesit-ready-p 'sisu t))
+ (sisu-spine-ts-mode)
+ (sisu-spine-mode)))
+
+(add-to-list 'auto-mode-alist '("\\.sst\\'" . sisu-spine-auto-mode))
+(add-to-list 'auto-mode-alist '("\\.ssm\\'" . sisu-spine-auto-mode))
+(add-to-list 'auto-mode-alist '("\\.ssi\\'" . sisu-spine-auto-mode))
diff --git a/sundry/editor-syntax-etc/emacs/sisu-spine-ts-mode.el b/sundry/editor-syntax-etc/emacs/sisu-spine-ts-mode.el
new file mode 100644
index 0000000..ef59d14
--- /dev/null
+++ b/sundry/editor-syntax-etc/emacs/sisu-spine-ts-mode.el
@@ -0,0 +1,296 @@
+;;; sisu-spine-ts-mode.el --- Tree-sitter major mode for SiSU spine markup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Free Software Foundation, Inc.
+
+;; Author: Ralph Amissah <ralph.amissah@gmail.com>
+;; Maintainer: Ralph Amissah <ralph.amissah@gmail.com>
+;; Keywords: text, syntax, processes, tools
+;; Version: 1.0.0
+;; URL: https://git.sisudoc.org/projects/sisudoc-spine/tree/sundry/editor-syntax-etc/emacs/sisu-spine-ts-mode.el
+;; https://sisudoc.org/
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;;; Commentary:
+
+;; Tree-sitter-backed major mode for SiSU spine markup (.sst / .ssm /
+;; .ssi). Sibling to `sisu-spine-mode' (regex / font-lock); requires
+;; Emacs 29 or newer with `treesit' built in and the tree-sitter-sisu
+;; parser installed.
+;;
+;; To install the parser inside Emacs:
+;;
+;; M-x sisu-spine-ts-install-grammar RET
+;;
+;; or, equivalently:
+;;
+;; (add-to-list 'treesit-language-source-alist
+;; '(sisu "https://git.sisudoc.org/projects"
+;; :source-dir "tree-sitter-sisu/src"))
+;; M-x treesit-install-language-grammar RET sisu RET
+;;
+;; The mode is auto-enabled for .sst / .ssm / .ssi files when the parser
+;; is available. When it is not, `sisu-spine-mode' (the regex variant)
+;; remains available as a fallback.
+
+;;; Code:
+
+(require 'treesit nil t)
+
+(defgroup sisu-spine-ts nil
+ "Tree-sitter mode for SiSU spine markup."
+ :group 'text
+ :prefix "sisu-spine-ts-")
+
+;; ---------------------------------------------------------------------
+;; Faces (mirror the structural categories the highlights.scm assigns)
+;; ---------------------------------------------------------------------
+
+(defface sisu-spine-ts-heading-1-face
+ '((t (:inherit outline-1 :weight bold)))
+ "Face for :A~ headings."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-heading-2-face
+ '((t (:inherit outline-2 :weight bold)))
+ "Face for :B~ headings."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-heading-3-face
+ '((t (:inherit outline-3 :weight bold)))
+ "Face for :C~ / :D~ headings."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-heading-segment-face
+ '((t (:inherit outline-4)))
+ "Face for 1~ / 2~ / 3~ segment headings."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-block-delimiter-face
+ '((t (:inherit font-lock-keyword-face)))
+ "Face for block opening/closing delimiters."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-raw-content-face
+ '((t (:inherit font-lock-string-face)))
+ "Face for raw block content (code, table, etc.)."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-footnote-face
+ '((t (:inherit font-lock-doc-face)))
+ "Face for footnote and editor-note bodies."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-link-face
+ '((t (:inherit link)))
+ "Face for link text and target URLs."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-book-index-face
+ '((t (:inherit font-lock-preprocessor-face)))
+ "Face for book-index entries (={...})."
+ :group 'sisu-spine-ts)
+
+(defface sisu-spine-ts-marker-face
+ '((t (:inherit font-lock-builtin-face)))
+ "Face for inline-formatting delimiters and other punctuation markers."
+ :group 'sisu-spine-ts)
+
+;; ---------------------------------------------------------------------
+;; Font-lock rules
+;; ---------------------------------------------------------------------
+
+(defvar sisu-spine-ts--font-lock-settings
+ (when (fboundp 'treesit-font-lock-rules)
+ (treesit-font-lock-rules
+ :language 'sisu
+ :feature 'comment
+ '((version_comment) @font-lock-doc-face
+ (header_comment) @font-lock-comment-face
+ (body_comment) @font-lock-comment-face)
+
+ :language 'sisu
+ :feature 'header
+ '((header_field key: (header_key) @font-lock-keyword-face)
+ (header_field value: (header_value) @font-lock-string-face)
+ (header_continuation) @font-lock-string-face)
+
+ :language 'sisu
+ :feature 'heading
+ '(((heading_part marker: (part_marker) @m
+ content: (heading_content) @sisu-spine-ts-heading-1-face)
+ (:match "^:A~$" @m))
+ ((heading_part marker: (part_marker) @m
+ content: (heading_content) @sisu-spine-ts-heading-2-face)
+ (:match "^:B~$" @m))
+ ((heading_part marker: (part_marker) @m
+ content: (heading_content) @sisu-spine-ts-heading-3-face)
+ (:match "^:[CD]~$" @m))
+ (heading_part marker: (part_marker) @sisu-spine-ts-marker-face)
+ (heading_segment marker: (segment_marker) @sisu-spine-ts-marker-face
+ content: (heading_content) @sisu-spine-ts-heading-segment-face)
+ (segment_name) @font-lock-function-name-face
+ (suppress_marker) @sisu-spine-ts-marker-face)
+
+ :language 'sisu
+ :feature 'block
+ '((block_open) @sisu-spine-ts-block-delimiter-face
+ (block_close) @sisu-spine-ts-block-delimiter-face
+ (raw_content) @sisu-spine-ts-raw-content-face
+ (table_spec) @sisu-spine-ts-block-delimiter-face)
+
+ :language 'sisu
+ :feature 'inline
+ '((emphasis) @italic
+ (bold) @bold
+ (italic) @italic
+ (underline) @underline
+ (citation_mark) @font-lock-string-face
+ (superscript) @font-lock-type-face
+ (subscript) @font-lock-type-face
+ (inserted) @underline
+ (strikethrough) @shadow
+ (monospace_inline) @font-lock-constant-face)
+
+ :language 'sisu
+ :feature 'note
+ '((footnote) @sisu-spine-ts-footnote-face
+ (footnote_marker) @sisu-spine-ts-marker-face
+ (editor_note) @sisu-spine-ts-footnote-face)
+
+ :language 'sisu
+ :feature 'link
+ '((link text: (link_text) @sisu-spine-ts-link-face)
+ (link target: (url) @sisu-spine-ts-link-face)
+ (link target: (anchor_ref) @sisu-spine-ts-link-face)
+ (link target: (collection_path) @sisu-spine-ts-link-face)
+ (image spec: (image_spec) @sisu-spine-ts-link-face)
+ (auto_footnote_marker) @sisu-spine-ts-marker-face
+ (inline_anchor) @font-lock-function-name-face
+ (anchor_name) @font-lock-function-name-face)
+
+ :language 'sisu
+ :feature 'index
+ '((book_index) @sisu-spine-ts-book-index-face
+ (index_content) @font-lock-string-face)
+
+ :language 'sisu
+ :feature 'misc
+ '((paragraph_prefix) @sisu-spine-ts-marker-face
+ (page_break) @sisu-spine-ts-marker-face
+ (horizontal_rule) @sisu-spine-ts-marker-face
+ (line_break) @sisu-spine-ts-marker-face
+ (ocn_suppress) @font-lock-comment-face
+ (ocn_suppress_open) @font-lock-comment-face
+ (ocn_suppress_close) @font-lock-comment-face
+ (composite_include) @font-lock-preprocessor-face
+ (include_path) @font-lock-string-face)))
+ "Tree-sitter font-lock rules for `sisu-spine-ts-mode'.")
+
+;; ---------------------------------------------------------------------
+;; Imenu / navigation / things
+;; ---------------------------------------------------------------------
+
+(defvar sisu-spine-ts--imenu-settings
+ '(("Part headings"
+ "\\`heading_part\\'"
+ nil
+ sisu-spine-ts--imenu-name-part)
+ ("Segment headings"
+ "\\`heading_segment\\'"
+ nil
+ sisu-spine-ts--imenu-name-segment))
+ "`treesit-simple-imenu-settings' for `sisu-spine-ts-mode'.")
+
+(defun sisu-spine-ts--imenu-name-part (node)
+ "Return display name for a heading_part NODE."
+ (let ((c (treesit-node-child-by-field-name node "content"))
+ (m (treesit-node-child-by-field-name node "marker")))
+ (concat (and m (treesit-node-text m t)) " "
+ (and c (treesit-node-text c t)))))
+
+(defun sisu-spine-ts--imenu-name-segment (node)
+ "Return display name for a heading_segment NODE."
+ (let ((c (treesit-node-child-by-field-name node "content"))
+ (m (treesit-node-child-by-field-name node "marker")))
+ (concat (and m (treesit-node-text m t)) " "
+ (and c (treesit-node-text c t)))))
+
+(defvar sisu-spine-ts--thing-settings
+ '((sisu
+ (defun "\\`heading_\\(part\\|segment\\)\\'")
+ (sentence "\\`paragraph\\'")
+ (text "\\`\\(text\\|raw_content\\|heading_content\\)\\'")))
+ "`treesit-thing-settings' for `sisu-spine-ts-mode'.")
+
+;; ---------------------------------------------------------------------
+;; Grammar install helper
+;; ---------------------------------------------------------------------
+
+;;;###autoload
+(defun sisu-spine-ts-install-grammar ()
+ "Register and install the tree-sitter-sisu grammar.
+Convenience wrapper around `treesit-install-language-grammar' with the
+upstream URL and source directory pre-filled."
+ (interactive)
+ (unless (boundp 'treesit-language-source-alist)
+ (user-error "treesit not available; Emacs 29+ required"))
+ (add-to-list 'treesit-language-source-alist
+ '(sisu "https://git.sisudoc.org/projects"
+ :source-dir "tree-sitter-sisu/src"))
+ (treesit-install-language-grammar 'sisu))
+
+;; ---------------------------------------------------------------------
+;; Major mode
+;; ---------------------------------------------------------------------
+
+;;;###autoload
+(define-derived-mode sisu-spine-ts-mode text-mode "SiSU-Spine[ts]"
+ "Major mode for SiSU spine markup, backed by tree-sitter."
+ (unless (and (fboundp 'treesit-ready-p) (treesit-ready-p 'sisu))
+ (user-error
+ "tree-sitter-sisu parser not installed; run M-x sisu-spine-ts-install-grammar"))
+ (treesit-parser-create 'sisu)
+
+ ;; Comments
+ (setq-local comment-start "% "
+ comment-end ""
+ comment-start-skip "%[ \t]+")
+
+ ;; Font-lock
+ (setq-local treesit-font-lock-settings sisu-spine-ts--font-lock-settings)
+ (setq-local treesit-font-lock-feature-list
+ '((comment header heading)
+ (block inline note link index)
+ (misc)
+ ()))
+
+ ;; Imenu / navigation
+ (setq-local treesit-simple-imenu-settings sisu-spine-ts--imenu-settings)
+ (setq-local treesit-thing-settings sisu-spine-ts--thing-settings)
+ (setq-local treesit-defun-type-regexp "\\`heading_\\(part\\|segment\\)\\'")
+ (setq-local treesit-defun-name-function
+ (lambda (node)
+ (let ((c (treesit-node-child-by-field-name node "content")))
+ (and c (treesit-node-text c t)))))
+
+ (treesit-major-mode-setup))
+
+;;;###autoload
+(when (fboundp 'treesit-ready-p)
+ (dolist (ext '("\\.sst\\'" "\\.ssm\\'" "\\.ssi\\'"))
+ ;; Prefer the ts mode iff the parser is installed; otherwise fall
+ ;; back to `sisu-spine-mode'.
+ (add-to-list 'auto-mode-alist
+ (cons ext
+ (lambda ()
+ (if (treesit-ready-p 'sisu t)
+ (sisu-spine-ts-mode)
+ (sisu-spine-mode)))))))
+
+(provide 'sisu-spine-ts-mode)
+
+;;; sisu-spine-ts-mode.el ends here
diff --git a/sundry/editor-syntax-etc/nvim/README.md b/sundry/editor-syntax-etc/nvim/README.md
new file mode 100644
index 0000000..8e889e7
--- /dev/null
+++ b/sundry/editor-syntax-etc/nvim/README.md
@@ -0,0 +1,87 @@
+# Neovim integration for SiSU spine markup
+
+Tree-sitter-backed syntax highlighting, folding, and structural
+navigation for `.sst` / `.ssm` / `.ssi` files in Neovim (>= 0.9).
+
+## What is in this directory
+
+```
+nvim/
+ ftdetect/sisu.lua - register .sst/.ssm/.ssi as filetype "sisu"
+ ftplugin/sisu.lua - per-buffer settings (commentstring, conceal)
+ lua/sisu-spine/init.lua - entry point: registers parser config
+ queries/sisu/ - tree-sitter queries (mirrors tree-sitter-sisu/queries/)
+ highlights.scm
+ folds.scm
+ injections.scm
+ textobjects.scm
+ indents.scm
+```
+
+## Install (manual)
+
+1. Symlink or copy this directory into your Neovim runtime path:
+
+ ```sh
+ ln -s /path/to/sisudoc-spine/sundry/editor-syntax-etc/nvim \
+ ~/.config/nvim/pack/sisu/start/sisu-spine
+ ```
+
+2. Tell `nvim-treesitter` how to fetch the parser. Add to your config
+ (`init.lua`):
+
+ ```lua
+ require("sisu-spine").setup()
+ require("nvim-treesitter.configs").setup({
+ ensure_installed = { "sisu" },
+ highlight = { enable = true },
+ indent = { enable = true },
+ fold = { enable = true },
+ textobjects = { select = { enable = true, lookahead = true } },
+ })
+ ```
+
+3. Build the parser:
+
+ ```vim
+ :TSInstall sisu
+ ```
+
+That is it. Open a `.sst` file - highlighting, folding, and textobject
+selection should all work.
+
+## Install (lazy.nvim)
+
+```lua
+{
+ dir = "/path/to/sisudoc-spine/sundry/editor-syntax-etc/nvim",
+ name = "sisu-spine",
+ ft = { "sisu" },
+ dependencies = { "nvim-treesitter/nvim-treesitter" },
+ config = function()
+ require("sisu-spine").setup()
+ end,
+}
+```
+
+## Sync queries from upstream
+
+The query files are duplicated from `tree-sitter-sisu/queries/` so that
+this Neovim drop-in works without depending on the parser repo's
+checkout layout. To refresh them after grammar changes:
+
+```sh
+cp ../../../sisudoc-spine-tools/tree-sitter-sisu/queries/*.scm \
+ queries/sisu/
+```
+
+(Path is relative to this README.)
+
+## Upstreaming the parser
+
+When the parser is publicly hosted under a stable URL it is worth
+submitting a config to `nvim-treesitter` so users can run `:TSInstall
+sisu` without the local `setup()` call. The required fields are in
+`lua/sisu-spine/init.lua` (`install_info` table); send a PR to
+<https://github.com/nvim-treesitter/nvim-treesitter> patching
+`lua/nvim-treesitter/parsers.lua`.
diff --git a/sundry/editor-syntax-etc/nvim/ftdetect/sisu.lua b/sundry/editor-syntax-etc/nvim/ftdetect/sisu.lua
new file mode 100644
index 0000000..51b4f2f
--- /dev/null
+++ b/sundry/editor-syntax-etc/nvim/ftdetect/sisu.lua
@@ -0,0 +1,7 @@
+vim.filetype.add({
+ extension = {
+ sst = "sisu",
+ ssm = "sisu",
+ ssi = "sisu",
+ },
+})
diff --git a/sundry/editor-syntax-etc/nvim/ftplugin/sisu.lua b/sundry/editor-syntax-etc/nvim/ftplugin/sisu.lua
new file mode 100644
index 0000000..a531238
--- /dev/null
+++ b/sundry/editor-syntax-etc/nvim/ftplugin/sisu.lua
@@ -0,0 +1,13 @@
+-- Buffer-local settings for SiSU spine markup.
+
+vim.bo.commentstring = "%% %s"
+vim.bo.comments = ":%"
+
+-- Soft wrap suits prose.
+vim.wo.wrap = true
+vim.wo.linebreak = true
+
+-- Conceal inline-formatting delimiters when the user opts in
+-- (`:set conceallevel=2`). See queries/sisu/highlights.scm for
+-- @conceal captures.
+vim.wo.conceallevel = vim.wo.conceallevel
diff --git a/sundry/editor-syntax-etc/nvim/lua/sisu-spine/init.lua b/sundry/editor-syntax-etc/nvim/lua/sisu-spine/init.lua
new file mode 100644
index 0000000..d1ae3df
--- /dev/null
+++ b/sundry/editor-syntax-etc/nvim/lua/sisu-spine/init.lua
@@ -0,0 +1,43 @@
+-- Entry point for the SiSU spine markup Neovim integration.
+--
+-- Registers a tree-sitter parser config so users can run
+-- :TSInstall sisu
+-- to fetch and build the parser via nvim-treesitter.
+--
+-- The parser source lives can be found under the
+-- `projects/` namespace on git.sisudoc.org.
+
+local M = {}
+
+--- Register the `sisu` parser with nvim-treesitter and ensure that
+--- `.sst` / `.ssm` / `.ssi` are detected as filetype "sisu".
+---
+--- Call once from your init.lua before invoking `:TSInstall sisu`.
+function M.setup()
+ local ok, parsers = pcall(require, "nvim-treesitter.parsers")
+ if not ok then
+ vim.notify(
+ "sisu-spine: nvim-treesitter is not installed; "
+ .. "syntax highlighting will not be available.",
+ vim.log.levels.WARN
+ )
+ return
+ end
+
+ local parser_config = parsers.get_parser_configs()
+ parser_config.sisu = {
+ install_info = {
+ url = "https://git.sisudoc.org/projects/tree-sitter-sisu",
+ files = {
+ "src/parser.c",
+ "src/scanner.c",
+ },
+ branch = "main",
+ generate_requires_npm = false,
+ requires_generate_from_grammar = false,
+ },
+ filetype = "sisu",
+ }
+end
+
+return M
diff --git a/sundry/editor-syntax-etc/nvim/queries/sisu/folds.scm b/sundry/editor-syntax-etc/nvim/queries/sisu/folds.scm
new file mode 100644
index 0000000..69c44d2
--- /dev/null
+++ b/sundry/editor-syntax-etc/nvim/queries/sisu/folds.scm
@@ -0,0 +1,23 @@
+; Code folding queries for SiSU Spine markup
+
+; Block elements are foldable
+(code_block_curly) @fold
+(code_block_tic) @fold
+(poem_block_curly) @fold
+(poem_block_tic) @fold
+(block_block_curly) @fold
+(block_block_tic) @fold
+(group_block_curly) @fold
+(group_block_tic) @fold
+(table_block_curly) @fold
+(table_block_tic) @fold
+(quote_block_tic) @fold
+
+; Multi-line book index entries are foldable
+(book_index) @fold
+
+; Pipe tables are foldable
+(pipe_table) @fold
+
+; Header fields with continuations are foldable
+(header_field) @fold
diff --git a/sundry/editor-syntax-etc/nvim/queries/sisu/highlights.scm b/sundry/editor-syntax-etc/nvim/queries/sisu/highlights.scm
new file mode 100644
index 0000000..3454bd4
--- /dev/null
+++ b/sundry/editor-syntax-etc/nvim/queries/sisu/highlights.scm
@@ -0,0 +1,189 @@
+; Syntax highlighting queries for SiSU Spine markup
+; Compatible with tree-sitter highlight capture names from
+; https://tree-sitter.github.io/tree-sitter/syntax-highlighting
+
+; =================================================================
+; Comments
+; =================================================================
+(version_comment) @comment.documentation
+(header_comment) @comment
+(body_comment) @comment
+
+; =================================================================
+; Header (document metadata)
+; =================================================================
+(header_field
+ key: (header_key) @keyword)
+
+(header_field
+ value: (header_value) @string)
+
+(header_continuation) @string
+
+; =================================================================
+; Headings
+; =================================================================
+(part_marker) @keyword.directive
+(segment_marker) @keyword.directive
+
+(heading_part
+ content: (heading_content) @markup.heading)
+
+(heading_segment
+ content: (heading_content) @markup.heading)
+
+(segment_name) @label
+(suppress_marker) @punctuation.special
+
+; Heading levels for more specific styling
+(heading_part
+ marker: (part_marker) @markup.heading.1
+ (#match? @markup.heading.1 "^:A~$"))
+
+(heading_part
+ marker: (part_marker) @markup.heading.2
+ (#match? @markup.heading.2 "^:B~$"))
+
+(heading_part
+ marker: (part_marker) @markup.heading.3
+ (#match? @markup.heading.3 "^:C~$"))
+
+(heading_part
+ marker: (part_marker) @markup.heading.4
+ (#match? @markup.heading.4 "^:D~$"))
+
+(heading_segment
+ marker: (segment_marker) @markup.heading.5
+ (#match? @markup.heading.5 "^1~$"))
+
+(heading_segment
+ marker: (segment_marker) @markup.heading.6
+ (#match? @markup.heading.6 "^2~$"))
+
+; =================================================================
+; Inline formatting
+; =================================================================
+(emphasis) @markup.italic
+(bold) @markup.bold
+(italic) @markup.italic
+(underline) @markup.underline
+(citation_mark) @markup.quote
+(superscript) @markup.superscript
+(subscript) @markup.subscript
+(inserted) @markup.underline
+(strikethrough) @markup.strikethrough
+(monospace_inline) @markup.raw
+
+; Formatting delimiters
+["*{" "}*"] @punctuation.special
+["!{" "}!"] @punctuation.special
+["/{" "}/"] @punctuation.special
+["_{" "}_"] @punctuation.special
+["\"{" "}\""] @punctuation.special
+["^{" "}^"] @punctuation.special
+[",{" "},"] @punctuation.special
+["+{" "}+"] @punctuation.special
+["-{" "}-"] @punctuation.special
+["#{" "}#"] @punctuation.special
+
+; =================================================================
+; Footnotes and editor notes
+; =================================================================
+(footnote) @markup.link
+(footnote_marker) @punctuation.special
+(editor_note) @markup.link
+
+["~{" "}~"] @punctuation.special
+; Editor-note channel selector: ~[* (asterisk set) or ~[+ (plus set).
+; A distinct capture lets themes colour the two channels separately
+; from the generic footnote delimiters above.
+(editor_note_marker) @attribute
+["]~"] @punctuation.special
+
+; =================================================================
+; Links and images
+; =================================================================
+(link
+ text: (link_text) @markup.link.label)
+
+(link
+ target: (url) @markup.link.url)
+
+(link
+ target: (anchor_ref) @markup.link.url)
+
+(link
+ target: (collection_path) @markup.link.url)
+
+(auto_footnote_marker) @punctuation.special
+
+(image
+ spec: (image_spec) @markup.link.label)
+
+(url) @markup.link.url
+
+(inline_anchor) @label
+(anchor_name) @label
+
+; =================================================================
+; Block elements
+; =================================================================
+(block_open) @keyword.directive
+(block_close) @keyword.directive
+(raw_content) @markup.raw
+
+; Code blocks get more specific highlighting
+(code_block_curly
+ open: (block_open) @keyword.directive)
+(code_block_curly
+ content: (raw_content) @markup.raw.block)
+(code_block_curly
+ close: (block_close) @keyword.directive)
+
+(code_block_tic
+ open: (block_open) @keyword.directive)
+(code_block_tic
+ content: (raw_content) @markup.raw.block)
+(code_block_tic
+ close: (block_close) @keyword.directive)
+
+; =================================================================
+; Book index
+; =================================================================
+(book_index) @markup.list
+(index_content) @string
+
+; =================================================================
+; Paragraph prefixes
+; =================================================================
+(paragraph_prefix) @punctuation.special
+
+; =================================================================
+; Special markers
+; =================================================================
+(ocn_suppress) @comment
+(ocn_suppress_open) @comment
+(ocn_suppress_close) @comment
+
+(page_break) @punctuation.special
+(horizontal_rule) @punctuation.special
+
+; =================================================================
+; Composite includes
+; =================================================================
+(composite_include) @keyword.import
+(include_path) @string.special.path
+
+; =================================================================
+; Pipe table
+; =================================================================
+(table_spec) @keyword.directive
+(table_row) @markup.raw
+
+; =================================================================
+; Text
+; =================================================================
+(text) @spell
+
+; Line break
+(line_break) @punctuation.special
diff --git a/sundry/editor-syntax-etc/nvim/queries/sisu/indents.scm b/sundry/editor-syntax-etc/nvim/queries/sisu/indents.scm
new file mode 100644
index 0000000..aa73af8
--- /dev/null
+++ b/sundry/editor-syntax-etc/nvim/queries/sisu/indents.scm
@@ -0,0 +1,48 @@
+; Indentation queries for SiSU Spine markup.
+;
+; SiSU markup is largely flat: paragraphs and headings live at column 0,
+; block bodies preserve their author-supplied indentation verbatim, and
+; nesting is by markers rather than by indent. So indents.scm is mostly a
+; no-op - the goal is to ensure that auto-indent on <CR> stays at column 0
+; for normal lines and respects existing indentation inside header
+; continuations and blocks.
+
+; Tree-sitter indent semantics (per nvim-treesitter and treesit):
+; @indent.begin - increases indent for the following line
+; @indent.end - matches the @indent.begin and decreases indent
+; @indent.zero - resets indent to column 0
+; @indent.align - aligns following lines with this node
+; @indent.branch - same level as the parent (for else/elif-style joins)
+
+; Top-level structures live at column 0 - reset to zero on the next line.
+(heading_part) @indent.zero
+(heading_segment) @indent.zero
+(paragraph) @indent.zero
+(book_index) @indent.zero
+(composite_include) @indent.zero
+(page_break) @indent.zero
+(horizontal_rule) @indent.zero
+(ocn_suppress_open) @indent.zero
+(ocn_suppress_close) @indent.zero
+(body_comment) @indent.zero
+
+; Block elements: opening line increases indent for the body, closing
+; line returns to zero. Editors that respect this will visually indent
+; raw content one step from the delimiter line, which is conventional.
+(code_block_curly) @indent.align
+(code_block_tic) @indent.align
+(poem_block_curly) @indent.align
+(poem_block_tic) @indent.align
+(block_block_curly) @indent.align
+(block_block_tic) @indent.align
+(group_block_curly) @indent.align
+(group_block_tic) @indent.align
+(table_block_curly) @indent.align
+(table_block_tic) @indent.align
+(quote_block_tic) @indent.align
+
+; Header continuation lines are indented by two spaces from column 0;
+; mark continuations as align so a host that chooses to auto-indent the
+; next continuation line matches the previous one.
+(header_field) @indent.align
+(header_continuation) @indent.align
diff --git a/sundry/editor-syntax-etc/nvim/queries/sisu/injections.scm b/sundry/editor-syntax-etc/nvim/queries/sisu/injections.scm
new file mode 100644
index 0000000..27f622b
--- /dev/null
+++ b/sundry/editor-syntax-etc/nvim/queries/sisu/injections.scm
@@ -0,0 +1,16 @@
+; Language injection queries for SiSU Spine markup
+;
+; Code blocks could potentially inject language-specific highlighting,
+; but SiSU code blocks don't specify language. These queries are
+; provided as a starting point for future extension.
+
+; Code block content could be injected with a specific language
+; if the block type or context provides a hint.
+; For now, raw content in code blocks is left unhighlighted.
+
+; Example: if code blocks specified a language, e.g. code(d){
+; ((code_block_curly
+; open: (block_open) @_open
+; content: (raw_content) @injection.content)
+; (#match? @_open "code\\(d\\)")
+; (#set! injection.language "d"))
diff --git a/sundry/editor-syntax-etc/nvim/queries/sisu/textobjects.scm b/sundry/editor-syntax-etc/nvim/queries/sisu/textobjects.scm
new file mode 100644
index 0000000..0a82481
--- /dev/null
+++ b/sundry/editor-syntax-etc/nvim/queries/sisu/textobjects.scm
@@ -0,0 +1,140 @@
+; Text-object queries for SiSU Spine markup.
+;
+; Capture conventions follow nvim-treesitter/textobjects:
+; @<thing>.outer -> select including delimiters / surrounding whitespace
+; @<thing>.inner -> select content only
+;
+; Hosts that consume these (Neovim's nvim-treesitter-textobjects, Helix,
+; Emacs treesit) bind keys such as `af` / `if` to .outer / .inner.
+
+; =================================================================
+; Headings (sectioning units)
+; =================================================================
+; A whole heading line is a "section header" object. Heading sections
+; (the heading plus its body content up to the next heading of equal or
+; higher level) are not directly expressible in tree-sitter without
+; additional grammar work; hosts can synthesise that from these captures.
+
+(heading_part) @class.outer
+(heading_part
+ content: (heading_content) @class.inner)
+
+(heading_segment) @class.outer
+(heading_segment
+ content: (heading_content) @class.inner)
+
+; =================================================================
+; Block elements (code / poem / block / group / table / quote)
+; =================================================================
+; Whole block including delimiters; raw_content is the inner.
+
+(code_block_curly) @function.outer
+(code_block_curly
+ content: (raw_content) @function.inner)
+
+(code_block_tic) @function.outer
+(code_block_tic
+ content: (raw_content) @function.inner)
+
+(poem_block_curly) @function.outer
+(poem_block_curly
+ content: (raw_content) @function.inner)
+
+(poem_block_tic) @function.outer
+(poem_block_tic
+ content: (raw_content) @function.inner)
+
+(block_block_curly) @function.outer
+(block_block_curly
+ content: (raw_content) @function.inner)
+
+(block_block_tic) @function.outer
+(block_block_tic
+ content: (raw_content) @function.inner)
+
+(group_block_curly) @function.outer
+(group_block_curly
+ content: (raw_content) @function.inner)
+
+(group_block_tic) @function.outer
+(group_block_tic
+ content: (raw_content) @function.inner)
+
+(table_block_curly) @function.outer
+(table_block_curly
+ content: (raw_content) @function.inner)
+
+(table_block_tic) @function.outer
+(table_block_tic
+ content: (raw_content) @function.inner)
+
+(quote_block_tic) @function.outer
+(quote_block_tic
+ content: (raw_content) @function.inner)
+
+(pipe_table) @function.outer
+
+; =================================================================
+; Footnotes and editor notes
+; =================================================================
+; Both share the same outer/inner shape; the inner skips the markers and
+; closing delimiters.
+
+(footnote) @comment.outer
+(footnote
+ (_)+ @comment.inner)
+
+(editor_note) @comment.outer
+(editor_note
+ (_)+ @comment.inner)
+
+; =================================================================
+; Links and images
+; =================================================================
+
+(link) @parameter.outer
+(link
+ text: (link_text) @parameter.inner)
+
+(image) @parameter.outer
+(image
+ spec: (image_spec) @parameter.inner)
+
+; =================================================================
+; Paragraph / inline-formatting runs
+; =================================================================
+
+(paragraph) @block.outer
+(paragraph
+ (_)+ @block.inner)
+
+; Inline formatting pairs - useful as fine-grained text objects.
+; The same delimiter character pattern (e.g. `*{` / `}*`) opens and
+; closes each, so .inner is everything between them.
+
+(emphasis) @assignment.outer
+(bold) @assignment.outer
+(italic) @assignment.outer
+(underline) @assignment.outer
+(citation_mark) @assignment.outer
+(superscript) @assignment.outer
+(subscript) @assignment.outer
+(inserted) @assignment.outer
+(strikethrough) @assignment.outer
+(monospace_inline) @assignment.outer
+
+; =================================================================
+; Book index entries
+; =================================================================
+
+(book_index) @attribute.outer
+(book_index
+ (index_content) @attribute.inner)
+
+; =================================================================
+; Header fields
+; =================================================================
+
+(header_field) @assignment.outer
+(header_field
+ value: (header_value) @assignment.inner)
diff --git a/sundry/editor-syntax-etc/vim/syntax/sisu-spine.vim b/sundry/editor-syntax-etc/vim/syntax/sisu-spine.vim
index 2de0095..35a893e 100644
--- a/sundry/editor-syntax-etc/vim/syntax/sisu-spine.vim
+++ b/sundry/editor-syntax-etc/vim/syntax/sisu-spine.vim
@@ -1,12 +1,22 @@
-" SiSU Vim syntax file (sisu-spine)
+" SiSU Vim syntax file (sisu-spine) - Vim 8 fallback (regex)
" SiSU Maintainer: Ralph Amissah <ralph.amissah@gmail.com>
" SiSU Markup: SiSU (sisu-5.6.7)
" sisu-spine Markup: sisu-spine
-" Last Change: 2017-06-22, 2025-02-21
+" Last Change: 2017-06-22, 2025-02-21, 2026-05-09
" URL: <https://git.sisudoc.org/projects/sisudoc-spine/tree/sundry/editor-syntax-etc/vim/syntax/sisu-spine.vim>
" <https://git.sisudoc.org/projects/sisudoc-spine/tree/sundry/editor-syntax-etc/vim/syntax/sisu.vim>
" <https://sisudoc.org/>
"(originally looked at Ruby Vim by Mirko Nasato)
+"
+" Status: This is the regex-based Vim 8 fallback. For Neovim users, the
+" tree-sitter-sisu grammar provides structural highlighting, folding and
+" textobjects with strictly better behaviour on nested markup, multi-line
+" footnotes, block bodies, and segmented headings; see
+" sundry/editor-syntax-etc/nvim/README.md
+" Emacs 29+ users have an equivalent treesit-based mode at
+" sundry/editor-syntax-etc/emacs/sisu-spine-ts-mode.el
+" This file remains the supported path for classic Vim, where tree-sitter
+" is not available without third-party plugins.
if version < 600
syntax clear
diff --git a/sundry/editor-syntax-etc/vim/templates/ssi.tpl b/sundry/editor-syntax-etc/vim/templates/ssi.tpl
new file mode 100644
index 0000000..28e8101
--- /dev/null
+++ b/sundry/editor-syntax-etc/vim/templates/ssi.tpl
@@ -0,0 +1,30 @@
+# SiSU 8.0 insert
+
+title:
+ main: "#___#"
+ sub: "#___#"
+ language: "#___#"
+
+creator:
+ author: "#___#"
+
+date:
+ :published: "YYYY-MM-DD"
+
+rights:
+ copyright: "#___#"
+ license: "#___#"
+
+classify:
+ topic_register: "#___#"
+
+make:
+ breaks: "new=:B; break=1"
+# home_button_text: "#___#"
+# footer: "#___#"
+
+#% -- body ---
+
+:A~ @title @author
+
+1~ #___#
diff --git a/sundry/editor-syntax-etc/vim/templates/ssm.tpl b/sundry/editor-syntax-etc/vim/templates/ssm.tpl
new file mode 100644
index 0000000..579375f
--- /dev/null
+++ b/sundry/editor-syntax-etc/vim/templates/ssm.tpl
@@ -0,0 +1,30 @@
+# SiSU 8.0 master
+
+title:
+ main: "#___#"
+ sub: "#___#"
+ language: "#___#"
+
+creator:
+ author: "#___#"
+
+date:
+ :published: "YYYY-MM-DD"
+
+rights:
+ copyright: "#___#"
+ license: "#___#"
+
+classify:
+ topic_register: "#___#"
+
+make:
+ breaks: "new=:B; break=1"
+# home_button_text: "#___#"
+# footer: "#___#"
+
+#% -- body ---
+
+:A~ @title @author
+
+1~ #___#
diff --git a/sundry/editor-syntax-etc/vim/templates/sst.tpl b/sundry/editor-syntax-etc/vim/templates/sst.tpl
new file mode 100644
index 0000000..069d498
--- /dev/null
+++ b/sundry/editor-syntax-etc/vim/templates/sst.tpl
@@ -0,0 +1,30 @@
+# SiSU 8.0
+
+title:
+ main: "#___#"
+ sub: "#___#"
+ language: "#___#"
+
+creator:
+ author: "#___#"
+
+date:
+ :published: "YYYY-MM-DD"
+
+rights:
+ copyright: "#___#"
+ license: "#___#"
+
+classify:
+ topic_register: "#___#"
+
+make:
+ breaks: "new=:B; break=1"
+# home_button_text: "#___#"
+# footer: "#___#"
+
+#% -- body ---
+
+:A~ @title @author
+
+1~ #___#
diff --git a/test/reference/abstraction/not_without_help.austin_amissah.en.ssp b/test/reference/abstraction/not_without_help.austin_amissah.en.ssp
index e19a060..bdb2619 100644
--- a/test/reference/abstraction/not_without_help.austin_amissah.en.ssp
+++ b/test/reference/abstraction/not_without_help.austin_amissah.en.ssp
@@ -5186,8 +5186,8 @@
.part: body
.ocn_off: true
.is_of_type: para
-.sha256: 4F233B87A3D3544DA570F2AA866958ABD50C36DEB08EA474BA2ADC95DAF597B5
-| The other people with whom I spent some time were not Israeli but Dutch. They were the Arienses, who had been in Ghana in the early 70s. Krick Ariens was Ambassador of the Netherlands to Ghana. He and his wife, Roberta, had been very gracious hosts to many Ghanaian friends. Krick joined with a number of Ghanaians to play tennis on Wednesdays at the court in the residence of his second in command, Joris Vos, later to become Ambassador to Australia, then the Soviet Union and then Ambassador to Russia and to a number of the States into which the Soviet Union broke afterwards. After being Secretary to the Minister of Foreign Affairs, he became Ambassador to the United States. But these were early days for Joris. I got in touch with the Arienses when I arrived in Israel. They were living in Jerusalem and invited me to dinner a couple of times and also took me on one occasion to a hospital to which the people of Holland had sent a planeload of tulips. Holland maintained very close relations with the Israelis at the time and, as stated earlier, it was the only country which had its Embassy in Jerusalem. Krick asked how the Wednesday tennis group was going. I told a long story of how the group continued to thrive after Joris Vos was replaced by Jaap de Hoop Schaffer. The group had at various times included Kwame Pianim, who was so strong, he played singles with Jaap before the rest of us turned up to join them in our usual doubles games; Francis Nkrumah, a paediatrician specialist and son of our first Prime Minister and President, later to become a Professor of the Medical School and head of the Noguchi Institute; the late Kwamena Phillips, a delightful companion and diplomat; Kofi Annan, a diplomat, then on assignment with the Tourist Company in Ghana, later to become Secretary-General of the United Nations; Issa Egala, a paediatrician specialist, then with the Police Hospital, Roger Korsah, a judge of the High Court, later to be judge of the Supreme Court of Zimbabwe; Miguel Ribeiro, a lawyer in private practice; Osafo Sampong, a lawyer with the Attorney-General's Office; Commander Kyeremeh, a naval officer, but then, I believe a member of the Government with responsibility for the Cocoa Marketing Board; and myself. But when Jaap was in turn succeeded by Christian Kroner, he put an end to the group with the cryptic remark that “friends are made, not inherited”. Roberta asked who this was and, when I told her, she summarily dismissed him by saying, “oh, he is not important”. Kroner's remark, though unimpeachable in this case, later caused him some embarrassment. He did not know who those using the tennis court in his residence were. He had obviously come in with the idea of making his own life without interferences from the past. When he later learnt who we were, he asked Kwame Pianim to persuade us to come back to his court. Not one of us accepted. By then, some of us were using the court of the Canadian High Commissioner down the road.
+.sha256: 3236AC8C5D4578179D719853CC9F5572C3A6D5DC9DFE524C45EED91305EA5A33
+| The other people with whom I spent some time were not Israeli but Dutch. They were the Arienses, who had been in Ghana in the early 70s. Krick Ariens was Ambassador of the Netherlands to Ghana. He and his wife, Roberta, had been very gracious hosts to many Ghanaian friends. Krick joined with a number of Ghanaians to play tennis on Wednesdays at the court in the residence of his second in command, Joris Vos, later to become Ambassador to Australia, then the Soviet Union and then Ambassador to Russia and to a number of the States into which the Soviet Union broke afterwards. After being Secretary to the Minister of Foreign Affairs, he became Ambassador to the United States. But these were early days for Joris. I got in touch with the Arienses when I arrived in Israel. They were living in Jerusalem and invited me to dinner a couple of times and also took me on one occasion to a hospital to which the people of Holland had sent a planeload of tulips. Holland maintained very close relations with the Israelis at the time and, as stated earlier, it was the only country which had its Embassy in Jerusalem. Krick asked how the Wednesday tennis group was going. I told a long story of how the group continued to thrive after Joris Vos was replaced by Jaap de Hoop Scheffer. The group had at various times included Kwame Pianim, who was so strong, he played singles with Jaap before the rest of us turned up to join them in our usual doubles games; Francis Nkrumah, a paediatrician specialist and son of our first Prime Minister and President, later to become a Professor of the Medical School and head of the Noguchi Institute; the late Kwamena Phillips, a delightful companion and diplomat; Kofi Annan, a diplomat, then on assignment with the Tourist Company in Ghana, later to become Secretary-General of the United Nations; Issa Egala, a paediatrician specialist, then with the Police Hospital, Roger Korsah, a judge of the High Court, later to be judge of the Supreme Court of Zimbabwe; Miguel Ribeiro, a lawyer in private practice; Osafo Sampong, a lawyer with the Attorney-General's Office; Commander Kyeremeh, a naval officer, but then, I believe a member of the Government with responsibility for the Cocoa Marketing Board; and myself. But when Jaap was in turn succeeded by Christian Kroner, he put an end to the group with the cryptic remark that “friends are made, not inherited”. Roberta asked who this was and, when I told her, she summarily dismissed him by saying, “oh, he is not important”. Kroner's remark, though unimpeachable in this case, later caused him some embarrassment. He did not know who those using the tennis court in his residence were. He had obviously come in with the idea of making his own life without interferences from the past. When he later learnt who we were, he asked Kwame Pianim to persuade us to come back to his court. Not one of us accepted. By then, some of us were using the court of the Canadian High Commissioner down the road.
[654] para
.part: body
diff --git a/test/reference/abstraction/the_autonomous_contract.ralph_amissah.en.ssp b/test/reference/abstraction/the_autonomous_contract.ralph_amissah.en.ssp
index 22f01c3..be1aa1b 100644
--- a/test/reference/abstraction/the_autonomous_contract.ralph_amissah.en.ssp
+++ b/test/reference/abstraction/the_autonomous_contract.ralph_amissah.en.ssp
@@ -599,8 +599,8 @@
.part: body
.ocn_off: true
.is_of_type: para
-.sha256: C4B6301574EFFA88E9488D08044D3674D08CEC0C4307664BD86BDBA30C049FCE
-| Within the traditional municipal order a limited degree of autonomy is available in contract. Autonomy is here used in the sense of reducing the relevance of specific national laws. This is achieved as discussed through: the selection of the law of a state that applies uniform law; the use of uniform rules and principles; and/or the use of negotiated standard contracts. There are problems however, with state's judiciaries' limited ability to disengage themselves from their traditional legal process, methods of legal reasoning, use of sources, and interpretation of uniform law, principles, rules and contracts. In addition to these there are problems associated with the enforcement of claims in other states world-wide as required for international commerce. These constraints have long represented a hindrance to the business community that has sought and found a preferable solution in international commercial arbitration. This may be further enhanced through the selection of a-national law as the governing law of the contract under arbitration, such as ⑆/┨ lex mercatoria ┣/. This a-national regulatory order is made possible by: ⑆*┨ (a) ┣* States' acceptance of ⑆_┨freedom of contract┣_ (⑆/┨ odre public ┣/ or public policy excepted). ⑆*┨ (b) ┣* Sanctity of contract embodied in the principle ⑆/┨ ⑆_┨pacta sunt servanda┣_ ┣/. ⑆*┨ (c) ┣* Written contractual selection of dispute resolution by ⑆_┨international commercial arbitration┣_ - ⑆/┨ ad hoc ┣/ or institutional, usually under internationally accepted arbitration rules. ⑆*┨ (d) ┣* Enforcement: arbitration where necessary borrowing the state apparatus for ⑆_┨law enforcement through the ⑆/┨ New York Convention┣_ on Recognition and Enforcement of Arbitral Awards 1958 ┣/. ⑆*┨ (e) ┣* Greater transnational effect is achieved through the exclusion of state law as governing the contract. Usually substituting the choice of general principles of law or ⑆/┨ ⑆_┨lex mercatoria┣_ ┣/ as governing the contract, or calling upon the arbitrators to act as ⑆/┨ amiable compositeur ┣/ or ⑆/┨ ex aequo et bono ┣/. For increased predictability preferably through application of the ⑆/┨ UNIDROIT Principles ┣/.
+.sha256: B784E23AE45968CFE43BFA2AA417E1F1553A763C0A2D8EC7FA3E2758BE8C92A0
+| Within the traditional municipal order a limited degree of autonomy is available in contract. Autonomy is here used in the sense of reducing the relevance of specific national laws. This is achieved as discussed through: the selection of the law of a state that applies uniform law; the use of uniform rules and principles; and/or the use of negotiated standard contracts. There are problems however, with state's judiciaries' limited ability to disengage themselves from their traditional legal process, methods of legal reasoning, use of sources, and interpretation of uniform law, principles, rules and contracts. In addition to these there are problems associated with the enforcement of claims in other states world-wide as required for international commerce. These constraints have long represented a hindrance to the business community that has sought and found a preferable solution in international commercial arbitration. This may be further enhanced through the selection of a-national law as the governing law of the contract under arbitration, such as ⑆/┨ lex mercatoria ┣/. This a-national regulatory order is made possible by: ⑆*┨ (a) ┣* States' acceptance of ⑆_┨freedom of contract┣_ (⑆/┨ odre public ┣/ or public policy excepted). ⑆*┨ (b) ┣* Sanctity of contract embodied in the principle ⑆/┨ ⑆_┨pacta sunt servanda┣_ ┣/. ⑆*┨ (c) ┣* Written contractual selection of dispute resolution by ⑆_┨international commercial arbitration┣_ - ⑆/┨ ad hoc ┣/ or institutional, usually under internationally accepted arbitration rules. ⑆*┨ (d) ┣* Enforcement: arbitration where necessary borrowing the state apparatus for law enforcement through the ⑆/┨ ⑆_┨New York Convention┣_ on Recognition and Enforcement of Arbitral Awards 1958 ┣/. ⑆*┨ (e) ┣* Greater transnational effect is achieved through the exclusion of state law as governing the contract. Usually substituting the choice of general principles of law or ⑆/┨ ⑆_┨lex mercatoria┣_ ┣/ as governing the contract, or calling upon the arbitrators to act as ⑆/┨ amiable compositeur ┣/ or ⑆/┨ ex aequo et bono ┣/. For increased predictability preferably through application of the ⑆/┨ UNIDROIT Principles ┣/.
[30] heading :3
.part: body
diff --git a/test/test-abstraction-ssp.sh b/test/test-abstraction-ssp.sh
index 28502ea..d03f70c 100755
--- a/test/test-abstraction-ssp.sh
+++ b/test/test-abstraction-ssp.sh
@@ -22,7 +22,12 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SPINE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
-SAMPLES_DIR="$SPINE_DIR/../sisudoc-spine-samples/markup/pod-samples/pod"
+SAMPLES_RAW="$SPINE_DIR/$SpinePOD"
+if [ -d "$SAMPLES_RAW" ]; then
+ SAMPLES_DIR="$(cd "$SAMPLES_RAW" && pwd)"
+else
+ SAMPLES_DIR="$SAMPLES_RAW"
+fi
REF_DIR="$SCRIPT_DIR/reference/abstraction"
TMP_DIR="$SCRIPT_DIR/current/abstraction"
diff --git a/views/version.txt b/views/version.txt
index 7056ca1..3e8e2a9 100644
--- a/views/version.txt
+++ b/views/version.txt
@@ -4,7 +4,7 @@ struct Version {
int minor;
int patch;
}
-enum _ver = Version(0, 19, 0);
+enum _ver = Version(0, 22, 0);
version (Posix) {
version (DigitalMars) {
} else version (LDC) {