diff options
| author | Ralph Amissah <ralph.amissah@gmail.com> | 2024-01-21 01:15:34 -0500 | 
|---|---|---|
| committer | Ralph Amissah <ralph.amissah@gmail.com> | 2024-01-25 12:58:32 -0500 | 
| commit | 10a66c974537dcb984217a6c581fc20fa7144db4 (patch) | |
| tree | 0305f1574d2a37f3d2667ba541e473f11908ba71 /src/doc_reform | |
| parent | org, ocda (ongoing) (diff) | |
org, ocda (ongoing) split file, separate functions
Diffstat (limited to 'src/doc_reform')
| -rw-r--r-- | src/doc_reform/io_out/sqlite.d | 4 | ||||
| -rw-r--r-- | src/doc_reform/meta/metadoc_from_src.d | 5362 | ||||
| -rw-r--r-- | src/doc_reform/meta/metadoc_from_src_functions.d | 5215 | ||||
| -rw-r--r-- | src/doc_reform/meta/metadoc_object_setter.d | 353 | 
4 files changed, 5526 insertions, 5408 deletions
| 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(); +  }  } | 
