aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sisudoc/ocda/abstraction
diff options
context:
space:
mode:
Diffstat (limited to 'src/sisudoc/ocda/abstraction')
-rw-r--r--src/sisudoc/ocda/abstraction/db_in.d5
-rw-r--r--src/sisudoc/ocda/abstraction/doc_has.d12
-rw-r--r--src/sisudoc/ocda/abstraction/ssp.d17
-rw-r--r--src/sisudoc/ocda/abstraction/ssp_in.d10
4 files changed, 35 insertions, 9 deletions
diff --git a/src/sisudoc/ocda/abstraction/db_in.d b/src/sisudoc/ocda/abstraction/db_in.d
index 986a09d..28d6423 100644
--- a/src/sisudoc/ocda/abstraction/db_in.d
+++ b/src/sisudoc/ocda/abstraction/db_in.d
@@ -347,6 +347,11 @@ template spineAbstractionDbRead() {
obj.metainfo.parent_ocn = row[_col["parent_ocn"]].as!int;
obj.metainfo.parent_lev_markup = row[_col["parent_lev"]].as!int;
obj.metainfo.last_descendant_ocn = row[_col["last_descendant_ocn"]].as!int;
+ /+ ↓ 2.1: a 2.0 database has no such columns, and reads as no range +/
+ if ("ocn_range_first" in _col) {
+ obj.metainfo.ocn_range_first = row[_col["ocn_range_first"]].as!int;
+ obj.metainfo.ocn_range_last = row[_col["ocn_range_last"]].as!int;
+ }
obj.metainfo.children_headings = _jsonInts(row[_col["children"]].as!string);
obj.metainfo.markedup_ancestors = _jsonEight(row[_col["ancestors"]].as!string);
obj.metainfo.collapsed_ancestors = _jsonEight(row[_col["ancestors_collapsed"]].as!string);
diff --git a/src/sisudoc/ocda/abstraction/doc_has.d b/src/sisudoc/ocda/abstraction/doc_has.d
index 4ecf018..f01af78 100644
--- a/src/sisudoc/ocda/abstraction/doc_has.d
+++ b/src/sisudoc/ocda/abstraction/doc_has.d
@@ -264,13 +264,11 @@ template spineDocHasFromAbstraction() {
_tag_assoc[obj.metainfo.identifier]["seg_lv4"]
= obj.tags.html_segment_anchor_tag_is;
}
- /+ ↓ An object that is not written into any segment still carries an
- identifier, and can share it: a poem block and its verses have one
- ocn between them, the verses are written and the block itself is not.
- The block comes second, so an unguarded assignment replaced a good
- segment name with an empty one, and the link came out as
- ".xhtml#297". seg_lv4 above is guarded already, which is why this
- showed in the epub and not in the html.
+ /+ ↓ An object that is not written into a segment still carries an
+ identifier, and could share it: a poem block carried the ocn of
+ its last verse until spec:2.1, with an issue affecting epub output.
+ Since spec:2.1 the poem has no identifier; the guard stays, for any
+ object that is not in a segment.
+/
if (obj.tags.epub_segment_anchor_tag_is.length > 0) {
_tag_assoc[obj.metainfo.identifier]["seg_lv1to4"]
diff --git a/src/sisudoc/ocda/abstraction/ssp.d b/src/sisudoc/ocda/abstraction/ssp.d
index c22741b..dfb8c10 100644
--- a/src/sisudoc/ocda/abstraction/ssp.d
+++ b/src/sisudoc/ocda/abstraction/ssp.d
@@ -59,6 +59,16 @@ module sisudoc.ocda.abstraction.ssp;
part when a property is added (a reader of the newer format still reads
the older one), the major part when one changes meaning or goes away.
+ 2.1 2026-09-29 .ocn_range, the first and last ocn of what a
+ container holds. A poem is a container of verses and
+ is cited as their range: it now opens its run of
+ verses rather than closing it, carries ocn 0 and no
+ identifier, and states the range. It used to carry
+ the last verse's ocn and identifier, so one number
+ named two objects. A 2.0 reader reads a 2.1 file:
+ the poem was never rendered and has no text, the
+ verses are unchanged, and the property is an
+ addition.
2.0 2026-09-18 source.digest changes meaning: it now covers every
markup file the document is made of, where it was the
sha256 of the master file alone. For a .sst that was
@@ -74,7 +84,7 @@ module sisudoc.ocda.abstraction.ssp;
reference to a heading above level 4 lands on;
was 0.1
+/
-enum ssp_format_version = "2.0";
+enum ssp_format_version = "2.1";
enum ssp_format_version_major = "2";
/+ ↓ escaping for values that are folded onto one line
@@ -181,6 +191,11 @@ template sspObjectRecord() {
if (obj.metainfo.last_descendant_ocn != 0) {
output ~= ".last_descendant: " ~ obj.metainfo.last_descendant_ocn.to!string;
}
+ /+ ↓ a container: the first and last ocn of what it holds (2.1) +/
+ if (obj.metainfo.ocn_range_first != 0) {
+ output ~= ".ocn_range: " ~ obj.metainfo.ocn_range_first.to!string
+ ~ " " ~ obj.metainfo.ocn_range_last.to!string;
+ }
/+ ↓ child headings (from pre-computed map) +/
if (obj.metainfo.children_headings.length > 0) {
string[] ch;
diff --git a/src/sisudoc/ocda/abstraction/ssp_in.d b/src/sisudoc/ocda/abstraction/ssp_in.d
index 0e461ad..0c67ab2 100644
--- a/src/sisudoc/ocda/abstraction/ssp_in.d
+++ b/src/sisudoc/ocda/abstraction/ssp_in.d
@@ -76,7 +76,7 @@ template spineAbstractionRead() {
object sections in the order the file gives them
+/
struct SSPdocument {
- string format; // "% SiSU Document Abstraction v2.0"
+ string format; // "% SiSU Document Abstraction v2.1"
string source; // "% Source: ..."
string[string] source_info; // the @source block
string[] source_info_order;
@@ -230,6 +230,14 @@ template spineAbstractionRead() {
case "section": obj.metainfo.is_of_section = _val; break;
case "parent": obj.metainfo.parent_ocn = _val.to!int; break;
case "last_descendant": obj.metainfo.last_descendant_ocn = _val.to!int; break;
+ case "ocn_range": {
+ auto _r = _ints(_val);
+ if (_r.length == 2) {
+ obj.metainfo.ocn_range_first = _r[0];
+ obj.metainfo.ocn_range_last = _r[1];
+ }
+ break;
+ }
case "children": obj.metainfo.children_headings = _ints(_val); break;
case "ancestors":
obj.metainfo.markedup_ancestors = _eight(_val);