diff options
Diffstat (limited to 'src/sisudoc')
| -rw-r--r-- | src/sisudoc/ocda/abstraction/db_in.d | 1 | ||||
| -rw-r--r-- | src/sisudoc/ocda/abstraction/doc_has.d | 40 | ||||
| -rw-r--r-- | src/sisudoc/ocda/abstraction/ssp.d | 12 | ||||
| -rw-r--r-- | src/sisudoc/ocda/abstraction/ssp_in.d | 1 | ||||
| -rw-r--r-- | src/sisudoc/ocda/meta/metadoc_from_src.d | 31 | ||||
| -rw-r--r-- | src/sisudoc/ocda/meta/metadoc_object_setter.d | 10 | ||||
| -rw-r--r-- | src/sisudoc/outputs/io_out/create_ocda_db.d | 6 |
7 files changed, 76 insertions, 25 deletions
diff --git a/src/sisudoc/ocda/abstraction/db_in.d b/src/sisudoc/ocda/abstraction/db_in.d index 0d78f12..6e9b0e2 100644 --- a/src/sisudoc/ocda/abstraction/db_in.d +++ b/src/sisudoc/ocda/abstraction/db_in.d @@ -277,6 +277,7 @@ template spineAbstractionDbRead() { obj.tags.segment_anchor_tag_epub = row[_col["segment_epub"]].as!string; obj.tags.html_segment_anchor_tag_is = row[_col["segment_html_is"]].as!string; obj.tags.epub_segment_anchor_tag_is = row[_col["segment_epub_is"]].as!string; + obj.tags.segment_lv4_is = row[_col["segment_lv4_is"]].as!string; obj.tags.anchor_tag_html = row[_col["anchor"]].as!string; obj.tags.heading_lev_anchor_tag = row[_col["heading_lev_anchor"]].as!string; { diff --git a/src/sisudoc/ocda/abstraction/doc_has.d b/src/sisudoc/ocda/abstraction/doc_has.d index 75a4640..051da33 100644 --- a/src/sisudoc/ocda/abstraction/doc_has.d +++ b/src/sisudoc/ocda/abstraction/doc_has.d @@ -163,20 +163,6 @@ template spineDocHasFromAbstraction() { _out.quotes = _count(_doc_has_block, "quotes"); string[] _images; string[string][string] _tag_assoc; - /+ ↓ keys waiting for the level 4 segment that will hold them. - - a heading above level 4 opens no html segment, so a cross reference - to it has to land on the next level 4 heading, which has not been - seen yet when the heading is read. The parser does this the same - way, back-filling a pending tag when the level 4 heading arrives - (metadoc_from_src.d, "tag_assoc[lv0_to_lv3_html_tag]"), and the - order of the objects is what both are reading it from. - +/ - string[] _awaiting_lv4; - void _backfill(string _seg) { - foreach (_k; _awaiting_lv4) { _tag_assoc[_k]["seg_lv4"] = _seg; } - _awaiting_lv4 = []; - } /+ ↓ segnames["html"] is seeded with the toc, which is a segment of its own before any level 4 heading opens one +/ _out.segnames_lv4 ~= "toc"; @@ -226,6 +212,7 @@ template spineDocHasFromAbstraction() { +/ if (obj.tags.heading_lev_anchor_tag.length > 0 && obj.tags.in_segment_html.length > 0 + && obj.metainfo.heading_lev_markup >= 4 ) { _tag_assoc[obj.tags.heading_lev_anchor_tag]["seg_lv4"] = obj.tags.in_segment_html; @@ -245,14 +232,23 @@ template spineDocHasFromAbstraction() { if (obj.metainfo.heading_lev_markup <= 4) { _out.segnames_lv_0_to_4 ~= obj.tags.segment_anchor_tag_epub; } - if (obj.metainfo.heading_lev_markup == 4) { - if (_section == "body") { _out.segnames_lv4 ~= obj.tags.anchor_tag_html; } - /+ ↓ this is the segment the headings above it were waiting for +/ - _backfill(obj.tags.in_segment_html); - } else if (obj.metainfo.heading_lev_markup < 4) { - foreach (_k; [obj.metainfo.identifier, obj.tags.heading_lev_anchor_tag, - obj.tags.anchor_tag_html]) { - if (_k.length > 0) { _awaiting_lv4 ~= _k; } + if (_section == "body" && obj.metainfo.heading_lev_markup == 4) { + _out.segnames_lv4 ~= obj.tags.anchor_tag_html; + } + /+ ↓ a heading above level 4 opens no html segment of its own, so + a cross reference to it lands on the level 4 segment that + follows. That is .segment_lv4_is, resolved in ocda where the + finished sections are to hand and carried by the artefact, so + there is nothing to work out here + +/ + if (obj.tags.segment_lv4_is.length > 0) { + /+ ↓ seg_lv4 only, and not through heading_lev_anchor_tag: that + names the level 4 heading itself, whose own entry says it + opens that segment rather than merely sits in it. epub + segments go down to level 1, so seg_lv1to4 is untouched + +/ + foreach (_k; [obj.metainfo.identifier, obj.tags.anchor_tag_html]) { + if (_k.length > 0) { _tag_assoc[_k]["seg_lv4"] = obj.tags.segment_lv4_is; } } } } diff --git a/src/sisudoc/ocda/abstraction/ssp.d b/src/sisudoc/ocda/abstraction/ssp.d index 6b487d7..487a33b 100644 --- a/src/sisudoc/ocda/abstraction/ssp.d +++ b/src/sisudoc/ocda/abstraction/ssp.d @@ -61,7 +61,9 @@ module sisudoc.ocda.abstraction.ssp; 1.1 2026-09-10 @source block; the document metadata the output writers read carried in full (14 meta and 3 make properties - added); was 0.1 + added); .segment_lv4_is, the segment a cross + reference to a heading above level 4 lands on; + was 0.1 +/ enum ssp_format_version = "1.1"; enum ssp_format_version_major = "1"; @@ -380,6 +382,14 @@ template sspObjectRecord() { if (obj.tags.epub_segment_anchor_tag_is.length > 0) { output ~= ".segment_epub_is: " ~ obj.tags.epub_segment_anchor_tag_is; } + /+ ↓ the level 4 segment a cross reference to this heading lands on, + emitted only where it is not the segment the heading sits in, which + is every heading at level 4 or below +/ + if (obj.tags.segment_lv4_is.length > 0 + && obj.tags.segment_lv4_is != obj.tags.html_segment_anchor_tag_is + ) { + output ~= ".segment_lv4_is: " ~ obj.tags.segment_lv4_is; + } /+ ↓ heading ancestors text +/ { bool has_hat = false; diff --git a/src/sisudoc/ocda/abstraction/ssp_in.d b/src/sisudoc/ocda/abstraction/ssp_in.d index 873cb7e..59a5b80 100644 --- a/src/sisudoc/ocda/abstraction/ssp_in.d +++ b/src/sisudoc/ocda/abstraction/ssp_in.d @@ -311,6 +311,7 @@ template spineAbstractionRead() { case "segment_epub": obj.tags.segment_anchor_tag_epub = _val; break; case "segment_html_is": obj.tags.html_segment_anchor_tag_is = _val; break; case "segment_epub_is": obj.tags.epub_segment_anchor_tag_is = _val; break; + case "segment_lv4_is": obj.tags.segment_lv4_is = _val; break; case "heading_ancestors_text": { string[8] _h; diff --git a/src/sisudoc/ocda/meta/metadoc_from_src.d b/src/sisudoc/ocda/meta/metadoc_from_src.d index c5e2ce8..fb30a94 100644 --- a/src/sisudoc/ocda/meta/metadoc_from_src.d +++ b/src/sisudoc/ocda/meta/metadoc_from_src.d @@ -1246,6 +1246,37 @@ template docAbstraction() { the_document_bookindex_section = get_ancestors.the_document_bookindex_section; the_document_blurb_section = get_ancestors.the_document_blurb_section; } + /+ ↓ the html segment a cross reference to a heading lands on. + a heading above level 4 opens no html segment, so a link to it goes + to the level 4 heading that follows it. The build loop cannot know + that yet and back-fills tag_assoc when the level 4 heading arrives + (see lv0to3_tags); this is the same answer, kept on the object, so + that it travels with the abstraction instead of living only in a map + the parser holds. Walking backwards, the last level 4 seen is the + next one for everything above it. + +/ + { + string _next_lv4; + foreach_reverse (ref obj; the_document_body_section) { + if (obj.metainfo.is_a != "heading") { continue; } + if (obj.metainfo.heading_lev_markup == 4) { + _next_lv4 = obj.tags.anchor_tag_html; + } else if (obj.metainfo.heading_lev_markup < 4) { + obj.tags.segment_lv4_is = _next_lv4; + } + } + /+ ↓ the head section's title sits above the body and resolves to the + body's first level 4 heading, which is what _next_lv4 now holds + +/ + foreach_reverse (ref obj; the_document_head_section) { + if (obj.metainfo.is_a != "heading") { continue; } + if (obj.metainfo.heading_lev_markup == 4) { + _next_lv4 = obj.tags.anchor_tag_html; + } else if (obj.metainfo.heading_lev_markup < 4) { + obj.tags.segment_lv4_is = _next_lv4; + } + } + } // get descendants if (the_document_body_section.length > 1) { auto pairs = after_doc_get_descendants( diff --git a/src/sisudoc/ocda/meta/metadoc_object_setter.d b/src/sisudoc/ocda/meta/metadoc_object_setter.d index 2eab062..6c090db 100644 --- a/src/sisudoc/ocda/meta/metadoc_object_setter.d +++ b/src/sisudoc/ocda/meta/metadoc_object_setter.d @@ -130,6 +130,16 @@ template ObjectSetter() { string segment_anchor_tag_epub = ""; string html_segment_anchor_tag_is = ""; string epub_segment_anchor_tag_is = ""; + /+ the html segment a cross reference to this heading lands on. + a heading above level 4 opens no html segment of its own, so a link to + it has to go to the level 4 heading that follows, which is not known + when the heading is read ("for html segname need following lv4 not yet + known", metadoc_from_src.d). It is resolved in a pass over the + finished sections and kept here, so that it is a property of the + object like any other and travels with the abstraction rather than + living only in the tag_associations map the parser builds. + +/ + string segment_lv4_is = ""; string heading_lev_anchor_tag = ""; string segname_prev = ""; string segname_next = ""; diff --git a/src/sisudoc/outputs/io_out/create_ocda_db.d b/src/sisudoc/outputs/io_out/create_ocda_db.d index f184854..b2cfd62 100644 --- a/src/sisudoc/outputs/io_out/create_ocda_db.d +++ b/src/sisudoc/outputs/io_out/create_ocda_db.d @@ -172,6 +172,7 @@ template spineAbstractionDb() { segment_epub TEXT, segment_html_is TEXT, segment_epub_is TEXT, + segment_lv4_is TEXT, anchor TEXT, heading_lev_anchor TEXT, heading_ancestors_text TEXT @@ -324,7 +325,7 @@ template spineAbstractionDb() { ~ "indent_base, indent_hang, bullet, lang," ~ "has_links, has_notes_reg, has_notes_star, has_images, has_images_no_dim," ~ "segment, segment_prev, segment_next, segment_epub," - ~ "segment_html_is, segment_epub_is," + ~ "segment_html_is, segment_epub_is, segment_lv4_is," ~ "anchor, heading_lev_anchor, heading_ancestors_text," ~ "table_cols, table_widths, table_aligns, table_header," ~ "code_linenumbers, text" @@ -339,7 +340,7 @@ template spineAbstractionDb() { ~ ":indent_base, :indent_hang, :bullet, :lang," ~ ":has_links, :has_notes_reg, :has_notes_star, :has_images, :has_images_no_dim," ~ ":segment, :segment_prev, :segment_next, :segment_epub," - ~ ":segment_html_is, :segment_epub_is," + ~ ":segment_html_is, :segment_epub_is, :segment_lv4_is," ~ ":anchor, :heading_lev_anchor, :heading_ancestors_text," ~ ":table_cols, :table_widths, :table_aligns, :table_header," ~ ":code_linenumbers, :text" @@ -483,6 +484,7 @@ template spineAbstractionDb() { bindStr(":segment_epub", obj.tags.segment_anchor_tag_epub); bindStr(":segment_html_is", obj.tags.html_segment_anchor_tag_is); bindStr(":segment_epub_is", obj.tags.epub_segment_anchor_tag_is); + bindStr(":segment_lv4_is", obj.tags.segment_lv4_is); bindStr(":anchor", obj.tags.anchor_tag_html); bindStr(":heading_lev_anchor", obj.tags.heading_lev_anchor_tag); bindJsonStrs(":heading_ancestors_text", obj.tags.heading_ancestors_text); |
