From 33d4cd24013c8660c100a0070802a0e9d1211421 Mon Sep 17 00:00:00 2001
From: Ralph Amissah <ralph.amissah@gmail.com>
Date: Tue, 28 Apr 2020 22:47:10 -0400
Subject: metaverse, doc structure & blocks, change tracking

---
 src/doc_reform/meta/defaults.d         | 32 ++++++++++++++
 src/doc_reform/meta/metadoc_from_src.d | 78 +++++++++++++++++-----------------
 src/doc_reform/meta/rgx.d              |  6 +--
 3 files changed, 74 insertions(+), 42 deletions(-)

(limited to 'src')

diff --git a/src/doc_reform/meta/defaults.d b/src/doc_reform/meta/defaults.d
index e592be7..8b6edad 100644
--- a/src/doc_reform/meta/defaults.d
+++ b/src/doc_reform/meta/defaults.d
@@ -2,6 +2,38 @@
   default settings
 +/
 module doc_reform.meta.defaults;
+template spineDocStatus() {
+  @safe static auto status() {
+    struct _e {
+      enum sect {
+        unset,
+        head,
+        toc,
+        substantive,
+        bibliography,
+        glossary,
+        book_index,
+        blurb,
+      }
+      enum block {
+        off,
+        closing,
+        code,
+        poem,
+        block,
+        group,
+        table,
+        quote,
+      }
+      enum ocn {
+        on,    // 0 object_number;
+        off,   // 1 no object_number;
+        dummy, // 2 no object_number & dummy headings
+      }
+    }
+    return _e();
+  }
+}
 template spineRgxDocStructFlags() {
   /+ regex flags +/
   @safe static int[string] flags_type_init() {
diff --git a/src/doc_reform/meta/metadoc_from_src.d b/src/doc_reform/meta/metadoc_from_src.d
index f5ff735..6aa1eb6 100644
--- a/src/doc_reform/meta/metadoc_from_src.d
+++ b/src/doc_reform/meta/metadoc_from_src.d
@@ -356,6 +356,7 @@ template docAbstraction() {
       reset_note_numbers=true;
     }
     mixin spineRgxDocStructFlags;
+    mixin spineDocStatus;
     mixin spineNode;
     auto node_para_int_    = node_metadata_para_int;
     auto node_para_str_    = node_metadata_para_str;
@@ -379,6 +380,12 @@ template docAbstraction() {
       "images"            : 0,
     ];
     auto obj_type_status = flags_type_init;
+    int[string] track = [
+      "section" : 0,
+      "block"   : 0,
+      "obj"     : 0,
+      "ocn"     : 0,
+    ];
     string[string] object_number_poem = [
       "start" : "",
       "end"   : ""
@@ -528,18 +535,15 @@ template docAbstraction() {
                                                                                 /+ heading, glossary, blurb, poem, group, block, quote, table +/
         line = line.inline_markup_faces; // by text line (rather than by text object), linebreaks in para problematic
         if (line.matchFirst(rgx.heading_biblio)
-        || (obj_type_status["biblio_section"] == State.on
+        || (track["section"] == status.sect.bibliography
           && ((!(line.matchFirst(rgx.heading_glossary)))
           && (!(line.matchFirst(rgx.heading_blurb)))
           && (!(line.matchFirst(rgx.heading)))
           && (!(line.matchFirst(rgx.comment)))))
         ) {
-          /+ within section (block object): biblio +/
-          obj_type_status["glossary_section"] = State.off;
-          obj_type_status["biblio_section"]   = State.on;
-          obj_type_status["blurb_section"]    = State.off;
+          track["section"] = status.sect.bibliography;
           if (opt_action.backmatter && opt_action.section_biblio) {
-            line.flow_txt_block_biblio(obj_type_status, bib_entry, biblio_entry_str_json, biblio_arr_json);
+            line.flow_txt_block_biblio(obj_type_status, bib_entry, biblio_entry_str_json, biblio_arr_json, track);
             debug(bibliobuild) {
               writeln("-  ", biblio_entry_str_json);
               writeln("-> ", biblio_arr_json.length);
@@ -547,7 +551,7 @@ template docAbstraction() {
           }
           continue;
         } else if (line.matchFirst(rgx.heading_glossary)
-        || (obj_type_status["glossary_section"] == State.on
+        || (track["section"] == status.sect.glossary
           && ((!(line.matchFirst(rgx.heading_biblio)))
           && (!(line.matchFirst(rgx.heading_blurb)))
           && (!(line.matchFirst(rgx.heading)))
@@ -558,9 +562,7 @@ template docAbstraction() {
             writeln(__LINE__);
             writeln(line);
           }
-          obj_type_status["glossary_section"] = State.on;
-          obj_type_status["biblio_section"]   = State.off;
-          obj_type_status["blurb_section"]    = State.off;
+          track["section"] = status.sect.glossary;
           if (opt_action.backmatter && opt_action.section_glossary) {
             indent=[
               "hang_position" : 0,
@@ -644,20 +646,17 @@ template docAbstraction() {
           }
           continue;
         } else if (line.matchFirst(rgx.heading_blurb)
-        || (obj_type_status["blurb_section"] == State.on
+        || (track["section"] == status.sect.blurb
           && ((!(line.matchFirst(rgx.heading_glossary)))
           && (!(line.matchFirst(rgx.heading_biblio)))
           && (!(line.matchFirst(rgx.heading)))
           && (!(line.matchFirst(rgx.comment)))))
         ) {
-          /+ within section (block object): blurb +/
+          track["section"] = status.sect.blurb;
           debug(blurb) {
             writeln(__LINE__);
             writeln(line);
           }
-          obj_type_status["glossary_section"] = State.off;
-          obj_type_status["biblio_section"]   = State.off;
-          obj_type_status["blurb_section"]    = State.on;
           if (opt_action.backmatter && opt_action.section_blurb) {
             indent=[
               "hang_position" : 0,
@@ -855,17 +854,17 @@ template docAbstraction() {
                 writeln(line);
               }
               assert(
-                line.matchFirst(rgx.book_index)
-                || line.matchFirst(rgx.book_index_open)
-                || obj_type_status["book_index"] == State.on,
+                line.matchFirst(rgx.book_index_item)
+                || line.matchFirst(rgx.book_index_item_open)
+                || track["section"] == status.sect.book_index,
                 "\nblocks closed, unless followed by book index, non-matching line:\n  \""
                 ~ line ~ "\""
               );
             }
-            if (line.matchFirst(rgx.book_index)
-            || line.matchFirst(rgx.book_index_open)
-            || obj_type_status["book_index"] == State.on )  {                              /+ book_index +/
-              an_object = line.flow_book_index_(an_object, book_idx_tmp, obj_type_status, opt_action);
+            if (line.matchFirst(rgx.book_index_item)
+            || line.matchFirst(rgx.book_index_item_open)
+            || track["section"] == status.sect.book_index)  {                              /+ book_index +/
+              an_object = line.flow_book_index_(an_object, book_idx_tmp, obj_type_status, track, opt_action);
             } else {                                                                       /+ not book_index +/
               an_object_key="body_nugget";
               if (auto m = line.matchFirst(rgx.comment)) {                                 /+ matched comment +/
@@ -913,7 +912,8 @@ template docAbstraction() {
                     lv,
                     collapsed_lev,
                     obj_type_status,
-                    conf_make_meta
+                    conf_make_meta,
+                    track,
                   );
                 } else if (line_occur["para"] == State.off) {                              /+ para match +/
                   an_object_key="body_nugget";
@@ -1166,9 +1166,7 @@ template docAbstraction() {
         && (the_document_body_section.length > previous_length)) {
           if ((the_document_body_section[$-1].metainfo.is_a == "heading")
           && (the_document_body_section[$-1].metainfo.heading_lev_markup < 5)) {
-            obj_type_status["glossary_section"] = State.off;
-            obj_type_status["biblio_section"]   = State.off;
-            obj_type_status["blurb_section"]    = State.off;
+            track["section"] = status.sect.unset;
           }
           if (the_document_body_section[$-1].metainfo.is_a == "verse") {             /+ scan for endnotes for whole poem (each verse in poem) +/
             foreach (i; previous_length .. the_document_body_section.length) {
@@ -3215,15 +3213,15 @@ template docAbstraction() {
     return ref int[string] obj_type_status,
     return ref int         bib_entry,
     return ref string      biblio_entry_str_json,
-    return ref string[]    biblio_arr_json
+    return ref string[]    biblio_arr_json,
+    return ref int[string] track,
   ) {
     mixin spineBiblio;
+    mixin spineDocStatus;
     auto jsn = BibJsnStr();
     static auto rgx = RgxI();
     if (line.matchFirst(rgx.heading_biblio)) {
-      obj_type_status["glossary_section"] = State.off;
-      obj_type_status["biblio_section"]   = TriState.on;
-      obj_type_status["blurb_section"]    = State.off;
+      track["section"] = status.sect.bibliography;
     }
     if (line.empty) {
       debug {
@@ -3688,10 +3686,12 @@ template docAbstraction() {
                string[string]  an_object,
     return ref string          book_idx_tmp,
     return ref int[string]     obj_type_status,
+    return ref int[string]     track,
                B               opt_action,
   ) {
+    mixin spineDocStatus;
     static auto rgx = RgxI();
-    if (auto m = line.match(rgx.book_index)) {                                   /+ match book_index +/
+    if (auto m = line.match(rgx.book_index_item)) {                                   /+ match book_index +/
       debug(bookindexmatch) {
         writefln(
           "* [bookindex] %s\n",
@@ -3699,8 +3699,8 @@ template docAbstraction() {
         );
       }
       an_object["bookindex_nugget"] = m.captures[1].to!string;
-    } else if (auto m = line.match(rgx.book_index_open))  {                      /+ match open book_index +/
-      obj_type_status["book_index"] = State.on;
+    } else if (auto m = line.match(rgx.book_index_item_open))  {                      /+ match open book_index +/
+      track["section"] = status.sect.book_index;
       if (opt_action.backmatter && opt_action.section_bookindex) {
         book_idx_tmp = m.captures[1].to!string;
         debug(bookindexmatch) {
@@ -3710,9 +3710,9 @@ template docAbstraction() {
           );
         }
       }
-    } else if (obj_type_status["book_index"] == State.on )  {                    /+ book_index flag set +/
-      if (auto m = line.match(rgx.book_index_close))  {
-        obj_type_status["book_index"] = State.off;
+    } else if (track["section"] == status.sect.book_index)  {                    /+ book_index flag set +/
+      if (auto m = line.match(rgx.book_index_item_close))  {
+        track["section"] = status.sect.unset;
         if (opt_action.backmatter
         && opt_action.section_bookindex) {
           an_object["bookindex_nugget"] = book_idx_tmp ~ m.captures[1].to!string;
@@ -3879,16 +3879,16 @@ template docAbstraction() {
     return ref int[string]     collapsed_lev,
     return ref int[string]     obj_type_status,
     return ref CMM             conf_make_meta,
+    return ref int[string]     track,
   ) {
+    mixin spineDocStatus;
     static auto rgx = RgxI();
     if (auto m = line.match(rgx.headings)) {                                      /+ heading match +/
       ++line_occur["heading"];
       obj_type_status["heading"]            = State.on;
       obj_type_status["para"]               = State.off;
       if (line.match(rgx.heading_seg_and_above)) {
-        obj_type_status["glossary_section"] = State.off;
-        obj_type_status["biblio_section"]   = State.off;
-        obj_type_status["blurb_section"]    = State.off;
+        track["section"]                    = status.sect.unset;
       }
       an_object[an_object_key] ~= line ~= "\n";
       an_object["lev"] ~= m.captures[1];
diff --git a/src/doc_reform/meta/rgx.d b/src/doc_reform/meta/rgx.d
index 5a0fbdc..07ec2d4 100644
--- a/src/doc_reform/meta/rgx.d
+++ b/src/doc_reform/meta/rgx.d
@@ -128,9 +128,9 @@ static template spineRgxIn() {
     static smid_a_image                                    = ctRegex!(`(?P<pre>(?:^|[ ]|[^\S]?)[{](?:~\^\s+|\s*))(?P<image>[a-zA-Z0-9._-]+?\.(?:png|gif|jpg))(?P<post>(?:.*?)\s*[}](?:image|(?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)\S+?)(?=[;:!,?.]?([ )\]]|$)))`, "mg");
     static smid_image_delimit                              = ctRegex!(`(?P<pre>^|[ ]|[^\S]?)\{\s*(?P<text>.+?)\s*\}(?:image)(?=[;:!,?.]?([ )\]]|$))`, "mg");
     /+ inline markup book index +/
-    static book_index                                     = ctRegex!(`^=\{\s*(?P<bookindex>.+?)\}$`, "m");
-    static book_index_open                                = ctRegex!(`^=\{\s*([^}]*?)$`);
-    static book_index_close                               = ctRegex!(`^(.*?)\}$`, "m");
+    static book_index_item                                = ctRegex!(`^=\{\s*(?P<bookindex>.+?)\}$`, "m");
+    static book_index_item_open                           = ctRegex!(`^=\{\s*([^}]*?)$`);
+    static book_index_item_close                          = ctRegex!(`^(.*?)\}$`, "m");
     static auto_heading_numbering_lv1                    = ctRegex!(`^1~`, "m");
     static auto_heading_numbering_lv2                    = ctRegex!(`^2~`, "m");
     static auto_heading_numbering_lv3                    = ctRegex!(`^3~`, "m");
-- 
cgit v1.2.3