From 10a66c974537dcb984217a6c581fc20fa7144db4 Mon Sep 17 00:00:00 2001
From: Ralph Amissah <ralph.amissah@gmail.com>
Date: Sun, 21 Jan 2024 01:15:34 -0500
Subject: org, ocda (ongoing) split file, separate functions

---
 src/doc_reform/io_out/sqlite.d                   |    4 +-
 src/doc_reform/meta/metadoc_from_src.d           | 5362 +---------------------
 src/doc_reform/meta/metadoc_from_src_functions.d | 5215 +++++++++++++++++++++
 src/doc_reform/meta/metadoc_object_setter.d      |  353 +-
 4 files changed, 5526 insertions(+), 5408 deletions(-)
 create mode 100644 src/doc_reform/meta/metadoc_from_src_functions.d

(limited to 'src')

diff --git a/src/doc_reform/io_out/sqlite.d b/src/doc_reform/io_out/sqlite.d
index 11f00a3..58dc834 100644
--- a/src/doc_reform/io_out/sqlite.d
+++ b/src/doc_reform/io_out/sqlite.d
@@ -1121,7 +1121,7 @@ template SQLiteTablesReCreate() {
         lev                              SMALLINT          NULL,
         node                             VARCHAR(16)       NULL,
         parent                           VARCHAR(16)       NULL,
-        last_decendant                   VARCHAR(16)       NULL, -- headings only
+        last_descendant                  VARCHAR(16)       NULL, -- headings only
         digest_clean                     CHAR(256),
         digest_all                       CHAR(256),
         seg_name                         CHAR(256),
@@ -1643,7 +1643,7 @@ template SQLiteTablesCreate() {
             lev                              SMALLINT          NULL,
             node                             VARCHAR(16)       NULL,
             parent                           VARCHAR(16)       NULL,
-            last_decendant                   VARCHAR(16)       NULL, -- headings only
+            last_descendant                  VARCHAR(16)       NULL, -- headings only
             digest_clean                     CHAR(256),
             digest_all                       CHAR(256),
             seg_name                         CHAR(256),
diff --git a/src/doc_reform/meta/metadoc_from_src.d b/src/doc_reform/meta/metadoc_from_src.d
index 03a0286..a05edf4 100644
--- a/src/doc_reform/meta/metadoc_from_src.d
+++ b/src/doc_reform/meta/metadoc_from_src.d
@@ -65,223 +65,8 @@ template docAbstraction() {
     doc_reform.meta.rgx,
     doc_reform.meta.metadoc_object_setter,
     doc_reform.meta.rgx;
-  // ↓ abstraction mixins
-  mixin ObjectSetter;
-  mixin InternalMarkup;
-  mixin spineRgxIn;
-  // initialize
-  ObjGenericComposite[] the_document_toc_section, the_document_head_section, the_document_body_section, the_document_endnotes_section, the_document_bibliography_section, the_document_bookindex_section, the_document_glossary_section, the_document_blurb_section, the_document_xml_dom_tail_section;
-  struct _theDoc {
-    ObjGenericComposite[] toc;
-    ObjGenericComposite[] head;
-    ObjGenericComposite[] body;
-    ObjGenericComposite[] bibliography;
-    ObjGenericComposite[] glossary;
-    ObjGenericComposite[] bookindex;
-    ObjGenericComposite[] blurb;
-    ObjGenericComposite[] endnotes;
-  }
-  string[string] an_object, processing, object_notes;
-  string an_object_key;
-  string[] anchor_tags;
-  string anchor_tag;
-  string anchor_tag_;
-  string[string] tag_in_seg;
-  string lev_anchor_tag;
-  string[string][string] tag_assoc;
-  string[] lv0to3_tags;
-  // enum
-  enum DocStructMarkupHeading {
-    h_sect_A,
-    h_sect_B,
-    h_sect_C,
-    h_sect_D,
-    h_text_1,
-    h_text_2,
-    h_text_3,
-    h_text_4,
-    h_text_5, // extra level, drop
-    content_non_header
-  } // header section A-D; header text 1-4
-  enum Status { off, on, }
-  enum OCNtype { ocn, non, bkidx, }
-  // biblio variables
-  string biblio_tag_name, biblio_tag_entry, st;
-  string[] biblio_arr_json;
-  string biblio_entry_str_json;
-  JSONValue[] bib_arr_json;
-  int bib_entry;
-  // counters
-  int cntr, previous_count, previous_length;
-  bool reset_note_numbers = true;
-  int[string] line_occur;
-  int html_segnames_ptr = 0;
-  int html_segnames_ptr_cntr = 0;
-  int verse_line, heading_ptr;
-  // paragraph attributes
-  int[string] indent;
-  bool bullet = true;
-  string content_non_header = "8";
-  static auto obj_im = ObjInlineMarkup();
-  static auto obj_att = ObjAttributes();
-  // ocn
-  struct OCNset {
-    int digit;
-    int object_number;
-    bool off;
-    string identifier;
-    int bkidx;
-    int type;
-  }
-  OCNset obj_cite_digits;
-  int obj_cite_digit_, obj_cite_digit_off, obj_cite_digit_bkidx, obj_cite_digit_type;
-  auto object_citation_number = OCNemitter();
-  struct ST_endnotes {
-    ObjGenericComposite[] endnotes;
-    OCNset                ocn;
-  }
-  struct ST_bookindex {
-    ObjGenericComposite[] bookindex;
-    OCNset                ocn;
-  }
-  struct ST_biblio_section {
-    ObjGenericComposite[]  bibliography_section;
-    string[string][string] tag_assoc;
-  }
-  int[] dom_structure_markedup_tags_status         = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,];
-  int[] dom_structure_markedup_tags_status_buffer  = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,];
-  int[] dom_structure_collapsed_tags_status        = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,];
-  int[] dom_structure_collapsed_tags_status_buffer = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,];
-  struct ST_ancestors {
-    ObjGenericComposite[] the_document_body_section;
-    ObjGenericComposite[] the_document_endnotes_section;
-    ObjGenericComposite[] the_document_glossary_section;
-    ObjGenericComposite[] the_document_bibliography_section;
-    ObjGenericComposite[] the_document_bookindex_section;
-    ObjGenericComposite[] the_document_blurb_section;
-  }
-  struct ST_segnames {
-    string[][string]      segnames;
-    int                   html_segnames_ptr_cntr;
-    int                   html_segnames_ptr;
-  }
-  struct  ST_txtPlusHasFootnotes {
-    string           obj_txt;
-    bool             has_notes_reg;
-    bool             has_notes_star;
-    bool             has_notes_plus;
-  }
-  struct ST_txtPlusHasFootnotesUrlsImages {
-    string           obj_txt;
-    bool             has_notes_reg;
-    bool             has_notes_star;
-    bool             has_notes_plus;
-    bool             has_urls;
-    bool             has_images_without_dimensions;
-  }
-  struct ST_txtAndAnchorTagPlusHasFootnotesUrlsImages {
-    string           obj_txt;
-    string           anchor_tag;
-    bool             has_notes_reg;
-    bool             has_notes_star;
-    bool             has_notes_plus;
-    bool             has_links; // use same name
-    bool             has_images_without_dimensions;
-  }
-  struct ST_the_section {
-    ObjGenericComposite[]  comp_section_obj; // array: the heading has 2 members inserted, paras just 1
-    uint[string]           pith;
-    string[string][string] tag_assoc;        // only for headings: html & epub
-  }
-  enum DomTags { none, open, close, close_and_open, open_still, }
-  // book index variables
-  string book_idx_tmp;
-  string[][string][string] bookindex_unordered_hashes;
-  // node
-  ObjGenericComposite comp_obj_, comp_obj_location, comp_obj_poem_ocn, comp_obj_comment;
-  auto node_construct = NodeStructureMetadata();
-  struct ST_txt_by_line_common_reset {
-    int[string]     line_occur;
-    string[string]  this_object;
-    uint[string]    pith;
-  }
-  struct ST_txt_by_line_block_start {
-    uint[string]    pith;
-    uint[string]    dochas;
-    string[string]  object_number_poem;
-  }
-  struct ST_txt_by_line_block_generic {
-    uint[string]    pith;
-    string[string]  this_object;
-  }
-  struct ST_txt_by_line_block_poem {
-    int             cntr;
-    uint[string]    pith;
-    string[string]  this_object;
-  }
-  struct ST_txt_by_line_block_biblio {
-    uint[string]    pith;
-    int             bib_entry;
-    string          biblio_entry_str_json;
-    string[]        biblio_arr_json;
-  }
-  struct ST_flow_book_index {
-    string[string]  this_object;
-    uint[string]    pith;
-    string          book_idx_tmp;
-  }
-  struct ST_flow_heading_found {
-    string[string]       heading_match_str;
-    Regex!(char)[string] heading_match_rgx;
-    uint[string]         pith;
-  }
-  struct ST_flow_heading_make_set {
-    char[]          line;
-    uint[string]    pith;
-    string[string]  this_object;
-  }
-  struct ST_flow_para_match {
-    uint[string]    pith;
-    string[string]  this_object;
-    string          this_object_key;
-    int[string]     indent;
-    bool            bullet;
-    int[string]     line_occur;
-  }
-  struct ST_flow_table_array_munge {
-    ObjGenericComposite table_object;
-    string[][]          table_array;
-  }
-  struct ST_flow_table_of_contents_gather_headings {
-    ObjGenericComposite[] the_document_toc_section;
-    string[][string]      lev4_subtoc;
-  }
-  struct ST_flow_bibliography {
-    JSONValue[] biblio_sorted;
-    JSONValue[] bib_arr_json;
-    string[]    biblio_unsorted_incomplete;
-  }
-  struct ST_flow_table_closed_make_special_notation_table {
-    string[string]        this_object;
-    ObjGenericComposite[] the_document_body_section;
-    OCNset                obj_cite_digits;
-    ObjGenericComposite   comp_obj_;
-    int                   cntr;
-    uint[string]          pith;
-  }
-  struct ST_flow_block_flag_line_empty {
-    string[string]           this_object;
-    ObjGenericComposite[]    the_document_body_section;
-    string[][string][string] bookindex_unordered_hashes;
-    OCNset                   obj_cite_digits;
-    ObjGenericComposite      comp_obj_;
-    int                      cntr;
-    uint[string]             pith;
-  }
-  struct ST_flow_table_substantive_munge {
-    ObjGenericComposite  table_object;
-    string               table_substantive;
-  }
+  public import doc_reform.meta.metadoc_from_src_functions;
+  mixin docAbstractionFunctions;
   @system auto docAbstraction(CMM,Opt,Mf) (
     char[][]           markup_sourcefile_content,
     CMM                conf_make_meta,
@@ -420,7 +205,6 @@ template docAbstraction() {
     string[][string] segnames = ["html": ["toc"], "epub": ["toc"]];
     int cnt1 = 1; int cnt2 = 1; int cnt3 = 1;
     // abstraction init ↑
-    enum Substitute { match, markup, }
     debug (substitutions) {
       writeln(__LINE__, ":", __FILE__, ": DEBUG substitutions:");
       if (!(conf_make_meta.make.headings.empty)) {
@@ -450,14 +234,6 @@ template docAbstraction() {
       string[string]   an_object,
       uint[string]     pith,
     ) {
-      struct _loopMarkupSrcByLineStruct {
-        ObjGenericComposite[] toc;
-        ObjGenericComposite[] body;
-        ObjGenericComposite[] glossary;
-        ObjGenericComposite[] blurb;
-        string[string]        object_notes;
-        string[][string]      segnames;
-      }
       _loopMarkupSrcByLineStruct ret;
       srcDocLoopLineByLine_:
       foreach (line; markup_sourcefile_content) {
@@ -528,7 +304,7 @@ template docAbstraction() {
             debug(glossary) { writeln(__LINE__); writeln(line); }
             pith["section"] = eN.sect.glossary;
             if (opt_action.backmatter && opt_action.section_glossary) {
-              ST_the_section add_to_glossary_sect = line.build_the_glossary_section(pith, tag_assoc);
+              ST_the_section add_to_glossary_sect = line.build_the_glossary_section(pith, tag_assoc); // double check, should not be necessary to pass pith
               the_document_glossary_section ~= add_to_glossary_sect.comp_section_obj[0];
               if (add_to_glossary_sect.comp_section_obj.length > 1) { // heading
                 the_document_glossary_section ~= add_to_glossary_sect.comp_section_obj[1];
@@ -547,7 +323,7 @@ template docAbstraction() {
             pith["section"] = eN.sect.blurb;
             debug(blurb) { writeln(__LINE__); writeln(line); }
             if ((opt_action.backmatter && opt_action.section_blurb) && !(line.empty)) {
-              ST_the_section add_to_blurb_sect = line.build_the_blurb_section(pith, tag_assoc, opt_action);
+              ST_the_section add_to_blurb_sect = line.build_the_blurb_section(pith, tag_assoc, opt_action); // double check, should not be necessary to pass pith
               the_document_blurb_section ~= add_to_blurb_sect.comp_section_obj[0];
               if (add_to_blurb_sect.comp_section_obj.length > 1) { // heading
                 the_document_blurb_section ~= add_to_blurb_sect.comp_section_obj[1];
@@ -1446,9 +1222,9 @@ template docAbstraction() {
         obj = _links(obj);
       }
     }
-    // get decendants
+    // get descendants
     if (the_document_body_section.length > 1) {
-      auto pairs = after_doc_get_decendants(
+      auto pairs = after_doc_get_descendants(
         the_document_head_section ~
         the_document_body_section ~
         the_document_endnotes_section ~
@@ -1458,7 +1234,7 @@ template docAbstraction() {
         the_document_blurb_section ~
         the_document_xml_dom_tail_section
       );
-      debug(decendants_tuple) {
+      debug(descendants_tuple) {
         pairs = pairs.sort();
         foreach (pair; pairs) { // (pair; pairs.sort())
           writeln(pair[0], "..", pair[1]);
@@ -1468,7 +1244,7 @@ template docAbstraction() {
         if (obj.metainfo.is_a == "heading") {
           foreach (pair; pairs) {
             if (obj.metainfo.ocn == pair[0]) {
-              obj.metainfo.last_decendant_ocn = pair[1];
+              obj.metainfo.last_descendant_ocn = pair[1];
             }
           }
         }
@@ -1478,7 +1254,7 @@ template docAbstraction() {
           if (obj.metainfo.is_a == "heading") {
             foreach (pair; pairs) {
               if (obj.metainfo.ocn == pair[0]) {
-                obj.metainfo.last_decendant_ocn = pair[1];
+                obj.metainfo.last_descendant_ocn = pair[1];
               }
             }
           }
@@ -1489,7 +1265,7 @@ template docAbstraction() {
           if (obj.metainfo.is_a == "heading") {
             foreach (pair; pairs) {
               if (obj.metainfo.ocn == pair[0]) {
-                obj.metainfo.last_decendant_ocn = pair[1];
+                obj.metainfo.last_descendant_ocn = pair[1];
               }
             }
           }
@@ -1500,7 +1276,7 @@ template docAbstraction() {
           if (obj.metainfo.is_a == "heading") {
             foreach (pair; pairs) {
               if (obj.metainfo.ocn == pair[0]) {
-                obj.metainfo.last_decendant_ocn = pair[1];
+                obj.metainfo.last_descendant_ocn = pair[1];
               }
             }
           }
@@ -1511,7 +1287,7 @@ template docAbstraction() {
           if (obj.metainfo.is_a == "heading") {
             foreach (pair; pairs) {
               if (obj.metainfo.ocn == pair[0]) {
-                obj.metainfo.last_decendant_ocn = pair[1];
+                obj.metainfo.last_descendant_ocn = pair[1];
               }
             }
           }
@@ -1522,7 +1298,7 @@ template docAbstraction() {
           if (obj.metainfo.is_a == "heading") {
             foreach (pair; pairs) {
               if (obj.metainfo.ocn == pair[0]) {
-                obj.metainfo.last_decendant_ocn = pair[1];
+                obj.metainfo.last_descendant_ocn = pair[1];
               }
             }
           }
@@ -1533,7 +1309,7 @@ template docAbstraction() {
           if (obj.metainfo.is_a == "heading") {
             foreach (pair; pairs) {
               if (obj.metainfo.ocn == pair[0]) {
-                obj.metainfo.last_decendant_ocn = pair[1];
+                obj.metainfo.last_descendant_ocn = pair[1];
               }
             }
           }
@@ -1544,7 +1320,7 @@ template docAbstraction() {
           if (obj.metainfo.is_a == "heading") {
             foreach (pair; pairs) {
               if (obj.metainfo.ocn == pair[0]) {
-                obj.metainfo.last_decendant_ocn = pair[1];
+                obj.metainfo.last_descendant_ocn = pair[1];
               }
             }
           }
@@ -1729,5112 +1505,4 @@ template docAbstraction() {
     }
     return ret;
   } // ← closed: abstract doc source
-  @safe pure ObjGenericComposite obj_heading_ancestors()(
-    ObjGenericComposite  obj,
-    string[]             lv_ancestors_txt,
-  ) {
-    switch (obj.metainfo.heading_lev_markup) {
-    case 0:
-      lv_ancestors_txt[0] = obj.text.to!string;
-      foreach(k; 1..8) { lv_ancestors_txt[k] = ""; }
-      goto default;
-    case 1:
-      lv_ancestors_txt[1] = obj.text.to!string;
-      foreach(k; 2..8) { lv_ancestors_txt[k] = ""; }
-      goto default;
-    case 2:
-      lv_ancestors_txt[2] = obj.text.to!string;
-      foreach(k; 3..8) { lv_ancestors_txt[k] = ""; }
-      goto default;
-    case 3:
-      lv_ancestors_txt[3] = obj.text.to!string;
-      foreach(k; 4..8) { lv_ancestors_txt[k] = ""; }
-      goto default;
-    case 4:
-      lv_ancestors_txt[4] = obj.text.to!string;
-      foreach(k; 5..8) { lv_ancestors_txt[k] = ""; }
-      goto default;
-    case 5:
-      lv_ancestors_txt[5] = obj.text.to!string;
-      foreach(k; 6..8) { lv_ancestors_txt[k] = ""; }
-      goto default;
-    case 6:
-      lv_ancestors_txt[6] = obj.text.to!string;
-      lv_ancestors_txt[7] = "";
-      goto default;
-    case 7:
-      lv_ancestors_txt[7] = obj.text.to!string;
-      goto default;
-    default:
-      obj.tags.heading_ancestors_text = lv_ancestors_txt.dup;
-    }
-    return obj;
-  }
-  @safe pure ObjGenericComposite obj_dom_structure_set_markup_tags()(
-    ObjGenericComposite  obj,
-    int[]                dom,
-    int                  lev
-  ) {
-    foreach (i; 0 .. 8) {
-      if (i < lev) {
-        if (dom[i] == DomTags.open
-           || dom[i] == DomTags.close_and_open
-        ) {
-          dom[i] = DomTags.open_still;
-        } else if (dom[i] == DomTags.close) {
-          dom[i] = DomTags.none;
-        }
-      } else if (i == lev) {
-        if (lev  == 0
-          && dom[i] == DomTags.open_still
-        ) {
-          dom[i] = DomTags.close;
-        } else if (dom[i] == DomTags.open
-          || dom[i] == DomTags.open_still
-          || dom[i] == DomTags.close_and_open
-        ) {
-          dom[i] = DomTags.close_and_open;
-        } else {
-          dom[i] = DomTags.open;
-        }
-      } else if (i > lev) {
-        if (dom[i] == DomTags.close) {
-          dom[i] = DomTags.none;
-        } else if (dom[i] == DomTags.open
-          || dom[i] == DomTags.open_still
-          || dom[i] == DomTags.close_and_open
-        ) {
-          dom[i] = DomTags.close;
-        }
-      }
-    }
-    debug(dom_magic_numbers) { writeln("marked up: ", lev, ": ", dom); }
-    obj.metainfo.dom_structure_markedup_tags_status = dom.dup;
-    return obj;
-  }
-  @safe pure ObjGenericComposite obj_dom_set_collapsed_tags()(
-    ObjGenericComposite  obj,
-    int[]                dom,
-    int                  lev
-  ) {
-    foreach (i; 0 .. 8) {
-      if (i < lev) {
-        if (dom[i] == DomTags.open
-           || dom[i] == DomTags.close_and_open
-        ) {
-          dom[i] = DomTags.open_still;
-        } else if (dom[i] == DomTags.close) {
-          dom[i] = DomTags.none;
-        }
-      } else if (i == lev) {
-        if (lev  == 0
-          && dom[i] == DomTags.open_still
-        ) {
-          dom[i] = DomTags.close;
-        } else if (dom[i] == DomTags.open
-          || dom[i] == DomTags.open_still
-          || dom[i] == DomTags.close_and_open
-        ) {
-          dom[i] = DomTags.close_and_open;
-        } else {
-          dom[i] = DomTags.open;
-        }
-      } else if (i > lev) {
-        if (dom[i] == DomTags.close) {
-          dom[i] = DomTags.none;
-        } else if (dom[i] == DomTags.open
-          || dom[i] == DomTags.open_still
-          || dom[i] == DomTags.close_and_open
-        ) {
-          dom[i] = DomTags.close;
-        }
-      }
-    }
-    debug(dom_magic_numbers) { writeln("collapsed: ", lev, ": ", dom); }
-    obj.metainfo.dom_structure_collapsed_tags_status = dom.dup;
-    return obj;
-  }
-  @safe static  OCNset ocn_emit(int ocn_status_flag) {
-    return object_citation_number.ocn_emitter(ocn_status_flag);
-  }
-  @safe auto inline_markup_faces(L)(L line) {
-    static auto rgx = RgxI();
-    static auto mkup = InlineMarkup();
-    line = replaceAll!(m => mkup.quote_o ~ m[1] ~ mkup.quote_c)(line, rgx.within_quotes);
-    line = replaceAll!(m => mkup.ff_i ~ mkup.mono ~ mkup.ff_o ~ m["text"] ~ mkup.ff_c ~ mkup.mono)(line, rgx.inline_mark_mono);
-    line = replaceAll!(m => mkup.ff_i ~ mkup.cite ~ mkup.ff_o ~ m["text"] ~ mkup.ff_c ~ mkup.cite)(line, rgx.inline_mark_cite);
-    foreach (regx; [rgx.inline_mark_emphasis, rgx.inline_mark_bold, rgx.inline_mark_underscore, rgx.inline_mark_italics, rgx.inline_mark_superscript, rgx.inline_mark_subscript, rgx.inline_mark_strike, rgx.inline_mark_insert]) {
-      line = replaceAll!(m => mkup.ff_i ~ m["mark"] ~ mkup.ff_o ~ m["text"] ~ mkup.ff_c ~ m["mark"])(line, regx);
-    }
-    return line;
-  }
-  @safe static string links_and_images()(string obj_txt) {
-    static auto rgx = RgxI();
-    static auto mkup = InlineMarkup();
-    if (obj_txt.match(rgx.smid_inline_url_generic)) {
-      if (
-        obj_txt.match(rgx.smid_inline_link_endnote_url_helper)
-        || obj_txt.match(rgx.smid_inline_link_endnote_url_helper_punctuated)
-      ) {
-        obj_txt = replaceAll!(m => format("%s%s%s%s%s%s%s %s%s%s%s%s%s %s%s",
-          mkup.lnk_o, m["content"].strip, mkup.lnk_c,
-          mkup.url_o, m["link"], mkup.url_c,
-          mkup.en_a_o,
-          mkup.lnk_o, m["link"].strip, mkup.lnk_c,
-          mkup.url_o, m["link"], mkup.url_c,
-          mkup.en_a_c,
-          m[3]
-        ))(obj_txt, rgx.smid_inline_link_endnote_url_helper_punctuated);
-        obj_txt = replaceAll!(m => format("%s%s%s%s%s%s%s %s%s%s%s%s%s %s",
-          mkup.lnk_o, m["content"].strip, mkup.lnk_c,
-          mkup.url_o, m["link"], mkup.url_c,
-          mkup.en_a_o,
-          mkup.lnk_o, m["link"].strip, mkup.lnk_c,
-          mkup.url_o, m["link"], mkup.url_c,
-          mkup.en_a_c
-        ))(obj_txt, rgx.smid_inline_link_endnote_url_helper);
-    } else {
-        obj_txt = replaceAll!(m => format("%s%s%s%s%s%s%s",
-          m["pre"],
-          mkup.lnk_o, m["content"].strip, mkup.lnk_c,
-          mkup.url_o, m["link"], mkup.url_c
-        ))(obj_txt, rgx.smid_inline_link_markup_regular);
-      }
-        obj_txt = replaceAll!(m => format("%s%s%s%s%s%s%s",
-          m["pre"],
-          mkup.lnk_o, m["link"].strip, mkup.lnk_c,
-          mkup.url_o, m["link"], mkup.url_c
-        ))(obj_txt, rgx.smid_inline_link_naked_url); //
-    }
-    return obj_txt;
-  }
-  // ↓ abstraction struct init
-  @safe static auto eN() {
-    struct _e {
-      enum bi {
-        off,
-        on,
-      }
-      enum ocn {
-        off,
-        on,
-        closing,
-        bkidx,
-        reset,
-      }
-      enum sect {
-        unset,
-        head,
-        toc,
-        substantive,
-        bibliography,
-        glossary,
-        book_index,
-        blurb,
-      }
-      enum txt_is {
-        off,
-        para,
-        heading,
-      }
-      enum blk_is {
-        off,
-        code,
-        poem,
-        block,
-        group,
-        table,
-        quote,
-      }
-      enum blk_state {
-        off,
-        on,
-        closing,
-      }
-      enum blk_delim {
-        off,
-        curly,
-        tic,
-        curly_special,
-        tic_special,
-      }
-    }
-    return _e();
-  }
-  @safe string[string][string] inline_para_link_anchor()(
-    string[string]          an_object,
-    string[string]          tag_in_seg,
-    string[string][string]  tag_assoc
-  ) {
-    static auto rgx = RgxI();
-    if (auto m = an_object["substantive"].match(rgx.inline_link_anchor)) {
-      if (m.captures[1] !in tag_assoc) {
-        tag_assoc[(m.captures[1])]["seg_lv4"]    = tag_in_seg["seg_lv4"];
-        tag_assoc[(m.captures[1])]["seg_lv1to4"] = tag_in_seg["seg_lv1to4"];
-      } else {
-        writeln("a tag named  already exists, check text line\n    ", an_object["substantive"]);
-      }
-    }
-    return tag_assoc;
-  }
-  @system ST_txt_by_line_common_reset txt_by_line_common_reset_()(
-    int[string]     line_occur,
-    string[string]  an_object,
-    uint[string]    pith,
-  ) {
-    line_occur["heading"]                               = eN.bi.off;
-    line_occur["para"]                                  = eN.bi.off;
-    pith["txt_is"]                                      = eN.txt_is.off;
-    an_object                                           = an_object.object_reset;
-    ST_txt_by_line_common_reset ret;
-    {
-      ret.line_occur  = line_occur;
-      ret.this_object = an_object;
-      ret.pith        = pith;
-    }
-    return ret;
-  }
-  ST_the_section build_the_glossary_section(
-    char[]                 line,             // line is immutable, not necessary to return unchanged
-    uint[string]           pith,
-    string[string][string] tag_assoc,        // only for headings: html & epub
-  ) {
-    static auto rgx = RgxI();
-    ObjGenericComposite comp_obj_;
-    ObjGenericComposite[] add_to_current_document_section;
-    indent = [
-      "hang_position" : 0,
-      "base_position" : 0,
-    ];
-    bullet = false;
-    pith["txt_is"]           = eN.txt_is.para;
-    line_occur["para"]       = eN.bi.off;
-    an_object_key            = "glossary_nugget";
-    ST_the_section ret;
-    if (line.matchFirst(rgx.heading_glossary)) {
-      {
-        comp_obj_                                = set_object_heading("lev1", "backmatter", "glossary", "Glossary");
-        comp_obj_.metainfo.identifier            = "";
-        comp_obj_.metainfo.dummy_heading         = false;
-        comp_obj_.metainfo.object_number_off     = false;
-        comp_obj_.metainfo.object_number_type    = 0;
-        comp_obj_.tags.segment_anchor_tag_epub   = "_part_glossary";
-        comp_obj_.tags.anchor_tag_html           = comp_obj_.tags.segment_anchor_tag_epub;
-        comp_obj_.tags.in_segment_html           = "glossary";
-        comp_obj_.tags.anchor_tags               = ["section_glossary"];
-        comp_obj_.metainfo.dom_structure_markedup_tags_status  = [ 1, 1, 0, 0, 0, 0, 0, 0];
-        comp_obj_.metainfo.dom_structure_collapsed_tags_status = [ 1, 1, 0, 0, 0, 0, 0, 0];
-        add_to_current_document_section           ~= comp_obj_; //
-        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-      } {
-        comp_obj_                                = set_object_heading("lev4", "backmatter", "glossary", "Glossary");
-        comp_obj_.metainfo.identifier            = "";
-        comp_obj_.metainfo.dummy_heading         = true;
-        comp_obj_.metainfo.object_number_off     = true;
-        comp_obj_.metainfo.object_number_type    = 0;
-        comp_obj_.tags.segment_anchor_tag_epub   = "glossary";
-        comp_obj_.tags.anchor_tag_html           = comp_obj_.tags.segment_anchor_tag_epub;
-        comp_obj_.tags.in_segment_html           = comp_obj_.tags.anchor_tag_html;
-        comp_obj_.metainfo.heading_lev_collapsed = 2;
-        comp_obj_.tags.anchor_tags               = ["glossary"];
-        add_to_current_document_section          ~= comp_obj_; //
-        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-        pith["ocn"] = eN.ocn.on;
-      }
-      {
-        ret.comp_section_obj         ~= add_to_current_document_section;
-        ret.pith                     = pith;
-        ret.tag_assoc                = tag_assoc; // only for headings: html & epub
-      }
-    } else { // para
-      {
-        auto _get = line.flow_para_match_(an_object, an_object_key, indent, bullet, pith, line_occur);
-        {
-          an_object     = _get.this_object;
-          an_object_key = _get.this_object_key;
-          pith          = _get.pith;
-          indent        = _get.indent;
-          bullet        = _get.bullet;
-          line_occur    = _get.line_occur;
-        }
-      }
-      comp_obj_                               = set_object_generic("backmatter", "glossary", "para", "glossary", links_and_images(line.to!string.strip).replaceFirst(rgx.para_attribs, ""), 0);
-      comp_obj_.metainfo.identifier           = "";
-      comp_obj_.metainfo.object_number_off    = true;
-      comp_obj_.metainfo.object_number_type   = 0;
-      comp_obj_.attrib.indent_hang            = indent["hang_position"];
-      comp_obj_.attrib.indent_base            = indent["base_position"];
-      comp_obj_.attrib.bullet                 = bullet;
-      add_to_current_document_section         ~= comp_obj_; //
-      pith["ocn"]                             = eN.ocn.on;
-      {
-        ret.comp_section_obj = add_to_current_document_section;
-        ret.pith             = pith;
-        ret.tag_assoc        = tag_assoc; // NO CHANGE here, only for headings: html & epub
-      }
-    }
-    return ret;
-  }
-  ST_the_section build_the_blurb_section(Opt) (
-    char[]                 line,             // line is immutable, not necessary to return unchanged
-    uint[string]           pith,
-    string[string][string] tag_assoc,        // only for headings: html & epub
-    Opt                    opt_action,
-  ) {
-    static auto rgx = RgxI();
-    ObjGenericComposite comp_obj_;
-    ObjGenericComposite[] add_to_current_document_section;
-    // assert (opt_action.backmatter && opt_action.section_blurb);
-    indent = [
-      "hang_position" : 0,
-      "base_position" : 0,
-    ];
-    bullet = false;
-    if (auto m = line.matchFirst(rgx.para_indent)) {
-      debug(paraindent) { writeln(line); }
-      indent["hang_position"] = (m["indent"]).to!int;
-      indent["base_position"] = (m["indent"]).to!int;
-    } else if (line.matchFirst(rgx.para_bullet)) {
-      debug(parabullet) { writeln(line); }
-      bullet = true;
-    } else if (auto m = line.matchFirst(rgx.para_indent_hang)) {
-      debug(paraindenthang) { writeln(line); }
-      indent = [
-        "hang_position" : (m["hang"]).to!int,
-        "base_position" : (m["indent"]).to!int,
-      ];
-    } else if (auto m = line.matchFirst(rgx.para_bullet_indent)) {
-      debug(parabulletindent) { writeln(line); }
-      indent = [
-        "hang_position" : (m["indent"]).to!int,
-        "base_position" : (m["indent"]).to!int,
-      ];
-      bullet = true;
-    }
-    pith["txt_is"]           = eN.txt_is.para;
-    line_occur["para"]       = eN.bi.off;
-    an_object_key = "blurb_nugget";
-    ST_the_section ret;
-    if (line.matchFirst(rgx.heading_blurb)
-    && (opt_action.backmatter && opt_action.section_blurb)) {
-      {
-        comp_obj_                                              = set_object_heading("lev1", "backmatter", "blurb", "Blurb");
-        comp_obj_.metainfo.identifier                          = "";
-        comp_obj_.metainfo.dummy_heading                       = false;
-        comp_obj_.metainfo.object_number_off                   = false;
-        comp_obj_.metainfo.object_number_type                  = 0;
-        comp_obj_.tags.segment_anchor_tag_epub                 = "_part_blurb";
-        comp_obj_.tags.anchor_tag_html                         = comp_obj_.tags.segment_anchor_tag_epub;
-        comp_obj_.tags.in_segment_html                         = "blurb";
-        comp_obj_.tags.anchor_tags                             = ["section_blurb"];
-        comp_obj_.metainfo.dom_structure_markedup_tags_status  = [ 1, 1, 0, 0, 0, 0, 0, 0];
-        comp_obj_.metainfo.dom_structure_collapsed_tags_status = [ 1, 1, 0, 0, 0, 0, 0, 0];
-        add_to_current_document_section                                 ~= comp_obj_;
-        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-      }
-      {
-        comp_obj_                                              = set_object_heading("lev4", "backmatter", "blurb", "Blurb");
-        comp_obj_.metainfo.identifier                          = "";
-        comp_obj_.metainfo.dummy_heading                       = true;
-        comp_obj_.metainfo.object_number_off                   = true;
-        comp_obj_.metainfo.object_number_type                  = 0;
-        comp_obj_.tags.segment_anchor_tag_epub                 = "blurb";
-        comp_obj_.tags.anchor_tag_html                         = comp_obj_.tags.segment_anchor_tag_epub;
-        comp_obj_.tags.in_segment_html                         = comp_obj_.tags.anchor_tag_html;
-        comp_obj_.metainfo.heading_lev_collapsed               = 2;
-        comp_obj_.tags.anchor_tags                             = ["blurb"];
-        add_to_current_document_section                                 ~= comp_obj_;
-        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-      }
-    } else if (line.matchFirst(rgx.headings)
-    && (opt_action.backmatter && opt_action.section_blurb)) {
-      comp_obj_                                              = comp_obj_.init;
-      comp_obj_.metainfo.is_of_part                          = "backmatter";
-      comp_obj_.metainfo.is_of_section                       = "blurb";
-      comp_obj_.metainfo.is_of_type                          = "para";
-      comp_obj_.metainfo.is_a                                = "heading";
-      comp_obj_.text                                         = line.to!string;
-      comp_obj_.metainfo.ocn                                 = 0;
-      comp_obj_.metainfo.identifier                          = "";
-      comp_obj_.metainfo.dummy_heading                       = false;
-      comp_obj_.metainfo.object_number_off                   = true;
-      comp_obj_.metainfo.object_number_type                  = 0;
-      comp_obj_.tags.segment_anchor_tag_epub                 = "blurb";
-      comp_obj_.tags.anchor_tag_html                         = comp_obj_.tags.segment_anchor_tag_epub;
-      comp_obj_.tags.in_segment_html                         = comp_obj_.tags.anchor_tag_html;
-      comp_obj_.metainfo.heading_lev_markup                  = an_object["lev_markup_number"].to!int;    // make int, remove need to conv
-      comp_obj_.metainfo.heading_lev_collapsed               = an_object["lev_collapsed_number"].to!int; // make int, remove need to conv
-      comp_obj_.metainfo.parent_ocn                          = 1;
-      comp_obj_.metainfo.parent_lev_markup                   = 0;
-      add_to_current_document_section                                 ~= comp_obj_;
-      tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-      tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-    } else if (!(line.empty)) {
-      {
-        auto _get = line.flow_para_match_(an_object, an_object_key, indent, bullet, pith, line_occur);
-        {
-          an_object     = _get.this_object;
-          an_object_key = _get.this_object_key;
-          pith          = _get.pith;
-          indent        = _get.indent;
-          bullet        = _get.bullet;
-          line_occur    = _get.line_occur;
-        }
-      }
-      comp_obj_                               = set_object_generic("backmatter", "blurb", "para", "blurb", links_and_images(line.to!string.strip).replaceFirst(rgx.para_attribs, ""), 0);
-      comp_obj_.metainfo.identifier           = "";
-      comp_obj_.metainfo.object_number_off    = true;
-      comp_obj_.metainfo.object_number_type   = 0;
-      comp_obj_.attrib.indent_hang            = indent["hang_position"];
-      comp_obj_.attrib.indent_base            = indent["base_position"];
-      comp_obj_.has.inline_links              = true;
-      comp_obj_.attrib.bullet                 = bullet;
-      add_to_current_document_section         ~= comp_obj_;
-    }
-    pith["ocn"] = eN.ocn.on;
-    {
-      ret.comp_section_obj = add_to_current_document_section;
-      ret.pith             = pith;
-      ret.tag_assoc        = tag_assoc; // NO CHANGE here, only for headings: html & epub
-    }
-    return ret;
-  }
-  @safe ST_txt_by_line_block_start txt_by_line_block_start()(
-    char[]         line,
-    uint[string]   pith,
-    uint[string]   dochas,
-    string[string] object_number_poem
-  ) {
-    static auto rgx = RgxI();
-    if (auto m = line.matchFirst(rgx.block_curly_code_open)) {
-      dochas["codeblock"]++;
-      an_object["lang"]               = "";
-      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
-      an_object["syntax"]             = (m["syntax"]) ? m["syntax"].to!string : "";
-      debug(codecurly) { writefln( "* [code curly] %s", line); }                              // code (curly) open
-      pith["block_is"]                = eN.blk_is.code;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.curly;
-    } else if (auto m = line.matchFirst(rgx.block_curly_poem_open)) {
-      dochas["poem"]++;
-      an_object["syntax"]             = "";
-      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
-      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
-      debug(poem) { writefln( "* [poem curly] %s", line); }                              // poem (curly) open
-      object_number_poem["start"]     = obj_cite_digits.object_number.to!string;
-      pith["block_is"]                = eN.blk_is.poem;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.curly;
-      pith["verse_new"]               = eN.bi.on;
-    } else if (auto m = line.matchFirst(rgx.block_curly_group_open)) {
-      dochas["group"]++;
-      an_object["syntax"]             = "";
-      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
-      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
-      debug(group) { writefln( "* [group curly] %s", line); }                             // group (curly) open
-      pith["block_is"]                = eN.blk_is.group;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.curly;
-    } else if (auto m = line.matchFirst(rgx.block_curly_block_open)) {
-      dochas["block"]++;
-      an_object["syntax"]             = "";
-      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
-      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
-      debug(block) { writefln( "* [block curly] %s", line); }
-      pith["block_is"]                = eN.blk_is.block;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.curly;
-    } else if (auto m = line.matchFirst(rgx.block_curly_quote_open)) {
-      dochas["quote"]++;
-      an_object["syntax"]             = "";
-      an_object["attrib"]             = m["attrib"].to!string;
-      an_object["lang"]               = m["lang"].to!string;
-      debug(quote) { writefln( "* [quote curly] %s", line); }
-      pith["block_is"]                = eN.blk_is.quote;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.curly;
-    } else if (auto m = line.matchFirst(rgx.block_curly_table_open)) {           // curly table open
-      debug(table) { writefln( "* [table curly] %s", line); }
-      dochas["table"] ++;
-      an_object["table_head"]         = m["attrib"].to!string;
-      an_object["block_type"]         = "curly";
-      pith["block_is"]                = eN.blk_is.table;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.curly;
-    } else if (auto m = line.matchFirst(rgx.block_curly_table_special_markup)) { // table: special table block markup syntax!
-      dochas["table"]++;
-      an_object["table_head"]         = m["attrib"].to!string;
-      an_object["block_type"]         = "special";
-      pith["block_is"]                = eN.blk_is.table;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.curly_special;
-    } else if (auto m = line.matchFirst(rgx.block_tic_code_open)) {
-      dochas["codeblock"]++;
-      an_object["lang"]               = "";
-      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
-      an_object["syntax"]             = (m["syntax"]) ? m["syntax"].to!string : "";
-      debug(codetic) { writefln( "* [code tic] %s", line); }
-      pith["block_is"]                = eN.blk_is.code;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.tic;
-    } else if (auto m = line.matchFirst(rgx.block_tic_poem_open)) {
-      dochas["poem"]++;
-      an_object["syntax"]             = "";
-      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
-      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
-      debug(poem) { writefln( "* [poem tic] %s", line); }
-      object_number_poem["start"]     = obj_cite_digits.object_number.to!string;
-      pith["block_is"]                = eN.blk_is.poem;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.tic;
-      pith["verse_new"]               = eN.bi.on;
-    } else if (auto m = line.matchFirst(rgx.block_tic_group_open)) {
-      dochas["group"]++;
-      an_object["syntax"]             = "";
-      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
-      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
-      debug(group) { writefln( "* [group tic] %s", line); }
-      pith["block_is"]                = eN.blk_is.group;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.tic;
-    } else if (auto m = line.matchFirst(rgx.block_tic_block_open)) {
-      dochas["block"]++;
-      an_object["syntax"]             = "";
-      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
-      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
-      debug(block) { writefln( "* [block tic] %s", line); }
-      pith["block_is"]                = eN.blk_is.block;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.tic;
-    } else if (auto m = line.matchFirst(rgx.block_tic_quote_open)) {
-      dochas["quote"]++;
-      an_object["syntax"]             = "";
-      an_object["attrib"]             = m["attrib"].to!string;
-      an_object["lang"]               = m["lang"].to!string;
-      debug(quote) { writefln( "* [quote tic] %s", line);                        // quote (tic) open
-      }
-      pith["block_is"]                = eN.blk_is.quote;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.tic;
-    } else if (auto m = line.matchFirst(rgx.block_tic_table_open)) {             // tic table open
-      debug(table) { writefln( "* [table tic] %s", line); }
-      dochas["table"] ++;
-      an_object["table_head"]         = m["attrib"].to!string;
-      an_object["block_type"]         = "tic";
-      pith["block_is"]                = eN.blk_is.table;
-      pith["block_state"]             = eN.blk_state.on;
-      pith["block_delim"]             = eN.blk_delim.tic;
-    }
-    ST_txt_by_line_block_start ret;
-    {
-      ret.pith               = pith;
-      ret.dochas             = dochas;
-      ret.object_number_poem = object_number_poem;
-    }
-    return ret;
-  }
-  @safe ST_txt_by_line_block_generic txt_by_line_block_quote()(
-    char[]          line,
-    string[string]  an_object,
-    uint[string]    pith,
-  ) {
-    static auto rgx = RgxI();
-    if (pith["block_is"] == eN.blk_is.quote){
-      if (pith["block_delim"] == eN.blk_delim.curly) {
-        if (line.matchFirst(rgx.block_curly_quote_close)) {
-          debug(quote) { writeln(line); }
-          an_object[an_object_key]    = an_object[an_object_key].stripRight;
-          pith["block_is"]            = eN.blk_is.quote;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          debug(quote) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      } else if (pith["block_delim"] == eN.blk_delim.tic) {
-        if (line.matchFirst(rgx.block_tic_close)) {
-          debug(quote) { writeln(line); }
-          an_object[an_object_key]    = an_object[an_object_key].stripRight;
-          pith["block_is"]            = eN.blk_is.quote;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          debug(quote) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      }
-    }
-    ST_txt_by_line_block_generic ret;
-    {
-      ret.pith        = pith;
-      ret.this_object = an_object;
-    }
-    return ret;
-  }
-  @safe ST_txt_by_line_block_generic txt_by_line_block_group()(
-    char[]          line,
-    string[string]  an_object,
-    uint[string]    pith,
-  ) {
-    static auto rgx = RgxI();
-    if (pith["block_is"] == eN.blk_is.group) {
-      if (pith["block_delim"] == eN.blk_delim.curly) {
-        if (line.matchFirst(rgx.block_curly_group_close)) {
-          debug(group) { writeln(line); }
-          an_object[an_object_key]    = an_object[an_object_key].stripRight;
-          pith["block_is"]            = eN.blk_is.group;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          debug(group) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      } else if (pith["block_delim"] == eN.blk_delim.tic) {
-        if (line.matchFirst(rgx.block_tic_close)) {
-          debug(group) { writeln(line); }
-          an_object[an_object_key]    = an_object[an_object_key].stripRight;
-          pith["block_is"]            = eN.blk_is.group;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          debug(group) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      }
-    }
-    ST_txt_by_line_block_generic ret;
-    {
-      ret.pith        = pith;
-      ret.this_object = an_object;
-    }
-    return ret;
-  }
-  @safe ST_txt_by_line_block_generic txt_by_line_block_block()(
-    char[]          line,
-    string[string]  an_object,
-    uint[string]    pith,
-  ) {
-    static auto rgx = RgxI();
-    if (pith["block_is"] == eN.blk_is.block) {
-      if (pith["block_delim"] == eN.blk_delim.curly) {
-        if (line.matchFirst(rgx.block_curly_block_close)) {
-          debug(block) { writeln(line); }
-          an_object[an_object_key]    = an_object[an_object_key].stripRight;
-          pith["block_is"]            = eN.blk_is.block;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          debug(block) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      } else if (pith["block_delim"] == eN.blk_delim.tic) {
-        if (line.matchFirst(rgx.block_tic_close)) {
-          debug(block) { writeln(line); }
-          an_object[an_object_key]    = an_object[an_object_key].stripRight;
-          pith["block_is"]            = eN.blk_is.block;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          debug(block) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      }
-    }
-    ST_txt_by_line_block_generic ret;
-    {
-      ret.pith        = pith;
-      ret.this_object = an_object;
-    }
-    return ret;
-  }
-  @safe ST_txt_by_line_block_poem txt_by_line_block_poem(CMM)(
-    char[]          line,
-    string[string]  an_object,
-    uint[string]    pith,
-    int             cntr,
-    string[string]  object_number_poem,
-    CMM             conf_make_meta,
-    string[string]  tag_in_seg,
-  ) {
-    static auto rgx = RgxI();
-    if (pith["block_is"] == eN.blk_is.poem) {
-      if (pith["block_delim"] == eN.blk_delim.curly) {
-        if (line.matchFirst(rgx.block_curly_poem_close)) {
-          if (an_object_key in an_object
-          || processing.length > 0) {
-            an_object[an_object_key]        = "";
-            debug(poem) { writefln( "* [poem curly] %s", line); }
-            if (processing.length > 0) {
-              an_object[an_object_key]      = processing["verse"];
-            }
-            debug(poem) {
-              writeln(__LINE__);
-              writefln( "* %s %s", obj_cite_digits.object_number, line);
-            }
-            if (an_object.length > 0) {
-              debug(poem) { writeln( obj_cite_digits.object_number, an_object[an_object_key]); }
-              an_object["is"]                                   = "verse";
-              ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
-                = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
-              an_object["substantive"]                          = substantive_obj_misc_struct.obj_txt;
-              anchor_tag                                        = substantive_obj_misc_struct.anchor_tag;
-              comp_obj_                                         = set_object_generic("body", "body", "block", "verse", an_object["substantive"], obj_cite_digits.object_number);
-              comp_obj_.metainfo.identifier                     = obj_cite_digits.identifier;
-              comp_obj_.metainfo.object_number_off              = obj_cite_digits.off;
-              comp_obj_.metainfo.o_n_book_index                 = obj_cite_digits.bkidx;
-              comp_obj_.metainfo.object_number_type             = obj_cite_digits.type;
-              comp_obj_.tags.html_segment_anchor_tag_is         = tag_in_seg["seg_lv4"];
-              comp_obj_.tags.epub_segment_anchor_tag_is         = tag_in_seg["seg_lv1to4"];
-              comp_obj_.has.inline_notes_reg                    = substantive_obj_misc_struct.has_notes_reg;
-              comp_obj_.has.inline_notes_star                   = substantive_obj_misc_struct.has_notes_star;
-              comp_obj_.has.inline_links                        = substantive_obj_misc_struct.has_links;
-              the_document_body_section                         ~= comp_obj_;
-              tag_assoc                                         = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
-            }
-            object_reset(an_object);
-            processing.remove("verse");
-            ++cntr;
-          }
-          object_number_poem["end"]   = obj_cite_digits.object_number.to!string;
-          pith["block_is"]            = eN.blk_is.poem;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          processing["verse"] ~= line ~= "\n";
-          if (pith["verse_new"] == eN.bi.on) {
-            obj_cite_digits = ocn_emit(pith["ocn"]);
-            pith["verse_new"]         = eN.bi.off;
-          } else if (line.matchFirst(rgx.newline_eol_delimiter_only)) {
-            processing["verse"]       = processing["verse"].stripRight;
-            verse_line                = eN.bi.off;
-            pith["verse_new"]         = eN.bi.on;
-          }
-          if (pith["verse_new"] == eN.bi.on) {
-            verse_line = 1;
-            an_object[an_object_key]  = processing["verse"];
-            debug(poem) { writefln(
-                "* %s curly\n%s",
-                obj_cite_digits.object_number,
-                an_object[an_object_key]
-              );
-            }
-            processing.remove("verse");
-            an_object["is"]                                     = "verse";
-            auto comp_obj_location = node_construct.node_location_emitter(
-              content_non_header,
-              tag_in_seg,
-              lev_anchor_tag,
-              tag_assoc,
-              obj_cite_digits,
-              cntr,
-              heading_ptr-1,
-              an_object["is"]
-            );
-            ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
-              = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
-            an_object["substantive"]                            = substantive_obj_misc_struct.obj_txt;
-            anchor_tag                                          = substantive_obj_misc_struct.anchor_tag;
-            comp_obj_                                           = set_object_generic("body", "body", "block", "verse", an_object["substantive"], obj_cite_digits.object_number);
-            comp_obj_.metainfo.identifier                       = obj_cite_digits.identifier;
-            comp_obj_.metainfo.object_number_off                = obj_cite_digits.off;
-            comp_obj_.metainfo.o_n_book_index                   = obj_cite_digits.bkidx;
-            comp_obj_.metainfo.object_number_type               = obj_cite_digits.type;
-            comp_obj_.tags.html_segment_anchor_tag_is           = tag_in_seg["seg_lv4"];
-            comp_obj_.tags.epub_segment_anchor_tag_is           = tag_in_seg["seg_lv1to4"];
-            comp_obj_.has.inline_notes_reg                      = substantive_obj_misc_struct.has_notes_reg;
-            comp_obj_.has.inline_notes_star                     = substantive_obj_misc_struct.has_notes_star;
-            comp_obj_.has.inline_links                          = substantive_obj_misc_struct.has_links;
-            the_document_body_section                           ~= comp_obj_;
-            tag_assoc                                           = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
-            object_reset(an_object);
-            processing.remove("verse");
-            ++cntr;
-          }
-        }
-      } else if (pith["block_delim"] == eN.blk_delim.tic) {
-        if (auto m = line.matchFirst(rgx.block_tic_close)) {
-          an_object[an_object_key] = "verse";
-          debug(poem) { writefln( "* [poem tic] %s", line); }
-          if (processing.length > 0) {
-            an_object[an_object_key]  = processing["verse"];
-          }
-          if (an_object.length > 0) {
-            debug(poem) { writeln(__LINE__); writeln(obj_cite_digits.object_number, line); }
-            processing.remove("verse");
-            an_object["is"]                                     = "verse";
-            ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
-              = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
-            an_object["substantive"]                            = substantive_obj_misc_struct.obj_txt;
-            anchor_tag                                          = substantive_obj_misc_struct.anchor_tag;
-            comp_obj_                                           = set_object_generic("body", "body", "block", "verse", an_object["substantive"], obj_cite_digits.object_number);
-            comp_obj_.metainfo.identifier                       = obj_cite_digits.identifier;
-            comp_obj_.metainfo.object_number_off                = obj_cite_digits.off;
-            comp_obj_.metainfo.o_n_book_index                   = obj_cite_digits.bkidx;
-            comp_obj_.metainfo.object_number_type               = obj_cite_digits.type;
-            comp_obj_.tags.html_segment_anchor_tag_is           = tag_in_seg["seg_lv4"];
-            comp_obj_.tags.epub_segment_anchor_tag_is           = tag_in_seg["seg_lv1to4"];
-            comp_obj_.has.inline_notes_reg                      = substantive_obj_misc_struct.has_notes_reg;
-            comp_obj_.has.inline_notes_star                     = substantive_obj_misc_struct.has_notes_star;
-            comp_obj_.has.inline_links                          = substantive_obj_misc_struct.has_links;
-            the_document_body_section                           ~= comp_obj_;
-            tag_assoc                                           = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
-            object_number_poem["end"]                           = obj_cite_digits.object_number.to!string;
-            object_reset(an_object);
-            processing.remove("verse");
-            ++cntr;
-          }
-          pith["block_is"]            = eN.blk_is.poem;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          processing["verse"]         ~= line ~= "\n";
-          if (pith["verse_new"] == eN.bi.on) {
-            obj_cite_digits           = ocn_emit(pith["ocn"]);
-            pith["verse_new"]         = eN.bi.off;
-          } else if (line.matchFirst(rgx.newline_eol_delimiter_only)) {
-            processing["verse"]       = processing["verse"].stripRight;
-            pith["verse_new"]         = eN.bi.on;
-            verse_line                = eN.bi.off;
-          }
-          if (pith["verse_new"] == eN.bi.on) {
-            verse_line = 1;
-            an_object[an_object_key]  = processing["verse"];
-            debug(poem) { writefln(
-                "* %s tic\n%s",
-                obj_cite_digits.object_number,
-                an_object[an_object_key]
-              );
-            }
-            processing.remove("verse");
-            an_object["is"]                                     = "verse";
-            auto comp_obj_location
-              = node_construct.node_location_emitter(
-                content_non_header,
-                tag_in_seg,
-                lev_anchor_tag,
-                tag_assoc,
-                obj_cite_digits,
-                cntr,
-                heading_ptr-1,
-                an_object["is"]
-              );
-            ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
-              = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
-            an_object["substantive"]                            = substantive_obj_misc_struct.obj_txt;
-            anchor_tag                                          = substantive_obj_misc_struct.anchor_tag;
-            comp_obj_                                           = set_object_generic("body", "body", "block", "verse", an_object["substantive"], obj_cite_digits.object_number);
-            comp_obj_.metainfo.identifier                       = obj_cite_digits.identifier;
-            comp_obj_.metainfo.object_number_off                = obj_cite_digits.off;
-            comp_obj_.metainfo.o_n_book_index                   = obj_cite_digits.bkidx;
-            comp_obj_.metainfo.object_number_type               = obj_cite_digits.type;
-            comp_obj_.tags.html_segment_anchor_tag_is           = tag_in_seg["seg_lv4"];
-            comp_obj_.tags.epub_segment_anchor_tag_is           = tag_in_seg["seg_lv1to4"];
-            comp_obj_.has.inline_notes_reg                      = substantive_obj_misc_struct.has_notes_reg;
-            comp_obj_.has.inline_notes_star                     = substantive_obj_misc_struct.has_notes_star;
-            comp_obj_.has.inline_links                          = substantive_obj_misc_struct.has_links;
-            the_document_body_section                           ~= comp_obj_;
-            tag_assoc                                           = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
-            object_reset(an_object);
-            processing.remove("verse");
-            ++cntr;
-          }
-        }
-      }
-    }
-    ST_txt_by_line_block_poem ret;
-    {
-      ret.cntr        = cntr;
-      ret.pith        = pith;
-      ret.this_object = an_object;
-    }
-    return ret;
-  }
-  @safe ST_txt_by_line_block_generic txt_by_line_block_code()(
-    char[]          line,
-    string[string]  an_object,
-    uint[string]    pith,
-  ) {
-    static auto rgx = RgxI();
-    if ( pith["block_is"] == eN.blk_is.code) {
-      if (pith["block_delim"] == eN.blk_delim.curly) {
-        if (line.matchFirst(rgx.block_curly_code_close)) {
-          debug(codecurly) { writeln(line); }
-          an_object[an_object_key] = an_object[an_object_key]
-            .replaceFirst(rgx.newline_eol_delimiter_only, "")
-            .stripRight;
-          pith["block_is"]            = eN.blk_is.code;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          debug(codecurly) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      } else if (pith["block_delim"] == eN.blk_delim.tic) {
-        if (line.matchFirst(rgx.block_tic_close)) {
-          debug(codetic) { writeln(line); }
-          an_object[an_object_key] = an_object[an_object_key]
-            .replaceFirst(rgx.newline_eol_delimiter_only, "")
-            .stripRight;
-          pith["block_is"]            = eN.blk_is.code;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          debug(codetic) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      }
-    }
-    ST_txt_by_line_block_generic ret;
-    {
-      ret.pith        = pith;
-      ret.this_object = an_object;
-    }
-    return ret;
-  }
-  @system auto txt_by_line_block_table(CMM)(
-    char[]          line,
-    string[string]  an_object,
-    uint[string]    pith,
-    CMM             conf_make_meta,
-  ) {
-    static auto rgx = RgxI();
-    if (pith["block_is"] == eN.blk_is.table) {
-      if (pith["block_delim"] == eN.blk_delim.curly) {
-        if (line.matchFirst(rgx.block_curly_table_close)) {
-          debug(table) { writeln(line); }
-          pith["block_is"]            = eN.blk_is.table;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          debug(table) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      } else if (pith["block_delim"] == eN.blk_delim.curly_special) {
-        if (line.empty) {
-          pith["block_is"]            = eN.blk_is.table;
-          pith["block_state"]         = eN.blk_state.off;
-          pith["block_delim"]         = eN.blk_delim.off;
-          {
-            auto _get = line.flow_table_closed_make_special_notation_table_(
-              an_object,
-              the_document_body_section,
-              obj_cite_digits,
-              comp_obj_,
-              cntr,
-              pith,
-              conf_make_meta,
-            );
-            {
-              an_object                 = _get.this_object;
-              the_document_body_section = _get.the_document_body_section;
-              obj_cite_digits           = _get.obj_cite_digits;
-              comp_obj_                 = _get.comp_obj_;
-              cntr                      = _get.cntr;
-              pith                      = _get.pith;
-            }
-          }
-        } else {
-          debug(table) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      } else if (pith["block_delim"] == eN.blk_delim.tic) {
-        if (line.matchFirst(rgx.block_tic_close)) {
-          debug(table) { writeln(line); }
-          pith["block_is"]            = eN.blk_is.table;
-          pith["block_state"]         = eN.blk_state.closing;
-          pith["block_delim"]         = eN.blk_delim.off;
-        } else {
-          debug(table) { writeln(line); }
-          an_object[an_object_key] ~= line ~= "\n";
-        }
-      }
-    }
-    struct ST_txt_by_line_block_table {
-      CMM             conf_make_meta;
-      uint[string]    pith;
-      string[string]  this_object;
-    }
-    ST_txt_by_line_block_table ret;
-    {
-      ret.conf_make_meta = conf_make_meta,
-      ret.pith           = pith;
-      ret.this_object    = an_object;
-    }
-    return ret;
-  }
-  @system ST_txt_by_line_block_biblio txt_by_line_block_biblio(
-    char[]                  line,
-    uint[string] pith,
-    int          bib_entry,
-    string       biblio_entry_str_json,
-    string[]     biblio_arr_json,
-  ) {
-    mixin spineBiblio;
-    auto jsn = BibJsnStr();
-    static auto rgx = RgxI();
-    string biblio_tag_map()(string abr) {
-      auto btm = [
-        "au"        : "author_raw",
-        "ed"        : "editor_raw",
-        "ti"        : "fulltitle",
-        "lng"       : "language",
-        "jo"        : "journal",
-        "vol"       : "volume",
-        "edn"       : "edition",
-        "yr"        : "year",
-        "pl"        : "place",
-        "pb"        : "publisher",
-        "pub"       : "publisher",
-        "pg"        : "pages",
-        "pgs"       : "pages",
-        "sn"        : "short_name"
-      ];
-      return btm[abr];
-    }
-    if (line.matchFirst(rgx.heading_biblio)) {
-      pith["section"] = eN.sect.bibliography;
-    }
-    if (line.empty) {
-      debug {
-        debug(biblioblock) { writeln("---"); }
-        debug(biblioblockinclude) { writeln(biblio_entry_str_json.length); }
-      }
-      if ((bib_entry == eN.bi.off)
-      && (biblio_entry_str_json.empty)) {
-        bib_entry = eN.bi.on;
-        biblio_entry_str_json = jsn.biblio_entry_tags_jsonstr;
-      } else if (!(biblio_entry_str_json.empty)) {
-        bib_entry = eN.bi.off;
-        if (!(biblio_entry_str_json == jsn.biblio_entry_tags_jsonstr)) {
-          auto biblio_entry = parseJSON(biblio_entry_str_json);
-          if (biblio_entry["fulltitle"].str.empty) {
-            writeln("check problem entry (Title missing): ", biblio_entry_str_json);
-          } else if ((biblio_entry["author_raw"].str.empty) && (biblio_entry["editor_raw"].str.empty)) {
-            writeln("check problem entry (No author and no editor): ", biblio_entry_str_json);
-          } else {
-            biblio_arr_json ~= biblio_entry_str_json;
-          }
-          biblio_entry_str_json = jsn.biblio_entry_tags_jsonstr;
-        }
-      } else {
-        writeln("?? 2. ERROR ", biblio_entry_str_json, "??");
-        biblio_entry_str_json = "";
-      }
-    } else if (line.matchFirst(rgx.biblio_tags)) {
-      debug(biblioblock) { writeln(line); }
-      auto bt = line.match(rgx.biblio_tags);
-      bib_entry = eN.bi.off;
-      st = bt.captures[1].to!string;
-      auto header_tag_value = (bt.captures[2]).to!string;
-      JSONValue j = parseJSON(biblio_entry_str_json);
-      biblio_tag_name = (st.match(rgx.biblio_abbreviations))
-        ? (biblio_tag_map(st))
-        : st;
-      j.object[biblio_tag_name] = header_tag_value;
-      debug(bibliounsortedcheckduplicates) { writeln(biblio_tag_name, ": ", header_tag_value); writeln("--"); }
-      switch (biblio_tag_name) {
-      case "author_raw": // author_arr author (fn sn)
-        j["author_arr"]
-         = header_tag_value.split(rgx.arr_delimiter);
-        string tmp;
-        biblioAuthorLoop:
-        foreach (au; j["author_arr"].array) {
-          if (auto x = au.str.match(rgx.name_delimiter)) {
-            tmp ~= x.captures[2] ~ " " ~ x.captures[1] ~ ", ";
-          } else {
-            tmp ~= au.str;
-          }
-        }
-        tmp = tmp.replace(rgx.trailing_comma, "");
-        j["author"].str = tmp;
-        goto default;
-      case "editor_raw": // editor_arr editor (fn sn)
-        j["editor_arr"]
-          = header_tag_value.split(rgx.arr_delimiter);
-        string tmp;
-        biblioEditorLoop:
-        foreach (ed; j["editor_arr"].array) {
-          if (auto x = ed.str.match(rgx.name_delimiter)) {
-            tmp ~= x.captures[2] ~ " " ~ x.captures[1] ~ ", ";
-          } else {
-            tmp ~= ed.str;
-          }
-        }
-        tmp = tmp.replace(rgx.trailing_comma, "");
-        j["editor"].str = tmp;
-        goto default;
-      case "fulltitle": // title & subtitle
-        goto default;
-      default:
-        break;
-      }
-      auto s = j.toString();
-      debug(biblio1) { writefln(
-          "* %s: %s\n%s",
-          biblio_tag_name,
-          biblio_tag_entry,
-          j[biblio_tag_name]
-        );
-      }
-      if (line.match(rgx.comment)) {
-        writeln("ERROR", line, "COMMENT");
-        writeln("ERROR", s, "%%");
-      }
-      if (!(match(line, rgx.comment))) {
-        debug(biblioblockinclude) { writeln(line); }
-        biblio_entry_str_json = s;
-      } else {
-        biblio_entry_str_json = "";
-      }
-      header_tag_value        = "";
-    }
-    ST_txt_by_line_block_biblio ret;
-    {
-      ret.pith                  = pith;
-      ret.bib_entry             = bib_entry;
-      ret.biblio_entry_str_json = biblio_entry_str_json;
-      ret.biblio_arr_json       = biblio_arr_json;
-    }
-    return ret;
-  }
-  // ↓ abstraction functions
-  @safe static string[string] object_reset()(string[string] an_object) {
-    an_object.remove("body_nugget");
-    an_object.remove("substantive");
-    an_object.remove("is");
-    an_object.remove("attrib");
-    an_object.remove("bookindex_nugget");
-    return an_object;
-  }
-  @safe static uint[string] _check_ocn_status_()(
-    char[]       line,
-    uint[string] pith,
-  ) {
-    static auto rgx = RgxI();
-    if (!(line.empty)) {
-      if (pith["no_ocn_multiple_objects"] == eN.bi.off) {
-        // not multi-line object, check whether object_number is on or turned off
-        if (line.matchFirst(rgx.object_number_block_marks)) {                      // switch off object_number
-          if (line.matchFirst(rgx.object_number_off_block)) {
-            pith["no_ocn_multiple_objects"]             = eN.bi.on;
-            pith["ocn"]                                 = eN.ocn.off;
-            debug(ocnoff) { writeln(line); }
-          }
-          if (line.matchFirst(rgx.object_number_off_block_dummy_heading)) {
-            pith["no_ocn_multiple_objects"]             = eN.bi.on;
-            pith["dummy_heading_multiple_objects"]      = eN.bi.on;
-            pith["ocn"]                                 = eN.ocn.off;
-            debug(ocnoff) { writeln(line); }
-          }
-        } else if (pith["no_ocn_multiple_objects"] == eN.bi.off) {
-            pith["dummy_heading_status"]                = eN.bi.off;
-            if (pith["dummy_heading_multiple_objects"]) {
-              pith["dummy_heading_status"]              = eN.bi.on;
-            }
-            if (line.matchFirst(rgx.object_number_off)) {
-              pith["ocn"]                               = eN.ocn.off;
-            } else if (line.matchFirst(rgx.object_number_off_dummy_heading)) {
-              pith["ocn"]                               = eN.ocn.off;
-              pith["dummy_heading_status"]              = eN.bi.on;
-            } else {
-              pith["ocn"]                               = eN.ocn.on;
-              pith["dummy_heading_status"]              = eN.bi.off;
-            }
-          } else {
-            pith["ocn"] = pith["no_ocn_multiple_objects"];
-          }
-      } else if (pith["no_ocn_multiple_objects"] == eN.bi.on) {
-        if (line.matchFirst(rgx.object_number_off_block_close)) {
-          pith["no_ocn_multiple_objects"]               = eN.bi.off;
-          pith["ocn"]                                   = eN.ocn.on;
-          pith["dummy_heading_status"]                  = eN.bi.off;
-          debug(ocnoff) { writeln(line); }
-        }
-      }
-    }
-    return pith;
-  }
-  @safe char[] _doc_header_and_make_substitutions_(CMM)(
-    char[]  line,
-    CMM     conf_make_meta,
-  ) {
-    enum Substitute { match, markup, }
-    if (conf_make_meta.make.substitute) {
-      foreach(substitution_pair; conf_make_meta.make.substitute) {
-        line = line.replaceAll(
-          regex("\b" ~ substitution_pair[Substitute.match]),
-          substitution_pair[Substitute.markup]
-        );
-      }
-    }
-    return line;
-  }
-  @safe char[] _doc_header_and_make_substitutions_fontface_(CMM)(
-    char[]  line,
-    CMM     conf_make_meta,
-  ) {
-    enum Substitute { match, markup, }
-    if ( conf_make_meta.make.bold) {
-      line = line.replaceAll(
-        regex("\b" ~ conf_make_meta.make.bold[Substitute.match]),
-        conf_make_meta.make.bold[Substitute.markup]
-      );
-    }
-    if (conf_make_meta.make.emphasis) {
-      line = line.replaceAll(
-        regex("\b" ~ conf_make_meta.make.emphasis[Substitute.match]),
-        conf_make_meta.make.emphasis[Substitute.markup]
-      );
-    }
-    if (conf_make_meta.make.italics) {
-      line = line.replaceAll(
-        regex("\b" ~ conf_make_meta.make.italics[Substitute.match]),
-        conf_make_meta.make.italics[Substitute.markup]
-      );
-    }
-    return line;
-  }
-  @system ST_flow_table_closed_make_special_notation_table flow_table_closed_make_special_notation_table_(CMM)(
-    char[]                line,
-    string[string]        an_object,
-    ObjGenericComposite[] the_document_body_section,
-    OCNset                obj_cite_digits,
-    ObjGenericComposite   comp_obj_,
-    int                   cntr,
-    uint[string]          pith,
-    CMM                   conf_make_meta
-  ) {
-    comp_obj_       = comp_obj_.init;
-    obj_cite_digits = ocn_emit(pith["ocn"]);
-    auto comp_obj_location = node_construct.node_location_emitter(
-        content_non_header,
-        tag_in_seg,
-        lev_anchor_tag,
-        tag_assoc,
-        obj_cite_digits,
-        cntr,
-        heading_ptr-1,
-        "table"
-      );
-    an_object["is"]                                             = "table";
-    ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
-      = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, "body_nugget", conf_make_meta, No._new_doc);
-    an_object["substantive"]                                    = substantive_obj_misc_struct.obj_txt;
-    comp_obj_.metainfo.ocn                                      = obj_cite_digits.object_number;
-    comp_obj_.metainfo.identifier                               = obj_cite_digits.identifier;
-    comp_obj_.metainfo.object_number_off                        = obj_cite_digits.off;
-    comp_obj_.tags.html_segment_anchor_tag_is                   = tag_in_seg["seg_lv4"];
-    comp_obj_.tags.epub_segment_anchor_tag_is                   = tag_in_seg["seg_lv1to4"];
-    comp_obj_.metainfo.o_n_book_index                           = obj_cite_digits.bkidx;
-    comp_obj_.metainfo.object_number_type                       = obj_cite_digits.type;
-    comp_obj_                                                   = comp_obj_.flow_table_instructions(an_object["table_head"]);
-    {
-      auto _get = comp_obj_.flow_table_substantive_munge_special(an_object["substantive"]);
-      {
-        comp_obj_           = _get.table_object;
-        an_object["substantive"] = _get.table_substantive;
-      }
-    }
-    the_document_body_section                                   ~= comp_obj_;
-    object_reset(an_object);
-    processing.remove("verse");
-    ++cntr;
-    ST_flow_table_closed_make_special_notation_table ret;
-    {
-      ret.this_object               = an_object;
-      ret.the_document_body_section = the_document_body_section;
-      ret.obj_cite_digits           = obj_cite_digits;
-      ret.comp_obj_                 = comp_obj_;
-      ret.cntr                      = cntr;
-      ret.pith                      = pith;
-    }
-    return ret;
-  }
-  @system ST_flow_block_flag_line_empty flow_block_flag_line_empty_(B,CMM,Ts)(
-    char[]                   line,
-    string[string]           an_object,
-    B                        bookindex_extract_hash,
-    ObjGenericComposite[]    the_document_body_section,
-    string[][string][string] bookindex_unordered_hashes,
-    OCNset                   obj_cite_digits,
-    ObjGenericComposite      comp_obj_,
-    int                      cntr,
-    uint[string]             pith,
-    string[string]           object_number_poem,
-    CMM                      conf_make_meta,
-    Ts                       tag_in_seg,
-  ) {
-    assert(
-      line.empty,
-      "\nline should be empty:\n  \""
-      ~ line ~ "\""
-    );
-    assert(
-      (pith["block_state"] == eN.blk_state.closing),
-      "code block status: closed"
-    );
-    static auto rgx = RgxI();
-    if (pith["block_state"] == eN.blk_state.closing) {
-      if (pith["block_is"] == eN.blk_is.quote) {
-        obj_cite_digits = ocn_emit(pith["ocn"]);
-        an_object["bookindex_nugget"]
-          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
-        bookindex_unordered_hashes
-          = bookindex_extract_hash.bookindex_nugget_hash(
-            an_object["bookindex_nugget"],
-            obj_cite_digits,
-            tag_in_seg
-          );
-        an_object["is"]                                         = "quote";
-        auto comp_obj_location
-          = node_construct.node_location_emitter(
-            content_non_header,
-            tag_in_seg,
-            lev_anchor_tag,
-            tag_assoc,
-            obj_cite_digits,
-            cntr,
-            heading_ptr-1,
-            an_object["is"]
-          );
-        ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
-          = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
-        an_object["substantive"]                                = substantive_obj_misc_struct.obj_txt;
-        anchor_tag                                              = substantive_obj_misc_struct.anchor_tag;
-        comp_obj_                                               = set_object_generic("body", "body", "block", "quote", an_object["substantive"], obj_cite_digits.object_number);
-        comp_obj_.metainfo.identifier                           = obj_cite_digits.identifier;
-        comp_obj_.metainfo.object_number_off                    = obj_cite_digits.off;
-        comp_obj_.metainfo.o_n_book_index                       = obj_cite_digits.bkidx;
-        comp_obj_.metainfo.object_number_type                   = obj_cite_digit_type;
-        comp_obj_.metainfo.lang                                 = an_object["lang"];
-        comp_obj_.metainfo.attrib                               = an_object["attrib"];
-        comp_obj_.tags.html_segment_anchor_tag_is               = tag_in_seg["seg_lv4"];
-        comp_obj_.tags.epub_segment_anchor_tag_is               = tag_in_seg["seg_lv1to4"];
-        comp_obj_.has.inline_notes_reg                          = substantive_obj_misc_struct.has_notes_reg;
-        comp_obj_.has.inline_notes_star                         = substantive_obj_misc_struct.has_notes_star;
-        comp_obj_.has.inline_links                              = substantive_obj_misc_struct.has_links;
-        the_document_body_section                               ~= comp_obj_;
-        tag_assoc                                               = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
-        pith["block_is"]                                        = eN.blk_is.quote;
-        pith["block_state"]                                     = eN.blk_state.off;
-        pith["block_delim"]                                     = eN.blk_delim.off;
-        object_reset(an_object);
-        processing.remove("verse");
-        ++cntr;
-      } else if (pith["block_is"] == eN.blk_is.group) {
-        obj_cite_digits = ocn_emit(pith["ocn"]);
-        an_object["bookindex_nugget"]
-          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
-        bookindex_unordered_hashes
-          = bookindex_extract_hash.bookindex_nugget_hash(
-            an_object["bookindex_nugget"],
-            obj_cite_digits,
-            tag_in_seg
-          );
-        an_object["is"]                                         = "group";
-        auto comp_obj_location
-          = node_construct.node_location_emitter(
-            content_non_header,
-            tag_in_seg,
-            lev_anchor_tag,
-            tag_assoc,
-            obj_cite_digits,
-            cntr,
-            heading_ptr-1,
-            an_object["is"]
-          );
-        ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
-          = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
-        an_object["substantive"]                                = substantive_obj_misc_struct.obj_txt;
-        anchor_tag                                              = substantive_obj_misc_struct.anchor_tag;
-        comp_obj_                                               = set_object_generic("body", "body", "block", "group", an_object["substantive"], obj_cite_digits.object_number);
-        comp_obj_.metainfo.identifier                           = obj_cite_digits.identifier;
-        comp_obj_.metainfo.object_number_off                    = obj_cite_digits.off;
-        comp_obj_.metainfo.o_n_book_index                       = obj_cite_digits.bkidx;
-        comp_obj_.metainfo.object_number_type                   = obj_cite_digits.type;
-        comp_obj_.metainfo.lang                                 = an_object["lang"];
-        comp_obj_.metainfo.attrib                               = an_object["attrib"];
-        comp_obj_.tags.html_segment_anchor_tag_is               = tag_in_seg["seg_lv4"];
-        comp_obj_.tags.epub_segment_anchor_tag_is               = tag_in_seg["seg_lv1to4"];
-        comp_obj_.has.inline_notes_reg                          = substantive_obj_misc_struct.has_notes_reg;
-        comp_obj_.has.inline_notes_star                         = substantive_obj_misc_struct.has_notes_star;
-        comp_obj_.has.inline_links                              = substantive_obj_misc_struct.has_links;
-        the_document_body_section                               ~= comp_obj_;
-        tag_assoc                                               = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
-        pith["block_is"]                                        = eN.blk_is.poem;
-        pith["block_state"]                                     = eN.blk_state.off;
-        pith["block_delim"]                                     = eN.blk_delim.off;
-        object_reset(an_object);
-        processing.remove("verse");
-        ++cntr;
-      } else if (pith["block_is"] == eN.blk_is.block) {
-        obj_cite_digits = ocn_emit(pith["ocn"]);
-        an_object["bookindex_nugget"]
-          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
-        bookindex_unordered_hashes
-          = bookindex_extract_hash.bookindex_nugget_hash(
-            an_object["bookindex_nugget"],
-            obj_cite_digits,
-            tag_in_seg
-          );
-        an_object["is"]                                         = "block";
-        auto comp_obj_location
-          = node_construct.node_location_emitter(
-            content_non_header,
-            tag_in_seg,
-            lev_anchor_tag,
-            tag_assoc,
-            obj_cite_digits,
-            cntr,
-            heading_ptr-1,
-            an_object["is"]
-          );
-        ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
-          = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
-        an_object["substantive"]                                = substantive_obj_misc_struct.obj_txt;
-        // anchor_tag                                           = substantive_obj_misc_struct.anchor_tag; // check
-        comp_obj_                                               = set_object_generic("body", "body", "block", "block", an_object["substantive"], obj_cite_digits.object_number);
-        comp_obj_.metainfo.identifier                           = obj_cite_digits.identifier;
-        comp_obj_.metainfo.object_number_off                    = obj_cite_digits.off;
-        comp_obj_.metainfo.o_n_book_index                       = obj_cite_digits.bkidx;
-        comp_obj_.metainfo.object_number_type                   = obj_cite_digit_type;
-        comp_obj_.metainfo.lang                                 = an_object["lang"];
-        comp_obj_.metainfo.attrib                               = an_object["attrib"];
-        comp_obj_.tags.html_segment_anchor_tag_is               = tag_in_seg["seg_lv4"];
-        comp_obj_.tags.epub_segment_anchor_tag_is               = tag_in_seg["seg_lv1to4"];
-        comp_obj_.has.inline_notes_reg                          = substantive_obj_misc_struct.has_notes_reg;
-        comp_obj_.has.inline_notes_star                         = substantive_obj_misc_struct.has_notes_star;
-        comp_obj_.has.inline_links                              = substantive_obj_misc_struct.has_links;
-        the_document_body_section                               ~= comp_obj_;
-        pith["block_is"]                                        = eN.blk_is.block;
-        pith["block_state"]                                     = eN.blk_state.off;
-        pith["block_delim"]                                     = eN.blk_delim.off;
-        object_reset(an_object);
-        processing.remove("verse");
-        ++cntr;
-      } else if (pith["block_is"] == eN.blk_is.poem) {
-        an_object["bookindex_nugget"]
-          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
-        bookindex_unordered_hashes
-          = bookindex_extract_hash.bookindex_nugget_hash(
-            an_object["bookindex_nugget"],
-            obj_cite_digits,
-            tag_in_seg
-          );
-        an_object["is"]                                         = "verse";
-        auto comp_obj_location
-          = node_construct.node_location_emitter(
-            content_non_header,
-            tag_in_seg,
-            lev_anchor_tag,
-            tag_assoc,
-            obj_cite_digits,
-            cntr,
-            heading_ptr-1,
-            an_object["is"]
-          );
-        comp_obj_poem_ocn                                       = set_object_generic("body", "body", "block", "poem", "", obj_cite_digits.object_number);
-        comp_obj_poem_ocn.metainfo.identifier                   = obj_cite_digits.identifier;
-        comp_obj_poem_ocn.metainfo.object_number_off            = obj_cite_digits.off;
-        comp_obj_poem_ocn.metainfo.o_n_book_index               = obj_cite_digits.bkidx;
-        comp_obj_poem_ocn.metainfo.object_number_type           = obj_cite_digits.type;
-        the_document_body_section                               ~= comp_obj_poem_ocn;
-        pith["block_is"]                                        = eN.blk_is.poem;
-        pith["block_state"]                                     = eN.blk_state.off;
-        pith["block_delim"]                                     = eN.blk_delim.off;
-        object_reset(an_object);
-        processing.remove("verse");
-      } else if (pith["block_is"] == eN.blk_is.code) {
-        obj_cite_digits = ocn_emit(pith["ocn"]);
-        an_object["bookindex_nugget"]
-          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
-        bookindex_unordered_hashes
-          = bookindex_extract_hash.bookindex_nugget_hash(
-            an_object["bookindex_nugget"],
-            obj_cite_digits,
-            tag_in_seg
-          );
-        an_object["is"]                                         = "code";
-        auto comp_obj_location
-          = node_construct.node_location_emitter(
-            content_non_header,
-            tag_in_seg,
-            lev_anchor_tag,
-            tag_assoc,
-            obj_cite_digits,
-            cntr,
-            heading_ptr-1,
-            an_object["is"]
-          );
-        ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
-          = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
-        an_object["substantive"]                                = substantive_obj_misc_struct.obj_txt;
-        anchor_tag                                              = substantive_obj_misc_struct.anchor_tag;
-        comp_obj_                                               = set_object_generic("body", "body", "block", "code", an_object["substantive"], obj_cite_digits.object_number);
-        comp_obj_.metainfo.identifier                           = obj_cite_digits.identifier;
-        comp_obj_.metainfo.object_number_off                    = obj_cite_digits.off;
-        comp_obj_.metainfo.o_n_book_index                       = obj_cite_digits.bkidx;
-        comp_obj_.metainfo.object_number_type                   = obj_cite_digits.type;
-        comp_obj_.metainfo.syntax                               = an_object["syntax"];
-        comp_obj_.metainfo.attrib                               = an_object["attrib"];
-        comp_obj_.code_block.linenumbers                        = (an_object["attrib"].match(rgx.code_numbering)) ? true : false;
-        comp_obj_.tags.html_segment_anchor_tag_is               = tag_in_seg["seg_lv4"];
-        comp_obj_.tags.epub_segment_anchor_tag_is               = tag_in_seg["seg_lv1to4"];
-        comp_obj_.has.inline_notes_reg                          = substantive_obj_misc_struct.has_notes_reg;
-        comp_obj_.has.inline_notes_star                         = substantive_obj_misc_struct.has_notes_star;
-        comp_obj_.has.inline_links                              = substantive_obj_misc_struct.has_links;
-        the_document_body_section                               ~= comp_obj_;
-        pith["block_is"]                                        = eN.blk_is.code;
-        pith["block_state"]                                     = eN.blk_state.off;
-        pith["block_delim"]                                     = eN.blk_delim.off;
-        object_reset(an_object);
-        processing.remove("verse");
-        ++cntr;
-      } else if (pith["block_is"]    == eN.blk_is.table) {
-        comp_obj_ = comp_obj_.init;
-        obj_cite_digits = ocn_emit(pith["ocn"]);
-        an_object["bookindex_nugget"]
-          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
-        bookindex_unordered_hashes
-          = bookindex_extract_hash.bookindex_nugget_hash(
-            an_object["bookindex_nugget"],
-            obj_cite_digits,
-            tag_in_seg
-          );
-        an_object["is"]                                         = "table";
-        auto comp_obj_location
-          = node_construct.node_location_emitter(
-            content_non_header,
-            tag_in_seg,
-            lev_anchor_tag,
-            tag_assoc,
-            obj_cite_digits,
-            cntr,
-            heading_ptr-1,
-            an_object["is"]
-          );
-        ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
-          = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
-        an_object["substantive"]                                = substantive_obj_misc_struct.obj_txt;
-        comp_obj_                                               = comp_obj_.init;
-        comp_obj_.metainfo.ocn                                  = obj_cite_digits.object_number;
-        comp_obj_.metainfo.identifier                           = obj_cite_digits.identifier;
-        comp_obj_.metainfo.object_number_off                    = obj_cite_digits.off;
-        comp_obj_.tags.html_segment_anchor_tag_is               = tag_in_seg["seg_lv4"];
-        comp_obj_.tags.epub_segment_anchor_tag_is               = tag_in_seg["seg_lv1to4"];
-        comp_obj_.metainfo.o_n_book_index                       = obj_cite_digits.bkidx;
-        comp_obj_.metainfo.object_number_type                   = obj_cite_digits.type;
-        comp_obj_                                               = comp_obj_.flow_table_instructions(an_object["table_head"]);
-        {
-          auto _get = comp_obj_.flow_table_substantive_munge(an_object["substantive"]);
-          {
-            comp_obj_           = _get.table_object;
-            an_object["substantive"] = _get.table_substantive;
-          }
-        }
-        the_document_body_section                               ~= comp_obj_;
-        pith["block_is"]                                        = eN.blk_is.table;
-        pith["block_state"]                                     = eN.blk_state.off;
-        pith["block_delim"]                                     = eN.blk_delim.off;
-        object_reset(an_object);
-        processing.remove("verse");
-        ++cntr;
-      }
-    }
-    ST_flow_block_flag_line_empty ret;
-    {
-      ret.this_object                = an_object;
-      ret.the_document_body_section  = the_document_body_section;
-      ret.bookindex_unordered_hashes = bookindex_unordered_hashes;
-      ret.obj_cite_digits            = obj_cite_digits;
-      ret.comp_obj_                  = comp_obj_; //
-      ret.cntr                       = cntr;
-      ret.pith                       = pith;
-    }
-    return ret;
-  }
-  @system ST_flow_book_index flow_book_index_(B)(
-    char[]          line,
-    string[string]  an_object,
-    string          book_idx_tmp,
-    uint[string]    pith,
-    B               opt_action,
-  ) {
-    static auto rgx = RgxI();
-    if (auto m = line.match(rgx.book_index_item)) {                                   // match book_index
-      debug(bookindexmatch) { writefln(
-          "* [bookindex] %s\n",
-          m["bookindex"].to!string,
-        );
-      }
-      an_object["bookindex_nugget"] = m.captures[1].to!string;
-    } else if (auto m = line.match(rgx.book_index_item_open))  {                      // match open book_index
-      pith["section"] = eN.sect.book_index;
-      if (opt_action.backmatter && opt_action.section_bookindex) {
-        book_idx_tmp = m.captures[1].to!string;
-        debug(bookindexmatch) { writefln( "* [bookindex] %s\n", book_idx_tmp,); }
-      }
-    } else if (pith["section"] == eN.sect.book_index)  {                    // book_index flag set
-      if (auto m = line.match(rgx.book_index_item_close))  {
-        pith["section"] = eN.sect.unset;
-        if (opt_action.backmatter
-        && opt_action.section_bookindex) {
-          an_object["bookindex_nugget"] = book_idx_tmp ~ m.captures[1].to!string;
-          debug(bookindexmatch) { writefln( "* [bookindex] %s\n", book_idx_tmp,); }
-        }
-        book_idx_tmp = "";
-      } else {
-        if (opt_action.backmatter
-        && opt_action.section_bookindex) {
-          book_idx_tmp ~= line;
-        }
-      }
-    }
-    ST_flow_book_index ret;
-    {
-      ret.this_object    = an_object;
-      ret.pith           = pith;
-      ret.book_idx_tmp   = book_idx_tmp;
-    }
-    return ret;
-  }
-  @safe ST_flow_heading_found flow_heading_found_()(
-    char[]                line,
-    string[string]        heading_match_str,
-    string[]              _make_unmarked_headings,
-    Regex!(char)[string]  heading_match_rgx,
-    uint[string]          pith,
-  ) {
-    static auto rgx = RgxI();
-    if ((_make_unmarked_headings.length > 2)
-    && (pith["make_headings"] == eN.bi.off)) {                        // headings found
-      debug(headingsfound) { writeln(_make_unmarked_headings); }
-      debug(headingsfound) {
-        writeln(_make_unmarked_headings.length);
-        writeln(_make_unmarked_headings);
-      }
-      switch (_make_unmarked_headings.length) {
-      case 7 :
-        if (!empty(_make_unmarked_headings[6])) {
-          heading_match_str["h_4"]
-            = "^(" ~ _make_unmarked_headings[6].to!string ~ ")";
-          heading_match_rgx["h_4"]
-            = regex(heading_match_str["h_4"]);
-        }
-        goto case;
-      case 6 :
-        if (!empty(_make_unmarked_headings[5])) {
-          heading_match_str["h_3"]
-            = "^(" ~ _make_unmarked_headings[5].to!string ~ ")";
-          heading_match_rgx["h_3"]
-            = regex(heading_match_str["h_3"]);
-        }
-        goto case;
-      case 5 :
-        if (!empty(_make_unmarked_headings[4])) {
-          heading_match_str["h_2"]
-            = "^(" ~ _make_unmarked_headings[4].to!string ~ ")";
-          heading_match_rgx["h_2"]
-            = regex(heading_match_str["h_2"]);
-        }
-        goto case;
-      case 4 :
-        if (!empty(_make_unmarked_headings[3])) {
-          heading_match_str["h_1"]
-            = "^(" ~ _make_unmarked_headings[3].to!string ~ ")";
-          heading_match_rgx["h_1"]
-            = regex(heading_match_str["h_1"]);
-        }
-        goto case;
-      case 3 :
-        if (!empty(_make_unmarked_headings[2])) {
-          heading_match_str["h_D"]
-            = "^(" ~ _make_unmarked_headings[2].to!string ~ ")";
-          heading_match_rgx["h_D"]
-            = regex(heading_match_str["h_D"]);
-        }
-        goto case;
-      case 2 :
-        if (!empty(_make_unmarked_headings[1])) {
-          heading_match_str["h_C"]
-            = "^(" ~ _make_unmarked_headings[1].to!string ~ ")";
-          heading_match_rgx["h_C"]
-            = regex(heading_match_str["h_C"]);
-        }
-        goto case;
-      case 1 :
-        if (!empty(_make_unmarked_headings[0])) {
-          heading_match_str["h_B"]
-            = "^(" ~ _make_unmarked_headings[0].to!string ~ ")";
-          heading_match_rgx["h_B"]
-            = regex(heading_match_str["h_B"]);
-        }
-        break;
-      default:
-        break;
-      }
-      pith["make_headings"] = eN.bi.on;
-    }
-    ST_flow_heading_found ret;
-    {
-      ret.heading_match_str = heading_match_str;
-      ret.heading_match_rgx = heading_match_rgx;
-      ret.pith              = pith;
-    }
-    return ret;
-  }
-  @safe ST_flow_heading_make_set flow_heading_make_set_()(
-               char[]                line,
-               int[string]           line_occur,
-    return ref Regex!(char)[string]  heading_match_rgx,
-    return ref uint[string]          pith,
-  ) {
-    if (pith["make_headings"] == eN.bi.on
-      && (line_occur["para"] == eN.bi.off
-      && line_occur["heading"] == eN.bi.off)
-      && pith["txt_is"] == eN.txt_is.off
-    ) {                             // heading make set
-      if (line.matchFirst(heading_match_rgx["h_B"])) {
-        line = "B~ " ~ line;
-        debug(headingsfound) { writeln(line); }
-      }
-      if (line.matchFirst(heading_match_rgx["h_C"])) {
-        line = "C~ " ~ line;
-        debug(headingsfound) { writeln(line); }
-      }
-      if (line.matchFirst(heading_match_rgx["h_D"])) {
-        line = "D~ " ~ line;
-        debug(headingsfound) { writeln(line); }
-      }
-      if (line.matchFirst(heading_match_rgx["h_1"])) {
-        line = "1~ " ~ line;
-        debug(headingsfound) { writeln(line); }
-      }
-      if (line.matchFirst(heading_match_rgx["h_2"])) {
-        line = "2~ " ~ line;
-        debug(headingsfound) { writeln(line); }
-      }
-      if (line.matchFirst(heading_match_rgx["h_3"])) {
-        line = "3~ " ~ line;
-        debug(headingsfound) { writeln(line); }
-      }
-      if (line.matchFirst(heading_match_rgx["h_4"])) {
-        line = "4~ " ~ line;
-        debug(headingsfound) { writeln(line); }
-      }
-    }
-    ST_flow_heading_make_set ret;
-    {
-      ret.line           = line;
-      ret.pith           = pith;
-      ret.this_object    = an_object;
-    }
-    return ret;
-  }
-  @safe auto flow_heading_matched_(CMM)(
-    char[]          line,
-    string[string]  an_object,
-    int[string]     line_occur,
-    string          an_object_key,
-    int[string]     lv,
-    int[string]     collapsed_lev,
-    uint[string]    pith,
-    CMM             conf_make_meta,
-  ) {
-    static auto rgx = RgxI();
-    static auto mkup = InlineMarkup();
-    if (auto m = line.match(rgx.headings)) {                                      // heading match
-      ++line_occur["heading"];
-      pith["txt_is"]           = eN.txt_is.heading;
-      if (line.match(rgx.heading_seg_and_above)) {
-        pith["section"]        = eN.sect.unset;
-      }
-      an_object[an_object_key] ~= line ~= "\n";
-      an_object["lev"] ~= m.captures[1];
-      assertions_doc_structure(an_object, an_object_key, lv); // includes most of the logic for collapsed levels
-      switch (an_object["lev"]) {
-      case "A":                                // Title set
-        if ((an_object[an_object_key].match(rgx.variable_doc_title_author_date))
-        || (an_object[an_object_key].match(rgx.variable_doc_title)
-        && an_object[an_object_key].match(rgx.variable_doc_author)
-        && an_object[an_object_key].match(rgx.variable_doc_date))) {
-          an_object[an_object_key] = an_object[an_object_key]
-            .replaceFirst(rgx.variable_doc_title_author_date,
-              (conf_make_meta.meta.title_full
-              ~ mkup.br_line_inline
-              ~ conf_make_meta.meta.creator_author
-              ~ " (" ~ (conf_make_meta.meta.date_published.replaceFirst(regex(r"(?:-00)+"),"")) ~ ")"))
-            .replaceFirst(rgx.variable_doc_title,
-              (conf_make_meta.meta.title_full ~ mkup.br_line_inline))
-            .replaceFirst(rgx.variable_doc_author,
-              conf_make_meta.meta.creator_author)
-            .replaceFirst(rgx.variable_doc_date,
-              " (" ~ (conf_make_meta.meta.date_published.replaceFirst(regex(r"(?:-00)+"),"")) ~ ")");
-        } else if ((an_object[an_object_key].match(rgx.variable_doc_title_author))
-        || (an_object[an_object_key].match(rgx.variable_doc_title)
-        && an_object[an_object_key].match(rgx.variable_doc_author))) {
-          an_object[an_object_key] = an_object[an_object_key]
-            .replaceFirst(rgx.variable_doc_title_author_date,
-              (conf_make_meta.meta.title_full
-              ~ mkup.br_line_inline
-              ~ conf_make_meta.meta.creator_author))
-            .replaceFirst(rgx.variable_doc_title,
-              (conf_make_meta.meta.title_full ~ mkup.br_line_inline))
-            .replaceFirst(rgx.variable_doc_author,
-              conf_make_meta.meta.creator_author);
-        } else if (an_object[an_object_key].match(rgx.variable_doc_title)) {
-          an_object[an_object_key] = an_object[an_object_key]
-            .replaceFirst(rgx.variable_doc_title,
-              conf_make_meta.meta.title_full);
-        }
-        collapsed_lev["h0"] = 0;
-        an_object["lev_collapsed_number"]
-          = collapsed_lev["h0"].to!string;
-        lv["lv"] = DocStructMarkupHeading.h_sect_A;
-        ++lv["h0"];
-        lv["h1"] = eN.bi.off;
-        lv["h2"] = eN.bi.off;
-        lv["h3"] = eN.bi.off;
-        lv["h4"] = eN.bi.off;
-        lv["h5"] = eN.bi.off;
-        lv["h6"] = eN.bi.off;
-        lv["h7"] = eN.bi.off;
-        goto default;
-      case "B":
-        collapsed_lev["h1"] = collapsed_lev["h0"] + 1;
-        an_object["lev_collapsed_number"]
-          = collapsed_lev["h1"].to!string;
-        lv["lv"] = DocStructMarkupHeading.h_sect_B;
-        ++lv["h1"];
-        lv["h2"] = eN.bi.off;
-        lv["h3"] = eN.bi.off;
-        lv["h4"] = eN.bi.off;
-        lv["h5"] = eN.bi.off;
-        lv["h6"] = eN.bi.off;
-        lv["h7"] = eN.bi.off;
-        goto default;
-      case "C":
-        collapsed_lev["h2"] = collapsed_lev["h1"] + 1;
-        an_object["lev_collapsed_number"]
-          = collapsed_lev["h2"].to!string;
-        lv["lv"] = DocStructMarkupHeading.h_sect_C;
-        ++lv["h2"];
-        lv["h3"] = eN.bi.off;
-        lv["h4"] = eN.bi.off;
-        lv["h5"] = eN.bi.off;
-        lv["h6"] = eN.bi.off;
-        lv["h7"] = eN.bi.off;
-        goto default;
-      case "D":
-        collapsed_lev["h3"] = collapsed_lev["h2"] + 1;
-        an_object["lev_collapsed_number"]
-          = collapsed_lev["h3"].to!string;
-        lv["lv"] = DocStructMarkupHeading.h_sect_D;
-        ++lv["h3"];
-        lv["h4"] = eN.bi.off;
-        lv["h5"] = eN.bi.off;
-        lv["h6"] = eN.bi.off;
-        lv["h7"] = eN.bi.off;
-        goto default;
-      case "1":
-        if (lv["h3"] > eN.bi.off) {
-          collapsed_lev["h4"] = collapsed_lev["h3"] + 1;
-        } else if (lv["h2"] > eN.bi.off) {
-          collapsed_lev["h4"] = collapsed_lev["h2"] + 1;
-        } else if (lv["h1"] > eN.bi.off) {
-          collapsed_lev["h4"] = collapsed_lev["h1"] + 1;
-        } else if (lv["h0"] > eN.bi.off) {
-          collapsed_lev["h4"] = collapsed_lev["h0"] + 1;
-        }
-        an_object["lev_collapsed_number"]
-          = collapsed_lev["h4"].to!string;
-        lv["lv"] = DocStructMarkupHeading.h_text_1;
-        ++lv["h4"];
-        lv["h5"] = eN.bi.off;
-        lv["h6"] = eN.bi.off;
-        lv["h7"] = eN.bi.off;
-        goto default;
-      case "2":
-        if (lv["h5"] > eN.bi.off) {
-          an_object["lev_collapsed_number"]
-            = collapsed_lev["h5"].to!string;
-        } else if (lv["h4"] > eN.bi.off) {
-          collapsed_lev["h5"] = collapsed_lev["h4"] + 1;
-          an_object["lev_collapsed_number"]
-            = collapsed_lev["h5"].to!string;
-        }
-        lv["lv"] = DocStructMarkupHeading.h_text_2;
-        ++lv["h5"];
-        lv["h6"] = eN.bi.off;
-        lv["h7"] = eN.bi.off;
-        goto default;
-      case "3":
-        if (lv["h6"] > eN.bi.off) {
-          an_object["lev_collapsed_number"]
-            = collapsed_lev["h6"].to!string;
-        } else if (lv["h5"] > eN.bi.off) {
-          collapsed_lev["h6"] = collapsed_lev["h5"] + 1;
-          an_object["lev_collapsed_number"]
-            = collapsed_lev["h6"].to!string;
-        }
-        lv["lv"] = DocStructMarkupHeading.h_text_3;
-        ++lv["h6"];
-        lv["h7"] = eN.bi.off;
-        goto default;
-      case "4":
-        if (lv["h7"] > eN.bi.off) {
-          an_object["lev_collapsed_number"]
-            = collapsed_lev["h7"].to!string;
-        } else if (lv["h6"] > eN.bi.off) {
-          collapsed_lev["h7"] = collapsed_lev["h6"] + 1;
-          an_object["lev_collapsed_number"]
-            = collapsed_lev["h7"].to!string;
-        }
-        lv["lv"] = DocStructMarkupHeading.h_text_4;
-        ++lv["h7"];
-        goto default;
-      default:
-        an_object["lev_markup_number"] = lv["lv"].to!string;
-      }
-      an_object["dummy_heading_status"] = (pith["dummy_heading_status"] == eN.bi.off) ? "f" : "t";
-      debug(heading) { writeln(line.strip); }
-    }
-    struct ST_flow_heading_matched {
-      string[string]  this_object;
-      int[string]     line_occur;
-      string          an_object_key;
-      int[string]     lv;
-      int[string]     collapsed_lev;
-      uint[string]    pith;
-      CMM             conf_make_meta;
-    }
-    ST_flow_heading_matched ret;
-    {
-      ret.this_object    = an_object;
-      ret.line_occur     = line_occur;
-      ret.an_object_key  = an_object_key;
-      ret.lv             = lv;
-      ret.collapsed_lev  = collapsed_lev;
-      ret.pith           = pith;
-      ret.conf_make_meta = conf_make_meta;
-    }
-    return ret;
-  }
-  @safe ST_flow_para_match flow_para_match_()(
-    char[]         line,
-    string[string]  an_object,
-    string          an_object_key,
-    int[string]     indent,
-    bool            bullet,
-    uint[string]    pith,
-    int[string]     line_occur,
-  ) {
-    static auto rgx = RgxI();
-    if (line_occur["para"] == eN.bi.off) {
-      line = font_faces_line(line);
-      // para matches
-      pith["txt_is"]           = eN.txt_is.para;
-      an_object[an_object_key] ~= line;
-      indent = [
-        "hang_position" : 0,
-        "base_position" : 0,
-      ];
-      bullet = false;
-      if (auto m = line.matchFirst(rgx.para_indent)) {
-        debug(paraindent) { writeln(line); }
-        indent["hang_position"] = (m["indent"]).to!int;
-        indent["base_position"] = (m["indent"]).to!int;
-      } else if (line.matchFirst(rgx.para_bullet)) {
-        debug(parabullet) { writeln(line); }
-        bullet = true;
-      } else if (auto m = line.matchFirst(rgx.para_indent_hang)) {
-        debug(paraindenthang) { writeln(line); }
-        indent = [
-          "hang_position" : (m["hang"]).to!int,
-          "base_position" : (m["indent"]).to!int,
-        ];
-      } else if (auto m = line.matchFirst(rgx.para_bullet_indent)) {
-        debug(parabulletindent) { writeln(line); }
-        indent = [
-          "hang_position" : (m["indent"]).to!int,
-          "base_position" : (m["indent"]).to!int,
-        ];
-        bullet = true;
-      }
-      ++line_occur["para"];
-    }
-    ST_flow_para_match ret;
-    {
-      ret.pith            = pith;
-      ret.this_object     = an_object;
-      ret.this_object_key = an_object_key;
-      ret.indent          = indent;
-      ret.bullet          = bullet;
-      ret.line_occur      = line_occur;
-    }
-    return ret;
-  }
-  @safe char[] font_faces_line()(
-    char[]  textline,
-  ) {
-    static auto rgx = RgxI();
-    static auto mkup = InlineMarkup();
-    if (textline.match(rgx.inline_faces_line)) {
-      textline = textline
-        .replaceFirst(rgx.inline_emphasis_line,
-          format(q"┃%s%s%s%s%s%s%s┃",
-            mkup.ff_i, mkup.emph, mkup.ff_o, "$1", mkup.ff_c, mkup.emph, "$2"))
-        .replaceFirst(rgx.inline_bold_line,
-          format(q"┃%s%s%s%s%s%s%s┃",
-            mkup.ff_i, mkup.bold, mkup.ff_o, "$1", mkup.ff_c, mkup.bold, "$2"))
-        .replaceFirst(rgx.inline_underscore_line,
-          format(q"┃%s%s%s%s%s%s%s┃",
-            mkup.ff_i, mkup.underscore, mkup.ff_o, "$1", mkup.ff_c, mkup.underscore, "$2"))
-        .replaceFirst(rgx.inline_italics_line,
-          format(q"┃%s%s%s%s%s%s%s┃",
-            mkup.ff_i, mkup.italic,  mkup.ff_o, "$1", mkup.ff_c, mkup.italic, "$2"));
-    }
-    return textline;
-  }
-  @safe ObjGenericComposite flow_table_instructions(H)(
-    ObjGenericComposite  table_object,
-    H                    table_head,
-  ) {
-    static auto rgx = RgxI();
-    table_object.metainfo.is_of_part        = "body";
-    table_object.metainfo.is_of_section     = "body";
-    table_object.metainfo.is_of_type        = "block";
-    table_object.metainfo.is_a              = "table";
-    table_object.has.inline_notes_reg       = false;
-    table_object.has.inline_notes_star      = false;
-    table_object.has.inline_links           = false;
-    if (auto m = table_head.matchFirst(rgx.table_head_instructions)) {
-      table_object.table.heading
-        = ((m["c_heading"].length > 0) && (m["c_heading"] == "h")) ? true : false;
-      table_object.table.number_of_columns
-        = ((m["c_num"].length > 0) && (m["c_num"].to!int > 0)) ? m["c_num"].to!int : 0;
-      foreach (cw; m["c_widths"].matchAll(rgx.table_col_widths)) {
-        auto x = cw.hit.matchFirst(rgx.table_col_widths_and_alignment);
-        table_object.table.column_widths ~= x["width"].to!int;
-        table_object.table.column_aligns ~= (x["align"].empty) ? "" : x["align"];
-      }
-    }
-    return table_object;
-  }
-  @safe ST_flow_table_array_munge flow_table_array_munge()(
-    ObjGenericComposite  table_object,
-    string[][]           table_array,
-  ) {
-    static auto rgx = RgxI();
-    static auto mng = InlineMarkup();
-    string _table_substantive;
-    ulong col_num;
-    ulong col_num_;
-    ulong col_num_chk = 0;
-    foreach(idx_r, row; table_array) {
-      debug(table_dev) { writeln("row ", idx_r); }
-      col_num_ = 0;
-      if (col_num == 0
-      || col_num < row.length) {
-        col_num = row.length;
-      }
-      if (col_num_chk == 0) {
-        col_num_chk = col_num;
-      } else if (col_num == 1) {
-        debug(table_dev) { writeln("table note: "); }
-      } else if (col_num_chk != col_num) {
-        debug(table_dev) { writeln("warning irregular number of columns: ", col_num_chk, " != ", col_num); }
-      } else {
-      }
-      foreach(idx_c, col; row) {
-        debug(table_dev) { write(idx_c, ", "); }
-        col_num_ = idx_c;
-        _table_substantive ~= col ~ mng.tc_s;
-        if (idx_r == 0 && table_object.table.heading) {
-        } else if (col.match(rgx.numeric_col) && idx_r == 1) { // conditions reversed to avoid: gdc compiled program run segfault
-          if ((table_object.table.column_aligns.length > idx_c)
-          && (table_object.table.column_aligns[idx_c].matchFirst(rgx.table_col_align_match))) {
-            table_object.table.column_aligns[idx_c] = table_object.table.column_aligns[idx_c];
-          } else if (table_object.table.column_aligns.length > idx_c) {
-            table_object.table.column_aligns[idx_c] = "r";
-          } else {
-            table_object.table.column_aligns ~= "r";
-          }
-        } else if (idx_r == 1) {
-          if ((table_object.table.column_aligns.length > idx_c)
-          && (table_object.table.column_aligns[idx_c].matchFirst(rgx.table_col_align_match))) {
-            table_object.table.column_aligns[idx_c] = table_object.table.column_aligns[idx_c];
-          } else if (table_object.table.column_aligns.length > idx_c) {
-            table_object.table.column_aligns[idx_c] = "l";
-          } else {
-            table_object.table.column_aligns ~= "l";
-          }
-        }
-      }
-      debug(table_dev) { writeln(""); }
-      if (col_num_chk > 0 && (col_num != col_num_chk)) {
-      } else if (col_num == col_num_chk){
-      } else {
-        col_num_chk = col_num;
-      }
-      _table_substantive = _table_substantive.replaceFirst(rgx.table_col_separator_nl, "\n");
-    }
-    if (table_object.table.number_of_columns != col_num) {
-      if (table_object.table.number_of_columns == 0) {
-        table_object.table.number_of_columns = (col_num).to!int;
-      } else {
-        debug(table_dev) { writeln(table_object.table.number_of_columns, " != ", col_num); }
-      }
-    }
-    if (table_object.table.number_of_columns == 0
-    && table_object.table.column_widths.length > 0) {
-      writeln(__LINE__, " ERROR");
-    }
-    if (table_object.table.number_of_columns > 0
-    && table_object.table.column_widths.length == 0) {
-      double col_w = (100.00 / table_object.table.number_of_columns);
-      foreach (i; 0..table_object.table.number_of_columns) {
-        table_object.table.column_widths ~= col_w;
-      }
-    } else if (table_object.table.number_of_columns
-    != table_object.table.column_widths.length) {
-      debug(table_dev) { writeln(m.hit); } // further logic required
-      if (table_object.table.number_of_columns > table_object.table.column_widths.length) {
-        double col_w = (100.00 - (table_object.table.column_widths).sum)
-          / (table_object.table.number_of_columns - table_object.table.column_widths.length);
-        foreach (i; 0..table_object.table.column_widths.length) {
-          table_object.table.column_widths ~= col_w;
-        }
-        foreach (i; 0..(table_object.table.number_of_columns - table_object.table.column_widths.length)) {
-          table_object.table.column_widths ~= col_w;
-        }
-      } else if (table_object.table.number_of_columns < table_object.table.column_widths.length) {
-        writeln(__LINE__, " warning, ERROR");
-      }
-    }
-    if (table_object.table.column_widths.sum > 101
-    || table_object.table.column_widths.sum < 95 ) {
-      writeln("sum: ", table_object.table.column_widths.sum,
-        ", array: ", table_object.table.column_widths,
-        ", cols: ", table_object.table.number_of_columns);
-      writeln(_table_substantive);
-    }
-    debug(table_res) {
-      writeln("aligns: ", table_object.table.column_aligns, "\n",
-        "no. of columns: ", table_object.table.number_of_columns, "\n",
-        "col widths: ", table_object.table.column_widths,
-          " sum: ", table_object.table.column_widths.sum, "\n",
-        _table_substantive);
-    }
-    table_object.text = _table_substantive;
-    ST_flow_table_array_munge ret;
-    {
-      ret.table_object      = table_object;
-      ret.table_array       = table_array;
-    }
-    return ret;
-  }
-  @system ST_flow_table_substantive_munge flow_table_substantive_munge()(
-    ObjGenericComposite  table_object,
-    string               table_substantive,
-  ) {
-    static auto rgx = RgxI();
-    static auto munge = ObjInlineMarkupMunge();
-    string[] _table_rows = (table_substantive).split(rgx.table_row_delimiter);
-    string[] _table_cols;
-    string[][] _table_array;
-    foreach(col; _table_rows) {
-      _table_cols = col.split(rgx.table_col_delimiter);
-      _table_array ~= _table_cols;
-    }
-    {
-      auto _get = table_object.flow_table_array_munge(_table_array);
-      {
-        table_object = _get.table_object;
-        _table_array = _get.table_array; // what do you do with this? how is this passed down?
-      }
-    }
-    ST_flow_table_substantive_munge ret;
-    {
-      ret.table_object      = table_object;
-      ret.table_substantive = table_substantive; // has anything been changed here?
-    }
-    return ret;
-  }
-  @system ST_flow_table_substantive_munge flow_table_substantive_munge_special()(
-    ObjGenericComposite  table_object,
-    string               table_substantive,
-  ) {
-    static auto rgx = RgxI();
-    static auto munge = ObjInlineMarkupMunge();
-    string[] _table_rows = (table_substantive).split(rgx.table_row_delimiter_special);
-    string[] _table_cols;
-    string[][] _table_array;
-    foreach(col; _table_rows) {
-      _table_cols = col.split(rgx.table_col_delimiter_special);
-      _table_array ~= _table_cols;
-    }
-    {
-      auto _get = table_object.flow_table_array_munge(_table_array);
-      {
-        table_object = _get.table_object;
-        _table_array = _get.table_array;
-      }
-    }
-    ST_flow_table_substantive_munge ret;
-    {
-      ret.table_object      = table_object;
-      ret.table_substantive = table_substantive;
-    }
-    return ret;
-  }
-  // abstraction functions ↑
-  // ↓ abstraction function emitters
-  @safe pure struct OCNemitter {
-    int ocn_digit, ocn_object_number, ocn_on_, ocn_off_, ocn_bkidx, ocn_bkidx_;
-    string object_identifier;
-    bool ocn_is_off;
-    @safe auto ocn_emitter(int ocn_status_flag) {
-      OCNset ocn;
-      assert(ocn_status_flag <= eN.ocn.reset);
-      ocn_object_number              = ocn_bkidx = 0;
-      object_identifier              = "";
-      ocn_is_off                     = false;
-      switch(ocn_status_flag) with (eN.ocn) {
-      case reset:
-        ocn_digit                    = ocn_on_             = 1;
-        object_identifier            = "1";
-        ocn_is_off                   = false;
-        ocn_off_                     = ocn_bkidx_ = 0;
-        break;
-      case on:
-        ocn_digit                    = ocn_object_number   = ++ocn_on_;
-        object_identifier            = ocn_digit.to!string;
-        ocn_is_off                   = false;
-        break;
-      case off:
-        ocn_digit                    = 0;
-        ocn_off_                     = ++ocn_off_;
-        object_identifier            = "a" ~ ocn_off_.to!string;
-        ocn_is_off                   = true;
-        break;
-      case bkidx:
-        ocn_bkidx                    = ++ocn_bkidx_;
-        break;
-      case closing: // unused?
-        break;
-      default:
-        ocn_digit                    = 0;
-      }
-      assert(ocn_digit >= 0);
-      ocn.digit                      = ocn_digit;
-      ocn.object_number              = ocn_object_number; // difference between .object_number and .digit?
-      ocn.identifier                 = object_identifier;
-      ocn.off                        = ocn_is_off;
-      ocn.bkidx                      = ocn_bkidx;
-      ocn.type                       = ocn_status_flag;
-      return ocn;
-    }
-    invariant() {
-    }
-  }
-  @safe ObjGenericComposite set_object_heading()(
-    string level,
-    string part,
-    string section,
-    string text,
-  ) {
-    ObjGenericComposite comp_obj;
-    comp_obj                                                = comp_obj.init;
-    comp_obj.metainfo.is_of_part                            = part;
-    comp_obj.metainfo.is_of_section                         = section;
-    comp_obj.metainfo.is_of_type                            = "para";
-    comp_obj.metainfo.is_a                                  = "heading";
-    comp_obj.text                                           = text;
-    comp_obj.metainfo.ocn                                   = 0;
-    if (level == "lev1") {
-      comp_obj.metainfo.heading_lev_markup                  = 1;
-      comp_obj.metainfo.heading_lev_collapsed               = 1;
-      comp_obj.metainfo.parent_ocn                          = 1;
-      comp_obj.metainfo.parent_lev_markup                   = 0;
-    } else if (level == "lev4") {
-      comp_obj.metainfo.heading_lev_markup                  = 4;
-      comp_obj.metainfo.heading_lev_collapsed               = 1;
-      comp_obj.metainfo.parent_ocn                          = 1;
-      comp_obj.metainfo.parent_lev_markup                   = 0;
-      comp_obj.metainfo.dom_structure_markedup_tags_status  = [ 1, 1, 0, 0, 1, 0, 0, 0]; // KEEP
-      comp_obj.metainfo.dom_structure_collapsed_tags_status = [ 1, 1, 1, 0, 0, 0, 0, 0]; // KEEP
-    }
-    return comp_obj;
-  }
-  @safe ObjGenericComposite set_object_generic()(
-    string part,
-    string section,
-    string type,
-    string is_a,
-    string text,
-    int ocn,
-  ) {
-    ObjGenericComposite comp_obj;
-    comp_obj                                                = comp_obj.init;
-    comp_obj.metainfo.is_of_part                            = part;
-    comp_obj.metainfo.is_of_section                         = section;
-    comp_obj.metainfo.is_of_type                            = type;
-    comp_obj.metainfo.is_a                                  = is_a;
-    comp_obj.text                                           = text;
-    comp_obj.metainfo.ocn                                   = ocn;
-    return comp_obj;
-  }
-  @safe static struct ObjInlineMarkupMunge {
-    string[string] obj_txt;
-    int n_foot, n_foot_reg, n_foot_sp_asterisk, n_foot_sp_plus;
-    string asterisks_, plus_;
-    string obj_txt_out, tail, note;
-    static auto rgx = RgxI();
-    static auto mkup = InlineMarkup();
-    int stage_reset_note_numbers = true;
-    private auto initialize_note_numbers() {
-      n_foot                          = 0;
-      n_foot_reg                      = 0;
-      n_foot_sp_asterisk              = 0;
-      n_foot_sp_plus                  = 0;
-    }
-    @safe static auto images()(string obj_txt_in) {
-      static auto mng = InlineMarkup();
-      // url matched
-      obj_txt_in = obj_txt_in.replaceAll(rgx.inline_notes_al_special, ""); // TODO reinstate when special footnotes are implemented
-      if (obj_txt_in.match(rgx.smid_image_generic)) {                            // images with and without links
-        debug(images) { writeln("Image: ", obj_txt_in); }
-        if (obj_txt_in.match(rgx.smid_image_with_dimensions)) {
-          obj_txt_in = obj_txt_in
-            .replaceAll(rgx.smid_image_with_dimensions, ("$1" ~ mkup.img ~ "$2,w$3h$4 " ~ "$5"))
-            .replaceAll(rgx.smid_image_delimit, ("$1"
-              ~ mkup.lnk_o ~ "$2".strip ~ mkup.lnk_c
-              ~ mkup.url_o ~ mkup.url_c));
-          debug(images) { writeln("IMAGE with size: ", obj_txt_in); }
-        } else if (obj_txt_in.match(rgx.smid_image)) {
-          obj_txt_in = obj_txt_in
-            .replaceAll(rgx.smid_image, ("$1" ~ mkup.img ~ "$2,w0h0" ~ "$3"))
-            .replaceAll(rgx.smid_image_delimit, ("$1"
-              ~ mkup.lnk_o ~ "$2".strip ~ mkup.lnk_c
-              ~ mkup.url_o ~ mkup.url_c));
-          debug(images) { writeln("IMAGE: ", obj_txt_in); } // decide on representation
-        }
-      }
-      return obj_txt_in;
-    }
-    @safe ST_txtPlusHasFootnotes footnotes_endnotes_markup_and_number_or_stars()(string obj_txt_in, bool reset_note_numbers) {
-      // endnotes (regular)
-      bool flg_notes_reg  = false;
-      bool flg_notes_star = false;
-      bool flg_notes_plus = false;
-      obj_txt_in = obj_txt_in.replaceAll(
-        rgx.inline_notes_curly,
-        (mkup.en_a_o ~ " $1" ~ mkup.en_a_c)
-      );
-      if (!(stage_reset_note_numbers) && reset_note_numbers) {
-        stage_reset_note_numbers = true;
-      }
-      obj_txt_out = "";
-      if (obj_txt_in.match(rgx.inline_notes_al_gen)) {
-        string[] _tmp_txt;
-        foreach (x; obj_txt_in.split("\n")) {
-          if (auto m = x.matchAll(rgx.inline_text_and_note_al_)) {
-            if (stage_reset_note_numbers) {
-              n_foot                  = 0;
-              n_foot_reg              = 0;
-              n_foot_sp_asterisk      = 0;
-              n_foot_sp_plus          = 0;
-            }
-            stage_reset_note_numbers = false;
-            foreach(n; m) {
-              if (n.hit.to!string.match(rgx.inline_al_delimiter_open_symbol_star)) {
-                flg_notes_star =  true;
-                ++n_foot_sp_asterisk;
-                asterisks_ = "*";
-                n_foot = n_foot_sp_asterisk;
-                _tmp_txt ~= n.hit.to!string.replaceFirst(
-                  rgx.inline_al_delimiter_open_symbol_star,
-                  (mkup.en_a_o ~ replicate(asterisks_, n_foot_sp_asterisk) ~ " ")
-                );
-              } else if (n.hit.to!string.match(rgx.inline_al_delimiter_open_symbol_plus)) {
-                flg_notes_plus =  true;
-                ++n_foot_sp_plus;
-                plus_ = "*";
-                n_foot = n_foot_sp_plus;
-                _tmp_txt ~= n.hit.to!string.replaceFirst(
-                  rgx.inline_al_delimiter_open_symbol_plus,
-                  (mkup.en_a_o ~ replicate(plus_, n_foot_sp_plus) ~ " ")
-                );
-              } else if (n.hit.to!string.matchFirst(rgx.inline_al_delimiter_open_regular)) {
-                string _tmp_str = n.hit.to!string;
-                flg_notes_reg =  true;
-                foreach (q; n.hit.to!string.matchAll(rgx.inline_al_delimiter_open_regular)) {
-                  ++n_foot_reg;
-                  n_foot = n_foot_reg;
-                  _tmp_str = replaceFirst!(m => mkup.en_a_o ~ n_foot.to!string ~ " ")
-                    (_tmp_str, rgx.inline_al_delimiter_open_regular);
-                }
-                _tmp_txt ~= _tmp_str;
-              } else {
-                _tmp_txt ~= n.hit.to!string;
-              }
-            }
-            obj_txt_out = _tmp_txt.join("\n");
-          }
-        }
-      } else {
-        obj_txt_out = obj_txt_in;
-      }
-      ST_txtPlusHasFootnotes ret;
-      {
-        ret.obj_txt            = obj_txt_out;
-        ret.has_notes_reg      = flg_notes_reg;
-        ret.has_notes_star     = flg_notes_star;
-        ret.has_notes_plus     = flg_notes_plus;
-      }
-      return ret;
-    }
-    @safe private ST_txtPlusHasFootnotesUrlsImages object_notes_and_links_()(
-      string obj_txt_in,
-      bool reset_note_numbers = false
-    ) {
-      obj_txt_out = "";
-      bool urls = false;
-      bool images_without_dimensions = false;
-      tail = "";
-      // special endnotes
-      obj_txt_in = obj_txt_in.replaceAll(
-        rgx.inline_notes_curly_sp_asterisk,
-        (mkup.en_a_o ~ "*" ~ " $1" ~ mkup.en_a_c)
-      );
-      obj_txt_in
-        = obj_txt_in.replaceAll(
-          rgx.inline_notes_curly_sp_plus,
-          (mkup.en_a_o ~ "+" ~ " $1" ~ mkup.en_a_c)
-        );
-      // image matched
-      if (obj_txt_in.match(rgx.smid_image_generic)) {
-        obj_txt_in = images(obj_txt_in);
-        if (obj_txt_in.match(rgx.smid_mod_image_without_dimensions)) {
-          images_without_dimensions = true;
-        }
-      }
-      // url matched
-      if (obj_txt_in.match(rgx.smid_inline_url)) {
-        urls = true;
-        obj_txt_in = obj_txt_in.links_and_images;
-      }
-      if (auto m = obj_txt_in.match(rgx.para_inline_link_anchor)) {
-        obj_txt_in = obj_txt_in
-          .replaceAll(rgx.para_inline_link_anchor, "┃$1┃");
-      }
-      ST_txtPlusHasFootnotes ftn = footnotes_endnotes_markup_and_number_or_stars(obj_txt_in, reset_note_numbers);
-      obj_txt_out = ftn.obj_txt;
-      debug(footnotes) { writeln(obj_txt_out, tail); }
-      obj_txt_out = obj_txt_out ~ tail;
-      debug(footnotesdone) {
-        foreach(m; matchAll(obj_txt_out, (mkup.en_a_o ~ `\s*(.+?)` ~ mkup.en_a_c))) {
-          writeln(m[1]);
-          writeln(m.hit);
-        }
-      }
-      ST_txtPlusHasFootnotesUrlsImages ret;
-      {
-        ret.obj_txt                       = obj_txt_out;
-        ret.has_notes_reg                 = ftn.has_notes_reg;
-        ret.has_notes_star                = ftn.has_notes_star;
-        ret.has_notes_plus                = ftn.has_notes_plus;
-        ret.has_urls                      = urls;
-        ret.has_images_without_dimensions = images_without_dimensions;
-      }
-      return ret;
-    }
-    @safe private ST_txtPlusHasFootnotesUrlsImages object_only_()(
-      string obj_txt_in,
-      bool reset_note_numbers = false
-    ) {
-      ST_txtPlusHasFootnotesUrlsImages ret;
-      {
-        ret.obj_txt                       = obj_txt_in;
-        ret.has_notes_reg                 = false;
-        ret.has_notes_star                = false;
-        ret.has_notes_plus                = false;
-        ret.has_urls                      = false;
-        ret.has_images_without_dimensions = false;
-      }
-      return ret;
-    }
-    ST_txtPlusHasFootnotesUrlsImages init() {
-      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_("");
-      return ret;
-    }
-    invariant() {
-    }
-    @safe ST_txtPlusHasFootnotesUrlsImages munge_heading()(
-      string obj_txt_in,
-      bool reset_note_numbers = false
-    ) {
-      obj_txt["munge"] = obj_txt_in
-       .replaceFirst(rgx.headings, "")
-       .replaceFirst(rgx.object_number_off_all, "")
-       .replaceFirst(rgx.markup_inline_linebreak, mkup.br_line_inline)
-       .strip;
-      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt["munge"], reset_note_numbers);
-      debug(munge) { writeln(__LINE__); writeln(obj_txt_in); writeln(__LINE__); writeln(obj_txt["munge"].to!string); }
-      return ret;
-    }
-    invariant() {
-    }
-    @safe ST_txtPlusHasFootnotesUrlsImages munge_para()(string obj_txt_in) {
-      obj_txt["munge"] = (obj_txt_in)
-        .replaceFirst(rgx.para_attribs, "")
-        .replaceFirst(rgx.object_number_off_all, "")
-        .replaceFirst(rgx.markup_inline_linebreak, mkup.br_line_inline);
-      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt["munge"]);
-      debug(munge) { writeln(__LINE__); writeln(obj_txt_in);
-        writeln(__LINE__);
-        writeln(obj_txt["munge"].to!string);
-      }
-      return ret;
-    }
-    @safe ST_txtPlusHasFootnotesUrlsImages munge_quote()(string obj_txt_in) {
-      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt_in.split("\n\n").join(" \\\\\n \\\\\n"));
-      return ret;
-    }
-    invariant() {
-    }
-    @safe ST_txtPlusHasFootnotesUrlsImages munge_group(string obj_txt_in) {
-      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt_in.split("\n\n").join("\n" ~ mkup.br_line_spaced ~ "\n"));
-      return ret;
-    }
-    invariant() {
-    }
-    @safe ST_txtPlusHasFootnotesUrlsImages munge_block()(string obj_txt_in) {
-      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt_in);
-      return ret;
-    }
-    invariant() {
-    }
-    @safe auto munge_verse()(string obj_txt_in) {
-      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt_in);
-      return ret;
-    }
-    invariant() {
-    }
-    @safe ST_txtPlusHasFootnotesUrlsImages munge_code()(string obj_txt_in) {
-      obj_txt_in = obj_txt_in.replaceAll(rgx.space, mkup.nbsp);
-      ST_txtPlusHasFootnotesUrlsImages ret = object_only_(obj_txt_in);
-      return ret;
-    }
-    invariant() {
-    }
-    @safe ST_txtPlusHasFootnotesUrlsImages munge_table()(string obj_txt_in) {
-      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt_in);
-      return ret;
-    }
-    invariant() {
-    }
-    @safe ST_txtPlusHasFootnotesUrlsImages munge_comment()(string obj_txt_in) {
-      ST_txtPlusHasFootnotesUrlsImages ret = object_only_(obj_txt_in);
-      return ret;
-    }
-    invariant() {
-    }
-  }
-  static struct ObjInlineMarkup {
-    static auto rgx = RgxI();
-    static auto munge = ObjInlineMarkupMunge();
-    string[string] obj_txt;
-    string anchor_tag = "";
-    @safe ST_txtAndAnchorTagPlusHasFootnotesUrlsImages obj_inline_markup_and_anchor_tags_and_misc(CMM)(
-      string[string]   obj_,
-      string           obj_key_,
-      CMM              conf_make_meta,
-      Flag!"_new_doc"  _new_doc
-    ) {
-      obj_txt["munge"]                                = obj_[obj_key_].dup;
-      obj_txt["munge"]                                = (obj_["is"].match(ctRegex!(`verse|code`)))
-      ? obj_txt["munge"]
-      : obj_txt["munge"].strip;
-      if (_new_doc) {
-        anchor_tag = "";
-      }
-      auto x = munge.init;
-      ST_txtAndAnchorTagPlusHasFootnotesUrlsImages ret;
-      ret.obj_txt                       = "";
-      ret.anchor_tag                    = "";
-      ret.has_notes_reg                 = false;
-      ret.has_notes_star                = false;
-      ret.has_notes_plus                = false;
-      ret.has_links                     = false;
-      ret.has_images_without_dimensions = false;
-      if ((obj_["is"] == "para")
-        || (obj_["is"] == "heading")
-        || (obj_["is"] == "quote")
-        || (obj_["is"] == "group")
-        || (obj_["is"] == "block")
-        || (obj_["is"] == "verse")) {
-        obj_txt["munge"]                              = (obj_txt["munge"]).inline_markup_faces;
-        obj_txt["munge"]                              = (obj_txt["munge"]).links_and_images;
-      }
-      switch (obj_["is"]) {
-      case "heading":
-        if (_new_doc) {
-          anchor_tag                                  = "";
-        }
-        obj_txt["munge"] = _configured_auto_heading_numbering_and_segment_anchor_tags(obj_txt["munge"], obj_, conf_make_meta, _new_doc);
-        obj_txt["munge"] = _make_segment_anchor_tags_if_none_provided(obj_txt["munge"], obj_["lev"], _new_doc);
-        if (auto m = obj_txt["munge"].match(rgx.heading_anchor_tag)) {
-          anchor_tag                                  = m.captures[1];
-        } else if (obj_["lev"] == "1") {
-          writeln("heading anchor tag missing: ", obj_txt["munge"]);
-        }
-        x                                             = munge.munge_heading(obj_txt["munge"], reset_note_numbers);
-        reset_note_numbers = false;
-        goto default;
-      case "para":
-        x                                             = munge.munge_para(obj_txt["munge"]);
-        goto default;
-      case "group":
-        x                                             = munge.munge_group(obj_txt["munge"]);
-        goto default;
-      case "block":
-        x                                             = munge.munge_block(obj_txt["munge"]);
-        goto default;
-      case "quote":
-        x                                             = munge.munge_quote(obj_txt["munge"]);
-        goto default;
-      case "verse":
-        x                                             = munge.munge_verse(obj_txt["munge"]);
-        goto default;
-      case "code":
-        x                                             = munge.munge_code(obj_txt["munge"]);
-        goto default;
-      case "table":
-        x                                             = munge.munge_table(obj_txt["munge"]);
-        goto default;
-      case "comment":
-        x                                             = munge.munge_comment(obj_txt["munge"]);
-        goto default;
-      case "doc_end_reset":
-        munge.initialize_note_numbers();
-        break;
-      default:
-        // para, heading, group, block, verse
-        ret.obj_txt                       = x.obj_txt;
-        ret.anchor_tag                    = anchor_tag;
-        ret.has_notes_reg                 = x.has_notes_reg;
-        ret.has_notes_star                = x.has_notes_star;
-        ret.has_notes_plus                = x.has_notes_plus;
-        ret.has_links                     = x.has_urls;
-        ret.has_images_without_dimensions = x.has_images_without_dimensions;
-        break;
-      }
-      anchor_tag = "";
-      return ret;
-    }
-    invariant() {
-    }
-    @safe auto _clean_heading_toc_()(
-      char[] heading_toc_,
-    ) {
-     auto m = (cast(char[]) heading_toc_).matchFirst(rgx.heading);
-     heading_toc_ = (m.post).replaceAll(rgx.inline_notes_curly_gen, "");
-     return heading_toc_;
-    };
-    @safe ST_flow_table_of_contents_gather_headings flow_table_of_contents_gather_headings(CMM)( //
-      string[string]         obj_,
-      CMM                    conf_make_meta,
-      string[string]         tag_in_seg,
-      string                 _anchor_tag,
-      string[][string]       lev4_subtoc,
-      ObjGenericComposite[]  the_document_toc_section,
-    ) {
-      ObjGenericComposite comp_obj_;
-      mixin InternalMarkup;
-      static auto mkup = InlineMarkup();
-      char[] heading_toc_                             = (obj_["substantive"].dup.strip.to!(char[]))
-        .replaceAll(rgx.inline_notes_al, "");
-      heading_toc_                                    = _clean_heading_toc_(heading_toc_);
-      auto attrib = "";
-      string toc_txt_, subtoc_txt_;
-      int[string] indent;
-      if (obj_["lev_markup_number"].to!int > 0) {
-        indent = [
-          "hang_position" : obj_["lev_markup_number"].to!int,
-          "base_position" : obj_["lev_markup_number"].to!int,
-        ];
-        toc_txt_ = format("%s%s%s%s#%s%s",
-          mkup.lnk_o,
-          heading_toc_.strip,
-          mkup.lnk_c,
-          mkup.url_o,
-          _anchor_tag,
-          mkup.url_c,
-        );
-        toc_txt_= toc_txt_.links_and_images;
-        comp_obj_                                  = set_object_generic("frontmatter", "toc", "para", "toc", toc_txt_.to!string.strip, 0);
-        comp_obj_.metainfo.identifier              = "";
-        comp_obj_.metainfo.object_number_off       = true;
-        comp_obj_.metainfo.object_number_type      = 0;
-        comp_obj_.metainfo.dummy_heading           = (an_object["dummy_heading_status"] == "t") ? true: false;
-        comp_obj_.attrib.indent_hang               = indent["hang_position"];
-        comp_obj_.attrib.indent_base               = indent["base_position"];
-        comp_obj_.attrib.bullet                    = false;
-        comp_obj_.has.inline_links                 = true;
-        the_document_toc_section                   ~= comp_obj_;
-      }
-      comp_obj_                                    = comp_obj_.init;
-      comp_obj_.metainfo.is_of_part                = "frontmatter";
-      comp_obj_.metainfo.is_of_section             = "toc";
-      comp_obj_.metainfo.is_of_type                = "para";
-      comp_obj_.metainfo.is_a                      = "toc";
-      comp_obj_.metainfo.ocn                       = 0;
-      comp_obj_.metainfo.identifier                = "";
-      comp_obj_.metainfo.object_number_off         = true;
-      comp_obj_.metainfo.object_number_type        = 0;
-      comp_obj_.metainfo.dummy_heading             = (an_object["dummy_heading_status"] == "t") ? true: false;
-      comp_obj_.attrib.bullet                      = false;
-      comp_obj_.has.inline_links                   = true;
-      switch (obj_["lev_markup_number"].to!int) {
-      case 0: .. case 3:
-        break;
-      case 4:
-        lev4_subtoc[tag_in_seg["seg_lv4"]] = [];
-        break;
-      case 5: .. case 7:
-        subtoc_txt_ = format("%s%s%s%s#%s%s",
-          mkup.lnk_o,
-          heading_toc_.strip,
-          mkup.lnk_c,
-          mkup.url_o,
-          _anchor_tag,
-          mkup.url_c,
-        );
-        lev4_subtoc[tag_in_seg["seg_lv4"]]
-        ~= links_and_images(obj_["lev_markup_number"]
-             ~ "~ " ~ subtoc_txt_.to!string.strip
-           );
-        break;
-      default:
-        break;
-      }
-      ST_flow_table_of_contents_gather_headings ret;
-      {
-        ret.the_document_toc_section = the_document_toc_section;
-        ret.lev4_subtoc              = lev4_subtoc;
-      }
-      return ret;
-    }
-    invariant() {
-    }
-  private:
-    static int[] heading_num = [ 0, 0, 0, 0 ];
-    static string heading_number_auto_composite = "";
-    static string heading_number_auto_composite_segname = "";
-    static bool[] auto_heading_numbering = [ true, true, true, true];
-    @safe static string _configured_auto_heading_numbering_and_segment_anchor_tags(CMM)(
-      string           munge_,
-      string[string]   obj_,
-      CMM              conf_make_meta,
-      bool             _new_doc,
-    ) {
-      if (_new_doc) {
-        heading_num                         = [ 0, 0, 0, 0 ];
-        heading_number_auto_composite       = "";
-        auto_heading_numbering              = [ true, true, true, true];
-      }
-      if (conf_make_meta.make.auto_num_top_lv) {
-        if (obj_["lev_markup_number"].to!int == 0) {
-          heading_num[0]                    = 0;
-          heading_num[1]                    = 0;
-          heading_num[2]                    = 0;
-          heading_num[3]                    = 0;
-          heading_number_auto_composite     = "";
-        }
-        // auto_num_depth minimum 0
-        // (1.) default 2 (1.1.1) max 3 (1.1.1.1) implement
-        if (
-          conf_make_meta.make.auto_num_top_lv
-          > obj_["lev_markup_number"].to!uint
-        ) {
-          heading_num[1]                    = 0;
-          heading_num[2]                    = 0;
-          heading_num[3]                    = 0;
-        } else if (
-          conf_make_meta.make.auto_num_top_lv
-            == obj_["lev_markup_number"].to!uint
-        ) {
-          auto_heading_numbering[0] =
-            (munge_.match(rgx.auto_heading_numbering_off_lv1)) ? false : true;
-          if (auto_heading_numbering[0]) {
-            heading_num[0] ++;
-          }
-          heading_num[1]                    = 0;
-          heading_num[2]                    = 0;
-          heading_num[3]                    = 0;
-        } else if (
-          conf_make_meta.make.auto_num_top_lv
-            == (obj_["lev_markup_number"].to!uint - 1)
-        ) {
-          auto_heading_numbering[1] =
-            (munge_.match(rgx.auto_heading_numbering_off_lv2)) ? false : true;
-          if (auto_heading_numbering[0]
-          && auto_heading_numbering[1]) {
-            heading_num[1] ++;
-          }
-          heading_num[2]                    = 0;
-          heading_num[3]                    = 0;
-        } else if (
-          conf_make_meta.make.auto_num_top_lv
-            == (obj_["lev_markup_number"].to!uint - 2)
-        ) {
-          auto_heading_numbering[2] =
-            (munge_.match(rgx.auto_heading_numbering_off_lv3)) ? false : true;
-          if (auto_heading_numbering[0]
-          && auto_heading_numbering[1]
-          && auto_heading_numbering[2]) {
-            heading_num[2] ++;
-          }
-          heading_num[3]                    = 0;
-        } else if (
-          conf_make_meta.make.auto_num_top_lv
-            == (obj_["lev_markup_number"].to!uint - 3)
-        ) {
-          auto_heading_numbering[3] =
-            (munge_.match(rgx.auto_heading_numbering_off_lv4)) ? false : true;
-          if (auto_heading_numbering[0]
-          && auto_heading_numbering[1]
-          && auto_heading_numbering[2]
-          && auto_heading_numbering[3]) {
-            heading_num[3] ++;
-          }
-        }
-        if (auto_heading_numbering[0]) {
-          if (heading_num[3] > 0) {
-            heading_number_auto_composite
-              = (conf_make_meta.make.auto_num_depth.to!uint == 3
-                && auto_heading_numbering[3])
-              ? (format(q"┃%s.%s.%s.%s┃",
-                  heading_num[0].to!string,
-                  heading_num[1].to!string,
-                  heading_num[2].to!string,
-                  heading_num[3].to!string
-                ))
-              : "";
-          } else if (heading_num[2] > 0) {
-            heading_number_auto_composite
-              = ((conf_make_meta.make.auto_num_depth.to!uint >= 2)
-                && (conf_make_meta.make.auto_num_depth.to!uint <= 3)
-                && auto_heading_numbering[2])
-              ? (format(q"┃%s.%s.%s┃",
-                  heading_num[0].to!string,
-                  heading_num[1].to!string,
-                  heading_num[2].to!string
-                ))
-              : "";
-          } else if (heading_num[1] > 0) {
-            heading_number_auto_composite
-              = ((conf_make_meta.make.auto_num_depth.to!uint >= 1)
-                && (conf_make_meta.make.auto_num_depth.to!uint <= 3)
-                && auto_heading_numbering[1])
-              ? (format(q"┃%s.%s┃",
-                  heading_num[0].to!string,
-                  heading_num[1].to!string
-                ))
-              : "";
-          } else if (heading_num[0] > 0
-            && munge_.match(rgx.auto_heading_numbering_lv1)
-          ) {
-            heading_number_auto_composite
-              = ((conf_make_meta.make.auto_num_depth.to!uint >= 0)
-                && (conf_make_meta.make.auto_num_depth.to!uint <= 3)
-                && auto_heading_numbering[0])
-              ? (format(q"┃%s┃",
-                  heading_num[0].to!string
-                ))
-              : "";
-          } else {
-            heading_number_auto_composite = "";
-          }
-        }
-        heading_number_auto_composite_segname =
-          (heading_number_auto_composite.empty)
-            ? ""
-            : "seg_" ~ heading_number_auto_composite;
-        debug(heading_number_auto) { writeln(heading_number_auto_composite); }
-        if ((!empty(heading_number_auto_composite))
-        && (obj_["lev_markup_number"].to!uint >= conf_make_meta.make.auto_num_top_lv)) {
-          munge_ = munge_
-          .replaceFirst(rgx.heading,
-            "$1~$2 " ~ heading_number_auto_composite ~ ". ")
-          .replaceFirst(rgx.heading_marker_missing_tag,
-            "$1~" ~ heading_number_auto_composite_segname ~ " ");
-        }
-      }
-      return munge_;
-    }
-    static int heading_num_lev1 = 0;
-    @safe static string _make_segment_anchor_tags_if_none_provided()(
-      string munge_,
-      string lev_,
-      bool   _new_doc
-    ) {
-      if (!(munge_.match(rgx.heading_anchor_tag))) {
-        if (lev_ == "A") { // (_new_doc)
-          heading_num_lev1 = 0;
-        }
-        if (munge_.match(rgx.heading_identify_anchor_tag)) {
-          if (auto m = munge_.match(rgx.heading_extract_named_anchor_tag)) {
-            munge_ = munge_.replaceFirst(
-              rgx.heading_marker_missing_tag,
-              "$1~" ~ m.captures[1].toLower ~ "_"  ~ m.captures[2] ~ " ");
-            if (auto n = munge_.match(rgx.heading_anchor_tag_plus_colon)) {
-              auto tag_remunge_ = n.captures[2]
-                .replaceAll(rgx.heading_marker_tag_has_colon, "..");
-              munge_ = munge_.replaceFirst(rgx.heading_anchor_tag_plus_colon, n.captures[1] ~ tag_remunge_ ~ " ");
-            }
-          } else if (auto m = munge_.match(rgx.heading_extract_unnamed_anchor_tag)) {
-            munge_ = munge_.replaceFirst(
-              rgx.heading_marker_missing_tag,
-              "$1~" ~ "s" ~ m.captures[1] ~ " ");
-          }
-        } else if (lev_ == "1") { // (if not successful) manufacture a unique anchor tag for lev == "1"
-          heading_num_lev1 ++;
-          munge_ = munge_.replaceFirst(
-            rgx.heading_marker_missing_tag,
-            "$1~" ~ "x" ~ heading_num_lev1.to!string ~ " ");
-        }
-      }
-      return munge_;
-    }
-  }
-  struct ObjAttributes {
-    string[string] _obj_attrib;
-    @safe string obj_attributes()(
-      string              obj_is_,
-      string              obj_raw,
-      ObjGenericComposite comp_obj_,
-    ) {
-      scope(exit) {
-        destroy(obj_is_);
-        destroy(obj_raw);
-        destroy(comp_obj_);
-      }
-      _obj_attrib["json"] ="{";
-      switch (obj_is_) {
-      case "heading":
-        _obj_attrib["json"] ~= txt_heading(obj_raw);
-        break;
-      case "para":
-        _obj_attrib["json"] ~= txt_para_and_blocks(obj_raw)
-        ~ txt_para(obj_raw);
-        break;
-      case "code":
-        _obj_attrib["json"] ~= txt_code(obj_raw);
-        break;
-      case "group":
-        _obj_attrib["json"] ~= txt_para_and_blocks(obj_raw)
-        ~ txt_group(obj_raw);
-        break;
-      case "block":
-        _obj_attrib["json"] ~= txt_para_and_blocks(obj_raw)
-        ~ txt_block(obj_raw);
-        break;
-      case "verse":
-        _obj_attrib["json"] ~= txt_verse(obj_raw);
-        break;
-      case "quote":
-        _obj_attrib["json"] ~= txt_quote(obj_raw);
-        break;
-      case "table":
-        _obj_attrib["json"] ~= txt_table(obj_raw);
-        break;
-      case "comment":
-        _obj_attrib["json"] ~= txt_comment(obj_raw);
-        break;
-      default:
-        _obj_attrib["json"] ~= txt_para(obj_raw);
-        break;
-      }
-      _obj_attrib["json"] ~= " }";
-      _obj_attrib["json"] = _set_additional_values_parse_as_json(_obj_attrib["json"], obj_is_, comp_obj_);
-      debug(structattrib) {
-        if (oa_j["is"].str() == "heading") {
-          writeln(_obj_attrib["json"]);
-          writeln(
-            "is: ", oa_j["is"].str(),
-            "; object_number: ", oa_j["object_number"].integer()
-          );
-        }
-      }
-      return _obj_attrib["json"];
-    }
-    invariant() {
-    }
-    private:
-    string _obj_attributes;
-    @safe string txt_para_and_blocks()(string obj_txt_in) {
-      if (obj_txt_in.matchFirst(rgx.para_bullet)) {
-        _obj_attributes =" \"bullet\": \"true\","
-        ~ " \"indent_hang\": 0,"
-        ~ " \"indent_base\": 0,";
-      } else if (auto m = obj_txt_in.matchFirst(rgx.para_bullet_indent)) {
-        _obj_attributes =" \"bullet\": \"true\","
-        ~ " \"indent_hang\": " ~ m["indent"].to!string ~ ","
-        ~ " \"indent_base\": " ~ m["indent"].to!string ~ ",";
-      } else if (auto m = obj_txt_in.matchFirst(rgx.para_indent_hang)) {
-        _obj_attributes =" \"bullet\": \"false\","
-        ~ " \"indent_hang\": " ~ m["hang"].to!string ~ ","
-        ~ " \"indent_base\": " ~ m["indent"].to!string ~ ",";
-      } else if (auto m = obj_txt_in.matchFirst(rgx.para_indent)) {
-        _obj_attributes =" \"bullet\": \"false\","
-        ~ " \"indent_hang\": " ~ m["indent"].to!string ~ ","
-        ~ " \"indent_base\": " ~ m["indent"].to!string ~ ",";
-      } else {
-        _obj_attributes =" \"bullet\": \"false\","
-        ~ " \"indent_hang\": 0,"
-        ~ " \"indent_base\": 0,";
-      }
-      return _obj_attributes;
-    }
-    @safe string txt_heading()(string obj_txt_in) {
-      _obj_attributes = " \"use\": \"content\","
-      ~ " \"of\": \"para\","
-      ~ " \"is\": \"heading\"";
-      return _obj_attributes;
-    }
-    invariant() {
-    }
-    @safe string txt_para()(string obj_txt_in) {
-      _obj_attributes = " \"use\": \"content\","
-      ~ " \"of\": \"para\","
-      ~ " \"is\": \"para\"";
-      return _obj_attributes;
-    }
-    invariant() {
-    }
-    @safe string txt_quote()(string obj_txt_in) {
-      _obj_attributes = " \"use\": \"content\","
-      ~ " \"of\": \"block\","
-      ~ " \"is\": \"quote\"";
-      return _obj_attributes;
-    }
-    invariant() {
-    }
-    @safe string txt_group()(string obj_txt_in) {
-      _obj_attributes = " \"use\": \"content\","
-      ~ " \"of\": \"block\","
-      ~ " \"is\": \"group\"";
-      return _obj_attributes;
-    }
-    invariant() {
-    }
-    @safe string txt_block()(string obj_txt_in) {
-      _obj_attributes = " \"use\": \"content\","
-      ~ " \"of\": \"block\","
-      ~ " \"is\": \"block\"";
-      return _obj_attributes;
-    }
-    invariant() {
-    }
-    @safe string txt_verse()(string obj_txt_in) {
-      _obj_attributes = " \"use\": \"content\","
-      ~ " \"of\": \"block\","
-      ~ " \"is\": \"verse\"";
-      return _obj_attributes;
-    }
-    invariant() {
-    }
-    @safe string txt_code()(string obj_txt_in) {
-      _obj_attributes = " \"use\": \"content\","
-      ~ " \"of\": \"block\","
-      ~ " \"is\": \"code\"";
-      return _obj_attributes;
-    }
-    invariant() {
-    }
-    @safe string txt_table()(string obj_txt_in) {
-      _obj_attributes = " \"use\": \"content\","
-      ~ " \"of\": \"block\","
-      ~ " \"is\": \"table\"";
-      return _obj_attributes;
-    }
-    invariant() {
-    }
-    @safe string txt_comment()(string obj_txt_in) {
-      _obj_attributes = " \"use\": \"comment\","
-      ~ " \"of\": \"comment\","
-      ~ " \"is\": \"comment\"";
-      return _obj_attributes;
-    }
-    invariant() {
-    }
-    @safe string _set_additional_values_parse_as_json()(
-      string              _obj_attrib,
-      string              obj_is_,
-      ObjGenericComposite comp_obj_,
-    ) {
-      JSONValue oa_j = parseJSON(_obj_attrib);
-      assert(
-        (oa_j.type == JSON_TYPE.OBJECT)
-      );
-      if (obj_is_ == "heading") {
-        oa_j.object["object_number"]              = comp_obj_.metainfo.ocn;
-        oa_j.object["lev_markup_number"]          = comp_obj_.metainfo.heading_lev_markup;
-        oa_j.object["lev_collapsed_number"]       = comp_obj_.metainfo.heading_lev_collapsed;
-        oa_j.object["heading_ptr"]                = comp_obj_.ptr.heading;
-        oa_j.object["doc_object_ptr"]             = comp_obj_.ptr.doc_object;
-      }
-      oa_j.object["parent_object_number"]         = comp_obj_.metainfo.parent_ocn;
-      oa_j.object["parent_lev_markup_number"]     = comp_obj_.metainfo.parent_lev_markup;
-      _obj_attrib                                 = oa_j.toString();
-      return _obj_attrib;
-    }
-  }
-  struct BookIndexNuggetHash {
-    string main_term, sub_term, sub_term_bits;
-    int object_number_offset, object_number_endpoint;
-    string[] object_numbers;
-    string[][string][string] bi_hash_nugget;
-    string[] bi_main_terms_split_arr;
-    @safe string[][string][string] bookindex_nugget_hash(S)(
-      string bookindex_section,
-      OCNset obj_cite_digits,
-      S      tag_in_seg,
-    ) {
-      debug(asserts) { static assert(is(typeof(obj_cite_digits.object_number) == int)); }
-      debug(bookindexraw) {
-        if (!bookindex_section.empty) {
-          writeln(
-            "* [bookindex] ",
-            "[", obj_cite_digits.object_number.to!string, ": ", tag_in_seg["seg_lv4"], "] ", bookindex_section,
-            "  - - - ",
-            "[", obj_cite_digits.object_number.to!string, "] ", bookindex_section
-          );
-        }
-      }
-      static auto rgx = RgxI();
-      if (!bookindex_section.empty) {
-        auto bi_main_terms_split_arr
-          = bookindex_section.split(rgx.bi_main_terms_split);
-        foreach (bi_main_terms_content; bi_main_terms_split_arr) {
-          auto bi_main_term_and_rest
-            = bi_main_terms_content.split(rgx.bi_main_term_plus_rest_split);
-          if (auto m = bi_main_term_and_rest[0].match(
-            rgx.bi_term_and_object_numbers_match)
-          ) {
-            main_term = m.captures[1].strip;
-            object_number_offset = m.captures[2].to!int;
-            object_number_endpoint = (obj_cite_digits.object_number + object_number_offset);
-            object_numbers ~= (obj_cite_digits.object_number.to!string
-            ~ "-" ~ object_number_endpoint.to!string);
-          } else {
-            main_term = bi_main_term_and_rest[0].strip;
-            object_numbers ~= obj_cite_digits.object_number.to!string;
-          }
-          bi_hash_nugget[main_term]["_a"] ~= object_numbers;
-          object_numbers = null;
-          if (bi_main_term_and_rest.length > 1) {
-            auto bi_sub_terms_split_arr
-              = bi_main_term_and_rest[1].split(
-                rgx.bi_sub_terms_plus_object_number_offset_split
-              );
-            foreach (sub_terms_bits; bi_sub_terms_split_arr) {
-              if (auto m = sub_terms_bits.match(rgx.bi_term_and_object_numbers_match)) {
-                sub_term = m.captures[1].strip;
-                object_number_offset = m.captures[2].to!int;
-                object_number_endpoint = (obj_cite_digits.object_number + object_number_offset);
-                object_numbers ~= (obj_cite_digits.object_number.to!string
-                ~ " - " ~ object_number_endpoint.to!string);
-              } else {
-                sub_term = sub_terms_bits.strip;
-                object_numbers ~= obj_cite_digits.object_number.to!string;
-              }
-              if (!empty(sub_term)) {
-                bi_hash_nugget[main_term][sub_term] ~= object_numbers;
-              }
-              object_numbers = null;
-            }
-          }
-        }
-      }
-      return bi_hash_nugget;
-    }
-    invariant() {
-    }
-  }
-  struct BookIndexReportIndent {
-    int mkn, skn;
-    @safe void bookindex_report_indented()(
-      string[][string][string] bookindex_unordered_hashes
-    ) {
-      auto mainkeys
-        = bookindex_unordered_hashes.byKey.array.sort().release;
-      foreach (mainkey; mainkeys) {
-        debug(bookindex1) { writeln(mainkey); }
-        auto subkeys
-          = bookindex_unordered_hashes[mainkey].byKey.array.sort().release;
-        foreach (subkey; subkeys) {
-          debug(bookindex1) {
-            writeln("  ", subkey);
-            writeln("    ", to!string(
-              bookindex_unordered_hashes[mainkey][subkey]
-            ));
-          }
-          ++skn;
-        }
-        ++mkn;
-      }
-    }
-  }
-  struct BookIndexReportSection {
-    int  mkn, skn;
-    static auto rgx = RgxI();
-    static auto munge = ObjInlineMarkupMunge();
-    @safe void bookindex_write_section()(
-      string[][string][string] bookindex_unordered_hashes
-    ) {
-      auto mainkeys =
-        bookindex_unordered_hashes.byKey.array
-        .sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable).release;
-      foreach (mainkey; mainkeys) {
-        write("_0_1 ⑆!┨", mainkey, "┣! ");
-        foreach (ref_; bookindex_unordered_hashes[mainkey]["_a"]) {
-          auto go = ref_.replaceAll(rgx.book_index_go, "$1");
-          write(" {", ref_, "}#", go, ", ");
-        }
-        writeln(" \\\\");
-        bookindex_unordered_hashes[mainkey].remove("_a");
-        auto subkeys =
-          bookindex_unordered_hashes[mainkey].byKey.array
-          .sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable).release;
-        foreach (subkey; subkeys) {
-          write("  ", subkey, ", ");
-          foreach (ref_; bookindex_unordered_hashes[mainkey][subkey]) {
-            auto go = ref_.replaceAll(rgx.book_index_go, "$1");
-            write(" {", ref_, "}#", go, ", ");
-          }
-          writeln(" \\\\");
-          ++skn;
-        }
-        ++mkn;
-      }
-    }
-    @system ST_bookindex backmatter_bookindex_build_abstraction_section(B)(
-      string[][string][string] bookindex_unordered_hashes,
-      OCNset                   obj_cite_digits,
-      B                        opt_action,
-    ) {
-      debug(asserts) { static assert(is(typeof(obj_cite_digits.object_number) == int)); }
-      mixin spineNode;
-      mixin InternalMarkup;
-      static auto mkup = InlineMarkup();
-      string type_is;
-      string lev;
-      int heading_lev_markup, heading_lev_collapsed;
-      string attrib;
-      int[string] indent;
-      auto mainkeys =
-        bookindex_unordered_hashes.byKey.array
-        .sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable).release;
-      ObjGenericComposite[] bookindex_section;
-      ObjGenericComposite comp_obj_;
-      auto node_para_int_ = node_metadata_para_int;
-      auto node_para_str_ = node_metadata_para_str;
-      if ((mainkeys.length > 0)
-      && (opt_action.backmatter
-      && opt_action.section_bookindex)) {
-        string bi_tmp;
-        string[] bi_tmp_tags;
-        {
-          comp_obj_                                     =  set_object_heading("lev1", "backmatter", "bookindex", "Book Index");
-          comp_obj_.metainfo.identifier                 = "";
-          comp_obj_.metainfo.dummy_heading              = false;
-          comp_obj_.metainfo.object_number_off          = false;
-          comp_obj_.metainfo.object_number_type         = 0;
-          comp_obj_.tags.segment_anchor_tag_epub        = "_part_book_index";
-          comp_obj_.tags.anchor_tag_html                = comp_obj_.tags.segment_anchor_tag_epub;
-          comp_obj_.tags.in_segment_html                = "bookindex";
-          comp_obj_.tags.anchor_tags                    = ["section_bookindex"];
-          comp_obj_.has.inline_links                    = true;
-          bookindex_section                             ~= comp_obj_;
-          tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-          tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-          ++mkn;
-        }
-        {
-          comp_obj_                                     = set_object_heading("lev4", "backmatter", "bookindex", "Index");
-          comp_obj_.metainfo.identifier                 = "";
-          comp_obj_.metainfo.dummy_heading              = true;
-          comp_obj_.metainfo.object_number_off          = true;
-          comp_obj_.metainfo.object_number_type         = 0;
-          comp_obj_.tags.segment_anchor_tag_epub        = "bookindex";
-          comp_obj_.tags.anchor_tag_html                = comp_obj_.tags.segment_anchor_tag_epub;
-          comp_obj_.tags.in_segment_html                = comp_obj_.tags.anchor_tag_html;
-          comp_obj_.metainfo.heading_lev_collapsed      = 2;
-          comp_obj_.has.inline_links                    = false;
-          comp_obj_.tags.anchor_tags                    = ["bookindex"];
-          bookindex_section                             ~= comp_obj_;
-          tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-          tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-          ++mkn;
-        }
-        import std.array : appender;
-        auto buffer = appender!(char[])();
-        string[dchar] transTable = [' ' : "_"];
-        foreach (mainkey; mainkeys) {
-          bi_tmp_tags = [""];
-          bi_tmp = mkup.ff_i ~ mkup.bold ~ mkup.ff_o ~ mainkey ~ mkup.ff_c ~ mkup.bold ~ " ";
-          buffer.clear();
-          bi_tmp_tags ~= translate(mainkey, transTable);
-          auto bkidx_lnk(string locs) {
-            string markup = "";
-            if (auto m = locs.matchFirst(rgx.book_index_go)) {
-              markup
-                = links_and_images("{ " ~ m["link"] ~ " }"
-                ~ "#" ~ m["ocn"] ~ ", ");
-            } else {
-              writeln(__LINE__, ": ", locs);
-            }
-            return markup;
-          }
-          foreach (ref_; bookindex_unordered_hashes[mainkey]["_a"]) {
-            bi_tmp ~= bkidx_lnk(ref_);
-          }
-          bi_tmp ~= " \\\\\n    ";
-          bookindex_unordered_hashes[mainkey].remove("_a");
-          auto subkeys =
-            bookindex_unordered_hashes[mainkey].byKey.array
-            .sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable).release;
-          foreach (subkey; subkeys) {
-            bi_tmp ~= subkey ~ ", ";
-            buffer.clear();
-            bi_tmp_tags ~= translate(subkey, transTable);
-            foreach (ref_; bookindex_unordered_hashes[mainkey][subkey]) {
-              bi_tmp ~= bkidx_lnk(ref_);
-            }
-            bi_tmp ~= " \\\\\n    ";
-            ++skn;
-          }
-          bi_tmp                                             = bi_tmp.replaceFirst(rgx.trailing_linebreak, "");
-          comp_obj_                                          = set_object_generic("backmatter", "bookindex", "para", "bookindex", bi_tmp.to!string.strip, 0);
-          comp_obj_.metainfo.identifier                      = "";
-          comp_obj_.metainfo.object_number_off               = true;
-          comp_obj_.metainfo.object_number_type              = 0;
-          comp_obj_.tags.anchor_tags                         = bi_tmp_tags;
-          comp_obj_.attrib.indent_hang                       = 0;
-          comp_obj_.attrib.indent_base                       = 1;
-          comp_obj_.attrib.bullet                            = false;
-          comp_obj_.has.inline_links                         = true;
-          comp_obj_.text                                     = bi_tmp.to!string.strip;
-          bookindex_section                                  ~= comp_obj_;
-          ++mkn;
-        }
-      } else {                              // no book index, (figure out what to do here)
-        comp_obj_                                       = set_object_heading("lev1", "backmatter", "bookindex", "(skip) there is no Book Index");
-        comp_obj_.metainfo.identifier                   = "";
-        comp_obj_.metainfo.dummy_heading                = true;
-        comp_obj_.metainfo.object_number_off            = true;
-        bookindex_section                               ~= comp_obj_;
-      }
-      ST_bookindex ret;
-      {
-        ret.bookindex = bookindex_section;
-        ret.ocn       = obj_cite_digits;
-      }
-      return ret;
-    }
-  }
-  struct NotesSection {
-    string[string] object_notes;
-    int previous_count;
-    int mkn;
-    static auto rgx = RgxI();
-    @safe private auto gather_notes_for_endnote_section(
-      ObjGenericComposite[] contents_am,
-      string[string]        tag_in_seg,
-      int                   cntr,
-    ) {
-      assert((contents_am[cntr].metainfo.is_a == "para")
-      || (contents_am[cntr].metainfo.is_a     == "heading")
-      || (contents_am[cntr].metainfo.is_a     == "quote")
-      || (contents_am[cntr].metainfo.is_a     == "group")
-      || (contents_am[cntr].metainfo.is_a     == "block")
-      || (contents_am[cntr].metainfo.is_a     == "verse"));
-      assert(cntr >= previous_count);
-      assert(
-        (contents_am[cntr].text).match(
-        rgx.inline_notes_al_all_note)
-      );
-      mixin InternalMarkup;
-      previous_count = cntr;
-      static auto mkup = InlineMarkup();
-      static auto munge = ObjInlineMarkupMunge();
-      foreach(m;
-        (contents_am[cntr].text).matchAll(
-          rgx.inline_notes_al_special_char_note)
-      ) {
-        debug(endnotes_build) { writeln(
-            "{", mkup.ff_i, mkup.superscript, mkup.ff_o, m["char"], ".", mkup.ff_c, mkup.superscript, "}"
-            ~ mkup.mark_internal_site_lnk,
-            tag_in_seg["seg_lv4"],
-              ".fnSuffix#noteref_\n  ", m["char"], " ",
-            m["note"]); // sometimes need segment name (segmented html & epub)
-        }
-        // you need anchor for segments at this point ->
-        object_notes["anchor"] ~= "note_" ~ m["char"] ~ "』";
-        object_notes["notes"]  ~= (tag_in_seg["seg_lv4"].empty)
-        ? (links_and_images(
-            "{" ~ mkup.ff_i ~ mkup.superscript  ~ mkup.ff_o ~ m["char"] ~ "." ~ mkup.ff_c  ~ mkup.superscript  ~ "}#noteref_"
-            ~ m["char"]) ~ " "
-            ~ m["note"] ~ "』"
-          )
-        : (links_and_images(
-            "{" ~ mkup.ff_i ~ mkup.superscript ~ mkup.ff_o ~ m["char"] ~ "." ~ mkup.ff_c  ~ mkup.superscript ~ "}"
-             ~ mkup.mark_internal_site_lnk
-             ~ tag_in_seg["seg_lv4"]
-             ~ ".fnSuffix#noteref_"
-             ~ m["char"]) ~ " "
-             ~ m["note"] ~ "』"
-          );
-      }
-      foreach(m;
-        (contents_am[cntr].text).matchAll(
-          rgx.inline_notes_al_regular_number_note)
-      ) {
-        debug(endnotes_build) { writeln(
-            "{", mkup.ff_i, mkup.superscipt, mkup.ff_o, m["num"], ".", mkup.ff_c, mkup.superscipt, "}"
-            ~ mkup.mark_internal_site_lnk,
-            tag_in_seg["seg_lv4"],
-              ".fnSuffix#noteref_\n  ", m["num"], " ",
-            m["note"]); // sometimes need segment name (segmented html & epub)
-        }
-        // you need anchor for segments at this point ->
-        object_notes["anchor"] ~= "note_" ~ m["num"] ~ "』";
-        object_notes["notes"]  ~= (tag_in_seg["seg_lv4"].empty)
-        ? (links_and_images(
-            "{" ~ mkup.ff_i ~ mkup.superscript  ~ mkup.ff_o ~ m["num"] ~ "." ~ mkup.ff_c  ~ mkup.superscript  ~ "}#noteref_"
-            ~ m["num"]) ~ " "
-            ~ m["note"] ~ "』"
-          )
-        : (links_and_images(
-            "{" ~ mkup.ff_i ~ mkup.superscript ~ mkup.ff_o ~ m["num"] ~ "." ~ mkup.ff_c  ~ mkup.superscript ~ "}"
-             ~ mkup.mark_internal_site_lnk
-             ~ tag_in_seg["seg_lv4"]
-             ~ ".fnSuffix#noteref_"
-             ~ m["num"]) ~ " "
-             ~ m["note"] ~ "』"
-          );
-      }
-      return object_notes;
-    }
-    @safe private auto gathered_notes() {
-      string[][string] endnotes_;
-      if (object_notes.length > 1) {
-        endnotes_["notes"] = (object_notes["notes"].split(rgx.break_string))[0..$-1];
-        endnotes_["anchor"] = (object_notes["anchor"].split(rgx.break_string))[0..$-1];
-      } else {
-        endnotes_["notes"] = [];
-        endnotes_["anchor"] = [];
-      }
-      return endnotes_;
-    }
-    @safe private ST_endnotes backmatter_endnote_objects(O)(
-      OCNset         obj_cite_digits,
-      O              opt_action,
-    ) {
-      mixin spineNode;
-      ObjGenericComposite[] the_document_endnotes_section;
-      auto endnotes_ = gathered_notes();
-      string type_is;
-      string lev, lev_markup_number, lev_collapsed_number;
-      string attrib;
-      int[string] indent;
-      ObjGenericComposite comp_obj_;
-      if ((endnotes_["notes"].length > 0)
-      && (opt_action.backmatter && opt_action.section_endnotes)) {
-        {
-          comp_obj_                                     = set_object_heading("lev1", "backmatter", "endnotes", "Endnotes");
-          comp_obj_.metainfo.identifier                 = "";
-          comp_obj_.metainfo.dummy_heading              = false;
-          comp_obj_.metainfo.object_number_off          = false;
-          comp_obj_.metainfo.object_number_type         = 0;
-          comp_obj_.tags.segment_anchor_tag_epub        = "_part_endnotes";
-          comp_obj_.tags.anchor_tag_html                = comp_obj_.tags.segment_anchor_tag_epub;
-          comp_obj_.tags.in_segment_html                = "endnotes";
-          comp_obj_.tags.anchor_tags                    = ["section_endnotes"];
-          the_document_endnotes_section                 ~= comp_obj_;
-          tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-          tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-          ++mkn;
-        }
-        {
-          comp_obj_                                     = set_object_heading("lev4", "backmatter", "endnotes", "Endnotes");
-          comp_obj_.metainfo.identifier                 = "";
-          comp_obj_.metainfo.dummy_heading              = true;
-          comp_obj_.metainfo.object_number_off          = true;
-          comp_obj_.metainfo.object_number_type         = 0;
-          comp_obj_.tags.segment_anchor_tag_epub        = "endnotes";
-          comp_obj_.tags.anchor_tag_html                = comp_obj_.tags.segment_anchor_tag_epub;
-          comp_obj_.tags.in_segment_html                = comp_obj_.tags.anchor_tag_html;
-          comp_obj_.tags.anchor_tags                    = ["endnotes"];
-          the_document_endnotes_section                 ~= comp_obj_;
-          tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-          tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-          ++mkn;
-        }
-      } else {
-        comp_obj_                                       = set_object_heading("lev1", "empty", "empty", "(skip) there are no Endnotes");
-        comp_obj_.metainfo.identifier                   = "";
-        comp_obj_.metainfo.dummy_heading                = true;
-        comp_obj_.metainfo.object_number_off            = true;
-        comp_obj_.metainfo.object_number_type           = 0;
-        the_document_endnotes_section                   ~= comp_obj_;
-      }
-      if (opt_action.backmatter && opt_action.section_endnotes) {
-        ObjGenericComposite comp_obj_endnote_;
-        comp_obj_endnote_                                       = set_object_generic("backmatter", "endnotes", "para", "endnote", "", 0);
-        comp_obj_endnote_.metainfo.identifier                   = "";
-        // comp_obj_.metainfo.dummy_heading                     = false;
-        comp_obj_.metainfo.object_number_off                    = true;
-        comp_obj_.metainfo.object_number_type                   = 0;
-        comp_obj_endnote_.attrib.indent_hang                    = 0;
-        comp_obj_endnote_.attrib.indent_base                    = 0;
-        comp_obj_endnote_.attrib.bullet                         = false;
-        foreach (i, endnote; endnotes_["notes"]) {
-          auto     m                                            = endnote.matchFirst(rgx.note_ref);
-          string   notenumber                                   = m["ref"].to!string;
-          string   anchor_tag                                   = "note_" ~ notenumber;
-          comp_obj_endnote_.tags.anchor_tags                    = [ endnotes_["anchor"][i] ];
-          comp_obj_endnote_.has.inline_links                    = true;
-          comp_obj_endnote_.text                                = endnote.inline_markup_faces.strip;
-          the_document_endnotes_section                         ~= comp_obj_endnote_;
-        }
-      }
-      ST_endnotes ret;
-      {
-        ret.endnotes = the_document_endnotes_section;
-        ret.ocn      = obj_cite_digits;
-      }
-      return ret;
-    }
-  }
-  @system public ST_biblio_section backmatter_make_the_bibliography_section()(
-    string[]     biblio_unsorted_incomplete,
-    JSONValue[]  bib_arr_json,
-  ) {
-    Bibliography biblio = Bibliography();
-    ObjGenericComposite comp_obj_;
-    static auto mkup = InlineMarkup();
-    ST_flow_bibliography _get = biblio.flow_bibliography_(biblio_unsorted_incomplete, bib_arr_json);
-    JSONValue[] biblio_ordered;
-    biblio_ordered            = _get.biblio_sorted;
-    if (biblio_ordered.length > 0) {
-      {
-        comp_obj_                                 = set_object_heading("lev1", "backmatter", "bibliography", "Bibliography");
-        comp_obj_.metainfo.identifier             = "";
-        comp_obj_.metainfo.dummy_heading          = false;
-        comp_obj_.metainfo.object_number_off      = false;
-        comp_obj_.metainfo.object_number_type     = 0;
-        comp_obj_.tags.segment_anchor_tag_epub    = "_part_bibliography";
-        comp_obj_.tags.anchor_tag_html            = comp_obj_.tags.segment_anchor_tag_epub;
-        comp_obj_.tags.in_segment_html            = "bibliography";
-        comp_obj_.tags.anchor_tags                = ["section_bibliography"];
-        comp_obj_.metainfo.dom_structure_markedup_tags_status  = [ 1, 1, 0, 0, 0, 0, 0, 0];
-        comp_obj_.metainfo.dom_structure_collapsed_tags_status = [ 1, 1, 0, 0, 0, 0, 0, 0];
-        the_document_bibliography_section         ~= comp_obj_;
-        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-      }
-      {
-        comp_obj_                                 = set_object_heading("lev4", "backmatter", "bibliography", "Bibliography");
-        comp_obj_.metainfo.identifier             = "";
-        comp_obj_.metainfo.dummy_heading          = true;
-        comp_obj_.metainfo.object_number_off      = true;
-        comp_obj_.metainfo.object_number_type     = 0;
-        comp_obj_.tags.segment_anchor_tag_epub    = "bibliography";
-        comp_obj_.tags.anchor_tag_html            = comp_obj_.tags.segment_anchor_tag_epub;
-        comp_obj_.tags.in_segment_html            = comp_obj_.tags.anchor_tag_html;
-        comp_obj_.tags.anchor_tags                = ["bibliography"];
-        the_document_bibliography_section         ~= comp_obj_;
-        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-      }
-      {
-        string out_;
-        foreach (entry; biblio_ordered) {
-          out_ = format("%s \"%s\"%s%s%s%s%s%s%s%s%s.",
-            ((entry["author"].str.empty) ? entry["editor"].str : entry["author"].str),
-            entry["fulltitle"].str,
-            ((entry["journal"].str.empty) ? "" : ", " ~ mkup.ff_i ~ mkup.italic ~ mkup.ff_o ~ entry["journal"].str ~ mkup.ff_c ~ mkup.italic),
-            ((entry["volume"].str.empty) ? "" : ", " ~ entry["volume"].str),
-            ((entry["in"].str.empty) ? "" : ", " ~ entry["in"].str),
-            ((!(entry["author"].str.empty) && (!(entry["editor"].str.empty))) ? entry["editor"].str : ""),
-            ", " ~ entry["year"].str,
-            ((entry["pages"].str.empty) ? "" : ", " ~ entry["pages"].str),
-            ((entry["publisher"].str.empty) ? "" : ", " ~ entry["publisher"].str),
-            ((entry["place"].str.empty) ? "" : ", " ~ entry["place"].str),
-            ((entry["url"].str.empty) ? "" : ", [" ~ entry["url"].str ~ "]"),
-          );
-          comp_obj_                                   = set_object_generic("backmatter", "bibliography", "para", "bibliography", out_.to!string.strip, 0);
-          comp_obj_.metainfo.identifier               = "";
-          comp_obj_.metainfo.object_number_off        = true;
-          comp_obj_.metainfo.object_number_type       = 0;
-          comp_obj_.attrib.indent_hang                = 0;
-          comp_obj_.attrib.indent_base                = 1;
-          comp_obj_.attrib.bullet                     = bullet;
-          comp_obj_.tags.anchor_tags                  = [anchor_tag];
-          the_document_bibliography_section           ~= comp_obj_;
-        }
-      }
-    } else {
-      comp_obj_                                   = set_object_heading("lev1", "empty", "empty", "(skip) there is no Bibliography");
-      comp_obj_.metainfo.identifier               = "";
-      comp_obj_.metainfo.dummy_heading            = true;
-      comp_obj_.metainfo.object_number_off        = true;
-      comp_obj_.metainfo.object_number_type       = 0;
-      the_document_bibliography_section           ~= comp_obj_;
-    }
-    debug(bibliosection) { foreach (o; the_document_bibliography_section) { writeln(o.text); } }
-    ST_biblio_section ret;
-    {
-      ret.bibliography_section = the_document_bibliography_section;
-      ret.tag_assoc            = tag_assoc; //
-    }
-    return ret;
-  }
-  struct Bibliography {
-    @system public ST_flow_bibliography flow_bibliography_()(
-      string[]    biblio_unsorted_incomplete,
-      JSONValue[] bib_arr_json
-    ) {
-      JSONValue[] biblio_unsorted
-        = biblio_make_unsorted_array_of_json_objects(biblio_unsorted_incomplete, bib_arr_json); // TODO lookat returns
-      biblio_arr_json = [];
-      biblio_unsorted_incomplete = [];
-      JSONValue[] biblio_sorted__ = biblio_sort(biblio_unsorted);
-      debug(biblio0) {
-        biblio_debug(biblio_sorted__);
-        writeln("---");
-        writeln("unsorted incomplete: ", biblio_unsorted_incomplete.length);
-        writeln("json:                ", bib_arr_json.length);
-        writeln("unsorted:            ", biblio_unsorted.length);
-        writeln("sorted:              ", biblio_sorted__.length);
-        int cntr;
-        int[7] x;
-        while (cntr < x.length) {
-          writeln(cntr, ": ", biblio_sorted__[cntr]["fulltitle"]);
-          cntr++;
-        }
-      }
-      ST_flow_bibliography ret;
-      {
-        ret.biblio_sorted  = biblio_sorted__;
-        ret.bib_arr_json  = bib_arr_json;
-        ret.biblio_unsorted_incomplete  = biblio_unsorted_incomplete;
-      }
-      return ret;
-    }
-    @system final private JSONValue[] biblio_make_unsorted_array_of_json_objects()(
-      string[]      biblio_unordered,
-      JSONValue[]   bib_arr_json
-    ) {
-      foreach (bibent; biblio_unordered) {
-        // update bib to include deemed_author, needed for:
-        // sort_bibliography_array_by_deemed_author_year_title
-        // either: sort on multiple fields, or; create such sort field
-        JSONValue j = parseJSON(bibent);
-        if (!empty(j["fulltitle"].str)) {
-          if (!empty(j["author_raw"].str)) {
-            j["deemed_author"] = j["author_arr"][0];
-          } else if (!empty(j["editor_raw"].str)) {
-            j["deemed_author"] = j["editor_arr"][0];
-          }
-          j["sortby_deemed_author_year_title"] = (
-            j["deemed_author"].str ~
-             "; " ~
-             j["year"].str ~
-             "; "  ~
-             j["fulltitle"].str
-          );
-        }
-        bib_arr_json ~= j;
-      }
-      return bib_arr_json.dup;
-    }
-    @system final private JSONValue[] biblio_sort()(JSONValue[] biblio_unordered) {
-      JSONValue[] biblio_sorted_;
-      biblio_sorted_
-        = sort!((a, b){
-          return ((a["sortby_deemed_author_year_title"].str) < (b["sortby_deemed_author_year_title"].str));
-        })(biblio_unordered).array;
-      debug(bibliosorted) {
-        foreach (j; biblio_sorted_) {
-          if (!empty(j["fulltitle"].str)) { writeln(j["sortby_deemed_author_year_title"]); }
-        }
-      }
-      return biblio_sorted_;
-    }
-    @system void biblio_debug()(JSONValue[] biblio_sorted) {
-      debug(biblio0) {
-        foreach (j; biblio_sorted) {
-          if (!empty(j["fulltitle"].str)) { writeln(j["sortby_deemed_author_year_title"]); }
-        }
-      }
-    }
-  }
-  @system public ObjGenericComposite[] backmatter_gather_table_of_contents(
-    ObjGenericComposite[] the_document_endnotes_section,
-    ObjGenericComposite[] the_document_glossary_section,
-    ObjGenericComposite[] the_document_bibliography_section,
-    ObjGenericComposite[] the_document_bookindex_section,
-    ObjGenericComposite[] the_document_blurb_section,
-  ) {
-    ObjGenericComposite[] toc_section_backmatter;
-    string toc_txt_;
-    static auto mkup = InlineMarkup();
-    ObjGenericComposite   comp_obj_;
-    int[string] indent = [
-      "hang_position" : 1,
-      "base_position" : 1,
-    ];
-    comp_obj_                                          = set_object_generic("frontmatter", "toc", "para", "toc", "", 0);
-    comp_obj_.metainfo.identifier                      = "";
-    comp_obj_.metainfo.object_number_off               = true;
-    comp_obj_.metainfo.object_number_type              = 0;
-    comp_obj_.attrib.indent_hang                       = indent["hang_position"];
-    comp_obj_.attrib.indent_base                       = indent["base_position"];
-    comp_obj_.attrib.bullet                            = false;
-    if (the_document_endnotes_section.length > 1) {
-      toc_txt_ = format("%s%s%s%s#%s%s",
-        mkup.lnk_o,
-        "Endnotes",
-        mkup.lnk_c,
-        mkup.url_o,
-        "endnotes",
-        mkup.url_c,
-      );
-      toc_txt_= toc_txt_.links_and_images;
-      comp_obj_.text                                   = toc_txt_.to!string.strip;
-      comp_obj_.has.inline_links                       = true;
-      toc_section_backmatter                           ~= comp_obj_;
-    }
-    if (the_document_glossary_section.length > 1) {
-      toc_txt_ = format("%s%s%s%s#%s%s",
-        mkup.lnk_o,
-        "Glossary",
-        mkup.lnk_c,
-        mkup.url_o,
-        "glossary",
-        mkup.url_c,
-      );
-      toc_txt_= toc_txt_.links_and_images;
-      comp_obj_.text                                   = toc_txt_.to!string.strip;
-      comp_obj_.has.inline_links                       = true;
-      toc_section_backmatter                           ~= comp_obj_;
-    }
-    if (the_document_bibliography_section.length > 1){
-      toc_txt_ = format("%s%s%s%s#%s%s",
-        mkup.lnk_o,
-        "Bibliography",
-        mkup.lnk_c,
-        mkup.url_o,
-        "bibliography",
-        mkup.url_c,
-      );
-      toc_txt_= toc_txt_.links_and_images;
-      comp_obj_.text                                   = toc_txt_.to!string.strip;
-      comp_obj_.has.inline_links                       = true;
-      toc_section_backmatter                           ~= comp_obj_;
-    }
-    if (the_document_bookindex_section.length > 1) {
-      toc_txt_ = format("%s%s%s%s#%s%s",
-        mkup.lnk_o,
-        "Book Index",
-        mkup.lnk_c,
-        mkup.url_o,
-        "bookindex",
-        mkup.url_c,
-      );
-      toc_txt_= toc_txt_.links_and_images;
-      comp_obj_.text                                   = toc_txt_.to!string.strip;
-      comp_obj_.has.inline_links                       = true;
-      toc_section_backmatter                           ~= comp_obj_;
-    }
-    if (the_document_blurb_section.length > 1) {
-      toc_txt_ = format("%s%s%s%s#%s%s",
-        mkup.lnk_o,
-        "Blurb",
-        mkup.lnk_c,
-        mkup.url_o,
-        "blurb",
-        mkup.url_c,
-      );
-      toc_txt_= toc_txt_.links_and_images;
-      comp_obj_.has.inline_links                       = true;
-      comp_obj_.text                                   = toc_txt_.to!string.strip;
-      toc_section_backmatter                           ~= comp_obj_;
-    }
-    debug(toc) {
-      writefln( "%s %s", __LINE__,);
-      foreach (toc_linked_heading; toc_section_backmatter) {
-        writeln(mkup.indent_by_spaces_provided(toc_linked_heading.attrib.indent_hang), toc_linked_heading.text);
-      }
-    }
-    return toc_section_backmatter;
-  }
-  @system public ST_ancestors after_doc_determine_ancestors(
-    ObjGenericComposite[] the_document_body_section,
-    ObjGenericComposite[] the_document_endnotes_section,
-    ObjGenericComposite[] the_document_glossary_section,
-    ObjGenericComposite[] the_document_bibliography_section,
-    ObjGenericComposite[] the_document_bookindex_section,
-    ObjGenericComposite[] the_document_blurb_section,
-  ) {
-    @safe int[] _get_ancestors_markup(ObjGenericComposite obj, int[] _ancestors_markup) {
-      if (obj.metainfo.is_a == "heading") {
-        debug(dom) { writeln(obj.text); }
-        if (obj.metainfo.heading_lev_markup == 1) {
-          _ancestors_markup = [
-            _ancestors_markup[0],
-            0,0,0,0,0,0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_markup == 2) {
-          _ancestors_markup = [
-            _ancestors_markup[0],
-            _ancestors_markup[1],
-            0,0,0,0,0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_markup == 3) {
-          _ancestors_markup = [
-            _ancestors_markup[0],
-            _ancestors_markup[1],
-            _ancestors_markup[2],
-            0,0,0,0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_markup == 4) {
-          _ancestors_markup = [
-            _ancestors_markup[0],
-            _ancestors_markup[1],
-            _ancestors_markup[2],
-            _ancestors_markup[3],
-            0,0,0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_markup == 5) {
-          _ancestors_markup = [
-            _ancestors_markup[0],
-            _ancestors_markup[1],
-            _ancestors_markup[2],
-            _ancestors_markup[3],
-            _ancestors_markup[4],
-            0,0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_markup == 6) {
-          _ancestors_markup = [
-            _ancestors_markup[0],
-            _ancestors_markup[1],
-            _ancestors_markup[2],
-            _ancestors_markup[3],
-            _ancestors_markup[4],
-            _ancestors_markup[5],
-            0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_markup == 7) {
-          _ancestors_markup = [
-            _ancestors_markup[0],
-            _ancestors_markup[1],
-            _ancestors_markup[2],
-            _ancestors_markup[3],
-            _ancestors_markup[4],
-            _ancestors_markup[5],
-            _ancestors_markup[6],
-            0
-          ];
-        }
-        if (obj.metainfo.heading_lev_markup == 8) {
-          _ancestors_markup = [
-            _ancestors_markup[0],
-            _ancestors_markup[1],
-            _ancestors_markup[2],
-            _ancestors_markup[3],
-            _ancestors_markup[4],
-            _ancestors_markup[5],
-            _ancestors_markup[6],
-            _ancestors_markup[7]
-          ];
-        }
-        _ancestors_markup[obj.metainfo.heading_lev_markup] = obj.metainfo.ocn;
-      }
-      debug(ancestor_markup) { writeln("marked up: ", _ancestors_markup); }
-      return _ancestors_markup;
-    }
-    @safe int[] _get_ancestors_collapsed(ObjGenericComposite obj, int[] _ancestors_collapsed) {
-      if (obj.metainfo.is_a == "heading") {
-        if (obj.metainfo.heading_lev_collapsed == 1) {
-          _ancestors_collapsed = [
-            _ancestors_collapsed[0],
-            0,0,0,0,0,0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_collapsed == 2) {
-          _ancestors_collapsed = [
-            _ancestors_collapsed[0],
-            _ancestors_collapsed[1],
-            0,0,0,0,0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_collapsed == 3) {
-          _ancestors_collapsed = [
-            _ancestors_collapsed[0],
-            _ancestors_collapsed[1],
-            _ancestors_collapsed[2],
-            0,0,0,0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_collapsed == 4) {
-          _ancestors_collapsed = [
-            _ancestors_collapsed[0],
-            _ancestors_collapsed[1],
-            _ancestors_collapsed[2],
-            _ancestors_collapsed[3],
-            0,0,0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_collapsed == 5) {
-          _ancestors_collapsed = [
-            _ancestors_collapsed[0],
-            _ancestors_collapsed[1],
-            _ancestors_collapsed[2],
-            _ancestors_collapsed[3],
-            _ancestors_collapsed[4],
-            0,0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_collapsed == 6) {
-          _ancestors_collapsed = [
-            _ancestors_collapsed[0],
-            _ancestors_collapsed[1],
-            _ancestors_collapsed[2],
-            _ancestors_collapsed[3],
-            _ancestors_collapsed[4],
-            _ancestors_collapsed[5],
-            0,0
-          ];
-        }
-        if (obj.metainfo.heading_lev_collapsed == 7) {
-          _ancestors_collapsed = [
-            _ancestors_collapsed[0],
-            _ancestors_collapsed[1],
-            _ancestors_collapsed[2],
-            _ancestors_collapsed[3],
-            _ancestors_collapsed[4],
-            _ancestors_collapsed[5],
-            _ancestors_collapsed[6],
-            0
-          ];
-        }
-        if (obj.metainfo.heading_lev_collapsed == 8) {
-          _ancestors_collapsed = [
-            _ancestors_collapsed[0],
-            _ancestors_collapsed[1],
-            _ancestors_collapsed[2],
-            _ancestors_collapsed[3],
-            _ancestors_collapsed[4],
-            _ancestors_collapsed[5],
-            _ancestors_collapsed[6],
-            _ancestors_collapsed[7]
-          ];
-        }
-        _ancestors_collapsed[obj.metainfo.heading_lev_collapsed] = obj.metainfo.ocn;
-      }
-      debug(ancestor_collapsed) { writeln("collapsed: ", _ancestors_collapsed); }
-      return _ancestors_collapsed;
-    }
-    // multiple 1~ levels, loop through document body
-    if (the_document_body_section.length > 1) {
-      int[] _ancestors_markup = [0,0,0,0,0,0,0,0];
-      int[][] _ancestors_markup_;
-      _ancestors_markup = [1,0,0,0,0,0,0,0];
-      _ancestors_markup_ ~= _ancestors_markup;
-      int[] _ancestors_collapsed = [0,0,0,0,0,0,0,0];
-      int[][] _ancestors_collapsed_;
-      _ancestors_collapsed = [1,0,0,0,0,0,0,0];
-      _ancestors_collapsed_ ~= _ancestors_collapsed;
-      foreach (ref obj; the_document_body_section) {
-        if (obj.metainfo.is_a == "heading") {
-          obj.metainfo.markedup_ancestors = _get_ancestors_markup(obj, _ancestors_markup);
-          obj.metainfo.collapsed_ancestors = _get_ancestors_collapsed(obj, _ancestors_collapsed);
-          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
-        }
-      }
-      debug(ancestors) {
-        writeln("ancestors markup o_n:    ", obj.metainfo.markedup_ancestors);
-        writeln("ancestors collapsed o_n: ", obj.metainfo.markedup_ancestors);
-      }
-    }
-    ST_ancestors ret;
-    ret.the_document_body_section         = the_document_body_section;
-    ret.the_document_endnotes_section     = the_document_endnotes_section;
-    ret.the_document_glossary_section     = the_document_glossary_section;
-    ret.the_document_bibliography_section = the_document_bibliography_section;
-    ret.the_document_bookindex_section    = the_document_bookindex_section;
-    ret.the_document_blurb_section        = the_document_blurb_section;
-    return ret;
-  }
-  @system public ST_segnames after_doc_determine_segnames(
-    ObjGenericComposite[] the_document_body_section,
-    ObjGenericComposite[] the_document_endnotes_section,
-    ObjGenericComposite[] the_document_glossary_section,
-    ObjGenericComposite[] the_document_bibliography_section,
-    ObjGenericComposite[] the_document_bookindex_section,
-    ObjGenericComposite[] the_document_blurb_section,
-    string[][string]      segnames,
-    int                   html_segnames_ptr_cntr,
-    int                   html_segnames_ptr,
-  ) {
-    if (the_document_endnotes_section.length > 1) {
-      segnames["html"] ~= "endnotes";
-      segnames["epub"] ~= "endnotes";
-      html_segnames_ptr = html_segnames_ptr_cntr;
-      foreach (ref obj; the_document_endnotes_section) {
-        if (obj.metainfo.is_a == "heading") {
-          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
-        }
-        if (obj.metainfo.heading_lev_markup == 4) {
-          obj.ptr.html_segnames = html_segnames_ptr;
-          break;
-        }
-      }
-      html_segnames_ptr_cntr++;
-    }
-    if (the_document_glossary_section.length > 1) {
-      segnames["html"] ~= "glossary";
-      segnames["epub"] ~= "glossary";
-      html_segnames_ptr = html_segnames_ptr_cntr;
-      foreach (ref obj; the_document_glossary_section) {
-        if (obj.metainfo.is_a == "heading") {
-          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
-        }
-        if (obj.metainfo.heading_lev_markup == 4) {
-          obj.ptr.html_segnames = html_segnames_ptr;
-          break;
-        }
-      }
-      html_segnames_ptr_cntr++;
-    }
-    if (the_document_bibliography_section.length > 1) {
-      segnames["html"] ~= "bibliography";
-      segnames["epub"] ~= "bibliography";
-      html_segnames_ptr = html_segnames_ptr_cntr;
-      foreach (ref obj; the_document_bibliography_section) {
-        if (obj.metainfo.is_a == "heading") {
-          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
-        }
-        if (obj.metainfo.heading_lev_markup == 4) {
-          obj.ptr.html_segnames = html_segnames_ptr;
-          break;
-        }
-      }
-      html_segnames_ptr_cntr++;
-    }
-    if (the_document_bookindex_section.length > 1) {
-      segnames["html"] ~= "bookindex";
-      segnames["epub"] ~= "bookindex";
-      html_segnames_ptr = html_segnames_ptr_cntr;
-      foreach (ref obj; the_document_bookindex_section) {
-        if (obj.metainfo.is_a == "heading") {
-          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
-        }
-        if (obj.metainfo.heading_lev_markup == 4) {
-          obj.ptr.html_segnames = html_segnames_ptr;
-          break;
-        }
-      }
-      html_segnames_ptr_cntr++;
-    }
-    if (the_document_blurb_section.length > 1) {
-      segnames["html"] ~= "blurb";
-      segnames["epub"] ~= "blurb";
-      html_segnames_ptr = html_segnames_ptr_cntr;
-      foreach (ref obj; the_document_blurb_section) {
-        if (obj.metainfo.is_a == "heading") {
-          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
-        }
-        if (obj.metainfo.heading_lev_markup == 4) {
-          obj.ptr.html_segnames = html_segnames_ptr;
-          break;
-        }
-      }
-      html_segnames_ptr_cntr++;
-    }
-    ST_segnames ret;
-    ret.segnames                          = segnames;
-    ret.html_segnames_ptr_cntr            = html_segnames_ptr_cntr;
-    ret.html_segnames_ptr                 = html_segnames_ptr;
-    return ret;
-  }
-  // decendants
-  @safe auto after_doc_get_decendants()(ObjGenericComposite[] document_sections) {
-    int[string] _heading_ocn_decendants;
-    string[] _ocn_open_key = ["","","","","","","",""];
-    auto _doc_sect_length = document_sections.length - 1;
-    int _last_ocn;
-    foreach (_lg, ref obj; document_sections) {
-      if (obj.metainfo.is_a == "heading") {
-        foreach (_dts_lv, dom_tag_status; obj.metainfo.dom_structure_markedup_tags_status) {
-          switch (dom_tag_status) with (DomTags) {
-          case none: break;
-          case open:
-              _ocn_open_key[_dts_lv] = (obj.metainfo.ocn).to!string;
-              _heading_ocn_decendants[_ocn_open_key[_dts_lv]] = obj.metainfo.ocn;
-            break;
-          case close:
-            if (_ocn_open_key[_dts_lv].empty) {
-              _ocn_open_key[_dts_lv] = "0";
-            }
-            _heading_ocn_decendants[_ocn_open_key[_dts_lv]] = obj.metainfo.ocn - 1;
-            _ocn_open_key[_dts_lv] = (0).to!string;
-            break;
-          case close_and_open:
-            if (_ocn_open_key[_dts_lv].empty) {
-              _ocn_open_key[_dts_lv] = "0";
-            }
-            _heading_ocn_decendants[_ocn_open_key[_dts_lv]] = obj.metainfo.ocn - 1;
-            _ocn_open_key[_dts_lv] = (obj.metainfo.ocn).to!string;
-            _heading_ocn_decendants[_ocn_open_key[_dts_lv]] = obj.metainfo.ocn;
-            break;
-          case open_still: break;
-          default: break;
-          }
-        }
-      }
-      if (obj.metainfo.ocn > 0) {
-        _last_ocn = obj.metainfo.ocn;
-      }
-      if (_lg == _doc_sect_length) {
-        _heading_ocn_decendants["1"] = _last_ocn; // close existing o_n key
-      }
-    }
-    Tuple!(int, int)[] pairs;
-    foreach (pair; _heading_ocn_decendants.byPair) {
-      pairs ~= tuple(pair[0].to!int, pair[1]);
-    }
-    return pairs.sort;
-  }
-  @safe string[] extract_images()(string content_block) {
-    static auto rgx = RgxI();
-    string[] images_;
-    if (auto m = content_block.matchAll(rgx.image)) {
-      images_ ~= m.captures[1];
-    }
-    return images_;
-  }
-  @system auto _image_dimensions(O,M)(O obj, M manifested) {
-    static auto rgx = RgxI();
-    if (obj.has.image_without_dimensions) {
-      import std.math;
-      import imageformats;
-      int w, h, chans;
-      real _w, _h;
-      int max_width = 640;
-      foreach (img; obj.text.matchAll(rgx.inline_image_without_dimensions)) {
-        try {
-          read_image_info(manifested.src.image_dir_path ~ "/" ~ img["img"], w, h, chans);
-        } catch (Exception ex) {
-          writeln("WARNING, image not found: ", img["img"], "\n  ", manifested.src.image_dir_path ~ "/" ~ img["img"]);
-        }
-        // calculate, decide max width and proportionally reduce to keep w & h within it
-        debug(images) { writeln("width: ", w, ", height: ", h); }
-        if (w > max_width) {
-          _w = max_width;
-          _h = round((max_width / w.to!real) * h.to!real);
-        } else {
-          _w = w;
-          _h = h;
-        }
-        obj.text = obj.text.replaceFirst(
-          rgx.inline_image_without_dimensions,
-          format(q"┃%s☼%s,w%sh%s %s┃",
-            "$1",
-            "$3",
-            _w.to!string,
-            _h.to!string,
-            "$6",
-          )
-        );
-      }
-      debug(images) { writeln("image without dimensions: ", obj.text); }
-    }
-    return obj;
-  }
-  // links
-  @safe auto _links(O)(O obj) {
-    static auto rgx = RgxI();
-    if (auto m = obj.text.match(rgx.inline_link_stow_uri)) {
-      debug(links) {
-        writeln("number of link matches to stow: ", (obj.text.match(rgx.inline_link_stow_uri)).count);
-        writeln("links to stow: ", (obj.text.match(rgx.inline_link_stow_uri)));
-      }
-      int _n_matches = (obj.text.match(rgx.inline_link_stow_uri)).count.to!int;
-      for(int i = 0; i < _n_matches; ++i) {
-        if (obj.text.match(rgx.inline_link_stow_uri)) {
-          obj.stow.link ~= obj.text.matchFirst(rgx.inline_link_stow_uri)[2];
-          obj.text = obj.text.replaceFirst(
-            rgx.inline_link_stow_uri,
-            format(q"┃┥%s┝┤%s├┃", "$1", i)
-          );
-        }
-      }
-    }
-    return obj;
-  }
-  struct NodeStructureMetadata {
-    int lv, lv0, lv1, lv2, lv3, lv4, lv5, lv6, lv7;
-    int obj_cite_digit;
-    int[string] p_; // p_ parent_
-    static auto rgx = RgxI();
-    @safe ObjGenericComposite node_location_emitter(La,Ta)(
-      string         lev_markup_number,
-      string[string] tag_in_seg,
-      La             lev_anchor_tag,
-      Ta             tag_assoc,
-      OCNset         obj_cite_digits,
-      int            cntr_,
-      int            ptr_,
-      string         is_
-    ) {
-      debug(asserts) { static assert(is(typeof(obj_cite_digits.object_number) == int)); }
-      assert(is_ != "heading");
-      assert(obj_cite_digits.object_number.to!int >= 0);
-      assert(is_ != "heading");                          // should not be necessary
-      assert(obj_cite_digits.object_number.to!int >= 0); // should not be necessary
-      if (lv7 > eN.bi.off) {
-        p_["lev_markup_number"]                       = DocStructMarkupHeading.h_text_4;
-        p_["object_number"]                           = lv7;
-      } else if (lv6 > eN.bi.off) {
-        p_["lev_markup_number"]                       = DocStructMarkupHeading.h_text_3;
-        p_["object_number"]                           = lv6;
-      } else if (lv5 > eN.bi.off) {
-        p_["lev_markup_number"]                       = DocStructMarkupHeading.h_text_2;
-        p_["object_number"]                           = lv5;
-      } else {
-        p_["lev_markup_number"]                       = DocStructMarkupHeading.h_text_1;
-        p_["object_number"]                           = lv4;
-      }
-      ObjGenericComposite comp_obj_location;
-      comp_obj_location                               = comp_obj_location.init;
-      comp_obj_location.metainfo.is_a                 = is_;
-      comp_obj_location.metainfo.ocn                  = obj_cite_digits.object_number;
-      comp_obj_location.metainfo.identifier           = obj_cite_digits.identifier;
-      comp_obj_location.tags.anchor_tag_html          = tag_in_seg["seg_lv4"];
-      comp_obj_location.tags.segment_anchor_tag_epub  = tag_in_seg["seg_lv1to4"];
-      comp_obj_location.tags.heading_lev_anchor_tag   = lev_anchor_tag;
-      comp_obj_location.metainfo.parent_ocn           = p_["object_number"];
-      comp_obj_location.metainfo.parent_lev_markup    = p_["lev_markup_number"];
-      debug(_node) {
-        if (lev_markup_number.match(rgx.levels_numbered_headings)) { writeln("x ", _node.to!string);
-        } else { writeln("- ", _node.to!string); }
-      }
-      assert(comp_obj_location.metainfo.parent_lev_markup >= 4);
-      assert(comp_obj_location.metainfo.parent_lev_markup <= 7);
-      assert(comp_obj_location.metainfo.parent_ocn >= 0);
-      return comp_obj_location;
-    }
-    invariant() {
-    }
-    @safe ObjGenericComposite node_emitter_heading(O,TaL,TA,SOAT)(
-      O              an_object,
-      string[string] tag_in_seg,
-      TaL            lev_anchor_tag,
-      TA             tag_assoc,
-      OCNset         obj_cite_digits,
-      int            cntr_,
-      int            ptr_,
-      string[]       lv_ancestors_txt,
-      int            html_segnames_ptr,
-      SOAT           substantive_object_and_anchor_tags_struct,
-    ) {
-      string _text                = an_object["substantive"];
-      string lev_markup_number    = an_object["lev_markup_number"];
-      string lev_collapsed_number = an_object["lev_collapsed_number"];
-      string dummy_heading_status = an_object["dummy_heading_status"];
-      string is_                  = an_object["is"];
-      debug(asserts) {
-        static assert(is(typeof(lev)                                       == string));
-        static assert(is(typeof(obj_cite_digits.object_number)             == int));
-      }
-      assert(is_ == "heading");
-      assert((obj_cite_digits.object_number).to!int >= 0);
-      assert(
-        lev_markup_number.match(rgx.levels_numbered),
-        ("not a valid heading level: " ~ lev_markup_number ~ " at " ~ obj_cite_digits.object_number.to!string)
-      );
-      if (lev_markup_number.match(rgx.levels_numbered)) {
-        if (lev_markup_number.to!int == 0) {
-          // TODO first hit (of two) with this assertion failure, check, fix & reinstate
-          // assert(obj_cite_digits.object_number.to!int == 1,
-          //   "ERROR header lev markup number is: " ~
-          //   lev_markup_number.to!string ~
-          //   " obj_cite_digits.object_number.to!int should == 1 but is: " ~
-          //    obj_cite_digits.object_number.to!string ~
-          //   "\n" ~ _text);
-        }
-      }
-      switch (lev_markup_number.to!int) {
-      case 0:
-        lv = DocStructMarkupHeading.h_sect_A;
-        lv0 = obj_cite_digit;
-        lv1 = 0; lv2 = 0; lv3 = 0; lv4 = 0; lv5 = 0; lv6 = 0; lv7 = 0;
-        p_["lev_markup_number"] = 0;
-        p_["object_number"] = 0;
-        break;
-      case 1:
-        lv = DocStructMarkupHeading.h_sect_B;
-        lv1 = obj_cite_digit;
-        lv2 = 0; lv3 = 0; lv4 = 0; lv5 = 0; lv6 = 0; lv7 = 0;
-        p_["lev_markup_number"]
-          = DocStructMarkupHeading.h_sect_A;
-        p_["object_number"] = lv0;
-        break;
-      case 2:
-        lv = DocStructMarkupHeading.h_sect_C;
-        lv2 = obj_cite_digit;
-        lv3 = 0; lv4 = 0; lv5 = 0; lv6 = 0; lv7 = 0;
-        p_["lev_markup_number"]
-          = DocStructMarkupHeading.h_sect_B;
-        p_["object_number"] = lv1;
-        break;
-      case 3:
-        lv = DocStructMarkupHeading.h_sect_D;
-        lv3 = obj_cite_digit;
-        lv4 = 0; lv5 = 0; lv6 = 0; lv7 = 0;
-        p_["lev_markup_number"]
-          = DocStructMarkupHeading.h_sect_C;
-        p_["object_number"] = lv2;
-        break;
-      case 4:
-        lv = DocStructMarkupHeading.h_text_1;
-        lv4 = obj_cite_digit;
-        lv5 = 0; lv6 = 0; lv7 = 0;
-        if (lv3 > eN.bi.off) {
-          p_["lev_markup_number"]
-            = DocStructMarkupHeading.h_sect_D;
-          p_["object_number"] = lv3;
-        } else if (lv2 > eN.bi.off) {
-          p_["lev_markup_number"]
-            = DocStructMarkupHeading.h_sect_C;
-          p_["object_number"] = lv2;
-        } else if (lv1 > eN.bi.off) {
-          p_["lev_markup_number"]
-            = DocStructMarkupHeading.h_sect_B;
-          p_["object_number"] = lv1;
-        } else {
-          p_["lev_markup_number"]
-            = DocStructMarkupHeading.h_sect_A;
-          p_["object_number"] = lv0;
-        }
-        break;
-      case 5:
-        lv = DocStructMarkupHeading.h_text_2;
-        lv5 = obj_cite_digit;
-        lv6 = 0; lv7 = 0;
-        p_["lev_markup_number"]
-          = DocStructMarkupHeading.h_text_1;
-        p_["object_number"] = lv4;
-        break;
-      case 6:
-        lv = DocStructMarkupHeading.h_text_3;
-        lv6 = obj_cite_digit;
-        lv7 = 0;
-        p_["lev_markup_number"]
-          = DocStructMarkupHeading.h_text_2;
-        p_["object_number"] = lv5;
-        break;
-      case 7:
-        lv = DocStructMarkupHeading.h_text_4;
-        lv7 = obj_cite_digit;
-        p_["lev_markup_number"]
-          = DocStructMarkupHeading.h_text_3;
-        p_["object_number"] = lv6;
-        break;
-      default:
-        break;
-      }
-      ObjGenericComposite comp_obj_;
-      comp_obj_                                        = comp_obj_.init;
-      comp_obj_.metainfo.is_of_part                    = "body";
-      comp_obj_.metainfo.is_of_section                 = "body";
-      comp_obj_.metainfo.is_of_type                    = "para";
-      comp_obj_.metainfo.is_a                          = "heading";
-      comp_obj_.text                                   = _text.to!string.strip;
-      comp_obj_.metainfo.ocn                           = obj_cite_digits.object_number;
-      comp_obj_.metainfo.identifier                    = obj_cite_digits.identifier;
-      comp_obj_.metainfo.dummy_heading                 = (dummy_heading_status == "t") ? true: false;
-      comp_obj_.metainfo.object_number_off             = obj_cite_digits.off;
-      // comp_obj_.metainfo.o_n_book_index             = obj_cite_digits.bkidx;
-      comp_obj_.metainfo.object_number_type            = obj_cite_digits.type;
-      comp_obj_.tags.segment_anchor_tag_epub           = tag_in_seg["seg_lv1to4"];
-      comp_obj_.tags.anchor_tag_html                   = tag_in_seg["seg_lv4"];
-      comp_obj_.tags.in_segment_html                   = comp_obj_.tags.anchor_tag_html;
-      comp_obj_.tags.heading_lev_anchor_tag            = lev_anchor_tag;
-      comp_obj_.tags.html_segment_anchor_tag_is        = tag_in_seg["seg_lv4"];
-      comp_obj_.tags.epub_segment_anchor_tag_is        = tag_in_seg["seg_lv1to4"];
-      comp_obj_.metainfo.heading_lev_markup            = (!(lev_markup_number.empty) ? lev_markup_number.to!int : 0);
-      comp_obj_.metainfo.heading_lev_collapsed         = (!(lev_collapsed_number.empty) ? lev_collapsed_number.to!int : 0);
-      comp_obj_.metainfo.parent_ocn                    = p_["object_number"];
-      comp_obj_.metainfo.parent_lev_markup             = p_["lev_markup_number"];
-      comp_obj_.tags.heading_ancestors_text            = lv_ancestors_txt;
-      comp_obj_.ptr.doc_object                         = cntr_;
-      comp_obj_.ptr.html_segnames                      = ((lev_markup_number == "4") ? html_segnames_ptr : 0);
-      comp_obj_.ptr.heading                            = ptr_;
-      comp_obj_.has.inline_notes_reg                   = substantive_object_and_anchor_tags_struct.has_notes_reg;
-      comp_obj_.has.inline_notes_star                  = substantive_object_and_anchor_tags_struct.has_notes_star;
-      comp_obj_.has.inline_links                       = substantive_object_and_anchor_tags_struct.has_links;
-      tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
-      tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
-      debug(_node) {
-        if (lev_markup_number.match(rgx.levels_numbered_headings)) { writeln("* ", _node.to!string); }
-      }
-      debug(nodeheading) {
-        if (lev_markup_number.match(rgx.levels_numbered_headings)) { writeln("* ", _node.to!string); }
-      }
-      assert(comp_obj_.metainfo.parent_lev_markup <= 7);
-      assert(comp_obj_.metainfo.parent_ocn >= 0);
-      if (lev_markup_number.match(rgx.levels_numbered_headings)) {
-        assert(comp_obj_.metainfo.heading_lev_markup <= 7);
-        assert(comp_obj_.metainfo.ocn >= 0);
-        if (comp_obj_.metainfo.parent_lev_markup > 0) {
-          assert(comp_obj_.metainfo.parent_lev_markup < comp_obj_.metainfo.heading_lev_markup);
-          if (comp_obj_.metainfo.ocn != 0) {
-            assert(comp_obj_.metainfo.parent_ocn < comp_obj_.metainfo.ocn);
-          }
-        }
-        if (comp_obj_.metainfo.heading_lev_markup == 0) {
-          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_sect_A);
-        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_sect_B) {
-          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_sect_A);
-        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_sect_C) {
-          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_sect_B);
-        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_sect_D) {
-          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_sect_C);
-        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_text_1) {
-          assert(comp_obj_.metainfo.parent_lev_markup <= DocStructMarkupHeading.h_sect_D);
-        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_text_2) {
-          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_text_1);
-        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_text_3) {
-          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_text_2);
-        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_text_4) {
-          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_text_3);
-        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_text_5) {
-        }
-      }
-      return comp_obj_;
-    }
-    invariant() {
-    }
-  }
-  // abstraction functions emitters ↑
-  // ↓ abstraction functions assertions
-  @safe pure void assertions_doc_structure()(
-    string[string]  an_object,
-    string          an_object_key,
-    int[string]     lv
-  ) {
-    string msg_error_doc_struct = "\nERROR in document structure, check markup (heading level relationships):\n";
-    if (lv["h3"] > eN.bi.off) {
-      assert(lv["h0"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h1"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h2"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    } else if (lv["h2"] > eN.bi.off) {
-      assert(lv["h0"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h1"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h3"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    } else if (lv["h1"] > eN.bi.off) {
-      assert(lv["h0"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h2"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h3"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    } else if (lv["h0"] > eN.bi.off) {
-      assert(lv["h1"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h2"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h3"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    } else {
-      assert(lv["h0"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h1"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h2"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h3"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    }
-    if (lv["h7"] > eN.bi.off) {
-      assert(lv["h4"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ "missing segment level 1~\n"
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h5"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h6"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    } else if (lv["h6"] > eN.bi.off) {
-      assert(lv["h4"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ "missing segment level 1~\n"
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h5"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h7"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    } else if (lv["h5"] > eN.bi.off) {
-      assert(lv["h4"] > eN.bi.off,
-        msg_error_doc_struct
-        ~ "missing segment level 1~\n"
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h6"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h7"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    } else if (lv["h4"] > eN.bi.off) {
-      assert(lv["h5"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h6"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h7"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    } else {
-      assert(lv["h4"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ "missing segment level 1~\n"
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h5"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h6"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h7"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    }
-    if (lv["h0"] == eN.bi.off) {
-      assert(lv["h1"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h2"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h3"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h4"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ "missing segment level 1~\n"
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h5"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h6"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h7"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    }
-    if (lv["h1"] == eN.bi.off) {
-      assert(lv["h2"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h3"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    }
-    if (lv["h2"] == eN.bi.off) {
-      assert(lv["h3"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    }
-    if (lv["h3"] == eN.bi.off) {
-    }
-    if (lv["h4"] == eN.bi.off) {
-      assert(lv["h5"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h6"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h7"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    }
-    if (lv["h5"] == eN.bi.off) {
-      assert(lv["h6"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-      assert(lv["h7"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    }
-    if (lv["h6"] == eN.bi.off) {
-      assert(lv["h7"] == eN.bi.off,
-        msg_error_doc_struct
-        ~ an_object[an_object_key]
-      );
-    }
-    if (lv["h7"] == eN.bi.off) {
-    }
-    switch ((an_object["lev"]).to!string) {
-    case "A":
-      if (lv["h0"] == eN.bi.off) {
-        assert(lv["h1"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level A~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h2"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level A~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h3"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level A~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h4"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 1~\n"
-          ~ "at level A~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h5"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level A~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h6"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level A~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h7"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level A~\n"
-          ~ an_object[an_object_key]
-        );
-      } else {                       // (lv["h0"] > eN.bi.off)
-        assert(lv["h0"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "should not enter level A a second time\n"
-          ~ "at level A~\n"
-          ~ an_object[an_object_key]
-        );
-      }
-      break;
-    case "B":
-      if (lv["h1"] == eN.bi.off) {
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level B~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h2"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level B~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h3"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level B~\n"
-          ~ an_object[an_object_key]
-        );
-      } else {                       // (lv["h1"] > eN.bi.off)
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level B~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h1"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level B~\n"
-          ~ an_object[an_object_key]
-        );
-      }
-      break;
-    case "C":
-      if (lv["h2"] == eN.bi.off) {
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level C~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h1"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "level C should not follow level A\n"
-          ~ "at level C~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h3"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level C~\n"
-          ~ an_object[an_object_key]
-        );
-      } else {                       // (lv["h2"] > eN.bi.off)
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level C~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h1"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level C~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h2"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level C~\n"
-          ~ an_object[an_object_key]
-        );
-      }
-      break;
-    case "D":
-      if (lv["h3"] == eN.bi.off) {
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level D~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h1"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "level D should not follow level A\n"
-          ~ "at level D~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h2"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level D~\n"
-          ~ an_object[an_object_key]
-        );
-      } else {                      // (lv["h3"] > eN.bi.off)
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level D~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h1"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level D~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h2"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level D~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h3"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level D~\n"
-          ~ an_object[an_object_key]
-        );
-      }
-      break;
-    case "1":
-      if (lv["h4"] == eN.bi.off) {
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 1~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h5"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 1~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h6"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 1~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h7"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 1~\n"
-          ~ an_object[an_object_key]
-        );
-      } else {                      // (lv["h4"] > eN.bi.off)
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 1~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h4"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 1~ ?\n"
-          ~ "at level 1~\n"
-          ~ an_object[an_object_key]
-        );
-      }
-      break;
-    case "2":
-      if (lv["h5"] == eN.bi.off) {
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 2~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h4"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 1~ ?\n"
-          ~ "at level 2~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h6"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 2~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h7"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 2~\n"
-          ~ an_object[an_object_key]
-        );
-      } else {                      // (lv["h5"] > eN.bi.off)
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 2~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h4"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 1~ ?\n"
-          ~ "at level 2~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h5"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 2~\n"
-          ~ an_object[an_object_key]
-        );
-      }
-      break;
-    case "3":
-      if (lv["h6"] == eN.bi.off) {
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 3~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h4"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 1~ ?\n"
-          ~ "at level 3~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h5"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 2~ ?\n"
-          ~ "at level 3~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h7"] == eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 3~\n"
-          ~ an_object[an_object_key]
-        );
-      } else {                      // (lv["h6"] > eN.bi.off)
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 3~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h4"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 1~ ?\n"
-          ~ "at level 3~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h5"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 3~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h6"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 3~\n"
-          ~ an_object[an_object_key]
-        );
-      }
-      break;
-    case "4":
-      if (lv["h7"] == eN.bi.off) {
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 4~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h4"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 1~ ?\n"
-          ~ "at level 4~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h5"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 2~ ?\n"
-          ~ "at level 4~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h6"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 3~ ?\n"
-          ~ "at level 4~\n"
-          ~ an_object[an_object_key]
-        );
-      } else {                      // (lv["h7"] > eN.bi.off)
-        assert(lv["h0"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 4~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h4"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "missing segment level 1~ ?\n"
-          ~ "at level 4~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h5"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 4~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h6"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 4~\n"
-          ~ an_object[an_object_key]
-        );
-        assert(lv["h7"] > eN.bi.off,
-          msg_error_doc_struct
-          ~ "at level 4~\n"
-          ~ an_object[an_object_key]
-        );
-      }
-      break;
-    default:
-      break;
-    }
-  }
-  // abstraction functions assertions ↑
-}
-template docSectKeysSeq() {
-  @safe auto docSectKeysSeq(string[][string] document_section_keys_sequenced) {
-    struct doc_sect_keys_seq {
-      string[] scroll() {
-        return document_section_keys_sequenced["scroll"];
-      }
-      string[] seg() {
-        return document_section_keys_sequenced["seg"];
-      }
-      string[] sql() {
-        return document_section_keys_sequenced["sql"];
-      }
-      string[] latex() {
-        return document_section_keys_sequenced["latex"];
-      }
-    }
-    return doc_sect_keys_seq();
-  }
 }
diff --git a/src/doc_reform/meta/metadoc_from_src_functions.d b/src/doc_reform/meta/metadoc_from_src_functions.d
new file mode 100644
index 0000000..557bfef
--- /dev/null
+++ b/src/doc_reform/meta/metadoc_from_src_functions.d
@@ -0,0 +1,5215 @@
+/+
+- 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 - 2024 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]
+
++/
+// document abstraction:
+// abstraction of sisu markup for downstream processing
+// metadoc_from_src.d
+module doc_reform.meta.metadoc_from_src_functions;
+template docAbstractionFunctions() {
+  // ↓ abstraction imports
+  import
+    std.algorithm,
+    std.container,
+    std.file,
+    std.json,
+    std.path;
+  import
+    doc_reform.meta,
+    doc_reform.meta.defaults,
+    doc_reform.meta.rgx,
+    doc_reform.meta.metadoc_object_setter,
+    doc_reform.meta.rgx;
+  // ↓ abstraction mixins
+  mixin ObjectSetter;
+  mixin InternalMarkup;
+  mixin spineRgxIn;
+  static auto rgx = RgxI();
+  // initialize
+  string[string] an_object, processing, object_notes;
+  string an_object_key;
+  string[] anchor_tags;
+  string anchor_tag;
+  string anchor_tag_;
+  string[string] tag_in_seg;
+  string lev_anchor_tag;
+  string[string][string] tag_assoc;
+  string[] lv0to3_tags;
+  // enum
+  // biblio variables
+  string biblio_tag_name, biblio_tag_entry, st;
+  string[] biblio_arr_json;
+  string biblio_entry_str_json;
+  JSONValue[] bib_arr_json;
+  int bib_entry;
+  // counters
+  int cntr, previous_count, previous_length;
+  bool reset_note_numbers = true;
+  int[string] line_occur;
+  int html_segnames_ptr = 0;
+  int html_segnames_ptr_cntr = 0;
+  int verse_line, heading_ptr;
+  // paragraph attributes
+  int[string] indent;
+  bool bullet = true;
+  string content_non_header = "8";
+  // ocn
+  OCNset obj_cite_digits;
+  int obj_cite_digit_, obj_cite_digit_off, obj_cite_digit_bkidx, obj_cite_digit_type;
+  int[] dom_structure_markedup_tags_status         = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,];
+  int[] dom_structure_markedup_tags_status_buffer  = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,];
+  int[] dom_structure_collapsed_tags_status        = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,];
+  int[] dom_structure_collapsed_tags_status_buffer = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,];
+  static auto obj_im = ObjInlineMarkup();
+  static auto obj_att = ObjAttributes();
+  auto object_citation_number = OCNemitter();
+  auto node_construct = NodeStructureMetadata();
+  // ↓ abstraction function emitters
+  // ↓ - emitters
+  @safe pure struct OCNemitter {
+    int ocn_digit, ocn_object_number, ocn_on_, ocn_off_, ocn_bkidx, ocn_bkidx_;
+    string object_identifier;
+    bool ocn_is_off;
+    @safe auto ocn_emitter(int ocn_status_flag) {
+      OCNset ocn;
+      assert(ocn_status_flag <= eN.ocn.reset);
+      ocn_object_number              = ocn_bkidx = 0;
+      object_identifier              = "";
+      ocn_is_off                     = false;
+      switch(ocn_status_flag) with (eN.ocn) {
+      case reset:
+        ocn_digit                    = ocn_on_             = 1;
+        object_identifier            = "1";
+        ocn_is_off                   = false;
+        ocn_off_                     = ocn_bkidx_ = 0;
+        break;
+      case on:
+        ocn_digit                    = ocn_object_number   = ++ocn_on_;
+        object_identifier            = ocn_digit.to!string;
+        ocn_is_off                   = false;
+        break;
+      case off:
+        ocn_digit                    = 0;
+        ocn_off_                     = ++ocn_off_;
+        object_identifier            = "a" ~ ocn_off_.to!string;
+        ocn_is_off                   = true;
+        break;
+      case bkidx:
+        ocn_bkidx                    = ++ocn_bkidx_;
+        break;
+      case closing: // unused?
+        break;
+      default:
+        ocn_digit                    = 0;
+      }
+      assert(ocn_digit >= 0);
+      ocn.digit                      = ocn_digit;
+      ocn.object_number              = ocn_object_number; // difference between .object_number and .digit?
+      ocn.identifier                 = object_identifier;
+      ocn.off                        = ocn_is_off;
+      ocn.bkidx                      = ocn_bkidx;
+      ocn.type                       = ocn_status_flag;
+      return ocn;
+    }
+    invariant() {
+    }
+  }
+  @safe pure ObjGenericComposite obj_heading_ancestors()(
+    ObjGenericComposite  obj,
+    string[]             lv_ancestors_txt,
+  ) {
+    switch (obj.metainfo.heading_lev_markup) {
+    case 0:
+      lv_ancestors_txt[0] = obj.text.to!string;
+      foreach(k; 1..8) { lv_ancestors_txt[k] = ""; }
+      goto default;
+    case 1:
+      lv_ancestors_txt[1] = obj.text.to!string;
+      foreach(k; 2..8) { lv_ancestors_txt[k] = ""; }
+      goto default;
+    case 2:
+      lv_ancestors_txt[2] = obj.text.to!string;
+      foreach(k; 3..8) { lv_ancestors_txt[k] = ""; }
+      goto default;
+    case 3:
+      lv_ancestors_txt[3] = obj.text.to!string;
+      foreach(k; 4..8) { lv_ancestors_txt[k] = ""; }
+      goto default;
+    case 4:
+      lv_ancestors_txt[4] = obj.text.to!string;
+      foreach(k; 5..8) { lv_ancestors_txt[k] = ""; }
+      goto default;
+    case 5:
+      lv_ancestors_txt[5] = obj.text.to!string;
+      foreach(k; 6..8) { lv_ancestors_txt[k] = ""; }
+      goto default;
+    case 6:
+      lv_ancestors_txt[6] = obj.text.to!string;
+      lv_ancestors_txt[7] = "";
+      goto default;
+    case 7:
+      lv_ancestors_txt[7] = obj.text.to!string;
+      goto default;
+    default:
+      obj.tags.heading_ancestors_text = lv_ancestors_txt.dup;
+    }
+    return obj;
+  }
+  @safe static  OCNset ocn_emit(int ocn_status_flag) {
+    return object_citation_number.ocn_emitter(ocn_status_flag);
+  }
+  @safe static uint[string] _check_ocn_status_()(
+    char[]       line,
+    uint[string] pith,
+  ) {
+    static auto rgx = RgxI();
+    if (!(line.empty)) {
+      if (pith["no_ocn_multiple_objects"] == eN.bi.off) {
+        // not multi-line object, check whether object_number is on or turned off
+        if (line.matchFirst(rgx.object_number_block_marks)) {                      // switch off object_number
+          if (line.matchFirst(rgx.object_number_off_block)) {
+            pith["no_ocn_multiple_objects"]             = eN.bi.on;
+            pith["ocn"]                                 = eN.ocn.off;
+            debug(ocnoff) { writeln(line); }
+          }
+          if (line.matchFirst(rgx.object_number_off_block_dummy_heading)) {
+            pith["no_ocn_multiple_objects"]             = eN.bi.on;
+            pith["dummy_heading_multiple_objects"]      = eN.bi.on;
+            pith["ocn"]                                 = eN.ocn.off;
+            debug(ocnoff) { writeln(line); }
+          }
+        } else if (pith["no_ocn_multiple_objects"] == eN.bi.off) {
+            pith["dummy_heading_status"]                = eN.bi.off;
+            if (pith["dummy_heading_multiple_objects"]) {
+              pith["dummy_heading_status"]              = eN.bi.on;
+            }
+            if (line.matchFirst(rgx.object_number_off)) {
+              pith["ocn"]                               = eN.ocn.off;
+            } else if (line.matchFirst(rgx.object_number_off_dummy_heading)) {
+              pith["ocn"]                               = eN.ocn.off;
+              pith["dummy_heading_status"]              = eN.bi.on;
+            } else {
+              pith["ocn"]                               = eN.ocn.on;
+              pith["dummy_heading_status"]              = eN.bi.off;
+            }
+          } else {
+            pith["ocn"] = pith["no_ocn_multiple_objects"];
+          }
+      } else if (pith["no_ocn_multiple_objects"] == eN.bi.on) {
+        if (line.matchFirst(rgx.object_number_off_block_close)) {
+          pith["no_ocn_multiple_objects"]               = eN.bi.off;
+          pith["ocn"]                                   = eN.ocn.on;
+          pith["dummy_heading_status"]                  = eN.bi.off;
+          debug(ocnoff) { writeln(line); }
+        }
+      }
+    }
+    return pith;
+  }
+  // ↑ - emitters ↑
+  // ↓ abstraction functions
+  // ↓ - reset text by line
+  @system ST_txt_by_line_common_reset txt_by_line_common_reset_()(
+    int[string]     line_occur,
+    string[string]  an_object,
+    uint[string]    pith,
+  ) {
+    line_occur["heading"]                               = eN.bi.off;
+    line_occur["para"]                                  = eN.bi.off;
+    pith["txt_is"]                                      = eN.txt_is.off;
+    an_object                                           = an_object.object_reset;
+    ST_txt_by_line_common_reset ret;
+    {
+      ret.line_occur  = line_occur;
+      ret.this_object = an_object;
+      ret.pith        = pith;
+    }
+    return ret;
+  }
+  // ↓ - reset object
+  @safe static string[string] object_reset()(string[string] an_object) {
+    an_object.remove("body_nugget");
+    an_object.remove("substantive");
+    an_object.remove("is");
+    an_object.remove("attrib");
+    an_object.remove("bookindex_nugget");
+    return an_object;
+  }
+  // ↑ - resets
+  // ↓ - markup text by line
+  @safe char[] font_faces_line()(char[] textline) {
+    static auto rgx = RgxI();
+    static auto mkup = InlineMarkup();
+    if (textline.match(rgx.inline_faces_line)) {
+      textline = textline
+        .replaceFirst(rgx.inline_emphasis_line,
+          format(q"┃%s%s%s%s%s%s%s┃",
+            mkup.ff_i, mkup.emph, mkup.ff_o, "$1", mkup.ff_c, mkup.emph, "$2"))
+        .replaceFirst(rgx.inline_bold_line,
+          format(q"┃%s%s%s%s%s%s%s┃",
+            mkup.ff_i, mkup.bold, mkup.ff_o, "$1", mkup.ff_c, mkup.bold, "$2"))
+        .replaceFirst(rgx.inline_underscore_line,
+          format(q"┃%s%s%s%s%s%s%s┃",
+            mkup.ff_i, mkup.underscore, mkup.ff_o, "$1", mkup.ff_c, mkup.underscore, "$2"))
+        .replaceFirst(rgx.inline_italics_line,
+          format(q"┃%s%s%s%s%s%s%s┃",
+            mkup.ff_i, mkup.italic,  mkup.ff_o, "$1", mkup.ff_c, mkup.italic, "$2"));
+    }
+    return textline;
+  }
+  @safe auto inline_markup_faces(L)(L line) {
+    static auto rgx = RgxI();
+    static auto mkup = InlineMarkup();
+    line = replaceAll!(m => mkup.quote_o ~ m[1] ~ mkup.quote_c)(line, rgx.within_quotes);
+    line = replaceAll!(m => mkup.ff_i ~ mkup.mono ~ mkup.ff_o ~ m["text"] ~ mkup.ff_c ~ mkup.mono)(line, rgx.inline_mark_mono);
+    line = replaceAll!(m => mkup.ff_i ~ mkup.cite ~ mkup.ff_o ~ m["text"] ~ mkup.ff_c ~ mkup.cite)(line, rgx.inline_mark_cite);
+    foreach (regx; [rgx.inline_mark_emphasis, rgx.inline_mark_bold, rgx.inline_mark_underscore, rgx.inline_mark_italics, rgx.inline_mark_superscript, rgx.inline_mark_subscript, rgx.inline_mark_strike, rgx.inline_mark_insert]) {
+      line = replaceAll!(m => mkup.ff_i ~ m["mark"] ~ mkup.ff_o ~ m["text"] ~ mkup.ff_c ~ m["mark"])(line, regx);
+    }
+    return line;
+  }
+  @safe static string links_and_images()(string obj_txt) {
+    static auto rgx = RgxI();
+    static auto mkup = InlineMarkup();
+    if (obj_txt.match(rgx.smid_inline_url_generic)) {
+      if (
+        obj_txt.match(rgx.smid_inline_link_endnote_url_helper)
+        || obj_txt.match(rgx.smid_inline_link_endnote_url_helper_punctuated)
+      ) {
+        obj_txt = replaceAll!(m => format("%s%s%s%s%s%s%s %s%s%s%s%s%s %s%s",
+          mkup.lnk_o, m["content"].strip, mkup.lnk_c,
+          mkup.url_o, m["link"], mkup.url_c,
+          mkup.en_a_o,
+          mkup.lnk_o, m["link"].strip, mkup.lnk_c,
+          mkup.url_o, m["link"], mkup.url_c,
+          mkup.en_a_c,
+          m[3]
+        ))(obj_txt, rgx.smid_inline_link_endnote_url_helper_punctuated);
+        obj_txt = replaceAll!(m => format("%s%s%s%s%s%s%s %s%s%s%s%s%s %s",
+          mkup.lnk_o, m["content"].strip, mkup.lnk_c,
+          mkup.url_o, m["link"], mkup.url_c,
+          mkup.en_a_o,
+          mkup.lnk_o, m["link"].strip, mkup.lnk_c,
+          mkup.url_o, m["link"], mkup.url_c,
+          mkup.en_a_c
+        ))(obj_txt, rgx.smid_inline_link_endnote_url_helper);
+    } else {
+        obj_txt = replaceAll!(m => format("%s%s%s%s%s%s%s",
+          m["pre"],
+          mkup.lnk_o, m["content"].strip, mkup.lnk_c,
+          mkup.url_o, m["link"], mkup.url_c
+        ))(obj_txt, rgx.smid_inline_link_markup_regular);
+      }
+        obj_txt = replaceAll!(m => format("%s%s%s%s%s%s%s",
+          m["pre"],
+          mkup.lnk_o, m["link"].strip, mkup.lnk_c,
+          mkup.url_o, m["link"], mkup.url_c
+        ))(obj_txt, rgx.smid_inline_link_naked_url); //
+    }
+    return obj_txt;
+  }
+  @safe char[] _doc_header_and_make_substitutions_(CMM)(
+    char[]  line,
+    CMM     conf_make_meta,
+  ) {
+    enum Substitute { match, markup, }
+    if (conf_make_meta.make.substitute) {
+      foreach(substitution_pair; conf_make_meta.make.substitute) {
+        line = line.replaceAll(
+          regex("\b" ~ substitution_pair[Substitute.match]),
+          substitution_pair[Substitute.markup]
+        );
+      }
+    }
+    return line;
+  }
+  @safe char[] _doc_header_and_make_substitutions_fontface_(CMM)(
+    char[]  line,
+    CMM     conf_make_meta,
+  ) {
+    enum Substitute { match, markup, }
+    if ( conf_make_meta.make.bold) {
+      line = line.replaceAll(
+        regex("\b" ~ conf_make_meta.make.bold[Substitute.match]),
+        conf_make_meta.make.bold[Substitute.markup]
+      );
+    }
+    if (conf_make_meta.make.emphasis) {
+      line = line.replaceAll(
+        regex("\b" ~ conf_make_meta.make.emphasis[Substitute.match]),
+        conf_make_meta.make.emphasis[Substitute.markup]
+      );
+    }
+    if (conf_make_meta.make.italics) {
+      line = line.replaceAll(
+        regex("\b" ~ conf_make_meta.make.italics[Substitute.match]),
+        conf_make_meta.make.italics[Substitute.markup]
+      );
+    }
+    return line;
+  }
+  // ↑ - markup by line
+  // ↓ - text by line (blocks etc.)
+  @safe ST_txt_by_line_block_start txt_by_line_block_start()(
+    char[]         line,
+    uint[string]   pith,
+    uint[string]   dochas,
+    string[string] object_number_poem
+  ) {
+    static auto rgx = RgxI();
+    if (auto m = line.matchFirst(rgx.block_curly_code_open)) {
+      dochas["codeblock"]++;
+      an_object["lang"]               = "";
+      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
+      an_object["syntax"]             = (m["syntax"]) ? m["syntax"].to!string : "";
+      debug(codecurly) { writefln( "* [code curly] %s", line); }                              // code (curly) open
+      pith["block_is"]                = eN.blk_is.code;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.curly;
+    } else if (auto m = line.matchFirst(rgx.block_curly_poem_open)) {
+      dochas["poem"]++;
+      an_object["syntax"]             = "";
+      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
+      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
+      debug(poem) { writefln( "* [poem curly] %s", line); }                              // poem (curly) open
+      object_number_poem["start"]     = obj_cite_digits.object_number.to!string;
+      pith["block_is"]                = eN.blk_is.poem;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.curly;
+      pith["verse_new"]               = eN.bi.on;
+    } else if (auto m = line.matchFirst(rgx.block_curly_group_open)) {
+      dochas["group"]++;
+      an_object["syntax"]             = "";
+      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
+      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
+      debug(group) { writefln( "* [group curly] %s", line); }                             // group (curly) open
+      pith["block_is"]                = eN.blk_is.group;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.curly;
+    } else if (auto m = line.matchFirst(rgx.block_curly_block_open)) {
+      dochas["block"]++;
+      an_object["syntax"]             = "";
+      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
+      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
+      debug(block) { writefln( "* [block curly] %s", line); }
+      pith["block_is"]                = eN.blk_is.block;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.curly;
+    } else if (auto m = line.matchFirst(rgx.block_curly_quote_open)) {
+      dochas["quote"]++;
+      an_object["syntax"]             = "";
+      an_object["attrib"]             = m["attrib"].to!string;
+      an_object["lang"]               = m["lang"].to!string;
+      debug(quote) { writefln( "* [quote curly] %s", line); }
+      pith["block_is"]                = eN.blk_is.quote;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.curly;
+    } else if (auto m = line.matchFirst(rgx.block_curly_table_open)) {           // curly table open
+      debug(table) { writefln( "* [table curly] %s", line); }
+      dochas["table"] ++;
+      an_object["table_head"]         = m["attrib"].to!string;
+      an_object["block_type"]         = "curly";
+      pith["block_is"]                = eN.blk_is.table;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.curly;
+    } else if (auto m = line.matchFirst(rgx.block_curly_table_special_markup)) { // table: special table block markup syntax!
+      dochas["table"]++;
+      an_object["table_head"]         = m["attrib"].to!string;
+      an_object["block_type"]         = "special";
+      pith["block_is"]                = eN.blk_is.table;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.curly_special;
+    } else if (auto m = line.matchFirst(rgx.block_tic_code_open)) {
+      dochas["codeblock"]++;
+      an_object["lang"]               = "";
+      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
+      an_object["syntax"]             = (m["syntax"]) ? m["syntax"].to!string : "";
+      debug(codetic) { writefln( "* [code tic] %s", line); }
+      pith["block_is"]                = eN.blk_is.code;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.tic;
+    } else if (auto m = line.matchFirst(rgx.block_tic_poem_open)) {
+      dochas["poem"]++;
+      an_object["syntax"]             = "";
+      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
+      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
+      debug(poem) { writefln( "* [poem tic] %s", line); }
+      object_number_poem["start"]     = obj_cite_digits.object_number.to!string;
+      pith["block_is"]                = eN.blk_is.poem;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.tic;
+      pith["verse_new"]               = eN.bi.on;
+    } else if (auto m = line.matchFirst(rgx.block_tic_group_open)) {
+      dochas["group"]++;
+      an_object["syntax"]             = "";
+      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
+      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
+      debug(group) { writefln( "* [group tic] %s", line); }
+      pith["block_is"]                = eN.blk_is.group;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.tic;
+    } else if (auto m = line.matchFirst(rgx.block_tic_block_open)) {
+      dochas["block"]++;
+      an_object["syntax"]             = "";
+      an_object["attrib"]             = (m["attrib"]) ? m["attrib"].to!string : "";
+      an_object["lang"]               = (m["lang"]) ? m["lang"].to!string : "";
+      debug(block) { writefln( "* [block tic] %s", line); }
+      pith["block_is"]                = eN.blk_is.block;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.tic;
+    } else if (auto m = line.matchFirst(rgx.block_tic_quote_open)) {
+      dochas["quote"]++;
+      an_object["syntax"]             = "";
+      an_object["attrib"]             = m["attrib"].to!string;
+      an_object["lang"]               = m["lang"].to!string;
+      debug(quote) { writefln( "* [quote tic] %s", line);                        // quote (tic) open
+      }
+      pith["block_is"]                = eN.blk_is.quote;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.tic;
+    } else if (auto m = line.matchFirst(rgx.block_tic_table_open)) {             // tic table open
+      debug(table) { writefln( "* [table tic] %s", line); }
+      dochas["table"] ++;
+      an_object["table_head"]         = m["attrib"].to!string;
+      an_object["block_type"]         = "tic";
+      pith["block_is"]                = eN.blk_is.table;
+      pith["block_state"]             = eN.blk_state.on;
+      pith["block_delim"]             = eN.blk_delim.tic;
+    }
+    ST_txt_by_line_block_start ret;
+    {
+      ret.pith               = pith;
+      ret.dochas             = dochas;
+      ret.object_number_poem = object_number_poem;
+    }
+    return ret;
+  }
+  @safe ST_txt_by_line_block_generic txt_by_line_block_group()(
+    char[]          line,
+    string[string]  an_object,
+    uint[string]    pith,
+  ) {
+    static auto rgx = RgxI();
+    if (pith["block_is"] == eN.blk_is.group) {
+      if (pith["block_delim"] == eN.blk_delim.curly) {
+        if (line.matchFirst(rgx.block_curly_group_close)) {
+          debug(group) { writeln(line); }
+          an_object[an_object_key]    = an_object[an_object_key].stripRight;
+          pith["block_is"]            = eN.blk_is.group;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          debug(group) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      } else if (pith["block_delim"] == eN.blk_delim.tic) {
+        if (line.matchFirst(rgx.block_tic_close)) {
+          debug(group) { writeln(line); }
+          an_object[an_object_key]    = an_object[an_object_key].stripRight;
+          pith["block_is"]            = eN.blk_is.group;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          debug(group) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      }
+    }
+    ST_txt_by_line_block_generic ret;
+    {
+      ret.pith        = pith;
+      ret.this_object = an_object;
+    }
+    return ret;
+  }
+  @safe ST_txt_by_line_block_generic txt_by_line_block_block()(
+    char[]          line,
+    string[string]  an_object,
+    uint[string]    pith,
+  ) {
+    static auto rgx = RgxI();
+    if (pith["block_is"] == eN.blk_is.block) {
+      if (pith["block_delim"] == eN.blk_delim.curly) {
+        if (line.matchFirst(rgx.block_curly_block_close)) {
+          debug(block) { writeln(line); }
+          an_object[an_object_key]    = an_object[an_object_key].stripRight;
+          pith["block_is"]            = eN.blk_is.block;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          debug(block) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      } else if (pith["block_delim"] == eN.blk_delim.tic) {
+        if (line.matchFirst(rgx.block_tic_close)) {
+          debug(block) { writeln(line); }
+          an_object[an_object_key]    = an_object[an_object_key].stripRight;
+          pith["block_is"]            = eN.blk_is.block;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          debug(block) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      }
+    }
+    ST_txt_by_line_block_generic ret;
+    {
+      ret.pith        = pith;
+      ret.this_object = an_object;
+    }
+    return ret;
+  }
+  @safe ST_txt_by_line_block_poem txt_by_line_block_poem(CMM)(
+    char[]          line,
+    string[string]  an_object,
+    uint[string]    pith,
+    int             cntr,
+    string[string]  object_number_poem,
+    CMM             conf_make_meta,
+    string[string]  tag_in_seg,
+  ) {
+    static auto rgx = RgxI();
+    if (pith["block_is"] == eN.blk_is.poem) {
+      if (pith["block_delim"] == eN.blk_delim.curly) {
+        if (line.matchFirst(rgx.block_curly_poem_close)) {
+          if (an_object_key in an_object
+          || processing.length > 0) {
+            an_object[an_object_key]        = "";
+            debug(poem) { writefln( "* [poem curly] %s", line); }
+            if (processing.length > 0) {
+              an_object[an_object_key]      = processing["verse"];
+            }
+            debug(poem) {
+              writeln(__LINE__);
+              writefln( "* %s %s", obj_cite_digits.object_number, line);
+            }
+            if (an_object.length > 0) {
+              debug(poem) { writeln( obj_cite_digits.object_number, an_object[an_object_key]); }
+              an_object["is"]                                   = "verse";
+              ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
+                = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
+              an_object["substantive"]                          = substantive_obj_misc_struct.obj_txt;
+              anchor_tag                                        = substantive_obj_misc_struct.anchor_tag;
+              comp_obj_                                         = set_object_generic("body", "body", "block", "verse", an_object["substantive"], obj_cite_digits.object_number);
+              comp_obj_.metainfo.identifier                     = obj_cite_digits.identifier;
+              comp_obj_.metainfo.object_number_off              = obj_cite_digits.off;
+              comp_obj_.metainfo.o_n_book_index                 = obj_cite_digits.bkidx;
+              comp_obj_.metainfo.object_number_type             = obj_cite_digits.type;
+              comp_obj_.tags.html_segment_anchor_tag_is         = tag_in_seg["seg_lv4"];
+              comp_obj_.tags.epub_segment_anchor_tag_is         = tag_in_seg["seg_lv1to4"];
+              comp_obj_.has.inline_notes_reg                    = substantive_obj_misc_struct.has_notes_reg;
+              comp_obj_.has.inline_notes_star                   = substantive_obj_misc_struct.has_notes_star;
+              comp_obj_.has.inline_links                        = substantive_obj_misc_struct.has_links;
+              the_document_body_section                         ~= comp_obj_;
+              tag_assoc                                         = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
+            }
+            object_reset(an_object);
+            processing.remove("verse");
+            ++cntr;
+          }
+          object_number_poem["end"]   = obj_cite_digits.object_number.to!string;
+          pith["block_is"]            = eN.blk_is.poem;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          processing["verse"] ~= line ~= "\n";
+          if (pith["verse_new"] == eN.bi.on) {
+            obj_cite_digits = ocn_emit(pith["ocn"]);
+            pith["verse_new"]         = eN.bi.off;
+          } else if (line.matchFirst(rgx.newline_eol_delimiter_only)) {
+            processing["verse"]       = processing["verse"].stripRight;
+            verse_line                = eN.bi.off;
+            pith["verse_new"]         = eN.bi.on;
+          }
+          if (pith["verse_new"] == eN.bi.on) {
+            verse_line = 1;
+            an_object[an_object_key]  = processing["verse"];
+            debug(poem) { writefln(
+                "* %s curly\n%s",
+                obj_cite_digits.object_number,
+                an_object[an_object_key]
+              );
+            }
+            processing.remove("verse");
+            an_object["is"]                                     = "verse";
+            auto comp_obj_location = node_construct.node_location_emitter(
+              content_non_header,
+              tag_in_seg,
+              lev_anchor_tag,
+              tag_assoc,
+              obj_cite_digits,
+              cntr,
+              heading_ptr-1,
+              an_object["is"]
+            );
+            ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
+              = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
+            an_object["substantive"]                            = substantive_obj_misc_struct.obj_txt;
+            anchor_tag                                          = substantive_obj_misc_struct.anchor_tag;
+            comp_obj_                                           = set_object_generic("body", "body", "block", "verse", an_object["substantive"], obj_cite_digits.object_number);
+            comp_obj_.metainfo.identifier                       = obj_cite_digits.identifier;
+            comp_obj_.metainfo.object_number_off                = obj_cite_digits.off;
+            comp_obj_.metainfo.o_n_book_index                   = obj_cite_digits.bkidx;
+            comp_obj_.metainfo.object_number_type               = obj_cite_digits.type;
+            comp_obj_.tags.html_segment_anchor_tag_is           = tag_in_seg["seg_lv4"];
+            comp_obj_.tags.epub_segment_anchor_tag_is           = tag_in_seg["seg_lv1to4"];
+            comp_obj_.has.inline_notes_reg                      = substantive_obj_misc_struct.has_notes_reg;
+            comp_obj_.has.inline_notes_star                     = substantive_obj_misc_struct.has_notes_star;
+            comp_obj_.has.inline_links                          = substantive_obj_misc_struct.has_links;
+            the_document_body_section                           ~= comp_obj_;
+            tag_assoc                                           = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
+            object_reset(an_object);
+            processing.remove("verse");
+            ++cntr;
+          }
+        }
+      } else if (pith["block_delim"] == eN.blk_delim.tic) {
+        if (auto m = line.matchFirst(rgx.block_tic_close)) {
+          an_object[an_object_key] = "verse";
+          debug(poem) { writefln( "* [poem tic] %s", line); }
+          if (processing.length > 0) {
+            an_object[an_object_key]  = processing["verse"];
+          }
+          if (an_object.length > 0) {
+            debug(poem) { writeln(__LINE__); writeln(obj_cite_digits.object_number, line); }
+            processing.remove("verse");
+            an_object["is"]                                     = "verse";
+            ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
+              = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
+            an_object["substantive"]                            = substantive_obj_misc_struct.obj_txt;
+            anchor_tag                                          = substantive_obj_misc_struct.anchor_tag;
+            comp_obj_                                           = set_object_generic("body", "body", "block", "verse", an_object["substantive"], obj_cite_digits.object_number);
+            comp_obj_.metainfo.identifier                       = obj_cite_digits.identifier;
+            comp_obj_.metainfo.object_number_off                = obj_cite_digits.off;
+            comp_obj_.metainfo.o_n_book_index                   = obj_cite_digits.bkidx;
+            comp_obj_.metainfo.object_number_type               = obj_cite_digits.type;
+            comp_obj_.tags.html_segment_anchor_tag_is           = tag_in_seg["seg_lv4"];
+            comp_obj_.tags.epub_segment_anchor_tag_is           = tag_in_seg["seg_lv1to4"];
+            comp_obj_.has.inline_notes_reg                      = substantive_obj_misc_struct.has_notes_reg;
+            comp_obj_.has.inline_notes_star                     = substantive_obj_misc_struct.has_notes_star;
+            comp_obj_.has.inline_links                          = substantive_obj_misc_struct.has_links;
+            the_document_body_section                           ~= comp_obj_;
+            tag_assoc                                           = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
+            object_number_poem["end"]                           = obj_cite_digits.object_number.to!string;
+            object_reset(an_object);
+            processing.remove("verse");
+            ++cntr;
+          }
+          pith["block_is"]            = eN.blk_is.poem;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          processing["verse"]         ~= line ~= "\n";
+          if (pith["verse_new"] == eN.bi.on) {
+            obj_cite_digits           = ocn_emit(pith["ocn"]);
+            pith["verse_new"]         = eN.bi.off;
+          } else if (line.matchFirst(rgx.newline_eol_delimiter_only)) {
+            processing["verse"]       = processing["verse"].stripRight;
+            pith["verse_new"]         = eN.bi.on;
+            verse_line                = eN.bi.off;
+          }
+          if (pith["verse_new"] == eN.bi.on) {
+            verse_line = 1;
+            an_object[an_object_key]  = processing["verse"];
+            debug(poem) { writefln(
+                "* %s tic\n%s",
+                obj_cite_digits.object_number,
+                an_object[an_object_key]
+              );
+            }
+            processing.remove("verse");
+            an_object["is"]                                     = "verse";
+            auto comp_obj_location
+              = node_construct.node_location_emitter(
+                content_non_header,
+                tag_in_seg,
+                lev_anchor_tag,
+                tag_assoc,
+                obj_cite_digits,
+                cntr,
+                heading_ptr-1,
+                an_object["is"]
+              );
+            ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
+              = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
+            an_object["substantive"]                            = substantive_obj_misc_struct.obj_txt;
+            anchor_tag                                          = substantive_obj_misc_struct.anchor_tag;
+            comp_obj_                                           = set_object_generic("body", "body", "block", "verse", an_object["substantive"], obj_cite_digits.object_number);
+            comp_obj_.metainfo.identifier                       = obj_cite_digits.identifier;
+            comp_obj_.metainfo.object_number_off                = obj_cite_digits.off;
+            comp_obj_.metainfo.o_n_book_index                   = obj_cite_digits.bkidx;
+            comp_obj_.metainfo.object_number_type               = obj_cite_digits.type;
+            comp_obj_.tags.html_segment_anchor_tag_is           = tag_in_seg["seg_lv4"];
+            comp_obj_.tags.epub_segment_anchor_tag_is           = tag_in_seg["seg_lv1to4"];
+            comp_obj_.has.inline_notes_reg                      = substantive_obj_misc_struct.has_notes_reg;
+            comp_obj_.has.inline_notes_star                     = substantive_obj_misc_struct.has_notes_star;
+            comp_obj_.has.inline_links                          = substantive_obj_misc_struct.has_links;
+            the_document_body_section                           ~= comp_obj_;
+            tag_assoc                                           = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
+            object_reset(an_object);
+            processing.remove("verse");
+            ++cntr;
+          }
+        }
+      }
+    }
+    ST_txt_by_line_block_poem ret;
+    {
+      ret.cntr        = cntr;
+      ret.pith        = pith;
+      ret.this_object = an_object;
+    }
+    return ret;
+  }
+  @safe ST_txt_by_line_block_generic txt_by_line_block_code()(
+    char[]          line,
+    string[string]  an_object,
+    uint[string]    pith,
+  ) {
+    static auto rgx = RgxI();
+    if ( pith["block_is"] == eN.blk_is.code) {
+      if (pith["block_delim"] == eN.blk_delim.curly) {
+        if (line.matchFirst(rgx.block_curly_code_close)) {
+          debug(codecurly) { writeln(line); }
+          an_object[an_object_key] = an_object[an_object_key]
+            .replaceFirst(rgx.newline_eol_delimiter_only, "")
+            .stripRight;
+          pith["block_is"]            = eN.blk_is.code;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          debug(codecurly) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      } else if (pith["block_delim"] == eN.blk_delim.tic) {
+        if (line.matchFirst(rgx.block_tic_close)) {
+          debug(codetic) { writeln(line); }
+          an_object[an_object_key] = an_object[an_object_key]
+            .replaceFirst(rgx.newline_eol_delimiter_only, "")
+            .stripRight;
+          pith["block_is"]            = eN.blk_is.code;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          debug(codetic) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      }
+    }
+    ST_txt_by_line_block_generic ret;
+    {
+      ret.pith        = pith;
+      ret.this_object = an_object;
+    }
+    return ret;
+  }
+  @system auto txt_by_line_block_table(CMM)(
+    char[]          line,
+    string[string]  an_object,
+    uint[string]    pith,
+    CMM             conf_make_meta,
+  ) {
+    static auto rgx = RgxI();
+    if (pith["block_is"] == eN.blk_is.table) {
+      if (pith["block_delim"] == eN.blk_delim.curly) {
+        if (line.matchFirst(rgx.block_curly_table_close)) {
+          debug(table) { writeln(line); }
+          pith["block_is"]            = eN.blk_is.table;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          debug(table) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      } else if (pith["block_delim"] == eN.blk_delim.curly_special) {
+        if (line.empty) {
+          pith["block_is"]            = eN.blk_is.table;
+          pith["block_state"]         = eN.blk_state.off;
+          pith["block_delim"]         = eN.blk_delim.off;
+          {
+            auto _get = line.flow_table_closed_make_special_notation_table_(
+              an_object,
+              the_document_body_section,
+              obj_cite_digits,
+              comp_obj_,
+              cntr,
+              pith,
+              conf_make_meta,
+            );
+            {
+              an_object                 = _get.this_object;
+              the_document_body_section = _get.the_document_body_section;
+              obj_cite_digits           = _get.obj_cite_digits;
+              comp_obj_                 = _get.comp_obj_;
+              cntr                      = _get.cntr;
+              pith                      = _get.pith;
+            }
+          }
+        } else {
+          debug(table) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      } else if (pith["block_delim"] == eN.blk_delim.tic) {
+        if (line.matchFirst(rgx.block_tic_close)) {
+          debug(table) { writeln(line); }
+          pith["block_is"]            = eN.blk_is.table;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          debug(table) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      }
+    }
+    struct ST_txt_by_line_block_table {
+      CMM             conf_make_meta;
+      uint[string]    pith;
+      string[string]  this_object;
+    }
+    ST_txt_by_line_block_table ret;
+    {
+      ret.conf_make_meta = conf_make_meta,
+      ret.pith           = pith;
+      ret.this_object    = an_object;
+    }
+    return ret;
+  }
+  @safe ST_txt_by_line_block_generic txt_by_line_block_quote()(
+    char[]          line,
+    string[string]  an_object,
+    uint[string]    pith,
+  ) {
+    static auto rgx = RgxI();
+    if (pith["block_is"] == eN.blk_is.quote){
+      if (pith["block_delim"] == eN.blk_delim.curly) {
+        if (line.matchFirst(rgx.block_curly_quote_close)) {
+          debug(quote) { writeln(line); }
+          an_object[an_object_key]    = an_object[an_object_key].stripRight;
+          pith["block_is"]            = eN.blk_is.quote;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          debug(quote) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      } else if (pith["block_delim"] == eN.blk_delim.tic) {
+        if (line.matchFirst(rgx.block_tic_close)) {
+          debug(quote) { writeln(line); }
+          an_object[an_object_key]    = an_object[an_object_key].stripRight;
+          pith["block_is"]            = eN.blk_is.quote;
+          pith["block_state"]         = eN.blk_state.closing;
+          pith["block_delim"]         = eN.blk_delim.off;
+        } else {
+          debug(quote) { writeln(line); }
+          an_object[an_object_key] ~= line ~= "\n";
+        }
+      }
+    }
+    ST_txt_by_line_block_generic ret;
+    {
+      ret.pith        = pith;
+      ret.this_object = an_object;
+    }
+    return ret;
+  }
+  @system ST_txt_by_line_block_biblio txt_by_line_block_biblio(
+    char[]                  line,
+    uint[string] pith,
+    int          bib_entry,
+    string       biblio_entry_str_json,
+    string[]     biblio_arr_json,
+  ) {
+    mixin spineBiblio;
+    auto jsn = BibJsnStr();
+    static auto rgx = RgxI();
+    string biblio_tag_map()(string abr) {
+      auto btm = [
+        "au"        : "author_raw",
+        "ed"        : "editor_raw",
+        "ti"        : "fulltitle",
+        "lng"       : "language",
+        "jo"        : "journal",
+        "vol"       : "volume",
+        "edn"       : "edition",
+        "yr"        : "year",
+        "pl"        : "place",
+        "pb"        : "publisher",
+        "pub"       : "publisher",
+        "pg"        : "pages",
+        "pgs"       : "pages",
+        "sn"        : "short_name"
+      ];
+      return btm[abr];
+    }
+    if (line.matchFirst(rgx.heading_biblio)) {
+      pith["section"] = eN.sect.bibliography;
+    }
+    if (line.empty) {
+      debug {
+        debug(biblioblock) { writeln("---"); }
+        debug(biblioblockinclude) { writeln(biblio_entry_str_json.length); }
+      }
+      if ((bib_entry == eN.bi.off)
+      && (biblio_entry_str_json.empty)) {
+        bib_entry = eN.bi.on;
+        biblio_entry_str_json = jsn.biblio_entry_tags_jsonstr;
+      } else if (!(biblio_entry_str_json.empty)) {
+        bib_entry = eN.bi.off;
+        if (!(biblio_entry_str_json == jsn.biblio_entry_tags_jsonstr)) {
+          auto biblio_entry = parseJSON(biblio_entry_str_json);
+          if (biblio_entry["fulltitle"].str.empty) {
+            writeln("check problem entry (Title missing): ", biblio_entry_str_json);
+          } else if ((biblio_entry["author_raw"].str.empty) && (biblio_entry["editor_raw"].str.empty)) {
+            writeln("check problem entry (No author and no editor): ", biblio_entry_str_json);
+          } else {
+            biblio_arr_json ~= biblio_entry_str_json;
+          }
+          biblio_entry_str_json = jsn.biblio_entry_tags_jsonstr;
+        }
+      } else {
+        writeln("?? 2. ERROR ", biblio_entry_str_json, "??");
+        biblio_entry_str_json = "";
+      }
+    } else if (line.matchFirst(rgx.biblio_tags)) {
+      debug(biblioblock) { writeln(line); }
+      auto bt = line.match(rgx.biblio_tags);
+      bib_entry = eN.bi.off;
+      st = bt.captures[1].to!string;
+      auto header_tag_value = (bt.captures[2]).to!string;
+      JSONValue j = parseJSON(biblio_entry_str_json);
+      biblio_tag_name = (st.match(rgx.biblio_abbreviations))
+        ? (biblio_tag_map(st))
+        : st;
+      j.object[biblio_tag_name] = header_tag_value;
+      debug(bibliounsortedcheckduplicates) { writeln(biblio_tag_name, ": ", header_tag_value); writeln("--"); }
+      switch (biblio_tag_name) {
+      case "author_raw": // author_arr author (fn sn)
+        j["author_arr"]
+         = header_tag_value.split(rgx.arr_delimiter);
+        string tmp;
+        biblioAuthorLoop:
+        foreach (au; j["author_arr"].array) {
+          if (auto x = au.str.match(rgx.name_delimiter)) {
+            tmp ~= x.captures[2] ~ " " ~ x.captures[1] ~ ", ";
+          } else {
+            tmp ~= au.str;
+          }
+        }
+        tmp = tmp.replace(rgx.trailing_comma, "");
+        j["author"].str = tmp;
+        goto default;
+      case "editor_raw": // editor_arr editor (fn sn)
+        j["editor_arr"]
+          = header_tag_value.split(rgx.arr_delimiter);
+        string tmp;
+        biblioEditorLoop:
+        foreach (ed; j["editor_arr"].array) {
+          if (auto x = ed.str.match(rgx.name_delimiter)) {
+            tmp ~= x.captures[2] ~ " " ~ x.captures[1] ~ ", ";
+          } else {
+            tmp ~= ed.str;
+          }
+        }
+        tmp = tmp.replace(rgx.trailing_comma, "");
+        j["editor"].str = tmp;
+        goto default;
+      case "fulltitle": // title & subtitle
+        goto default;
+      default:
+        break;
+      }
+      auto s = j.toString();
+      debug(biblio1) { writefln(
+          "* %s: %s\n%s",
+          biblio_tag_name,
+          biblio_tag_entry,
+          j[biblio_tag_name]
+        );
+      }
+      if (line.match(rgx.comment)) {
+        writeln("ERROR", line, "COMMENT");
+        writeln("ERROR", s, "%%");
+      }
+      if (!(match(line, rgx.comment))) {
+        debug(biblioblockinclude) { writeln(line); }
+        biblio_entry_str_json = s;
+      } else {
+        biblio_entry_str_json = "";
+      }
+      header_tag_value        = "";
+    }
+    ST_txt_by_line_block_biblio ret;
+    {
+      ret.pith                  = pith;
+      ret.bib_entry             = bib_entry;
+      ret.biblio_entry_str_json = biblio_entry_str_json;
+      ret.biblio_arr_json       = biblio_arr_json;
+    }
+    return ret;
+  }
+  // ↑ - text by line
+  // ↓ - para
+  @safe string[string][string] inline_para_link_anchor()(
+    string[string]          an_object,
+    string[string]          tag_in_seg,
+    string[string][string]  tag_assoc
+  ) {
+    static auto rgx = RgxI();
+    if (auto m = an_object["substantive"].match(rgx.inline_link_anchor)) {
+      if (m.captures[1] !in tag_assoc) {
+        tag_assoc[(m.captures[1])]["seg_lv4"]    = tag_in_seg["seg_lv4"];
+        tag_assoc[(m.captures[1])]["seg_lv1to4"] = tag_in_seg["seg_lv1to4"];
+      } else {
+        writeln("a tag named  already exists, check text line\n    ", an_object["substantive"]);
+      }
+    }
+    return tag_assoc;
+  }
+  @safe ST_flow_para_match flow_para_match_()(
+    char[]         line,
+    string[string]  an_object,
+    string          an_object_key,
+    int[string]     indent,
+    bool            bullet,
+    uint[string]    pith,
+    int[string]     line_occur,
+  ) {
+    static auto rgx = RgxI();
+    if (line_occur["para"] == eN.bi.off) {
+      line = font_faces_line(line);
+      // para matches
+      pith["txt_is"]           = eN.txt_is.para;
+      an_object[an_object_key] ~= line;
+      indent = [
+        "hang_position" : 0,
+        "base_position" : 0,
+      ];
+      bullet = false;
+      if (auto m = line.matchFirst(rgx.para_indent)) {
+        debug(paraindent) { writeln(line); }
+        indent["hang_position"] = (m["indent"]).to!int;
+        indent["base_position"] = (m["indent"]).to!int;
+      } else if (line.matchFirst(rgx.para_bullet)) {
+        debug(parabullet) { writeln(line); }
+        bullet = true;
+      } else if (auto m = line.matchFirst(rgx.para_indent_hang)) {
+        debug(paraindenthang) { writeln(line); }
+        indent = [
+          "hang_position" : (m["hang"]).to!int,
+          "base_position" : (m["indent"]).to!int,
+        ];
+      } else if (auto m = line.matchFirst(rgx.para_bullet_indent)) {
+        debug(parabulletindent) { writeln(line); }
+        indent = [
+          "hang_position" : (m["indent"]).to!int,
+          "base_position" : (m["indent"]).to!int,
+        ];
+        bullet = true;
+      }
+      ++line_occur["para"];
+    }
+    ST_flow_para_match ret;
+    {
+      ret.pith            = pith;
+      ret.this_object     = an_object;
+      ret.this_object_key = an_object_key;
+      ret.indent          = indent;
+      ret.bullet          = bullet;
+      ret.line_occur      = line_occur;
+    }
+    return ret;
+  }
+  // ↑ - para
+  // ↓ - heading
+  @safe ST_flow_heading_found flow_heading_found_()(
+    char[]                line,
+    string[string]        heading_match_str,
+    string[]              _make_unmarked_headings,
+    Regex!(char)[string]  heading_match_rgx,
+    uint[string]          pith,
+  ) {
+    static auto rgx = RgxI();
+    if ((_make_unmarked_headings.length > 2)
+    && (pith["make_headings"] == eN.bi.off)) {                        // headings found
+      debug(headingsfound) { writeln(_make_unmarked_headings); }
+      debug(headingsfound) {
+        writeln(_make_unmarked_headings.length);
+        writeln(_make_unmarked_headings);
+      }
+      switch (_make_unmarked_headings.length) {
+      case 7 :
+        if (!empty(_make_unmarked_headings[6])) {
+          heading_match_str["h_4"]
+            = "^(" ~ _make_unmarked_headings[6].to!string ~ ")";
+          heading_match_rgx["h_4"]
+            = regex(heading_match_str["h_4"]);
+        }
+        goto case;
+      case 6 :
+        if (!empty(_make_unmarked_headings[5])) {
+          heading_match_str["h_3"]
+            = "^(" ~ _make_unmarked_headings[5].to!string ~ ")";
+          heading_match_rgx["h_3"]
+            = regex(heading_match_str["h_3"]);
+        }
+        goto case;
+      case 5 :
+        if (!empty(_make_unmarked_headings[4])) {
+          heading_match_str["h_2"]
+            = "^(" ~ _make_unmarked_headings[4].to!string ~ ")";
+          heading_match_rgx["h_2"]
+            = regex(heading_match_str["h_2"]);
+        }
+        goto case;
+      case 4 :
+        if (!empty(_make_unmarked_headings[3])) {
+          heading_match_str["h_1"]
+            = "^(" ~ _make_unmarked_headings[3].to!string ~ ")";
+          heading_match_rgx["h_1"]
+            = regex(heading_match_str["h_1"]);
+        }
+        goto case;
+      case 3 :
+        if (!empty(_make_unmarked_headings[2])) {
+          heading_match_str["h_D"]
+            = "^(" ~ _make_unmarked_headings[2].to!string ~ ")";
+          heading_match_rgx["h_D"]
+            = regex(heading_match_str["h_D"]);
+        }
+        goto case;
+      case 2 :
+        if (!empty(_make_unmarked_headings[1])) {
+          heading_match_str["h_C"]
+            = "^(" ~ _make_unmarked_headings[1].to!string ~ ")";
+          heading_match_rgx["h_C"]
+            = regex(heading_match_str["h_C"]);
+        }
+        goto case;
+      case 1 :
+        if (!empty(_make_unmarked_headings[0])) {
+          heading_match_str["h_B"]
+            = "^(" ~ _make_unmarked_headings[0].to!string ~ ")";
+          heading_match_rgx["h_B"]
+            = regex(heading_match_str["h_B"]);
+        }
+        break;
+      default:
+        break;
+      }
+      pith["make_headings"] = eN.bi.on;
+    }
+    ST_flow_heading_found ret;
+    {
+      ret.heading_match_str = heading_match_str;
+      ret.heading_match_rgx = heading_match_rgx;
+      ret.pith              = pith;
+    }
+    return ret;
+  }
+  @safe ST_flow_heading_make_set flow_heading_make_set_()(
+               char[]                line,
+               int[string]           line_occur,
+    return ref Regex!(char)[string]  heading_match_rgx,
+    return ref uint[string]          pith,
+  ) {
+    if (pith["make_headings"] == eN.bi.on
+      && (line_occur["para"] == eN.bi.off
+      && line_occur["heading"] == eN.bi.off)
+      && pith["txt_is"] == eN.txt_is.off
+    ) {                             // heading make set
+      if (line.matchFirst(heading_match_rgx["h_B"])) {
+        line = "B~ " ~ line;
+        debug(headingsfound) { writeln(line); }
+      }
+      if (line.matchFirst(heading_match_rgx["h_C"])) {
+        line = "C~ " ~ line;
+        debug(headingsfound) { writeln(line); }
+      }
+      if (line.matchFirst(heading_match_rgx["h_D"])) {
+        line = "D~ " ~ line;
+        debug(headingsfound) { writeln(line); }
+      }
+      if (line.matchFirst(heading_match_rgx["h_1"])) {
+        line = "1~ " ~ line;
+        debug(headingsfound) { writeln(line); }
+      }
+      if (line.matchFirst(heading_match_rgx["h_2"])) {
+        line = "2~ " ~ line;
+        debug(headingsfound) { writeln(line); }
+      }
+      if (line.matchFirst(heading_match_rgx["h_3"])) {
+        line = "3~ " ~ line;
+        debug(headingsfound) { writeln(line); }
+      }
+      if (line.matchFirst(heading_match_rgx["h_4"])) {
+        line = "4~ " ~ line;
+        debug(headingsfound) { writeln(line); }
+      }
+    }
+    ST_flow_heading_make_set ret;
+    {
+      ret.line           = line;
+      ret.pith           = pith;
+      ret.this_object    = an_object;
+    }
+    return ret;
+  }
+  @safe auto flow_heading_matched_(CMM)(
+    char[]          line,
+    string[string]  an_object,
+    int[string]     line_occur,
+    string          an_object_key,
+    int[string]     lv,
+    int[string]     collapsed_lev,
+    uint[string]    pith,
+    CMM             conf_make_meta,
+  ) {
+    static auto rgx = RgxI();
+    static auto mkup = InlineMarkup();
+    if (auto m = line.match(rgx.headings)) {                                      // heading match
+      ++line_occur["heading"];
+      pith["txt_is"]           = eN.txt_is.heading;
+      if (line.match(rgx.heading_seg_and_above)) {
+        pith["section"]        = eN.sect.unset;
+      }
+      an_object[an_object_key] ~= line ~= "\n";
+      an_object["lev"] ~= m.captures[1];
+      assertions_doc_structure(an_object, an_object_key, lv); // includes most of the logic for collapsed levels
+      switch (an_object["lev"]) {
+      case "A":                                // Title set
+        if ((an_object[an_object_key].match(rgx.variable_doc_title_author_date))
+        || (an_object[an_object_key].match(rgx.variable_doc_title)
+        && an_object[an_object_key].match(rgx.variable_doc_author)
+        && an_object[an_object_key].match(rgx.variable_doc_date))) {
+          an_object[an_object_key] = an_object[an_object_key]
+            .replaceFirst(rgx.variable_doc_title_author_date,
+              (conf_make_meta.meta.title_full
+              ~ mkup.br_line_inline
+              ~ conf_make_meta.meta.creator_author
+              ~ " (" ~ (conf_make_meta.meta.date_published.replaceFirst(regex(r"(?:-00)+"),"")) ~ ")"))
+            .replaceFirst(rgx.variable_doc_title,
+              (conf_make_meta.meta.title_full ~ mkup.br_line_inline))
+            .replaceFirst(rgx.variable_doc_author,
+              conf_make_meta.meta.creator_author)
+            .replaceFirst(rgx.variable_doc_date,
+              " (" ~ (conf_make_meta.meta.date_published.replaceFirst(regex(r"(?:-00)+"),"")) ~ ")");
+        } else if ((an_object[an_object_key].match(rgx.variable_doc_title_author))
+        || (an_object[an_object_key].match(rgx.variable_doc_title)
+        && an_object[an_object_key].match(rgx.variable_doc_author))) {
+          an_object[an_object_key] = an_object[an_object_key]
+            .replaceFirst(rgx.variable_doc_title_author_date,
+              (conf_make_meta.meta.title_full
+              ~ mkup.br_line_inline
+              ~ conf_make_meta.meta.creator_author))
+            .replaceFirst(rgx.variable_doc_title,
+              (conf_make_meta.meta.title_full ~ mkup.br_line_inline))
+            .replaceFirst(rgx.variable_doc_author,
+              conf_make_meta.meta.creator_author);
+        } else if (an_object[an_object_key].match(rgx.variable_doc_title)) {
+          an_object[an_object_key] = an_object[an_object_key]
+            .replaceFirst(rgx.variable_doc_title,
+              conf_make_meta.meta.title_full);
+        }
+        collapsed_lev["h0"] = 0;
+        an_object["lev_collapsed_number"]
+          = collapsed_lev["h0"].to!string;
+        lv["lv"] = DocStructMarkupHeading.h_sect_A;
+        ++lv["h0"];
+        lv["h1"] = eN.bi.off;
+        lv["h2"] = eN.bi.off;
+        lv["h3"] = eN.bi.off;
+        lv["h4"] = eN.bi.off;
+        lv["h5"] = eN.bi.off;
+        lv["h6"] = eN.bi.off;
+        lv["h7"] = eN.bi.off;
+        goto default;
+      case "B":
+        collapsed_lev["h1"] = collapsed_lev["h0"] + 1;
+        an_object["lev_collapsed_number"]
+          = collapsed_lev["h1"].to!string;
+        lv["lv"] = DocStructMarkupHeading.h_sect_B;
+        ++lv["h1"];
+        lv["h2"] = eN.bi.off;
+        lv["h3"] = eN.bi.off;
+        lv["h4"] = eN.bi.off;
+        lv["h5"] = eN.bi.off;
+        lv["h6"] = eN.bi.off;
+        lv["h7"] = eN.bi.off;
+        goto default;
+      case "C":
+        collapsed_lev["h2"] = collapsed_lev["h1"] + 1;
+        an_object["lev_collapsed_number"]
+          = collapsed_lev["h2"].to!string;
+        lv["lv"] = DocStructMarkupHeading.h_sect_C;
+        ++lv["h2"];
+        lv["h3"] = eN.bi.off;
+        lv["h4"] = eN.bi.off;
+        lv["h5"] = eN.bi.off;
+        lv["h6"] = eN.bi.off;
+        lv["h7"] = eN.bi.off;
+        goto default;
+      case "D":
+        collapsed_lev["h3"] = collapsed_lev["h2"] + 1;
+        an_object["lev_collapsed_number"]
+          = collapsed_lev["h3"].to!string;
+        lv["lv"] = DocStructMarkupHeading.h_sect_D;
+        ++lv["h3"];
+        lv["h4"] = eN.bi.off;
+        lv["h5"] = eN.bi.off;
+        lv["h6"] = eN.bi.off;
+        lv["h7"] = eN.bi.off;
+        goto default;
+      case "1":
+        if (lv["h3"] > eN.bi.off) {
+          collapsed_lev["h4"] = collapsed_lev["h3"] + 1;
+        } else if (lv["h2"] > eN.bi.off) {
+          collapsed_lev["h4"] = collapsed_lev["h2"] + 1;
+        } else if (lv["h1"] > eN.bi.off) {
+          collapsed_lev["h4"] = collapsed_lev["h1"] + 1;
+        } else if (lv["h0"] > eN.bi.off) {
+          collapsed_lev["h4"] = collapsed_lev["h0"] + 1;
+        }
+        an_object["lev_collapsed_number"]
+          = collapsed_lev["h4"].to!string;
+        lv["lv"] = DocStructMarkupHeading.h_text_1;
+        ++lv["h4"];
+        lv["h5"] = eN.bi.off;
+        lv["h6"] = eN.bi.off;
+        lv["h7"] = eN.bi.off;
+        goto default;
+      case "2":
+        if (lv["h5"] > eN.bi.off) {
+          an_object["lev_collapsed_number"]
+            = collapsed_lev["h5"].to!string;
+        } else if (lv["h4"] > eN.bi.off) {
+          collapsed_lev["h5"] = collapsed_lev["h4"] + 1;
+          an_object["lev_collapsed_number"]
+            = collapsed_lev["h5"].to!string;
+        }
+        lv["lv"] = DocStructMarkupHeading.h_text_2;
+        ++lv["h5"];
+        lv["h6"] = eN.bi.off;
+        lv["h7"] = eN.bi.off;
+        goto default;
+      case "3":
+        if (lv["h6"] > eN.bi.off) {
+          an_object["lev_collapsed_number"]
+            = collapsed_lev["h6"].to!string;
+        } else if (lv["h5"] > eN.bi.off) {
+          collapsed_lev["h6"] = collapsed_lev["h5"] + 1;
+          an_object["lev_collapsed_number"]
+            = collapsed_lev["h6"].to!string;
+        }
+        lv["lv"] = DocStructMarkupHeading.h_text_3;
+        ++lv["h6"];
+        lv["h7"] = eN.bi.off;
+        goto default;
+      case "4":
+        if (lv["h7"] > eN.bi.off) {
+          an_object["lev_collapsed_number"]
+            = collapsed_lev["h7"].to!string;
+        } else if (lv["h6"] > eN.bi.off) {
+          collapsed_lev["h7"] = collapsed_lev["h6"] + 1;
+          an_object["lev_collapsed_number"]
+            = collapsed_lev["h7"].to!string;
+        }
+        lv["lv"] = DocStructMarkupHeading.h_text_4;
+        ++lv["h7"];
+        goto default;
+      default:
+        an_object["lev_markup_number"] = lv["lv"].to!string;
+      }
+      an_object["dummy_heading_status"] = (pith["dummy_heading_status"] == eN.bi.off) ? "f" : "t";
+      debug(heading) { writeln(line.strip); }
+    }
+    struct ST_flow_heading_matched {
+      string[string]  this_object;
+      int[string]     line_occur;
+      string          an_object_key;
+      int[string]     lv;
+      int[string]     collapsed_lev;
+      uint[string]    pith;
+      CMM             conf_make_meta;
+    }
+    ST_flow_heading_matched ret;
+    {
+      ret.this_object    = an_object;
+      ret.line_occur     = line_occur;
+      ret.an_object_key  = an_object_key;
+      ret.lv             = lv;
+      ret.collapsed_lev  = collapsed_lev;
+      ret.pith           = pith;
+      ret.conf_make_meta = conf_make_meta;
+    }
+    return ret;
+  }
+  // ↑ - heading
+  // ↓ - table
+  @safe ObjGenericComposite flow_table_instructions(H)(
+    ObjGenericComposite  table_object,
+    H                    table_head,
+  ) {
+    static auto rgx = RgxI();
+    table_object.metainfo.is_of_part        = "body";
+    table_object.metainfo.is_of_section     = "body";
+    table_object.metainfo.is_of_type        = "block";
+    table_object.metainfo.is_a              = "table";
+    table_object.has.inline_notes_reg       = false;
+    table_object.has.inline_notes_star      = false;
+    table_object.has.inline_links           = false;
+    if (auto m = table_head.matchFirst(rgx.table_head_instructions)) {
+      table_object.table.heading
+        = ((m["c_heading"].length > 0) && (m["c_heading"] == "h")) ? true : false;
+      table_object.table.number_of_columns
+        = ((m["c_num"].length > 0) && (m["c_num"].to!int > 0)) ? m["c_num"].to!int : 0;
+      foreach (cw; m["c_widths"].matchAll(rgx.table_col_widths)) {
+        auto x = cw.hit.matchFirst(rgx.table_col_widths_and_alignment);
+        table_object.table.column_widths ~= x["width"].to!int;
+        table_object.table.column_aligns ~= (x["align"].empty) ? "" : x["align"];
+      }
+    }
+    return table_object;
+  }
+  @safe ST_flow_table_array_munge flow_table_array_munge()(
+    ObjGenericComposite  table_object,
+    string[][]           table_array,
+  ) {
+    static auto rgx = RgxI();
+    static auto mng = InlineMarkup();
+    string _table_substantive;
+    ulong col_num;
+    ulong col_num_;
+    ulong col_num_chk = 0;
+    foreach(idx_r, row; table_array) {
+      debug(table_dev) { writeln("row ", idx_r); }
+      col_num_ = 0;
+      if (col_num == 0
+      || col_num < row.length) {
+        col_num = row.length;
+      }
+      if (col_num_chk == 0) {
+        col_num_chk = col_num;
+      } else if (col_num == 1) {
+        debug(table_dev) { writeln("table note: "); }
+      } else if (col_num_chk != col_num) {
+        debug(table_dev) { writeln("warning irregular number of columns: ", col_num_chk, " != ", col_num); }
+      } else {
+      }
+      foreach(idx_c, col; row) {
+        debug(table_dev) { write(idx_c, ", "); }
+        col_num_ = idx_c;
+        _table_substantive ~= col ~ mng.tc_s;
+        if (idx_r == 0 && table_object.table.heading) {
+        } else if (col.match(rgx.numeric_col) && idx_r == 1) { // conditions reversed to avoid: gdc compiled program run segfault
+          if ((table_object.table.column_aligns.length > idx_c)
+          && (table_object.table.column_aligns[idx_c].matchFirst(rgx.table_col_align_match))) {
+            table_object.table.column_aligns[idx_c] = table_object.table.column_aligns[idx_c];
+          } else if (table_object.table.column_aligns.length > idx_c) {
+            table_object.table.column_aligns[idx_c] = "r";
+          } else {
+            table_object.table.column_aligns ~= "r";
+          }
+        } else if (idx_r == 1) {
+          if ((table_object.table.column_aligns.length > idx_c)
+          && (table_object.table.column_aligns[idx_c].matchFirst(rgx.table_col_align_match))) {
+            table_object.table.column_aligns[idx_c] = table_object.table.column_aligns[idx_c];
+          } else if (table_object.table.column_aligns.length > idx_c) {
+            table_object.table.column_aligns[idx_c] = "l";
+          } else {
+            table_object.table.column_aligns ~= "l";
+          }
+        }
+      }
+      debug(table_dev) { writeln(""); }
+      if (col_num_chk > 0 && (col_num != col_num_chk)) {
+      } else if (col_num == col_num_chk){
+      } else {
+        col_num_chk = col_num;
+      }
+      _table_substantive = _table_substantive.replaceFirst(rgx.table_col_separator_nl, "\n");
+    }
+    if (table_object.table.number_of_columns != col_num) {
+      if (table_object.table.number_of_columns == 0) {
+        table_object.table.number_of_columns = (col_num).to!int;
+      } else {
+        debug(table_dev) { writeln(table_object.table.number_of_columns, " != ", col_num); }
+      }
+    }
+    if (table_object.table.number_of_columns == 0
+    && table_object.table.column_widths.length > 0) {
+      writeln(__LINE__, " ERROR");
+    }
+    if (table_object.table.number_of_columns > 0
+    && table_object.table.column_widths.length == 0) {
+      double col_w = (100.00 / table_object.table.number_of_columns);
+      foreach (i; 0..table_object.table.number_of_columns) {
+        table_object.table.column_widths ~= col_w;
+      }
+    } else if (table_object.table.number_of_columns
+    != table_object.table.column_widths.length) {
+      debug(table_dev) { writeln(m.hit); } // further logic required
+      if (table_object.table.number_of_columns > table_object.table.column_widths.length) {
+        double col_w = (100.00 - (table_object.table.column_widths).sum)
+          / (table_object.table.number_of_columns - table_object.table.column_widths.length);
+        foreach (i; 0..table_object.table.column_widths.length) {
+          table_object.table.column_widths ~= col_w;
+        }
+        foreach (i; 0..(table_object.table.number_of_columns - table_object.table.column_widths.length)) {
+          table_object.table.column_widths ~= col_w;
+        }
+      } else if (table_object.table.number_of_columns < table_object.table.column_widths.length) {
+        writeln(__LINE__, " warning, ERROR");
+      }
+    }
+    if (table_object.table.column_widths.sum > 101
+    || table_object.table.column_widths.sum < 95 ) {
+      writeln("sum: ", table_object.table.column_widths.sum,
+        ", array: ", table_object.table.column_widths,
+        ", cols: ", table_object.table.number_of_columns);
+      writeln(_table_substantive);
+    }
+    debug(table_res) {
+      writeln("aligns: ", table_object.table.column_aligns, "\n",
+        "no. of columns: ", table_object.table.number_of_columns, "\n",
+        "col widths: ", table_object.table.column_widths,
+          " sum: ", table_object.table.column_widths.sum, "\n",
+        _table_substantive);
+    }
+    table_object.text = _table_substantive;
+    ST_flow_table_array_munge ret;
+    {
+      ret.table_object      = table_object;
+      ret.table_array       = table_array;
+    }
+    return ret;
+  }
+  @system ST_flow_table_substantive_munge flow_table_substantive_munge()(
+    ObjGenericComposite  table_object,
+    string               table_substantive,
+  ) {
+    static auto rgx = RgxI();
+    static auto munge = ObjInlineMarkupMunge();
+    string[] _table_rows = (table_substantive).split(rgx.table_row_delimiter);
+    string[] _table_cols;
+    string[][] _table_array;
+    foreach(col; _table_rows) {
+      _table_cols = col.split(rgx.table_col_delimiter);
+      _table_array ~= _table_cols;
+    }
+    {
+      auto _get = table_object.flow_table_array_munge(_table_array);
+      {
+        table_object = _get.table_object;
+        _table_array = _get.table_array; // what do you do with this? how is this passed down?
+      }
+    }
+    ST_flow_table_substantive_munge ret;
+    {
+      ret.table_object      = table_object;
+      ret.table_substantive = table_substantive; // has anything been changed here?
+    }
+    return ret;
+  }
+  @system ST_flow_table_substantive_munge flow_table_substantive_munge_special()(
+    ObjGenericComposite  table_object,
+    string               table_substantive,
+  ) {
+    static auto rgx = RgxI();
+    static auto munge = ObjInlineMarkupMunge();
+    string[] _table_rows = (table_substantive).split(rgx.table_row_delimiter_special);
+    string[] _table_cols;
+    string[][] _table_array;
+    foreach(col; _table_rows) {
+      _table_cols = col.split(rgx.table_col_delimiter_special);
+      _table_array ~= _table_cols;
+    }
+    {
+      auto _get = table_object.flow_table_array_munge(_table_array);
+      {
+        table_object = _get.table_object;
+        _table_array = _get.table_array;
+      }
+    }
+    ST_flow_table_substantive_munge ret;
+    {
+      ret.table_object      = table_object;
+      ret.table_substantive = table_substantive;
+    }
+    return ret;
+  }
+  @system ST_flow_table_closed_make_special_notation_table flow_table_closed_make_special_notation_table_(CMM)(
+    char[]                line,
+    string[string]        an_object,
+    ObjGenericComposite[] the_document_body_section,
+    OCNset                obj_cite_digits,
+    ObjGenericComposite   comp_obj_,
+    int                   cntr,
+    uint[string]          pith,
+    CMM                   conf_make_meta
+  ) {
+    comp_obj_       = comp_obj_.init;
+    obj_cite_digits = ocn_emit(pith["ocn"]);
+    auto comp_obj_location = node_construct.node_location_emitter(
+        content_non_header,
+        tag_in_seg,
+        lev_anchor_tag,
+        tag_assoc,
+        obj_cite_digits,
+        cntr,
+        heading_ptr-1,
+        "table"
+      );
+    an_object["is"]                                             = "table";
+    ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
+      = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, "body_nugget", conf_make_meta, No._new_doc);
+    an_object["substantive"]                                    = substantive_obj_misc_struct.obj_txt;
+    comp_obj_.metainfo.ocn                                      = obj_cite_digits.object_number;
+    comp_obj_.metainfo.identifier                               = obj_cite_digits.identifier;
+    comp_obj_.metainfo.object_number_off                        = obj_cite_digits.off;
+    comp_obj_.tags.html_segment_anchor_tag_is                   = tag_in_seg["seg_lv4"];
+    comp_obj_.tags.epub_segment_anchor_tag_is                   = tag_in_seg["seg_lv1to4"];
+    comp_obj_.metainfo.o_n_book_index                           = obj_cite_digits.bkidx;
+    comp_obj_.metainfo.object_number_type                       = obj_cite_digits.type;
+    comp_obj_                                                   = comp_obj_.flow_table_instructions(an_object["table_head"]);
+    {
+      auto _get = comp_obj_.flow_table_substantive_munge_special(an_object["substantive"]);
+      {
+        comp_obj_           = _get.table_object;
+        an_object["substantive"] = _get.table_substantive;
+      }
+    }
+    the_document_body_section                                   ~= comp_obj_;
+    object_reset(an_object);
+    processing.remove("verse");
+    ++cntr;
+    ST_flow_table_closed_make_special_notation_table ret;
+    {
+      ret.this_object               = an_object;
+      ret.the_document_body_section = the_document_body_section;
+      ret.obj_cite_digits           = obj_cite_digits;
+      ret.comp_obj_                 = comp_obj_;
+      ret.cntr                      = cntr;
+      ret.pith                      = pith;
+    }
+    return ret;
+  }
+  // ↑ - table
+  
+  @system ST_flow_block_flag_line_empty flow_block_flag_line_empty_(B,CMM,Ts)(
+    char[]                   line,
+    string[string]           an_object,
+    B                        bookindex_extract_hash,
+    ObjGenericComposite[]    the_document_body_section,
+    string[][string][string] bookindex_unordered_hashes,
+    OCNset                   obj_cite_digits,
+    ObjGenericComposite      comp_obj_,
+    int                      cntr,
+    uint[string]             pith,
+    string[string]           object_number_poem,
+    CMM                      conf_make_meta,
+    Ts                       tag_in_seg,
+  ) {
+    assert(
+      line.empty,
+      "\nline should be empty:\n  \""
+      ~ line ~ "\""
+    );
+    assert(
+      (pith["block_state"] == eN.blk_state.closing),
+      "code block status: closed"
+    );
+    static auto rgx = RgxI();
+    if (pith["block_state"] == eN.blk_state.closing) {
+      if (pith["block_is"] == eN.blk_is.quote) {
+        obj_cite_digits = ocn_emit(pith["ocn"]);
+        an_object["bookindex_nugget"]
+          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
+        bookindex_unordered_hashes
+          = bookindex_extract_hash.bookindex_nugget_hash(
+            an_object["bookindex_nugget"],
+            obj_cite_digits,
+            tag_in_seg
+          );
+        an_object["is"]                                         = "quote";
+        auto comp_obj_location
+          = node_construct.node_location_emitter(
+            content_non_header,
+            tag_in_seg,
+            lev_anchor_tag,
+            tag_assoc,
+            obj_cite_digits,
+            cntr,
+            heading_ptr-1,
+            an_object["is"]
+          );
+        ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
+          = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
+        an_object["substantive"]                                = substantive_obj_misc_struct.obj_txt;
+        anchor_tag                                              = substantive_obj_misc_struct.anchor_tag;
+        comp_obj_                                               = set_object_generic("body", "body", "block", "quote", an_object["substantive"], obj_cite_digits.object_number);
+        comp_obj_.metainfo.identifier                           = obj_cite_digits.identifier;
+        comp_obj_.metainfo.object_number_off                    = obj_cite_digits.off;
+        comp_obj_.metainfo.o_n_book_index                       = obj_cite_digits.bkidx;
+        comp_obj_.metainfo.object_number_type                   = obj_cite_digit_type;
+        comp_obj_.metainfo.lang                                 = an_object["lang"];
+        comp_obj_.metainfo.attrib                               = an_object["attrib"];
+        comp_obj_.tags.html_segment_anchor_tag_is               = tag_in_seg["seg_lv4"];
+        comp_obj_.tags.epub_segment_anchor_tag_is               = tag_in_seg["seg_lv1to4"];
+        comp_obj_.has.inline_notes_reg                          = substantive_obj_misc_struct.has_notes_reg;
+        comp_obj_.has.inline_notes_star                         = substantive_obj_misc_struct.has_notes_star;
+        comp_obj_.has.inline_links                              = substantive_obj_misc_struct.has_links;
+        the_document_body_section                               ~= comp_obj_;
+        tag_assoc                                               = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
+        pith["block_is"]                                        = eN.blk_is.quote;
+        pith["block_state"]                                     = eN.blk_state.off;
+        pith["block_delim"]                                     = eN.blk_delim.off;
+        object_reset(an_object);
+        processing.remove("verse");
+        ++cntr;
+      } else if (pith["block_is"] == eN.blk_is.group) {
+        obj_cite_digits = ocn_emit(pith["ocn"]);
+        an_object["bookindex_nugget"]
+          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
+        bookindex_unordered_hashes
+          = bookindex_extract_hash.bookindex_nugget_hash(
+            an_object["bookindex_nugget"],
+            obj_cite_digits,
+            tag_in_seg
+          );
+        an_object["is"]                                         = "group";
+        auto comp_obj_location
+          = node_construct.node_location_emitter(
+            content_non_header,
+            tag_in_seg,
+            lev_anchor_tag,
+            tag_assoc,
+            obj_cite_digits,
+            cntr,
+            heading_ptr-1,
+            an_object["is"]
+          );
+        ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
+          = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
+        an_object["substantive"]                                = substantive_obj_misc_struct.obj_txt;
+        anchor_tag                                              = substantive_obj_misc_struct.anchor_tag;
+        comp_obj_                                               = set_object_generic("body", "body", "block", "group", an_object["substantive"], obj_cite_digits.object_number);
+        comp_obj_.metainfo.identifier                           = obj_cite_digits.identifier;
+        comp_obj_.metainfo.object_number_off                    = obj_cite_digits.off;
+        comp_obj_.metainfo.o_n_book_index                       = obj_cite_digits.bkidx;
+        comp_obj_.metainfo.object_number_type                   = obj_cite_digits.type;
+        comp_obj_.metainfo.lang                                 = an_object["lang"];
+        comp_obj_.metainfo.attrib                               = an_object["attrib"];
+        comp_obj_.tags.html_segment_anchor_tag_is               = tag_in_seg["seg_lv4"];
+        comp_obj_.tags.epub_segment_anchor_tag_is               = tag_in_seg["seg_lv1to4"];
+        comp_obj_.has.inline_notes_reg                          = substantive_obj_misc_struct.has_notes_reg;
+        comp_obj_.has.inline_notes_star                         = substantive_obj_misc_struct.has_notes_star;
+        comp_obj_.has.inline_links                              = substantive_obj_misc_struct.has_links;
+        the_document_body_section                               ~= comp_obj_;
+        tag_assoc                                               = an_object.inline_para_link_anchor(tag_in_seg, tag_assoc);
+        pith["block_is"]                                        = eN.blk_is.poem;
+        pith["block_state"]                                     = eN.blk_state.off;
+        pith["block_delim"]                                     = eN.blk_delim.off;
+        object_reset(an_object);
+        processing.remove("verse");
+        ++cntr;
+      } else if (pith["block_is"] == eN.blk_is.block) {
+        obj_cite_digits = ocn_emit(pith["ocn"]);
+        an_object["bookindex_nugget"]
+          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
+        bookindex_unordered_hashes
+          = bookindex_extract_hash.bookindex_nugget_hash(
+            an_object["bookindex_nugget"],
+            obj_cite_digits,
+            tag_in_seg
+          );
+        an_object["is"]                                         = "block";
+        auto comp_obj_location
+          = node_construct.node_location_emitter(
+            content_non_header,
+            tag_in_seg,
+            lev_anchor_tag,
+            tag_assoc,
+            obj_cite_digits,
+            cntr,
+            heading_ptr-1,
+            an_object["is"]
+          );
+        ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
+          = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
+        an_object["substantive"]                                = substantive_obj_misc_struct.obj_txt;
+        // anchor_tag                                           = substantive_obj_misc_struct.anchor_tag; // check
+        comp_obj_                                               = set_object_generic("body", "body", "block", "block", an_object["substantive"], obj_cite_digits.object_number);
+        comp_obj_.metainfo.identifier                           = obj_cite_digits.identifier;
+        comp_obj_.metainfo.object_number_off                    = obj_cite_digits.off;
+        comp_obj_.metainfo.o_n_book_index                       = obj_cite_digits.bkidx;
+        comp_obj_.metainfo.object_number_type                   = obj_cite_digit_type;
+        comp_obj_.metainfo.lang                                 = an_object["lang"];
+        comp_obj_.metainfo.attrib                               = an_object["attrib"];
+        comp_obj_.tags.html_segment_anchor_tag_is               = tag_in_seg["seg_lv4"];
+        comp_obj_.tags.epub_segment_anchor_tag_is               = tag_in_seg["seg_lv1to4"];
+        comp_obj_.has.inline_notes_reg                          = substantive_obj_misc_struct.has_notes_reg;
+        comp_obj_.has.inline_notes_star                         = substantive_obj_misc_struct.has_notes_star;
+        comp_obj_.has.inline_links                              = substantive_obj_misc_struct.has_links;
+        the_document_body_section                               ~= comp_obj_;
+        pith["block_is"]                                        = eN.blk_is.block;
+        pith["block_state"]                                     = eN.blk_state.off;
+        pith["block_delim"]                                     = eN.blk_delim.off;
+        object_reset(an_object);
+        processing.remove("verse");
+        ++cntr;
+      } else if (pith["block_is"] == eN.blk_is.poem) {
+        an_object["bookindex_nugget"]
+          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
+        bookindex_unordered_hashes
+          = bookindex_extract_hash.bookindex_nugget_hash(
+            an_object["bookindex_nugget"],
+            obj_cite_digits,
+            tag_in_seg
+          );
+        an_object["is"]                                         = "verse";
+        auto comp_obj_location
+          = node_construct.node_location_emitter(
+            content_non_header,
+            tag_in_seg,
+            lev_anchor_tag,
+            tag_assoc,
+            obj_cite_digits,
+            cntr,
+            heading_ptr-1,
+            an_object["is"]
+          );
+        comp_obj_poem_ocn                                       = set_object_generic("body", "body", "block", "poem", "", obj_cite_digits.object_number);
+        comp_obj_poem_ocn.metainfo.identifier                   = obj_cite_digits.identifier;
+        comp_obj_poem_ocn.metainfo.object_number_off            = obj_cite_digits.off;
+        comp_obj_poem_ocn.metainfo.o_n_book_index               = obj_cite_digits.bkidx;
+        comp_obj_poem_ocn.metainfo.object_number_type           = obj_cite_digits.type;
+        the_document_body_section                               ~= comp_obj_poem_ocn;
+        pith["block_is"]                                        = eN.blk_is.poem;
+        pith["block_state"]                                     = eN.blk_state.off;
+        pith["block_delim"]                                     = eN.blk_delim.off;
+        object_reset(an_object);
+        processing.remove("verse");
+      } else if (pith["block_is"] == eN.blk_is.code) {
+        obj_cite_digits = ocn_emit(pith["ocn"]);
+        an_object["bookindex_nugget"]
+          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
+        bookindex_unordered_hashes
+          = bookindex_extract_hash.bookindex_nugget_hash(
+            an_object["bookindex_nugget"],
+            obj_cite_digits,
+            tag_in_seg
+          );
+        an_object["is"]                                         = "code";
+        auto comp_obj_location
+          = node_construct.node_location_emitter(
+            content_non_header,
+            tag_in_seg,
+            lev_anchor_tag,
+            tag_assoc,
+            obj_cite_digits,
+            cntr,
+            heading_ptr-1,
+            an_object["is"]
+          );
+        ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
+          = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
+        an_object["substantive"]                                = substantive_obj_misc_struct.obj_txt;
+        anchor_tag                                              = substantive_obj_misc_struct.anchor_tag;
+        comp_obj_                                               = set_object_generic("body", "body", "block", "code", an_object["substantive"], obj_cite_digits.object_number);
+        comp_obj_.metainfo.identifier                           = obj_cite_digits.identifier;
+        comp_obj_.metainfo.object_number_off                    = obj_cite_digits.off;
+        comp_obj_.metainfo.o_n_book_index                       = obj_cite_digits.bkidx;
+        comp_obj_.metainfo.object_number_type                   = obj_cite_digits.type;
+        comp_obj_.metainfo.syntax                               = an_object["syntax"];
+        comp_obj_.metainfo.attrib                               = an_object["attrib"];
+        comp_obj_.code_block.linenumbers                        = (an_object["attrib"].match(rgx.code_numbering)) ? true : false;
+        comp_obj_.tags.html_segment_anchor_tag_is               = tag_in_seg["seg_lv4"];
+        comp_obj_.tags.epub_segment_anchor_tag_is               = tag_in_seg["seg_lv1to4"];
+        comp_obj_.has.inline_notes_reg                          = substantive_obj_misc_struct.has_notes_reg;
+        comp_obj_.has.inline_notes_star                         = substantive_obj_misc_struct.has_notes_star;
+        comp_obj_.has.inline_links                              = substantive_obj_misc_struct.has_links;
+        the_document_body_section                               ~= comp_obj_;
+        pith["block_is"]                                        = eN.blk_is.code;
+        pith["block_state"]                                     = eN.blk_state.off;
+        pith["block_delim"]                                     = eN.blk_delim.off;
+        object_reset(an_object);
+        processing.remove("verse");
+        ++cntr;
+      } else if (pith["block_is"]    == eN.blk_is.table) {
+        comp_obj_ = comp_obj_.init;
+        obj_cite_digits = ocn_emit(pith["ocn"]);
+        an_object["bookindex_nugget"]
+          = ("bookindex_nugget" in an_object) ? an_object["bookindex_nugget"] : "";
+        bookindex_unordered_hashes
+          = bookindex_extract_hash.bookindex_nugget_hash(
+            an_object["bookindex_nugget"],
+            obj_cite_digits,
+            tag_in_seg
+          );
+        an_object["is"]                                         = "table";
+        auto comp_obj_location
+          = node_construct.node_location_emitter(
+            content_non_header,
+            tag_in_seg,
+            lev_anchor_tag,
+            tag_assoc,
+            obj_cite_digits,
+            cntr,
+            heading_ptr-1,
+            an_object["is"]
+          );
+        ST_txtAndAnchorTagPlusHasFootnotesUrlsImages substantive_obj_misc_struct
+          = obj_im.obj_inline_markup_and_anchor_tags_and_misc(an_object, an_object_key, conf_make_meta, No._new_doc);
+        an_object["substantive"]                                = substantive_obj_misc_struct.obj_txt;
+        comp_obj_                                               = comp_obj_.init;
+        comp_obj_.metainfo.ocn                                  = obj_cite_digits.object_number;
+        comp_obj_.metainfo.identifier                           = obj_cite_digits.identifier;
+        comp_obj_.metainfo.object_number_off                    = obj_cite_digits.off;
+        comp_obj_.tags.html_segment_anchor_tag_is               = tag_in_seg["seg_lv4"];
+        comp_obj_.tags.epub_segment_anchor_tag_is               = tag_in_seg["seg_lv1to4"];
+        comp_obj_.metainfo.o_n_book_index                       = obj_cite_digits.bkidx;
+        comp_obj_.metainfo.object_number_type                   = obj_cite_digits.type;
+        comp_obj_                                               = comp_obj_.flow_table_instructions(an_object["table_head"]);
+        {
+          auto _get = comp_obj_.flow_table_substantive_munge(an_object["substantive"]);
+          {
+            comp_obj_           = _get.table_object;
+            an_object["substantive"] = _get.table_substantive;
+          }
+        }
+        the_document_body_section                               ~= comp_obj_;
+        pith["block_is"]                                        = eN.blk_is.table;
+        pith["block_state"]                                     = eN.blk_state.off;
+        pith["block_delim"]                                     = eN.blk_delim.off;
+        object_reset(an_object);
+        processing.remove("verse");
+        ++cntr;
+      }
+    }
+    ST_flow_block_flag_line_empty ret;
+    {
+      ret.this_object                = an_object;
+      ret.the_document_body_section  = the_document_body_section;
+      ret.bookindex_unordered_hashes = bookindex_unordered_hashes;
+      ret.obj_cite_digits            = obj_cite_digits;
+      ret.comp_obj_                  = comp_obj_; //
+      ret.cntr                       = cntr;
+      ret.pith                       = pith;
+    }
+    return ret;
+  }
+  // ↓ - object set
+  @safe ObjGenericComposite set_object_heading()(
+    string level,
+    string part,
+    string section,
+    string text,
+  ) {
+    ObjGenericComposite comp_obj;
+    {
+      comp_obj                                                = comp_obj.init;
+      comp_obj.metainfo.is_of_part                            = part;
+      comp_obj.metainfo.is_of_section                         = section;
+      comp_obj.metainfo.is_of_type                            = "para";
+      comp_obj.metainfo.is_a                                  = "heading";
+      comp_obj.text                                           = text;
+      comp_obj.metainfo.ocn                                   = 0;
+      if (level == "lev1") {
+        comp_obj.metainfo.heading_lev_markup                  = 1;
+        comp_obj.metainfo.heading_lev_collapsed               = 1;
+        comp_obj.metainfo.parent_ocn                          = 1;
+        comp_obj.metainfo.parent_lev_markup                   = 0;
+      } else if (level == "lev4") {
+        comp_obj.metainfo.heading_lev_markup                  = 4;
+        comp_obj.metainfo.heading_lev_collapsed               = 1;
+        comp_obj.metainfo.parent_ocn                          = 1;
+        comp_obj.metainfo.parent_lev_markup                   = 0;
+        comp_obj.metainfo.dom_structure_markedup_tags_status  = [ 1, 1, 0, 0, 1, 0, 0, 0];
+        comp_obj.metainfo.dom_structure_collapsed_tags_status = [ 1, 1, 1, 0, 0, 0, 0, 0];
+      }
+    }
+    return comp_obj;
+  }
+  @safe ObjGenericComposite set_object_generic()(
+    string part,
+    string section,
+    string type,
+    string is_a,
+    string text,
+    int ocn,
+  ) {
+    ObjGenericComposite comp_obj;
+    {
+      comp_obj                                                = comp_obj.init;
+      comp_obj.metainfo.is_of_part                            = part;
+      comp_obj.metainfo.is_of_section                         = section;
+      comp_obj.metainfo.is_of_type                            = type;
+      comp_obj.metainfo.is_a                                  = is_a;
+      comp_obj.text                                           = text;
+      comp_obj.metainfo.ocn                                   = ocn;
+    }
+    return comp_obj;
+  }
+  // ↑ - object set
+  // ↓ - object inline munge
+  @safe static struct ObjInlineMarkupMunge {
+    string[string] obj_txt;
+    int n_foot, n_foot_reg, n_foot_sp_asterisk, n_foot_sp_plus;
+    string asterisks_, plus_;
+    string obj_txt_out, tail, note;
+    static auto rgx = RgxI();
+    static auto mkup = InlineMarkup();
+    int stage_reset_note_numbers = true;
+    private auto initialize_note_numbers() {
+      n_foot                          = 0;
+      n_foot_reg                      = 0;
+      n_foot_sp_asterisk              = 0;
+      n_foot_sp_plus                  = 0;
+    }
+    @safe static auto images()(string obj_txt_in) {
+      static auto mng = InlineMarkup();
+      // url matched
+      obj_txt_in = obj_txt_in.replaceAll(rgx.inline_notes_al_special, ""); // TODO reinstate when special footnotes are implemented
+      if (obj_txt_in.match(rgx.smid_image_generic)) {                            // images with and without links
+        debug(images) { writeln("Image: ", obj_txt_in); }
+        if (obj_txt_in.match(rgx.smid_image_with_dimensions)) {
+          obj_txt_in = obj_txt_in
+            .replaceAll(rgx.smid_image_with_dimensions, ("$1" ~ mkup.img ~ "$2,w$3h$4 " ~ "$5"))
+            .replaceAll(rgx.smid_image_delimit, ("$1"
+              ~ mkup.lnk_o ~ "$2".strip ~ mkup.lnk_c
+              ~ mkup.url_o ~ mkup.url_c));
+          debug(images) { writeln("IMAGE with size: ", obj_txt_in); }
+        } else if (obj_txt_in.match(rgx.smid_image)) {
+          obj_txt_in = obj_txt_in
+            .replaceAll(rgx.smid_image, ("$1" ~ mkup.img ~ "$2,w0h0" ~ "$3"))
+            .replaceAll(rgx.smid_image_delimit, ("$1"
+              ~ mkup.lnk_o ~ "$2".strip ~ mkup.lnk_c
+              ~ mkup.url_o ~ mkup.url_c));
+          debug(images) { writeln("IMAGE: ", obj_txt_in); } // decide on representation
+        }
+      }
+      return obj_txt_in;
+    }
+    @safe ST_txtPlusHasFootnotes footnotes_endnotes_markup_and_number_or_stars()(string obj_txt_in, bool reset_note_numbers) {
+      // endnotes (regular)
+      bool flg_notes_reg  = false;
+      bool flg_notes_star = false;
+      bool flg_notes_plus = false;
+      obj_txt_in = obj_txt_in.replaceAll(
+        rgx.inline_notes_curly,
+        (mkup.en_a_o ~ " $1" ~ mkup.en_a_c)
+      );
+      if (!(stage_reset_note_numbers) && reset_note_numbers) {
+        stage_reset_note_numbers = true;
+      }
+      obj_txt_out = "";
+      if (obj_txt_in.match(rgx.inline_notes_al_gen)) {
+        string[] _tmp_txt;
+        foreach (x; obj_txt_in.split("\n")) {
+          if (auto m = x.matchAll(rgx.inline_text_and_note_al_)) {
+            if (stage_reset_note_numbers) {
+              n_foot                  = 0;
+              n_foot_reg              = 0;
+              n_foot_sp_asterisk      = 0;
+              n_foot_sp_plus          = 0;
+            }
+            stage_reset_note_numbers = false;
+            foreach(n; m) {
+              if (n.hit.to!string.match(rgx.inline_al_delimiter_open_symbol_star)) {
+                flg_notes_star =  true;
+                ++n_foot_sp_asterisk;
+                asterisks_ = "*";
+                n_foot = n_foot_sp_asterisk;
+                _tmp_txt ~= n.hit.to!string.replaceFirst(
+                  rgx.inline_al_delimiter_open_symbol_star,
+                  (mkup.en_a_o ~ replicate(asterisks_, n_foot_sp_asterisk) ~ " ")
+                );
+              } else if (n.hit.to!string.match(rgx.inline_al_delimiter_open_symbol_plus)) {
+                flg_notes_plus =  true;
+                ++n_foot_sp_plus;
+                plus_ = "*";
+                n_foot = n_foot_sp_plus;
+                _tmp_txt ~= n.hit.to!string.replaceFirst(
+                  rgx.inline_al_delimiter_open_symbol_plus,
+                  (mkup.en_a_o ~ replicate(plus_, n_foot_sp_plus) ~ " ")
+                );
+              } else if (n.hit.to!string.matchFirst(rgx.inline_al_delimiter_open_regular)) {
+                string _tmp_str = n.hit.to!string;
+                flg_notes_reg =  true;
+                foreach (q; n.hit.to!string.matchAll(rgx.inline_al_delimiter_open_regular)) {
+                  ++n_foot_reg;
+                  n_foot = n_foot_reg;
+                  _tmp_str = replaceFirst!(m => mkup.en_a_o ~ n_foot.to!string ~ " ")
+                    (_tmp_str, rgx.inline_al_delimiter_open_regular);
+                }
+                _tmp_txt ~= _tmp_str;
+              } else {
+                _tmp_txt ~= n.hit.to!string;
+              }
+            }
+            obj_txt_out = _tmp_txt.join("\n");
+          }
+        }
+      } else {
+        obj_txt_out = obj_txt_in;
+      }
+      ST_txtPlusHasFootnotes ret;
+      {
+        ret.obj_txt            = obj_txt_out;
+        ret.has_notes_reg      = flg_notes_reg;
+        ret.has_notes_star     = flg_notes_star;
+        ret.has_notes_plus     = flg_notes_plus;
+      }
+      return ret;
+    }
+    @safe private ST_txtPlusHasFootnotesUrlsImages object_notes_and_links_()(
+      string obj_txt_in,
+      bool reset_note_numbers = false
+    ) {
+      obj_txt_out = "";
+      bool urls = false;
+      bool images_without_dimensions = false;
+      tail = "";
+      // special endnotes
+      obj_txt_in = obj_txt_in.replaceAll(
+        rgx.inline_notes_curly_sp_asterisk,
+        (mkup.en_a_o ~ "*" ~ " $1" ~ mkup.en_a_c)
+      );
+      obj_txt_in
+        = obj_txt_in.replaceAll(
+          rgx.inline_notes_curly_sp_plus,
+          (mkup.en_a_o ~ "+" ~ " $1" ~ mkup.en_a_c)
+        );
+      // image matched
+      if (obj_txt_in.match(rgx.smid_image_generic)) {
+        obj_txt_in = images(obj_txt_in);
+        if (obj_txt_in.match(rgx.smid_mod_image_without_dimensions)) {
+          images_without_dimensions = true;
+        }
+      }
+      // url matched
+      if (obj_txt_in.match(rgx.smid_inline_url)) {
+        urls = true;
+        obj_txt_in = obj_txt_in.links_and_images;
+      }
+      if (auto m = obj_txt_in.match(rgx.para_inline_link_anchor)) {
+        obj_txt_in = obj_txt_in
+          .replaceAll(rgx.para_inline_link_anchor, "┃$1┃");
+      }
+      ST_txtPlusHasFootnotes ftn = footnotes_endnotes_markup_and_number_or_stars(obj_txt_in, reset_note_numbers);
+      obj_txt_out = ftn.obj_txt;
+      debug(footnotes) { writeln(obj_txt_out, tail); }
+      obj_txt_out = obj_txt_out ~ tail;
+      debug(footnotesdone) {
+        foreach(m; matchAll(obj_txt_out, (mkup.en_a_o ~ `\s*(.+?)` ~ mkup.en_a_c))) {
+          writeln(m[1]);
+          writeln(m.hit);
+        }
+      }
+      ST_txtPlusHasFootnotesUrlsImages ret;
+      {
+        ret.obj_txt                       = obj_txt_out;
+        ret.has_notes_reg                 = ftn.has_notes_reg;
+        ret.has_notes_star                = ftn.has_notes_star;
+        ret.has_notes_plus                = ftn.has_notes_plus;
+        ret.has_urls                      = urls;
+        ret.has_images_without_dimensions = images_without_dimensions;
+      }
+      return ret;
+    }
+    @safe private ST_txtPlusHasFootnotesUrlsImages object_only_()(
+      string obj_txt_in,
+      bool reset_note_numbers = false
+    ) {
+      ST_txtPlusHasFootnotesUrlsImages ret;
+      {
+        ret.obj_txt                       = obj_txt_in;
+        ret.has_notes_reg                 = false;
+        ret.has_notes_star                = false;
+        ret.has_notes_plus                = false;
+        ret.has_urls                      = false;
+        ret.has_images_without_dimensions = false;
+      }
+      return ret;
+    }
+    ST_txtPlusHasFootnotesUrlsImages init() {
+      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_("");
+      return ret;
+    }
+    invariant() {
+    }
+    @safe ST_txtPlusHasFootnotesUrlsImages munge_heading()(
+      string obj_txt_in,
+      bool reset_note_numbers = false
+    ) {
+      obj_txt["munge"] = obj_txt_in
+       .replaceFirst(rgx.headings, "")
+       .replaceFirst(rgx.object_number_off_all, "")
+       .replaceFirst(rgx.markup_inline_linebreak, mkup.br_line_inline)
+       .strip;
+      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt["munge"], reset_note_numbers);
+      debug(munge) { writeln(__LINE__); writeln(obj_txt_in); writeln(__LINE__); writeln(obj_txt["munge"].to!string); }
+      return ret;
+    }
+    invariant() {
+    }
+    @safe ST_txtPlusHasFootnotesUrlsImages munge_para()(string obj_txt_in) {
+      obj_txt["munge"] = (obj_txt_in)
+        .replaceFirst(rgx.para_attribs, "")
+        .replaceFirst(rgx.object_number_off_all, "")
+        .replaceFirst(rgx.markup_inline_linebreak, mkup.br_line_inline);
+      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt["munge"]);
+      debug(munge) { writeln(__LINE__); writeln(obj_txt_in);
+        writeln(__LINE__);
+        writeln(obj_txt["munge"].to!string);
+      }
+      return ret;
+    }
+    @safe ST_txtPlusHasFootnotesUrlsImages munge_quote()(string obj_txt_in) {
+      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt_in.split("\n\n").join(" \\\\\n \\\\\n"));
+      return ret;
+    }
+    invariant() {
+    }
+    @safe ST_txtPlusHasFootnotesUrlsImages munge_group(string obj_txt_in) {
+      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt_in.split("\n\n").join("\n" ~ mkup.br_line_spaced ~ "\n"));
+      return ret;
+    }
+    invariant() {
+    }
+    @safe ST_txtPlusHasFootnotesUrlsImages munge_block()(string obj_txt_in) {
+      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt_in);
+      return ret;
+    }
+    invariant() {
+    }
+    @safe auto munge_verse()(string obj_txt_in) {
+      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt_in);
+      return ret;
+    }
+    invariant() {
+    }
+    @safe ST_txtPlusHasFootnotesUrlsImages munge_code()(string obj_txt_in) {
+      obj_txt_in = obj_txt_in.replaceAll(rgx.space, mkup.nbsp);
+      ST_txtPlusHasFootnotesUrlsImages ret = object_only_(obj_txt_in);
+      return ret;
+    }
+    invariant() {
+    }
+    @safe ST_txtPlusHasFootnotesUrlsImages munge_table()(string obj_txt_in) {
+      ST_txtPlusHasFootnotesUrlsImages ret = object_notes_and_links_(obj_txt_in);
+      return ret;
+    }
+    invariant() {
+    }
+    @safe ST_txtPlusHasFootnotesUrlsImages munge_comment()(string obj_txt_in) {
+      ST_txtPlusHasFootnotesUrlsImages ret = object_only_(obj_txt_in);
+      return ret;
+    }
+    invariant() {
+    }
+  }
+  // ↑ - object inline munge
+  // ↓ - object inline markup
+  static struct ObjInlineMarkup {
+    static auto rgx = RgxI();
+    static auto munge = ObjInlineMarkupMunge();
+    string[string] obj_txt;
+    string anchor_tag = "";
+    @safe ST_txtAndAnchorTagPlusHasFootnotesUrlsImages obj_inline_markup_and_anchor_tags_and_misc(CMM)(
+      string[string]   obj_,
+      string           obj_key_,
+      CMM              conf_make_meta,
+      Flag!"_new_doc"  _new_doc
+    ) {
+      obj_txt["munge"]                                = obj_[obj_key_].dup;
+      obj_txt["munge"]                                = (obj_["is"].match(ctRegex!(`verse|code`)))
+      ? obj_txt["munge"]
+      : obj_txt["munge"].strip;
+      if (_new_doc) {
+        anchor_tag = "";
+      }
+      auto x = munge.init;
+      ST_txtAndAnchorTagPlusHasFootnotesUrlsImages ret;
+      ret.obj_txt                       = "";
+      ret.anchor_tag                    = "";
+      ret.has_notes_reg                 = false;
+      ret.has_notes_star                = false;
+      ret.has_notes_plus                = false;
+      ret.has_links                     = false;
+      ret.has_images_without_dimensions = false;
+      if ((obj_["is"] == "para")
+        || (obj_["is"] == "heading")
+        || (obj_["is"] == "quote")
+        || (obj_["is"] == "group")
+        || (obj_["is"] == "block")
+        || (obj_["is"] == "verse")) {
+        obj_txt["munge"]                              = (obj_txt["munge"]).inline_markup_faces;
+        obj_txt["munge"]                              = (obj_txt["munge"]).links_and_images;
+      }
+      switch (obj_["is"]) {
+      case "heading":
+        if (_new_doc) {
+          anchor_tag                                  = "";
+        }
+        obj_txt["munge"] = _configured_auto_heading_numbering_and_segment_anchor_tags(obj_txt["munge"], obj_, conf_make_meta, _new_doc);
+        obj_txt["munge"] = _make_segment_anchor_tags_if_none_provided(obj_txt["munge"], obj_["lev"], _new_doc);
+        if (auto m = obj_txt["munge"].match(rgx.heading_anchor_tag)) {
+          anchor_tag                                  = m.captures[1];
+        } else if (obj_["lev"] == "1") {
+          writeln("heading anchor tag missing: ", obj_txt["munge"]);
+        }
+        x                                             = munge.munge_heading(obj_txt["munge"], reset_note_numbers);
+        reset_note_numbers = false;
+        goto default;
+      case "para":
+        x                                             = munge.munge_para(obj_txt["munge"]);
+        goto default;
+      case "group":
+        x                                             = munge.munge_group(obj_txt["munge"]);
+        goto default;
+      case "block":
+        x                                             = munge.munge_block(obj_txt["munge"]);
+        goto default;
+      case "quote":
+        x                                             = munge.munge_quote(obj_txt["munge"]);
+        goto default;
+      case "verse":
+        x                                             = munge.munge_verse(obj_txt["munge"]);
+        goto default;
+      case "code":
+        x                                             = munge.munge_code(obj_txt["munge"]);
+        goto default;
+      case "table":
+        x                                             = munge.munge_table(obj_txt["munge"]);
+        goto default;
+      case "comment":
+        x                                             = munge.munge_comment(obj_txt["munge"]);
+        goto default;
+      case "doc_end_reset":
+        munge.initialize_note_numbers();
+        break;
+      default:
+        // para, heading, group, block, verse
+        ret.obj_txt                       = x.obj_txt;
+        ret.anchor_tag                    = anchor_tag;
+        ret.has_notes_reg                 = x.has_notes_reg;
+        ret.has_notes_star                = x.has_notes_star;
+        ret.has_notes_plus                = x.has_notes_plus;
+        ret.has_links                     = x.has_urls;
+        ret.has_images_without_dimensions = x.has_images_without_dimensions;
+        break;
+      }
+      anchor_tag = "";
+      return ret;
+    }
+    invariant() {
+    }
+    @safe auto _clean_heading_toc_()(
+      char[] heading_toc_,
+    ) {
+     auto m = (cast(char[]) heading_toc_).matchFirst(rgx.heading);
+     heading_toc_ = (m.post).replaceAll(rgx.inline_notes_curly_gen, "");
+     return heading_toc_;
+    };
+    @safe ST_flow_table_of_contents_gather_headings flow_table_of_contents_gather_headings(CMM)( //
+      string[string]         obj_,
+      CMM                    conf_make_meta,
+      string[string]         tag_in_seg,
+      string                 _anchor_tag,
+      string[][string]       lev4_subtoc,
+      ObjGenericComposite[]  the_document_toc_section,
+    ) {
+      ObjGenericComposite comp_obj_;
+      mixin InternalMarkup;
+      static auto mkup = InlineMarkup();
+      char[] heading_toc_                             = (obj_["substantive"].dup.strip.to!(char[]))
+        .replaceAll(rgx.inline_notes_al, "");
+      heading_toc_                                    = _clean_heading_toc_(heading_toc_);
+      auto attrib = "";
+      string toc_txt_, subtoc_txt_;
+      int[string] indent;
+      if (obj_["lev_markup_number"].to!int > 0) {
+        indent = [
+          "hang_position" : obj_["lev_markup_number"].to!int,
+          "base_position" : obj_["lev_markup_number"].to!int,
+        ];
+        toc_txt_ = format("%s%s%s%s#%s%s",
+          mkup.lnk_o,
+          heading_toc_.strip,
+          mkup.lnk_c,
+          mkup.url_o,
+          _anchor_tag,
+          mkup.url_c,
+        );
+        toc_txt_= toc_txt_.links_and_images;
+        comp_obj_                                  = set_object_generic("frontmatter", "toc", "para", "toc", toc_txt_.to!string.strip, 0);
+        comp_obj_.metainfo.identifier              = "";
+        comp_obj_.metainfo.object_number_off       = true;
+        comp_obj_.metainfo.object_number_type      = 0;
+        comp_obj_.metainfo.dummy_heading           = (an_object["dummy_heading_status"] == "t") ? true: false;
+        comp_obj_.attrib.indent_hang               = indent["hang_position"];
+        comp_obj_.attrib.indent_base               = indent["base_position"];
+        comp_obj_.attrib.bullet                    = false;
+        comp_obj_.has.inline_links                 = true;
+        the_document_toc_section                   ~= comp_obj_;
+      }
+      comp_obj_                                    = comp_obj_.init;
+      comp_obj_.metainfo.is_of_part                = "frontmatter";
+      comp_obj_.metainfo.is_of_section             = "toc";
+      comp_obj_.metainfo.is_of_type                = "para";
+      comp_obj_.metainfo.is_a                      = "toc";
+      comp_obj_.metainfo.ocn                       = 0;
+      comp_obj_.metainfo.identifier                = "";
+      comp_obj_.metainfo.object_number_off         = true;
+      comp_obj_.metainfo.object_number_type        = 0;
+      comp_obj_.metainfo.dummy_heading             = (an_object["dummy_heading_status"] == "t") ? true: false;
+      comp_obj_.attrib.bullet                      = false;
+      comp_obj_.has.inline_links                   = true;
+      switch (obj_["lev_markup_number"].to!int) {
+      case 0: .. case 3:
+        break;
+      case 4:
+        lev4_subtoc[tag_in_seg["seg_lv4"]] = [];
+        break;
+      case 5: .. case 7:
+        subtoc_txt_ = format("%s%s%s%s#%s%s",
+          mkup.lnk_o,
+          heading_toc_.strip,
+          mkup.lnk_c,
+          mkup.url_o,
+          _anchor_tag,
+          mkup.url_c,
+        );
+        lev4_subtoc[tag_in_seg["seg_lv4"]]
+        ~= links_and_images(obj_["lev_markup_number"]
+             ~ "~ " ~ subtoc_txt_.to!string.strip
+           );
+        break;
+      default:
+        break;
+      }
+      ST_flow_table_of_contents_gather_headings ret;
+      {
+        ret.the_document_toc_section = the_document_toc_section;
+        ret.lev4_subtoc              = lev4_subtoc;
+      }
+      return ret;
+    }
+    invariant() {
+    }
+  private:
+    static int[] heading_num = [ 0, 0, 0, 0 ];
+    static string heading_number_auto_composite = "";
+    static string heading_number_auto_composite_segname = "";
+    static bool[] auto_heading_numbering = [ true, true, true, true];
+    @safe static string _configured_auto_heading_numbering_and_segment_anchor_tags(CMM)(
+      string           munge_,
+      string[string]   obj_,
+      CMM              conf_make_meta,
+      bool             _new_doc,
+    ) {
+      if (_new_doc) {
+        heading_num                         = [ 0, 0, 0, 0 ];
+        heading_number_auto_composite       = "";
+        auto_heading_numbering              = [ true, true, true, true];
+      }
+      if (conf_make_meta.make.auto_num_top_lv) {
+        if (obj_["lev_markup_number"].to!int == 0) {
+          heading_num[0]                    = 0;
+          heading_num[1]                    = 0;
+          heading_num[2]                    = 0;
+          heading_num[3]                    = 0;
+          heading_number_auto_composite     = "";
+        }
+        // auto_num_depth minimum 0
+        // (1.) default 2 (1.1.1) max 3 (1.1.1.1) implement
+        if (
+          conf_make_meta.make.auto_num_top_lv
+          > obj_["lev_markup_number"].to!uint
+        ) {
+          heading_num[1]                    = 0;
+          heading_num[2]                    = 0;
+          heading_num[3]                    = 0;
+        } else if (
+          conf_make_meta.make.auto_num_top_lv
+            == obj_["lev_markup_number"].to!uint
+        ) {
+          auto_heading_numbering[0] =
+            (munge_.match(rgx.auto_heading_numbering_off_lv1)) ? false : true;
+          if (auto_heading_numbering[0]) {
+            heading_num[0] ++;
+          }
+          heading_num[1]                    = 0;
+          heading_num[2]                    = 0;
+          heading_num[3]                    = 0;
+        } else if (
+          conf_make_meta.make.auto_num_top_lv
+            == (obj_["lev_markup_number"].to!uint - 1)
+        ) {
+          auto_heading_numbering[1] =
+            (munge_.match(rgx.auto_heading_numbering_off_lv2)) ? false : true;
+          if (auto_heading_numbering[0]
+          && auto_heading_numbering[1]) {
+            heading_num[1] ++;
+          }
+          heading_num[2]                    = 0;
+          heading_num[3]                    = 0;
+        } else if (
+          conf_make_meta.make.auto_num_top_lv
+            == (obj_["lev_markup_number"].to!uint - 2)
+        ) {
+          auto_heading_numbering[2] =
+            (munge_.match(rgx.auto_heading_numbering_off_lv3)) ? false : true;
+          if (auto_heading_numbering[0]
+          && auto_heading_numbering[1]
+          && auto_heading_numbering[2]) {
+            heading_num[2] ++;
+          }
+          heading_num[3]                    = 0;
+        } else if (
+          conf_make_meta.make.auto_num_top_lv
+            == (obj_["lev_markup_number"].to!uint - 3)
+        ) {
+          auto_heading_numbering[3] =
+            (munge_.match(rgx.auto_heading_numbering_off_lv4)) ? false : true;
+          if (auto_heading_numbering[0]
+          && auto_heading_numbering[1]
+          && auto_heading_numbering[2]
+          && auto_heading_numbering[3]) {
+            heading_num[3] ++;
+          }
+        }
+        if (auto_heading_numbering[0]) {
+          if (heading_num[3] > 0) {
+            heading_number_auto_composite
+              = (conf_make_meta.make.auto_num_depth.to!uint == 3
+                && auto_heading_numbering[3])
+              ? (format(q"┃%s.%s.%s.%s┃",
+                  heading_num[0].to!string,
+                  heading_num[1].to!string,
+                  heading_num[2].to!string,
+                  heading_num[3].to!string
+                ))
+              : "";
+          } else if (heading_num[2] > 0) {
+            heading_number_auto_composite
+              = ((conf_make_meta.make.auto_num_depth.to!uint >= 2)
+                && (conf_make_meta.make.auto_num_depth.to!uint <= 3)
+                && auto_heading_numbering[2])
+              ? (format(q"┃%s.%s.%s┃",
+                  heading_num[0].to!string,
+                  heading_num[1].to!string,
+                  heading_num[2].to!string
+                ))
+              : "";
+          } else if (heading_num[1] > 0) {
+            heading_number_auto_composite
+              = ((conf_make_meta.make.auto_num_depth.to!uint >= 1)
+                && (conf_make_meta.make.auto_num_depth.to!uint <= 3)
+                && auto_heading_numbering[1])
+              ? (format(q"┃%s.%s┃",
+                  heading_num[0].to!string,
+                  heading_num[1].to!string
+                ))
+              : "";
+          } else if (heading_num[0] > 0
+            && munge_.match(rgx.auto_heading_numbering_lv1)
+          ) {
+            heading_number_auto_composite
+              = ((conf_make_meta.make.auto_num_depth.to!uint >= 0)
+                && (conf_make_meta.make.auto_num_depth.to!uint <= 3)
+                && auto_heading_numbering[0])
+              ? (format(q"┃%s┃",
+                  heading_num[0].to!string
+                ))
+              : "";
+          } else {
+            heading_number_auto_composite = "";
+          }
+        }
+        heading_number_auto_composite_segname =
+          (heading_number_auto_composite.empty)
+            ? ""
+            : "seg_" ~ heading_number_auto_composite;
+        debug(heading_number_auto) { writeln(heading_number_auto_composite); }
+        if ((!empty(heading_number_auto_composite))
+        && (obj_["lev_markup_number"].to!uint >= conf_make_meta.make.auto_num_top_lv)) {
+          munge_ = munge_
+          .replaceFirst(rgx.heading,
+            "$1~$2 " ~ heading_number_auto_composite ~ ". ")
+          .replaceFirst(rgx.heading_marker_missing_tag,
+            "$1~" ~ heading_number_auto_composite_segname ~ " ");
+        }
+      }
+      return munge_;
+    }
+    static int heading_num_lev1 = 0;
+    @safe static string _make_segment_anchor_tags_if_none_provided()(
+      string munge_,
+      string lev_,
+      bool   _new_doc
+    ) {
+      if (!(munge_.match(rgx.heading_anchor_tag))) {
+        if (lev_ == "A") { // (_new_doc)
+          heading_num_lev1 = 0;
+        }
+        if (munge_.match(rgx.heading_identify_anchor_tag)) {
+          if (auto m = munge_.match(rgx.heading_extract_named_anchor_tag)) {
+            munge_ = munge_.replaceFirst(
+              rgx.heading_marker_missing_tag,
+              "$1~" ~ m.captures[1].toLower ~ "_"  ~ m.captures[2] ~ " ");
+            if (auto n = munge_.match(rgx.heading_anchor_tag_plus_colon)) {
+              auto tag_remunge_ = n.captures[2]
+                .replaceAll(rgx.heading_marker_tag_has_colon, "..");
+              munge_ = munge_.replaceFirst(rgx.heading_anchor_tag_plus_colon, n.captures[1] ~ tag_remunge_ ~ " ");
+            }
+          } else if (auto m = munge_.match(rgx.heading_extract_unnamed_anchor_tag)) {
+            munge_ = munge_.replaceFirst(
+              rgx.heading_marker_missing_tag,
+              "$1~" ~ "s" ~ m.captures[1] ~ " ");
+          }
+        } else if (lev_ == "1") { // (if not successful) manufacture a unique anchor tag for lev == "1"
+          heading_num_lev1 ++;
+          munge_ = munge_.replaceFirst(
+            rgx.heading_marker_missing_tag,
+            "$1~" ~ "x" ~ heading_num_lev1.to!string ~ " ");
+        }
+      }
+      return munge_;
+    }
+  }
+  // ↑ - object inline markup
+  // ↓ - object attributes
+  struct ObjAttributes {
+    string[string] _obj_attrib;
+    @safe string obj_attributes()(
+      string              obj_is_,
+      string              obj_raw,
+      ObjGenericComposite comp_obj_,
+    ) {
+      scope(exit) {
+        destroy(obj_is_);
+        destroy(obj_raw);
+        destroy(comp_obj_);
+      }
+      _obj_attrib["json"] ="{";
+      switch (obj_is_) {
+      case "heading":
+        _obj_attrib["json"] ~= txt_heading(obj_raw);
+        break;
+      case "para":
+        _obj_attrib["json"] ~= txt_para_and_blocks(obj_raw)
+        ~ txt_para(obj_raw);
+        break;
+      case "code":
+        _obj_attrib["json"] ~= txt_code(obj_raw);
+        break;
+      case "group":
+        _obj_attrib["json"] ~= txt_para_and_blocks(obj_raw)
+        ~ txt_group(obj_raw);
+        break;
+      case "block":
+        _obj_attrib["json"] ~= txt_para_and_blocks(obj_raw)
+        ~ txt_block(obj_raw);
+        break;
+      case "verse":
+        _obj_attrib["json"] ~= txt_verse(obj_raw);
+        break;
+      case "quote":
+        _obj_attrib["json"] ~= txt_quote(obj_raw);
+        break;
+      case "table":
+        _obj_attrib["json"] ~= txt_table(obj_raw);
+        break;
+      case "comment":
+        _obj_attrib["json"] ~= txt_comment(obj_raw);
+        break;
+      default:
+        _obj_attrib["json"] ~= txt_para(obj_raw);
+        break;
+      }
+      _obj_attrib["json"] ~= " }";
+      _obj_attrib["json"] = _set_additional_values_parse_as_json(_obj_attrib["json"], obj_is_, comp_obj_);
+      debug(structattrib) {
+        if (oa_j["is"].str() == "heading") {
+          writeln(_obj_attrib["json"]);
+          writeln(
+            "is: ", oa_j["is"].str(),
+            "; object_number: ", oa_j["object_number"].integer()
+          );
+        }
+      }
+      return _obj_attrib["json"];
+    }
+    invariant() {
+    }
+    private:
+    string _obj_attributes;
+    @safe string txt_para_and_blocks()(string obj_txt_in) {
+      if (obj_txt_in.matchFirst(rgx.para_bullet)) {
+        _obj_attributes =" \"bullet\": \"true\","
+        ~ " \"indent_hang\": 0,"
+        ~ " \"indent_base\": 0,";
+      } else if (auto m = obj_txt_in.matchFirst(rgx.para_bullet_indent)) {
+        _obj_attributes =" \"bullet\": \"true\","
+        ~ " \"indent_hang\": " ~ m["indent"].to!string ~ ","
+        ~ " \"indent_base\": " ~ m["indent"].to!string ~ ",";
+      } else if (auto m = obj_txt_in.matchFirst(rgx.para_indent_hang)) {
+        _obj_attributes =" \"bullet\": \"false\","
+        ~ " \"indent_hang\": " ~ m["hang"].to!string ~ ","
+        ~ " \"indent_base\": " ~ m["indent"].to!string ~ ",";
+      } else if (auto m = obj_txt_in.matchFirst(rgx.para_indent)) {
+        _obj_attributes =" \"bullet\": \"false\","
+        ~ " \"indent_hang\": " ~ m["indent"].to!string ~ ","
+        ~ " \"indent_base\": " ~ m["indent"].to!string ~ ",";
+      } else {
+        _obj_attributes =" \"bullet\": \"false\","
+        ~ " \"indent_hang\": 0,"
+        ~ " \"indent_base\": 0,";
+      }
+      return _obj_attributes;
+    }
+    @safe string txt_heading()(string obj_txt_in) {
+      _obj_attributes = " \"use\": \"content\","
+      ~ " \"of\": \"para\","
+      ~ " \"is\": \"heading\"";
+      return _obj_attributes;
+    }
+    invariant() {
+    }
+    @safe string txt_para()(string obj_txt_in) {
+      _obj_attributes = " \"use\": \"content\","
+      ~ " \"of\": \"para\","
+      ~ " \"is\": \"para\"";
+      return _obj_attributes;
+    }
+    invariant() {
+    }
+    @safe string txt_quote()(string obj_txt_in) {
+      _obj_attributes = " \"use\": \"content\","
+      ~ " \"of\": \"block\","
+      ~ " \"is\": \"quote\"";
+      return _obj_attributes;
+    }
+    invariant() {
+    }
+    @safe string txt_group()(string obj_txt_in) {
+      _obj_attributes = " \"use\": \"content\","
+      ~ " \"of\": \"block\","
+      ~ " \"is\": \"group\"";
+      return _obj_attributes;
+    }
+    invariant() {
+    }
+    @safe string txt_block()(string obj_txt_in) {
+      _obj_attributes = " \"use\": \"content\","
+      ~ " \"of\": \"block\","
+      ~ " \"is\": \"block\"";
+      return _obj_attributes;
+    }
+    invariant() {
+    }
+    @safe string txt_verse()(string obj_txt_in) {
+      _obj_attributes = " \"use\": \"content\","
+      ~ " \"of\": \"block\","
+      ~ " \"is\": \"verse\"";
+      return _obj_attributes;
+    }
+    invariant() {
+    }
+    @safe string txt_code()(string obj_txt_in) {
+      _obj_attributes = " \"use\": \"content\","
+      ~ " \"of\": \"block\","
+      ~ " \"is\": \"code\"";
+      return _obj_attributes;
+    }
+    invariant() {
+    }
+    @safe string txt_table()(string obj_txt_in) {
+      _obj_attributes = " \"use\": \"content\","
+      ~ " \"of\": \"block\","
+      ~ " \"is\": \"table\"";
+      return _obj_attributes;
+    }
+    invariant() {
+    }
+    @safe string txt_comment()(string obj_txt_in) {
+      _obj_attributes = " \"use\": \"comment\","
+      ~ " \"of\": \"comment\","
+      ~ " \"is\": \"comment\"";
+      return _obj_attributes;
+    }
+    invariant() {
+    }
+    @safe string _set_additional_values_parse_as_json()(
+      string              _obj_attrib,
+      string              obj_is_,
+      ObjGenericComposite comp_obj_,
+    ) {
+      JSONValue oa_j = parseJSON(_obj_attrib);
+      assert(
+        (oa_j.type == JSON_TYPE.OBJECT)
+      );
+      if (obj_is_ == "heading") {
+        oa_j.object["object_number"]              = comp_obj_.metainfo.ocn;
+        oa_j.object["lev_markup_number"]          = comp_obj_.metainfo.heading_lev_markup;
+        oa_j.object["lev_collapsed_number"]       = comp_obj_.metainfo.heading_lev_collapsed;
+        oa_j.object["heading_ptr"]                = comp_obj_.ptr.heading;
+        oa_j.object["doc_object_ptr"]             = comp_obj_.ptr.doc_object;
+      }
+      oa_j.object["parent_object_number"]         = comp_obj_.metainfo.parent_ocn;
+      oa_j.object["parent_lev_markup_number"]     = comp_obj_.metainfo.parent_lev_markup;
+      _obj_attrib                                 = oa_j.toString();
+      return _obj_attrib;
+    }
+  }
+  // ↑ - object attributes
+  // ↓ - object tags
+  @safe pure ObjGenericComposite obj_dom_structure_set_markup_tags()(
+    ObjGenericComposite  obj,
+    int[]                dom,
+    int                  lev
+  ) {
+    foreach (i; 0 .. 8) {
+      if (i < lev) {
+        if (dom[i] == DomTags.open
+           || dom[i] == DomTags.close_and_open
+        ) {
+          dom[i] = DomTags.open_still;
+        } else if (dom[i] == DomTags.close) {
+          dom[i] = DomTags.none;
+        }
+      } else if (i == lev) {
+        if (lev  == 0
+          && dom[i] == DomTags.open_still
+        ) {
+          dom[i] = DomTags.close;
+        } else if (dom[i] == DomTags.open
+          || dom[i] == DomTags.open_still
+          || dom[i] == DomTags.close_and_open
+        ) {
+          dom[i] = DomTags.close_and_open;
+        } else {
+          dom[i] = DomTags.open;
+        }
+      } else if (i > lev) {
+        if (dom[i] == DomTags.close) {
+          dom[i] = DomTags.none;
+        } else if (dom[i] == DomTags.open
+          || dom[i] == DomTags.open_still
+          || dom[i] == DomTags.close_and_open
+        ) {
+          dom[i] = DomTags.close;
+        }
+      }
+    }
+    debug(dom_magic_numbers) { writeln("marked up: ", lev, ": ", dom); }
+    obj.metainfo.dom_structure_markedup_tags_status = dom.dup;
+    return obj;
+  }
+  @safe pure ObjGenericComposite obj_dom_set_collapsed_tags()(
+    ObjGenericComposite  obj,
+    int[]                dom,
+    int                  lev
+  ) {
+    foreach (i; 0 .. 8) {
+      if (i < lev) {
+        if (dom[i] == DomTags.open
+           || dom[i] == DomTags.close_and_open
+        ) {
+          dom[i] = DomTags.open_still;
+        } else if (dom[i] == DomTags.close) {
+          dom[i] = DomTags.none;
+        }
+      } else if (i == lev) {
+        if (lev  == 0
+          && dom[i] == DomTags.open_still
+        ) {
+          dom[i] = DomTags.close;
+        } else if (dom[i] == DomTags.open
+          || dom[i] == DomTags.open_still
+          || dom[i] == DomTags.close_and_open
+        ) {
+          dom[i] = DomTags.close_and_open;
+        } else {
+          dom[i] = DomTags.open;
+        }
+      } else if (i > lev) {
+        if (dom[i] == DomTags.close) {
+          dom[i] = DomTags.none;
+        } else if (dom[i] == DomTags.open
+          || dom[i] == DomTags.open_still
+          || dom[i] == DomTags.close_and_open
+        ) {
+          dom[i] = DomTags.close;
+        }
+      }
+    }
+    debug(dom_magic_numbers) { writeln("collapsed: ", lev, ": ", dom); }
+    obj.metainfo.dom_structure_collapsed_tags_status = dom.dup;
+    return obj;
+  }
+  // ↑ - object tags
+  // ↓ - table of contents
+  @system ObjGenericComposite[] backmatter_gather_table_of_contents(
+    ObjGenericComposite[] the_document_endnotes_section,
+    ObjGenericComposite[] the_document_glossary_section,
+    ObjGenericComposite[] the_document_bibliography_section,
+    ObjGenericComposite[] the_document_bookindex_section,
+    ObjGenericComposite[] the_document_blurb_section,
+  ) {
+    ObjGenericComposite[] toc_section_backmatter;
+    string toc_txt_;
+    static auto mkup = InlineMarkup();
+    ObjGenericComposite   comp_obj_;
+    int[string] indent = [
+      "hang_position" : 1,
+      "base_position" : 1,
+    ];
+    comp_obj_                                          = set_object_generic("frontmatter", "toc", "para", "toc", "", 0);
+    comp_obj_.metainfo.identifier                      = "";
+    comp_obj_.metainfo.object_number_off               = true;
+    comp_obj_.metainfo.object_number_type              = 0;
+    comp_obj_.attrib.indent_hang                       = indent["hang_position"];
+    comp_obj_.attrib.indent_base                       = indent["base_position"];
+    comp_obj_.attrib.bullet                            = false;
+    if (the_document_endnotes_section.length > 1) {
+      toc_txt_ = format("%s%s%s%s#%s%s",
+        mkup.lnk_o,
+        "Endnotes",
+        mkup.lnk_c,
+        mkup.url_o,
+        "endnotes",
+        mkup.url_c,
+      );
+      toc_txt_= toc_txt_.links_and_images;
+      comp_obj_.text                                   = toc_txt_.to!string.strip;
+      comp_obj_.has.inline_links                       = true;
+      toc_section_backmatter                           ~= comp_obj_;
+    }
+    if (the_document_glossary_section.length > 1) {
+      toc_txt_ = format("%s%s%s%s#%s%s",
+        mkup.lnk_o,
+        "Glossary",
+        mkup.lnk_c,
+        mkup.url_o,
+        "glossary",
+        mkup.url_c,
+      );
+      toc_txt_= toc_txt_.links_and_images;
+      comp_obj_.text                                   = toc_txt_.to!string.strip;
+      comp_obj_.has.inline_links                       = true;
+      toc_section_backmatter                           ~= comp_obj_;
+    }
+    if (the_document_bibliography_section.length > 1){
+      toc_txt_ = format("%s%s%s%s#%s%s",
+        mkup.lnk_o,
+        "Bibliography",
+        mkup.lnk_c,
+        mkup.url_o,
+        "bibliography",
+        mkup.url_c,
+      );
+      toc_txt_= toc_txt_.links_and_images;
+      comp_obj_.text                                   = toc_txt_.to!string.strip;
+      comp_obj_.has.inline_links                       = true;
+      toc_section_backmatter                           ~= comp_obj_;
+    }
+    if (the_document_bookindex_section.length > 1) {
+      toc_txt_ = format("%s%s%s%s#%s%s",
+        mkup.lnk_o,
+        "Book Index",
+        mkup.lnk_c,
+        mkup.url_o,
+        "bookindex",
+        mkup.url_c,
+      );
+      toc_txt_= toc_txt_.links_and_images;
+      comp_obj_.text                                   = toc_txt_.to!string.strip;
+      comp_obj_.has.inline_links                       = true;
+      toc_section_backmatter                           ~= comp_obj_;
+    }
+    if (the_document_blurb_section.length > 1) {
+      toc_txt_ = format("%s%s%s%s#%s%s",
+        mkup.lnk_o,
+        "Blurb",
+        mkup.lnk_c,
+        mkup.url_o,
+        "blurb",
+        mkup.url_c,
+      );
+      toc_txt_= toc_txt_.links_and_images;
+      comp_obj_.has.inline_links                       = true;
+      comp_obj_.text                                   = toc_txt_.to!string.strip;
+      toc_section_backmatter                           ~= comp_obj_;
+    }
+    debug(toc) {
+      writefln( "%s %s", __LINE__,);
+      foreach (toc_linked_heading; toc_section_backmatter) {
+        writeln(mkup.indent_by_spaces_provided(toc_linked_heading.attrib.indent_hang), toc_linked_heading.text);
+      }
+    }
+    return toc_section_backmatter;
+  }
+  // ↑ - table of contents
+  // ↓ - endnotes
+  struct NotesSection {
+    string[string] object_notes;
+    int previous_count;
+    int mkn;
+    static auto rgx = RgxI();
+    @safe private auto gather_notes_for_endnote_section(
+      ObjGenericComposite[] contents_am,
+      string[string]        tag_in_seg,
+      int                   cntr,
+    ) {
+      assert((contents_am[cntr].metainfo.is_a == "para")
+      || (contents_am[cntr].metainfo.is_a     == "heading")
+      || (contents_am[cntr].metainfo.is_a     == "quote")
+      || (contents_am[cntr].metainfo.is_a     == "group")
+      || (contents_am[cntr].metainfo.is_a     == "block")
+      || (contents_am[cntr].metainfo.is_a     == "verse"));
+      assert(cntr >= previous_count);
+      assert(
+        (contents_am[cntr].text).match(
+        rgx.inline_notes_al_all_note)
+      );
+      mixin InternalMarkup;
+      previous_count = cntr;
+      static auto mkup = InlineMarkup();
+      static auto munge = ObjInlineMarkupMunge();
+      foreach(m;
+        (contents_am[cntr].text).matchAll(
+          rgx.inline_notes_al_special_char_note)
+      ) {
+        debug(endnotes_build) { writeln(
+            "{", mkup.ff_i, mkup.superscript, mkup.ff_o, m["char"], ".", mkup.ff_c, mkup.superscript, "}"
+            ~ mkup.mark_internal_site_lnk,
+            tag_in_seg["seg_lv4"],
+              ".fnSuffix#noteref_\n  ", m["char"], " ",
+            m["note"]); // sometimes need segment name (segmented html & epub)
+        }
+        // you need anchor for segments at this point ->
+        object_notes["anchor"] ~= "note_" ~ m["char"] ~ "』";
+        object_notes["notes"]  ~= (tag_in_seg["seg_lv4"].empty)
+        ? (links_and_images(
+            "{" ~ mkup.ff_i ~ mkup.superscript  ~ mkup.ff_o ~ m["char"] ~ "." ~ mkup.ff_c  ~ mkup.superscript  ~ "}#noteref_"
+            ~ m["char"]) ~ " "
+            ~ m["note"] ~ "』"
+          )
+        : (links_and_images(
+            "{" ~ mkup.ff_i ~ mkup.superscript ~ mkup.ff_o ~ m["char"] ~ "." ~ mkup.ff_c  ~ mkup.superscript ~ "}"
+             ~ mkup.mark_internal_site_lnk
+             ~ tag_in_seg["seg_lv4"]
+             ~ ".fnSuffix#noteref_"
+             ~ m["char"]) ~ " "
+             ~ m["note"] ~ "』"
+          );
+      }
+      foreach(m;
+        (contents_am[cntr].text).matchAll(
+          rgx.inline_notes_al_regular_number_note)
+      ) {
+        debug(endnotes_build) { writeln(
+            "{", mkup.ff_i, mkup.superscipt, mkup.ff_o, m["num"], ".", mkup.ff_c, mkup.superscipt, "}"
+            ~ mkup.mark_internal_site_lnk,
+            tag_in_seg["seg_lv4"],
+              ".fnSuffix#noteref_\n  ", m["num"], " ",
+            m["note"]); // sometimes need segment name (segmented html & epub)
+        }
+        // you need anchor for segments at this point ->
+        object_notes["anchor"] ~= "note_" ~ m["num"] ~ "』";
+        object_notes["notes"]  ~= (tag_in_seg["seg_lv4"].empty)
+        ? (links_and_images(
+            "{" ~ mkup.ff_i ~ mkup.superscript  ~ mkup.ff_o ~ m["num"] ~ "." ~ mkup.ff_c  ~ mkup.superscript  ~ "}#noteref_"
+            ~ m["num"]) ~ " "
+            ~ m["note"] ~ "』"
+          )
+        : (links_and_images(
+            "{" ~ mkup.ff_i ~ mkup.superscript ~ mkup.ff_o ~ m["num"] ~ "." ~ mkup.ff_c  ~ mkup.superscript ~ "}"
+             ~ mkup.mark_internal_site_lnk
+             ~ tag_in_seg["seg_lv4"]
+             ~ ".fnSuffix#noteref_"
+             ~ m["num"]) ~ " "
+             ~ m["note"] ~ "』"
+          );
+      }
+      return object_notes;
+    }
+    @safe private auto gathered_notes() {
+      string[][string] endnotes_;
+      if (object_notes.length > 1) {
+        endnotes_["notes"] = (object_notes["notes"].split(rgx.break_string))[0..$-1];
+        endnotes_["anchor"] = (object_notes["anchor"].split(rgx.break_string))[0..$-1];
+      } else {
+        endnotes_["notes"] = [];
+        endnotes_["anchor"] = [];
+      }
+      return endnotes_;
+    }
+    @safe private ST_endnotes backmatter_endnote_objects(O)(
+      OCNset         obj_cite_digits,
+      O              opt_action,
+    ) {
+      mixin spineNode;
+      ObjGenericComposite[] the_document_endnotes_section;
+      auto endnotes_ = gathered_notes();
+      string type_is;
+      string lev, lev_markup_number, lev_collapsed_number;
+      string attrib;
+      int[string] indent;
+      ObjGenericComposite comp_obj_;
+      if ((endnotes_["notes"].length > 0)
+      && (opt_action.backmatter && opt_action.section_endnotes)) {
+        {
+          comp_obj_                                     = set_object_heading("lev1", "backmatter", "endnotes", "Endnotes");
+          comp_obj_.metainfo.identifier                 = "";
+          comp_obj_.metainfo.dummy_heading              = false;
+          comp_obj_.metainfo.object_number_off          = false;
+          comp_obj_.metainfo.object_number_type         = 0;
+          comp_obj_.tags.segment_anchor_tag_epub        = "_part_endnotes";
+          comp_obj_.tags.anchor_tag_html                = comp_obj_.tags.segment_anchor_tag_epub;
+          comp_obj_.tags.in_segment_html                = "endnotes";
+          comp_obj_.tags.anchor_tags                    = ["section_endnotes"];
+          the_document_endnotes_section                 ~= comp_obj_;
+          tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+          tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+          ++mkn;
+        }
+        {
+          comp_obj_                                     = set_object_heading("lev4", "backmatter", "endnotes", "Endnotes");
+          comp_obj_.metainfo.identifier                 = "";
+          comp_obj_.metainfo.dummy_heading              = true;
+          comp_obj_.metainfo.object_number_off          = true;
+          comp_obj_.metainfo.object_number_type         = 0;
+          comp_obj_.tags.segment_anchor_tag_epub        = "endnotes";
+          comp_obj_.tags.anchor_tag_html                = comp_obj_.tags.segment_anchor_tag_epub;
+          comp_obj_.tags.in_segment_html                = comp_obj_.tags.anchor_tag_html;
+          comp_obj_.tags.anchor_tags                    = ["endnotes"];
+          the_document_endnotes_section                 ~= comp_obj_;
+          tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+          tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+          ++mkn;
+        }
+      } else {
+        comp_obj_                                       = set_object_heading("lev1", "empty", "empty", "(skip) there are no Endnotes");
+        comp_obj_.metainfo.identifier                   = "";
+        comp_obj_.metainfo.dummy_heading                = true;
+        comp_obj_.metainfo.object_number_off            = true;
+        comp_obj_.metainfo.object_number_type           = 0;
+        the_document_endnotes_section                   ~= comp_obj_;
+      }
+      if (opt_action.backmatter && opt_action.section_endnotes) {
+        ObjGenericComposite comp_obj_endnote_;
+        comp_obj_endnote_                                       = set_object_generic("backmatter", "endnotes", "para", "endnote", "", 0);
+        comp_obj_endnote_.metainfo.identifier                   = "";
+        // comp_obj_.metainfo.dummy_heading                     = false;
+        comp_obj_.metainfo.object_number_off                    = true;
+        comp_obj_.metainfo.object_number_type                   = 0;
+        comp_obj_endnote_.attrib.indent_hang                    = 0;
+        comp_obj_endnote_.attrib.indent_base                    = 0;
+        comp_obj_endnote_.attrib.bullet                         = false;
+        foreach (i, endnote; endnotes_["notes"]) {
+          auto     m                                            = endnote.matchFirst(rgx.note_ref);
+          string   notenumber                                   = m["ref"].to!string;
+          string   anchor_tag                                   = "note_" ~ notenumber;
+          comp_obj_endnote_.tags.anchor_tags                    = [ endnotes_["anchor"][i] ];
+          comp_obj_endnote_.has.inline_links                    = true;
+          comp_obj_endnote_.text                                = endnote.inline_markup_faces.strip;
+          the_document_endnotes_section                         ~= comp_obj_endnote_;
+        }
+      }
+      ST_endnotes ret;
+      {
+        ret.endnotes = the_document_endnotes_section;
+        ret.ocn      = obj_cite_digits;
+      }
+      return ret;
+    }
+  }
+  // ↑ - endnotes
+  // ↓ - section book index
+  @system ST_flow_book_index flow_book_index_(B)(
+    char[]          line,
+    string[string]  an_object,
+    string          book_idx_tmp,
+    uint[string]    pith,
+    B               opt_action,
+  ) {
+    static auto rgx = RgxI();
+    if (auto m = line.match(rgx.book_index_item)) {                                   // match book_index
+      debug(bookindexmatch) { writefln(
+          "* [bookindex] %s\n",
+          m["bookindex"].to!string,
+        );
+      }
+      an_object["bookindex_nugget"] = m.captures[1].to!string;
+    } else if (auto m = line.match(rgx.book_index_item_open))  {                      // match open book_index
+      pith["section"] = eN.sect.book_index;
+      if (opt_action.backmatter && opt_action.section_bookindex) {
+        book_idx_tmp = m.captures[1].to!string;
+        debug(bookindexmatch) { writefln( "* [bookindex] %s\n", book_idx_tmp,); }
+      }
+    } else if (pith["section"] == eN.sect.book_index)  {                    // book_index flag set
+      if (auto m = line.match(rgx.book_index_item_close))  {
+        pith["section"] = eN.sect.unset;
+        if (opt_action.backmatter
+        && opt_action.section_bookindex) {
+          an_object["bookindex_nugget"] = book_idx_tmp ~ m.captures[1].to!string;
+          debug(bookindexmatch) { writefln( "* [bookindex] %s\n", book_idx_tmp,); }
+        }
+        book_idx_tmp = "";
+      } else {
+        if (opt_action.backmatter
+        && opt_action.section_bookindex) {
+          book_idx_tmp ~= line;
+        }
+      }
+    }
+    ST_flow_book_index ret;
+    {
+      ret.this_object    = an_object;
+      ret.pith           = pith;
+      ret.book_idx_tmp   = book_idx_tmp;
+    }
+    return ret;
+  }
+  struct BookIndexNuggetHash {
+    string main_term, sub_term, sub_term_bits;
+    int object_number_offset, object_number_endpoint;
+    string[] object_numbers;
+    string[][string][string] bi_hash_nugget;
+    string[] bi_main_terms_split_arr;
+    @safe string[][string][string] bookindex_nugget_hash(S)(
+      string bookindex_section,
+      OCNset obj_cite_digits,
+      S      tag_in_seg,
+    ) {
+      debug(asserts) { static assert(is(typeof(obj_cite_digits.object_number) == int)); }
+      debug(bookindexraw) {
+        if (!bookindex_section.empty) {
+          writeln(
+            "* [bookindex] ",
+            "[", obj_cite_digits.object_number.to!string, ": ", tag_in_seg["seg_lv4"], "] ", bookindex_section,
+            "  - - - ",
+            "[", obj_cite_digits.object_number.to!string, "] ", bookindex_section
+          );
+        }
+      }
+      static auto rgx = RgxI();
+      if (!bookindex_section.empty) {
+        auto bi_main_terms_split_arr
+          = bookindex_section.split(rgx.bi_main_terms_split);
+        foreach (bi_main_terms_content; bi_main_terms_split_arr) {
+          auto bi_main_term_and_rest
+            = bi_main_terms_content.split(rgx.bi_main_term_plus_rest_split);
+          if (auto m = bi_main_term_and_rest[0].match(
+            rgx.bi_term_and_object_numbers_match)
+          ) {
+            main_term = m.captures[1].strip;
+            object_number_offset = m.captures[2].to!int;
+            object_number_endpoint = (obj_cite_digits.object_number + object_number_offset);
+            object_numbers ~= (obj_cite_digits.object_number.to!string
+            ~ "-" ~ object_number_endpoint.to!string);
+          } else {
+            main_term = bi_main_term_and_rest[0].strip;
+            object_numbers ~= obj_cite_digits.object_number.to!string;
+          }
+          bi_hash_nugget[main_term]["_a"] ~= object_numbers;
+          object_numbers = null;
+          if (bi_main_term_and_rest.length > 1) {
+            auto bi_sub_terms_split_arr
+              = bi_main_term_and_rest[1].split(
+                rgx.bi_sub_terms_plus_object_number_offset_split
+              );
+            foreach (sub_terms_bits; bi_sub_terms_split_arr) {
+              if (auto m = sub_terms_bits.match(rgx.bi_term_and_object_numbers_match)) {
+                sub_term = m.captures[1].strip;
+                object_number_offset = m.captures[2].to!int;
+                object_number_endpoint = (obj_cite_digits.object_number + object_number_offset);
+                object_numbers ~= (obj_cite_digits.object_number.to!string
+                ~ " - " ~ object_number_endpoint.to!string);
+              } else {
+                sub_term = sub_terms_bits.strip;
+                object_numbers ~= obj_cite_digits.object_number.to!string;
+              }
+              if (!empty(sub_term)) {
+                bi_hash_nugget[main_term][sub_term] ~= object_numbers;
+              }
+              object_numbers = null;
+            }
+          }
+        }
+      }
+      return bi_hash_nugget;
+    }
+    invariant() {
+    }
+  }
+  struct BookIndexReportIndent {
+    int mkn, skn;
+    @safe void bookindex_report_indented()(
+      string[][string][string] bookindex_unordered_hashes
+    ) {
+      auto mainkeys
+        = bookindex_unordered_hashes.byKey.array.sort().release;
+      foreach (mainkey; mainkeys) {
+        debug(bookindex1) { writeln(mainkey); }
+        auto subkeys
+          = bookindex_unordered_hashes[mainkey].byKey.array.sort().release;
+        foreach (subkey; subkeys) {
+          debug(bookindex1) {
+            writeln("  ", subkey);
+            writeln("    ", to!string(
+              bookindex_unordered_hashes[mainkey][subkey]
+            ));
+          }
+          ++skn;
+        }
+        ++mkn;
+      }
+    }
+  }
+  struct BookIndexReportSection {
+    int  mkn, skn;
+    static auto rgx = RgxI();
+    static auto munge = ObjInlineMarkupMunge();
+    @safe void bookindex_write_section()(
+      string[][string][string] bookindex_unordered_hashes
+    ) {
+      auto mainkeys =
+        bookindex_unordered_hashes.byKey.array
+        .sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable).release;
+      foreach (mainkey; mainkeys) {
+        write("_0_1 ⑆!┨", mainkey, "┣! ");
+        foreach (ref_; bookindex_unordered_hashes[mainkey]["_a"]) {
+          auto go = ref_.replaceAll(rgx.book_index_go, "$1");
+          write(" {", ref_, "}#", go, ", ");
+        }
+        writeln(" \\\\");
+        bookindex_unordered_hashes[mainkey].remove("_a");
+        auto subkeys =
+          bookindex_unordered_hashes[mainkey].byKey.array
+          .sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable).release;
+        foreach (subkey; subkeys) {
+          write("  ", subkey, ", ");
+          foreach (ref_; bookindex_unordered_hashes[mainkey][subkey]) {
+            auto go = ref_.replaceAll(rgx.book_index_go, "$1");
+            write(" {", ref_, "}#", go, ", ");
+          }
+          writeln(" \\\\");
+          ++skn;
+        }
+        ++mkn;
+      }
+    }
+    @system ST_bookindex backmatter_bookindex_build_abstraction_section(B)(
+      string[][string][string] bookindex_unordered_hashes,
+      OCNset                   obj_cite_digits,
+      B                        opt_action,
+    ) {
+      debug(asserts) { static assert(is(typeof(obj_cite_digits.object_number) == int)); }
+      mixin spineNode;
+      mixin InternalMarkup;
+      static auto mkup = InlineMarkup();
+      string type_is;
+      string lev;
+      int heading_lev_markup, heading_lev_collapsed;
+      string attrib;
+      int[string] indent;
+      auto mainkeys =
+        bookindex_unordered_hashes.byKey.array
+        .sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable).release;
+      ObjGenericComposite[] bookindex_section;
+      ObjGenericComposite comp_obj_;
+      auto node_para_int_ = node_metadata_para_int;
+      auto node_para_str_ = node_metadata_para_str;
+      if ((mainkeys.length > 0)
+      && (opt_action.backmatter
+      && opt_action.section_bookindex)) {
+        string bi_tmp;
+        string[] bi_tmp_tags;
+        {
+          comp_obj_                                     =  set_object_heading("lev1", "backmatter", "bookindex", "Book Index");
+          comp_obj_.metainfo.identifier                 = "";
+          comp_obj_.metainfo.dummy_heading              = false;
+          comp_obj_.metainfo.object_number_off          = false;
+          comp_obj_.metainfo.object_number_type         = 0;
+          comp_obj_.tags.segment_anchor_tag_epub        = "_part_book_index";
+          comp_obj_.tags.anchor_tag_html                = comp_obj_.tags.segment_anchor_tag_epub;
+          comp_obj_.tags.in_segment_html                = "bookindex";
+          comp_obj_.tags.anchor_tags                    = ["section_bookindex"];
+          comp_obj_.has.inline_links                    = true;
+          bookindex_section                             ~= comp_obj_;
+          tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+          tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+          ++mkn;
+        }
+        {
+          comp_obj_                                     = set_object_heading("lev4", "backmatter", "bookindex", "Index");
+          comp_obj_.metainfo.identifier                 = "";
+          comp_obj_.metainfo.dummy_heading              = true;
+          comp_obj_.metainfo.object_number_off          = true;
+          comp_obj_.metainfo.object_number_type         = 0;
+          comp_obj_.tags.segment_anchor_tag_epub        = "bookindex";
+          comp_obj_.tags.anchor_tag_html                = comp_obj_.tags.segment_anchor_tag_epub;
+          comp_obj_.tags.in_segment_html                = comp_obj_.tags.anchor_tag_html;
+          comp_obj_.metainfo.heading_lev_collapsed      = 2;
+          comp_obj_.has.inline_links                    = false;
+          comp_obj_.tags.anchor_tags                    = ["bookindex"];
+          bookindex_section                             ~= comp_obj_;
+          tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+          tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+          ++mkn;
+        }
+        import std.array : appender;
+        auto buffer = appender!(char[])();
+        string[dchar] transTable = [' ' : "_"];
+        foreach (mainkey; mainkeys) {
+          bi_tmp_tags = [""];
+          bi_tmp = mkup.ff_i ~ mkup.bold ~ mkup.ff_o ~ mainkey ~ mkup.ff_c ~ mkup.bold ~ " ";
+          buffer.clear();
+          bi_tmp_tags ~= translate(mainkey, transTable);
+          auto bkidx_lnk(string locs) {
+            string markup = "";
+            if (auto m = locs.matchFirst(rgx.book_index_go)) {
+              markup
+                = links_and_images("{ " ~ m["link"] ~ " }"
+                ~ "#" ~ m["ocn"] ~ ", ");
+            } else {
+              writeln(__LINE__, ": ", locs);
+            }
+            return markup;
+          }
+          foreach (ref_; bookindex_unordered_hashes[mainkey]["_a"]) {
+            bi_tmp ~= bkidx_lnk(ref_);
+          }
+          bi_tmp ~= " \\\\\n    ";
+          bookindex_unordered_hashes[mainkey].remove("_a");
+          auto subkeys =
+            bookindex_unordered_hashes[mainkey].byKey.array
+            .sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable).release;
+          foreach (subkey; subkeys) {
+            bi_tmp ~= subkey ~ ", ";
+            buffer.clear();
+            bi_tmp_tags ~= translate(subkey, transTable);
+            foreach (ref_; bookindex_unordered_hashes[mainkey][subkey]) {
+              bi_tmp ~= bkidx_lnk(ref_);
+            }
+            bi_tmp ~= " \\\\\n    ";
+            ++skn;
+          }
+          bi_tmp                                             = bi_tmp.replaceFirst(rgx.trailing_linebreak, "");
+          comp_obj_                                          = set_object_generic("backmatter", "bookindex", "para", "bookindex", bi_tmp.to!string.strip, 0);
+          comp_obj_.metainfo.identifier                      = "";
+          comp_obj_.metainfo.object_number_off               = true;
+          comp_obj_.metainfo.object_number_type              = 0;
+          comp_obj_.tags.anchor_tags                         = bi_tmp_tags;
+          comp_obj_.attrib.indent_hang                       = 0;
+          comp_obj_.attrib.indent_base                       = 1;
+          comp_obj_.attrib.bullet                            = false;
+          comp_obj_.has.inline_links                         = true;
+          comp_obj_.text                                     = bi_tmp.to!string.strip;
+          bookindex_section                                  ~= comp_obj_;
+          ++mkn;
+        }
+      } else {                              // no book index, (figure out what to do here)
+        comp_obj_                                       = set_object_heading("lev1", "backmatter", "bookindex", "(skip) there is no Book Index");
+        comp_obj_.metainfo.identifier                   = "";
+        comp_obj_.metainfo.dummy_heading                = true;
+        comp_obj_.metainfo.object_number_off            = true;
+        bookindex_section                               ~= comp_obj_;
+      }
+      ST_bookindex ret;
+      {
+        ret.bookindex = bookindex_section;
+        ret.ocn       = obj_cite_digits;
+      }
+      return ret;
+    }
+  }
+  // ↑ - section book index
+  // ↓ - section glossary
+  // ↓ build
+  ST_the_section build_the_glossary_section(
+    char[]                 line,             // line is immutable, not necessary to return unchanged
+    uint[string]           pith,             // double check, should not be necessary to pass pith
+    string[string][string] tag_assoc,        // only for headings: html & epub
+  ) {
+    static auto rgx = RgxI();
+    ObjGenericComposite comp_obj_;
+    ObjGenericComposite[] add_to_current_document_section;
+    indent = [
+      "hang_position" : 0,
+      "base_position" : 0,
+    ];
+    bullet = false;
+    pith["txt_is"]           = eN.txt_is.para;
+    line_occur["para"]       = eN.bi.off;
+    an_object_key            = "glossary_nugget";
+    ST_the_section ret;
+    if (line.matchFirst(rgx.heading_glossary)) {
+      {
+        comp_obj_                                = set_object_heading("lev1", "backmatter", "glossary", "Glossary");
+        comp_obj_.metainfo.identifier            = "";
+        comp_obj_.metainfo.dummy_heading         = false;
+        comp_obj_.metainfo.object_number_off     = false;
+        comp_obj_.metainfo.object_number_type    = 0;
+        comp_obj_.tags.segment_anchor_tag_epub   = "_part_glossary";
+        comp_obj_.tags.anchor_tag_html           = comp_obj_.tags.segment_anchor_tag_epub;
+        comp_obj_.tags.in_segment_html           = "glossary";
+        comp_obj_.tags.anchor_tags               = ["section_glossary"];
+        comp_obj_.metainfo.dom_structure_markedup_tags_status  = [ 1, 1, 0, 0, 0, 0, 0, 0];
+        comp_obj_.metainfo.dom_structure_collapsed_tags_status = [ 1, 1, 0, 0, 0, 0, 0, 0];
+        add_to_current_document_section           ~= comp_obj_; //
+        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+      } {
+        comp_obj_                                = set_object_heading("lev4", "backmatter", "glossary", "Glossary");
+        comp_obj_.metainfo.identifier            = "";
+        comp_obj_.metainfo.dummy_heading         = true;
+        comp_obj_.metainfo.object_number_off     = true;
+        comp_obj_.metainfo.object_number_type    = 0;
+        comp_obj_.tags.segment_anchor_tag_epub   = "glossary";
+        comp_obj_.tags.anchor_tag_html           = comp_obj_.tags.segment_anchor_tag_epub;
+        comp_obj_.tags.in_segment_html           = comp_obj_.tags.anchor_tag_html;
+        comp_obj_.metainfo.heading_lev_collapsed = 2;
+        comp_obj_.tags.anchor_tags               = ["glossary"];
+        add_to_current_document_section          ~= comp_obj_; //
+        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+        pith["ocn"] = eN.ocn.on;
+      }
+      {
+        ret.comp_section_obj         ~= add_to_current_document_section;
+        ret.pith                     = pith;
+        ret.tag_assoc                = tag_assoc; // only for headings: html & epub
+      }
+    } else { // para
+      {
+        auto _get = line.flow_para_match_(an_object, an_object_key, indent, bullet, pith, line_occur);
+        {
+          an_object     = _get.this_object;
+          an_object_key = _get.this_object_key;
+          pith          = _get.pith;
+          indent        = _get.indent;
+          bullet        = _get.bullet;
+          line_occur    = _get.line_occur;
+        }
+      }
+      comp_obj_                               = set_object_generic("backmatter", "glossary", "para", "glossary", links_and_images(line.to!string.strip).replaceFirst(rgx.para_attribs, ""), 0);
+      comp_obj_.metainfo.identifier           = "";
+      comp_obj_.metainfo.object_number_off    = true;
+      comp_obj_.metainfo.object_number_type   = 0;
+      comp_obj_.attrib.indent_hang            = indent["hang_position"];
+      comp_obj_.attrib.indent_base            = indent["base_position"];
+      comp_obj_.attrib.bullet                 = bullet;
+      add_to_current_document_section         ~= comp_obj_; //
+      pith["ocn"]                             = eN.ocn.on;
+      {
+        ret.comp_section_obj = add_to_current_document_section;
+        ret.pith             = pith;
+        ret.tag_assoc        = tag_assoc; // NO CHANGE here, only for headings: html & epub
+      }
+    }
+    return ret;
+  }
+  // ↑ - section glossary
+  // ↓ - section bibliography
+  @system ST_biblio_section backmatter_make_the_bibliography_section()(
+    string[]     biblio_unsorted_incomplete,
+    JSONValue[]  bib_arr_json,
+  ) {
+    Bibliography biblio = Bibliography();
+    ObjGenericComposite comp_obj_;
+    static auto mkup = InlineMarkup();
+    ST_flow_bibliography _get = biblio.flow_bibliography_(biblio_unsorted_incomplete, bib_arr_json);
+    JSONValue[] biblio_ordered;
+    biblio_ordered            = _get.biblio_sorted;
+    if (biblio_ordered.length > 0) {
+      {
+        comp_obj_                                 = set_object_heading("lev1", "backmatter", "bibliography", "Bibliography");
+        comp_obj_.metainfo.identifier             = "";
+        comp_obj_.metainfo.dummy_heading          = false;
+        comp_obj_.metainfo.object_number_off      = false;
+        comp_obj_.metainfo.object_number_type     = 0;
+        comp_obj_.tags.segment_anchor_tag_epub    = "_part_bibliography";
+        comp_obj_.tags.anchor_tag_html            = comp_obj_.tags.segment_anchor_tag_epub;
+        comp_obj_.tags.in_segment_html            = "bibliography";
+        comp_obj_.tags.anchor_tags                = ["section_bibliography"];
+        comp_obj_.metainfo.dom_structure_markedup_tags_status  = [ 1, 1, 0, 0, 0, 0, 0, 0];
+        comp_obj_.metainfo.dom_structure_collapsed_tags_status = [ 1, 1, 0, 0, 0, 0, 0, 0];
+        the_document_bibliography_section         ~= comp_obj_;
+        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+      }
+      {
+        comp_obj_                                 = set_object_heading("lev4", "backmatter", "bibliography", "Bibliography");
+        comp_obj_.metainfo.identifier             = "";
+        comp_obj_.metainfo.dummy_heading          = true;
+        comp_obj_.metainfo.object_number_off      = true;
+        comp_obj_.metainfo.object_number_type     = 0;
+        comp_obj_.tags.segment_anchor_tag_epub    = "bibliography";
+        comp_obj_.tags.anchor_tag_html            = comp_obj_.tags.segment_anchor_tag_epub;
+        comp_obj_.tags.in_segment_html            = comp_obj_.tags.anchor_tag_html;
+        comp_obj_.tags.anchor_tags                = ["bibliography"];
+        the_document_bibliography_section         ~= comp_obj_;
+        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+      }
+      {
+        string out_;
+        foreach (entry; biblio_ordered) {
+          out_ = format("%s \"%s\"%s%s%s%s%s%s%s%s%s.",
+            ((entry["author"].str.empty) ? entry["editor"].str : entry["author"].str),
+            entry["fulltitle"].str,
+            ((entry["journal"].str.empty) ? "" : ", " ~ mkup.ff_i ~ mkup.italic ~ mkup.ff_o ~ entry["journal"].str ~ mkup.ff_c ~ mkup.italic),
+            ((entry["volume"].str.empty) ? "" : ", " ~ entry["volume"].str),
+            ((entry["in"].str.empty) ? "" : ", " ~ entry["in"].str),
+            ((!(entry["author"].str.empty) && (!(entry["editor"].str.empty))) ? entry["editor"].str : ""),
+            ", " ~ entry["year"].str,
+            ((entry["pages"].str.empty) ? "" : ", " ~ entry["pages"].str),
+            ((entry["publisher"].str.empty) ? "" : ", " ~ entry["publisher"].str),
+            ((entry["place"].str.empty) ? "" : ", " ~ entry["place"].str),
+            ((entry["url"].str.empty) ? "" : ", [" ~ entry["url"].str ~ "]"),
+          );
+          comp_obj_                                   = set_object_generic("backmatter", "bibliography", "para", "bibliography", out_.to!string.strip, 0);
+          comp_obj_.metainfo.identifier               = "";
+          comp_obj_.metainfo.object_number_off        = true;
+          comp_obj_.metainfo.object_number_type       = 0;
+          comp_obj_.attrib.indent_hang                = 0;
+          comp_obj_.attrib.indent_base                = 1;
+          comp_obj_.attrib.bullet                     = bullet;
+          comp_obj_.tags.anchor_tags                  = [anchor_tag];
+          the_document_bibliography_section           ~= comp_obj_;
+        }
+      }
+    } else {
+      comp_obj_                                   = set_object_heading("lev1", "empty", "empty", "(skip) there is no Bibliography");
+      comp_obj_.metainfo.identifier               = "";
+      comp_obj_.metainfo.dummy_heading            = true;
+      comp_obj_.metainfo.object_number_off        = true;
+      comp_obj_.metainfo.object_number_type       = 0;
+      the_document_bibliography_section           ~= comp_obj_;
+    }
+    debug(bibliosection) { foreach (o; the_document_bibliography_section) { writeln(o.text); } }
+    ST_biblio_section ret;
+    {
+      ret.bibliography_section = the_document_bibliography_section;
+      ret.tag_assoc            = tag_assoc; //
+    }
+    return ret;
+  }
+  struct Bibliography {
+    @system ST_flow_bibliography flow_bibliography_()(
+      string[]    biblio_unsorted_incomplete,
+      JSONValue[] bib_arr_json
+    ) {
+      JSONValue[] biblio_unsorted
+        = biblio_make_unsorted_array_of_json_objects(biblio_unsorted_incomplete, bib_arr_json); // TODO lookat returns
+      biblio_arr_json = [];
+      biblio_unsorted_incomplete = [];
+      JSONValue[] biblio_sorted__ = biblio_sort(biblio_unsorted);
+      debug(biblio0) {
+        biblio_debug(biblio_sorted__);
+        writeln("---");
+        writeln("unsorted incomplete: ", biblio_unsorted_incomplete.length);
+        writeln("json:                ", bib_arr_json.length);
+        writeln("unsorted:            ", biblio_unsorted.length);
+        writeln("sorted:              ", biblio_sorted__.length);
+        int cntr;
+        int[7] x;
+        while (cntr < x.length) {
+          writeln(cntr, ": ", biblio_sorted__[cntr]["fulltitle"]);
+          cntr++;
+        }
+      }
+      ST_flow_bibliography ret;
+      {
+        ret.biblio_sorted  = biblio_sorted__;
+        ret.bib_arr_json  = bib_arr_json;
+        ret.biblio_unsorted_incomplete  = biblio_unsorted_incomplete;
+      }
+      return ret;
+    }
+    @system final private JSONValue[] biblio_make_unsorted_array_of_json_objects()(
+      string[]      biblio_unordered,
+      JSONValue[]   bib_arr_json
+    ) {
+      foreach (bibent; biblio_unordered) {
+        // update bib to include deemed_author, needed for:
+        // sort_bibliography_array_by_deemed_author_year_title
+        // either: sort on multiple fields, or; create such sort field
+        JSONValue j = parseJSON(bibent);
+        if (!empty(j["fulltitle"].str)) {
+          if (!empty(j["author_raw"].str)) {
+            j["deemed_author"] = j["author_arr"][0];
+          } else if (!empty(j["editor_raw"].str)) {
+            j["deemed_author"] = j["editor_arr"][0];
+          }
+          j["sortby_deemed_author_year_title"] = (
+            j["deemed_author"].str ~
+             "; " ~
+             j["year"].str ~
+             "; "  ~
+             j["fulltitle"].str
+          );
+        }
+        bib_arr_json ~= j;
+      }
+      return bib_arr_json.dup;
+    }
+    @system final private JSONValue[] biblio_sort()(JSONValue[] biblio_unordered) {
+      JSONValue[] biblio_sorted_;
+      biblio_sorted_
+        = sort!((a, b){
+          return ((a["sortby_deemed_author_year_title"].str) < (b["sortby_deemed_author_year_title"].str));
+        })(biblio_unordered).array;
+      debug(bibliosorted) {
+        foreach (j; biblio_sorted_) {
+          if (!empty(j["fulltitle"].str)) { writeln(j["sortby_deemed_author_year_title"]); }
+        }
+      }
+      return biblio_sorted_;
+    }
+    @system void biblio_debug()(JSONValue[] biblio_sorted) {
+      debug(biblio0) {
+        foreach (j; biblio_sorted) {
+          if (!empty(j["fulltitle"].str)) { writeln(j["sortby_deemed_author_year_title"]); }
+        }
+      }
+    }
+  }
+  // ↑ - section bibliography
+  // ↓ - section blurb
+  ST_the_section build_the_blurb_section(Opt) (
+    char[]                 line,             // line is immutable, not necessary to return unchanged
+    uint[string]           pith,             // double check, should not be necessary to pass pith
+    string[string][string] tag_assoc,        // only for headings: html & epub
+    Opt                    opt_action,
+  ) {
+    static auto rgx = RgxI();
+    ObjGenericComposite comp_obj_;
+    ObjGenericComposite[] add_to_current_document_section;
+    // assert (opt_action.backmatter && opt_action.section_blurb);
+    indent = [
+      "hang_position" : 0,
+      "base_position" : 0,
+    ];
+    bullet = false;
+    if (auto m = line.matchFirst(rgx.para_indent)) {
+      debug(paraindent) { writeln(line); }
+      indent["hang_position"] = (m["indent"]).to!int;
+      indent["base_position"] = (m["indent"]).to!int;
+    } else if (line.matchFirst(rgx.para_bullet)) {
+      debug(parabullet) { writeln(line); }
+      bullet = true;
+    } else if (auto m = line.matchFirst(rgx.para_indent_hang)) {
+      debug(paraindenthang) { writeln(line); }
+      indent = [
+        "hang_position" : (m["hang"]).to!int,
+        "base_position" : (m["indent"]).to!int,
+      ];
+    } else if (auto m = line.matchFirst(rgx.para_bullet_indent)) {
+      debug(parabulletindent) { writeln(line); }
+      indent = [
+        "hang_position" : (m["indent"]).to!int,
+        "base_position" : (m["indent"]).to!int,
+      ];
+      bullet = true;
+    }
+    pith["txt_is"]           = eN.txt_is.para;
+    line_occur["para"]       = eN.bi.off;
+    an_object_key = "blurb_nugget";
+    ST_the_section ret;
+    if (line.matchFirst(rgx.heading_blurb)
+    && (opt_action.backmatter && opt_action.section_blurb)) {
+      {
+        comp_obj_                                              = set_object_heading("lev1", "backmatter", "blurb", "Blurb");
+        comp_obj_.metainfo.identifier                          = "";
+        comp_obj_.metainfo.dummy_heading                       = false;
+        comp_obj_.metainfo.object_number_off                   = false;
+        comp_obj_.metainfo.object_number_type                  = 0;
+        comp_obj_.tags.segment_anchor_tag_epub                 = "_part_blurb";
+        comp_obj_.tags.anchor_tag_html                         = comp_obj_.tags.segment_anchor_tag_epub;
+        comp_obj_.tags.in_segment_html                         = "blurb";
+        comp_obj_.tags.anchor_tags                             = ["section_blurb"];
+        comp_obj_.metainfo.dom_structure_markedup_tags_status  = [ 1, 1, 0, 0, 0, 0, 0, 0];
+        comp_obj_.metainfo.dom_structure_collapsed_tags_status = [ 1, 1, 0, 0, 0, 0, 0, 0];
+        add_to_current_document_section                                 ~= comp_obj_;
+        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+      }
+      {
+        comp_obj_                                              = set_object_heading("lev4", "backmatter", "blurb", "Blurb");
+        comp_obj_.metainfo.identifier                          = "";
+        comp_obj_.metainfo.dummy_heading                       = true;
+        comp_obj_.metainfo.object_number_off                   = true;
+        comp_obj_.metainfo.object_number_type                  = 0;
+        comp_obj_.tags.segment_anchor_tag_epub                 = "blurb";
+        comp_obj_.tags.anchor_tag_html                         = comp_obj_.tags.segment_anchor_tag_epub;
+        comp_obj_.tags.in_segment_html                         = comp_obj_.tags.anchor_tag_html;
+        comp_obj_.metainfo.heading_lev_collapsed               = 2;
+        comp_obj_.tags.anchor_tags                             = ["blurb"];
+        add_to_current_document_section                                 ~= comp_obj_;
+        tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+        tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+      }
+    } else if (line.matchFirst(rgx.headings)
+    && (opt_action.backmatter && opt_action.section_blurb)) {
+      comp_obj_                                              = comp_obj_.init;
+      comp_obj_.metainfo.is_of_part                          = "backmatter";
+      comp_obj_.metainfo.is_of_section                       = "blurb";
+      comp_obj_.metainfo.is_of_type                          = "para";
+      comp_obj_.metainfo.is_a                                = "heading";
+      comp_obj_.text                                         = line.to!string;
+      comp_obj_.metainfo.ocn                                 = 0;
+      comp_obj_.metainfo.identifier                          = "";
+      comp_obj_.metainfo.dummy_heading                       = false;
+      comp_obj_.metainfo.object_number_off                   = true;
+      comp_obj_.metainfo.object_number_type                  = 0;
+      comp_obj_.tags.segment_anchor_tag_epub                 = "blurb";
+      comp_obj_.tags.anchor_tag_html                         = comp_obj_.tags.segment_anchor_tag_epub;
+      comp_obj_.tags.in_segment_html                         = comp_obj_.tags.anchor_tag_html;
+      comp_obj_.metainfo.heading_lev_markup                  = an_object["lev_markup_number"].to!int;    // make int, remove need to conv
+      comp_obj_.metainfo.heading_lev_collapsed               = an_object["lev_collapsed_number"].to!int; // make int, remove need to conv
+      comp_obj_.metainfo.parent_ocn                          = 1;
+      comp_obj_.metainfo.parent_lev_markup                   = 0;
+      add_to_current_document_section                                 ~= comp_obj_;
+      tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+      tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+    } else if (!(line.empty)) {
+      {
+        auto _get = line.flow_para_match_(an_object, an_object_key, indent, bullet, pith, line_occur);
+        {
+          an_object     = _get.this_object;
+          an_object_key = _get.this_object_key;
+          pith          = _get.pith;
+          indent        = _get.indent;
+          bullet        = _get.bullet;
+          line_occur    = _get.line_occur;
+        }
+      }
+      comp_obj_                               = set_object_generic("backmatter", "blurb", "para", "blurb", links_and_images(line.to!string.strip).replaceFirst(rgx.para_attribs, ""), 0);
+      comp_obj_.metainfo.identifier           = "";
+      comp_obj_.metainfo.object_number_off    = true;
+      comp_obj_.metainfo.object_number_type   = 0;
+      comp_obj_.attrib.indent_hang            = indent["hang_position"];
+      comp_obj_.attrib.indent_base            = indent["base_position"];
+      comp_obj_.has.inline_links              = true;
+      comp_obj_.attrib.bullet                 = bullet;
+      add_to_current_document_section         ~= comp_obj_;
+    }
+    pith["ocn"] = eN.ocn.on;
+    {
+      ret.comp_section_obj = add_to_current_document_section;
+      ret.pith             = pith;
+      ret.tag_assoc        = tag_assoc; // NO CHANGE here, only for headings: html & epub
+    }
+    return ret;
+  }
+  // ↑ - section blurb
+  // ↓ - images
+  @safe string[] extract_images()(string content_block) {
+    static auto rgx = RgxI();
+    string[] images_;
+    if (auto m = content_block.matchAll(rgx.image)) {
+      images_ ~= m.captures[1];
+    }
+    return images_;
+  }
+  @system auto _image_dimensions(O,M)(O obj, M manifested) {
+    static auto rgx = RgxI();
+    if (obj.has.image_without_dimensions) {
+      import std.math;
+      import imageformats;
+      int w, h, chans;
+      real _w, _h;
+      int max_width = 640;
+      foreach (img; obj.text.matchAll(rgx.inline_image_without_dimensions)) {
+        try {
+          read_image_info(manifested.src.image_dir_path ~ "/" ~ img["img"], w, h, chans);
+        } catch (Exception ex) {
+          writeln("WARNING, image not found: ", img["img"], "\n  ", manifested.src.image_dir_path ~ "/" ~ img["img"]);
+        }
+        // calculate, decide max width and proportionally reduce to keep w & h within it
+        debug(images) { writeln("width: ", w, ", height: ", h); }
+        if (w > max_width) {
+          _w = max_width;
+          _h = round((max_width / w.to!real) * h.to!real);
+        } else {
+          _w = w;
+          _h = h;
+        }
+        obj.text = obj.text.replaceFirst(
+          rgx.inline_image_without_dimensions,
+          format(q"┃%s☼%s,w%sh%s %s┃",
+            "$1",
+            "$3",
+            _w.to!string,
+            _h.to!string,
+            "$6",
+          )
+        );
+      }
+      debug(images) { writeln("image without dimensions: ", obj.text); }
+    }
+    return obj;
+  }
+  // ↑ - images
+  // ↓ - links
+  @safe auto _links(O)(O obj) {
+    static auto rgx = RgxI();
+    if (auto m = obj.text.match(rgx.inline_link_stow_uri)) {
+      debug(links) {
+        writeln("number of link matches to stow: ", (obj.text.match(rgx.inline_link_stow_uri)).count);
+        writeln("links to stow: ", (obj.text.match(rgx.inline_link_stow_uri)));
+      }
+      int _n_matches = (obj.text.match(rgx.inline_link_stow_uri)).count.to!int;
+      for(int i = 0; i < _n_matches; ++i) {
+        if (obj.text.match(rgx.inline_link_stow_uri)) {
+          obj.stow.link ~= obj.text.matchFirst(rgx.inline_link_stow_uri)[2];
+          obj.text = obj.text.replaceFirst(
+            rgx.inline_link_stow_uri,
+            format(q"┃┥%s┝┤%s├┃", "$1", i)
+          );
+        }
+      }
+    }
+    return obj;
+  }
+  // ↑ - links
+  // ↓ - segnames
+  @system ST_segnames after_doc_determine_segnames(
+    ObjGenericComposite[] the_document_body_section,
+    ObjGenericComposite[] the_document_endnotes_section,
+    ObjGenericComposite[] the_document_glossary_section,
+    ObjGenericComposite[] the_document_bibliography_section,
+    ObjGenericComposite[] the_document_bookindex_section,
+    ObjGenericComposite[] the_document_blurb_section,
+    string[][string]      segnames,
+    int                   html_segnames_ptr_cntr,
+    int                   html_segnames_ptr,
+  ) {
+    if (the_document_endnotes_section.length > 1) {
+      segnames["html"] ~= "endnotes";
+      segnames["epub"] ~= "endnotes";
+      html_segnames_ptr = html_segnames_ptr_cntr;
+      foreach (ref obj; the_document_endnotes_section) {
+        if (obj.metainfo.is_a == "heading") {
+          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
+        }
+        if (obj.metainfo.heading_lev_markup == 4) {
+          obj.ptr.html_segnames = html_segnames_ptr;
+          break;
+        }
+      }
+      html_segnames_ptr_cntr++;
+    }
+    if (the_document_glossary_section.length > 1) {
+      segnames["html"] ~= "glossary";
+      segnames["epub"] ~= "glossary";
+      html_segnames_ptr = html_segnames_ptr_cntr;
+      foreach (ref obj; the_document_glossary_section) {
+        if (obj.metainfo.is_a == "heading") {
+          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
+        }
+        if (obj.metainfo.heading_lev_markup == 4) {
+          obj.ptr.html_segnames = html_segnames_ptr;
+          break;
+        }
+      }
+      html_segnames_ptr_cntr++;
+    }
+    if (the_document_bibliography_section.length > 1) {
+      segnames["html"] ~= "bibliography";
+      segnames["epub"] ~= "bibliography";
+      html_segnames_ptr = html_segnames_ptr_cntr;
+      foreach (ref obj; the_document_bibliography_section) {
+        if (obj.metainfo.is_a == "heading") {
+          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
+        }
+        if (obj.metainfo.heading_lev_markup == 4) {
+          obj.ptr.html_segnames = html_segnames_ptr;
+          break;
+        }
+      }
+      html_segnames_ptr_cntr++;
+    }
+    if (the_document_bookindex_section.length > 1) {
+      segnames["html"] ~= "bookindex";
+      segnames["epub"] ~= "bookindex";
+      html_segnames_ptr = html_segnames_ptr_cntr;
+      foreach (ref obj; the_document_bookindex_section) {
+        if (obj.metainfo.is_a == "heading") {
+          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
+        }
+        if (obj.metainfo.heading_lev_markup == 4) {
+          obj.ptr.html_segnames = html_segnames_ptr;
+          break;
+        }
+      }
+      html_segnames_ptr_cntr++;
+    }
+    if (the_document_blurb_section.length > 1) {
+      segnames["html"] ~= "blurb";
+      segnames["epub"] ~= "blurb";
+      html_segnames_ptr = html_segnames_ptr_cntr;
+      foreach (ref obj; the_document_blurb_section) {
+        if (obj.metainfo.is_a == "heading") {
+          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
+        }
+        if (obj.metainfo.heading_lev_markup == 4) {
+          obj.ptr.html_segnames = html_segnames_ptr;
+          break;
+        }
+      }
+      html_segnames_ptr_cntr++;
+    }
+    ST_segnames ret;
+    ret.segnames                          = segnames;
+    ret.html_segnames_ptr_cntr            = html_segnames_ptr_cntr;
+    ret.html_segnames_ptr                 = html_segnames_ptr;
+    return ret;
+  }
+  // ↑ - segnames
+  // ↓ - ancestors descendants
+  struct NodeStructureMetadata {
+    int lv, lv0, lv1, lv2, lv3, lv4, lv5, lv6, lv7;
+    int obj_cite_digit;
+    int[string] p_; // p_ parent_
+    static auto rgx = RgxI();
+    @safe ObjGenericComposite node_location_emitter(La,Ta)(
+      string         lev_markup_number,
+      string[string] tag_in_seg,
+      La             lev_anchor_tag,
+      Ta             tag_assoc,
+      OCNset         obj_cite_digits,
+      int            cntr_,
+      int            ptr_,
+      string         is_
+    ) {
+      debug(asserts) { static assert(is(typeof(obj_cite_digits.object_number) == int)); }
+      assert(is_ != "heading");
+      assert(obj_cite_digits.object_number.to!int >= 0);
+      assert(is_ != "heading");                          // should not be necessary
+      assert(obj_cite_digits.object_number.to!int >= 0); // should not be necessary
+      if (lv7 > eN.bi.off) {
+        p_["lev_markup_number"]                       = DocStructMarkupHeading.h_text_4;
+        p_["object_number"]                           = lv7;
+      } else if (lv6 > eN.bi.off) {
+        p_["lev_markup_number"]                       = DocStructMarkupHeading.h_text_3;
+        p_["object_number"]                           = lv6;
+      } else if (lv5 > eN.bi.off) {
+        p_["lev_markup_number"]                       = DocStructMarkupHeading.h_text_2;
+        p_["object_number"]                           = lv5;
+      } else {
+        p_["lev_markup_number"]                       = DocStructMarkupHeading.h_text_1;
+        p_["object_number"]                           = lv4;
+      }
+      ObjGenericComposite comp_obj_location;
+      comp_obj_location                               = comp_obj_location.init;
+      comp_obj_location.metainfo.is_a                 = is_;
+      comp_obj_location.metainfo.ocn                  = obj_cite_digits.object_number;
+      comp_obj_location.metainfo.identifier           = obj_cite_digits.identifier;
+      comp_obj_location.tags.anchor_tag_html          = tag_in_seg["seg_lv4"];
+      comp_obj_location.tags.segment_anchor_tag_epub  = tag_in_seg["seg_lv1to4"];
+      comp_obj_location.tags.heading_lev_anchor_tag   = lev_anchor_tag;
+      comp_obj_location.metainfo.parent_ocn           = p_["object_number"];
+      comp_obj_location.metainfo.parent_lev_markup    = p_["lev_markup_number"];
+      debug(_node) {
+        if (lev_markup_number.match(rgx.levels_numbered_headings)) { writeln("x ", _node.to!string);
+        } else { writeln("- ", _node.to!string); }
+      }
+      assert(comp_obj_location.metainfo.parent_lev_markup >= 4);
+      assert(comp_obj_location.metainfo.parent_lev_markup <= 7);
+      assert(comp_obj_location.metainfo.parent_ocn >= 0);
+      return comp_obj_location;
+    }
+    invariant() {
+    }
+    @safe ObjGenericComposite node_emitter_heading(O,TaL,TA,SOAT)(
+      O              an_object,
+      string[string] tag_in_seg,
+      TaL            lev_anchor_tag,
+      TA             tag_assoc,
+      OCNset         obj_cite_digits,
+      int            cntr_,
+      int            ptr_,
+      string[]       lv_ancestors_txt,
+      int            html_segnames_ptr,
+      SOAT           substantive_object_and_anchor_tags_struct,
+    ) {
+      string _text                = an_object["substantive"];
+      string lev_markup_number    = an_object["lev_markup_number"];
+      string lev_collapsed_number = an_object["lev_collapsed_number"];
+      string dummy_heading_status = an_object["dummy_heading_status"];
+      string is_                  = an_object["is"];
+      debug(asserts) {
+        static assert(is(typeof(lev)                                       == string));
+        static assert(is(typeof(obj_cite_digits.object_number)             == int));
+      }
+      assert(is_ == "heading");
+      assert((obj_cite_digits.object_number).to!int >= 0);
+      assert(
+        lev_markup_number.match(rgx.levels_numbered),
+        ("not a valid heading level: " ~ lev_markup_number ~ " at " ~ obj_cite_digits.object_number.to!string)
+      );
+      if (lev_markup_number.match(rgx.levels_numbered)) {
+        if (lev_markup_number.to!int == 0) {
+          // TODO first hit (of two) with this assertion failure, check, fix & reinstate
+          // assert(obj_cite_digits.object_number.to!int == 1,
+          //   "ERROR header lev markup number is: " ~
+          //   lev_markup_number.to!string ~
+          //   " obj_cite_digits.object_number.to!int should == 1 but is: " ~
+          //    obj_cite_digits.object_number.to!string ~
+          //   "\n" ~ _text);
+        }
+      }
+      switch (lev_markup_number.to!int) {
+      case 0:
+        lv = DocStructMarkupHeading.h_sect_A;
+        lv0 = obj_cite_digit;
+        lv1 = 0; lv2 = 0; lv3 = 0; lv4 = 0; lv5 = 0; lv6 = 0; lv7 = 0;
+        p_["lev_markup_number"] = 0;
+        p_["object_number"] = 0;
+        break;
+      case 1:
+        lv = DocStructMarkupHeading.h_sect_B;
+        lv1 = obj_cite_digit;
+        lv2 = 0; lv3 = 0; lv4 = 0; lv5 = 0; lv6 = 0; lv7 = 0;
+        p_["lev_markup_number"]
+          = DocStructMarkupHeading.h_sect_A;
+        p_["object_number"] = lv0;
+        break;
+      case 2:
+        lv = DocStructMarkupHeading.h_sect_C;
+        lv2 = obj_cite_digit;
+        lv3 = 0; lv4 = 0; lv5 = 0; lv6 = 0; lv7 = 0;
+        p_["lev_markup_number"]
+          = DocStructMarkupHeading.h_sect_B;
+        p_["object_number"] = lv1;
+        break;
+      case 3:
+        lv = DocStructMarkupHeading.h_sect_D;
+        lv3 = obj_cite_digit;
+        lv4 = 0; lv5 = 0; lv6 = 0; lv7 = 0;
+        p_["lev_markup_number"]
+          = DocStructMarkupHeading.h_sect_C;
+        p_["object_number"] = lv2;
+        break;
+      case 4:
+        lv = DocStructMarkupHeading.h_text_1;
+        lv4 = obj_cite_digit;
+        lv5 = 0; lv6 = 0; lv7 = 0;
+        if (lv3 > eN.bi.off) {
+          p_["lev_markup_number"]
+            = DocStructMarkupHeading.h_sect_D;
+          p_["object_number"] = lv3;
+        } else if (lv2 > eN.bi.off) {
+          p_["lev_markup_number"]
+            = DocStructMarkupHeading.h_sect_C;
+          p_["object_number"] = lv2;
+        } else if (lv1 > eN.bi.off) {
+          p_["lev_markup_number"]
+            = DocStructMarkupHeading.h_sect_B;
+          p_["object_number"] = lv1;
+        } else {
+          p_["lev_markup_number"]
+            = DocStructMarkupHeading.h_sect_A;
+          p_["object_number"] = lv0;
+        }
+        break;
+      case 5:
+        lv = DocStructMarkupHeading.h_text_2;
+        lv5 = obj_cite_digit;
+        lv6 = 0; lv7 = 0;
+        p_["lev_markup_number"]
+          = DocStructMarkupHeading.h_text_1;
+        p_["object_number"] = lv4;
+        break;
+      case 6:
+        lv = DocStructMarkupHeading.h_text_3;
+        lv6 = obj_cite_digit;
+        lv7 = 0;
+        p_["lev_markup_number"]
+          = DocStructMarkupHeading.h_text_2;
+        p_["object_number"] = lv5;
+        break;
+      case 7:
+        lv = DocStructMarkupHeading.h_text_4;
+        lv7 = obj_cite_digit;
+        p_["lev_markup_number"]
+          = DocStructMarkupHeading.h_text_3;
+        p_["object_number"] = lv6;
+        break;
+      default:
+        break;
+      }
+      ObjGenericComposite comp_obj_;
+      comp_obj_                                        = comp_obj_.init;
+      comp_obj_.metainfo.is_of_part                    = "body";
+      comp_obj_.metainfo.is_of_section                 = "body";
+      comp_obj_.metainfo.is_of_type                    = "para";
+      comp_obj_.metainfo.is_a                          = "heading";
+      comp_obj_.text                                   = _text.to!string.strip;
+      comp_obj_.metainfo.ocn                           = obj_cite_digits.object_number;
+      comp_obj_.metainfo.identifier                    = obj_cite_digits.identifier;
+      comp_obj_.metainfo.dummy_heading                 = (dummy_heading_status == "t") ? true: false;
+      comp_obj_.metainfo.object_number_off             = obj_cite_digits.off;
+      // comp_obj_.metainfo.o_n_book_index             = obj_cite_digits.bkidx;
+      comp_obj_.metainfo.object_number_type            = obj_cite_digits.type;
+      comp_obj_.tags.segment_anchor_tag_epub           = tag_in_seg["seg_lv1to4"];
+      comp_obj_.tags.anchor_tag_html                   = tag_in_seg["seg_lv4"];
+      comp_obj_.tags.in_segment_html                   = comp_obj_.tags.anchor_tag_html;
+      comp_obj_.tags.heading_lev_anchor_tag            = lev_anchor_tag;
+      comp_obj_.tags.html_segment_anchor_tag_is        = tag_in_seg["seg_lv4"];
+      comp_obj_.tags.epub_segment_anchor_tag_is        = tag_in_seg["seg_lv1to4"];
+      comp_obj_.metainfo.heading_lev_markup            = (!(lev_markup_number.empty) ? lev_markup_number.to!int : 0);
+      comp_obj_.metainfo.heading_lev_collapsed         = (!(lev_collapsed_number.empty) ? lev_collapsed_number.to!int : 0);
+      comp_obj_.metainfo.parent_ocn                    = p_["object_number"];
+      comp_obj_.metainfo.parent_lev_markup             = p_["lev_markup_number"];
+      comp_obj_.tags.heading_ancestors_text            = lv_ancestors_txt;
+      comp_obj_.ptr.doc_object                         = cntr_;
+      comp_obj_.ptr.html_segnames                      = ((lev_markup_number == "4") ? html_segnames_ptr : 0);
+      comp_obj_.ptr.heading                            = ptr_;
+      comp_obj_.has.inline_notes_reg                   = substantive_object_and_anchor_tags_struct.has_notes_reg;
+      comp_obj_.has.inline_notes_star                  = substantive_object_and_anchor_tags_struct.has_notes_star;
+      comp_obj_.has.inline_links                       = substantive_object_and_anchor_tags_struct.has_links;
+      tag_assoc[comp_obj_.tags.anchor_tag_html]["seg_lv4"]            = comp_obj_.tags.in_segment_html;
+      tag_assoc[comp_obj_.tags.segment_anchor_tag_epub]["seg_lv1to4"] = comp_obj_.tags.segment_anchor_tag_epub;
+      debug(_node) {
+        if (lev_markup_number.match(rgx.levels_numbered_headings)) { writeln("* ", _node.to!string); }
+      }
+      debug(nodeheading) {
+        if (lev_markup_number.match(rgx.levels_numbered_headings)) { writeln("* ", _node.to!string); }
+      }
+      assert(comp_obj_.metainfo.parent_lev_markup <= 7);
+      assert(comp_obj_.metainfo.parent_ocn >= 0);
+      if (lev_markup_number.match(rgx.levels_numbered_headings)) {
+        assert(comp_obj_.metainfo.heading_lev_markup <= 7);
+        assert(comp_obj_.metainfo.ocn >= 0);
+        if (comp_obj_.metainfo.parent_lev_markup > 0) {
+          assert(comp_obj_.metainfo.parent_lev_markup < comp_obj_.metainfo.heading_lev_markup);
+          if (comp_obj_.metainfo.ocn != 0) {
+            assert(comp_obj_.metainfo.parent_ocn < comp_obj_.metainfo.ocn);
+          }
+        }
+        if (comp_obj_.metainfo.heading_lev_markup == 0) {
+          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_sect_A);
+        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_sect_B) {
+          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_sect_A);
+        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_sect_C) {
+          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_sect_B);
+        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_sect_D) {
+          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_sect_C);
+        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_text_1) {
+          assert(comp_obj_.metainfo.parent_lev_markup <= DocStructMarkupHeading.h_sect_D);
+        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_text_2) {
+          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_text_1);
+        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_text_3) {
+          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_text_2);
+        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_text_4) {
+          assert(comp_obj_.metainfo.parent_lev_markup == DocStructMarkupHeading.h_text_3);
+        } else if  (comp_obj_.metainfo.heading_lev_markup == DocStructMarkupHeading.h_text_5) {
+        }
+      }
+      return comp_obj_;
+    }
+    invariant() {
+    }
+  }
+  @system ST_ancestors after_doc_determine_ancestors(
+    ObjGenericComposite[] the_document_body_section,
+    ObjGenericComposite[] the_document_endnotes_section,
+    ObjGenericComposite[] the_document_glossary_section,
+    ObjGenericComposite[] the_document_bibliography_section,
+    ObjGenericComposite[] the_document_bookindex_section,
+    ObjGenericComposite[] the_document_blurb_section,
+  ) {
+    @safe int[] _get_ancestors_markup(ObjGenericComposite obj, int[] _ancestors_markup) {
+      if (obj.metainfo.is_a == "heading") {
+        debug(dom) { writeln(obj.text); }
+        if (obj.metainfo.heading_lev_markup == 1) {
+          _ancestors_markup = [
+            _ancestors_markup[0],
+            0,0,0,0,0,0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_markup == 2) {
+          _ancestors_markup = [
+            _ancestors_markup[0],
+            _ancestors_markup[1],
+            0,0,0,0,0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_markup == 3) {
+          _ancestors_markup = [
+            _ancestors_markup[0],
+            _ancestors_markup[1],
+            _ancestors_markup[2],
+            0,0,0,0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_markup == 4) {
+          _ancestors_markup = [
+            _ancestors_markup[0],
+            _ancestors_markup[1],
+            _ancestors_markup[2],
+            _ancestors_markup[3],
+            0,0,0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_markup == 5) {
+          _ancestors_markup = [
+            _ancestors_markup[0],
+            _ancestors_markup[1],
+            _ancestors_markup[2],
+            _ancestors_markup[3],
+            _ancestors_markup[4],
+            0,0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_markup == 6) {
+          _ancestors_markup = [
+            _ancestors_markup[0],
+            _ancestors_markup[1],
+            _ancestors_markup[2],
+            _ancestors_markup[3],
+            _ancestors_markup[4],
+            _ancestors_markup[5],
+            0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_markup == 7) {
+          _ancestors_markup = [
+            _ancestors_markup[0],
+            _ancestors_markup[1],
+            _ancestors_markup[2],
+            _ancestors_markup[3],
+            _ancestors_markup[4],
+            _ancestors_markup[5],
+            _ancestors_markup[6],
+            0
+          ];
+        }
+        if (obj.metainfo.heading_lev_markup == 8) {
+          _ancestors_markup = [
+            _ancestors_markup[0],
+            _ancestors_markup[1],
+            _ancestors_markup[2],
+            _ancestors_markup[3],
+            _ancestors_markup[4],
+            _ancestors_markup[5],
+            _ancestors_markup[6],
+            _ancestors_markup[7]
+          ];
+        }
+        _ancestors_markup[obj.metainfo.heading_lev_markup] = obj.metainfo.ocn;
+      }
+      debug(ancestor_markup) { writeln("marked up: ", _ancestors_markup); }
+      return _ancestors_markup;
+    }
+    @safe int[] _get_ancestors_collapsed(ObjGenericComposite obj, int[] _ancestors_collapsed) {
+      if (obj.metainfo.is_a == "heading") {
+        if (obj.metainfo.heading_lev_collapsed == 1) {
+          _ancestors_collapsed = [
+            _ancestors_collapsed[0],
+            0,0,0,0,0,0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_collapsed == 2) {
+          _ancestors_collapsed = [
+            _ancestors_collapsed[0],
+            _ancestors_collapsed[1],
+            0,0,0,0,0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_collapsed == 3) {
+          _ancestors_collapsed = [
+            _ancestors_collapsed[0],
+            _ancestors_collapsed[1],
+            _ancestors_collapsed[2],
+            0,0,0,0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_collapsed == 4) {
+          _ancestors_collapsed = [
+            _ancestors_collapsed[0],
+            _ancestors_collapsed[1],
+            _ancestors_collapsed[2],
+            _ancestors_collapsed[3],
+            0,0,0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_collapsed == 5) {
+          _ancestors_collapsed = [
+            _ancestors_collapsed[0],
+            _ancestors_collapsed[1],
+            _ancestors_collapsed[2],
+            _ancestors_collapsed[3],
+            _ancestors_collapsed[4],
+            0,0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_collapsed == 6) {
+          _ancestors_collapsed = [
+            _ancestors_collapsed[0],
+            _ancestors_collapsed[1],
+            _ancestors_collapsed[2],
+            _ancestors_collapsed[3],
+            _ancestors_collapsed[4],
+            _ancestors_collapsed[5],
+            0,0
+          ];
+        }
+        if (obj.metainfo.heading_lev_collapsed == 7) {
+          _ancestors_collapsed = [
+            _ancestors_collapsed[0],
+            _ancestors_collapsed[1],
+            _ancestors_collapsed[2],
+            _ancestors_collapsed[3],
+            _ancestors_collapsed[4],
+            _ancestors_collapsed[5],
+            _ancestors_collapsed[6],
+            0
+          ];
+        }
+        if (obj.metainfo.heading_lev_collapsed == 8) {
+          _ancestors_collapsed = [
+            _ancestors_collapsed[0],
+            _ancestors_collapsed[1],
+            _ancestors_collapsed[2],
+            _ancestors_collapsed[3],
+            _ancestors_collapsed[4],
+            _ancestors_collapsed[5],
+            _ancestors_collapsed[6],
+            _ancestors_collapsed[7]
+          ];
+        }
+        _ancestors_collapsed[obj.metainfo.heading_lev_collapsed] = obj.metainfo.ocn;
+      }
+      debug(ancestor_collapsed) { writeln("collapsed: ", _ancestors_collapsed); }
+      return _ancestors_collapsed;
+    }
+    // multiple 1~ levels, loop through document body
+    if (the_document_body_section.length > 1) {
+      int[] _ancestors_markup = [0,0,0,0,0,0,0,0];
+      int[][] _ancestors_markup_;
+      _ancestors_markup = [1,0,0,0,0,0,0,0];
+      _ancestors_markup_ ~= _ancestors_markup;
+      int[] _ancestors_collapsed = [0,0,0,0,0,0,0,0];
+      int[][] _ancestors_collapsed_;
+      _ancestors_collapsed = [1,0,0,0,0,0,0,0];
+      _ancestors_collapsed_ ~= _ancestors_collapsed;
+      foreach (ref obj; the_document_body_section) {
+        if (obj.metainfo.is_a == "heading") {
+          obj.metainfo.markedup_ancestors = _get_ancestors_markup(obj, _ancestors_markup);
+          obj.metainfo.collapsed_ancestors = _get_ancestors_collapsed(obj, _ancestors_collapsed);
+          obj.metainfo.parent_ocn = obj.metainfo.markedup_ancestors[obj.metainfo.parent_lev_markup];
+        }
+      }
+      debug(ancestors) {
+        writeln("ancestors markup o_n:    ", obj.metainfo.markedup_ancestors);
+        writeln("ancestors collapsed o_n: ", obj.metainfo.markedup_ancestors);
+      }
+    }
+    ST_ancestors ret;
+    ret.the_document_body_section         = the_document_body_section;
+    ret.the_document_endnotes_section     = the_document_endnotes_section;
+    ret.the_document_glossary_section     = the_document_glossary_section;
+    ret.the_document_bibliography_section = the_document_bibliography_section;
+    ret.the_document_bookindex_section    = the_document_bookindex_section;
+    ret.the_document_blurb_section        = the_document_blurb_section;
+    return ret;
+  }
+  // ↑ - ancestors
+  // ↓ - descendants
+  // descendants
+  @safe auto after_doc_get_descendants()(ObjGenericComposite[] document_sections) {
+    int[string] _heading_ocn_descendants;
+    string[] _ocn_open_key = ["","","","","","","",""];
+    auto _doc_sect_length = document_sections.length - 1;
+    int _last_ocn;
+    foreach (_lg, ref obj; document_sections) {
+      if (obj.metainfo.is_a == "heading") {
+        foreach (_dts_lv, dom_tag_status; obj.metainfo.dom_structure_markedup_tags_status) {
+          switch (dom_tag_status) with (DomTags) {
+          case none: break;
+          case open:
+              _ocn_open_key[_dts_lv] = (obj.metainfo.ocn).to!string;
+              _heading_ocn_descendants[_ocn_open_key[_dts_lv]] = obj.metainfo.ocn;
+            break;
+          case close:
+            if (_ocn_open_key[_dts_lv].empty) {
+              _ocn_open_key[_dts_lv] = "0";
+            }
+            _heading_ocn_descendants[_ocn_open_key[_dts_lv]] = obj.metainfo.ocn - 1;
+            _ocn_open_key[_dts_lv] = (0).to!string;
+            break;
+          case close_and_open:
+            if (_ocn_open_key[_dts_lv].empty) {
+              _ocn_open_key[_dts_lv] = "0";
+            }
+            _heading_ocn_descendants[_ocn_open_key[_dts_lv]] = obj.metainfo.ocn - 1;
+            _ocn_open_key[_dts_lv] = (obj.metainfo.ocn).to!string;
+            _heading_ocn_descendants[_ocn_open_key[_dts_lv]] = obj.metainfo.ocn;
+            break;
+          case open_still: break;
+          default: break;
+          }
+        }
+      }
+      if (obj.metainfo.ocn > 0) {
+        _last_ocn = obj.metainfo.ocn;
+      }
+      if (_lg == _doc_sect_length) {
+        _heading_ocn_descendants["1"] = _last_ocn; // close existing o_n key
+      }
+    }
+    Tuple!(int, int)[] pairs;
+    foreach (pair; _heading_ocn_descendants.byPair) {
+      pairs ~= tuple(pair[0].to!int, pair[1]);
+    }
+    return pairs.sort;
+  }
+  // ↑ - descendants
+  // ↓ - assertions
+  @safe pure void assertions_doc_structure()(
+    string[string]  an_object,
+    string          an_object_key,
+    int[string]     lv
+  ) {
+    string msg_error_doc_struct = "\nERROR in document structure, check markup (heading level relationships):\n";
+    if (lv["h3"] > eN.bi.off) {
+      assert(lv["h0"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h1"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h2"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    } else if (lv["h2"] > eN.bi.off) {
+      assert(lv["h0"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h1"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h3"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    } else if (lv["h1"] > eN.bi.off) {
+      assert(lv["h0"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h2"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h3"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    } else if (lv["h0"] > eN.bi.off) {
+      assert(lv["h1"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h2"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h3"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    } else {
+      assert(lv["h0"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h1"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h2"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h3"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    }
+    if (lv["h7"] > eN.bi.off) {
+      assert(lv["h4"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ "missing segment level 1~\n"
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h5"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h6"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    } else if (lv["h6"] > eN.bi.off) {
+      assert(lv["h4"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ "missing segment level 1~\n"
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h5"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h7"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    } else if (lv["h5"] > eN.bi.off) {
+      assert(lv["h4"] > eN.bi.off,
+        msg_error_doc_struct
+        ~ "missing segment level 1~\n"
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h6"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h7"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    } else if (lv["h4"] > eN.bi.off) {
+      assert(lv["h5"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h6"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h7"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    } else {
+      assert(lv["h4"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ "missing segment level 1~\n"
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h5"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h6"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h7"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    }
+    if (lv["h0"] == eN.bi.off) {
+      assert(lv["h1"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h2"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h3"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h4"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ "missing segment level 1~\n"
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h5"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h6"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h7"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    }
+    if (lv["h1"] == eN.bi.off) {
+      assert(lv["h2"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h3"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    }
+    if (lv["h2"] == eN.bi.off) {
+      assert(lv["h3"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    }
+    if (lv["h3"] == eN.bi.off) {
+    }
+    if (lv["h4"] == eN.bi.off) {
+      assert(lv["h5"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h6"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h7"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    }
+    if (lv["h5"] == eN.bi.off) {
+      assert(lv["h6"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+      assert(lv["h7"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    }
+    if (lv["h6"] == eN.bi.off) {
+      assert(lv["h7"] == eN.bi.off,
+        msg_error_doc_struct
+        ~ an_object[an_object_key]
+      );
+    }
+    if (lv["h7"] == eN.bi.off) {
+    }
+    switch ((an_object["lev"]).to!string) {
+    case "A":
+      if (lv["h0"] == eN.bi.off) {
+        assert(lv["h1"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level A~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h2"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level A~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h3"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level A~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h4"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 1~\n"
+          ~ "at level A~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h5"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level A~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h6"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level A~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h7"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level A~\n"
+          ~ an_object[an_object_key]
+        );
+      } else {                       // (lv["h0"] > eN.bi.off)
+        assert(lv["h0"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "should not enter level A a second time\n"
+          ~ "at level A~\n"
+          ~ an_object[an_object_key]
+        );
+      }
+      break;
+    case "B":
+      if (lv["h1"] == eN.bi.off) {
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level B~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h2"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level B~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h3"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level B~\n"
+          ~ an_object[an_object_key]
+        );
+      } else {                       // (lv["h1"] > eN.bi.off)
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level B~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h1"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level B~\n"
+          ~ an_object[an_object_key]
+        );
+      }
+      break;
+    case "C":
+      if (lv["h2"] == eN.bi.off) {
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level C~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h1"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "level C should not follow level A\n"
+          ~ "at level C~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h3"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level C~\n"
+          ~ an_object[an_object_key]
+        );
+      } else {                       // (lv["h2"] > eN.bi.off)
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level C~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h1"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level C~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h2"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level C~\n"
+          ~ an_object[an_object_key]
+        );
+      }
+      break;
+    case "D":
+      if (lv["h3"] == eN.bi.off) {
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level D~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h1"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "level D should not follow level A\n"
+          ~ "at level D~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h2"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level D~\n"
+          ~ an_object[an_object_key]
+        );
+      } else {                      // (lv["h3"] > eN.bi.off)
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level D~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h1"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level D~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h2"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level D~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h3"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level D~\n"
+          ~ an_object[an_object_key]
+        );
+      }
+      break;
+    case "1":
+      if (lv["h4"] == eN.bi.off) {
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 1~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h5"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 1~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h6"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 1~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h7"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 1~\n"
+          ~ an_object[an_object_key]
+        );
+      } else {                      // (lv["h4"] > eN.bi.off)
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 1~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h4"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 1~ ?\n"
+          ~ "at level 1~\n"
+          ~ an_object[an_object_key]
+        );
+      }
+      break;
+    case "2":
+      if (lv["h5"] == eN.bi.off) {
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 2~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h4"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 1~ ?\n"
+          ~ "at level 2~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h6"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 2~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h7"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 2~\n"
+          ~ an_object[an_object_key]
+        );
+      } else {                      // (lv["h5"] > eN.bi.off)
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 2~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h4"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 1~ ?\n"
+          ~ "at level 2~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h5"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 2~\n"
+          ~ an_object[an_object_key]
+        );
+      }
+      break;
+    case "3":
+      if (lv["h6"] == eN.bi.off) {
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 3~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h4"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 1~ ?\n"
+          ~ "at level 3~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h5"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 2~ ?\n"
+          ~ "at level 3~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h7"] == eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 3~\n"
+          ~ an_object[an_object_key]
+        );
+      } else {                      // (lv["h6"] > eN.bi.off)
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 3~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h4"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 1~ ?\n"
+          ~ "at level 3~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h5"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 3~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h6"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 3~\n"
+          ~ an_object[an_object_key]
+        );
+      }
+      break;
+    case "4":
+      if (lv["h7"] == eN.bi.off) {
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 4~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h4"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 1~ ?\n"
+          ~ "at level 4~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h5"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 2~ ?\n"
+          ~ "at level 4~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h6"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 3~ ?\n"
+          ~ "at level 4~\n"
+          ~ an_object[an_object_key]
+        );
+      } else {                      // (lv["h7"] > eN.bi.off)
+        assert(lv["h0"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 4~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h4"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "missing segment level 1~ ?\n"
+          ~ "at level 4~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h5"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 4~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h6"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 4~\n"
+          ~ an_object[an_object_key]
+        );
+        assert(lv["h7"] > eN.bi.off,
+          msg_error_doc_struct
+          ~ "at level 4~\n"
+          ~ an_object[an_object_key]
+        );
+      }
+      break;
+    default:
+      break;
+    }
+  }
+  // ↑ - assertions
+}
+template docSectKeysSeq() {
+  @safe auto docSectKeysSeq(string[][string] document_section_keys_sequenced) {
+    struct doc_sect_keys_seq {
+      string[] scroll() {
+        return document_section_keys_sequenced["scroll"];
+      }
+      string[] seg() {
+        return document_section_keys_sequenced["seg"];
+      }
+      string[] sql() {
+        return document_section_keys_sequenced["sql"];
+      }
+      string[] latex() {
+        return document_section_keys_sequenced["latex"];
+      }
+    }
+    return doc_sect_keys_seq();
+  }
+}
diff --git a/src/doc_reform/meta/metadoc_object_setter.d b/src/doc_reform/meta/metadoc_object_setter.d
index 9c4b46b..29d527b 100644
--- a/src/doc_reform/meta/metadoc_object_setter.d
+++ b/src/doc_reform/meta/metadoc_object_setter.d
@@ -55,6 +55,51 @@
 module doc_reform.meta.metadoc_object_setter;
 template ObjectSetter() {
   /+ structs +/
+  struct DocObj_TxtAttrib_ {
+    int                    indent_base                         = 0;
+    int                    indent_hang                         = 0;
+    bool                   bullet                              = false;
+    string                 language                            = "";
+  }
+  struct DocObj_Has_ {
+    bool                   inline_links                        = false;
+    bool                   inline_notes_reg                    = false;
+    bool                   inline_notes_star                   = false;
+    bool                   images                              = false;
+    bool                   image_without_dimensions            = false;
+  }
+  struct DocObj_Table_ {
+    int                    number_of_columns                   = 0;
+    double[]               column_widths                       = [];
+    string[]               column_aligns                       = [];
+    bool                   heading                             = false;
+    bool                   walls                               = false;
+  }
+  struct DocObj_CodeBlock_ {
+    string                 syntax                              = "";
+    bool                   linenumbers                         = false;
+  }
+  struct DocObj_Stow_ {
+    string[]               link                               = [];
+  }
+  struct DocObj_Pointer_ {
+    int                    doc_object                          = 0;
+    int                    html_segnames                       = 0;
+    int                    heading                             = 0;
+  }
+  struct DocObj_Tags_ {
+    string[]               heading_ancestors_text              = [ "", "", "", "", "", "", "", "", ];
+    string                 anchor_tag_html                     = "";
+    string                 in_segment_html                     = "";
+    string                 segment_anchor_tag_epub             = "";
+    string                 html_segment_anchor_tag_is          = "";
+    string                 epub_segment_anchor_tag_is          = "";
+    string                 heading_lev_anchor_tag              = "";
+    string                 segname_prev                        = "";
+    string                 segname_next                        = "";
+    string[]               lev4_subtoc                         = [];
+    string[]               anchor_tags                         = [];
+  }
   struct DocObj_MetaInfo_ {
     string                 is_of_part                           = ""; // frontmatter, body, backmatter
     string                 is_of_section                        = ""; // toc, body, glossary, biography, book index, blurb
@@ -91,19 +136,6 @@ template ObjectSetter() {
     @safe string object_number_blurb() const @property {
       return (o_n_blurb == 0) ? "" : o_n_blurb.to!string;
     }
-    bool                   object_number_off                    = false;
-    bool                   visible_object_number                = false;
-    int                    object_number_type                   = 0; // { ocn, non, bkidx }
-    /+ node +/
-    string[string][string] node;
-    int                    ocn                                  = 0;
-    string                 identifier                           = "";
-    @safe string object_number() const @property {
-      return (ocn == 0) ? "" : ocn.to!string;
-    }
-    int                    o_n_type                             = 0;
-    int                    heading_lev_markup                   = 9;
-    int                    heading_lev_collapsed                = 9;
     @safe string marked_up_level() const @property {
       string _out;
       switch (heading_lev_markup) {
@@ -119,6 +151,19 @@ template ObjectSetter() {
       }
       return _out;
     }
+    @safe string object_number() const @property {
+      return (ocn == 0) ? "" : ocn.to!string;
+    }
+    bool                   object_number_off                    = false;
+    bool                   visible_object_number                = false;
+    int                    object_number_type                   = 0; // { ocn, non, bkidx }
+    /+ node +/
+    string[string][string] node;
+    int                    ocn                                  = 0;
+    string                 identifier                           = "";
+    int                    o_n_type                             = 0;
+    int                    heading_lev_markup                   = 9;
+    int                    heading_lev_collapsed                = 9;
     bool                   dummy_heading                        = false;
     int[]                  markedup_ancestors                   = [ 0, 0, 0, 0, 0, 0, 0, 0,];
     int[]                  collapsed_ancestors                  = [ 0, 0, 0, 0, 0, 0, 0, 0,];
@@ -126,52 +171,7 @@ template ObjectSetter() {
     int[]                  dom_structure_collapsed_tags_status  = [ 0, 0, 0, 0, 0, 0, 0, 0,];
     int                    parent_lev_markup                    = 0;
     int                    parent_ocn                           = 0;
-    int                    last_decendant_ocn                   = 0;
-  }
-  struct DocObj_TxtAttrib_ {
-    int                    indent_base                         = 0;
-    int                    indent_hang                         = 0;
-    bool                   bullet                              = false;
-    string                 language                            = "";
-  }
-  struct DocObj_Has_ {
-    bool                   inline_links                        = false;
-    bool                   inline_notes_reg                    = false;
-    bool                   inline_notes_star                   = false;
-    bool                   images                              = false;
-    bool                   image_without_dimensions            = false;
-  }
-  struct DocObj_Table_ {
-    int                    number_of_columns                   = 0;
-    double[]               column_widths                       = [];
-    string[]               column_aligns                       = [];
-    bool                   heading                             = false;
-    bool                   walls                               = false;
-  }
-  struct DocObj_CodeBlock_ {
-    string                 syntax                              = "";
-    bool                   linenumbers                         = false;
-  }
-  struct DocObj_Stow_ {
-    string[]               link                               = [];
-  }
-  struct DocObj_Pointer_ {
-    int                    doc_object                          = 0;
-    int                    html_segnames                       = 0;
-    int                    heading                             = 0;
-  }
-  struct DocObj_Tags_ {
-    string[]               heading_ancestors_text              = [ "", "", "", "", "", "", "", "", ];
-    string                 anchor_tag_html                     = "";
-    string                 in_segment_html                     = "";
-    string                 segment_anchor_tag_epub             = "";
-    string                 html_segment_anchor_tag_is          = "";
-    string                 epub_segment_anchor_tag_is          = "";
-    string                 heading_lev_anchor_tag              = "";
-    string                 segname_prev                        = "";
-    string                 segname_next                        = "";
-    string[]               lev4_subtoc                         = [];
-    string[]               anchor_tags                         = [];
+    int                    last_descendant_ocn                  = 0;
   }
   struct ObjGenericComposite {
     string                 text                                = "";
@@ -184,7 +184,242 @@ template ObjectSetter() {
     DocObj_Stow_           stow;
     DocObj_Pointer_        ptr;
   }
+  struct _theDoc {
+    ObjGenericComposite[] toc;
+    ObjGenericComposite[] head;
+    ObjGenericComposite[] body;
+    ObjGenericComposite[] bibliography;
+    ObjGenericComposite[] glossary;
+    ObjGenericComposite[] bookindex;
+    ObjGenericComposite[] blurb;
+    ObjGenericComposite[] endnotes;
+  }
   struct TheObjects {
     ObjGenericComposite[] oca;
   }
+  ObjGenericComposite comp_obj_, comp_obj_location, comp_obj_poem_ocn, comp_obj_comment;
+  ObjGenericComposite[] the_document_toc_section, the_document_head_section, the_document_body_section, the_document_endnotes_section, the_document_bibliography_section, the_document_bookindex_section, the_document_glossary_section, the_document_blurb_section, the_document_xml_dom_tail_section;
+  struct OCNset {
+    int digit;
+    int object_number;
+    bool off;
+    string identifier;
+    int bkidx;
+    int type;
+  }
+  struct ST_endnotes {
+    ObjGenericComposite[] endnotes;
+    OCNset                ocn;
+  }
+  struct ST_bookindex {
+    ObjGenericComposite[] bookindex;
+    OCNset                ocn;
+  }
+  struct ST_biblio_section {
+    ObjGenericComposite[]  bibliography_section;
+    string[string][string] tag_assoc;
+  }
+  struct ST_ancestors {
+    ObjGenericComposite[] the_document_body_section;
+    ObjGenericComposite[] the_document_endnotes_section;
+    ObjGenericComposite[] the_document_glossary_section;
+    ObjGenericComposite[] the_document_bibliography_section;
+    ObjGenericComposite[] the_document_bookindex_section;
+    ObjGenericComposite[] the_document_blurb_section;
+  }
+  struct ST_segnames {
+    string[][string]      segnames;
+    int                   html_segnames_ptr_cntr;
+    int                   html_segnames_ptr;
+  }
+  struct  ST_txtPlusHasFootnotes {
+    string           obj_txt;
+    bool             has_notes_reg;
+    bool             has_notes_star;
+    bool             has_notes_plus;
+  }
+  struct ST_txtPlusHasFootnotesUrlsImages {
+    string           obj_txt;
+    bool             has_notes_reg;
+    bool             has_notes_star;
+    bool             has_notes_plus;
+    bool             has_urls;
+    bool             has_images_without_dimensions;
+  }
+  struct ST_txtAndAnchorTagPlusHasFootnotesUrlsImages {
+    string           obj_txt;
+    string           anchor_tag;
+    bool             has_notes_reg;
+    bool             has_notes_star;
+    bool             has_notes_plus;
+    bool             has_links; // use same name
+    bool             has_images_without_dimensions;
+  }
+  struct ST_the_section {
+    ObjGenericComposite[]  comp_section_obj; // array: the heading has 2 members inserted, paras just 1
+    uint[string]           pith;
+    string[string][string] tag_assoc;        // only for headings: html & epub
+  }
+  // book index variables
+  string book_idx_tmp;
+  string[][string][string] bookindex_unordered_hashes;
+  // node
+  struct ST_txt_by_line_common_reset {
+    int[string]     line_occur;
+    string[string]  this_object;
+    uint[string]    pith;
+  }
+  struct ST_txt_by_line_block_start {
+    uint[string]    pith;
+    uint[string]    dochas;
+    string[string]  object_number_poem;
+  }
+  struct ST_txt_by_line_block_generic {
+    uint[string]    pith;
+    string[string]  this_object;
+  }
+  struct ST_txt_by_line_block_poem {
+    int             cntr;
+    uint[string]    pith;
+    string[string]  this_object;
+  }
+  struct ST_txt_by_line_block_biblio {
+    uint[string]    pith;
+    int             bib_entry;
+    string          biblio_entry_str_json;
+    string[]        biblio_arr_json;
+  }
+  struct ST_flow_book_index {
+    string[string]  this_object;
+    uint[string]    pith;
+    string          book_idx_tmp;
+  }
+  struct ST_flow_heading_found {
+    string[string]       heading_match_str;
+    Regex!(char)[string] heading_match_rgx;
+    uint[string]         pith;
+  }
+  struct ST_flow_heading_make_set {
+    char[]          line;
+    uint[string]    pith;
+    string[string]  this_object;
+  }
+  struct ST_flow_para_match {
+    uint[string]    pith;
+    string[string]  this_object;
+    string          this_object_key;
+    int[string]     indent;
+    bool            bullet;
+    int[string]     line_occur;
+  }
+  struct ST_flow_table_array_munge {
+    ObjGenericComposite table_object;
+    string[][]          table_array;
+  }
+  struct ST_flow_table_of_contents_gather_headings {
+    ObjGenericComposite[] the_document_toc_section;
+    string[][string]      lev4_subtoc;
+  }
+  struct ST_flow_bibliography {
+    JSONValue[] biblio_sorted;
+    JSONValue[] bib_arr_json;
+    string[]    biblio_unsorted_incomplete;
+  }
+  struct ST_flow_table_closed_make_special_notation_table {
+    string[string]        this_object;
+    ObjGenericComposite[] the_document_body_section;
+    OCNset                obj_cite_digits;
+    ObjGenericComposite   comp_obj_;
+    int                   cntr;
+    uint[string]          pith;
+  }
+  struct ST_flow_block_flag_line_empty {
+    string[string]           this_object;
+    ObjGenericComposite[]    the_document_body_section;
+    string[][string][string] bookindex_unordered_hashes;
+    OCNset                   obj_cite_digits;
+    ObjGenericComposite      comp_obj_;
+    int                      cntr;
+    uint[string]             pith;
+  }
+  struct ST_flow_table_substantive_munge {
+    ObjGenericComposite  table_object;
+    string               table_substantive;
+  }
+  struct _loopMarkupSrcByLineStruct {
+    ObjGenericComposite[] toc;
+    ObjGenericComposite[] body;
+    ObjGenericComposite[] glossary;
+    ObjGenericComposite[] blurb;
+    string[string]        object_notes;
+    string[][string]      segnames;
+  }
+  enum DocStructMarkupHeading {
+    h_sect_A,
+    h_sect_B,
+    h_sect_C,
+    h_sect_D,
+    h_text_1,
+    h_text_2,
+    h_text_3,
+    h_text_4,
+    h_text_5, // extra level, drop
+    content_non_header
+  } // header section A-D; header text 1-4
+  enum Status { off, on, }
+  enum OCNtype { ocn, non, bkidx, }
+  enum DomTags { none, open, close, close_and_open, open_still, }
+  enum Substitute { match, markup, }
+  @safe static auto eN() {
+    struct _e {
+      enum bi {
+        off,
+        on,
+      }
+      enum ocn {
+        off,
+        on,
+        closing,
+        bkidx,
+        reset,
+      }
+      enum sect {
+        unset,
+        head,
+        toc,
+        substantive,
+        bibliography,
+        glossary,
+        book_index,
+        blurb,
+      }
+      enum txt_is {
+        off,
+        para,
+        heading,
+      }
+      enum blk_is {
+        off,
+        code,
+        poem,
+        block,
+        group,
+        table,
+        quote,
+      }
+      enum blk_state {
+        off,
+        on,
+        closing,
+      }
+      enum blk_delim {
+        off,
+        curly,
+        tic,
+        curly_special,
+        tic_special,
+      }
+    }
+    return _e();
+  }
 }
-- 
cgit v1.2.3