diff options
Diffstat (limited to 'lib/sdp')
| -rw-r--r-- | lib/sdp/ao_abstract_doc_source.d | 5053 | ||||
| -rw-r--r-- | lib/sdp/ao_ansi_colors.d (renamed from lib/sdp/ao_utils.d) | 2 | ||||
| -rw-r--r-- | lib/sdp/ao_assertions.d | 221 | ||||
| -rw-r--r-- | lib/sdp/ao_defaults.d | 85 | ||||
| -rw-r--r-- | lib/sdp/ao_object_setter.d | 172 | ||||
| -rw-r--r-- | lib/sdp/ao_output_debugs.d | 138 | ||||
| -rw-r--r-- | lib/sdp/ao_read_markup_source.d | 55 | ||||
| -rw-r--r-- | lib/sdp/ao_read_source_files.d | 281 | ||||
| -rw-r--r-- | lib/sdp/ao_rgx.d | 50 | ||||
| -rw-r--r-- | lib/sdp/ao_scan_inserts.d | 199 | ||||
| -rw-r--r-- | lib/sdp/ao_structs.d | 43 | ||||
| -rw-r--r-- | lib/sdp/compile_time_info.d | 2 | ||||
| -rwxr-xr-x | lib/sdp/sdp.d | 186 | 
13 files changed, 4166 insertions, 2321 deletions
| diff --git a/lib/sdp/ao_abstract_doc_source.d b/lib/sdp/ao_abstract_doc_source.d index 34e4072..74d1baa 100644 --- a/lib/sdp/ao_abstract_doc_source.d +++ b/lib/sdp/ao_abstract_doc_source.d @@ -2,126 +2,146 @@    document abstraction    ao_abstract_doc_source.d  +/ -mixin template SiSUdocAbstraction() { +template SiSUdocAbstraction() {    private:    struct Abstraction { + +    /+ ↓ abstraction imports +/ +    import +      lib.sdp.ao_defaults,                  // sdp/ao_defaults.d +      lib.sdp.ao_object_setter,             // sdp/ao_object_setter.d +      lib.sdp.ao_rgx,                       // sdp/ao_rgx.d +      lib.sdp.ao_ansi_colors;               // sdp/ao_ansi_colors.d + +    /+ ↓ abstraction mixins +/ +    mixin ObjectSetter; +    mixin InternalMarkup; +    // // mixin SiSUrgxInitFlags; +    // // mixin AssertionsOnBlocks; +    // mixin SiSUbiblio; // issue +    // mixin SiSUheader; + +    /+ ↓ abstraction struct init +/ +    /+ initialize +/ +     +    auto rgx = Rgx(); +    string[string][] contents_the_objects; +    string[string] an_object, processing; +    auto set_abstract_object = ObjectAbstractSet(); +    auto set_header = HeaderDocMetadataMakeJson(); +    auto note_section = NotesSection(); +     +    /+ enum +/ +    enum State { off, on } +    enum TriState { off, on, closing } // make aware, possibility of third state +    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 DocStructCollapsedHeading { lv0, lv1, lv2, lv3, lv4, lv5, lv6, lv7 } // not yet used +     +    /+ biblio variables +/ +    string biblio_tag_name, biblio_tag_entry, st; +    string[] biblio_arr_json; +    JSONValue[] bib_arr_json; +    int bib_entry; +     +    /+ counters +/ +    long counter, previous_count; +    int[string] line_occur; +    int verse_line, heading_pointer; +     +    /+ paragraph attributes +/ +    string[string] indent; +    bool bullet = true; +    string content_non_header = "8"; +     +    auto obj_im = ObjInlineMarkup(); +    auto obj_att = ObjAttrib(); +     +    /+ ocn +/ +    int obj_cite_number, obj_cite_number_; +    auto object_citation_number = OCNemitter(); +    int obj_cite_number_emit(int obj_cite_number_status_flag) { +      return object_citation_number.obj_cite_number_emitter(obj_cite_number_status_flag); +    } +     +    /+ book index variables +/ +    string book_idx_tmp; +    string[][string][string] bookindex_unordered_hashes; +    auto bookindex_extract_hash = BookIndexNuggetHash(); +    string[][string][string] bkidx_hash(string bookindex_section, int obj_cite_number) { +      return bookindex_extract_hash.bookindex_nugget_hash(bookindex_section, obj_cite_number); +    } +     +    /+ node +/ +    string node; +    auto node_construct = NodeStructureMetadata(); +    string node_jstr( +      string lev_markup_number, +      int obj_cite_number_, +      long counter, +      int heading_pointer, +      string is_ +    ) { +      return node_construct.node_emitter( +        lev_markup_number, +        obj_cite_number_, +        counter, +        heading_pointer, +        is_ +      ); +    } +    string node_jstr_heading( +      string lev_markup_number, +      string lev_collapsed_number, +      int obj_cite_number_, +      long counter, +      int heading_pointer, +      string is_ +    ) { +      return node_construct.node_emitter_heading( +        lev_markup_number, +        lev_collapsed_number, +        obj_cite_number_, +        counter, +        heading_pointer, +        is_ +      ); +    } +    // mixin SiSUdocAbstractionFunctions; +      /+ ↓ abstract marked up document +/      auto abstract_doc_source(char[][] markup_sourcefile_content) { -      /+ initialize +/ -      mixin ObjectSetters; -      mixin AssertionsOnMarkupDocumentStructure; -      mixin AssertionsOnBlocks; -      mixin ScreenTxtColors; -      auto rgx = Rgx(); -      auto set_oa = ObjectAbstractSet(); -      auto set_header = HeaderDocMetadataMakeJson(); -      auto notesection = NotesSection(); -      string[string][] contents; -      mixin Structs; -      string notes_str; -      string[string] object, processing, head; -      string biblio_tag_name, biblio_tag_entry, book_idx_tmp, st; -      string[] biblio_arr_json; -      JSONValue[] bib_arr_json; -      uint[string] line_occur; -      uint counter, ocn, ocn_, verse_line, bib_entry, heading_pointer, notepoint, count_biblio_entry; -      ulong previous_count; -      string indent_first, indent_second; -      string[][string][string] bookindex_unordered_hashes; -      bool bullet = true; -      uint[string] lv = [ -        "lv" : 0, -        "h0" : 0, -        "h1" : 0, -        "h2" : 0, -        "h3" : 0, -        "h4" : 0, -        "h5" : 0, -        "h6" : 0, -        "h7" : 0, -        "lcn" : 0, -      ]; -      int[string] collapsed_lev = [ -        "h0" : 0, -        "h1" : 0, -        "h2" : 0, -        "h3" : 0, -        "h4" : 0, -        "h5" : 0, -        "h6" : 0, -        "h7" : 0 -      ]; -      auto rgx_h_A = regex(r"^(none)"); -      auto rgx_h_B = regex(r"^(none)"); -      auto rgx_h_C = regex(r"^(none)"); -      auto rgx_h_D = regex(r"^(none)"); -      auto rgx_h_1 = regex(r"^(none)"); -      auto rgx_h_2 = regex(r"^(none)"); -      auto rgx_h_3 = regex(r"^(none)"); -      auto rgx_h_4 = regex(r"^(none)"); -      auto str_h_A = "^(none)"; -      auto str_h_B = "^(none)"; -      auto str_h_C = "^(none)"; -      auto str_h_D = "^(none)"; -      auto str_h_1 = "^(none)"; -      auto str_h_2 = "^(none)"; -      auto str_h_3 = "^(none)"; -      auto str_h_4 = "^(none)"; -      string content_non_header = "8"; -      string node; -      auto obj_im = ObjInlineMarkup(); -      auto obj_att = ObjAttrib(); -      auto object_citation_number = OCNemitter(); -      auto ft = flag_type.dup; -      int ocn_emit(int ocn_status_flag) { -        return object_citation_number.ocn_emitter(ocn_status_flag); -      } -      auto bookindex_extract_hash = BookIndexNuggetHash(); -      string[][string][string] bkidx_hash(string bookindex, int ocn) { -        return bookindex_extract_hash.bookindex_nugget_hash(bookindex, ocn); -      } -      auto node_construct = NodeStructureMetadata(); -      string node_jstr( -        string lvn, -        int ocn_, -        int counter, -        int heading_pointer, -        string is_ -      ) { -        return node_construct.node_emitter( -          lvn, -          ocn_, -          counter, -          heading_pointer, -          is_ -        ); + +      /+ ↓ abstraction init +/ +      scope(success) {        } -      string node_jstr_heading( -        string lvn, -        string lcn, -        int ocn_, -        int counter, -        int heading_pointer, -        string is_ -      ) { -        return node_construct.node_emitter_heading( -          lvn, -          lcn, -          ocn_, -          counter, -          heading_pointer, -          is_ -        ); +      scope(failure) {        } -      string[string] ocn_poem = [ -        "start" : "", -        "end"   : "" -      ]; -      int tell_lo(string color, int ocn, in char[] line) { +      scope(exit) { +        destroy(contents_the_objects); +        destroy(an_object); +        destroy(processing); +        destroy(biblio_arr_json); +      } +      auto type = flags_type_init; +      auto dochead_make = parseJSON(header_make_jsonstr).object; +      auto dochead_metadata = parseJSON(header_metadata_jsonstr).object; +      mixin ScreenTxtColors; +      int tell_lo(string color, int obj_cite_number, in char[] line) {          writefln(            "%s%s %s",            scr_txt_marker[color], -          to!string(ocn), +          to!string(obj_cite_number),            to!string(line)          );          return 0; @@ -134,29 +154,66 @@ mixin template SiSUdocAbstraction() {          );          return 0;        } -      scope(success) { -      } -      scope(failure) { -      } -      scope(exit) { -        destroy(contents); -        destroy(object); -        destroy(processing); -        destroy(biblio_arr_json); -      } -      auto dochead_make = parseJSON(header_make_jsonstr).object; -      auto dochead_metadata = parseJSON(header_metadata_jsonstr).object; +      string[string] obj_cite_number_poem = [ +        "start" : "", +        "end"   : "" +      ]; +      int[string] lv = [ +        "lv" : State.off, +        "h0" : State.off, +        "h1" : State.off, +        "h2" : State.off, +        "h3" : State.off, +        "h4" : State.off, +        "h5" : State.off, +        "h6" : State.off, +        "h7" : State.off, +        "lev_collapsed_number" : 0, +      ]; +      int[string] collapsed_lev = [ +        "h0" : State.off, +        "h1" : State.off, +        "h2" : State.off, +        "h3" : State.off, +        "h4" : State.off, +        "h5" : State.off, +        "h6" : State.off, +        "h7" : State.off +      ]; +      string[string] heading_match_str = [ +        "h_A": "^(none)", +        "h_B": "^(none)", +        "h_C": "^(none)", +        "h_D": "^(none)", +        "h_1": "^(none)", +        "h_2": "^(none)", +        "h_3": "^(none)", +        "h_4": "^(none)" +      ]; +      auto heading_match_rgx = [ +        "h_A": regex(r"^(none)"), +        "h_B": regex(r"^(none)"), +        "h_C": regex(r"^(none)"), +        "h_D": regex(r"^(none)"), +        "h_1": regex(r"^(none)"), +        "h_2": regex(r"^(none)"), +        "h_3": regex(r"^(none)"), +        "h_4": regex(r"^(none)") +      ]; +      /+ abstraction init ↑ +/ +        /+ ↓ loop markup document/text line by line +/ +      srcDocLoop:        foreach (line; markup_sourcefile_content) { +          /+ ↓ markup document/text line by line +/          /+ scope +/          scope(exit) {          }          scope(failure) { -          writefln( -            "%s:%s failed here: \n  line: %s", -            __FILE__, -            __LINE__, +          stderr.writefln( +            "%s:%s failed here:\n  line: %s", +            __FILE__, __LINE__,              line,            );          } @@ -176,679 +233,74 @@ mixin template SiSUdocAbstraction() {              );            }          } -        if ((!line.empty) && (ft["ocn_status_multi_obj"] == 0)) { -        /+ not multi-line object, check whether ocn is on or turned off +/ -          if (match(line, rgx.ocn_block_marks)) { -          /+ switch off ocn +/ -            if (match(line, rgx.ocn_off_block)) { -              ft["ocn_status_multi_obj"] = 1; -              debug(ocnoff) { -                tell_l("fuchsia", line); -              } -            } -            if (match(line, rgx.ocn_off_block_dh)) { -              ft["ocn_status_multi_obj"] = 2; -              debug(ocnoff) { -                tell_l("fuchsia", line); -              } -            } -          } else { -            if (ft["ocn_status_multi_obj"] == 0) { -              if (match(line, rgx.ocn_off)) { -                ft["ocn_status"] = 1; -              } else if (match(line, rgx.ocn_off_dh)) { -                ft["ocn_status"] = 2; -              } else { -                ft["ocn_status"] = 2; -                ft["ocn_status"] = 0; -              } -            } else { -              ft["ocn_status"] = ft["ocn_status_multi_obj"]; -            } -          } -        } else if ((!line.empty) && (ft["ocn_status_multi_obj"] > 0)) { -          if (auto m = match(line, rgx.ocn_off_block_close)) { -            ft["ocn_status_multi_obj"] = 0; -            ft["ocn_status"] = 0; -            debug(ocnoff) { -              tell_l("green", line); -            } -          } +        if (!line.empty) { +          check_obj_cite_number_status(line, type);          } -        if (ft["code"] == 1) { -        /+ block object: code +/ -          if (ft["curly_code"] == 1) { -            if (auto m = match(line, rgx.block_curly_code_close)) { -              debug(code) {                              // code (curly) close -                tell_l("blue", line); -              } -              ft["blocks"] = 2; -              ft["code"] = 2; -              ft["curly_code"] = 0; -            } else { -              debug(code) {                              // code (curly) line -                tell_l("blue", line); -              } -              object["obj"] ~= line ~= "\n";             // code (curly) line -            } -          } else if (ft["tic_code"] == 1) { -            if (auto m = match(line, rgx.block_tic_close)) { -              debug(code) {                              // code (tic) close -                tell_l("blue", line); -              } -              ft["blocks"] = 2; -              ft["code"] = 2; -              ft["tic_code"] = 0; -            } else { -              debug(code) {                              // code (tic) line -                tell_l("blue", line); -              } -              object["obj"] ~= line ~= "\n";             // code (tic) line -            } -          } +        if (type["code"] == TriState.on) { +          /+ block object: code +/ +          code_block(line, an_object, type); +          continue;          } else if (!match(line, rgx.regular_parse_skip)) { -        /+ object other than code block object (includes regular text paragraph) +/ +          /+ object other than code block object (includes regular text paragraph) +/            if (((match(line, rgx.heading_biblio) -          || (ft["heading_biblio"] == 1))) +          || (type["heading_biblio"] == State.on)))            && (!match(line, rgx.heading))            && (!match(line, rgx.comment))) { -          /+ within block object: biblio +/ -            if (match(line, rgx.heading_biblio)) { -              ft["heading_biblio"] = 1; -            } -            if (empty(line) && (bib_entry == 0)) { -              ++count_biblio_entry; -              biblio_arr_json ~= biblio_entry_tags_jsonstr; -              bib_entry = 1; -            } -            debug(biblio) { -              writefln( -                "%s * %s %s", -                scr_txt_color["yellow"], -                scr_txt_color["off"], -                line -              ); -            } -            if (match(line, rgx.biblio_tags)) { -              auto bt = match(line, rgx.biblio_tags); -              bib_entry = 0; -              st=to!string(bt.captures[1]); -              biblio_tag_entry=to!string(bt.captures[2]); -              JSONValue j = parseJSON(biblio_arr_json[count_biblio_entry-1]); // core.exception.RangeError@lib/sdp/ao_abstract_doc_source.d(288): Range violation (LDC) [: same for 343], fix to subtract 1 done! -              if (match(st, rgx.biblio_abbreviations)) { -                biblio_tag_name=biblio_tag_map[st]; -              } else { -                biblio_tag_name=st; -              } -              j.object[biblio_tag_name] = biblio_tag_entry; -              auto header_tag_value=to!string(bt.captures[2]); -              switch (biblio_tag_name) { -              case "author_raw": // author_arr author (fn sn) -                j["author_arr"]=split(header_tag_value, rgx.arr_delimiter); -                string tmp; -                foreach (au; j["author_arr"].array) { -                  if (auto x = match(au.str, rgx.name_delimiter)) { -                    tmp ~= x.captures[2] ~ " " ~ x.captures[1] ~ ", "; -                  } else { -                    tmp ~= au.str; -                  } -                } -                tmp = replace(tmp, rgx.trailing_comma, ""); -                j["author"].str = tmp; -                break; -              case "editor_raw": // editor_arr editor (fn sn) -                j["editor_arr"]=split(header_tag_value, rgx.arr_delimiter); -                string tmp; -                foreach (ed; j["editor_arr"].array) { -                  if (auto x = match(ed.str, rgx.name_delimiter)) { -                    tmp ~= x.captures[2] ~ " " ~ x.captures[1] ~ ", "; -                  } else { -                    tmp ~= ed.str; -                  } -                } -                tmp = replace(tmp, rgx.trailing_comma, ""); -                j["editor"].str = tmp; -                break; -              case "fulltitle": // title & subtitle -                break; -              default: -                break; -              } -              auto s = to!string(j); -              s = j.toString(); -              debug(biblio) { -                writefln( -                  "%s* %s%s: %s\n%s", -                  scr_txt_color["red"], -                  scr_txt_color["off"], -                  biblio_tag_name, -                  biblio_tag_entry, -                  j[biblio_tag_name] -                ); -                writeln(j[biblio_tag_name], ":", j[biblio_tag_name]); -              } -              biblio_arr_json[count_biblio_entry-1] = s; -              biblio_tag_entry=""; -            } -          } else if (ft["poem"] == 1) { -          /+ within block object: poem +/ -            if (ft["curly_poem"] == 1) { -              if (auto m = match(line, rgx.block_curly_poem_close)) { -                object["obj"]="verse"; // check that this is as you please -                debug(poem) {                            // poem (curly) close -                  writefln( -                    "%s* [poem curly] %s%s", -                    scr_txt_color["red"], -                    scr_txt_color["off"], -                    line -                  ); -                } -                if (processing.length > 0) { -                  object["obj"] = processing["verse"]; -                } -                debug(poem) {                            // poem (curly) close -                  writeln(__LINE__); -                  writefln( -                    "%s%s %s", -                    scr_txt_marker["fuchsia"], -                    ocn, -                    line -                  ); -                } -                if (object.length > 0) { -                  debug(poem) {                            // poem (curly) close -                    writeln(__LINE__); -                    tell_lo( -                      "fuchsia", -                      ocn, -                      object["obj"] -                    ); -                    writeln(__LINE__); -                  } -                  object["is"] = "verse"; -                  object["markup"] = -                    obj_im.obj_inline_markup(object["is"], object["obj"]); -                  object["attrib"] = -                    obj_att.obj_attributes(object["is"], object["obj"], node); -                  contents ~= -                    set_oa.contents_block( -                      object["is"], -                      object["markup"], -                      object["attrib"], -                      ocn -                    ); -                  object.remove("obj"); -                  object.remove("markup"); -                  object.remove("is"); -                  object.remove("attrib"); -                  object.remove("bookindex"); -                  processing.remove("verse"); -                  counter++; -                } -                ocn_poem["end"] = to!string(ocn); -                ft["blocks"] = 2; -                ft["poem"] = 2; -                ft["curly_poem"] = 0; -              } else { -                processing["verse"] ~= line ~= "\n"; -                if (ft["verse_new"] == 1) { -                  ocn = ocn_emit(ft["ocn_status"]); -                  ft["verse_new"] = 0; -                } else if (match(line, rgx.line_delimiter_only)) { -                  verse_line = 0; -                  ft["verse_new"] = 1; -                } -                if (ft["verse_new"] == 1) { -                  verse_line=1; -                  object["obj"] = processing["verse"]; -                  debug(poem) {                          // poem verse -                    writefln( -                      "%s%s curly\n%s", -                      scr_txt_marker["green"], -                      ocn, -                      object["obj"] -                    ); -                  } -                  processing.remove("verse"); -                  object["is"] = "verse"; -                  node = node_jstr( -                    content_non_header, -                    ocn, -                    counter, -                    heading_pointer-1, -                    object["is"] -                  ); -                  object["markup"] = obj_im.obj_inline_markup(object["is"], object["obj"]); -                  object["attrib"] = obj_att.obj_attributes(object["is"], object["obj"], node); -                  contents ~= -                    set_oa.contents_block( -                      object["is"], -                      object["markup"], -                      object["attrib"], -                      ocn -                    ); -                  object.remove("obj"); -                  object.remove("markup"); -                  object.remove("is"); -                  object.remove("attrib"); -                  object.remove("bookindex"); -                  processing.remove("verse"); -                  counter++; -                } -              } -            } else if (ft["tic_poem"] == 1) { -              if (auto m = match(line, rgx.block_tic_close)) { // tic_poem_close -                object["obj"]="verse"; // check that this is as you please -                debug(poem) {                            // poem (curly) close -                  writefln( -                    "%s* [poem tic] %s%s", -                    scr_txt_color["red"], -                    scr_txt_color["off"], -                    line -                  ); -                } -                if (processing.length > 0) {       // needs looking at -                  object["obj"] = processing["verse"]; -                } -                if (object.length > 0) { -                  debug(poem) {                            // poem (tic) close -                    writeln(__LINE__); -                    tell_lo("fuchsia", ocn, line); -                  } -                  processing.remove("verse"); -                  object["is"] = "verse"; -                  object["markup"] = -                    obj_im.obj_inline_markup(object["is"], object["obj"]); -                  object["attrib"] = -                    obj_att.obj_attributes(object["is"], object["obj"], node); -                  contents ~= -                    set_oa.contents_block( -                      object["is"], -                      object["markup"], -                      object["attrib"], -                      ocn -                    ); -                  ocn_poem["end"] = to!string(ocn); -                  object.remove("obj"); -                  object.remove("markup"); -                  object.remove("is"); -                  object.remove("attrib"); -                  object.remove("bookindex"); -                  processing.remove("verse"); -                  counter++; -                } -                ft["blocks"] = 2; -                ft["poem"] = 2; -                ft["tic_poem"] = 0; -              } else { -                processing["verse"] ~= line ~= "\n"; -                if (ft["verse_new"] == 1) { -                  ocn = ocn_emit(ft["ocn_status"]); -                  ft["verse_new"] = 0; -                } else if (match(line, rgx.line_delimiter_only)) { -                  ft["verse_new"] = 1; -                  verse_line = 0; -                } -                if (ft["verse_new"] == 1) { -                  verse_line=1; -                  object["obj"] = processing["verse"]; -                  debug(poem) {                            // poem (tic) close -                    writefln( -                      "%s%s tic\n%s", -                      scr_txt_marker["green"], -                      ocn, -                      object["obj"] -                    ); -                  } -                  processing.remove("verse"); -                  object["is"] = "verse"; -                  node = -                    node_jstr( -                      content_non_header, -                      ocn, -                      counter, -                      heading_pointer-1, -                      object["is"] -                    ); -                  object["markup"] = -                    obj_im.obj_inline_markup(object["is"], object["obj"]); -                  object["attrib"] = -                    obj_att.obj_attributes(object["is"], object["obj"], node); -                  contents ~= -                    set_oa.contents_block( -                      object["is"], -                      object["markup"], -                      object["attrib"], -                      ocn -                    ); -                  object.remove("obj"); -                  object.remove("markup"); -                  object.remove("is"); -                  object.remove("attrib"); -                  object.remove("bookindex"); -                  processing.remove("verse"); -                  counter++; -                } -              } -            } +            /+ within block object: biblio +/ +            biblio_block(line, type, bib_entry, biblio_arr_json); +            continue; +          } else if (type["poem"] == TriState.on) { +            /+ within block object: poem +/ +            poem_block(line, an_object, type, counter, obj_cite_number_poem); +            continue;            /+ within block object: group +/ -          } else if (ft["group"] == 1) { -            if (ft["curly_group"] == 1) { -              if (auto m = match(line, rgx.block_curly_group_close)) { -                debug(group) {                           // group (curly) close -                  tell_l("blue", line); -                } -                ft["blocks"] = 2; -                ft["group"] = 2; -                ft["curly_group"] = 0; -              } else { -                debug(group) {                           // group -                  tell_l("blue", line); -                } -                object["obj"] ~= line ~= "\n";           // build group array (or string) -              } -            } else if (ft["tic_group"] == 1) { -              if (auto m = match(line, rgx.block_tic_close)) { -                debug(group) {                           // group (tic) close -                  tell_l("blue", line); -                } -                ft["blocks"] = 2; -                ft["group"] = 2; -                ft["tic_group"] = 0; -              } else { -                debug(group) {                           // group -                  tell_l("blue", line); -                } -                object["obj"] ~= line ~= "\n";           // build group array (or string) -              } -            } -          } else if (ft["block"] == 1) { -          /+ within block object: block +/ -            if (ft["curly_block"] == 1) { -              if (auto m = match(line, rgx.block_curly_block_close)) { -                debug(block) {                           // block (curly) close -                  tell_l("blue", line); -                } -                ft["blocks"] = 2; -                ft["block"] = 2; -                ft["curly_block"] = 0; -              } else { -                debug(block) {                           // block -                  tell_l("blue", line); -                } -                object["obj"] ~= line ~= "\n";           // build block array (or string) -              } -            } else if (ft["tic_block"] == 1) { -              if (auto m = match(line, rgx.block_tic_close)) { -                debug(block) {                           // block (tic) close -                  tell_l("blue", line); -                } -                ft["blocks"] = 2; -                ft["block"] = 2; -                ft["tic_block"] = 0; -              } else { -                debug(block) {                           // block -                  tell_l("blue", line); -                } -                object["obj"] ~= line ~= "\n";           // build block array (or string) -              } -            } -          } else if (ft["quote"] == 1) { -          /+ within block object: quote +/ -            if (ft["curly_quote"] == 1) { -              if (auto m = match(line, rgx.block_curly_quote_close)) { -                debug(quote) {                           // quote (curly) close -                  tell_l("blue", line); -                } -                ft["blocks"] = 2; -                ft["quote"] = 2; -                ft["curly_quote"] = 0; -              } else { -                debug(quote) {                           // quote -                  tell_l("blue", line); -                } -                object["obj"] ~= line ~= "\n";           // build quote array (or string) -              } -            } else if (ft["tic_quote"] == 1) { -              if (auto m = match(line, rgx.block_tic_close)) { -                debug(quote) {                           // quote (tic) close -                  tell_l("blue", line); -                } -                ft["blocks"] = 2; -                ft["quote"] = 2; -                ft["tic_quote"] = 0; -              } else { -                debug(quote) {                           // quote -                  tell_l("blue", line); -                } -                object["obj"] ~= line ~= "\n";           // build quote array (or string) -              } -            } -          } else if (ft["table"] == 1) { -          /+ within block object: table +/ -            if (ft["curly_table"] == 1) { -              if (auto m = match(line, rgx.block_curly_table_close)) { -                debug(table) {                           // table (curly) close -                  tell_l("blue", line); -                } -                ft["blocks"] = 2; -                ft["table"] = 2; -                ft["curly_table"] = 0; -              } else { -                debug(table) {                           // table -                  tell_l("blue", line); -                } -                object["obj"] ~= line ~= "\n";           // build table array (or string) -              } -            } else if (ft["tic_table"] == 1) { -              if (auto m = match(line, rgx.block_tic_close)) { -                debug(table) {                           // table (tic) close -                  tell_l("blue", line); -                } -                ft["blocks"] = 2; -                ft["table"] = 2; -                ft["tic_table"] = 0; -              } else { -                debug(table) {                           // table -                  tell_l("blue", line); -                } -                object["obj"] ~= line ~= "\n";           // build table array (or string) -              } -            } +          } else if (type["group"] == TriState.on) { +            /+ within block object: group +/ +            group_block(line, an_object, type); +            continue; +          } else if (type["block"] == TriState.on) { +            /+ within block object: block +/ +            block_block(line, an_object, type); +            continue; +          } else if (type["quote"] == TriState.on) { +            /+ within block object: quote +/ +            quote_block(line, an_object, type); +            continue; +          } else if (type["table"] == TriState.on) { +            /+ within block object: table +/ +            table_block(line, an_object, type); +            continue;            } else {            /+ not within a block group +/              assert( -              (ft["blocks"] == 0) -              || (ft["blocks"] == 2), +              (type["blocks"] == TriState.off) +              || (type["blocks"] == TriState.closing),                "block status: none or closed"              ); -            assertions_flag_types_block_status_none_or_closed(ft); -            if (auto m = match(line, rgx.block_curly_code_open)) { -            /+ curly code open +/ -              debug(code) {                              // code (curly) open -                writefln( -                  "%s* [code curly] %s%s", -                  scr_txt_color["blue"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ft["blocks"] = 1; -              ft["code"] = 1; -              ft["curly_code"] = 1; -            } else if (auto m = match(line, rgx.block_curly_poem_open)) { -            /+ curly poem open +/ -              object.remove("obj"); -              object.remove("markup"); -              object.remove("is"); -              object.remove("attrib"); -              object.remove("bookindex"); -              processing.remove("verse"); -              debug(poem) {                              // poem (curly) open -                writefln( -                  "%s* [poem curly] %s%s", -                  scr_txt_color["red"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ocn_poem["start"] = to!string(ocn); -              ft["blocks"] = 1; -              ft["verse_new"] = 1; -              ft["poem"] = 1; -              ft["curly_poem"] = 1; -            } else if (auto m = match(line, rgx.block_curly_group_open)) { -            /+ curly group open +/ -              debug(group) {                             // group (curly) open -                writefln( -                  "%s* [group curly] %s%s", -                  scr_txt_color["blue"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ft["blocks"] = 1; -              ft["group"] = 1; -              ft["curly_group"] = 1; -            } else if (auto m = match(line, rgx.block_curly_block_open)) { -            /+ curly block open +/ -              debug(block) {                             // block (curly) open -                writefln( -                  "%s* [block curly] %s%s", -                  scr_txt_color["blue"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ft["blocks"] = 1; -              ft["block"] = 1; -              ft["curly_block"] = 1; -            } else if (auto m = match(line, rgx.block_curly_quote_open)) { -            /+ curly quote open +/ -              debug(quote) {                             // quote (curly) open -                writefln( -                  "%s* [quote curly] %s%s", -                  scr_txt_color["blue"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ft["blocks"] = 1; -              ft["quote"] = 1; -              ft["curly_quote"] = 1; -            } else if (auto m = match(line, rgx.block_curly_table_open)) { -            /+ curly table open +/ -              debug(table) {                             // table (curly) open -                writefln( -                  "%s* [table curly] %s%s", -                  scr_txt_color["blue"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ft["blocks"] = 1; -              ft["table"] = 1; -              ft["curly_table"] = 1; -            } else if (auto m = match(line, rgx.block_tic_code_open)) { -            /+ tic code open +/ -              debug(code) {                              // code (tic) open -                writefln( -                  "%s* [code tic] %s%s", -                  scr_txt_color["blue"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ft["blocks"] = 1; -              ft["code"] = 1; -              ft["tic_code"] = 1; -            } else if (auto m = match(line, rgx.block_tic_poem_open)) { -            /+ tic poem open +/ -              object.remove("obj"); -              object.remove("markup"); -              object.remove("is"); -              object.remove("attrib"); -              object.remove("bookindex"); -              processing.remove("verse"); -              debug(poem) {                              // poem (tic) open -                writefln( -                  "%s* [poem tic] %s%s", -                  scr_txt_color["red"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ocn_poem["start"] = to!string(ocn); -              ft["blocks"] = 1; -              ft["verse_new"] = 1; -              ft["poem"] = 1; -              ft["tic_poem"] = 1; -            } else if (auto m = match(line, rgx.block_tic_group_open)) { -            /+ tic group open +/ -              debug(group) {                             // group (tic) open -                writefln( -                  "%s* [group tic] %s%s", -                  scr_txt_color["blue"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ft["blocks"] = 1; -              ft["group"] = 1; -              ft["tic_group"] = 1; -            } else if (auto m = match(line, rgx.block_tic_block_open)) { -            /+ tic block open +/ -              debug(block) {                             // block (tic) open -                writefln( -                  "%s* [block tic] %s%s", -                  scr_txt_color["blue"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ft["blocks"] = 1; -              ft["block"] = 1; -              ft["tic_block"] = 1; -            } else if (auto m = match(line, rgx.block_tic_quote_open)) { -            /+ tic quote open +/ -              debug(quote) {                             // quote (tic) open -                writefln( -                  "%s* [quote tic] %s%s", -                  scr_txt_color["blue"], -                  scr_txt_color["off"], -                  line -                ); -              } -              ft["blocks"] = 1; -              ft["quote"] = 1; -              ft["tic_quote"] = 1; -            } else if (auto m = match(line, rgx.block_tic_table_open)) { -            /+ tic table open +/ -              debug(table) {                             // table (tic) open -                writefln( -                  "%s* [table tic] %s%s", -                  scr_txt_color["blue"], -                  scr_txt_color["off"], -                  line -                ); +            assertions_flag_types_block_status_none_or_closed(type); +            if (match(line, rgx.block_open)) { +              if (match(line, (rgx.block_poem_open))) { +                /+ poem to verse exceptions! +/ +                object_reset(an_object); +                processing.remove("verse"); +                obj_cite_number_poem["start"] = to!string(obj_cite_number);                } -              ft["blocks"] = 1; -              ft["table"] = 1; -              ft["tic_table"] = 1; +              start_block(line, type, obj_cite_number_poem); +              continue;              } else if (!line.empty) { -            /+ line not empty +/ -            /+ non blocks (headers, paragraphs) & closed blocks +/ +              /+ line not empty +/ +              /+ non blocks (headers, paragraphs) & closed blocks +/                assert(                  !line.empty,                  "line tested, line not empty surely"                );                assert( -                (ft["blocks"] == 0) -                || (ft["blocks"] == 2), +                (type["blocks"] == TriState.off) +                || (type["blocks"] == TriState.closing),                  "code block status: none or closed"                ); -              if (ft["blocks"] == 2) { -              // blocks closed, unless followed by book index +              if (type["blocks"] == TriState.closing) { +                // blocks closed, unless followed by book index                  debug(check) {                           // block                    writeln(__LINE__);                    tell_l("red", line); @@ -856,655 +308,98 @@ mixin template SiSUdocAbstraction() {                  assert(                    match(line, rgx.book_index)                    || match(line, rgx.book_index_open) -                  || ft["book_index"] == 1 +                  || type["book_index"] == State.on                  );                } -              if (auto m = match(line, rgx.book_index)) { -              /+ match book_index +/ -                debug(bookindexmatch) {                       // book index -                  writefln( -                    "%s* [bookindex] %s%s\n", -                    scr_txt_color["blue"], -                    scr_txt_color["off"], -                    to!string(m.captures[1]), -                  ); -                  // writeln(scr_txt_marker["blue"], to!string(m.captures[1]), "\n"); -                } -                object["bookindex"] = to!string(m.captures[1]); -              } else if (auto m = match(line, rgx.book_index_open))  { -              /* match open book_index */ -                ft["book_index"] = 1; -                book_idx_tmp = to!string(m.captures[1]); -                debug(bookindexmatch) {                       // book index -                  writefln( -                    "%s* [bookindex] %s%s\n", -                    scr_txt_color["blue"], -                    scr_txt_color["off"], -                    book_idx_tmp, -                  ); -                } -              } else if (ft["book_index"] == 1 )  { -              /+ book_index flag set +/ -                if (auto m = match(line, rgx.book_index_close))  { -                  ft["book_index"] = 0; -                  object["bookindex"] = book_idx_tmp ~ to!string(m.captures[1]); -                  debug(bookindexmatch) {                     // book index -                    writefln( -                      "%s* [bookindex] %s%s\n", -                      scr_txt_color["blue"], -                      scr_txt_color["off"], -                      book_idx_tmp, -                    ); -                  } -                  book_idx_tmp = ""; -                } else { -                  book_idx_tmp ~= line; -                } +              if ((match(line, rgx.book_index)) +              || (match(line, rgx.book_index_open)) +              || (type["book_index"] == State.on ))  { +                /+ book_index +/ +                book_index(line, book_idx_tmp, an_object, type);                } else { -              /+ not book_index +/ +                /+ not book_index +/                  if (auto m = match(line, rgx.comment)) { -                /+ matched comment +/ +                  /+ matched comment +/                    debug(comment) {                      tell_l("blue", line);                    } -                  object["obj"] ~= line ~= "\n"; -                  contents ~= -                    set_oa.contents_comment(strip(object["obj"])); -                  object.remove("obj"); -                  object.remove("markup"); -                  object.remove("is"); -                  object.remove("attrib"); -                  object.remove("bookindex"); +                  an_object["obj"] ~= line ~= "\n"; +                  contents_the_objects ~= +                    set_abstract_object.contents_comment(strip(an_object["obj"])); +                  header_set_common(line_occur, an_object, type);                    processing.remove("verse"); -                  line_occur["header_metadata"] = 0; -                  line_occur["header_make"] = 0; -                  line_occur["heading"] = 0; -                  line_occur["para"] = 0; -                  ft["header"] = 0; -                  ft["header_make"] = 0; -                  ft["header_metadata"] = 0; -                  ft["heading"] = 0; -                  ft["para"] = 0; -                  counter++; -                } else if (auto m = match(line, rgx.header_make)) { -                /+ matched header_make +/ -                  debug(header1) {                          // header -                    tell_l("yellow", line); -                  } -                  ft["header"] = 1; -                  ft["header_make"] = 1; -                  ft["header_metadata"] = 0; -                  ft["heading"] = 0; -                  ft["para"] = 0; -                  line_occur["header_make"]++; -                  object["obj"] ~= line ~= "\n"; -                } else if (auto m = match(line, rgx.header_metadata)) { -                /+ matched header_metadata +/ -                  debug(header1) {                          // header -                    tell_l("yellow", line); -                  } -                  ft["header"] = 1; -                  ft["header_make"] = 0; -                  ft["header_metadata"] = 1; -                  ft["heading"] = 0; -                  ft["para"] = 0; -                  line_occur["header_metadata"]++; -                  object["obj"] ~= line ~= "\n"; -                } else if (ft["header_make"] == 1 -                && (line_occur["header_make"] > 0)) { -                /+ header_make flag set +/ -                  if (auto m = match(line, rgx.header_sub)) { -                  /+ sub-header +/ -                    debug(header1) { -                      tell_l("yellow", line); -                    } -                    line_occur["header_make"]++; -                    object["obj"] ~= line ~= "\n"; -                  } -                } else if (ft["header_metadata"] == 1 -                && (line_occur["header_metadata"] > 0)) { -                /+ header_metadata flag set +/ -                  if (auto m = match(line, rgx.header_sub)) { -                  /+ sub-header +/ -                    debug(header1) { -                      tell_l("yellow", line); -                    } -                    line_occur["header_metadata"]++; -                    object["obj"] ~= line ~= "\n"; -                  } -                } else if (((line_occur["para"] == 0) -                && (line_occur["heading"] == 0)) -                && ((ft["para"] == 0) -                && (ft["heading"] == 0))) { -                /+ heading or para but neither flag nor line exists +/ +                  type["header_make"] = State.off; +                  type["header_metadata"] = State.off; +                  ++counter; +                } else if ((match(line, rgx.header_make)) +                  || (match(line, rgx.header_metadata)) +                  || (type["header_make"] == State.on +                  && (line_occur["header_make"] > State.off)) +                  || (type["header_metadata"] == State.on +                  && (line_occur["header_metadata"] > State.off))) { +                    header_extract(line, line_occur, an_object, type); +                } else if (((line_occur["para"] == State.off) +                && (line_occur["heading"] == State.off)) +                && ((type["para"] == State.off) +                && (type["heading"] == State.off))) { +                  /+ heading or para but neither flag nor line exists +/                    if ((to!string(dochead_make["make"]["headings"]).length > 2) -                  && (ft["make_headings"] == 0)) { -                  /+ headings found +/ -                    debug(headingsfound) { -                      writeln(dochead_make["make"]["headings"]); -                    } -                    auto make_headings_txt = -                      match( -                        to!string(dochead_make["make"]["headings"]), -                        rgx.within_quotes); -                    char[][] make_headings_spl = -                      split( -                        cast(char[]) make_headings_txt.captures[1], -                        rgx.make_heading_delimiter); -                    debug(headingsfound) { -                      writeln(make_headings_spl.length); -                      writeln(make_headings_spl); -                    } -                    switch (make_headings_spl.length) { -                    case 7 : -                      if (!empty(make_headings_spl[6])) { -                        str_h_4 = "^(" ~ to!string(make_headings_spl[6]) ~ ")"; -                        rgx_h_4 = regex(str_h_4); -                      } -                      goto case; -                    case 6 : -                      if (!empty(make_headings_spl[5])) { -                        str_h_3 = "^(" ~ to!string(make_headings_spl[5]) ~ ")"; -                        rgx_h_3 = regex(str_h_3); -                      } -                      goto case; -                    case 5 : -                      if (!empty(make_headings_spl[4])) { -                        str_h_2 = "^(" ~ to!string(make_headings_spl[4]) ~ ")"; -                        rgx_h_2 = regex(str_h_2); -                      } -                      goto case; -                    case 4 : -                      if (!empty(make_headings_spl[3])) { -                        str_h_1 = "^(" ~ to!string(make_headings_spl[3]) ~ ")"; -                        rgx_h_1 = regex(str_h_1); -                      } -                      goto case; -                    case 3 : -                      if (!empty(make_headings_spl[2])) { -                        str_h_D = "^(" ~ to!string(make_headings_spl[2]) ~ ")"; -                        rgx_h_D = regex(str_h_D); -                      } -                      goto case; -                    case 2 : -                      if (!empty(make_headings_spl[1])) { -                        str_h_C = "^(" ~ to!string(make_headings_spl[1]) ~ ")"; -                        rgx_h_C = regex(str_h_C); -                      } -                      goto case; -                    case 1 : -                      if (!empty(make_headings_spl[0])) { -                        str_h_B = "^(" ~ to!string(make_headings_spl[0]) ~ ")"; -                        rgx_h_B = regex(str_h_B); -                      } -                      break; -                    default: -                      break; -                    } -                    ft["make_headings"] = 1; +                  && (type["make_headings"] == State.off)) { +                    /+ heading found +/ +                    auto dochead_make_headings = +                      to!string(dochead_make["make"]["headings"]); +                    heading_found(line, dochead_make_headings, heading_match_str, heading_match_rgx, type);                    } -                  if ((ft["make_headings"] == 1) -                  && ((line_occur["para"] == 0) -                  && (line_occur["heading"] == 0)) -                  && ((ft["para"] == 0) -                  && (ft["heading"] == 0))) { -                  /+ heading make set +/ -                    if (match(line, rgx_h_B)) { -                      line = "B~ " ~ line; -                      debug(headingsfound) { -                        writeln(line); -                      } -                    } -                    if (match(line, rgx_h_C)) { -                      line = "C~ " ~ line; -                      debug(headingsfound) { -                        writeln(line); -                      } -                    } -                    if (match(line, rgx_h_D)) { -                      line = "D~ " ~ line; -                      debug(headingsfound) { -                        writeln(line); -                      } -                    } -                    if (match(line, rgx_h_1)) { -                      line = "1~ " ~ line; -                      debug(headingsfound) { -                        writeln(line); -                      } -                    } -                    if (match(line, rgx_h_2)) { -                      line = "2~ " ~ line; -                      debug(headingsfound) { -                        writeln(line); -                      } -                    } -                    if (match(line, rgx_h_3)) { -                      line = "3~ " ~ line; -                      debug(headingsfound) { -                        writeln(line); -                      } -                    } -                    if (match(line, rgx_h_4)) { -                      line = "4~ " ~ line; -                      debug(headingsfound) { -                        writeln(line); -                      } -                    } +                  if ((type["make_headings"] == State.on) +                  && ((line_occur["para"] == State.off) +                  && (line_occur["heading"] == State.off)) +                  && ((type["para"] == State.off) +                  && (type["heading"] == State.off))) { +                    /+ heading make set +/ +                    heading_make_set(line, line_occur, heading_match_rgx, type);                    }                    if (auto m = match(line, rgx.heading)) { -                  /+ heading match +/ -                    ft["heading"] = 1; -                    ft["header"] = 0; -                    ft["header_make"] = 0; -                    ft["header_metadata"] = 0; -                    ft["heading_biblio"] = 0; -                    ft["para"] = 0; -                    line_occur["heading"]++; -                    object["obj"] ~= line ~= "\n"; -                    object["lev"] ~= m.captures[1]; -                    assertions_doc_structure(object, lv); // includes most of the logic for collapsed levels -                    switch (to!string(object["lev"])) { -                    case "A": -                      object["lvn"]="0"; -                      lv["lv"] = 0; -                      lv["h0"]++; -                      lv["h1"] = 0; -                      lv["h2"] = 0; -                      lv["h3"] = 0; -                      lv["h4"] = 0; -                      lv["h5"] = 0; -                      lv["h6"] = 0; -                      lv["h7"] = 0; -                      collapsed_lev["h0"] = 1; -                      object["lcn"] = to!string(collapsed_lev["h0"]); -                      break; -                    case "B": -                      collapsed_lev["h1"] = collapsed_lev["h0"] + 1; -                      object["lcn"] = to!string(collapsed_lev["h1"]); -                      object["lvn"]="1"; -                      lv["lv"] = 1; -                      lv["h1"]++; -                      lv["h2"] = 0; -                      lv["h3"] = 0; -                      lv["h4"] = 0; -                      lv["h5"] = 0; -                      lv["h6"] = 0; -                      lv["h7"] = 0; -                      break; -                    case "C": -                      collapsed_lev["h2"] = collapsed_lev["h1"] + 1; -                      object["lcn"] = to!string(collapsed_lev["h2"]); -                      object["lvn"]="2"; -                      lv["lv"] = 2; -                      lv["h2"]++; -                      lv["h3"] = 0; -                      lv["h4"] = 0; -                      lv["h5"] = 0; -                      lv["h6"] = 0; -                      lv["h7"] = 0; -                      break; -                    case "D": -                      collapsed_lev["h3"] = collapsed_lev["h2"] + 1; -                      object["lcn"] = to!string(collapsed_lev["h3"]); -                      object["lvn"]="3"; -                      lv["lv"] = 3; -                      lv["h3"]++; -                      lv["h4"] = 0; -                      lv["h5"] = 0; -                      lv["h6"] = 0; -                      lv["h7"] = 0; -                      break; -                    case "1": -                      if (lv["h3"] > 0) { -                        collapsed_lev["h4"] = collapsed_lev["h3"] + 1; -                      } else if (lv["h2"] > 0) { -                        collapsed_lev["h4"] = collapsed_lev["h2"] + 1; -                      } else if (lv["h1"] > 0) { -                        collapsed_lev["h4"] = collapsed_lev["h1"] + 1; -                      } else if (lv["h0"] > 0) { -                        collapsed_lev["h4"] = collapsed_lev["h0"] + 1; -                      } -                      object["lcn"] = to!string(collapsed_lev["h4"]); -                      object["lvn"]="4"; -                      lv["lv"] = 4; -                      lv["h4"]++; -                      lv["h5"] = 0; -                      lv["h6"] = 0; -                      lv["h7"] = 0; -                      break; -                    case "2": -                      if (lv["h5"] > 0) { -                        object["lcn"] = to!string(collapsed_lev["h5"]); -                      } else if (lv["h4"] > 0) { -                        collapsed_lev["h5"] = collapsed_lev["h4"] + 1; -                        object["lcn"] = to!string(collapsed_lev["h5"]); -                      } -                      object["lvn"]="5"; -                      lv["lv"] = 5; -                      lv["h5"]++; -                      lv["h6"] = 0; -                      lv["h7"] = 0; -                      break; -                    case "3": -                      if (lv["h6"] > 0) { -                        object["lcn"] = to!string(collapsed_lev["h6"]); -                      } else if (lv["h5"] > 0) { -                        collapsed_lev["h6"] = collapsed_lev["h5"] + 1; -                        object["lcn"] = to!string(collapsed_lev["h6"]); -                      } -                      object["lvn"]="6"; -                      lv["lv"] = 6; -                      lv["h6"]++; -                      lv["h7"] = 0; -                      break; -                    case "4": -                      if (lv["h7"] > 0) { -                        object["lcn"] = to!string(collapsed_lev["h7"]); -                      } else if (lv["h6"] > 0) { -                        collapsed_lev["h7"] = collapsed_lev["h6"] + 1; -                        object["lcn"] = to!string(collapsed_lev["h7"]); -                      } -                      object["lvn"]="7"; -                      lv["lv"] = 7; -                      lv["h7"]++; -                      break; -                    default: -                      break; -                    } -                    debug(heading) {                         // heading -                      tell_l("yellow", strip(line)); -                    } -                  } else if (line_occur["para"] == 0) { -                  /+ para matches +/ -                    if (auto m = match(line, rgx.para_indent)) { -                      debug(paraindent) {                    // para indent -                        tell_l("blue", line); -                      } -                      ft["para"] = 1; -                      object["obj"] ~= line ~= "\n"; -                      indent_first = to!string(m.captures[1]); -                      indent_second = "0"; -                      bullet = false; -                    } else if (auto m = match(line, rgx.para_bullet)) { -                      debug(parabullet) {                    // para bullet -                        tell_l("blue", line); -                      } -                      ft["para"] = 1; -                      object["obj"] ~= line; -                      indent_first = "0"; -                      indent_second = "0"; -                      bullet = true; -                    } else if (auto m = match(line, rgx.para_indent_hang)) { -                      debug(paraindenthang) {                // para indent hang -                        tell_l("blue", line); -                      } -                      ft["para"] = 1; -                      object["obj"] ~= line; -                      indent_first = to!string(m.captures[1]); -                      indent_second = to!string(m.captures[2]); -                      bullet = false; -                    } else if (auto m = match(line, rgx.para_bullet_indent)) { -                      debug(parabulletindent) {              // para bullet indent -                        tell_l("blue", line); -                      } -                      ft["para"] = 1; -                      object["obj"] ~= line; -                      indent_first = to!string(m.captures[1]); -                      indent_second = "0"; -                      bullet = true; -                    } else { -                      ft["para"] = 1; -                      object["obj"] ~= line; -                      indent_first = "0"; -                      indent_second = "0"; -                      bullet = false; -                    } -                    line_occur["para"]++; +                    /+ heading match +/ +                    heading_match(line, line_occur, an_object, lv, collapsed_lev, type); +                  } else if (line_occur["para"] == State.off) { +                    /+ para match +/ +                    para_match(line, an_object, indent, bullet, type);                    } -                } else if (line_occur["header_make"] > 0) { -                /+ header_make +/ -                // should be caught by sub-header +                } else if (line_occur["header_make"] > State.off) { +                  /+ header_make +/ +                  // should be caught by sub-header                    debug(header) {                      tell_l("red", line);                    } -                  object["obj"] ~= line ~= "\n"; -                  line_occur["header_make"]++; -                } else if (line_occur["header_metadata"] > 0) { -                /+ header_metadata +/ -                // should be caught by sub-header +                  an_object["obj"] ~= line ~= "\n"; +                  ++line_occur["header_make"]; +                } else if (line_occur["header_metadata"] > State.off) { +                  /+ header_metadata +/ +                  // should be caught by sub-header                    debug(header) {                          // para                      tell_l("red", line);                    } -                  object["obj"] ~= line ~= "\n"; -                  line_occur["header_metadata"]++; -                } else if (line_occur["heading"] > 0) { -                /+ heading +/ +                  an_object["obj"] ~= line ~= "\n"; +                  ++line_occur["header_metadata"]; +                } else if (line_occur["heading"] > State.off) { +                  /+ heading +/                    debug(heading) {                         // heading                      tell_l("blue", line);                    } -                  object["obj"] ~= line ~= "\n"; -                  line_occur["heading"]++; -                } else if (line_occur["para"] > 0) { -                /+ paragraph +/ +                  an_object["obj"] ~= line ~= "\n"; +                  ++line_occur["heading"]; +                } else if (line_occur["para"] > State.off) { +                  /+ paragraph +/                    debug(para) {                      tell_l("blue", line);                    } -                  object["obj"] ~= line; -                  line_occur["para"]++; +                  an_object["obj"] ~= line; +                  ++line_occur["para"];                  }                } -            } else if (ft["blocks"] == 2) { -            /+ line empty, with blocks flag +/ -              assert( -                line.empty, -                "line should be empty" -              ); -              assert( -                (ft["blocks"] == 2), -                "code block status: closed" -              ); -              assertions_flag_types_block_status_none_or_closed(ft); -              if (ft["code"] == 2) { -                ocn = ocn_emit(ft["ocn_status"]); -                object["bookindex"] = -                  ("bookindex" in object) ? object["bookindex"] : ""; -                bookindex_unordered_hashes = -                  bkidx_hash(object["bookindex"], ocn); -                object["is"] = "code"; -                node = -                  node_jstr( -                    content_non_header, -                    ocn, -                    counter, -                    heading_pointer-1, -                    object["is"] -                  ); -                object["markup"] = -                  obj_im.obj_inline_markup(object["is"], object["obj"]); -                object["attrib"] = -                  obj_att.obj_attributes(object["is"], object["obj"], node); -                contents ~= -                  set_oa.contents_block( -                    object["is"], -                    object["markup"], -                    object["attrib"], -                    ocn -                  ); -                object.remove("obj"); -                object.remove("markup"); -                object.remove("is"); -                object.remove("attrib"); -                object.remove("bookindex"); -                processing.remove("verse"); -                counter++; -                ft["blocks"] = 0; -                ft["code"] = 0; -              } else if (ft["poem"] == 2) { -                object["bookindex"] = -                  ("bookindex" in object) ? object["bookindex"] : ""; -                bookindex_unordered_hashes = -                  bkidx_hash(object["bookindex"], ocn); -                object["is"] = "verse"; // check also -                node = -                  node_jstr( -                    content_non_header, -                    ocn, -                    counter, -                    heading_pointer-1, -                    object["is"] -                  ); -                contents ~= -                  set_oa.contents_block_ocn_string( -                    "poem", -                    "", -                    (ocn_poem["start"], ocn_poem["end"]), -                    node -                  ); // bookindex -                object.remove("obj"); -                object.remove("markup"); -                object.remove("is"); -                object.remove("attrib"); -                object.remove("bookindex"); -                processing.remove("verse"); -                ft["blocks"] = 0; -                ft["poem"] = 0; -              } else if (ft["table"] == 2) { -                ocn = ocn_emit(ft["ocn_status"]); -                object["bookindex"] = -                  ("bookindex" in object) ? object["bookindex"] : ""; -                bookindex_unordered_hashes = -                  bkidx_hash(object["bookindex"], ocn); -                object["is"] = "table"; -                node = -                  node_jstr( -                    content_non_header, -                    ocn, -                    counter, -                    heading_pointer-1, -                    object["is"] -                  ); -                object["markup"] = -                  obj_im.obj_inline_markup(object["is"], object["obj"]); -                object["attrib"] = -                  obj_att.obj_attributes(object["is"], object["obj"], node); -                contents ~= -                  set_oa.contents_block( -                    object["is"], -                    object["markup"], -                    object["attrib"], -                    ocn -                  ); -                object.remove("obj"); -                object.remove("markup"); -                object.remove("is"); -                object.remove("attrib"); -                object.remove("bookindex"); -                processing.remove("verse"); -                counter++; -                ft["blocks"] = 0; -                ft["table"] = 0; -              } else if (ft["group"] == 2) { -                ocn = ocn_emit(ft["ocn_status"]); -                object["bookindex"] = ("bookindex" in object) ? object["bookindex"] : ""; -                bookindex_unordered_hashes = bkidx_hash(object["bookindex"], ocn); -                object["is"] = "group"; -                node = -                  node_jstr( -                    content_non_header, -                    ocn, -                    counter, -                    heading_pointer-1, -                    object["is"] -                  ); -                object["markup"] = -                  obj_im.obj_inline_markup(object["is"], object["obj"]); -                object["attrib"] = -                  obj_att.obj_attributes(object["is"], object["obj"], node); -                contents ~= -                  set_oa.contents_block( -                    object["is"], -                    object["markup"], -                    object["attrib"], -                    ocn -                  ); -                object.remove("obj"); -                object.remove("markup"); -                object.remove("is"); -                object.remove("attrib"); -                object.remove("bookindex"); -                processing.remove("verse"); -                counter++; -                ft["blocks"] = 0; -                ft["group"] = 0; -              } else if (ft["block"] == 2) { -                ocn = ocn_emit(ft["ocn_status"]); -                object["bookindex"] = ("bookindex" in object) ? object["bookindex"] : ""; -                bookindex_unordered_hashes = bkidx_hash(object["bookindex"], ocn); -                object["is"] = "block"; -                node = -                  node_jstr( -                    content_non_header, -                    ocn, -                    counter, -                    heading_pointer-1, -                    object["is"] -                   ); -                object["markup"] = -                  obj_im.obj_inline_markup(object["is"], object["obj"]); -                object["attrib"] = -                  obj_att.obj_attributes(object["is"], object["obj"], node); -                contents ~= -                  set_oa.contents_block( -                    object["is"], -                    object["markup"], -                    object["attrib"], -                    ocn -                  ); -                object.remove("obj"); -                object.remove("markup"); -                object.remove("is"); -                object.remove("attrib"); -                object.remove("bookindex"); -                processing.remove("verse"); -                counter++; -                ft["blocks"] = 0; -                ft["block"] = 0; -              } else if (ft["quote"] == 2) { -                ocn = ocn_emit(ft["ocn_status"]); -                object["bookindex"] = ("bookindex" in object) ? object["bookindex"] : ""; -                bookindex_unordered_hashes = -                  bkidx_hash(object["bookindex"], ocn); -                object["is"] = "quote"; -                node = -                  node_jstr( -                    content_non_header, -                    ocn, -                    counter, -                    heading_pointer-1, -                    object["is"] -                  ); -                object["markup"] = -                  obj_im.obj_inline_markup(object["is"], object["obj"]); -                object["attrib"] = -                  obj_att.obj_attributes(object["is"], object["obj"], node); -                contents ~= -                  set_oa.contents_block( -                    object["is"], -                    object["markup"], -                    object["attrib"], -                    ocn -                  ); -                object.remove("obj"); -                object.remove("markup"); -                object.remove("is"); -                object.remove("attrib"); -                object.remove("bookindex"); -                processing.remove("verse"); -                counter++; -                ft["blocks"] = 0; -                ft["quote"] = 0; -              } +            } else if (type["blocks"] == TriState.closing) { +              /+ line empty, with blocks flag +/ +              block_flag_line_empty(line, an_object, contents_the_objects, bookindex_unordered_hashes, obj_cite_number, node, counter, type, obj_cite_number_poem); // watch              } else {              /+ line empty +/                /+ line.empty, post contents, empty variables: +/ @@ -1513,156 +408,122 @@ mixin template SiSUdocAbstraction() {                  "line should be empty"                );                assert( -                (ft["blocks"] == 0), +                (type["blocks"] == State.off),                  "code block status: none"                ); -              if ((ft["header_make"] == 1) -              && (line_occur["header_make"] > 0)) { -              /+ header_make instructions (current line empty) +/ +              if ((type["header_make"] == State.on) +              && (line_occur["header_make"] > State.off)) { +                /+ header_make instructions (current line empty) +/                  auto dochead_metadata_and_make = -                  set_header.header_metadata_and_make_jsonstr(strip(object["obj"]), dochead_metadata, dochead_make); +                  set_header.header_metadata_and_make_jsonstr(strip(an_object["obj"]), dochead_metadata, dochead_make);                  static assert(!isTypeTuple!(dochead_metadata_and_make));                  dochead_metadata = dochead_metadata_and_make[0];                  dochead_make = dochead_metadata_and_make[1]; -                line_occur["header_make"] = 0; -                line_occur["header_metadata"] = 0; -                line_occur["heading"] = 0; -                line_occur["para"]= 0; -                ft["header"] = 0; -                ft["heading"] = 0; -                ft["para"] = 0; -                object.remove("obj"); -                object.remove("markup"); -                object.remove("is"); -                object.remove("attrib"); -                object.remove("bookindex"); +                header_set_common(line_occur, an_object, type);                  processing.remove("verse"); -              } else if ((ft["header_metadata"] == 1) -              && (line_occur["header_metadata"] > 0)) { -              /+ header_metadata (current line empty) +/ +              } else if ((type["header_metadata"] == State.on) +              && (line_occur["header_metadata"] > State.off)) { +                /+ header_metadata (current line empty) +/                  auto dochead_metadata_and_make = -                  set_header.header_metadata_and_make_jsonstr(strip(object["obj"]), dochead_metadata, dochead_make); +                  set_header.header_metadata_and_make_jsonstr(strip(an_object["obj"]), dochead_metadata, dochead_make);                  static assert(!isTypeTuple!(dochead_metadata_and_make));                  dochead_metadata = dochead_metadata_and_make[0];                  dochead_make = dochead_metadata_and_make[1]; -                line_occur["header_make"] = 0; -                line_occur["header_metadata"] = 0; -                line_occur["heading"] = 0; -                line_occur["para"]= 0; -                ft["header"] = 0; -                ft["header_make"] = 0; -                ft["header_metadata"] = 0; -                ft["heading"] = 0; -                ft["para"] = 0; -                object.remove("obj"); -                object.remove("markup"); -                object.remove("is"); -                object.remove("attrib"); -                object.remove("bookindex"); +                header_set_common(line_occur, an_object, type); +                type["header_make"] = State.off; +                type["header_metadata"] = State.off;                  processing.remove("verse"); -              } else if ((ft["heading"] == 1) -              && (line_occur["heading"] > 0)) { -              /+ heading object (current line empty) +/ -                ocn = ocn_emit(ft["ocn_status"]); -                object["bookindex"] = -                  ("bookindex" in object) ? object["bookindex"] : ""; +              } else if ((type["heading"] == State.on) +              && (line_occur["heading"] > State.off)) { +                /+ heading object (current line empty) +/ +                obj_cite_number = obj_cite_number_emit(type["obj_cite_number_status"]); +                an_object["bookindex"] = +                  ("bookindex" in an_object) ? an_object["bookindex"] : "";                  bookindex_unordered_hashes = -                  bkidx_hash(object["bookindex"], ocn); -                object["is"] = "heading"; +                  bkidx_hash(an_object["bookindex"], obj_cite_number); +                an_object["is"] = "heading";                  node =                    node_jstr_heading( -                    object["lvn"], -                    object["lcn"], -                    ocn, +                    an_object["lev_markup_number"], +                    an_object["lev_collapsed_number"], +                    obj_cite_number,                      counter,                      heading_pointer, -                    object["is"] +                    an_object["is"]                    ); // heading -                object["markup"] = -                  obj_im.obj_inline_markup(object["is"], object["obj"]); -                object["attrib"] = -                  obj_att.obj_attributes(object["is"], object["obj"], node); -                heading_pointer++; -                contents ~= -                  set_oa.contents_heading( -                    ft["ocn_status"], -                    object["markup"], -                    object["attrib"], -                    ocn, object["lev"], -                    object["lvn"], -                    object["lcn"] +                an_object["substantive"] = +                  obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +                an_object["attrib"] = +                  obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +                ++heading_pointer; +                contents_the_objects ~= +                  set_abstract_object.contents_heading( +                    type["obj_cite_number_status"], +                    an_object["substantive"], +                    an_object["attrib"], +                    obj_cite_number, an_object["lev"], +                    an_object["lev_markup_number"], +                    an_object["lev_collapsed_number"]                    );                  // track previous heading and make assertions                  debug(objectrelated1) { // check                    tell_l("blue", line); +                  // writeln(an_object["obj"]); +                  // writeln(contents_am[counter]["obj_cite_number"], " ", contents_am[counter]["obj"]); +                  // writeln(m.hit, "\n");                  } -                line_occur["header_make"] = 0; -                line_occur["header_metadata"] = 0; -                line_occur["heading"] = 0; -                line_occur["para"] = 0; -                ft["header"] = 0; -                ft["header_make"] = 0; -                ft["header_metadata"] = 0; -                ft["heading"] = 0; -                ft["para"] = 0; -                object.remove("obj"); -                object.remove("markup"); -                object.remove("is"); -                object.remove("attrib"); -                object.remove("lev"); -                object.remove("lvn"); -                object.remove("bookindex"); +                header_set_common(line_occur, an_object, type); +                type["header_make"] = State.off; +                type["header_metadata"] = State.off; +                an_object.remove("lev"); +                an_object.remove("lev_markup_number"); +                // an_object["lev_markup_number"]="9";                  processing.remove("verse"); -                counter++; -              } else if ((ft["para"] == 1) && (line_occur["para"] > 0)) { -              /+ paragraph object (current line empty) +/ -                ocn = ocn_emit(ft["ocn_status"]); -                object["bookindex"] = -                  ("bookindex" in object) ? object["bookindex"] : ""; +                ++counter; +              } else if ((type["para"] == State.on) && (line_occur["para"] > State.off)) { +                /+ paragraph object (current line empty) +/ +                obj_cite_number = obj_cite_number_emit(type["obj_cite_number_status"]); +                an_object["bookindex"] = +                  ("bookindex" in an_object) ? an_object["bookindex"] : "";                  bookindex_unordered_hashes = -                  bkidx_hash(object["bookindex"], ocn); -                object["is"] = "para"; +                  bkidx_hash(an_object["bookindex"], obj_cite_number); +                an_object["is"] = "para";                  node =                    node_jstr(                      content_non_header, -                    ocn, +                    obj_cite_number,                      counter,                      heading_pointer-1, -                    object["is"] +                    an_object["is"]                    ); -                object["markup"] = -                  obj_im.obj_inline_markup(object["is"], object["obj"]); -                object["attrib"] = -                  obj_att.obj_attributes(object["is"], object["obj"], node); -                contents ~= -                  set_oa.contents_para( -                    object["is"], -                    object["markup"], -                    object["attrib"], -                    ocn, -                    indent_first, -                    indent_second, +                an_object["substantive"] = +                  obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +                an_object["attrib"] = +                  obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +                contents_the_objects ~= +                  set_abstract_object.contents_para( +                    an_object["is"], +                    an_object["substantive"], +                    an_object["attrib"], +                    obj_cite_number, +                    indent,                      bullet                    ); -                line_occur["header_make"] = 0; -                line_occur["header_metadata"] = 0; -                line_occur["heading"] = 0; -                line_occur["para"] = 0; -                ft["header"] = 0; -                ft["header_make"] = 0; -                ft["header_metadata"] = 0; -                ft["heading"] = 0; -                ft["para"] = 0; -                indent_first = "0"; -                indent_second = "0"; +                // contents_the_objects ~= +                //   set_abstract_object.contents_para( +                //     an_object, +                //     obj_cite_number, +                //     indent, +                //     bullet +                //   ); +                header_set_common(line_occur, an_object, type); +                type["header_make"] = State.off; +                type["header_metadata"] = State.off; +                indent["first"] = "0"; +                indent["second"] = "0";                  bullet = false; -                object.remove("obj"); -                object.remove("markup"); -                object.remove("is"); -                object.remove("attrib"); -                object.remove("bookindex");                  processing.remove("verse"); -                counter++; +                ++counter;                } else {                  assert(                    line == null, @@ -1673,25 +534,32 @@ mixin template SiSUdocAbstraction() {              } // close else for line empty            } // close else for not the above          } // close after non code, other blocks or regular text -        if (((contents[$-1]["is"] == "para") -        || (contents[$-1]["is"] == "heading")) +        if (((contents_the_objects[$-1]["is"] == "para") +        || (contents_the_objects[$-1]["is"] == "heading"))          && (counter-1 > previous_count)) { -          if (match(contents[$-1]["obj"], +          if (match(contents_the_objects[$-1]["obj"],            rgx.inline_notes_delimiter_al_regular_number_note)) {              // endnotes/ footnotes for              // doc objects other than paragraphs & headings              // various forms of grouped text -            previous_count=contents.length -1; -            notesection.gather_notes_for_endnote_section( -              contents, -              contents.length -1 +            previous_count=contents_the_objects.length -1; +            note_section.gather_notes_for_endnote_section( +              contents_the_objects, +              contents_the_objects.length -1              ); +            // notes[notepoint]=note_section.notes_section(contents_the_objects, counter-1); +            // notepoint +=1;            }          }        } /+ ← closed: loop markup document/text line by line +/ +        /+ ↓ post loop markup document/text +/        debug(objectrelated2) { // check            tell_l("blue", line); +        // writeln(__FILE__, ":", __LINE__); +        // writeln(counter); +        // // contents_am[0..counter] +        // writeln(contents_am.length);        }        /+          Backmatter: @@ -1701,93 +569,3192 @@ mixin template SiSUdocAbstraction() {          * book index        +/        obj_im.obj_inline_markup("doc_end_reset", ""); -      auto en_tuple = notesection.endnote_objects(ocn); +      auto en_tuple = +        note_section.endnote_objects(obj_cite_number);        static assert(!isTypeTuple!(en_tuple)); -      auto endnotes = en_tuple[0]; -      ocn = en_tuple[1]; +      auto endnotes_section = en_tuple[0]; +      obj_cite_number = en_tuple[1];        debug(endnotes) {          writefln(            "%s %s",            __LINE__, -          endnotes.length +          endnotes_section.length          ); -        foreach (n; endnotes) { +        foreach (n; endnotes_section) {            writeln(n);          }        }        auto biblio_unsorted_incomplete = biblio_arr_json.dup; +      // destroy(biblio_arr_json);        auto biblio = Bibliography(); -      auto biblio_ordered = biblio.bibliography(biblio_unsorted_incomplete, bib_arr_json); +      auto biblio_ordered = +        biblio.bibliography(biblio_unsorted_incomplete, bib_arr_json);        auto bi = BookIndexReportSection();        auto bi_tuple = -        bi.bookindex_build_section(bookindex_unordered_hashes, ocn); +        bi.bookindex_build_section(bookindex_unordered_hashes, obj_cite_number);        static assert(!isTypeTuple!(bi_tuple)); -      auto bookindex = bi_tuple[0]; -      auto document = contents ~ endnotes ~ bookindex; -      ocn = bi_tuple[1]; +      auto bookindex_section = bi_tuple[0]; +      obj_cite_number = bi_tuple[1];        debug(bookindex) {                         // bookindex -        foreach (bi_entry; bookindex) { +        foreach (bi_entry; bookindex_section) {            writeln(bi_entry["obj"]);          }        } +      auto document_the = +        contents_the_objects ~ endnotes_section ~ bookindex_section;        debug(heading) {                         // heading          string spc; -        foreach (o; document) { +        foreach (o; document_the) {            if (o["is"] == "heading") { -            switch (o["lvn"]) { +            switch (o["lev_markup_number"]) {              case "0": +            // case to!string(DocStructMarkupHeading.h_sect_A):                spc="";                break;              case "1": +            // case to!string(DocStructMarkupHeading.h_sect_B):                spc="  ";                break;              case "2": +            // case to!string(DocStructMarkupHeading.h_sect_C):                spc="    ";                break;              case "3": +            // case to!string(DocStructMarkupHeading.h_sect_D):                spc="      ";                break;              case "4": +            // case to!string(DocStructMarkupHeading.h_text_1):                spc="        ";                break;              case "5": +            // case to!string(DocStructMarkupHeading.h_text_2):                spc="          ";                break;              case "6": +            // case to!string(DocStructMarkupHeading.h_text_3):                spc="            ";                break;              case "7": +            // case to!string(DocStructMarkupHeading.h_text_4):                spc="              ";                break;              case "8": +            // case to!string(DocStructMarkupHeading.h_text_5):                spc="                ";                break;              default:                spc="";                break;              } +            // writeln( +            //   spc, "* ", " ", +            //   o +            // );              writefln(                "%s*  $s\n            %s",                spc,                strip(o["obj"]),                o["attrib"]              ); +            // writeln(spc, "* ", to!string(o["lev_collapsed_number"]), " ", strip(o["obj"]));              // tell_l("yellow", spc, strip(o["obj"]));            }          }        } -      destroy(contents); -      destroy(endnotes); -      destroy(bookindex); +      destroy(contents_the_objects); +      destroy(endnotes_section); +      destroy(bookindex_section); +      // struct Document { +      //   char content; +      //   char head_make; +      //   char head_metadata; +      //   char bookindex_section; +      //   char biblio; +      // } +      // struct Document { +      //   char content; +      //   char head_make; +      //   char head_metadata; +      //   char bookindex_section; +      //   char biblio; +      // }        auto t =          tuple( -          document, +          document_the,            dochead_make,            dochead_metadata,            bookindex_unordered_hashes,            biblio_ordered          );        return t; +      /+ post loop markup document/text ↑ +/ + +    } /+ ← closed: abstract doc source +/ + +    /+ ↓ abstraction functions +/ +    auto object_reset(ref string[string] an_object) { +      an_object.remove("obj"); +      an_object.remove("substantive"); +      an_object.remove("is"); +      an_object.remove("attrib"); +      an_object.remove("bookindex"); +    } +    auto header_set_common( +      ref int[string] line_occur, +      ref string[string] an_object, +      ref int[string] type +    ) { +      // line_occur["header"] = State.off; +      line_occur["header_make"] = State.off; +      line_occur["header_metadata"] = State.off; +      line_occur["heading"] = State.off; +      line_occur["para"]= State.off; +      type["header"] = State.off; +      // type["header_make"] = State.off; +      // type["header_metadata"] = State.off; +      type["heading"] = State.off; +      type["para"] = State.off; +      object_reset(an_object); +    } +    auto check_obj_cite_number_status(char[] line, ref int[string] type) { +      if ((!line.empty) && (type["obj_cite_number_status_multi_obj"] == TriState.off)) { +        /+ not multi-line object, check whether obj_cite_number is on or turned off +/ +        if (match(line, rgx.obj_cite_number_block_marks)) { +          /+ switch off obj_cite_number +/ +          if (match(line, rgx.obj_cite_number_off_block)) { +            type["obj_cite_number_status_multi_obj"] = TriState.on; +            debug(ocnoff) { +              tell_l("fuchsia", line); +            } +          } +          if (match(line, rgx.obj_cite_number_off_block_dh)) { +            type["obj_cite_number_status_multi_obj"] = TriState.closing; +            debug(ocnoff) { +              tell_l("fuchsia", line); +            } +          } +        } else { +          if (type["obj_cite_number_status_multi_obj"] == TriState.off) { +            if (match(line, rgx.obj_cite_number_off)) { +              type["obj_cite_number_status"] = TriState.on; +            } else if (match(line, rgx.obj_cite_number_off_dh)) { +              type["obj_cite_number_status"] = TriState.closing; +            } else { +              // type["obj_cite_number_status"] = TriState.closing; +              type["obj_cite_number_status"] = TriState.off; +            } +          } else { +            type["obj_cite_number_status"] = +              type["obj_cite_number_status_multi_obj"]; +          } +        } +      } else if ((!line.empty) && (type["obj_cite_number_status_multi_obj"] > TriState.off)) { +        if (auto m = match(line, rgx.obj_cite_number_off_block_close)) { +          type["obj_cite_number_status_multi_obj"] = TriState.off; +          type["obj_cite_number_status"] = TriState.off; +          debug(ocnoff) { +            tell_l("green", line); +          } +        } +      } +      return 0; +    } +    auto start_block( +      char[] line, +      ref int[string] type, +      string[string] obj_cite_number_poem +    ) { +      if (match(line, rgx.block_curly_code_open)) { +        /+ curly code open +/ +        debug(code) {                              // code (curly) open +          writefln( +            "%s* [code curly] %s%s", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            line +          ); +        } +        type["blocks"] = TriState.on; +        type["code"] = TriState.on; +        type["curly_code"] = TriState.on; +      } else if (match(line, rgx.block_curly_poem_open)) { +        /+ curly poem open +/ +        debug(poem) {                              // poem (curly) open +          writefln( +            "%s* [poem curly] %s%s", +            scr_txt_color["red"], +            scr_txt_color["off"], +            line +          ); +        } +        obj_cite_number_poem["start"] = +          to!string(obj_cite_number); +        type["blocks"] = TriState.on; +        type["verse_new"] = State.on; +        type["poem"] = TriState.on; +        type["curly_poem"] = TriState.on; +      } else if (match(line, rgx.block_curly_group_open)) { +        /+ curly group open +/ +        debug(group) {                             // group (curly) open +          writefln( +            "%s* [group curly] %s%s", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            line +          ); +        } +        type["blocks"] = TriState.on; +        type["group"] = TriState.on; +        type["curly_group"] = TriState.on; +      } else if (match(line, rgx.block_curly_block_open)) { +        /+ curly block open +/ +        debug(block) {                             // block (curly) open +          writefln( +            "%s* [block curly] %s%s", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            line +          ); +        } +        type["blocks"] = TriState.on; +        type["block"] = TriState.on; +        type["curly_block"] = TriState.on; +      } else if (match(line, rgx.block_curly_quote_open)) { +        /+ curly quote open +/ +        debug(quote) {                             // quote (curly) open +          writefln( +            "%s* [quote curly] %s%s", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            line +          ); +        } +        type["blocks"] = TriState.on; +        type["quote"] = TriState.on; +        type["curly_quote"] = TriState.on; +      } else if (match(line, rgx.block_curly_table_open)) { +        /+ curly table open +/ +        debug(table) {                             // table (curly) open +          writefln( +            "%s* [table curly] %s%s", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            line +          ); +        } +        type["blocks"] = TriState.on; +        type["table"] = TriState.on; +        type["curly_table"] = TriState.on; +      } else if (match(line, rgx.block_tic_code_open)) { +        /+ tic code open +/ +        debug(code) {                              // code (tic) open +          writefln( +            "%s* [code tic] %s%s", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            line +          ); +        } +        type["blocks"] = TriState.on; +        type["code"] = TriState.on; +        type["tic_code"] = TriState.on; +      } else if (match(line, rgx.block_tic_poem_open)) { +        /+ tic poem open +/ +        debug(poem) {                              // poem (tic) open +          writefln( +            "%s* [poem tic] %s%s", +            scr_txt_color["red"], +            scr_txt_color["off"], +            line +          ); +        } +        obj_cite_number_poem["start"] = to!string(obj_cite_number); +        type["blocks"] = TriState.on; +        type["verse_new"] = State.on; +        type["poem"] = TriState.on; +        type["tic_poem"] = TriState.on; +      } else if (match(line, rgx.block_tic_group_open)) { +        /+ tic group open +/ +        debug(group) {                             // group (tic) open +          writefln( +            "%s* [group tic] %s%s", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            line +          ); +        } +        type["blocks"] = TriState.on; +        type["group"] = TriState.on; +        type["tic_group"] = TriState.on; +      } else if (match(line, rgx.block_tic_block_open)) { +        /+ tic block open +/ +        debug(block) {                             // block (tic) open +          writefln( +            "%s* [block tic] %s%s", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            line +          ); +        } +        type["blocks"] = TriState.on; +        type["block"] = TriState.on; +        type["tic_block"] = TriState.on; +      } else if (match(line, rgx.block_tic_quote_open)) { +        /+ tic quote open +/ +        debug(quote) {                             // quote (tic) open +          writefln( +            "%s* [quote tic] %s%s", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            line +          ); +        } +        type["blocks"] = TriState.on; +        type["quote"] = TriState.on; +        type["tic_quote"] = TriState.on; +      } else if (match(line, rgx.block_tic_table_open)) { +        /+ tic table open +/ +        debug(table) {                             // table (tic) open +          writefln( +            "%s* [table tic] %s%s", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            line +          ); +        } +        type["blocks"] = TriState.on; +        type["table"] = TriState.on; +        type["tic_table"] = TriState.on; +      } +      return 0; +    } +    auto code_block( +      char[] line, +      ref string[string] an_object, +      ref int[string] type +    ) { +      if (type["curly_code"] == TriState.on) { +        if (auto m = match(line, rgx.block_curly_code_close)) { +          debug(code) {                              // code (curly) close +            tell_l("blue", line); +          } +          type["blocks"] = TriState.closing; +          type["code"] = TriState.closing; +          type["curly_code"] = TriState.off; +        } else { +          debug(code) {                              // code (curly) line +            tell_l("blue", line); +          } +          an_object["obj"] ~= line ~= "\n";                       // code (curly) line +        } +      } else if (type["tic_code"] == TriState.on) { +        if (auto m = match(line, rgx.block_tic_close)) { +          debug(code) {                              // code (tic) close +            tell_l("blue", line); +          } +          type["blocks"] = TriState.closing; +          type["code"] = TriState.closing; +          type["tic_code"] = TriState.off; +        } else { +          debug(code) {                              // code (tic) line +            tell_l("blue", line); +          } +          an_object["obj"] ~= line ~= "\n";                       // code (tic) line +        } +      } +      return 0; +    } +    final 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]; +    } +    auto biblio_block( +      char[] line, +      ref int[string] type, +      ref int bib_entry, +      ref string[] biblio_arr_json +    ) { +      if (match(line, rgx.heading_biblio)) { +        type["heading_biblio"] = TriState.on; +      } +      if (empty(line) && (bib_entry == TriState.off)) { +        biblio_arr_json ~= biblio_entry_tags_jsonstr; +        bib_entry = TriState.on; +      } +      debug(biblio) { +        writefln( +          "%s * %s %s", +          scr_txt_color["yellow"], +          scr_txt_color["off"], +          line +        ); +      } +      if (match(line, rgx.biblio_tags)) { +        auto bt = match(line, rgx.biblio_tags); +        bib_entry = 0; +        st=to!string(bt.captures[1]); +        biblio_tag_entry=to!string(bt.captures[2]); +        JSONValue j = parseJSON(biblio_arr_json[$-1]); +        biblio_tag_name = (match(st, rgx.biblio_abbreviations)) +          ? (biblio_tag_map(st)) +          : st; +        j.object[biblio_tag_name] = biblio_tag_entry; +        auto header_tag_value=to!string(bt.captures[2]); +        switch (biblio_tag_name) { +        case "author_raw": // author_arr author (fn sn) +          j["author_arr"] = +            split(header_tag_value, rgx.arr_delimiter); +          string tmp; +          biblioAuthorLoop: +          foreach (au; j["author_arr"].array) { +            if (auto x = match(au.str, rgx.name_delimiter)) { +              tmp ~= x.captures[2] ~ " " ~ x.captures[1] ~ ", "; +            } else { +              tmp ~= au.str; +            } +          } +          tmp = replace(tmp, rgx.trailing_comma, ""); +          // tmp = replace(tmp, regex(r"(,[ ]*)$","g"), ""); +          j["author"].str = tmp; +          break; +        case "editor_raw": // editor_arr editor (fn sn) +          j["editor_arr"] = +            split(header_tag_value, rgx.arr_delimiter); +          string tmp; +          biblioEditorLoop: +          foreach (ed; j["editor_arr"].array) { +            if (auto x = match(ed.str, rgx.name_delimiter)) { +              tmp ~= x.captures[2] ~ " " ~ x.captures[1] ~ ", "; +            } else { +              tmp ~= ed.str; +            } +          } +          tmp = replace(tmp, rgx.trailing_comma, ""); +          // tmp = replace(tmp, regex(r"(,[ ]*)$","g"), ""); +          j["editor"].str = tmp; +          break; +        case "fulltitle": // title & subtitle +          break; +        default: +          break; +        } +        // header_tag_value=""; +        auto s = to!string(j); +        s = j.toString(); +        debug(biblio) { +          writefln( +            "%s* %s%s: %s\n%s", +            scr_txt_color["red"], +            scr_txt_color["off"], +            biblio_tag_name, +            biblio_tag_entry, +            j[biblio_tag_name] +          ); +        } +        biblio_arr_json ~= s; +        biblio_tag_entry=""; +      } +      return 0; +    } +    auto poem_block( +      char[] line, +      ref string[string] an_object, +      ref int[string] type, +      ref long counter, +      string[string] obj_cite_number_poem +    ) { +      if (type["curly_poem"] == TriState.on) { +        if (auto m = match(line, rgx.block_curly_poem_close)) { +          an_object["obj"]="verse"; // check that this is as you please +          debug(poem) {                            // poem (curly) close +            writefln( +              "%s* [poem curly] %s%s", +              scr_txt_color["red"], +              scr_txt_color["off"], +              line +            ); +          } +          if (processing.length > 0) { +            an_object["obj"] = processing["verse"]; +          } +          debug(poem) {                            // poem (curly) close +            writeln(__LINE__); +            writefln( +              "%s%s %s", +              scr_txt_marker["fuchsia"], +              obj_cite_number, +              line +            ); +            // writeln(an_object.keys); +            // writeln(an_object.length); +          } +          if (an_object.length > 0) { +            debug(poem) {                            // poem (curly) close +              tell_lo( +                "fuchsia", +                obj_cite_number, +                an_object["obj"] +              ); +            } +            an_object["is"] = "verse"; +            an_object["substantive"] = +              obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +            an_object["attrib"] = +              obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +            contents_the_objects ~= +              set_abstract_object.contents_block( +                an_object["is"], +                an_object["substantive"], +                an_object["attrib"], +                obj_cite_number +              ); +            object_reset(an_object); +            processing.remove("verse"); +            ++counter; +          } +          obj_cite_number_poem["end"] = +            to!string(obj_cite_number); +          type["blocks"] = TriState.closing; +          type["poem"] = TriState.closing; +          type["curly_poem"] = TriState.off; +        } else { +          processing["verse"] ~= line ~= "\n"; +          if (type["verse_new"] == State.on) { +            obj_cite_number = +              obj_cite_number_emit(type["obj_cite_number_status"]); +            type["verse_new"] = State.off; +          } else if (match(line, rgx.line_delimiter_only)) { +            verse_line = TriState.off; +            type["verse_new"] = State.on; +          } +          if (type["verse_new"] == State.on) { +            verse_line=1; +            an_object["obj"] = processing["verse"]; +            debug(poem) {                          // poem verse +              writefln( +                "%s%s curly\n%s", +                scr_txt_marker["green"], +                obj_cite_number, +                an_object["obj"] +              ); +            } +            processing.remove("verse"); +            an_object["is"] = "verse"; +            node = node_jstr( +              content_non_header, +              obj_cite_number, +              counter, +              heading_pointer-1, +              an_object["is"] +            ); +            an_object["substantive"] = +              obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +            an_object["attrib"] = +              obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +            contents_the_objects ~= +              set_abstract_object.contents_block( +                an_object["is"], +                an_object["substantive"], +                an_object["attrib"], +                obj_cite_number +              ); +            object_reset(an_object); +            processing.remove("verse"); +            ++counter; +          } +        } +      } else if (type["tic_poem"] == TriState.on) { +        if (auto m = match(line, rgx.block_tic_close)) { // tic_poem_close +          an_object["obj"]="verse"; // check that this is as you please +          debug(poem) {                            // poem (curly) close +            writefln( +              "%s* [poem tic] %s%s", +              scr_txt_color["red"], +              scr_txt_color["off"], +              line +            ); +          } +          if (processing.length > 0) {       // needs looking at +            an_object["obj"] = processing["verse"]; +          } +          if (an_object.length > 0) { +            debug(poem) {                            // poem (tic) close +              writeln(__LINE__); +              tell_lo("fuchsia", obj_cite_number, line); +            } +            processing.remove("verse"); +            an_object["is"] = "verse"; +            an_object["substantive"] = +              obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +            an_object["attrib"] = +              obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +            contents_the_objects ~= +              set_abstract_object.contents_block( +                an_object["is"], +                an_object["substantive"], +                an_object["attrib"], +                obj_cite_number +              ); +            obj_cite_number_poem["end"] = to!string(obj_cite_number); +            object_reset(an_object); +            processing.remove("verse"); +            ++counter; +          } +          type["blocks"] = TriState.closing; +          type["poem"] = TriState.closing; +          type["tic_poem"] = TriState.off; +        } else { +          processing["verse"] ~= line ~= "\n"; +          if (type["verse_new"] == State.on) { +            obj_cite_number = +              obj_cite_number_emit(type["obj_cite_number_status"]); +            type["verse_new"] = State.off; +          } else if (match(line, rgx.line_delimiter_only)) { +            type["verse_new"] = State.on; +            verse_line = TriState.off; +          } +          if (type["verse_new"] == State.on) { +            verse_line=1; +            an_object["obj"] = processing["verse"]; +            debug(poem) {                            // poem (tic) close +              writefln( +                "%s%s tic\n%s", +                scr_txt_marker["green"], +                obj_cite_number, +                an_object["obj"] +              ); +            } +            processing.remove("verse"); +            an_object["is"] = "verse"; +            node = +              node_jstr( +                content_non_header, +                obj_cite_number, +                counter, +                heading_pointer-1, +                an_object["is"] +              ); +            an_object["substantive"] = +              obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +            an_object["attrib"] = +              obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +            contents_the_objects ~= +              set_abstract_object.contents_block( +                an_object["is"], +                an_object["substantive"], +                an_object["attrib"], +                obj_cite_number +              ); +            object_reset(an_object); +            processing.remove("verse"); +            ++counter; +          } +        } +      } +      return 0; +    } +    auto group_block( +      char[] line, +      ref string[string] an_object, +      ref int[string] type +    ) { +      if (type["curly_group"] == State.on) { +        if (match(line, rgx.block_curly_group_close)) { +          debug(group) {                           // group (curly) close +            tell_l("blue", line); +          } +          type["blocks"] = TriState.closing; +          type["group"] = TriState.closing; +          type["curly_group"] = TriState.off; +        } else { +          debug(group) {                           // group +            tell_l("blue", line); +          } +          an_object["obj"] ~= line ~= "\n";           // build group array (or string) +        } +      } else if (type["tic_group"] == TriState.on) { +        if (match(line, rgx.block_tic_close)) { +          debug(group) {                           // group (tic) close +            tell_l("blue", line); +          } +          type["blocks"] = TriState.closing; +          type["group"] = TriState.closing; +          type["tic_group"] = TriState.off; +        } else { +          debug(group) {                           // group +            tell_l("blue", line); +          } +          an_object["obj"] ~= line ~= "\n";           // build group array (or string) +        } +      } +      return 0; +    } +    auto block_block( +      char[] line, +      ref string[string] an_object, +      ref int[string] type +    ) { +      if (type["curly_block"] == TriState.on) { +        if (match(line, rgx.block_curly_block_close)) { +          debug(block) {                           // block (curly) close +            tell_l("blue", line); +          } +          type["blocks"] = TriState.closing; +          type["block"] = TriState.closing; +          type["curly_block"] = TriState.off; +        } else { +          debug(block) {                           // block +            tell_l("blue", line); +          } +          an_object["obj"] ~= line ~= "\n";           // build block array (or string) +        } +      } else if (type["tic_block"] == TriState.on) { +        if (match(line, rgx.block_tic_close)) { +          debug(block) {                           // block (tic) close +            tell_l("blue", line); +          } +          type["blocks"] = TriState.closing; +          type["block"] = TriState.closing; +          type["tic_block"] = TriState.off; +        } else { +          debug(block) {                           // block +            tell_l("blue", line); +          } +          an_object["obj"] ~= line ~= "\n";           // build block array (or string) +        } +      } +      return 0; +    } +    auto quote_block(char[] line, ref string[string] an_object, ref int[string] type) { +      if (type["curly_quote"] == TriState.on) { +        if (match(line, rgx.block_curly_quote_close)) { +          debug(quote) {                           // quote (curly) close +            tell_l("blue", line); +          } +          type["blocks"] = TriState.closing; +          type["quote"] = TriState.closing; +          type["curly_quote"] = TriState.off; +        } else { +          debug(quote) {                           // quote +            tell_l("blue", line); +          } +          an_object["obj"] ~= line ~= "\n";           // build quote array (or string) +        } +      } else if (type["tic_quote"] == TriState.on) { +        if (match(line, rgx.block_tic_close)) { +          debug(quote) {                           // quote (tic) close +            tell_l("blue", line); +          } +          type["blocks"] = TriState.closing; +          type["quote"] = TriState.closing; +          type["tic_quote"] = TriState.off; +        } else { +          debug(quote) {                           // quote +            tell_l("blue", line); +          } +          an_object["obj"] ~= line ~= "\n";           // build quote array (or string) +        } +      } +      return 0; +    } +    auto table_block(char[] line, ref string[string] an_object, ref int[string] type) { +      if (type["curly_table"] == TriState.on) { +        if (match(line, rgx.block_curly_table_close)) { +          debug(table) {                           // table (curly) close +            tell_l("blue", line); +          } +          type["blocks"] = TriState.closing; +          type["table"] = TriState.closing; +          type["curly_table"] = TriState.off; +        } else { +          debug(table) {                           // table +            tell_l("blue", line); +          } +          an_object["obj"] ~= line ~= "\n";           // build table array (or string) +        } +      } else if (type["tic_table"] == TriState.on) { +        if (match(line, rgx.block_tic_close)) { +          debug(table) {                           // table (tic) close +            tell_l("blue", line); +          } +          type["blocks"] = TriState.closing; +          type["table"] = TriState.closing; +          type["tic_table"] = TriState.off; +        } else { +          debug(table) {                           // table +            tell_l("blue", line); +          } +          an_object["obj"] ~= line ~= "\n";           // build table array (or string) +        } +      } +      return 0; +    } +    auto block_flag_line_empty( +      char[] line, +      ref string[string] an_object, +      ref string[string][] contents_the_objects, +      ref string[][string][string] bookindex_unordered_hashes, +      ref int obj_cite_number, +      ref string node, +      ref long counter, +      ref int[string] type, +      string[string] obj_cite_number_poem +    ) { +      // line.empty, post contents, empty variables --------------- +      assert( +        line.empty, +        "line should be empty" +      ); +      assert( +        (type["blocks"] == TriState.closing), +        "code block status: closed" +      ); +      assertions_flag_types_block_status_none_or_closed(type); +      if (type["code"] == TriState.closing) { +        obj_cite_number = +          obj_cite_number_emit(type["obj_cite_number_status"]); +        an_object["bookindex"] = +          ("bookindex" in an_object) ? an_object["bookindex"] : ""; +        bookindex_unordered_hashes = +          bkidx_hash(an_object["bookindex"], obj_cite_number); +        an_object["is"] = "code"; +        node = +          node_jstr( +            content_non_header, +            obj_cite_number, +            counter, +            heading_pointer-1, +            an_object["is"] +          ); +        an_object["substantive"] = +          obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +        an_object["attrib"] = +          obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +        contents_the_objects ~= +          set_abstract_object.contents_block( +            an_object["is"], +            an_object["substantive"], +            an_object["attrib"], +            obj_cite_number +          ); +        object_reset(an_object); +        processing.remove("verse"); +        ++counter; +        type["blocks"] = TriState.off; +        type["code"] = TriState.off; +      } else if (type["poem"] == TriState.closing) { +        an_object["bookindex"] = +          ("bookindex" in an_object) ? an_object["bookindex"] : ""; +        bookindex_unordered_hashes = +          bkidx_hash(an_object["bookindex"], obj_cite_number); +        // obj_cite_number = obj_cite_number_emit(type["obj_cite_number_status"]); +        an_object["is"] = "verse"; // check also +        node = +          node_jstr( +            content_non_header, +            obj_cite_number, +            counter, +            heading_pointer-1, +            an_object["is"] +            // "verse" +          ); +        contents_the_objects ~= +          set_abstract_object.contents_block_obj_cite_number_string( +            "poem", +            "", +            (obj_cite_number_poem["start"], obj_cite_number_poem["end"]), +            node +          ); // bookindex +        object_reset(an_object); +        processing.remove("verse"); +        // ++obj_cite_number; +        type["blocks"] = TriState.off; +        type["poem"] = TriState.off; +      } else if (type["table"] == TriState.closing) { +        obj_cite_number = +          obj_cite_number_emit(type["obj_cite_number_status"]); +        an_object["bookindex"] = +          ("bookindex" in an_object) ? an_object["bookindex"] : ""; +        bookindex_unordered_hashes = +          bkidx_hash(an_object["bookindex"], obj_cite_number); +        an_object["is"] = "table"; +        node = +          node_jstr( +            content_non_header, +            obj_cite_number, +            counter, +            heading_pointer-1, +            an_object["is"] +          ); +        an_object["substantive"] = +          obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +        an_object["attrib"] = +          obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +        contents_the_objects ~= +          set_abstract_object.contents_block( +            an_object["is"], +            an_object["substantive"], +            an_object["attrib"], +            obj_cite_number +          ); +        object_reset(an_object); +        processing.remove("verse"); +        ++counter; +        type["blocks"] = TriState.off; +        type["table"] = TriState.off; +      } else if (type["group"] == TriState.closing) { +        obj_cite_number = +          obj_cite_number_emit(type["obj_cite_number_status"]); +        an_object["bookindex"] = +          ("bookindex" in an_object) ? an_object["bookindex"] : ""; +        bookindex_unordered_hashes = +          bkidx_hash(an_object["bookindex"], obj_cite_number); +        an_object["is"] = "group"; +        node = +          node_jstr( +            content_non_header, +            obj_cite_number, +            counter, +            heading_pointer-1, +            an_object["is"] +          ); +        an_object["substantive"] = +          obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +        an_object["attrib"] = +          obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +        contents_the_objects ~= +          set_abstract_object.contents_block( +            an_object["is"], +            an_object["substantive"], +            an_object["attrib"], +            obj_cite_number +          ); +        object_reset(an_object); +        processing.remove("verse"); +        ++counter; +        type["blocks"] = TriState.off; +        type["group"] = TriState.off; +      } else if (type["block"] == TriState.closing) { +        obj_cite_number = obj_cite_number_emit(type["obj_cite_number_status"]); +        an_object["bookindex"] = +          ("bookindex" in an_object) ? an_object["bookindex"] : ""; +        bookindex_unordered_hashes = +          bkidx_hash(an_object["bookindex"], obj_cite_number); +        an_object["is"] = "block"; +        node = +          node_jstr( +            content_non_header, +            obj_cite_number, +            counter, +            heading_pointer-1, +            an_object["is"] +           ); +        an_object["substantive"] = +          obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +        an_object["attrib"] = +          obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +        contents_the_objects ~= +          set_abstract_object.contents_block( +            an_object["is"], +            an_object["substantive"], +            an_object["attrib"], +            obj_cite_number +          ); +        object_reset(an_object); +        processing.remove("verse"); +        ++counter; +        type["blocks"] = TriState.off; +        type["block"] = TriState.off; +      } else if (type["quote"] == TriState.closing) { +        obj_cite_number = +          obj_cite_number_emit(type["obj_cite_number_status"]); +        an_object["bookindex"] = +          ("bookindex" in an_object) ? an_object["bookindex"] : ""; +        bookindex_unordered_hashes = +          bkidx_hash(an_object["bookindex"], obj_cite_number); +        an_object["is"] = "quote"; +        node = +          node_jstr( +            content_non_header, +            obj_cite_number, +            counter, +            heading_pointer-1, +            an_object["is"] +          ); +        an_object["substantive"] = +          obj_im.obj_inline_markup(an_object["is"], an_object["obj"]); +        an_object["attrib"] = +          obj_att.obj_attributes(an_object["is"], an_object["obj"], node); +        contents_the_objects ~= +          set_abstract_object.contents_block( +            an_object["is"], +            an_object["substantive"], +            an_object["attrib"], +            obj_cite_number +          ); +        object_reset(an_object); +        processing.remove("verse"); +        ++counter; +        type["blocks"] = TriState.off; +        type["quote"] = TriState.off; +      } +      return 0; +    } +    auto book_index( +      char[] line, +      ref string book_idx_tmp, +      ref string[string] an_object, +      ref int[string] type +    ) { +      if (auto m = match(line, rgx.book_index)) { +        /+ match book_index +/ +        debug(bookindexmatch) {                       // book index +          writefln( +            "%s* [bookindex] %s%s\n", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            to!string(m.captures[1]), +          ); +          // writeln(scr_txt_marker["blue"], to!string(m.captures[1]), "\n"); +        } +        an_object["bookindex"] = to!string(m.captures[1]); +      } else if (auto m = match(line, rgx.book_index_open))  { +        /+ match open book_index +/ +        type["book_index"] = State.on; +        book_idx_tmp = to!string(m.captures[1]); +        debug(bookindexmatch) {                       // book index +          writefln( +            "%s* [bookindex] %s%s\n", +            scr_txt_color["blue"], +            scr_txt_color["off"], +            book_idx_tmp, +          ); +          // writeln(scr_txt_marker["blue"], book_idx_tmp, "\n"); +        } +      } else if (type["book_index"] == State.on )  { +        /+ book_index flag set +/ +        if (auto m = match(line, rgx.book_index_close))  { +          type["book_index"] = State.off; +          an_object["bookindex"] = book_idx_tmp ~ to!string(m.captures[1]); +          debug(bookindexmatch) {                     // book index +            writefln( +              "%s* [bookindex] %s%s\n", +              scr_txt_color["blue"], +              scr_txt_color["off"], +              book_idx_tmp, +            ); +            // writeln(scr_txt_marker["blue"], book_idx_tmp, "\n"); +          } +          book_idx_tmp = ""; +        } else { +          book_idx_tmp ~= line; +        } +      } +    } +    auto header_extract( +      char[] line, +      ref int[string] line_occur, +      ref string[string] an_object, +      ref int[string] type +    ) { +      if (auto m = match(line, rgx.header_make)) { +        /+ matched header_make +/ +        debug(header1) {                          // header +          tell_l("yellow", line); +        } +        type["header"] = State.on; +        type["header_make"] = State.on; +        type["header_metadata"] = State.off; +        type["heading"] = State.off; +        type["para"] = State.off; +        ++line_occur["header_make"]; +        an_object["obj"] ~= line ~= "\n"; +      } else if (auto m = match(line, rgx.header_metadata)) { +        /+ matched header_metadata +/ +        debug(header1) {                          // header +          tell_l("yellow", line); +        } +        type["header"] = State.on; +        type["header_make"] = State.off; +        type["header_metadata"] = State.on; +        type["heading"] = State.off; +        type["para"] = State.off; +        ++line_occur["header_metadata"]; +        an_object["obj"] ~= line ~= "\n"; +      } else if (type["header_make"] == State.on +      && (line_occur["header_make"] > State.off)) { +        /+ header_make flag set +/ +        if (auto m = match(line, rgx.header_sub)) { +          /+ sub-header +/ +          debug(header1) { +            tell_l("yellow", line); +          } +          // type["header"] = State.on; +          ++line_occur["header_make"]; +          an_object["obj"] ~= line ~= "\n"; +        } +      } else if (type["header_metadata"] == State.on +      && (line_occur["header_metadata"] > State.off)) { +        /+ header_metadata flag set +/ +        if (auto m = match(line, rgx.header_sub)) { +          /+ sub-header +/ +          debug(header1) { +            tell_l("yellow", line); +          } +          ++line_occur["header_metadata"]; +          an_object["obj"] ~= line ~= "\n"; +        } +      } +      return 0; +    } +    auto heading_found( +      char[] line, +      string dochead_make_headings, +      ref string[string] heading_match_str, +      ref Regex!(char)[string] heading_match_rgx, +      ref int[string] type +    ) { +      if ((to!string(dochead_make_headings).length > 2) +      && (type["make_headings"] == State.off)) { +        /+ headings found +/ +        debug(headingsfound) { +          writeln(dochead_make_headings); +        } +        auto make_headings_txt = +          match( +            to!string(dochead_make_headings), +            rgx.within_quotes); +        char[][] make_headings_spl = +          split( +            cast(char[]) make_headings_txt.captures[1], +            rgx.make_heading_delimiter); +        debug(headingsfound) { +          writeln(make_headings_spl.length); +          writeln(make_headings_spl); +        } +        switch (make_headings_spl.length) { +        case 7 : +          if (!empty(make_headings_spl[6])) { +            heading_match_str["h_4"] = +              "^(" ~ to!string(make_headings_spl[6]) ~ ")"; +            heading_match_rgx["h_4"] = +              regex(heading_match_str["h_4"]); +          } +          goto case; +        case 6 : +          if (!empty(make_headings_spl[5])) { +            heading_match_str["h_3"] = +              "^(" ~ to!string(make_headings_spl[5]) ~ ")"; +            heading_match_rgx["h_3"] = +              regex(heading_match_str["h_3"]); +          } +          goto case; +        case 5 : +          if (!empty(make_headings_spl[4])) { +            heading_match_str["h_2"] = +              "^(" ~ to!string(make_headings_spl[4]) ~ ")"; +            heading_match_rgx["h_2"] = +              regex(heading_match_str["h_2"]); +          } +          goto case; +        case 4 : +          if (!empty(make_headings_spl[3])) { +            heading_match_str["h_1"] = +              "^(" ~ to!string(make_headings_spl[3]) ~ ")"; +            heading_match_rgx["h_1"] = +              regex(heading_match_str["h_1"]); +          } +          goto case; +        case 3 : +          if (!empty(make_headings_spl[2])) { +            heading_match_str["h_D"] = +              "^(" ~ to!string(make_headings_spl[2]) ~ ")"; +            heading_match_rgx["h_D"] = +              regex(heading_match_str["h_D"]); +          } +          goto case; +        case 2 : +          if (!empty(make_headings_spl[1])) { +            heading_match_str["h_C"] = +              "^(" ~ to!string(make_headings_spl[1]) ~ ")"; +            heading_match_rgx["h_C"] = +              regex(heading_match_str["h_C"]); +          } +          goto case; +        case 1 : +          if (!empty(make_headings_spl[0])) { +            heading_match_str["h_B"] = +              "^(" ~ to!string(make_headings_spl[0]) ~ ")"; +            heading_match_rgx["h_B"] = +              regex(heading_match_str["h_B"]); +          } +          break; +        default: +          break; +        } +        type["make_headings"] = State.on; +      } +    } +    auto heading_make_set( +      ref char[] line, +      ref int[string] line_occur, +      ref Regex!(char)[string] heading_match_rgx, +      ref int[string] type +    ) { +      if ((type["make_headings"] == State.on) +      && ((line_occur["para"] == State.off) +      && (line_occur["heading"] == State.off)) +      && ((type["para"] == State.off) +      && (type["heading"] == State.off))) { +        /+ heading make set +/ +        if (match(line, heading_match_rgx["h_B"])) { +          line = "B~ " ~ line; +          debug(headingsfound) { +            writeln(line); +          } +        } +        if (match(line, heading_match_rgx["h_C"])) { +          line = "C~ " ~ line; +          debug(headingsfound) { +            writeln(line); +          } +        } +        if (match(line, heading_match_rgx["h_D"])) { +          line = "D~ " ~ line; +          debug(headingsfound) { +            writeln(line); +          } +        } +        if (match(line, heading_match_rgx["h_1"])) { +          line = "1~ " ~ line; +          debug(headingsfound) { +            writeln(line); +          } +        } +        if (match(line, heading_match_rgx["h_2"])) { +          line = "2~ " ~ line; +          debug(headingsfound) { +            writeln(line); +          } +        } +        if (match(line, heading_match_rgx["h_3"])) { +          line = "3~ " ~ line; +          debug(headingsfound) { +            writeln(line); +          } +        } +        if (match(line, heading_match_rgx["h_4"])) { +          line = "4~ " ~ line; +          debug(headingsfound) { +            writeln(line); +          } +        } +      } +    } +    auto heading_match( +      char[] line, +      ref int[string] line_occur, +      ref string[string] an_object, +      ref int[string] lv, +      ref int[string] collapsed_lev, +      ref int[string] type +    ) { +      if (auto m = match(line, rgx.heading)) { +        /+ heading match +/ +        type["heading"] = State.on; +        type["header"] = State.off; +        type["header_make"] = State.off; +        type["header_metadata"] = State.off; +        type["heading_biblio"] = State.off; +        type["para"] = State.off; +        ++line_occur["heading"]; +        an_object["obj"] ~= line ~= "\n"; +        an_object["lev"] ~= m.captures[1]; +        assertions_doc_structure(an_object, lv); // includes most of the logic for collapsed levels +        switch (an_object["lev"]) { +        case "A": +          collapsed_lev["h0"] = 1; +          an_object["lev_collapsed_number"] = +            to!string(collapsed_lev["h0"]); +          lv["lv"] = DocStructMarkupHeading.h_sect_A; +          ++lv["h0"]; +          lv["h1"] = State.off; +          lv["h2"] = State.off; +          lv["h3"] = State.off; +          lv["h4"] = State.off; +          lv["h5"] = State.off; +          lv["h6"] = State.off; +          lv["h7"] = State.off; +          goto default; +        case "B": +          collapsed_lev["h1"] = collapsed_lev["h0"] + 1; +          an_object["lev_collapsed_number"] = +            to!string(collapsed_lev["h1"]); +          lv["lv"] = DocStructMarkupHeading.h_sect_B; +          ++lv["h1"]; +          lv["h2"] = State.off; +          lv["h3"] = State.off; +          lv["h4"] = State.off; +          lv["h5"] = State.off; +          lv["h6"] = State.off; +          lv["h7"] = State.off; +          goto default; +        case "C": +          collapsed_lev["h2"] = collapsed_lev["h1"] + 1; +          an_object["lev_collapsed_number"] = +            to!string(collapsed_lev["h2"]); +          lv["lv"] = DocStructMarkupHeading.h_sect_C; +          ++lv["h2"]; +          lv["h3"] = State.off; +          lv["h4"] = State.off; +          lv["h5"] = State.off; +          lv["h6"] = State.off; +          lv["h7"] = State.off; +          goto default; +        case "D": +          collapsed_lev["h3"] = collapsed_lev["h2"] + 1; +          an_object["lev_collapsed_number"] = +            to!string(collapsed_lev["h3"]); +          lv["lv"] = DocStructMarkupHeading.h_sect_D; +          ++lv["h3"]; +          lv["h4"] = State.off; +          lv["h5"] = State.off; +          lv["h6"] = State.off; +          lv["h7"] = State.off; +          goto default; +        case "1": +          if (lv["h3"] > State.off) { +            collapsed_lev["h4"] = collapsed_lev["h3"] + 1; +          } else if (lv["h2"] > State.off) { +            collapsed_lev["h4"] = collapsed_lev["h2"] + 1; +          } else if (lv["h1"] > State.off) { +            collapsed_lev["h4"] = collapsed_lev["h1"] + 1; +          } else if (lv["h0"] > State.off) { +            collapsed_lev["h4"] = collapsed_lev["h0"] + 1; +          } +          an_object["lev_collapsed_number"] = +            to!string(collapsed_lev["h4"]); +          lv["lv"] = DocStructMarkupHeading.h_text_1; +          ++lv["h4"]; +          lv["h5"] = State.off; +          lv["h6"] = State.off; +          lv["h7"] = State.off; +          goto default; +        case "2": +          if (lv["h5"] > State.off) { +            an_object["lev_collapsed_number"] = +              to!string(collapsed_lev["h5"]); +          } else if (lv["h4"] > State.off) { +            collapsed_lev["h5"] = collapsed_lev["h4"] + 1; +            an_object["lev_collapsed_number"] = +              to!string(collapsed_lev["h5"]); +          } +          lv["lv"] = DocStructMarkupHeading.h_text_2; +          ++lv["h5"]; +          lv["h6"] = State.off; +          lv["h7"] = State.off; +          goto default; +        case "3": +          if (lv["h6"] > State.off) { +            an_object["lev_collapsed_number"] = +              to!string(collapsed_lev["h6"]); +          } else if (lv["h5"] > State.off) { +            collapsed_lev["h6"] = collapsed_lev["h5"] + 1; +            an_object["lev_collapsed_number"] = +              to!string(collapsed_lev["h6"]); +          } +          lv["lv"] = DocStructMarkupHeading.h_text_3; +          ++lv["h6"]; +          lv["h7"] = State.off; +          goto default; +        case "4": +          if (lv["h7"] > State.off) { +            an_object["lev_collapsed_number"] = +              to!string(collapsed_lev["h7"]); +          } else if (lv["h6"] > State.off) { +            collapsed_lev["h7"] = collapsed_lev["h6"] + 1; +            an_object["lev_collapsed_number"] = +              to!string(collapsed_lev["h7"]); +          } +          lv["lv"] = DocStructMarkupHeading.h_text_4; +          ++lv["h7"]; +          goto default; +        default: +          an_object["lev_markup_number"] = to!string(lv["lv"]); +        } +        debug(heading) {                         // heading +          // writeln(m.captures[1], " ", m.captures[2], "\n");      // figure inclusion of post capture text +          // writeln(m.hit, "\n"); +          tell_l("yellow", strip(line)); +        } +      } +    } +    auto para_match( +      char[] line, +      ref string[string] an_object, +      ref string[string] indent, +      ref bool bullet, +      ref int[string] type +    ) { +      if (line_occur["para"] == State.off) { +        /+ para matches +/ +          // paragraphs +          // (fl  ag_type["heading"] = true) && +        if (auto m = match(line, rgx.para_indent)) { +          debug(paraindent) {                    // para indent +            tell_l("blue", line); +          } +          type["para"] = State.on; +          an_object["obj"] ~= line ~= "\n"; +          indent["first"] = to!string(m.captures[1]); +          indent["second"] = "0"; +          bullet = false; +        } else if (auto m = match(line, rgx.para_bullet)) { +          debug(parabullet) {                    // para bullet +            tell_l("blue", line); +          } +          type["para"] = State.on; +          an_object["obj"] ~= line; +          indent["first"] = "0"; +          indent["second"] = "0"; +          bullet = true; +        } else if (auto m = match(line, rgx.para_indent_hang)) { +          debug(paraindenthang) {                // para indent hang +            tell_l("blue", line); +          } +          type["para"] = State.on; +          an_object["obj"] ~= line; +          indent["first"] = to!string(m.captures[1]); +          indent["second"] = to!string(m.captures[2]); +          bullet = false; +        } else if (auto m = match(line, rgx.para_bullet_indent)) { +          debug(parabulletindent) {              // para bullet indent +            tell_l("blue", line); +          } +          type["para"] = State.on; +          an_object["obj"] ~= line; +          indent["first"] = to!string(m.captures[1]); +          indent["second"] = "0"; +          bullet = true; +        } else { +          // !line.empty +          type["para"] = State.on; +          an_object["obj"] ~= line; +          indent["first"] = "0"; +          indent["second"] = "0"; +          bullet = false; +        } +        ++line_occur["para"]; +      } +    } +    /+ abstraction functions ↑ +/ + +    /+ ↓ abstraction function emitters +/ +    struct OCNemitter { +    // class OCNemitter : AssertOCN { +      int obj_cite_number, obj_cite_number_; +      int obj_cite_number_emitter(int obj_cite_number_status_flag) +      in { assert(obj_cite_number_status_flag <= 2); } +      body { +        if (obj_cite_number_status_flag == 0) { +          obj_cite_number=++obj_cite_number_; +        } else { +          obj_cite_number=0; +        } +        assert(obj_cite_number >= 0); +        return obj_cite_number; +      } +      invariant() { +      } +    } +    struct ObjAttributes { +    // class ObjAttributes : AssertObjAttributes { +      string[string] obj_txt; +      string para_and_blocks(string obj_txt_in) +      in { } +      body { +        auto rgx = Rgx(); +        obj_txt["munge"]=obj_txt_in; +        if (match(obj_txt_in, rgx.para_bullet)) { +          obj_txt["attrib"] =" \"bullet\": \"true\"," +          ~ " \"indent_first\": 0," +          ~ " \"indent_rest\": 0,"; +        } else if (auto m = match(obj_txt_in, rgx.para_bullet_indent)) { +          obj_txt["attrib"] =" \"bullet\": \"true\"," +          ~ " \"indent_first\": " ~ to!string(m.captures[1]) ~ "," +          ~ " \"indent_rest\": " ~ to!string(m.captures[1]) ~ ","; +        } else if (auto m = match(obj_txt_in, rgx.para_indent_hang)) { +          obj_txt["attrib"] =" \"bullet\": \"false\"," +          ~ " \"indent_first\": " ~ to!string(m.captures[1]) ~ "," +          ~ " \"indent_rest\": " ~  to!string(m.captures[2]) ~ ","; +        } else if (auto m = match(obj_txt_in, rgx.para_indent)) { +          obj_txt["attrib"] =" \"bullet\": \"false\"," +          ~ " \"indent_first\": " ~ to!string(m.captures[1]) ~ "," +          ~ " \"indent_rest\": " ~ to!string(m.captures[1]) ~ ","; +        } else { +          obj_txt["attrib"] =" \"bullet\": \"false\"," +          ~ " \"indent_first\": 0," +          ~ " \"indent_rest\": 0,"; +        } +        return obj_txt["attrib"]; +      } +      string para(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"content\"," +        ~ " \"of\": \"para\"," +        ~ " \"is\": \"para\""; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +      string heading(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"content\"," +        ~ " \"of\": \"para\"," +        ~ " \"is\": \"heading\""; +        // obj_txt["struct"]=; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +      string header_make(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"head\"," +        ~ " \"of\": \"header\"," +        ~ " \"is\": \"header_make\""; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +      string header_metadata(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"head\"," +        ~ " \"of\": \"header\"," +        ~ " \"is\": \"header_metadata\""; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +      string code(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"content\"," +        ~ " \"of\": \"block\"," +        ~ " \"is\": \"code\""; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +      string group(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"content\"," +        ~ " \"of\": \"block\"," +        ~ " \"is\": \"group\""; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +      string block(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"content\"," +        ~ " \"of\": \"block\"," +        ~ " \"is\": \"block\""; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +      string verse(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"content\"," +        ~ " \"of\": \"block\"," +        ~ " \"is\": \"verse\""; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +      string quote(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"content\"," +        ~ " \"of\": \"block\"," +        ~ " \"is\": \"quote\""; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +      string table(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"content\"," +        ~ " \"of\": \"block\"," +        ~ " \"is\": \"table\""; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +      string comment(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["attrib"] = " \"use\": \"comment\"," +        ~ " \"of\": \"comment\"," +        ~ " \"is\": \"comment\""; +        return obj_txt["attrib"]; +      } +      invariant() { +      } +    } +    struct ObjInlineMarkupMunge { +    // struct ObjInlineMarkupMunge : AssertObjInlineMarkup { +      string[string] obj_txt; +      int n_foot, n_foot_reg, n_foot_sp_asterisk, n_foot_sp_plus; +      string obj_txt_out, tail, note; +      private auto initialize_note_numbers() { +        n_foot = 0; +        n_foot_reg = 0; +        n_foot_sp_asterisk = 0; +        n_foot_sp_plus = 0; +      } +      private auto object_notes_(string obj_txt_in) +      in { } +      body { +        auto rgx = Rgx(); +        auto mkup = InlineMarkup(); +        obj_txt_out = ""; +        tail = ""; +        obj_txt_in = replaceAll( +          obj_txt_in, +          rgx.inline_notes_curly_sp_asterisk, +          (mkup.en_a_o ~ "*" ~ " $1" ~ mkup.en_a_c) +        ); +        obj_txt_in = +          replaceAll( +            obj_txt_in, +            rgx.inline_notes_curly_sp_plus, +            (mkup.en_a_o ~ "+" ~ " $1" ~ mkup.en_a_c) +          ); +        obj_txt_in = +          replaceAll( +            obj_txt_in, +            rgx.inline_notes_curly, +            (mkup.en_a_o ~ " $1" ~ mkup.en_a_c) +          ); +        if (match(obj_txt_in, rgx.inline_notes_al_gen)) { +          foreach(m; matchAll(obj_txt_in, rgx.inline_text_and_note_al)) { +            if (match(obj_txt_in, rgx.inline_al_delimiter_open_asterisk)) { +              ++n_foot_sp_asterisk; +              n_foot=n_foot_sp_asterisk; +            } else if (match(obj_txt_in, rgx.inline_al_delimiter_open_plus)) { +              ++n_foot_sp_plus; +              n_foot=n_foot_sp_plus; +            } else { +              ++n_foot_reg; +              n_foot=n_foot_reg; +            } +            obj_txt_out ~= replaceFirst( +              m.hit, +              rgx.inline_al_delimiter_open_regular, +              (mkup.en_a_o ~ to!string(n_foot)) +            ); +            tail = m.post; +            // if (!empty(m.post)) { +            //   tail = m.post; +            // } else { +            //   tail = ""; +            // } +          } +        } else { +          obj_txt_out = obj_txt_in; +        } +        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.captures[1]); +            writeln(m.hit); +          } +        } +        return obj_txt_out; +      } +      string para(string obj_txt_in) +      in { } +      body { +        auto rgx = Rgx(); +        obj_txt["munge"]=obj_txt_in; +        obj_txt["munge"]=replaceFirst(obj_txt["munge"], rgx.para_attribs, ""); +        obj_txt["munge"]=replaceFirst(obj_txt["munge"], rgx.obj_cite_number_off_all, ""); +        obj_txt["munge"]=object_notes_(obj_txt["munge"]); +        debug(munge) { +          writeln(__LINE__); +          writeln(obj_txt_in); +          writeln(__LINE__); +          writeln(to!string(obj_txt["munge"])); +        } +        return obj_txt["munge"]; +      } +      string heading(string obj_txt_in) +      in { } +      body { +        auto rgx = Rgx(); +        obj_txt["munge"]=obj_txt_in; +        obj_txt["munge"]=replaceFirst(obj_txt["munge"], rgx.heading, ""); +        obj_txt["munge"]=replaceFirst(obj_txt["munge"], rgx.obj_cite_number_off_all, ""); +        obj_txt["munge"]=object_notes_(obj_txt["munge"]); +        debug(munge) { +          writeln(__LINE__); +          writeln(obj_txt_in); +          writeln(__LINE__); +          writeln(to!string(obj_txt["munge"])); +        } +        return obj_txt["munge"]; +      } +      invariant() { +      } +      string header_make(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        return obj_txt["munge"]; +      } +      invariant() { +      } +      string header_metadata(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        return obj_txt["munge"]; +      } +      invariant() { +      } +      string code(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        return obj_txt["munge"]; +      } +      invariant() { +      } +      string group(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["munge"]=object_notes_(obj_txt["munge"]); +        return obj_txt["munge"]; +      } +      invariant() { +      } +      string block(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["munge"]=object_notes_(obj_txt["munge"]); +        return obj_txt["munge"]; +      } +      invariant() { +      } +      string verse(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        obj_txt["munge"]=object_notes_(obj_txt["munge"]); +        return obj_txt["munge"]; +      } +      invariant() { +      } +      string quote(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        return obj_txt["munge"]; +      } +      invariant() { +      } +      string table(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        return obj_txt["munge"]; +      } +      invariant() { +      } +      string comment(string obj_txt_in) +      in { } +      body { +        obj_txt["munge"]=obj_txt_in; +        return obj_txt["munge"]; +      } +      invariant() { +      } +    } +    struct ObjInlineMarkup { +    // struct ObjInlineMarkup : AssertObjInlineMarkup { +      auto munge = ObjInlineMarkupMunge(); +      string[string] obj_txt; +      string obj_inline_markup(string obj_is_, string obj_raw) +      in { } +      body { +        obj_txt["munge"]=obj_raw.dup; +        obj_txt["munge"]=(match(obj_is_, ctRegex!(`verse|code`))) +          ? obj_txt["munge"] +          : strip(obj_txt["munge"]); +        switch (obj_is_) { +        case "header_make": +          obj_txt["munge"]=munge.header_make(obj_txt["munge"]); +          break; +        case "header_metadata": +          obj_txt["munge"]=munge.header_metadata(obj_txt["munge"]); +          break; +        case "heading": +          obj_txt["munge"]=munge.heading(obj_txt["munge"]); +          break; +        case "para": +          obj_txt["munge"]=munge.para(obj_txt["munge"]); +          break; +        case "code": +          obj_txt["munge"]=munge.code(obj_txt["munge"]); +          break; +        case "group": +          obj_txt["munge"]=munge.group(obj_txt["munge"]); +          break; +        case "block": +          obj_txt["munge"]=munge.block(obj_txt["munge"]); +          break; +        case "verse": +          obj_txt["munge"]=munge.verse(obj_txt["munge"]); +          break; +        case "quote": +          obj_txt["munge"]=munge.quote(obj_txt["munge"]); +          break; +        case "table": +          obj_txt["munge"]=munge.table(obj_txt["munge"]); +          break; +        case "comment": +          obj_txt["munge"]=munge.comment(obj_txt["munge"]); +          break; +        case "doc_end_reset": +          munge.initialize_note_numbers(); +          break; +        default: +          break; +        } +        return obj_txt["munge"]; +      } +      invariant() { +      } +    } +    struct ObjAttrib { +    // struct ObjAttrib : AssertObjAttrib { +    // auto sink = appender!(char[])(); +      auto attrib = ObjAttributes(); +      string[string] obj_attrib; +      string obj_attributes(string obj_is_, string obj_raw, string node) +      in { } +      body { +        // string s = "{ \"language\": \"D\", \"rating\": 3.14, \"code\": \"42\" }"; +        scope(exit) { +          // destroy(obj_is_); +          destroy(obj_raw); +          destroy(node); +        } +        JSONValue node_j = parseJSON(node); +        obj_attrib.remove("json"); +        obj_attrib["json"] ="{"; +        switch (obj_is_) { +        case "header_make": +          obj_attrib["json"] ~= attrib.header_make(obj_raw); +          break; +        case "header_metadata": +          obj_attrib["json"] ~= attrib.header_metadata(obj_raw); +          break; +        case "heading": +          obj_attrib["json"] ~= attrib.heading(obj_raw); // +          break; +        case "para": +          obj_attrib["json"] ~= attrib.para_and_blocks(obj_raw) +          ~ attrib.para(obj_raw); +          break; +        case "code": +          obj_attrib["json"] ~= attrib.code(obj_raw); +          break; +        case "group": +          obj_attrib["json"] ~= attrib.para_and_blocks(obj_raw) +          ~ attrib.group(obj_raw); +          break; +        case "block": +          obj_attrib["json"] ~= attrib.para_and_blocks(obj_raw) +          ~ attrib.block(obj_raw); +          break; +        case "verse": +          obj_attrib["json"] ~= attrib.verse(obj_raw); +          break; +        case "quote": +          obj_attrib["json"] ~= attrib.quote(obj_raw); +          break; +        case "table": +          obj_attrib["json"] ~= attrib.table(obj_raw); +          break; +        case "comment": +          obj_attrib["json"] ~= attrib.comment(obj_raw); +          break; +        default: +          obj_attrib["json"] ~= attrib.para(obj_raw); +          break; +        } +        obj_attrib["json"] ~=" }"; +        JSONValue oa_j = parseJSON(obj_attrib["json"]); +        assert( +          (oa_j.type == JSON_TYPE.OBJECT) && +          (node_j.type == JSON_TYPE.OBJECT) +        ); +        if (obj_is_ == "heading") { +          oa_j.object["obj_cite_number"] = node_j["obj_cite_number"]; +          oa_j.object["lev_markup_number"] = node_j["lev_markup_number"]; +          oa_j.object["lev_collapsed_number"] = node_j["lev_collapsed_number"]; +          oa_j.object["heading_pointer"] = +            node_j["heading_pointer"]; // check +          oa_j.object["doc_object_pointer"] = +            node_j["doc_object_pointer"]; // check +        } +        oa_j.object["parent_obj_cite_number"] = node_j["parent_obj_cite_number"]; +        oa_j.object["parent_lev_markup_number"] = node_j["parent_lev_markup_number"]; +        obj_attrib["json"] = oa_j.toString(); +        debug(structattrib) { +          if (oa_j["is"].str() == "heading") { +            // writeln(__LINE__); +            writeln(obj_attrib["json"]); +            // writeln(node); +            writeln( +              "is: ", oa_j["is"].str(), +              "; obj_cite_number: ", oa_j["obj_cite_number"].integer() +            ); +          } +        } +        // obj_attrib["json"]="{}"; +        return obj_attrib["json"]; +      } +      invariant() { +      } +    } +    struct HeaderDocMetadataMakeJson { +    // class HeaderMetadataMakeHash : AssertHeaderMetadataMakeJson { +      auto rgx = Rgx(); +      string hm, hs; +      auto header_metadata_and_make_jsonstr( +        string header, +        JSONValue[string] dochead_metadata, +        JSONValue[string] dochead_make +      ) +      in { } +      body { +        scope(exit) { +          destroy(header); +          destroy(dochead_metadata); +          destroy(dochead_make); +        } +        if (auto t = match(header, rgx.head_main)) { +          char[][] obj_spl = split( +            cast(char[]) header, +            rgx.line_delimiter_ws_strip +          ); +          auto hm = to!string(t.captures[1]); +          if (match(hm, rgx.main_headers)) { +            foreach (line; obj_spl) { +              if (auto m = match(line, rgx.head_main)) { +                if (!empty(m.captures[2])) { +                  if (hm == "creator") { +                    dochead_metadata[hm]["author"].str = +                      to!string(m.captures[2]); +                  } else if (hm == "title") { +                    dochead_metadata[hm]["main"].str = +                      to!string(m.captures[2]); +                  } else if (hm == "publisher") { +                    dochead_metadata[hm]["name"].str = +                      to!string(m.captures[2]); +                  } +                } +              } else if (auto s = match(line, rgx.head_sub)) { +                if (!empty(s.captures[2])) { +                  auto hs = to!string(s.captures[1]); +                  if ((hm == "make" ) +                  && (dochead_make[hm].type() == JSON_TYPE.OBJECT)) { +                    switch (hm) { +                    case "make": +                      if (match(hs, rgx.subhead_make)) { +                        if (dochead_make[hm][hs].type() == JSON_TYPE.STRING) { +                          dochead_make[hm][hs].str = to!string(s.captures[2]); +                        } +                      } else { +                        writeln("not a valid header type:", hm, ":", hs); +                        destroy(hm); +                        destroy(hs); +                      } +                      break; +                    default: +                      break; +                    } +                  } else if (dochead_metadata[hm].type() == JSON_TYPE.OBJECT) { +                    switch (hm) { +                    case "creator": +                      if (match(hs, rgx.subhead_creator)) { +                        if (dochead_metadata[hm][hs].type() == JSON_TYPE.STRING) { +                          dochead_metadata[hm][hs].str = +                            to!string(s.captures[2]); +                        } +                      } else { +                        writeln("not a valid header type:", hm, ":", hs); +                        destroy(hm); +                        destroy(hs); +                      } +                      break; +                    case "title": +                      if (match(hs, rgx.subhead_title)) { +                        if ((hs == "subtitle") +                        && (dochead_metadata[hm]["sub"].type() == JSON_TYPE.STRING)) { +                          dochead_metadata[hm]["sub"].str = +                            to!string(s.captures[2]); +                        } else if (dochead_metadata[hm][hs].type() == JSON_TYPE.STRING) { +                          dochead_metadata[hm][hs].str = +                            to!string(s.captures[2]); +                        } +                      } else { +                        writeln("not a valid header type:", hm, ":", hs); +                        destroy(hm); +                        destroy(hs); +                      } +                      break; +                    case "rights": +                      if (match(hs, rgx.subhead_rights)) { +                        if (dochead_metadata[hm][hs].type() == JSON_TYPE.STRING) { +                          dochead_metadata[hm][hs].str = +                            to!string(s.captures[2]); +                        } +                      } else { +                        writeln("not a valid header type:", hm, ":", hs); +                        destroy(hm); +                        destroy(hs); +                      } +                      break; +                    case "date": +                      if (match(hs, rgx.subhead_date)) { +                        if (dochead_metadata[hm][hs].type() == JSON_TYPE.STRING) { +                          dochead_metadata[hm][hs].str = +                            to!string(s.captures[2]); +                        } +                      } else { +                        writeln("not a valid header type:", hm, ":", hs); +                        destroy(hm); +                        destroy(hs); +                      } +                      break; +                    case "original": +                      if (match(hs, rgx.subhead_original)) { +                        if (dochead_metadata[hm][hs].type() == JSON_TYPE.STRING) { +                          dochead_metadata[hm][hs].str = +                            to!string(s.captures[2]); +                        } +                      } else { +                        writeln("not a valid header type:", hm, ":", hs); +                        destroy(hm); +                        destroy(hs); +                      } +                      break; +                    case "classify": +                      if (match(hs, rgx.subhead_classify)) { +                        if (dochead_metadata[hm][hs].type() == JSON_TYPE.STRING) { +                          dochead_metadata[hm][hs].str = +                            to!string(s.captures[2]); +                        } +                      } else { +                        writeln("not a valid header type:", hm, ":", hs); +                        destroy(hm); +                        destroy(hs); +                      } +                      break; +                    case "identifier": +                      if (match(hs, rgx.subhead_identifier)) { +                        if (dochead_metadata[hm][hs].type() == JSON_TYPE.STRING) { +                          dochead_metadata[hm][hs].str = +                            to!string(s.captures[2]); +                        } +                      } else { +                        writeln("not a valid header type:", hm, ":", hs); +                        destroy(hm); +                        destroy(hs); +                      } +                      break; +                    case "notes": +                      if (match(hs, rgx.subhead_notes)) { +                        if (dochead_metadata[hm][hs].type() == JSON_TYPE.STRING) { +                          dochead_metadata[hm][hs].str = +                            to!string(s.captures[2]); +                        } +                      } else { +                        writeln("not a valid header type:", hm, ":", hs); +                        destroy(hm); +                        destroy(hs); +                      } +                      break; +                    case "publisher": +                      if (match(hs, rgx.subhead_publisher)) { +                        if (dochead_metadata[hm][hs].type() == JSON_TYPE.STRING) { +                          dochead_metadata[hm][hs].str = +                            to!string(s.captures[2]); +                        } +                      } else { +                        writeln("not a valid header type:", hm, ":", hs); +                        destroy(hm); +                        destroy(hs); +                      } +                      break; +                    case "links": +                      destroy(hm); +                      destroy(hs); +                      // if (match(hs, rgx.subhead_links)) { +                      //   if (dochead_metadata[hm][hs].type() == JSON_TYPE.STRING) { +                      //     dochead_metadata[hm][hs].str = to!string(s.captures[2]); +                      //   } +                      // } else { +                      //   writeln("not a valid header type:", hm, ":", hs); +                      //   destroy(hm); +                      //   destroy(hs); +                      // } +                      break; +                    default: +                      break; +                    } +                  } +                } +              } +            } +          } else { +            writeln("not a valid header type:", hm); +          } +        } +        auto t = tuple(dochead_metadata, dochead_make); +        static assert(!isTypeTuple!(t)); +        return t; +      } +      // invariant() { +      // } +    } +    class HeaderMetadataMakeHash { +    // class HeaderMetadataMakeHash : AssertHeaderMetadataMakeHash { +      auto rgx = Rgx(); +      string header_main; +      string[string] head; +      string[string] header_topic_hash(string header) +      in { } +      body { +        if (auto t = match(header, rgx.head_main)) { +          char[][] obj_spl = split( +            cast(char[]) header, +            rgx.line_delimiter_ws_strip +          ); +          auto header_main = to!string(t.captures[1]); +          head[header_main] = "{"; +          foreach (line; obj_spl) { +            if (auto m = match(line, rgx.head_main)) { +              if (!empty(m.captures[2])) { +                head[header_main] ~= +                  "\"" ~ header_main ~ +                  "\": \"" ~ +                  to!string(m.captures[2]) ~ +                  "\","; +              } +            } else if (auto s = match(line, rgx.head_sub)) { +              head[header_main] ~= "\"" ~ s.captures[1] ~ "\":"; +              if (!empty(s.captures[2])) { +                head[header_main] ~= "\"" ~ s.captures[2] ~ "\","; +              } +            } +          } +          head[header_main] = replaceFirst( +            head[header_main], +            rgx.tailing_comma, +            "" +          ); +          head[header_main] ~= "}"; +          debug(headerjson) { +            JSONValue j = parseJSON(head[header_main]); +            assert( +              (j.type == JSON_TYPE.OBJECT) +            ); +          } +        } +        return head; +      } +      invariant() { +      } +    } +    struct BookIndexNuggetHash { +    // class BookIndexNuggetHash : AssertBookIndexNuggetHash { +      string main_term, sub_term, sub_term_bits; +      int obj_cite_number_offset, obj_cite_number_endpoint; +      string[] obj_cite_numbers; +      string[][string][string] bi; +      string[][string][string] hash_nugget; +      string[] bi_main_terms_split_arr; +      string[][string][string] bookindex_nugget_hash(string bookindex_section, int obj_cite_number) +      in { +        debug(bookindexraw) { +          mixin ScreenTxtColors; +          if (!bookindex_section.empty) { +            writeln( +              scr_txt_color["blue"], "* [bookindex] ", scr_txt_color["off"], +              "[", to!string(obj_cite_number), "] ", bookindex_section +            ); +          } +        } +      } +      body { +        auto rgx = Rgx(); +        if (!bookindex_section.empty) { +          auto bi_main_terms_split_arr = +            split(bookindex_section, rgx.bi_main_terms_split); +          foreach (bi_main_terms_content; bi_main_terms_split_arr) { +            auto bi_main_term_and_rest = +              split(bi_main_terms_content, rgx.bi_main_term_plus_rest_split); +            if (auto m = match( +              bi_main_term_and_rest[0], +              rgx.bi_term_and_obj_cite_numbers_match) +            ) { +              main_term = strip(m.captures[1]); +              obj_cite_number_offset = to!int(m.captures[2]); +              obj_cite_number_endpoint=(obj_cite_number + obj_cite_number_offset); +              obj_cite_numbers ~= (to!string(obj_cite_number) ~ "-" ~ to!string(obj_cite_number_endpoint)); +            } else { +              main_term = strip(bi_main_term_and_rest[0]); +              obj_cite_numbers ~= to!string(obj_cite_number); +            } +            bi[main_term]["_a"] ~= obj_cite_numbers; +            obj_cite_numbers=null; +            if (bi_main_term_and_rest.length > 1) { +              auto bi_sub_terms_split_arr = +                split( +                  bi_main_term_and_rest[1], +                  rgx.bi_sub_terms_plus_obj_cite_number_offset_split +                ); +              foreach (sub_terms_bits; bi_sub_terms_split_arr) { +                if (auto m = match(sub_terms_bits, rgx.bi_term_and_obj_cite_numbers_match)) { +                  sub_term = strip(m.captures[1]); +                  obj_cite_number_offset = to!int(m.captures[2]); +                  obj_cite_number_endpoint=(obj_cite_number + obj_cite_number_offset); +                  obj_cite_numbers ~= (to!string(obj_cite_number) ~ " - " ~ to!string(obj_cite_number_endpoint)); +                } else { +                  sub_term = strip(sub_terms_bits); +                  obj_cite_numbers ~= to!string(obj_cite_number); +                } +                if (!empty(sub_term)) { +                  bi[main_term][sub_term] ~= obj_cite_numbers; +                } +                obj_cite_numbers=null; +              } +            } +          } +        } +        hash_nugget = bi; +        return hash_nugget; +      } +      invariant() { +      } +    } +    struct BookIndexReport { +    // class BookIndexReport : AssertBookIndexReport { +      int mkn, skn; +      auto bookindex_report_sorted( +        string[][string][string] bookindex_unordered_hashes +      ) { +        auto mainkeys=bookindex_unordered_hashes.byKey.array. +          sort!("toLower(a) < toLower(b)", SwapStrategy.stable).release; +        foreach (mainkey; mainkeys) { +          auto subkeys=bookindex_unordered_hashes[mainkey].byKey.array. +            sort!("toLower(a) < toLower(b)", SwapStrategy.stable).release; +          foreach (subkey; subkeys) { +            debug(bookindex) { +              writeln( +                mainkey, ": ", +                subkey, ": ", +                to!string(bookindex_unordered_hashes[mainkey][subkey]) +              ); +            } +            ++skn; +          } +          ++mkn; +        } +        // return bookindex_the; +      } +    } +    struct BookIndexReportIndent { +      int mkn, skn; +      auto bookindex_report_indented( +        string[][string][string] bookindex_unordered_hashes +      ) { +        auto mainkeys= +          bookindex_unordered_hashes.byKey.array.sort().release; +        foreach (mainkey; mainkeys) { +          debug(bookindex) { +            writeln(mainkey); +          } +          auto subkeys= +            bookindex_unordered_hashes[mainkey].byKey.array.sort().release; +          foreach (subkey; subkeys) { +            debug(bookindex) { +              writeln("  ", subkey); +              writeln("    ", to!string( +                bookindex_unordered_hashes[mainkey][subkey] +              )); +            } +            // bookindex_the[mkn][mainkey][skn][subkey] ~= (bookindex_unordered_hashes[mainkey][subkey]); +            ++skn; +          } +          ++mkn; +        } +      } +    } +    struct BookIndexReportSection { +      mixin ObjectSetter; +      int mkn, skn; +      auto rgx = Rgx(); +      auto bookindex_write_section( +        string[][string][string] bookindex_unordered_hashes +      ) { +        auto mainkeys=bookindex_unordered_hashes.byKey.array.sort().release; +        foreach (mainkey; mainkeys) { +          write("_0_1 !{", mainkey, "}! "); +          foreach (ref_; bookindex_unordered_hashes[mainkey]["_a"]) { +            auto go = replaceAll(ref_, rgx.book_index_go, "$1"); +            write(" {", ref_, "}#", go, ", "); +          } +          writeln(" \\\\"); +          bookindex_unordered_hashes[mainkey].remove("_a"); +          auto subkeys= +            bookindex_unordered_hashes[mainkey].byKey.array.sort().release; +          foreach (subkey; subkeys) { +            write("  ", subkey, ", "); +            foreach (ref_; bookindex_unordered_hashes[mainkey][subkey]) { +              auto go = replaceAll(ref_, rgx.book_index_go, "$1"); +              write(" {", ref_, "}#", go, ", "); +            } +            writeln(" \\\\"); +            ++skn; +          } +          ++mkn; +        } +      } +      auto bookindex_build_section( +        string[][string][string] bookindex_unordered_hashes, +        int obj_cite_number +      ) { +        string type; +        int type_heading; +        string lev, lev_markup_number, lev_collapsed_number; +        string attrib; +        string[string] indent; +        auto set_abstract_object = ObjectAbstractSet(); +        auto mainkeys = +          bookindex_unordered_hashes.byKey.array.sort().release; +        string bi_tmp; +        string[string][] bookindex_section; +        // writeln(mainkeys.length); +        // B~ Book Index +        type_heading=1; +        bi_tmp = "Book Index"; +        attrib=""; +        lev="B"; +        lev_markup_number="1"; +        lev_collapsed_number="1"; +        bookindex_section ~= +          set_abstract_object.contents_heading( +            type_heading, +            bi_tmp, +            attrib, +            obj_cite_number, +            lev, +            lev_markup_number, +            lev_collapsed_number +          ); +        ++obj_cite_number; +        ++mkn; +        // 1~ Index +        type_heading=1; +        bi_tmp = "Index"; +        attrib=""; +        lev="1"; +        lev_markup_number="4"; +        lev_collapsed_number="2"; +        bookindex_section ~= +          set_abstract_object.contents_heading( +            type_heading, +            bi_tmp, +            attrib, +            obj_cite_number, +            lev, +            lev_markup_number, +            lev_collapsed_number +          ); +        ++obj_cite_number; +        ++mkn; +        foreach (mainkey; mainkeys) { +          bi_tmp = "!{" ~ mainkey ~ "}! "; +          // bi_tmp = "_0_1 !{" ~ mainkey ~ "}! "; +          foreach (ref_; bookindex_unordered_hashes[mainkey]["_a"]) { +            auto go = replaceAll(ref_, rgx.book_index_go, "$1"); +            bi_tmp ~= " {" ~ ref_ ~ "}#" ~ go ~ ", "; +          } +          bi_tmp ~= " \\\\\n    "; +          bookindex_unordered_hashes[mainkey].remove("_a"); +          auto subkeys = +            bookindex_unordered_hashes[mainkey].byKey.array.sort().release; +          foreach (subkey; subkeys) { +            bi_tmp ~= subkey ~ ", "; +            foreach (ref_; bookindex_unordered_hashes[mainkey][subkey]) { +              auto go = replaceAll(ref_, rgx.book_index_go, "$1"); +              bi_tmp ~= " {" ~ ref_ ~ "}#" ~ go ~ ", "; +            } +            bi_tmp ~= " \\\\\n    "; +            ++skn; +          } +          bi_tmp = replaceFirst(bi_tmp, rgx.trailing_linebreak, ""); +          type="para"; +          attrib=""; +          indent["first"] = "0"; +          indent["second"] = "1"; +          attrib=""; +          // bookindex_section ~= +          //   set_abstract_object.contents_para( +          //     obj, +          //     obj_cite_number, +          //     indent, +          //     false +          //   ); +          bookindex_section ~= +            set_abstract_object.contents_para( +              type, +              bi_tmp, +              attrib, +              obj_cite_number, +              indent, +              false +            ); +          ++obj_cite_number; +          ++mkn; +        } +        auto t = tuple(bookindex_section, obj_cite_number); +        return t; +      } +      auto bookindex_build_section_( +        string[][string][string] bookindex_unordered_hashes +      ) { +        auto mainkeys = +          bookindex_unordered_hashes.byKey.array.sort().release; +        string bi_tmp; +        string[] bookindex_section; +        // int bi_num; +        // writeln(mainkeys.length); +        foreach (mainkey; mainkeys) { +          bi_tmp = "_0_1 !{" ~ mainkey ~ "}! "; +          foreach (ref_; bookindex_unordered_hashes[mainkey]["_a"]) { +            auto go = replaceAll(ref_, rgx.book_index_go, "$1"); +            bi_tmp ~= " {" ~ ref_ ~ "}#" ~ go ~ ", "; +          } +          bi_tmp ~= " \\\\\n    "; +          bookindex_unordered_hashes[mainkey].remove("_a"); +          auto subkeys = +            bookindex_unordered_hashes[mainkey].byKey.array.sort().release; +          foreach (subkey; subkeys) { +            bi_tmp ~= subkey ~ ", "; +            // bi_tmp ~= "  " ~ subkey ~ ", "; +            foreach (ref_; bookindex_unordered_hashes[mainkey][subkey]) { +              auto go = replaceAll(ref_, rgx.book_index_go, "$1"); +              bi_tmp ~= " {" ~ ref_ ~ "}#" ~ go ~ ", "; +            } +            bi_tmp ~= " \\\\\n    "; +            ++skn; +          } +          bi_tmp = replaceFirst(bi_tmp, rgx.trailing_linebreak, ""); +          bookindex_section ~= bi_tmp; +          ++mkn; +        } +        return bookindex_section; +      } +    } +    struct NotesSection { +      mixin ObjectSetter; +      string object_notes; +      long previous_count; +      int mkn; +      auto rgx = Rgx(); +      private auto gather_notes_for_endnote_section( +        string[string][] contents_am, +        long counter +      ) +      in { +        // endnotes/ footnotes for +        // doc objects other than paragraphs & headings +        // various forms of grouped text +        assert((contents_am[counter]["is"] == "para") +        || (contents_am[counter]["is"] == "heading")); +        assert(counter > previous_count); +        previous_count=counter; +        assert( +          match(contents_am[counter]["obj"], +          rgx.inline_notes_delimiter_al_regular_number_note) +        ); +      } +      body { +        foreach(m; +        matchAll(contents_am[counter]["obj"], +        rgx.inline_notes_delimiter_al_regular_number_note)) { +          debug(endnotes_build) { +            writeln( +              "{^{", m.captures[1], ".}^}#noteref_", m.captures[1], " ", +              m.captures[2]); // sometimes need segment name (segmented html & epub) +            // writeln("{^{", m.captures[1], ".}^}#", contents_am[counter]["obj_cite_number"], " ", m.captures[2]); +          } +          object_notes ~= +            "{^{" ~ m.captures[1] ~ ".}^}#noteref_" ~ +            m.captures[1] ~ " " ~ m.captures[2] ~ "』"; +        } +        return object_notes; +      } +      private auto gathered_notes() +      in { +      } +      body { +        string[] endnotes_; +        if (object_notes.length > 1) { +          endnotes_ = (split(object_notes, rgx.break_string))[0..$-1]; +        } +        return endnotes_; +      } +      private auto endnote_objects(int obj_cite_number) +      in { +      } +      body { +        auto set_abstract_object = ObjectAbstractSet(); +        string[string][] endnotes_section; +        auto endnotes_ = gathered_notes(); +        // auto endnotes_ = (split(object_notes, rgx.break_string))[0..$-1]; +        string type; +        int type_heading; +        string lev, lev_markup_number, lev_collapsed_number; +        string attrib; +        string[string] indent; +        // B~ Endnotes +        type_heading=1; +        attrib=""; +        lev="B"; +        lev_markup_number="1"; +        lev_collapsed_number="1"; +        endnotes_section ~= +          set_abstract_object.contents_heading( +            type_heading, +            "Endnotes", +            attrib, +            obj_cite_number, +            lev, +            lev_markup_number, +            lev_collapsed_number +          ); +        ++obj_cite_number; +        ++mkn; +        // 1~ Endnotes +        type_heading=1; +        attrib=""; +        lev="1"; +        lev_markup_number="4"; +        lev_collapsed_number="2"; +        endnotes_section ~= +          set_abstract_object.contents_heading( +            type_heading, +            "Endnotes", +            attrib, +            obj_cite_number, +            lev, +            lev_markup_number, +            lev_collapsed_number +          ); +        ++obj_cite_number; +        ++mkn; +        foreach (endnote; endnotes_) { +          type="para"; +          attrib=""; +          indent["first"] = "0"; +          indent["second"] = "0"; +          attrib=""; +          // endnotes ~= +          //   set_abstract_object.contents_para( +          //     obj, +          //     obj_cite_number, +          //     indent, +          //     false +          //   ); +          endnotes_section ~= +            set_abstract_object.contents_para( +              type, +              endnote, +              attrib, +              obj_cite_number, +              indent, +              false +            ); +          ++obj_cite_number; +          ++mkn; +        } +        auto t = tuple(endnotes_section, obj_cite_number); +        return t; +      } +    } +    struct Bibliography { +      public JSONValue[] bibliography(ref string[] biblio_unsorted_incomplete, ref JSONValue[] bib_arr_json) +      in { } +      body { +        JSONValue[] biblio_unsorted = +          biblio_unsorted_complete(biblio_unsorted_incomplete, bib_arr_json); +        JSONValue[] biblio_sorted = biblio_sort(biblio_unsorted); +        biblio_debug(biblio_sorted); +        return biblio_sorted; +      } +      final private JSONValue[] biblio_unsorted_complete( +        string[] biblio_unordered, +        ref 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; +        } +        JSONValue[] biblio_unsorted_array_of_json_objects = +          bib_arr_json.dup; +        return biblio_unsorted_array_of_json_objects; +      } +      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"]); +              // writeln(j["deemed_author"], " (", j["author"], ") ",  j["fulltitle"]); +            } +          } +        } +        return biblio_sorted; +      } +      auto biblio_debug(JSONValue[] biblio_sorted) { +        debug(biblio) { +          foreach (j; biblio_sorted) { +            if (!empty(j["fulltitle"].str)) { +              writeln(j["sortby_deemed_author_year_title"]); +            } +          } +        } +      } +    } +    struct NodeStructureMetadata { +    // class NodeStructureMetadata : AssertNodeJSON { +      int lv, lv0, lv1, lv2, lv3, lv4, lv5, lv6, lv7; +      int obj_cite_number; +      int[string] p_; // p_ parent_ +      string node; +      string node_emitter( +        string lev_markup_number, +        int obj_cite_number_, +        long counter_, +        int pointer_, +        string is_ +      ) +      in { +        auto rgx = Rgx(); +        assert(is_ != "heading"); +        assert(to!int(obj_cite_number_) >= 0); +      } +      body { +        // scope(failure) { +        //   writeln(__FILE__, ":", __LINE__, " failed here:"); +        //   writeln("  is  : ", is_); +        //   writeln("  node: ", node); +        // } +        assert(is_ != "heading"); // should not be necessary +        assert(to!int(obj_cite_number_) >= 0); // should not be necessary +        int obj_cite_number=to!int(obj_cite_number_); +        if (lv7 > State.off) { +          p_["lev_markup_number"] = DocStructMarkupHeading.h_text_4; +          p_["obj_cite_number"] = lv7; +        } else if (lv6 > State.off) { +          p_["lev_markup_number"] = DocStructMarkupHeading.h_text_3; +          p_["obj_cite_number"] = lv6; +        } else if (lv5 > State.off) { +          p_["lev_markup_number"] = DocStructMarkupHeading.h_text_2; +          p_["obj_cite_number"] = lv5; +        } else { +          p_["lev_markup_number"] = DocStructMarkupHeading.h_text_1; +          p_["obj_cite_number"] = lv4; +        } +        node=("{ " ~ +          "\"is\": \"" ~ is_ ~ "\"" ~ +          ", \"heading_pointer\": " ~ to!string(pointer_) ~ +          ", \"doc_object_pointer\": " ~ to!string(counter_) ~ +          ", \"obj_cite_number\": " ~ to!string(obj_cite_number_) ~ +          ", \"parent_obj_cite_number\": " ~ to!string(p_["obj_cite_number"]) ~ +          ", \"parent_lev_markup_number\": " ~ to!string(p_["lev_markup_number"]) ~ +          " }" +        ); +        debug(node) { +          mixin ScreenTxtColors; +          if (match(lev_markup_number, rgx.levels_numbered_headings)) { +            writeln(scr_txt_marker["yellow"], to!string(node)); +          } else { +            writeln(scr_txt_marker["white"], to!string(node)); +          } +        } +        JSONValue j = parseJSON(node); +        assert(j["parent_lev_markup_number"].integer >= 4); +        assert(j["parent_lev_markup_number"].integer <= 7); +        assert(j["parent_obj_cite_number"].integer >= 0); +        return node; +      } +      invariant() { +      } +      string node_emitter_heading( +        string lev_markup_number, +        string lev_collapsed_number, +        int obj_cite_number_, +        long counter_, +        int pointer_, +        string is_ +      ) +      in { +        auto rgx = Rgx(); +        assert(is_ == "heading"); +        assert(to!int(obj_cite_number_) >= 0); +        assert( +          match(lev_markup_number, rgx.levels_numbered), +          ("not a valid heading level: " ~ lev_markup_number ~ " at " ~ to!string(obj_cite_number_)) +        ); +        // assert(to!int(obj_cite_number_) >= 0); +        if (match(lev_markup_number, rgx.levels_numbered)) { +          if (to!int(lev_markup_number) == 0) { +            assert(to!int(obj_cite_number_) == 1); +            // writeln(lev_markup_number); +          } +        } +      } +      body { +        // scope(failure) { +        //   writeln(__FILE__, ":", __LINE__, " failed here:"); +        //   writeln("  is  : ", is_); +        //   writeln("  node: ", node); +        // } +        auto rgx = Rgx(); +        int obj_cite_number = to!int(obj_cite_number_); +        switch (lev_markup_number) { // switch (to!string(lv)) { +        case "0": +          lv = DocStructMarkupHeading.h_sect_A; +          lv0 = obj_cite_number; +          lv1=0; lv2=0; lv3=0; lv4=0; lv5=0; lv6=0; lv7=0; +          p_["lev_markup_number"] = 0; +          p_["obj_cite_number"] = 0; +          break; +        case "1": +          lv = DocStructMarkupHeading.h_sect_B; +          lv1 = obj_cite_number; +          lv2=0; lv3=0; lv4=0; lv5=0; lv6=0; lv7=0; +          p_["lev_markup_number"] = +            DocStructMarkupHeading.h_sect_A; +          p_["obj_cite_number"] = lv0; +          break; +        case "2": +          lv = DocStructMarkupHeading.h_sect_C; +          lv2 = obj_cite_number; +          lv3=0; lv4=0; lv5=0; lv6=0; lv7=0; +          p_["lev_markup_number"] = +            DocStructMarkupHeading.h_sect_B; +          p_["obj_cite_number"] = lv1; +          break; +        case "3": +          lv = DocStructMarkupHeading.h_sect_D; +          lv3=obj_cite_number; +          lv4=0; lv5=0; lv6=0; lv7=0; +          p_["lev_markup_number"] = +            DocStructMarkupHeading.h_sect_C; +          p_["obj_cite_number"] = lv2; +          break; +        case "4": +          lv = DocStructMarkupHeading.h_text_1; +          lv4 = obj_cite_number; +          lv5=0; lv6=0; lv7=0; +          if (lv3 > State.off) { +            p_["lev_markup_number"] = +              DocStructMarkupHeading.h_sect_D; +            p_["obj_cite_number"] = lv3; +          } else if (lv2 > State.off) { +            p_["lev_markup_number"] = +              DocStructMarkupHeading.h_sect_C; +            p_["obj_cite_number"] = lv2; +          } else if (lv1 > State.off) { +            p_["lev_markup_number"] = +              DocStructMarkupHeading.h_sect_B; +            p_["obj_cite_number"] = lv1; +          } else { +            p_["lev_markup_number"] = +              DocStructMarkupHeading.h_sect_A; +            p_["obj_cite_number"] = lv0; +          } +          break; +        case "5": +          lv = DocStructMarkupHeading.h_text_2; +          lv5 = obj_cite_number; +          lv6=0; lv7=0; +          p_["lev_markup_number"] = +            DocStructMarkupHeading.h_text_1; +          p_["obj_cite_number"] = lv4; +          break; +        case "6": +          lv = DocStructMarkupHeading.h_text_3; +          lv6 = obj_cite_number; +          lv7=0; +          p_["lev_markup_number"] = +            DocStructMarkupHeading.h_text_2; +          p_["obj_cite_number"] = lv5; +          break; +        case "7": +          lv = DocStructMarkupHeading.h_text_4; +          lv7 = obj_cite_number; +          p_["lev_markup_number"] = +            DocStructMarkupHeading.h_text_3; +          p_["obj_cite_number"] = lv6; +          break; +        default: +          // if (lv7 > State.off) { +          //   p_["lev_markup_number"] = 7; p_["obj_cite_number"] = lv7; +          // } else if (lv6 > State.off) { +          //   p_["lev_markup_number"] = 6; p_["obj_cite_number"] = lv6; +          // } else if (lv5 > State.off) { +          //   p_["lev_markup_number"] = 5; p_["obj_cite_number"] = lv5; +          // } else { +          //   p_["lev_markup_number"] = 4; p_["obj_cite_number"] = lv4; +          // } +          break; +        } +        node=("{ " ~ +          "\"is\": \"" ~ is_ ~ "\"" ~ +          ", \"heading_pointer\": " ~ to!string(pointer_) ~ +          ", \"doc_object_pointer\": " ~ to!string(counter_) ~ +          ", \"obj_cite_number\": " ~ to!string(obj_cite_number_) ~ +          ",  \"lev_markup_number\": " ~ to!string(lev_markup_number) ~ +          ",  \"lev_collapsed_number\": " ~ to!string(lev_collapsed_number) ~ +          ", \"parent_obj_cite_number\": " ~ to!string(p_["obj_cite_number"]) ~ +          ", \"parent_lev_markup_number\": " ~ to!string(p_["lev_markup_number"]) ~ +          " }" +        ); +        debug(heading) { +          mixin ScreenTxtColors; +          if (match(lev_markup_number, rgx.levels_numbered_headings)) { +            writeln(scr_txt_marker["yellow"], to!string(node)); +          } +        } +        debug(node) { +          mixin ScreenTxtColors; +          if (match(lev_markup_number, rgx.levels_numbered_headings)) { +            writeln(scr_txt_marker["yellow"], to!string(node)); +          } else { +            writeln(scr_txt_marker["white"], to!string(node)); +          } +        } +        JSONValue j = parseJSON(node); +        assert(j["parent_lev_markup_number"].integer <= 7); +        assert(j["parent_obj_cite_number"].integer >= 0); +        if (match(lev_markup_number, rgx.levels_numbered_headings)) { +          assert(j["lev_markup_number"].integer <= 7); +          assert(j["obj_cite_number"].integer >= 0); +          if (j["parent_lev_markup_number"].integer > 0) { +            assert(j["parent_lev_markup_number"].integer < j["lev_markup_number"].integer); +            if (j["obj_cite_number"].integer != 0) { +              assert(j["parent_obj_cite_number"].integer < j["obj_cite_number"].integer); +            } +          } +          if (j["lev_markup_number"].integer == 0) { +            assert(j["parent_lev_markup_number"].integer == DocStructMarkupHeading.h_sect_A); +          } else if  (j["lev_markup_number"].integer == DocStructMarkupHeading.h_sect_B) { +            assert(j["parent_lev_markup_number"].integer == DocStructMarkupHeading.h_sect_A); +          } else if  (j["lev_markup_number"].integer == DocStructMarkupHeading.h_sect_C) { +            assert(j["parent_lev_markup_number"].integer == DocStructMarkupHeading.h_sect_B); +          } else if  (j["lev_markup_number"].integer == DocStructMarkupHeading.h_sect_D) { +            assert(j["parent_lev_markup_number"].integer == DocStructMarkupHeading.h_sect_C); +          } else if  (j["lev_markup_number"].integer == DocStructMarkupHeading.h_text_1) { +            assert(j["parent_lev_markup_number"].integer <= DocStructMarkupHeading.h_sect_D); +          } else if  (j["lev_markup_number"].integer == DocStructMarkupHeading.h_text_2) { +            assert(j["parent_lev_markup_number"].integer == DocStructMarkupHeading.h_text_1); +          } else if  (j["lev_markup_number"].integer == DocStructMarkupHeading.h_text_3) { +            assert(j["parent_lev_markup_number"].integer == DocStructMarkupHeading.h_text_2); +          } else if  (j["lev_markup_number"].integer == DocStructMarkupHeading.h_text_4) { +            assert(j["parent_lev_markup_number"].integer == DocStructMarkupHeading.h_text_3); +          } else if  (j["lev_markup_number"].integer == DocStructMarkupHeading.h_text_5) { +            // writeln(j["parent_lev_markup_number"].integer); +            // assert(j["parent_lev_markup_number"].integer >= 4); +            // assert(j["parent_lev_markup_number"].integer <= 7); +          } +        } +        return node; +      } +      invariant() { +      } +    } +    /+ abstraction functions emitters ↑ +/ + +    /+ ↓ abstraction functions assertions +/ +    auto assertions_doc_structure(string[string] an_object, int[string] lv) { +      if (lv["h3"] > State.off) { +        assert(lv["h0"] > State.off); +        assert(lv["h1"] > State.off); +        assert(lv["h2"] > State.off); +      } else if (lv["h2"] > State.off) { +        assert(lv["h0"] > State.off); +        assert(lv["h1"] > State.off); +        assert(lv["h3"] == State.off); +      } else if (lv["h1"] > State.off) { +        assert(lv["h0"] > State.off); +        assert(lv["h2"] == State.off); +        assert(lv["h3"] == State.off); +      } else if (lv["h0"] > State.off) { +        assert(lv["h1"] == State.off); +        assert(lv["h2"] == State.off); +        assert(lv["h3"] == State.off); +      } else { +        assert(lv["h0"] == State.off); +        assert(lv["h1"] == State.off); +        assert(lv["h2"] == State.off); +        assert(lv["h3"] == State.off); +      } +      if (lv["h7"] > State.off) { +        assert(lv["h4"] > State.off); +        assert(lv["h5"] > State.off); +        assert(lv["h6"] > State.off); +      } else if (lv["h6"] > State.off) { +        assert(lv["h4"] > State.off); +        assert(lv["h5"] > State.off); +        assert(lv["h7"] == State.off); +      } else if (lv["h5"] > State.off) { +        assert(lv["h4"] > State.off); +        assert(lv["h6"] == State.off); +        assert(lv["h7"] == State.off); +      } else if (lv["h4"] > State.off) { +        assert(lv["h5"] == State.off); +        assert(lv["h6"] == State.off); +        assert(lv["h7"] == State.off); +      } else { +        assert(lv["h4"] == State.off); +        assert(lv["h5"] == State.off); +        assert(lv["h6"] == State.off); +        assert(lv["h7"] == State.off); +      } +      if (lv["h0"] == State.off) { +        assert(lv["h1"] == State.off); +        assert(lv["h2"] == State.off); +        assert(lv["h3"] == State.off); +        assert(lv["h4"] == State.off); +        assert(lv["h5"] == State.off); +        assert(lv["h6"] == State.off); +        assert(lv["h7"] == State.off); +      } +      if (lv["h1"] == State.off) { +        assert(lv["h2"] == State.off); +        assert(lv["h3"] == State.off); +      } +      if (lv["h2"] == State.off) { +        assert(lv["h3"] == State.off); +      } +      if (lv["h3"] == State.off) { +      } +      if (lv["h4"] == State.off) { +        assert(lv["h5"] == State.off); +        assert(lv["h6"] == State.off); +        assert(lv["h7"] == State.off); +      } +      if (lv["h5"] == State.off) { +        assert(lv["h6"] == State.off); +        assert(lv["h7"] == State.off); +      } +      if (lv["h6"] == State.off) { +        assert(lv["h7"] == State.off); +      } +      if (lv["h7"] == State.off) { +      } +      switch (to!string(an_object["lev"])) { +      case "A": +        if (lv["h0"] == State.off) { +          assert(lv["h1"] == State.off); +          assert(lv["h2"] == State.off); +          assert(lv["h3"] == State.off); +          assert(lv["h4"] == State.off); +          assert(lv["h5"] == State.off); +          assert(lv["h6"] == State.off); +          assert(lv["h7"] == State.off); +        } else {  // (lv["h0"] > State.off) +          assert(lv["h0"] == State.off,"error should not enter level A a second time"); +        } +        break; +      case "B": +        if (lv["h1"] == State.off) { +          assert(lv["h0"] > State.off); +          assert(lv["h2"] == State.off); +          assert(lv["h3"] == State.off); +        } else {                 // (lv["h1"] > State.off) +          assert(lv["h0"] > State.off); +          assert(lv["h1"] > State.off);  // +        } +        break; +      case "C": +        if (lv["h2"] == State.off) { +          assert(lv["h0"] > State.off); +          assert(lv["h1"] > State.off); +          assert(lv["h3"] == State.off); +        } else {                 // (lv["h2"] > State.off) +          assert(lv["h0"] > State.off); +          assert(lv["h1"] > State.off); +          assert(lv["h2"] > State.off);  // +        } +        break; +      case "D": +        if (lv["h3"] == State.off) { +          assert(lv["h0"] > State.off); +          assert(lv["h1"] > State.off); +          assert(lv["h2"] > State.off); +        } else {                 // (lv["h3"] > State.off) +          assert(lv["h0"] > State.off); +          assert(lv["h1"] > State.off); +          assert(lv["h2"] > State.off); +          assert(lv["h3"] > State.off); +        } +        break; +      case "1": +        if (lv["h4"] == State.off) { +          assert(lv["h0"] > State.off); +        } else {                 // (lv["h4"] > State.off) +          assert(lv["h0"] > State.off); +          assert(lv["h4"] > State.off);  // +        } +        break; +      case "2": +        if (lv["h5"] == State.off) { +          assert(lv["h0"] > State.off); +          assert(lv["h4"] > State.off); +        } else {                 // (lv["h5"] > State.off) +          assert(lv["h0"] > State.off); +          assert(lv["h4"] > State.off); +          assert(lv["h5"] > State.off);  // +        } +        break; +      case "3": +        if (lv["h6"] == State.off) { +          assert(lv["h0"] > State.off); +          assert(lv["h4"] > State.off); +          assert(lv["h5"] > State.off); +        } else {                 // (lv["h6"] > State.off) +          assert(lv["h0"] > State.off); +          assert(lv["h4"] > State.off); +          assert(lv["h5"] > State.off); +          assert(lv["h6"] > State.off);  // +        } +        break; +      case "4": +        if (lv["h7"] == State.off) { +          assert(lv["h0"] > State.off); +          assert(lv["h4"] > State.off); +          assert(lv["h5"] > State.off); +          assert(lv["h6"] > State.off); +        } else {                 // (lv["h7"] > State.off) +          assert(lv["h0"] > State.off); +          assert(lv["h4"] > State.off); +          assert(lv["h5"] > State.off); +          assert(lv["h6"] > State.off); +          assert(lv["h7"] > State.off);  // +        } +        break; +      default: +        break; +      } +    } +    auto assertions_flag_types_block_status_none_or_closed(int[string] type) { +      assert( +        (type["code"] == TriState.off) +        || (type["code"] == TriState.closing), +        "code block status: off or closing"); +      assert( +        (type["poem"] == TriState.off) +        || (type["poem"] == TriState.closing), +        "poem status: off or closing"); +      assert( +        (type["table"] == TriState.off) +        || (type["table"] == TriState.closing), +        "table status: off or closing"); +      assert( +        (type["group"] == TriState.off) +        || (type["group"] == TriState.closing), +        "group block status: off or closing"); +      assert( +        (type["block"] == TriState.off) +        || (type["block"] == TriState.closing), +        "block status: off or closing");      } -  } -} +    /+ abstraction functions assertions ↑ +/ + +  } /+ ← closed: struct Abstraction +/ + +} /+ ← closed: template SiSUdocAbstraction +/ diff --git a/lib/sdp/ao_utils.d b/lib/sdp/ao_ansi_colors.d index e5245dd..e5a46f9 100644 --- a/lib/sdp/ao_utils.d +++ b/lib/sdp/ao_ansi_colors.d @@ -2,7 +2,7 @@    utils    ao_util.d  +/ -mixin template ScreenTxtColors() { +template ScreenTxtColors() {    string[string] scr_txt_color = [      "off"           : "\033[0m",      "white"         : "\033[37m", diff --git a/lib/sdp/ao_assertions.d b/lib/sdp/ao_assertions.d deleted file mode 100644 index 2aa2c1d..0000000 --- a/lib/sdp/ao_assertions.d +++ /dev/null @@ -1,221 +0,0 @@ -/+ -  assertions -  ao_assertions.d -+/ -mixin template AssertionsOnMarkupDocumentStructure() { -  auto assertions_doc_structure(string[string] object, uint[string] lv) { -    if (lv["h3"] > 0) { -      assert(lv["h0"] > 0); -      assert(lv["h1"] > 0); -      assert(lv["h2"] > 0); -      assert(lv["h3"] > 0); -    } else if (lv["h2"] > 0) { -      assert(lv["h0"] > 0); -      assert(lv["h1"] > 0); -      assert(lv["h2"] > 0); -      assert(lv["h3"] == 0); -    } else if (lv["h1"] > 0) { -      assert(lv["h0"] > 0); -      assert(lv["h1"] > 0); -      assert(lv["h2"] == 0); -      assert(lv["h3"] == 0); -    } else if (lv["h0"] > 0) { -      assert(lv["h0"] > 0); -      assert(lv["h1"] == 0); -      assert(lv["h2"] == 0); -      assert(lv["h3"] == 0); -    } else { -      assert(lv["h0"] == 0); -      assert(lv["h1"] == 0); -      assert(lv["h2"] == 0); -      assert(lv["h3"] == 0); -    } -    if (lv["h7"] > 0) { -      assert(lv["h4"] > 0); -      assert(lv["h5"] > 0); -      assert(lv["h6"] > 0); -      assert(lv["h7"] > 0); -    } else if (lv["h6"] > 0) { -      assert(lv["h4"] > 0); -      assert(lv["h5"] > 0); -      assert(lv["h6"] > 0); -      assert(lv["h7"] == 0); -    } else if (lv["h5"] > 0) { -      assert(lv["h4"] > 0); -      assert(lv["h5"] > 0); -      assert(lv["h6"] == 0); -      assert(lv["h7"] == 0); -    } else if (lv["h4"] > 0) { -      assert(lv["h4"] > 0); -      assert(lv["h5"] == 0); -      assert(lv["h6"] == 0); -      assert(lv["h7"] == 0); -    } else { -      assert(lv["h4"] == 0); -      assert(lv["h5"] == 0); -      assert(lv["h6"] == 0); -      assert(lv["h7"] == 0); -    } -    if (lv["h0"] == 0) { -      assert(lv["h0"] == 0); -      assert(lv["h1"] == 0); -      assert(lv["h2"] == 0); -      assert(lv["h3"] == 0); -      assert(lv["h4"] == 0); -      assert(lv["h5"] == 0); -      assert(lv["h6"] == 0); -      assert(lv["h7"] == 0); -    } -    if (lv["h1"] == 0) { -      assert(lv["h1"] == 0); -      assert(lv["h2"] == 0); -      assert(lv["h3"] == 0); -    } -    if (lv["h2"] == 0) { -      assert(lv["h2"] == 0); -      assert(lv["h3"] == 0); -    } -    if (lv["h3"] == 0) { -      assert(lv["h3"] == 0); -    } -    if (lv["h4"] == 0) { -      assert(lv["h4"] == 0); -      assert(lv["h5"] == 0); -      assert(lv["h6"] == 0); -      assert(lv["h7"] == 0); -    } -    if (lv["h5"] == 0) { -      assert(lv["h5"] == 0); -      assert(lv["h6"] == 0); -      assert(lv["h7"] == 0); -    } -    if (lv["h6"] == 0) { -      assert(lv["h6"] == 0); -      assert(lv["h7"] == 0); -    } -    if (lv["h6"] == 0) { -      assert(lv["h7"] == 0); -    } -    switch (to!string(object["lev"])) { -    case "A": -      if (lv["h0"]==0) { -        assert(lv["h0"] == 0); -        assert(lv["h1"] == 0); -        assert(lv["h2"] == 0); -        assert(lv["h3"] == 0); -        assert(lv["h4"] == 0); -        assert(lv["h5"] == 0); -        assert(lv["h6"] == 0); -        assert(lv["h7"] == 0); -      } else {  // (lv["h0"] >0) -        assert(lv["h0"] == 0,"error should not enter level A a second time"); -      } -      break; -    case "B": -      if (lv["h1"]==0) { -        assert(lv["h0"] > 0); -        assert(lv["h1"] == 0); // -        assert(lv["h2"] == 0); -        assert(lv["h3"] == 0); -      } else {                 // (lv["h1"] >0) -        assert(lv["h0"] > 0); -        assert(lv["h1"] > 0);  // -      } -      break; -    case "C": -      if (lv["h2"]==0) { -        assert(lv["h0"] > 0); -        assert(lv["h1"] > 0); -        assert(lv["h2"] == 0); // -        assert(lv["h3"] == 0); -      } else {                 // (lv["h2"] > 0) -        assert(lv["h0"] > 0); -        assert(lv["h1"] > 0); -        assert(lv["h2"] > 0);  // -      } -      break; -    case "D": -      if (lv["h3"]==0) { -        assert(lv["h0"] > 0); -        assert(lv["h1"] > 0); -        assert(lv["h2"] > 0); -        assert(lv["h3"] == 0); // -      } else {                 // (lv["h3"] >0) -        assert(lv["h0"] > 0); -        assert(lv["h1"] > 0); -        assert(lv["h2"] > 0); -        assert(lv["h3"] > 0); -      } -      break; -    case "1": -      if (lv["h4"]==0) { -        assert(lv["h0"] > 0); -        assert(lv["h4"] == 0); // -      } else {                 // (lv["h4"] >0) -        assert(lv["h0"] > 0); -        assert(lv["h4"] > 0);  // -      } -      break; -    case "2": -      if (lv["h5"]==0) { -        assert(lv["h0"] > 0); -        assert(lv["h4"] > 0); -        assert(lv["h5"] == 0); // -      } else {                 // (lv["h5"] >0) -        assert(lv["h0"] > 0); -        assert(lv["h4"] > 0); -        assert(lv["h5"] > 0);  // -      } -      break; -    case "3": -      if (lv["h6"]==0) { -        assert(lv["h0"] > 0); -        assert(lv["h4"] > 0); -        assert(lv["h5"] > 0); -        assert(lv["h6"] == 0); // -      } else {                 // (lv["h6"] >0) -        assert(lv["h0"] > 0); -        assert(lv["h4"] > 0); -        assert(lv["h5"] > 0); -        assert(lv["h6"] > 0);  // -      } -      break; -    case "4": -      if (lv["h7"]==0) { -        assert(lv["h0"] > 0); -        assert(lv["h4"] > 0); -        assert(lv["h5"] > 0); -        assert(lv["h6"] > 0); -        assert(lv["h7"] == 0); // -      } else {                 // (lv["h7"] >0) -        assert(lv["h0"] > 0); -        assert(lv["h4"] > 0); -        assert(lv["h5"] > 0); -        assert(lv["h6"] > 0); -        assert(lv["h7"] > 0);  // -      } -      break; -    default: -      break; -    } -  } -} -mixin template AssertionsOnBlocks() { -  auto assertions_flag_types_block_status_none_or_closed(int[string] flag_type) { -    assert( -      (flag_type["code"] == 0) || (flag_type["code"] == 2), -      "code block status: none or closed"); -    assert( -      (flag_type["poem"] == 0) || (flag_type["poem"] == 2), -      "poem status: none or closed"); -    assert( -      (flag_type["table"] == 0) || (flag_type["table"] == 2), -      "table status: none or closed"); -    assert( -      (flag_type["group"] == 0) || (flag_type["group"] == 2), -      "group block status: none or closed"); -    assert( -      (flag_type["block"] == 0) || (flag_type["block"] == 2), -      "block status: none or closed"); -  } -} diff --git a/lib/sdp/ao_defaults.d b/lib/sdp/ao_defaults.d index 166871b..04f5506 100644 --- a/lib/sdp/ao_defaults.d +++ b/lib/sdp/ao_defaults.d @@ -167,37 +167,40 @@ template SiSUheader() {  }  /+ regex flags +/  template SiSUrgxInitFlags() { -  int[string] flag_type = [ -    "make_headings"        : 0, -    "header_make"          : 0, -    "header_metadata"      : 0, -    "heading"              : 0, -    "heading_biblio"       : 0, -    "para"                 : 0, -    "blocks"               : 0, // 0..2 generic -    "code"                 : 0, // 0..2 -    "poem"                 : 0, // 0..2 -    "table"                : 0, // 0..2 -    "group"                : 0, // 0..2 -    "block"                : 0, // 0..2 -    "quote"                : 0, // 0..2 -    "verse_new"            : 0, -    "curly_code"           : 0, -    "curly_poem"           : 0, -    "curly_table"          : 0, -    "curly_group"          : 0, -    "curly_block"          : 0, -    "curly_quote"          : 0, -    "tic_code"             : 0, -    "tic_poem"             : 0, -    "tic_table"            : 0, -    "tic_group"            : 0, -    "tic_block"            : 0, -    "tic_quote"            : 0, -    "ocn_status"           : 0, // 0 ocn; 1 no ocn; 2 no ocn & dummy headings -    "ocn_status_multi_obj" : 0, // 0 ocn; 1 no ocn; 2 no ocn & dummy headings -    "book_index"           : 0, -  ]; +  int[string] flags_type_init() { +    int[string] flags_type_init = [ +      "make_headings"        : 0, +      "header_make"          : 0, +      "header_metadata"      : 0, +      "heading"              : 0, +      "heading_biblio"       : 0, +      "para"                 : 0, +      "blocks"               : 0, // 0..2 generic +      "code"                 : 0, // 0..2 +      "poem"                 : 0, // 0..2 +      "table"                : 0, // 0..2 +      "group"                : 0, // 0..2 +      "block"                : 0, // 0..2 +      "quote"                : 0, // 0..2 +      "verse_new"            : 0, +      "curly_code"           : 0, +      "curly_poem"           : 0, +      "curly_table"          : 0, +      "curly_group"          : 0, +      "curly_block"          : 0, +      "curly_quote"          : 0, +      "tic_code"             : 0, +      "tic_poem"             : 0, +      "tic_table"            : 0, +      "tic_group"            : 0, +      "tic_block"            : 0, +      "tic_quote"            : 0, +      "obj_cite_number_status"           : 0, // 0 obj_cite_number; 1 no obj_cite_number; 2 no obj_cite_number & dummy headings +      "obj_cite_number_status_multi_obj" : 0, // 0 obj_cite_number; 1 no obj_cite_number; 2 no obj_cite_number & dummy headings +      "book_index"           : 0, +    ]; +    return flags_type_init; +  }  }  template SiSUbiblio() {    auto biblio_entry_tags_jsonstr =  `{ @@ -229,31 +232,15 @@ template SiSUbiblio() {      "short_name"                       : "",      "id"                               : ""    }`; // is: book, article, magazine, newspaper, blog, other -  auto biblio_tag_map = [ -    "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" -  ]; // is: book, article, magazine, newspaper, blog, other  }  template InternalMarkup() { -  struct InternalMarkup { +  struct InlineMarkup {      auto en_a_o = "【"; auto en_a_c = "】";      auto en_b_o = "〖"; auto en_b_c = "〗";      // auto segname_prefix_auto_num_extract = "c";      // auto segname_prefix_auto_num_provide = "s";      // auto segname_prefix_auto_num_other = "x"; -    // auto ocn_id_char = "";                                              //'o'; now as before; remove for html5 +    // auto obj_cite_number_id_char = "";                                              //'o'; now as before; remove for html5      // auto note = "note_";      // auto note_ref = "noteref_";      // auto note_astx = "note_astx_"; diff --git a/lib/sdp/ao_object_setter.d b/lib/sdp/ao_object_setter.d index ce4611d..a44aeb0 100644 --- a/lib/sdp/ao_object_setter.d +++ b/lib/sdp/ao_object_setter.d @@ -2,174 +2,92 @@    object setter    ao_object_setter.d  +/ -mixin template ObjectSetters() { +template ObjectSetter() {    struct ObjectAbstractSet {      import std.conv : to; -    mixin Structs; -    ObjComposite contents_comment_new(in string object) { -      ObjComposite object_set; -      object_set.use                  = "comment"; -      object_set.of                   = "comment"; -      object_set.is_a                 = "comment"; -      object_set.object               = object; -      // does not have .attrib; -      // does not have .ocn -      return object_set; -    }      string[string] contents_comment(in string object) {        string[string] object_set;        object_set["use"]           = "comment";        object_set["of"]            = "comment";        object_set["is"]            = "comment";        object_set["obj"]           = object; -      return object_set; -    } -    ObjComposite contents_heading_new( -      in int type, -      in string object, -      in string attrib, -      in int ocn, -      in string lev, -      in string lvn, -      in string lcn, -    ) { -      ObjComposite object_set; -      object_set.use                  = "content"; -      object_set.of                   = "para"; -      object_set.is_a                 = "heading"; -      object_set.object               = object; -      object_set.ocn                  = (ocn==0) ? "" : to!string(ocn); -      object_set.attrib               = attrib; -      object_set.heading.type         = to!string(type); -      object_set.heading.lev          = to!string(lev); -      object_set.heading.lvn          = to!string(lvn); -      object_set.heading.lcn          = to!string(lcn); +      // object_set["attrib"]     = attrib;        return object_set;      }      string[string] contents_heading(        in int type,        in string object,        in string attrib, -      in int ocn, +      in int obj_cite_number,        in string lev, -      in string lvn, -      in string lcn, +      in string lev_markup_number, +      in string lev_collapsed_number,      ) {        string[string] object_set; -      object_set["use"]           = "content"; -      object_set["of"]            = "para"; -      object_set["is"]            = "heading"; -      object_set["type"]          = to!string(type); -      object_set["obj"]           = object; -      object_set["ocn"]           = (ocn==0) ? "" : to!string(ocn); -      object_set["lev"]           = to!string(lev); -      object_set["lvn"]           = to!string(lvn); -      object_set["lcn"]           = to!string(lcn); -      object_set["attrib"]        = attrib; -      return object_set; -    } -    ObjComposite contents_para_new( -      in string is_a, -      in string object, -      in string attrib, -      in int ocn, -      in string indent_first, -      in string indent_second, -      in bool bullet -    ) { -      ObjComposite object_set; -      object_set.use                 = "content"; -      object_set.of                  = "para"; -      object_set.is_a                = "heading"; -      object_set.object              = object; -      object_set.ocn                 = (ocn==0) ? "" : to!string(ocn); -      object_set.attrib              = attrib; -      object_set.para.indent_first        = indent_first; -      object_set.para.indent_second       = indent_second; -      object_set.para.bullet              = to!string(bullet); +      object_set["use"]                  = "content"; +      object_set["of"]                   = "para"; +      object_set["is"]                   = "heading"; +      object_set["type"]                 = to!string(type); +      // object_set["is"]                = type; // "heading" "heading_dummy" +      object_set["obj"]                  = object; +      object_set["obj_cite_number"]      = (obj_cite_number==0) ? "" : to!string(obj_cite_number); +      object_set["lev"]                  = to!string(lev); +      object_set["lev_markup_number"]    = to!string(lev_markup_number); +      object_set["lev_collapsed_number"] = to!string(lev_collapsed_number); +      object_set["attrib"]               = attrib; +      // object_set["children"]          = children;        return object_set;      }      string[string] contents_para(        in string is_a,        in string object,        in string attrib, -      in int ocn, -      in string indent_first, -      in string indent_second, +      in int obj_cite_number, +      in string[string] indent,        in bool bullet      ) {        string[string] object_set; -      object_set["use"]           = "content"; -      object_set["of"]            = "para"; -      object_set["is"]            = is_a; -      object_set["obj"]           = object; -      object_set["ocn"]           = (ocn==0) ? "" : to!string(ocn); -      object_set["indent_first"]  = indent_first; -      object_set["indent_second"] = indent_second; -      object_set["bullet"]        = to!string(bullet); -      object_set["attrib"]        = attrib; -      return object_set; -    } -    ObjComposite contents_block_new( -      in string type, -      in string object, -      in string attrib, -      in int ocn -    ) { -      ObjComposite object_set; -      // does not have .attrib; -      object_set.use                 = "content"; -      object_set.of                  = "block"; -      object_set.is_a                = type; -      object_set.object              = object; -      object_set.ocn                 = (ocn==0) ? "" : to!string(ocn); -      object_set.attrib              = attrib; +      object_set["use"]              = "content"; +      object_set["of"]               = "para"; +      object_set["is"]               = is_a; +      // object_set["status"]        = status; +      object_set["obj"]              = object; +      object_set["obj_cite_number"]  = (obj_cite_number==0) ? "" : to!string(obj_cite_number); +      object_set["indent_first"]     = indent["first"]; +      object_set["indent_second"]    = indent["second"]; +      object_set["bullet"]           = to!string(bullet); +      object_set["attrib"]           = attrib;        return object_set;      }      string[string] contents_block(        in string type,        in string object,        in string attrib, -      in int ocn +      in int obj_cite_number      ) {        string[string] object_set; -      object_set["use"]           = "content"; -      object_set["of"]            = "block"; -      object_set["is"]            = type; -      object_set["obj"]           = object; -      object_set["ocn"]           = (ocn==0) ? "" : to!string(ocn); -      object_set["attrib"]        = attrib; -      return object_set; -    } -    ObjComposite contents_block_ocn_string_new( -      in string type, -      in string object, -      in string ocn, -      in string node -    ) { -      ObjComposite object_set; -      object_set.use                 = "content"; -      object_set.of                  = "block"; -      object_set.is_a                = type; -      object_set.object              = object; -      object_set.ocn                 = ocn; -      object_set.block_ocn_string.node  = node; -      // object_set.attrib              = attrib; +      object_set["use"]             = "content"; +      object_set["of"]              = "block"; +      object_set["is"]              = type; +      object_set["obj"]             = object; +      object_set["obj_cite_number"] = (obj_cite_number==0) ? "" : to!string(obj_cite_number); +      object_set["attrib"]          = attrib;        return object_set;      } -    string[string] contents_block_ocn_string( +    string[string] contents_block_obj_cite_number_string(        in string type,        in string object, -      in string ocn, +      in string obj_cite_number,        in string node      ) {        string[string] object_set; -      object_set["use"]           = "content"; -      object_set["of"]            = "block"; -      object_set["is"]            = type; -      object_set["obj"]           = object; -      object_set["ocn"]           = ocn; -      object_set["node"]          = node; +      object_set["use"]             = "content"; +      object_set["of"]              = "block"; +      object_set["is"]              = type; +      object_set["obj"]             = object; +      object_set["obj_cite_number"] = obj_cite_number; +      object_set["node"]            = node; +      // object_set["attrib"]       = "";        return object_set;      }    } diff --git a/lib/sdp/ao_output_debugs.d b/lib/sdp/ao_output_debugs.d index d2c2c73..020474e 100644 --- a/lib/sdp/ao_output_debugs.d +++ b/lib/sdp/ao_output_debugs.d @@ -11,7 +11,7 @@ template SiSUoutputDebugs() {        string[][string][string] bookindex_unordered_hashes,        JSONValue[] biblio,        string fn_src, -      string[string] actions +      bool[string] opt_action_bool      ) {        mixin RgxInit;        mixin ScreenTxtColors; @@ -28,10 +28,10 @@ template SiSUoutputDebugs() {                writefln(                  "%s%s node: %s heading: %s %s",                  scr_txt_marker["cyan"], -                obj["ocn"], -                " node: ", obj["node"], -                " heading: ", obj["lvn"], -                " ", obj["obj"], +                obj["obj_cite_number"], +                obj["node"], +                obj["lev_markup_number"], +                obj["obj"],                );              } else {              } @@ -49,7 +49,7 @@ template SiSUoutputDebugs() {            if (obj["use"] == "content") {              writefln(                "[%s][%s]\n%s", -              obj["ocn"], +              obj["obj_cite_number"],                obj["is"],                obj["obj"]              ); @@ -68,7 +68,7 @@ template SiSUoutputDebugs() {              writefln(                "%s* [%s][%s] %s%s",                scr_txt_color["green"], -              obj["ocn"], +              obj["obj_cite_number"],                obj["is"],                scr_txt_color["off"],                obj["obj"] @@ -236,13 +236,13 @@ template SiSUoutputDebugs() {        }        debug(summary) {          string[string] check = [ -          "last_ocn" : "NA [debug \"checkdoc\" not run]", +          "last_obj_cite_number" : "NA [debug \"checkdoc\" not run]",          ];          debug(checkdoc) {            foreach (obj; contents) {              if (obj["use"] == "content") { -              if (!empty(obj["ocn"])) { -                check["last_ocn"] = obj["ocn"]; +              if (!empty(obj["obj_cite_number"])) { +                check["last_obj_cite_number"] = obj["obj_cite_number"];                }              }            } @@ -260,7 +260,7 @@ template SiSUoutputDebugs() {                  "%s%s~ [%s] %s",                  scr_txt_marker["yellow"],                  obj["lev"], -                obj["ocn"], +                obj["obj_cite_number"],                  // "[", obj["is"], "] ",                  obj["obj"]                ); @@ -275,8 +275,8 @@ template SiSUoutputDebugs() {            fn_src,            "length contents array: ",            contents.length, -          "last ocn: ", -          check["last_ocn"], +          "last obj_cite_number: ", +          check["last_obj_cite_number"],            "length bookindex: ",            bookindex_unordered_hashes.length,            __FILE__, @@ -284,119 +284,119 @@ template SiSUoutputDebugs() {          );          debug(checkdoc) {            if (auto mfn=match(fn_src, rgx.src_fn)) { -            if (actions["assert"] == "yes") { +            if (opt_action_bool["assertions"]) {                switch (mfn.captures[2]) {                case "live-manual.ssm": -                assert(check["last_ocn"] == -                  "1019","last ocn should be: 1019 (check test, document is frequently updated)"); // ok +                assert(check["last_obj_cite_number"] == +                  "1019","last obj_cite_number should be: 1019 (check test, document is frequently updated)"); // ok                  break;                case "sisu_markup.sst": -                assert(check["last_ocn"] == -                  "297","last ocn should be: 297"); // ok -                // assert(check["last_ocn"] == "297","last ocn should be: 297"); +                assert(check["last_obj_cite_number"] == +                  "297","last obj_cite_number expected to be: 297 rather than " ~ check["last_obj_cite_number"]); // ok +                // assert(check["last_obj_cite_number"] == "297","last obj_cite_number expected to be: 297 rather than " ~ check["last_obj_cite_number"]);                  // notes for first divergance study sisu headings 247 250 -                // sisu has issue with code that contains heading 1~ which results in no ocn! ?? -                // sisu currently has incorrect last body ocn of 294! +                // sisu has issue with code that contains heading 1~ which results in no obj_cite_number! ?? +                // sisu currently has incorrect last body obj_cite_number of 294!                  // bug in sisu? attend                  break;                // sisu-markup-samples:                case "accelerando.charles_stross.sst": -                assert(check["last_ocn"] == -                  "2861","last ocn should be: 2861"); // ok +                assert(check["last_obj_cite_number"] == +                  "2861","last obj_cite_number expected to be: 2861 rather than " ~ check["last_obj_cite_number"]); // ok                  break;                case "alices_adventures_in_wonderland.lewis_carroll.sst": -                assert(check["last_ocn"] == -                  "805","last ocn should be: 805"); // 808 +                assert(check["last_obj_cite_number"] == +                  "805","last obj_cite_number expected to be: 805 rather than " ~ check["last_obj_cite_number"]); // 808                  break;                case "autonomy_markup0.sst": -                assert(check["last_ocn"] == -                  "77","last ocn should be: 77"); // ok endnotes -                // assert(check["last_ocn"] == "78","last ocn should be: 78"); +                assert(check["last_obj_cite_number"] == +                  "77","last obj_cite_number expected to be: 77 rather than " ~ check["last_obj_cite_number"]); // ok endnotes +                // assert(check["last_obj_cite_number"] == "78","last obj_cite_number expected to be: 78 rather than " ~ check["last_obj_cite_number"]);                  break;                case "content.cory_doctorow.sst": -                assert(check["last_ocn"] == -                  "953","last ocn should be: 953"); // 1007 way off, check ocn off switches -                // assert(check["last_ocn"] == "953","last ocn should be: 953"); +                assert(check["last_obj_cite_number"] == +                  "953","last obj_cite_number expected to be: 953 rather than " ~ check["last_obj_cite_number"]); // 1007 way off, check obj_cite_number off switches +                // assert(check["last_obj_cite_number"] == "953","last obj_cite_number expected to be: 953 rather than " ~ check["last_obj_cite_number"]);                  break;                case "democratizing_innovation.eric_von_hippel.sst":                  // fixed ERROR! range violation, broken check! endnotes, bookindex, biblio                  // error in bookindex ... (ch1; ch6; ch8 ) -                assert(check["last_ocn"] == -                  "905","last ocn should be: 905"); // 911 +                assert(check["last_obj_cite_number"] == +                  "905","last obj_cite_number expected to be: 905 rather than " ~ check["last_obj_cite_number"]); // 911                  break;                case "down_and_out_in_the_magic_kingdom.cory_doctorow.sst": -                assert(check["last_ocn"] == -                  "1417","last ocn should be: 1417"); // 1455 check ocn off switches +                assert(check["last_obj_cite_number"] == +                  "1417","last obj_cite_number expected to be: 1417 rather than " ~ check["last_obj_cite_number"]); // 1455 check obj_cite_number off switches                  break;                case "for_the_win.cory_doctorow.sst": -                assert(check["last_ocn"] == -                  "3510","last ocn should be: 3510"); // 3569 check ocn off switches +                assert(check["last_obj_cite_number"] == +                  "3510","last obj_cite_number expected to be: 3510 rather than " ~ check["last_obj_cite_number"]); // 3569 check obj_cite_number off switches                  break;                case "free_as_in_freedom_2.richard_stallman_and_the_free_software_revolution.sam_williams.richard_stallman.sst": -                assert(check["last_ocn"] == -                  "1082","last ocn should be: 1082"); // check 1079 too few +                assert(check["last_obj_cite_number"] == +                  "1082","last obj_cite_number expected to be: 1082 rather than " ~ check["last_obj_cite_number"]); // check 1079 too few                  break;                case "free_culture.lawrence_lessig.sst": -                assert(check["last_ocn"] == -                  "1330","last ocn should be: 1330"); // 1312 +                assert(check["last_obj_cite_number"] == +                  "1330","last obj_cite_number expected to be: 1330 rather than " ~ check["last_obj_cite_number"]); // 1312                  // fixed ERROR! range violation, broken check!                  // error in bookindex ... sections piracy (ch1) & property (ch10 market concentration) fixed                  break;                case "free_for_all.peter_wayner.sst": // endnotes, bookindex, biblio -                assert(check["last_ocn"] == -                  "1559","last ocn should be: 1559"); // 1560, check ocn off switches, has endnotes so 2 too many -                // assert(check["last_ocn"] == "1559","last ocn should be: 1559"); +                assert(check["last_obj_cite_number"] == +                  "1559","last obj_cite_number expected to be: 1559 rather than " ~ check["last_obj_cite_number"]); // 1560, check obj_cite_number off switches, has endnotes so 2 too many +                // assert(check["last_obj_cite_number"] == "1559","last obj_cite_number expected to be: 1559 rather than " ~ check["last_obj_cite_number"]);                  break;                case "gpl2.fsf.sst": -                assert(check["last_ocn"] == -                  "65","last ocn should be: 65"); // ok endnotes? check -                // assert(check["last_ocn"] == "66","last ocn should be: 66"); +                assert(check["last_obj_cite_number"] == +                  "65","last obj_cite_number expected to be: 65 rather than " ~ check["last_obj_cite_number"]); // ok endnotes? check +                // assert(check["last_obj_cite_number"] == "66","last obj_cite_number expected to be: 66 rather than " ~ check["last_obj_cite_number"]);                  break;                case "gpl3.fsf.sst": -                assert(check["last_ocn"] == -                  "123","last ocn should be: 123"); // ok +                assert(check["last_obj_cite_number"] == +                  "123","last obj_cite_number expected to be: 123 rather than " ~ check["last_obj_cite_number"]); // ok                  break;                case "gullivers_travels.jonathan_swift.sst": -                assert(check["last_ocn"] == -                  "668","last ocn should be: 668"); // 674 +                assert(check["last_obj_cite_number"] == +                  "668","last obj_cite_number expected to be: 668 rather than " ~ check["last_obj_cite_number"]); // 674                  break;                case "little_brother.cory_doctorow.sst": -                assert(check["last_ocn"] == -                  "3130","last ocn should be: 3130"); // 3204, check ocn off switches +                assert(check["last_obj_cite_number"] == +                  "3130","last obj_cite_number expected to be: 3130 rather than " ~ check["last_obj_cite_number"]); // 3204, check obj_cite_number off switches                  break;                case "the_cathedral_and_the_bazaar.eric_s_raymond.sst": -                assert(check["last_ocn"] == -                  "258","last ocn should be: 258"); // ok +                assert(check["last_obj_cite_number"] == +                  "258","last obj_cite_number expected to be: 258 rather than " ~ check["last_obj_cite_number"]); // ok                  break;                case "the_public_domain.james_boyle.sst": -                assert(check["last_ocn"] == -                  "970","last ocn should be: 970"); // 978 +                assert(check["last_obj_cite_number"] == +                  "970","last obj_cite_number expected to be: 970 rather than " ~ check["last_obj_cite_number"]); // 978                  break;                case "the_wealth_of_networks.yochai_benkler.sst": // endnotes, bookindex -                assert(check["last_ocn"] == -                  "829","last ocn should be: 829"); // ok -                // assert(check["last_ocn"] == "832","last ocn should be: 832"); +                assert(check["last_obj_cite_number"] == +                  "829","last obj_cite_number expected to be: 829 rather than " ~ check["last_obj_cite_number"]); // ok +                // assert(check["last_obj_cite_number"] == "832","last obj_cite_number expected to be: 832 rather than " ~ check["last_obj_cite_number"]);                  // has endnotes and bookindex, issue with sisu.rb                  break;                case "through_the_looking_glass.lewis_carroll.sst": -                assert(check["last_ocn"] == -                  "949","last ocn should be: 949"); // 955 +                assert(check["last_obj_cite_number"] == +                  "949","last obj_cite_number expected to be: 949 rather than " ~ check["last_obj_cite_number"]); // 955                  break;                case "two_bits.christopher_kelty.sst": // endnotes, bookindex, biblio -                assert(check["last_ocn"] == -                  "1190","last ocn should be: 1190"); // 1191 -                // assert(check["last_ocn"] == "1193","last ocn should be: 1193"); // 1191 ok? +                assert(check["last_obj_cite_number"] == +                  "1190","last obj_cite_number expected to be: 1190 rather than " ~ check["last_obj_cite_number"]); // 1191 +                // assert(check["last_obj_cite_number"] == "1193","last obj_cite_number expected to be: 1193 rather than " ~ check["last_obj_cite_number"]); // 1191 ok?                  // has endnotes and bookindex, issue with sisu.rb                  break;                  // fixed ERROR! range violation!                  // error in bookindex ... (ch3 the movement)                case "un_contracts_international_sale_of_goods_convention_1980.sst": -                assert(check["last_ocn"] == -                  "377","last ocn should be: 377"); // ok +                assert(check["last_obj_cite_number"] == +                  "377","last obj_cite_number expected to be: 377 rather than " ~ check["last_obj_cite_number"]); // ok                  break;                case "viral_spiral.david_bollier.sst": // endnotes, bookindex -                assert(check["last_ocn"] == -                  "1078","last ocn should be: 1078"); // 1100 +                assert(check["last_obj_cite_number"] == +                  "1078","last obj_cite_number expected to be: 1078 rather than " ~ check["last_obj_cite_number"]); // 1100                  // fixed ERROR! range violation!                  // error in bookindex ... (ch7 ... building the cc machine, an extra semi colon)                  break; diff --git a/lib/sdp/ao_read_markup_source.d b/lib/sdp/ao_read_markup_source.d deleted file mode 100644 index 6eaecbe..0000000 --- a/lib/sdp/ao_read_markup_source.d +++ /dev/null @@ -1,55 +0,0 @@ -/+ -  read markup source -  ao_read_markup_source.d -+/ -mixin template SiSUmarkupRaw() { -  struct MarkupRaw { -    auto rgx = Rgx(); -    final private string markupSourceString(in char[] fn_src) { -      enforce( -        exists(fn_src)!=0, -        "file not found" -      ); -      string source_txt_str; -      try { -        if (exists(fn_src)) { -          source_txt_str = readText(fn_src); // ok -        } -      } -      catch (ErrnoException ex) { -        // Handle errors -      } -      catch (UTFException ex) { -        // Handle validation errors -      } -      catch (FileException ex) { -        // Handle errors -      } -      std.utf.validate(source_txt_str); -      return source_txt_str; -    } -    final private char[][] markupSourceLineArray(in string src_text) { -      char[][] source_line_arr = -        split(cast(char[]) src_text, rgx.line_delimiter); -      return source_line_arr; -    } -    final char[][] markupInsertSourceContentRawLineArray(in char[] fn_src) { -      enforce( -        match(fn_src, rgx.src_fn_find_inserts), -        "not a sisu markup filename" -      ); -      auto source_txt_str = markupSourceString(fn_src); -      auto source_line_arr = markupSourceLineArray(source_txt_str); -      return source_line_arr; -    } -    final char[][] markupSourceContentRawLineArray(in char[] fn_src) { -      enforce( -        match(fn_src, rgx.src_pth), -        "not a sisu markup filename" -      ); -      auto source_txt_str = markupSourceString(fn_src); -      auto source_line_arr = markupSourceLineArray(source_txt_str); -      return source_line_arr; -    } -  } -} diff --git a/lib/sdp/ao_read_source_files.d b/lib/sdp/ao_read_source_files.d new file mode 100644 index 0000000..a5ca084 --- /dev/null +++ b/lib/sdp/ao_read_source_files.d @@ -0,0 +1,281 @@ +/+ +  ao_read_source_files.d +  - open markup files +  - if master file scan for addional files to import/insert ++/ +// module ao_read_source_files; +template SiSUmarkupRaw() { +  private import +    std.exception, +    std.regex, +    std.stdio, +    std.utf, +    std.conv : to; +  private import +    ao_rgx;       // ao_defaults.d +  mixin RgxInit; +  auto rgx = Rgx(); +  struct MarkupRaw { +    final char[][] sourceContent(in string fn_src) { +      auto raw = MarkupRawUnit(); +      auto sourcefile_content = +        raw.markupSourceContentRawLineArray(fn_src, rgx.src_pth); +      if (match(fn_src, rgx.src_fn_master)) { +        auto ins = Inserts(); +        sourcefile_content = +          ins.scan_master_doc_source_for_insert_filenames(sourcefile_content, fn_src); +        // auto ins = SiSUdocInserts.Inserts(); +      } +      return sourcefile_content; +    } +  } +  private +  struct MarkupRawUnit { +    private import std.file; +    final private string readInMarkupSource(in string fn_src) { +      enforce( +        exists(fn_src)!=0, +        "file not found" +      ); +      string source_txt_str; +      try { +        if (exists(fn_src)) { +          source_txt_str = readText(fn_src); +        } +      } +      catch (ErrnoException ex) { +      //// Handle errors +      // switch(ex.errno) { +      // case EPERM: +      // case EACCES: +      //   // Permission denied +      //   break; +      // case ENOENT: +      //   // File does not exist +      //   break; +      // default: +      //   // Handle other errors +      //   break; +      // } +      } +      catch (UTFException ex) { +        // Handle validation errors +      } +      catch (FileException ex) { +        // Handle errors +      } +      std.utf.validate(source_txt_str); +      return source_txt_str; +    } +    final private char[][] markupSourceLineArray(in string src_text) { +      char[][] source_line_arr = +        split(cast(char[]) src_text, rgx.line_delimiter); +      return source_line_arr; +    } +    final char[][] markupSourceContentRawLineArray(in string fn_src, Regex!(char) rgx_file ) { +      enforce( +        match(fn_src, rgx_file), +        "not a sisu markup filename" +      ); +      auto source_txt_str = readInMarkupSource(fn_src); +      auto source_line_arr = markupSourceLineArray(source_txt_str); +      return source_line_arr; +    } +  } +  struct Inserts { +    private import ao_defaults;    // ao_defaults.d +    private import ao_ansi_colors; // ao_ansi_colors.d +    auto scan_subdoc_source( +      char[][] markup_sourcefile_insert_content, +      string fn_src +    ) { +      mixin SiSUrgxInitFlags; +      char[][] contents_insert; +      auto type1 = flags_type_init; +      mixin ScreenTxtColors; +      int tell_l(string color, in char[] line) { +        writeln(scr_txt_marker[color], line); +        return 0; +      } +      auto fn_pth_full = match(fn_src, rgx.src_pth); +      auto markup_src_file_path = fn_pth_full.captures[1]; +      foreach (line; markup_sourcefile_insert_content) { +        if (type1["curly_code"] == 1) { +          type1["header_make"] = 0; +          type1["header_metadata"] = 0; +          if (auto m = match(line, rgx.block_curly_code_close)) { +            type1["curly_code"] = 0; +          } +          contents_insert ~= line; +        } else if (auto m = match(line, rgx.block_curly_code_open)) { +          type1["curly_code"] = 1; +          type1["header_make"] = 0; +          type1["header_metadata"] = 0; +          contents_insert ~= line; +        } else if (type1["tic_code"] == 1) { +          type1["header_make"] = 0; +          type1["header_metadata"] = 0; +          if (auto m = match(line, rgx.block_tic_close)) { +            type1["tic_code"] = 0; +          } +          contents_insert ~= line; +        } else if (auto m = match(line, rgx.block_tic_code_open)) { +          type1["tic_code"] = 1; +          type1["header_make"] = 0; +          type1["header_metadata"] = 0; +          contents_insert ~= line; +        } else if ( +          (type1["header_make"] == 1) +          && match(line, rgx.header_sub) +        ) { +            type1["header_make"] = 1; +            type1["header_metadata"] = 0; +            // cont_dynamic_array ~= "% " ~ line; +        } else if ( +          (type1["header_metadata"] == 1) +          && match(line, rgx.header_sub) +        ) { +            type1["header_metadata"] = 1; +            type1["header_make"] = 0; +            // cont_dynamic_array ~= "% " ~ line; +        } else if (auto m = match(line, rgx.insert_src_fn_ssi_or_sst)) { +          type1["header_make"] = 0; +          type1["header_metadata"] = 0; +          auto insert_fn = m.captures[2]; +          auto insert_sub_pth = m.captures[1]; +          auto fn_src_insert = +            to!string(markup_src_file_path ~ insert_sub_pth ~ insert_fn); +          auto raw = MarkupRawUnit(); +          auto markup_sourcesubfile_insert_content = +            raw.markupSourceContentRawLineArray(fn_src_insert, rgx.src_fn_find_inserts); +          debug(insert) {                              // insert file +            tell_l("red", line); +            tell_l("red", fn_src_insert); +            tell_l("fuchsia", "ERROR"); +            writeln( +              "  length contents insert array: ", +              markup_sourcesubfile_insert_content.length +            ); +          } +          auto ins = Inserts(); +          /+ +            1. load file, +            2. read lines; +            3. scan lines, +            4. if filename insert, and insert filename +            5.   repeat 1 +            6. else +            7.   add line to new array; +          +/ +        } else { +          type1["header_make"] = 0; +          type1["header_metadata"] = 0; +          contents_insert ~= line; +        } +      } // end src subdoc (inserts) loop +      return contents_insert; +    } +    auto scan_master_doc_source_for_insert_filenames( +      char[][] sourcefile_content, +      string fn_src +    ) { +      mixin SiSUrgxInitFlags; +      char[][] contents; +      auto type = flags_type_init; +      mixin ScreenTxtColors; +      int tell_l(string color, in char[] line) { +        writeln(scr_txt_marker[color], line); +        return 0; +      } +      auto fn_pth_full = match(fn_src, rgx.src_pth); +      auto markup_src_file_path = fn_pth_full.captures[1]; +      foreach (line; sourcefile_content) { +        if (type["curly_code"] == 1) { +          type["header_make"] = 0; +          type["header_metadata"] = 0; +          if (auto m = match(line, rgx.block_curly_code_close)) { +            type["curly_code"] = 0; +          } +          contents ~= line; +        } else if (auto m = match(line, rgx.block_curly_code_open)) { +          type["curly_code"] = 1; +          type["header_make"] = 0; +          type["header_metadata"] = 0; +          contents ~= line; +        } else if (type["tic_code"] == 1) { +          type["header_make"] = 0; +          type["header_metadata"] = 0; +          if (auto m = match(line, rgx.block_tic_close)) { +            type["tic_code"] = 0; +          } +          contents ~= line; +        } else if (auto m = match(line, rgx.block_tic_code_open)) { +          type["tic_code"] = 1; +          type["header_make"] = 0; +          type["header_metadata"] = 0; +          contents ~= line; +        } else if ( +          (type["header_make"] == 1) +          && match(line, rgx.header_sub) +        ) { +          contents ~= line; +        } else if ( +          (type["header_metadata"] == 1) +          && match(line, rgx.header_sub) +        ) { +          contents ~= line; +        } else if (auto m = match(line, rgx.header_make)) { +          type["header_make"] = 1; +          type["header_metadata"] = 0; +          contents ~= line; +        } else if (auto m = match(line, rgx.header_metadata)) { +          type["header_make"] = 0; +          type["header_metadata"] = 1; +          contents ~= line; +        } else if (auto m = match(line, rgx.insert_src_fn_ssi_or_sst)) { +          type["header_make"] = 0; +          type["header_metadata"] = 0; +          auto insert_fn = m.captures[2]; +          auto insert_sub_pth = m.captures[1]; +          auto fn_src_insert = +            to!string(markup_src_file_path ~ insert_sub_pth ~ insert_fn); +          auto raw = MarkupRawUnit(); +          auto markup_sourcefile_insert_content = +            raw.markupSourceContentRawLineArray(fn_src_insert, rgx.src_fn_find_inserts); +          debug(insert) {                              // insert file +            tell_l("red", line); +            tell_l("red", fn_src_insert); +            writeln( +              "  length contents insert array: ", +              markup_sourcefile_insert_content.length +            ); +          } +          auto ins = Inserts(); +          auto contents_insert = ins.scan_subdoc_source( +            markup_sourcefile_insert_content, +            to!string(fn_src_insert) +          ); +          contents ~= contents_insert; +          /+ +            1. load file, +            2. read lines; +            3. scan lines, +            4. if filename insert, and insert filename +            5.   repeat 1 +            6. else +            7.   add line to new array; +          +/ +        } else { +          type["header_make"] = 0; +          type["header_metadata"] = 0; +          contents ~= line; +        } +      } // end src doc loop +      debug(insert) {                              // insert file +        writeln(__LINE__); +        writeln(contents.length); +      } +      return contents; +    } +  } +} diff --git a/lib/sdp/ao_rgx.d b/lib/sdp/ao_rgx.d index 4c36ff9..e675ca1 100644 --- a/lib/sdp/ao_rgx.d +++ b/lib/sdp/ao_rgx.d @@ -2,7 +2,7 @@    regex    ao_rgx.d  +/ -mixin template RgxInit() { +template RgxInit() {    struct Rgx {      /+ misc +/      static flag_action               = ctRegex!(`^(--[a-z][a-z0-9-]+)$`); @@ -11,11 +11,14 @@ mixin template RgxInit() {      static src_fn                    = ctRegex!(`^([a-zA-Z0-9._-]+/)*([a-zA-Z0-9._-]+[.]ss[tm])$`);      static src_fn_master             = ctRegex!(`^([a-zA-Z0-9._-]+/)*([a-zA-Z0-9._-]+[.]ssm)$`);      static src_fn_find_inserts       = ctRegex!(`^([a-zA-Z0-9._-]+/)*([a-zA-Z0-9._-]+[.]ss[im])$`); +    // static ssm_fn                    = ctRegex!(`^[a-zA-Z0-9._-]+[.]ssm$`);      static line_delimiter            = ctRegex!("\n"); +    // static arr_delimiter             = ctRegex!(`\s*[;]\s*`);      static within_quotes             = ctRegex!(`"(.+?)"`);      static make_heading_delimiter    = ctRegex!(`[;][ ]*`);      static arr_delimiter             = ctRegex!(`[ ]*[;][ ]*`);      static name_delimiter            = ctRegex!(`^([^,]+)[ ]*,[ ]+(.+?)$`); +    // static name_delimiter            = ctRegex!(`^(.+?)[ ]*,[ ]*(.+?)$`);      static book_index_go             = ctRegex!("([0-9]+)(?:-[0-9]+)?");      static trailing_comma            = ctRegex!(",[ ]*$");      static trailing_linebreak        = ctRegex!(",[ ]{1,2}\\\\\\\\\n[ ]{4}$","m"); @@ -26,6 +29,7 @@ mixin template RgxInit() {      static levels_numbered           = ctRegex!(`^[0-9]$`);      static levels_numbered_headings  = ctRegex!(`^[0-7]$`);      /+ insert markup file +/ +    // static insert_src_fn_ssi_or_sst  = ctRegex!(`^<<\s*([a-zA-Z0-9._-]+/)*(?P<filename>[a-zA-Z0-9._-]+[.]ss[ti])$`);      static insert_src_fn_ssi_or_sst  = ctRegex!(`^<<\s*(?P<path>[a-zA-Z0-9._-]+/)*(?P<filename>[a-zA-Z0-9._-]+[.]ss[ti])$`);      // static insert_ssi_or_sst_fn      = ctRegex!(`^<<\s*[a-zA-Z0-9._-]+[.]ss[ti]`);      /+ comments +/ @@ -49,7 +53,13 @@ mixin template RgxInit() {      static para_indent        = ctRegex!(`^_([1-9]) `);      static para_indent_hang   = ctRegex!(`^_([0-9])_([0-9]) `);      static para_attribs       = ctRegex!(`^_(([0-9])(_([0-9]))?|_([1-9])?[*]) `); +    /+ blocked markup +/ +    static block_open                = ctRegex!("^((code|poem|group|block|quote|table)[{].*?$)|^`{3} (code|poem|group|block|quote|table)"); +    // static block_open_less_code      = ctRegex!("^(((poem|group|block|quote|table)[{].*?$)|`{3} (poem|group|block|quote|table))"); +    static block_poem_open                = ctRegex!("^((poem[{].*?$)|`{3} poem)");      /+ blocked markup tics +/ +    static block_tic_open            = ctRegex!("^`{3} (code|poem|group|block|quote|table)"); +    // static block_tic_open_less_code  = ctRegex!("^`{3} (poem|group|block|quote|table)");      static block_tic_code_open       = ctRegex!("^`{3} (code)");      static block_tic_poem_open       = ctRegex!("^`{3} (poem)");      static block_tic_group_open      = ctRegex!("^`{3} (group)"); @@ -58,6 +68,8 @@ mixin template RgxInit() {      static block_tic_table_open      = ctRegex!("^`{3} (table)");      static block_tic_close           = ctRegex!("^(`{3})$","m");      /+ blocked markup curly +/ +    static block_curly_open          = ctRegex!(`^((code|poem|group|block|quote|table)[{].*?$)`); +    // static block_curly_open_less_code = ctRegex!(`^((poem|group|block|quote|table)[{].*?$)`);      static block_curly_code_open     = ctRegex!(`^(code[{].*?$)`);      static block_curly_code_close    = ctRegex!(`^([}]code)`);      static block_curly_poem_open     = ctRegex!(`^(poem[{].*?$)`); @@ -85,22 +97,33 @@ mixin template RgxInit() {      static inline_notes_al_gen                   = ctRegex!(`【.+?】`, "m");      static inline_notes_curly_gen                = ctRegex!(`~\{.+?\}~`, "m");      static inline_notes_curly                    = ctRegex!(`~\{\s*(.+?)\}~`, "mg"); +    // static inline_notes_curly                    = ctRegex!(`~\{(?:[*+]\s+|\s*)(.+?)\}~`, "mg");      static inline_al_delimiter_open_regular             = ctRegex!(`【`, "m");      static inline_al_delimiter_close_regular            = ctRegex!(`】`, "m");      static inline_al_delimiter_open_and_close_regular   = ctRegex!(`【|】`, "m");      static inline_notes_delimiter_al_regular            = ctRegex!(`【(.+?)】`, "m");      static inline_notes_delimiter_al_regular_number_note = ctRegex!(`【(\d+)\s+(.+?)】`, "m"); +          static inline_al_delimiter_open_asterisk         = ctRegex!(`【\*`, "m");      static inline_al_delimiter_open_plus             = ctRegex!(`【\+`, "m"); +          static inline_curly_delimiter_open_regular             = ctRegex!(`~\{\s*`, "m");      static inline_curly_delimiter_close_regular            = ctRegex!(`\s*\}~`, "m");      static inline_curly_delimiter_open_and_close_regular   = ctRegex!(`~\{\s*|\s*\}~`, "m");      static inline_notes_delimiter_curly_regular            = ctRegex!(`~\{[ ]*(.+?)\}~`, "m"); +    // static inline_notes_curly_regular            = ctRegex!(`(?:[~][{][ ]*)(.+?)(?:[}][~])`, "m"); +    // static inline_notes_curly_regular            = ctRegex!(`~\{\s*(.+?)\}~`, "m"); +    // static inline_notes_curly                    = ctRegex!(`~\{(?:[*+]\s+|\s*)(.+?)\}~`, "mg");      static inline_notes_curly_sp                 = ctRegex!(`~\{[*+]+\s+(.+?)\}~`, "m");      static inline_notes_curly_sp_asterisk        = ctRegex!(`~\{[*]+\s+(.+?)\}~`, "m");      static inline_notes_curly_sp_plus            = ctRegex!(`~\{[+]+\s+(.+?)\}~`, "m"); +    // static inline_text_and_note_curly            = ctRegex!(`(.+?)~\{(?:[*+]\s+|\s*)(.+?)\}~`, "mg");      static inline_text_and_note_al               = ctRegex!(`(?P<text>.+?)【(?:[*+ ]*)(?P<note>.+?)】`, "mg");      static inline_text_and_note_curly            = ctRegex!(`(?P<text>.+?)(?:(?:[~])[{][*+ ]*)(?P<note>.+?)(?:[}][~])`, "mg"); +    // static inline_text_and_note_curly            = ctRegex!(`(?P<text>.+?)~\{(?:[*+]\s+|\s*)(?P<note>.+?)\}~`, "mg"); +    // static inline_text_and_note_curly_sp         = ctRegex!(`(.+?)~\{[*+]+\s+(.+?)\}~`, "mg"); +    // static inline_text_and_note_curly_sp_asterisk = ctRegex!(`(.+?)~\{[*]+\s+(.+?)\}~`, "mg"); +    // static inline_text_and_note_curly_sp_plus    = ctRegex!(`(.+?)~\{[+]+\s+(.+?)\}~`, "mg");      static inline_note_curly_delimiters          = ctRegex!(`(~\{[*+]?\s*)(.+?)(\}~)`, "mg");      static inline_notes_square                   = ctRegex!(`~\[\s*(.+?)\]~`, "mg");      static inline_text_and_note_square_sp        = ctRegex!(`(.+?)~\[[*+]+\s+(.+?)\]~`, "mg"); @@ -110,16 +133,16 @@ mixin template RgxInit() {      static book_index                = ctRegex!(`^=\{\s*(.+?)\}$`, "m");      static book_index_open           = ctRegex!(`^=\{\s*([^}]+?)$`);      static book_index_close          = ctRegex!(`^(.*?)\}$`, "m"); // strip -    /+ no ocn object +/ -    static ocn_off                   = ctRegex!(`~#$`, "m"); -    static ocn_off_dh                = ctRegex!(`-#$`, "m"); -    static ocn_off_all               = ctRegex!(`[~-]#$`, "m"); -    /+ no ocn block +/ -    static ocn_off_block             = ctRegex!(`^--~#$`); -    static ocn_off_block_dh          = ctRegex!(`^---#$`); -    static ocn_off_block_close       = ctRegex!(`^--\+#$`); -    // static auto_ocn_ignore           = ctRegex!(`^[+~*$-]{3,}$`); // reminder -    static ocn_block_marks           = ctRegex!(`^--[+~-]#$`); +    /+ no obj_cite_number object +/ +    static obj_cite_number_off                   = ctRegex!(`~#$`, "m"); +    static obj_cite_number_off_dh                = ctRegex!(`-#$`, "m"); +    static obj_cite_number_off_all               = ctRegex!(`[~-]#$`, "m"); +    /+ no obj_cite_number block +/ +    static obj_cite_number_off_block             = ctRegex!(`^--~#$`); +    static obj_cite_number_off_block_dh          = ctRegex!(`^---#$`); +    static obj_cite_number_off_block_close       = ctRegex!(`^--\+#$`); +    // static auto_obj_cite_number_ignore           = ctRegex!(`^[+~*$-]{3,}$`); // reminder +    static obj_cite_number_block_marks           = ctRegex!(`^--[+~-]#$`);      /+ ignore outside code blocks +/      static regular_parse_skip        = ctRegex!(`^(--[+~-]#|-[\\]{2}-|=[.\\]{2}=)$`); // not structural info      /+ line & page breaks +/ @@ -148,10 +171,11 @@ mixin template RgxInit() {      /+ biblio tags +/      static biblio_tags               = ctRegex!(`^(is|au|author_raw|author|author_arr|editor_raw|ed|editor_arr|ti|title|subtitle|fulltitle|lng|language|trans|src|jo|journal|in|vol|volume|edn|edition|yr|year|pl|place|pb|pub|publisher|url|pg|pages|note|short_name|id):\s+(.+)`);      static biblio_abbreviations      = ctRegex!(`^(au|ed|ti|lng|jo|vol|edn|yr|pl|pb|pub|pg|pgs|sn)$`); +    // static biblio_tags               = ctRegex!(`^(is|author_raw|author|author_arr|editor_raw|editor_arr|title|subtitle|fulltitle|language|trans|src|journal|in|volume|edition|year|place|publisher|url|pages|note|short_name|id):\s+(.+)`);      /+ bookindex split +/      static bi_main_terms_split       = ctRegex!(`\s*;\s*`);      static bi_main_term_plus_rest_split = ctRegex!(`\s*:\s*`); -    static bi_sub_terms_plus_ocn_offset_split = ctRegex!(`\s*\|\s*`); -    static bi_term_and_ocns_match    = ctRegex!(`^(.+?)\+(\d+)`); +    static bi_sub_terms_plus_obj_cite_number_offset_split = ctRegex!(`\s*\|\s*`); +    static bi_term_and_obj_cite_numbers_match    = ctRegex!(`^(.+?)\+(\d+)`);    }  } diff --git a/lib/sdp/ao_scan_inserts.d b/lib/sdp/ao_scan_inserts.d deleted file mode 100644 index f70b2e7..0000000 --- a/lib/sdp/ao_scan_inserts.d +++ /dev/null @@ -1,199 +0,0 @@ -/+ -  inserts -  ao_inserts.d -+/ -mixin template SiSUdocInserts() { -  private: -  struct Inserts { -    auto scan_subdoc_source( -      char[][] markup_sourcefile_insert_content, -      string fn_src -    ) { -      char[][] contents_insert; -      auto ft1 = flag_type.dup; -      mixin ScreenTxtColors; -      auto rgx = Rgx(); -      int tell_l(string color, in char[] line) { -        writeln(scr_txt_marker[color], line); -        return 0; -      } -      auto fn_pth_full = match(fn_src, rgx.src_pth); -      auto markup_src_file_path = fn_pth_full.captures[1]; -      foreach (line; markup_sourcefile_insert_content) { -        if (ft1["curly_code"] == 1) { -          ft1["header_make"] = 0; -          ft1["header_metadata"] = 0; -          if (auto m = match(line, rgx.block_curly_code_close)) { -            ft1["curly_code"] = 0; -          } -          contents_insert ~= line; -        } else if (auto m = match(line, rgx.block_curly_code_open)) { -          ft1["curly_code"] = 1; -          ft1["header_make"] = 0; -          ft1["header_metadata"] = 0; -          contents_insert ~= line; -        } else if (ft1["tic_code"] == 1) { -          ft1["header_make"] = 0; -          ft1["header_metadata"] = 0; -          if (auto m = match(line, rgx.block_tic_close)) { -            ft1["tic_code"] = 0; -          } -          contents_insert ~= line; -        } else if (auto m = match(line, rgx.block_tic_code_open)) { -          ft1["tic_code"] = 1; -          ft1["header_make"] = 0; -          ft1["header_metadata"] = 0; -          contents_insert ~= line; -        } else if ( -          (ft1["header_make"] == 1) -          && match(line, rgx.header_sub) -        ) { -            ft1["header_make"] = 1; -            ft1["header_metadata"] = 0; -        } else if ( -          (ft1["header_metadata"] == 1) -          && match(line, rgx.header_sub) -        ) { -            ft1["header_metadata"] = 1; -            ft1["header_make"] = 0; -        } else if (auto m = match(line, rgx.insert_src_fn_ssi_or_sst)) { -          ft1["header_make"] = 0; -          ft1["header_metadata"] = 0; -          auto insert_fn = m.captures[2]; -          auto insert_sub_pth = m.captures[1]; -          auto fn_src_insert = -            (markup_src_file_path ~ insert_sub_pth ~ insert_fn); -          auto raw = MarkupRaw(); -          auto markup_sourcesubfile_insert_content = -            raw.markupInsertSourceContentRawLineArray(fn_src_insert); -          debug(insert) {                              // insert file -            tell_l("red", line); -            tell_l("red", fn_src_insert); -            tell_l("fuchsia", "ERROR"); -            writeln( -              "  length contents insert array: ", -              markup_sourcesubfile_insert_content.length -            ); -          } -          auto ins = Inserts(); -          /+ -            1. load file, -            2. read lines; -            3. scan lines, -            4. if filename insert, and insert filename -            5.   repeat 1 -            6. else -            7.   add line to new array; -          +/ -        } else { -          ft1["header_make"] = 0; -          ft1["header_metadata"] = 0; -          contents_insert ~= line; -        } -      } // end src subdoc (inserts) loop -      return contents_insert; -    } -    auto scan_doc_source( -      char[][] markup_sourcefile_content, -      string fn_src -    ) { -      char[][] contents; -      auto ft = flag_type.dup; -      mixin ScreenTxtColors; -      auto rgx = Rgx(); -      int tell_l(string color, in char[] line) { -        writeln(scr_txt_marker[color], line); -        return 0; -      } -      auto fn_pth_full = match(fn_src, rgx.src_pth); -      auto markup_src_file_path = fn_pth_full.captures[1]; -      foreach (line; markup_sourcefile_content) { -        if (ft["curly_code"] == 1) { -          ft["header_make"] = 0; -          ft["header_metadata"] = 0; -          if (auto m = match(line, rgx.block_curly_code_close)) { -            ft["curly_code"] = 0; -          } -          contents ~= line; -        } else if (auto m = match(line, rgx.block_curly_code_open)) { -          ft["curly_code"] = 1; -          ft["header_make"] = 0; -          ft["header_metadata"] = 0; -          contents ~= line; -        } else if (ft["tic_code"] == 1) { -          ft["header_make"] = 0; -          ft["header_metadata"] = 0; -          if (auto m = match(line, rgx.block_tic_close)) { -            ft["tic_code"] = 0; -          } -          contents ~= line; -        } else if (auto m = match(line, rgx.block_tic_code_open)) { -          ft["tic_code"] = 1; -          ft["header_make"] = 0; -          ft["header_metadata"] = 0; -          contents ~= line; -        } else if ( -          (ft["header_make"] == 1) -          && match(line, rgx.header_sub) -        ) { -          contents ~= line; -        } else if ( -          (ft["header_metadata"] == 1) -          && match(line, rgx.header_sub) -        ) { -          contents ~= line; -        } else if (auto m = match(line, rgx.header_make)) { -          ft["header_make"] = 1; -          ft["header_metadata"] = 0; -          contents ~= line; -        } else if (auto m = match(line, rgx.header_metadata)) { -          ft["header_make"] = 0; -          ft["header_metadata"] = 1; -          contents ~= line; -        } else if (auto m = match(line, rgx.insert_src_fn_ssi_or_sst)) { -          ft["header_make"] = 0; -          ft["header_metadata"] = 0; -          auto insert_fn = m.captures[2]; -          auto insert_sub_pth = m.captures[1]; -          auto fn_src_insert = -            (markup_src_file_path ~ insert_sub_pth ~ insert_fn); -          auto raw = MarkupRaw(); -          auto markup_sourcefile_insert_content = -            raw.markupInsertSourceContentRawLineArray(fn_src_insert); -          debug(insert) {                              // insert file -            tell_l("red", line); -            tell_l("red", fn_src_insert); -            writeln( -              "  length contents insert array: ", -              markup_sourcefile_insert_content.length -            ); -          } -          auto ins = Inserts(); -          auto contents_insert = ins.scan_subdoc_source( -            markup_sourcefile_insert_content, -            to!string(fn_src_insert) -          ); -          contents ~= contents_insert; -          /+ -            1. load file, -            2. read lines; -            3. scan lines, -            4. if filename insert, and insert filename -            5.   repeat 1 -            6. else -            7.   add line to new array; -          +/ -        } else { -          ft["header_make"] = 0; -          ft["header_metadata"] = 0; -          contents ~= line; -        } -      } // end src doc loop -      debug(insert) {                              // insert file -        writeln(__LINE__); -        writeln(contents.length); -      } -      return contents; -    } -  } -} diff --git a/lib/sdp/ao_structs.d b/lib/sdp/ao_structs.d deleted file mode 100644 index 0aeb235..0000000 --- a/lib/sdp/ao_structs.d +++ /dev/null @@ -1,43 +0,0 @@ -/+ -  structs -  ao_structs.d -+/ -/+ structs +/ - -mixin template Structs() { -  struct ObjHeading { -    string type; -    string lev; -    string lvn; -    string lcn; -  } -  struct ObjPara { -    string indent_first; -    string indent_second; -    string bullet; -  } -  struct ObjComment { -    // does not have .attrib; -    // does not have .ocn -  } -  struct ObjBlock { -  } -  struct ObjBlockOcnString { -    // does not have .attrib; -    string node; -  } -  struct ObjComposite { -    // size_t id; -    string use; -    string of; -    string is_a; -    string object; -    string ocn; -    string attrib; -    // int ocn; -    ObjHeading heading; -    ObjPara para; -    ObjBlock block; -    ObjBlockOcnString block_ocn_string; -  } -} diff --git a/lib/sdp/compile_time_info.d b/lib/sdp/compile_time_info.d index e541113..783ac62 100644 --- a/lib/sdp/compile_time_info.d +++ b/lib/sdp/compile_time_info.d @@ -2,7 +2,7 @@    compile_time_info    compile_time_info.d  +/ -mixin template CompileTimeInfo() { +template CompileTimeInfo() {    version(Windows) {      pragma(msg, "[ Windows compilation ]");      enum os = "Windows"; diff --git a/lib/sdp/sdp.d b/lib/sdp/sdp.d new file mode 100755 index 0000000..8c44d16 --- /dev/null +++ b/lib/sdp/sdp.d @@ -0,0 +1,186 @@ +#!/usr/bin/env rdmd +// [used by rdmd] +/+ +  sdp +  sdp.d ++/ +/+ sdp  sisu document parser +/ +private import +  std.getopt, +  std.process, +  std.stdio, +  std.algorithm, +  std.array, +  std.container, +  std.exception, +  std.json, +  // std.path, +  std.range, +  std.regex, +  // std.stdio, +  std.string, +  std.traits, +  std.typecons, +  std.utf, +  // std.variant, +  std.conv : to; +/+ sdp  sisu document parser +/ +import +  compile_time_info,            // compile_time_info.d +  ao_abstract_doc_source,       // ao_abstract_doc_source.d +  ao_defaults,                  // ao_defaults.d +  ao_read_source_files,         // ao_read_source_files.d +  ao_output_debugs,             // ao_output_debugs.d +  ao_rgx,                       // ao_rgx.d +  ao_ansi_colors;               // ao_ansi_colors.d +  // std.conv; +mixin(import("version.txt")); +mixin CompileTimeInfo; +mixin RgxInit; +void main(string[] args) { +   +  mixin SiSUheader; +  mixin SiSUbiblio; +  mixin SiSUrgxInitFlags; +  mixin SiSUmarkupRaw; +  mixin SiSUdocAbstraction; +  mixin SiSUoutputDebugs; +  mixin ScreenTxtColors; +  auto raw = MarkupRaw(); +  auto abs = Abstraction(); +  auto dbg = SDPoutputDebugs(); +  /+ +  struct DocumentParts { +    string[string][] contents; +    JSONValue[string] metadata_json; +    JSONValue[string] make_json; +    string[][string][string] bookindex_unordered_hashes; +    JSONValue[] biblio; +  } +  +/ +  string[] fns_src; +  string flag_action; +  string arg_unrecognized; +  auto rgx = Rgx(); +  scope(success) { +    debug(checkdoc) { +      writefln( +        "%s~ run complete, ok ~ %s (sdp-%s.%s.%s, %s v%s, %s %s)", +        scr_txt_color["cyan"], scr_txt_color["off"], +        ver.major, ver.minor, ver.patch, +        __VENDOR__, __VERSION__, +        bits, os, +      ); +    } +    // stderr.writeln("0"); +  } +  scope(failure) { +    debug(checkdoc) { +      stderr.writefln( +        "%s~ run failure ~%s", +         scr_txt_color["fuchsia"], scr_txt_color["off"], +      ); +    } +  } +   +  bool[string] opt_action_bool = [ +    "assertions"          : false, +    "html"                : false, +    "no_obj_cite_number"  : false, +    "verbose"             : false, +  ]; +  auto helpInfo = getopt(args, +    std.getopt.config.passThrough, +    "assert",    "--assert set optional assertions on",          &opt_action_bool["assertions"], +    "html",      "--html process html output",                   &opt_action_bool["html"], +    "no-ocn",    "--no-ocn suppress object cite number output",  &opt_action_bool["no_obj_cite_number"], +    "verbose|v", "--verbose output to terminal",                 &opt_action_bool["verbose"], +  ); +  if (helpInfo.helpWanted) { +    defaultGetoptPrinter("Some information about the program.", helpInfo.options); +  } +  foreach(arg; args) { +    if (match(arg, rgx.flag_action)) { +      flag_action ~= " " ~ arg;   // flags not taken by getopt +    } else if (match(arg, rgx.src_pth)) { +      fns_src ~= arg;             // gather input markup source file names for processing +    } else {                      // anything remaining, unused +      arg_unrecognized ~= " " ~ arg; +    } +  } +  foreach(fn_src; fns_src) { +    if (!empty(fn_src)) { +      scope(success) { +        debug(checkdoc) { +          writefln( +            "%s~ document complete, ok ~%s", +            scr_txt_color["green"], scr_txt_color["off"], +          ); +        } +        // stderr.writeln("0"); +      } +      scope(failure) { +        debug(checkdoc) { +          stderr.writefln( +            "%s~ document run failure ~%s (%s  v%s)\n\t%s", +            scr_txt_color["red"], scr_txt_color["off"], +            __VENDOR__, __VERSION__, +            fn_src +          ); +        } +        // stderr.writeln("1"); +      } +      enforce( +        match(fn_src, rgx.src_pth), +        "not a sisu markup filename" +      ); +      /+ ↓ read file +/ +      auto sourcefile_content = +        raw.sourceContent(fn_src); +      /+ ↓ porcess document, return abstraction as tuple +/ +      auto t = +        abs.abstract_doc_source(sourcefile_content); +      static assert(!isTypeTuple!(t)); +      auto doc_ao_contents = t[0]; // contents ~ endnotes ~ bookindex; +      // static assert(!isIterable!(doc_ao_contents)); +      auto doc_ao_metadata_json = t[1]; +      auto doc_ao_make_json = t[2]; +      auto doc_ao_bookindex_unordered_hashes = t[3]; +      auto doc_ao_biblio = t[4]; +      // destroy(t); +      /+ ↓ document parts +/ +      debug(checkdoc) { // checkbook & dumpdoc +        dbg.abstract_doc_source_debugs( +          doc_ao_contents, +          doc_ao_make_json, +          doc_ao_metadata_json, +          doc_ao_bookindex_unordered_hashes, +          doc_ao_biblio, +          fn_src, +          opt_action_bool +        ); +      } +      scope(exit) { +        debug(checkdoc) { +          writefln( +            "processed file: %s", +            fn_src +          ); +        } +        destroy(sourcefile_content); +        destroy(t); +        destroy(doc_ao_contents); +        destroy(doc_ao_make_json); +        destroy(doc_ao_metadata_json); +        destroy(doc_ao_bookindex_unordered_hashes); +        destroy(doc_ao_biblio); +        destroy(fn_src); +      } +    } else { +      /+ no recognized filename provided +/ +      writeln("no recognized filename"); +      break; +      // terminate, stop +    } +  } +} | 
