aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRalph Amissah <ralph.amissah@gmail.com>2026-04-22 14:04:24 -0400
committerRalph Amissah <ralph.amissah@gmail.com>2026-04-22 20:42:31 -0400
commit0cd28e99f8847b8c4b554a45f1ae22a4cd19eb1c (patch)
tree997613cefb3cf30427f647790d6d2f98c9a05c00 /src
parent.ssp serializer: include all ObjGenericComposite fields (diff)
.ssp: add .children property for heading tree navigation
- Add explicit child heading OCN lists to heading objects, pre-computed in a single O(n) pass over the body section before serialization. This makes the document tree directly navigable without scanning - each heading lists its direct sub-heading OCNs. - Example output for a chapter heading: [10] heading :1 .last_descendant: 65 .children: 14 24 42 57 - Implementation: builds an int[][int] map (parent_ocn -> child heading OCNs) from one pass over the body objects, then emits .children: during serialization for headings that have entries in the map. - The tree was already reconstructable from parent_ocn + last_descendant_ocn, but .children makes it immediate - no scanning required to find a heading's sub-structure. - Tested against all 35 sample documents - zero failures. Co-Authored-By: Anthropic Claude Opus 4.6 (1M context)
Diffstat (limited to 'src')
-rw-r--r--src/sisudoc/io_out/create_abstraction_txt.d19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/sisudoc/io_out/create_abstraction_txt.d b/src/sisudoc/io_out/create_abstraction_txt.d
index 7d0425c..d393f61 100644
--- a/src/sisudoc/io_out/create_abstraction_txt.d
+++ b/src/sisudoc/io_out/create_abstraction_txt.d
@@ -162,6 +162,16 @@ template spineAbstractionTxt() {
output ~= "}";
output ~= "";
+ /+ ↓ pre-compute heading children map (one pass over body) +/
+ int[][int] heading_children; // parent_ocn -> [child heading OCNs]
+ if ("body" in doc_abstraction) {
+ foreach (obj; doc_abstraction["body"]) {
+ if (obj.metainfo.is_a == "heading" && obj.metainfo.parent_ocn != 0) {
+ heading_children[obj.metainfo.parent_ocn] ~= obj.metainfo.ocn;
+ }
+ }
+ }
+
/+ ↓ document sections +/
string[] section_order = ["head", "toc", "body", "endnotes",
"glossary", "bibliography", "bookindex", "blurb"];
@@ -201,6 +211,15 @@ template spineAbstractionTxt() {
if (obj.metainfo.last_descendant_ocn != 0)
output ~= ".last_descendant: " ~ obj.metainfo.last_descendant_ocn.to!string;
+ /+ ↓ child headings (from pre-computed map) +/
+ if (obj.metainfo.is_a == "heading" && obj.metainfo.ocn in heading_children) {
+ string[] ch;
+ foreach (c; heading_children[obj.metainfo.ocn]) {
+ ch ~= c.to!string;
+ }
+ output ~= ".children: " ~ ch.join(" ");
+ }
+
/+ ↓ ancestors (only if non-zero) +/
{
bool has_anc = false;