/+ document abstraction ao_abstract_doc_source.d +/ 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) { /+ ↓ abstraction init +/ scope(success) { } scope(failure) { } 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(obj_cite_number), to!string(line) ); return 0; } int tell_l(string color, in char[] line) { writefln( "%s%s", scr_txt_marker[color], line ); return 0; } 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) { stderr.writefln( "%s:%s failed here:\n line: %s", __FILE__, __LINE__, line, ); } line = replaceAll(line, rgx.true_dollar, "$$$$"); // dollar represented as $$ needed to stop submatching on $ // (substitutions using ${identifiers} must take into account (e.g. happen earlier)) debug(source) { // source lines writeln(line); // writeln(scr_txt_marker["green"], line); } debug(srclines) { if (!line.empty) { // source lines, not empty writefln( "%s%s", scr_txt_marker["green"], line ); } } if (!line.empty) { check_obj_cite_number_status(line, type); } 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) +/ if (((match(line, rgx.heading_biblio) || (type["heading_biblio"] == State.on))) && (!match(line, rgx.heading)) && (!match(line, rgx.comment))) { /+ 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 (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( (type["blocks"] == TriState.off) || (type["blocks"] == TriState.closing), "block status: none or closed" ); 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); } start_block(line, type, obj_cite_number_poem); continue; } else if (!line.empty) { /+ line not empty +/ /+ non blocks (headers, paragraphs) & closed blocks +/ assert( !line.empty, "line tested, line not empty surely" ); assert( (type["blocks"] == TriState.off) || (type["blocks"] == TriState.closing), "code block status: none or closed" ); if (type["blocks"] == TriState.closing) { // blocks closed, unless followed by book index debug(check) { // block writeln(__LINE__); tell_l("red", line); } assert( match(line, rgx.book_index) || match(line, rgx.book_index_open) || type["book_index"] == State.on ); } 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 +/ if (auto m = match(line, rgx.comment)) { /+ matched comment +/ debug(comment) { tell_l("blue", line); } 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"); 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) && (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 ((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 +/ 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"] > State.off) { /+ header_make +/ // should be caught by sub-header debug(header) { tell_l("red", line); } 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); } an_object["obj"] ~= line ~= "\n"; ++line_occur["header_metadata"]; } else if (line_occur["heading"] > State.off) { /+ heading +/ debug(heading) { // heading tell_l("blue", line); } an_object["obj"] ~= line ~= "\n"; ++line_occur["heading"]; } else if (line_occur["para"] > State.off) { /+ paragraph +/ debug(para) { tell_l("blue", line); } an_object["obj"] ~= line; ++line_occur["para"]; } } } 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: +/ assert( line.empty, "line should be empty" ); assert( (type["blocks"] == State.off), "code block status: none" ); 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(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]; header_set_common(line_occur, an_object, type); processing.remove("verse"); } 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(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]; header_set_common(line_occur, an_object, type); type["header_make"] = State.off; type["header_metadata"] = State.off; processing.remove("verse"); } 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(an_object["bookindex"], obj_cite_number); an_object["is"] = "heading"; node = node_jstr_heading( an_object["lev_markup_number"], an_object["lev_collapsed_number"], obj_cite_number, counter, heading_pointer, an_object["is"] ); // heading 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"); } 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 ((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(an_object["bookindex"], obj_cite_number); an_object["is"] = "para"; 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_para( an_object["is"], an_object["substantive"], an_object["attrib"], obj_cite_number, indent, bullet ); // 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; processing.remove("verse"); ++counter; } else { assert( line == null, "line variable should be empty, should not occur" ); // check what happens when paragraph separated by 2 newlines } } // close else for line empty } // close else for not the above } // close after non code, other blocks or regular text if (((contents_the_objects[$-1]["is"] == "para") || (contents_the_objects[$-1]["is"] == "heading")) && (counter-1 > previous_count)) { 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_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: * endnotes * glossary * references / bibliography * book index +/ obj_im.obj_inline_markup("doc_end_reset", ""); auto en_tuple = note_section.endnote_objects(obj_cite_number); static assert(!isTypeTuple!(en_tuple)); auto endnotes_section = en_tuple[0]; obj_cite_number = en_tuple[1]; debug(endnotes) { writefln( "%s %s", __LINE__, endnotes_section.length ); 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 bi = BookIndexReportSection(); auto bi_tuple = bi.bookindex_build_section(bookindex_unordered_hashes, obj_cite_number); static assert(!isTypeTuple!(bi_tuple)); auto bookindex_section = bi_tuple[0]; obj_cite_number = bi_tuple[1]; debug(bookindex) { // 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_the) { if (o["is"] == "heading") { 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_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_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 +/