aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRalph Amissah <ralph.amissah@gmail.com>2026-04-22 14:09:25 -0400
committerRalph Amissah <ralph.amissah@gmail.com>2026-04-22 20:42:31 -0400
commitc02be49130e6eecce62d5117bc95d698fb386901 (patch)
tree41ea77a532dc59817f13611c065c5cdedbaf5a7a
parent.ssp: omit empty-value array property entries (diff)
add --pod2 flag, decouple --show-abstraction from --pod
Finer-grained control over when .ssp files are produced: --show-abstraction writes .ssp to OUTPUT/lang/abstraction/ independently of any pod flag --pod builds pod without .ssp bundled --pod2 builds pod with .ssp in media/abstraction/ Changes to spine.d: - show_abstraction() now only responds to its own flag and pod2, no longer triggered by source_or_pod - Add pod2 to opts init, getopt, OptActions - pod() returns true for both --pod and --pod2 - source_or_pod() includes pod2 Changes to source_pod.d: - Remove per-document pod directory (rmdirRecurse) before regeneration, ensuring clean slate on every run. This prevents stale content from previous runs (e.g. a --pod2 run followed by --pod would otherwise leave an outdated media/abstraction/ directory) - Gate abstraction directory creation and .ssp bundling on pod2 flag specifically Tested: --pod (no .ssp), --pod2 (.ssp in pod + zip), --show-abstraction (standalone .ssp), --pod after --pod2 (stale abstraction cleaned up). All 35 sample documents pass. Co-Authored-By: Anthropic Claude Opus 4.6 (1M context)
-rw-r--r--org/out_src_pod.org65
-rw-r--r--org/spine.org11
-rw-r--r--src/sisudoc/io_out/source_pod.d65
-rwxr-xr-xsrc/sisudoc/spine.d11
4 files changed, 90 insertions, 62 deletions
diff --git a/org/out_src_pod.org b/org/out_src_pod.org
index 3062d1e..e1076c2 100644
--- a/org/out_src_pod.org
+++ b/org/out_src_pod.org
@@ -33,6 +33,15 @@ template spinePod() {
<<source_pod_init>>
if (doc_matters.opt.action.source_or_pod) {
try {
+ /+ ↓ clean slate: remove per-document pod directory before regeneration,
+ but only on the first language of a multi-language document,
+ so that subsequent languages' files are not wiped +/
+ if (doc_matters.src.language == doc_matters.pod.manifest_list_of_languages[0]) {
+ string doc_pod_dir = pths_pod.base_filesystem_(doc_matters.src.filename);
+ if (exists(doc_pod_dir) && doc_pod_dir.isDir) {
+ doc_pod_dir.rmdirRecurse;
+ }
+ }
{
podArchive_directory_tree(doc_matters, pths_pod);
}
@@ -145,34 +154,32 @@ auto pod_zipMakeReady(M,P,S)(M doc_matters, P pths_pod, S _st) {
}
}
}
- } { // bundle abstraction .ssp file
- 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";
- }
- if (doc_matters.opt.action.source_or_pod) {
+ } { // 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);
- }
- if (doc_matters.opt.action.source_or_pod) {
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);
+ } 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);
+ }
}
}
} { // bundle dr_document_make
@@ -418,8 +425,10 @@ void podArchive_directory_tree(M,P)(M doc_matters, P pths_pod) { // create direc
if (!exists(pths_pod.css(doc_matters.src.filename).filesystem_open_zpod)) {
pths_pod.css(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse;
}
- if (!exists(pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod)) {
- pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse;
+ if (doc_matters.opt.action.pod2) {
+ if (!exists(pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod)) {
+ pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse;
+ }
}
if (!exists(pths_pod.image_root(doc_matters.src.filename).filesystem_open_zpod)) {
pths_pod.image_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse;
diff --git a/org/spine.org b/org/spine.org
index e1748e7..e140bd2 100644
--- a/org/spine.org
+++ b/org/spine.org
@@ -340,6 +340,7 @@ bool[string] opts = [
"pdf-color-links" : false,
"pdf-init" : false,
"pod" : false,
+ "pod2" : false,
"serial" : false,
"show-abstraction" : false,
"show-abstraction-db" : false,
@@ -467,6 +468,7 @@ auto helpInfo = getopt(args,
"pdf-color-links", "mono or color links for pdfs", &opts["pdf-color-links"],
"pdf-init", "initialise latex shared files (see latex-header-sty)", &opts["pdf-init"],
"pod", "spine (doc reform) pod source content bundled", &opts["pod"],
+ "pod2", "pod with document abstraction (.ssp) bundled", &opts["pod2"],
"quiet|q", "output to terminal", &opts["vox_is1"],
"section-backmatter", "document backmatter (default)" , &opts["backmatter"],
"section-biblio", "document biblio (default)", &opts["section_biblio"],
@@ -693,13 +695,16 @@ struct OptActions {
return ((opts["ocn-off"]) || (opts["no-ocn"])) ? true : false;
}
@trusted bool pod() {
- return opts["pod"];
+ return (opts["pod"] || opts["pod2"]) ? true : false;
+ }
+ @trusted bool pod2() {
+ return opts["pod2"];
}
@trusted bool show_config() {
return opts["show-config"];
}
@trusted bool show_abstraction() {
- return (opts["show-abstraction"] || source_or_pod) ? true : false;
+ return (opts["show-abstraction"] || pod2) ? true : false;
}
@trusted bool show_abstraction_db() {
return opts["show-abstraction-db"];
@@ -744,7 +749,7 @@ struct OptActions {
return opts["source"];
}
@trusted bool source_or_pod() {
- return (opts["pod"] || opts["source"]) ? true : false;
+ return (opts["pod"] || opts["pod2"] || opts["source"]) ? true : false;
}
@trusted bool sqlite_discrete() {
return opts["sqlite-discrete"];
diff --git a/src/sisudoc/io_out/source_pod.d b/src/sisudoc/io_out/source_pod.d
index c77ce45..138f105 100644
--- a/src/sisudoc/io_out/source_pod.d
+++ b/src/sisudoc/io_out/source_pod.d
@@ -72,6 +72,15 @@ template spinePod() {
assert (doc_matters.src.filename.match(rgx_files.src_fn));
if (doc_matters.opt.action.source_or_pod) {
try {
+ /+ ↓ clean slate: remove per-document pod directory before regeneration,
+ but only on the first language of a multi-language document,
+ so that subsequent languages' files are not wiped +/
+ if (doc_matters.src.language == doc_matters.pod.manifest_list_of_languages[0]) {
+ string doc_pod_dir = pths_pod.base_filesystem_(doc_matters.src.filename);
+ if (exists(doc_pod_dir) && doc_pod_dir.isDir) {
+ doc_pod_dir.rmdirRecurse;
+ }
+ }
{
podArchive_directory_tree(doc_matters, pths_pod);
}
@@ -114,8 +123,10 @@ template spinePod() {
if (!exists(pths_pod.css(doc_matters.src.filename).filesystem_open_zpod)) {
pths_pod.css(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse;
}
- if (!exists(pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod)) {
- pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse;
+ if (doc_matters.opt.action.pod2) {
+ if (!exists(pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod)) {
+ pths_pod.abstraction_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse;
+ }
}
if (!exists(pths_pod.image_root(doc_matters.src.filename).filesystem_open_zpod)) {
pths_pod.image_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse;
@@ -182,34 +193,32 @@ template spinePod() {
}
}
}
- } { // bundle abstraction .ssp file
- 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";
- }
- if (doc_matters.opt.action.source_or_pod) {
+ } { // 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);
- }
- if (doc_matters.opt.action.source_or_pod) {
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);
+ } 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);
+ }
}
}
} { // bundle dr_document_make
diff --git a/src/sisudoc/spine.d b/src/sisudoc/spine.d
index 0598ca7..e710281 100755
--- a/src/sisudoc/spine.d
+++ b/src/sisudoc/spine.d
@@ -165,6 +165,7 @@ string program_name = "spine";
"pdf-color-links" : false,
"pdf-init" : false,
"pod" : false,
+ "pod2" : false,
"serial" : false,
"show-abstraction" : false,
"show-abstraction-db" : false,
@@ -278,6 +279,7 @@ string program_name = "spine";
"pdf-color-links", "mono or color links for pdfs", &opts["pdf-color-links"],
"pdf-init", "initialise latex shared files (see latex-header-sty)", &opts["pdf-init"],
"pod", "spine (doc reform) pod source content bundled", &opts["pod"],
+ "pod2", "pod with document abstraction (.ssp) bundled", &opts["pod2"],
"quiet|q", "output to terminal", &opts["vox_is1"],
"section-backmatter", "document backmatter (default)" , &opts["backmatter"],
"section-biblio", "document biblio (default)", &opts["section_biblio"],
@@ -497,13 +499,16 @@ string program_name = "spine";
return ((opts["ocn-off"]) || (opts["no-ocn"])) ? true : false;
}
@trusted bool pod() {
- return opts["pod"];
+ return (opts["pod"] || opts["pod2"]) ? true : false;
+ }
+ @trusted bool pod2() {
+ return opts["pod2"];
}
@trusted bool show_config() {
return opts["show-config"];
}
@trusted bool show_abstraction() {
- return (opts["show-abstraction"] || source_or_pod) ? true : false;
+ return (opts["show-abstraction"] || pod2) ? true : false;
}
@trusted bool show_abstraction_db() {
return opts["show-abstraction-db"];
@@ -548,7 +553,7 @@ string program_name = "spine";
return opts["source"];
}
@trusted bool source_or_pod() {
- return (opts["pod"] || opts["source"]) ? true : false;
+ return (opts["pod"] || opts["pod2"] || opts["source"]) ? true : false;
}
@trusted bool sqlite_discrete() {
return opts["sqlite-discrete"];