From 4bc9e4921afac5ddf9e84c2f1873639179be86ef Mon Sep 17 00:00:00 2001 From: Ralph Amissah Date: Tue, 29 May 2018 18:11:26 -0400 Subject: 0.26.2 image(s) without dimensions --- dub.sdl | 8 +- maker.org | 8 +- org/default_paths.org | 22 ++-- org/default_regex.org | 2 + org/meta_abstraction.org | 244 ++++++++++++++++++++++++++-------------- org/output_sqlite.org | 31 +---- org/output_xmls.org | 27 +++-- org/output_xmls_css.org | 5 + org/sdp.org | 3 +- src/sdp/meta/metadoc.d | 1 + src/sdp/meta/metadoc_from_src.d | 60 ++++++++-- src/sdp/meta/object_setter.d | 89 +++++++-------- src/sdp/meta/rgx.d | 2 + src/sdp/output/html.d | 4 +- src/sdp/output/paths_source.d | 22 ++-- src/sdp/output/rgx.d | 1 + src/sdp/output/sqlite.d | 49 +------- src/sdp/output/xmls.d | 23 ++-- src/sdp/output/xmls_css.d | 3 + views/version.txt | 2 +- 20 files changed, 337 insertions(+), 269 deletions(-) diff --git a/dub.sdl b/dub.sdl index c64118f..24a53da 100644 --- a/dub.sdl +++ b/dub.sdl @@ -8,12 +8,12 @@ targetPath "./bin" #sourcePath "./src/sdp" stringImportPaths "./views" buildRequirements "allowWarnings" -dependency "toml" version="~>0.4.0-rc.2" # https://code.dlang.org/packages/toml https://github.com/toml-lang/toml/wiki +dependency "toml" version="~>0.4.0-rc.2" # https://code.dlang.org/packages/toml https://github.com/toml-lang/toml/wiki dependency "toml:json" version="~>0.4.0-rc.2" -dependency "d2sqlite3" version="~>0.16.1" # https://code.dlang.org/packages/d2sqlite3 http://biozic.github.io/d2sqlite3/d2sqlite3.html +dependency "d2sqlite3" version="~>0.16.1" # https://code.dlang.org/packages/d2sqlite3 http://biozic.github.io/d2sqlite3/d2sqlite3.html subconfiguration "d2sqlite3" "all-included" -dependency "archive" version="~>0.6.0" # http://code.dlang.org/packages/archive https://github.com/rcythr/archive -dependency "imageformats" version="~>7.0.0" +dependency "archive" version="~>0.6.0" # http://code.dlang.org/packages/archive https://github.com/rcythr/archive +dependency "imageformats" version="~>7.0.0" # https://code.dlang.org/packages/imageformats https://github.com/lgvz/imageformats configuration "reggae" { name "build" targetType "executable" diff --git a/maker.org b/maker.org index 419d5c9..158a239 100644 --- a/maker.org +++ b/maker.org @@ -819,12 +819,12 @@ targetPath "./bin" #sourcePath "./src/sdp" stringImportPaths "./views" buildRequirements "allowWarnings" -dependency "toml" version="~>0.4.0-rc.2" # https://code.dlang.org/packages/toml https://github.com/toml-lang/toml/wiki +dependency "toml" version="~>0.4.0-rc.2" # https://code.dlang.org/packages/toml https://github.com/toml-lang/toml/wiki dependency "toml:json" version="~>0.4.0-rc.2" -dependency "d2sqlite3" version="~>0.16.1" # https://code.dlang.org/packages/d2sqlite3 http://biozic.github.io/d2sqlite3/d2sqlite3.html +dependency "d2sqlite3" version="~>0.16.1" # https://code.dlang.org/packages/d2sqlite3 http://biozic.github.io/d2sqlite3/d2sqlite3.html subconfiguration "d2sqlite3" "all-included" -dependency "archive" version="~>0.6.0" # http://code.dlang.org/packages/archive https://github.com/rcythr/archive -dependency "imageformats" version="~>7.0.0" +dependency "archive" version="~>0.6.0" # http://code.dlang.org/packages/archive https://github.com/rcythr/archive +dependency "imageformats" version="~>7.0.0" # https://code.dlang.org/packages/imageformats https://github.com/lgvz/imageformats #+END_SRC ** generic :generic: diff --git a/org/default_paths.org b/org/default_paths.org index 16dcfaf..b8ff2a4 100644 --- a/org/default_paths.org +++ b/org/default_paths.org @@ -348,18 +348,22 @@ template PathMatters() { return _dir; } auto image_dir_path() { - string _img_pth(string _possible_img_pth) { - return asNormalizedPath(file_with_absolute_path.dirName ~ "/" ~ _possible_img_pth).array; - } string _paths; string[] _possible_img_pths = [ "./image", "../image", "../../image" ]; string _img_pth_found = ""; - foreach(_possible_img_pth; _possible_img_pths) { - if (exists(_img_pth(_possible_img_pth))) { - _img_pth_found = _img_pth(_possible_img_pth); - break; - } else { - _paths ~= " " ~ _img_pth(_possible_img_pth); + if (is_pod) { + _img_pth_found = asNormalizedPath(file_with_absolute_path.dirName ~ "/../../image").array; + } else { + string _img_pth(string _possible_img_pth) { + return asNormalizedPath(file_with_absolute_path.dirName ~ "/" ~ _possible_img_pth).array; + } + foreach(_possible_img_pth; _possible_img_pths) { + if (exists(_img_pth(_possible_img_pth))) { + _img_pth_found = _img_pth(_possible_img_pth); + break; + } else { + _paths ~= " " ~ _img_pth(_possible_img_pth); + } } } if (_img_pth_found.empty) { diff --git a/org/default_regex.org b/org/default_regex.org index 6b535a0..a018c1b 100644 --- a/org/default_regex.org +++ b/org/default_regex.org @@ -272,6 +272,7 @@ static image = ctRegex!(`([a-zA-Z0-9._ static smid_image_generic = ctRegex!(`(?:^|[ ]|[^\S]?)\{(?:~\^\s+|\s*)\S+\.(?:png|gif|jpg).+?\}(?:image|(?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)\S+?)[;:!,?.]?(?:[ )\]]|$)`, "mg"); static smid_image_with_dimensions = ctRegex!(`(?P
(?:^|[ ]|[^\S]?)\{(?:~\^\s+|\s*))(?P\S+\.(?:png|gif|jpg))\s+(?P\d+)x(?P\d+)\s*(?P(?:.+?)\s*\}(?:image|(?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)\S+?)(?:[;:!,?.]?(?:[ )\]]|$)))`, "mg");
 static smid_image                                      = ctRegex!(`(?P
(?:^|[ ]|[^\S]?)\{(?:~\^\s+|\s*))(?P\S+\.(?:png|gif|jpg))\s*(?P(?:.+?)\s*\}(?:image|(?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)\S+?)(?:[;:!,?.]?(?:[ )\]]|$)))`, "mg");
+static smid_mod_image_without_dimensions               = ctRegex!(`\{(?:~\^\s+|\s*)☼\S+\.(?:png|gif|jpg),w0h0\s+(?:.+?)\s*\}(?:image|(?:https?|git):\/\/\S+?)(?:[;:!,?.]?(?:[ )\]]|$))`, "mg");
 #+END_SRC
 
 *** inline markup book index                             :inline:bookindex:
@@ -489,6 +490,7 @@ static inline_text_and_note_al_                       = ctRegex!(`(.+?(?:【[*+]
 #+BEGIN_SRC d
 /+ inline markup footnotes endnotes +/
 static inline_image                                   = ctRegex!(`(?P
┥)☼(?P(?P\S+?\.(?:jpg|gif|png)),w(?P\d+)h(?P\d+))\s*(?P.*?┝┤.+?├)`, "mg");
+static inline_image_without_dimensions                = ctRegex!(`(?P
┥)☼(?P(?P\S+?\.(?:jpg|gif|png)),w(?P0)h(?P0))\s*(?P.*?┝┤.+?├)`, "mg");
 static inline_link                                    = ctRegex!(`┥(?P.+?)┝┤(?P.+?)├`, "mg");
 static inline_link_clean                              = ctRegex!(`┤(?:.+?)├|[┥┝]`, "mg");
 static inline_a_url                                   = ctRegex!(`(┤)(\S+?)(├)`, "mg");
diff --git a/org/meta_abstraction.org b/org/meta_abstraction.org
index 43cd85d..f74c8d6 100644
--- a/org/meta_abstraction.org
+++ b/org/meta_abstraction.org
@@ -36,10 +36,11 @@ template SiSUdocAbstraction() {
   /+ ↓ abstraction struct init +/
   <>
   /+ ↓ abstract marked up document +/
-  auto SiSUdocAbstraction(Src,CMM,Opt)(
+  auto SiSUdocAbstraction(Src,CMM,Opt,Mfst)(
     Src                  markup_sourcefile_content,
     CMM                  conf_make_meta,
     Opt                  opt_action,
+    Mfst                 manifest_matter,
   ) {
     static auto rgx = Rgx();
     debug(asserts) {
@@ -49,7 +50,7 @@ template SiSUdocAbstraction() {
     <>
     /+ abstraction init ↑ +/
     <>
-    /+ ↓ loop markup document/text line by line +/
+    /+ ↓ ↻ loop markup document/text line by line +/
     srcDocLoop:
     foreach (line; markup_sourcefile_content) {
       // "line" variable can be empty but should never be null
@@ -84,6 +85,7 @@ template SiSUdocAbstraction() {
     } /+ ← closed: loop markup document/text line by line +/
     /+ ↓ post loop markup document/text +/
     <>
+    <>
     /+ post loop markup document/text ↑ +/
   } /+ ← closed: abstract doc source +/
   /+ ↓ abstraction functions +/
@@ -409,7 +411,7 @@ string[][string][string] bookindex_unordered_hashes;
 /+ node +/
 ObjGenericComposite comp_obj_heading, comp_obj_location, comp_obj_block, comp_obj_code, comp_obj_poem_ocn, comp_obj_comment;
 auto node_construct = NodeStructureMetadata();
-enum sObj { content, anchor_tags, notes_reg, notes_star, links }
+enum sObj { content, anchor_tags, notes_reg, notes_star, links, image_no_dimensions }
 #+END_SRC
 
 *** scope
@@ -566,8 +568,8 @@ debug (substitutions) {
 }
 #+END_SRC
 
-** 2. _loop: process document body_ [+6]                                :loop:
-*** loop scope                                                      :scope:
+** 2. ↻ *LOOP* _loop: process document body_ [+6]                         :loop:
+*** Loop scope                                                      :scope:
 
 #+name: abs_in_loop_body_00
 #+BEGIN_SRC d
@@ -1297,6 +1299,7 @@ if ((obj_type_status["heading"] == State.on)
   comp_obj_para.inline_notes_reg      = substantive_obj_misc_tuple[sObj.notes_reg];
   comp_obj_para.inline_notes_star     = substantive_obj_misc_tuple[sObj.notes_star];
   comp_obj_para.inline_links          = substantive_obj_misc_tuple[sObj.links];
+  comp_obj_para.contains_image_without_dimensions  = substantive_obj_misc_tuple[sObj.image_no_dimensions];
   the_document_body_section           ~= comp_obj_para;
   _common_reset_(line_occur, an_object, obj_type_status);
   indent=[
@@ -1782,11 +1785,11 @@ the_document_head_section ~= the_document_body_section[0];
 the_document_body_section=the_document_body_section[1..$];
 #+END_SRC
 
-*** _post main-loop loops_                                           :post:
-**** 1. _loop backmatter:_ loop up to lev4, extract html_segnames, set pointers
+*** ↻ *LOOPs* _post main-loop loops_                                     :post:
+**** 1. ↻ _Loop backmatter:_ loop up to lev4, extract html_segnames, set pointers
 
-this extra loop is needed to determine pre and (in particular) next segment for
-html, that is then used in a subsequent loop
+this extra loop is used/needed to determine pre and (in particular) next segment
+for html, that is then used in a subsequent loop
 
 NOTE there are issues attempting to do this on first pass as:
   - backmatter is created out of sequence and
@@ -1795,10 +1798,9 @@ NOTE there are issues attempting to do this on first pass as:
   - it is quite neat to have all in one place as we have here
 
   - could optimise a bit by
-    - skipping second (and third) loop unless the html seg or epub output is
-      selected
+    - skipping this loop unless the html seg or epub output is selected
 
-***** section: endnotes
+***** ↻ Loop section: endnotes
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -1815,7 +1817,7 @@ if (the_endnotes_section.length > 1) {
 }
 #+END_SRC
 
-***** section: glossary
+***** ↻ Loop section: glossary
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -1832,7 +1834,7 @@ if (the_glossary_section.length > 1) {
 }
 #+END_SRC
 
-***** section: bibliography
+***** ↻ Loop section: bibliography
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -1849,7 +1851,7 @@ if (the_bibliography_section.length > 1) {
 }
 #+END_SRC
 
-***** section: book index
+***** ↻ Loop section: book index
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -1872,7 +1874,7 @@ if (the_bookindex_section["scroll"].length > 1) {
 }
 #+END_SRC
 
-***** section: blurb
+***** ↻ Loop section: blurb
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -1889,7 +1891,7 @@ if (the_blurb_section.length > 1) {
 }
 #+END_SRC
 
-**** 2. _loop all objects:_ encode _structural relationships_ (sections, segments, objects)
+**** 2. ↻ _Loop all objects:_ encode _structural relationships_ (sections, segments, objects)
 
 needed for DOM structure, segnames & subtoc, backmatter pointers & unique image
 list
@@ -1898,25 +1900,36 @@ if used minimally only for DOM structure, segnames, subtoc, could optimise by
 - skipping second and third pass unless the output html seg or epub is being
   made!
 
-or could conveniently be used more extensively for ancestors as well (though
-this can be extracted earlier)
+- this loop could conveniently be used more extensively for ancestors as well
+  (though this information can be extracted earlier)
 
 Build here:
 - DOM structure
-- ancestors and decendants
-  - ancestors could be determined earlier, but convenient to have here
-  - descendants could be in the form of: headings contained under current
-    heading, and/or; the range of objects under the current heading
-- you could decide on a sequential object list, containing all objects (both
-  substantive and non-substantive objects), in addition to ocn, which are for
-  substantive/ citable objects within the document
+  - ancestors & decendants
+    - ancestors could be determined earlier, but convenient to have here
+    - descendants could be in the form of: headings contained under current
+      heading, and/or; the range of objects under the current heading
+- numbering
+  - already given
+    - substantive object numbers
+    - endnote
+  - provide
+    - glossary
+    - bibliography
+    - book index
+    - blurb
+    - other non-substantive objects (prefix & other stuff)
+  - you could also decide on a sequential object list, containing all objects
+    (both substantive and non-substantive objects), in addition to ocn, which
+    are for substantive/ citable objects within the document
 
 (as needed) up to document heading 1~, lev4 html:
 
-during the third pass all previous and next segment names are known
-next are not yet known for backmatter during the second pass
+- during this (the third) pass all previous and next segment names are known
+- next are not yet known for backmatter during the second pas
 
-***** images
+***** Methods
+****** images: extract
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -1931,7 +1944,47 @@ auto extract_images(S)(S content_block) {
 string[] segnames_0_4;
 #+END_SRC
 
-***** section: head
+****** images: dimensions
+
+#+name: abs_post
+#+BEGIN_SRC d
+auto _image_dimensions(M,O)(M manifest_matter, O obj) {
+  if (obj.contains_image_without_dimensions) {
+    import std.math;
+    import imageformats;
+    int w, h, chans;
+    real _w, _h;
+    int max_width = 640;
+    foreach (m; obj.text.matchAll(rgx.inline_image_without_dimensions)) {
+      debug(images) {
+        writeln(manifest_matter.src.image_dir_path ~ "/" ~ m.captures["img"]);
+      }
+      read_image_info(manifest_matter.src.image_dir_path ~ "/" ~ m.captures["img"], w, h, chans);
+      // calculate, decide max width and proportionally reduce to keep w & h within it
+      debug(images) {
+        writeln("width: ", w, ", height: ", h);
+      }
+      if (w > max_width) {
+        _w = max_width;
+        _h = round((max_width / w.to!real) * h.to!real);
+      } else {
+        _w = w;
+        _h = h;
+      }
+      obj.text = obj.text.replaceFirst(
+        rgx.inline_image_without_dimensions,
+        ("$1☼$3,w" ~ _w.to!string ~ "h" ~ _h.to!string ~ " $6")
+      );
+    }
+    debug(images) {
+      writeln("image without dimensions: ", obj.text);
+    }
+  }
+  return obj;
+}
+#+END_SRC
+
+***** ↻ Loop section: head
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -1968,7 +2021,7 @@ foreach (ref obj; the_document_head_section) {
 }
 #+END_SRC
 
-***** section: toc
+***** ↻ Loop section: toc
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -2029,7 +2082,7 @@ if (the_table_of_contents_section["scroll"].length > 1) {
 }
 #+END_SRC
 
-***** section: document body
+***** ↻ Loop section: document body
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -2066,13 +2119,16 @@ if (the_document_body_section.length > 1) {
       obj = obj_heading_ancestors(obj, lv_ancestors_txt);
     } else if (obj.is_a == "para") {
        _images ~= extract_images(obj.text);
+       obj = _image_dimensions(manifest_matter, obj);
     }
   }
 }
 auto images=uniq(_images.sort());
 #+END_SRC
 
-***** section: endnotes
+***** ↻ Loop section: endnotes
+
+- endnotes have their own number, (also use in node) and they belong to calling object
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -2118,7 +2174,9 @@ if (the_endnotes_section.length > 1) {
 }
 #+END_SRC
 
-***** section: glossary
+***** ↻ Loop section: glossary
+
+- add glossary numbering, (also use in node) no need to show in text
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -2164,7 +2222,9 @@ if (the_glossary_section.length > 1) {
 }
 #+END_SRC
 
-***** section: bibliography
+***** ↻ Loop section: bibliography
+
+- add bibliography numbering, (also use in node) no need to show in text
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -2210,7 +2270,9 @@ if (the_bibliography_section.length > 1) {
 }
 #+END_SRC
 
-***** section: book index (scroll, seg)
+***** ↻ Loop section: book index (scroll, seg)
+
+- add book index numbering?, (also use in node) no need to show in text
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -2305,7 +2367,7 @@ if (the_bookindex_section["scroll"].length > 1) {
 }
 #+END_SRC
 
-***** section: blurb
+***** ↻ Loop section: blurb
 
 #+name: abs_post
 #+BEGIN_SRC d
@@ -2449,6 +2511,7 @@ if ((opt_action.html)
   document_section_keys_sequenced["seg"]    ~= "tail";
   document_section_keys_sequenced["scroll"] ~= "tail";
 }
+auto sequenced_document_keys = docSectKeysSeq!()(document_section_keys_sequenced);
 #+END_SRC
 
 *** dup
@@ -2487,11 +2550,11 @@ dom_collapsed_buffer = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,];
 
 *** [#A] _return document tuple_                               :return:tuple:
 
-#+name: abs_post
+#+name: abs_return_tuple
 #+BEGIN_SRC d
 auto t = tuple(
   document_the,
-  docSectKeysSeq!()(document_section_keys_sequenced),
+  sequenced_document_keys,
   segnames,
   segnames_0_4,
   images,
@@ -4940,6 +5003,7 @@ static struct ObjInlineMarkupMunge {
   body {
     obj_txt_out = "";
     bool urls = false;
+    bool images_without_dimensions = false;
     tail = "";
     /+ special endnotes +/
     obj_txt_in = obj_txt_in.replaceAll(
@@ -4954,6 +5018,9 @@ static struct ObjInlineMarkupMunge {
     /+ image matched +/
     if (obj_txt_in.match(rgx.smid_image_generic)) {
       obj_txt_in = images(obj_txt_in);
+      if (obj_txt_in.match(rgx.smid_mod_image_without_dimensions)) {
+        images_without_dimensions = true;
+      }
     }
     /+ url matched +/
     if (obj_txt_in.match(rgx.smid_inline_url)) {
@@ -4979,6 +5046,7 @@ static struct ObjInlineMarkupMunge {
       ftn[2],
       ftn[3],
       urls,
+      images_without_dimensions,
     );
     return t;
   }
@@ -5249,9 +5317,10 @@ static struct ObjInlineMarkup {
     static __gshared string[] anchor_tags_ = [];
     auto x = munge.init;
     bool[string] obj_notes_and_links;
-    obj_notes_and_links["notes_reg"]  = false;
-    obj_notes_and_links["notes_star"] = false;
-    obj_notes_and_links["links"]      = false;
+    obj_notes_and_links["notes_reg"]           = false;
+    obj_notes_and_links["notes_star"]          = false;
+    obj_notes_and_links["links"]               = false;
+    obj_notes_and_links["image_no_dimensions"] = false;
     switch (obj_["is"]) {
     case "heading":
       static __gshared string anchor_tag = "";
@@ -5300,6 +5369,7 @@ static struct ObjInlineMarkup {
       obj_notes_and_links["notes_star"] = x[2];
       obj_notes_and_links["notes_plus"] = x[3];
       obj_notes_and_links["links"]      = x[4];
+      obj_notes_and_links["image_no_dimensions"] = x[5];
       break;
     }
     auto t = tuple(
@@ -5308,6 +5378,7 @@ static struct ObjInlineMarkup {
       obj_notes_and_links["notes_reg"],
       obj_notes_and_links["notes_star"],
       obj_notes_and_links["links"],
+      obj_notes_and_links["image_no_dimensions"],
     );
     anchor_tags_=[];
     return t;
@@ -7311,50 +7382,51 @@ struct HeadingAttrib {
 #+BEGIN_SRC d
 struct ObjGenericComposite {
   // size_t id;
-  string                 of_part                      = "";
-  string                 of_section                   = "";
-  string                 is_of                        = "";
-  string                 is_a                         = "";
-  string                 text                         = "";
-  string                 obj_cite_number              = "";
-  string                 obj_cite_number_off          = "";
-  string                 obj_cite_number_bkidx        = "";
-  int                    obj_cite_number_type         = 0;
-  string[]               anchor_tags                  = [];
-  int                    indent_base                  = 0;
-  int                    indent_hang                  = 0;
-  bool                   bullet                       = false;
-  bool                   inline_links                 = false;
-  bool                   inline_notes_reg             = false;
-  bool                   inline_notes_star            = false;
-  string                 language                     = ""; // not implemented, consider
-  string                 code_block_syntax            = "";
-  int                    table_number_of_columns      = 0;
-  double[]               table_column_widths          = [];
-  string[]               table_column_aligns          = [];
-  bool                   table_heading                = false;
-  bool                   table_walls                  = false; // not implemented
-  int                    ocn                          = 0;
-  string                 segment_anchor_tag           = "";
-  string                 segname_prev                 = "";
-  string                 segname_next                 = "";
-  int                    parent_lev_markup            = 0;
-  int                    parent_ocn                   = 0;
-  int[]                  ancestors                    = [];
-  string                 marked_up_level              = "9";
-  int                    heading_lev_markup           = 9;
-  int                    heading_lev_collapsed        = 9;
-  int[]                  dom_markedup                 = [ 0, 0, 0, 0, 0, 0, 0, 0,];
-  int[]                  dom_collapsed                = [ 0, 0, 0, 0, 0, 0, 0, 0,];
-  int[]                  heading_ancestors            = [ 0, 0, 0, 0, 0, 0, 0, 0,];
-  string[]               heading_ancestors_text       = [ "", "", "", "", "", "", "", "", ];
-  string[]               lev4_subtoc                  = [];
-  int                    heading_array_ptr            = 0;
-  int                    ptr_doc_object               = 0;
-  int                    ptr_html_segnames            = 0;
-  int                    ptr_heading                  = 0;
-  int                    array_ptr                    = 0;
-  int                    heading_array_ptr_segments   = 0;
+  string                 of_part                            = "";
+  string                 of_section                         = "";
+  string                 is_of                              = "";
+  string                 is_a                               = "";
+  string                 text                               = "";
+  string                 obj_cite_number                    = "";
+  string                 obj_cite_number_off                = "";
+  string                 obj_cite_number_bkidx              = "";
+  int                    obj_cite_number_type               = 0;
+  string[]               anchor_tags                        = [];
+  int                    indent_base                        = 0;
+  int                    indent_hang                        = 0;
+  bool                   bullet                             = false;
+  bool                   inline_links                       = false;
+  bool                   inline_notes_reg                   = false;
+  bool                   inline_notes_star                  = false;
+  bool                   contains_image_without_dimensions  = false;
+  string                 language                           = ""; // not implemented, consider
+  string                 code_block_syntax                  = "";
+  int                    table_number_of_columns            = 0;
+  double[]               table_column_widths                = [];
+  string[]               table_column_aligns                = [];
+  bool                   table_heading                      = false;
+  bool                   table_walls                        = false; // not implemented
+  int                    ocn                                = 0;
+  string                 segment_anchor_tag                 = "";
+  string                 segname_prev                       = "";
+  string                 segname_next                       = "";
+  int                    parent_lev_markup                  = 0;
+  int                    parent_ocn                         = 0;
+  int[]                  ancestors                          = [];
+  string                 marked_up_level                    = "9";
+  int                    heading_lev_markup                 = 9;
+  int                    heading_lev_collapsed              = 9;
+  int[]                  dom_markedup                       = [ 0, 0, 0, 0, 0, 0, 0, 0,];
+  int[]                  dom_collapsed                      = [ 0, 0, 0, 0, 0, 0, 0, 0,];
+  int[]                  heading_ancestors                  = [ 0, 0, 0, 0, 0, 0, 0, 0,];
+  string[]               heading_ancestors_text             = [ "", "", "", "", "", "", "", "", ];
+  string[]               lev4_subtoc                        = [];
+  int                    heading_array_ptr                  = 0;
+  int                    ptr_doc_object                     = 0;
+  int                    ptr_html_segnames                  = 0;
+  int                    ptr_heading                        = 0;
+  int                    array_ptr                          = 0;
+  int                    heading_array_ptr_segments         = 0;
   string[string][string] node;
 }
 #+END_SRC
diff --git a/org/output_sqlite.org b/org/output_sqlite.org
index fe76db4..c7b6571 100644
--- a/org/output_sqlite.org
+++ b/org/output_sqlite.org
@@ -1016,16 +1016,13 @@ foreach (part; doc_matters.xml.keys_seq.sql) {
       }
       break;
     case "backmatter":
-      assert(part == "endnotes" || "glossary" || "bibliography" || "bookindex_seg" || "blurb" || "tail", part);
+      assert(part == "glossary" || "bibliography" || "bookindex_seg" || "blurb" || "tail", part);
       switch (obj.is_of) {
       case "para":
         switch (obj.is_a) {
         case "heading":
           obj_txt = format_and_sqlite_load.heading(obj);
           break;
-        case "endnote":              assert(part == "endnotes", part);
-          obj_txt = format_and_sqlite_load.para(obj);
-          break;
         case "glossary":             assert(part == "glossary", part);
           obj_txt = format_and_sqlite_load.para(obj);
           break;
@@ -1086,7 +1083,7 @@ return _insert_doc_objects.join.to!(char[]).toUTF8;
 #+END_SRC
 
 ** 5. SQL statements
-*** drop tables
+*** drop index and tables
 **** DROP INDEX IF EXISTS
 
 #+name: sqlite_statement_drop_existing_index
@@ -1118,7 +1115,7 @@ DROP TABLE IF EXISTS doc_objects;
 DROP TABLE IF EXISTS urls;
 #+END_SRC
 
-*** create tables
+*** create tables and index
 **** CREATE TABLE metadata_and_text
 
 #+name: sqlite_statement_create_table_metadata_and_src_txt
@@ -1223,24 +1220,9 @@ CREATE TABLE doc_objects (
   ocns                             VARCHAR(6),
   clean                            TEXT NULL,
   body                             TEXT NULL,
-  book_idx                         TEXT NULL,
   seg                              VARCHAR(256) NULL,
   lev_an                           VARCHAR(1),
   lev                              SMALLINT NULL,
-  lev0                             SMALLINT,
-  lev1                             SMALLINT,
-  lev2                             SMALLINT,
-  lev3                             SMALLINT,
-  lev4                             SMALLINT,
-  lev5                             SMALLINT,
-  lev6                             SMALLINT,
-  lev7                             SMALLINT,
-  en_a                             SMALLINT NULL,
-  en_z                             SMALLINT NULL,
-  en_a_asterisk                    SMALLINT NULL,
-  en_z_asterisk                    SMALLINT NULL,
-  en_a_plus                        SMALLINT NULL,
-  en_z_plus                        SMALLINT NULL,
   t_of                             VARCHAR(16),
   t_is                             VARCHAR(16),
   node                             VARCHAR(16) NULL,
@@ -1259,13 +1241,6 @@ CREATE INDEX idx_ocn ON doc_objects(ocn);
 CREATE INDEX idx_digest_clean ON doc_objects(digest_clean);
 CREATE INDEX idx_digest_all ON doc_objects(digest_all);
 CREATE INDEX idx_clean ON doc_objects(clean);
-CREATE INDEX idx_lev0 ON doc_objects(lev0);
-CREATE INDEX idx_lev1 ON doc_objects(lev1);
-CREATE INDEX idx_lev2 ON doc_objects(lev2);
-CREATE INDEX idx_lev3 ON doc_objects(lev3);
-CREATE INDEX idx_lev4 ON doc_objects(lev4);
-CREATE INDEX idx_lev5 ON doc_objects(lev5);
-CREATE INDEX idx_lev6 ON doc_objects(lev6);
 CREATE INDEX idx_title ON metadata_and_text(title);
 CREATE INDEX idx_author ON metadata_and_text(creator_author);
 CREATE INDEX idx_filename ON metadata_and_text(src_filename);
diff --git a/org/output_xmls.org b/org/output_xmls.org
index ec2e5d8..7b86093 100644
--- a/org/output_xmls.org
+++ b/org/output_xmls.org
@@ -172,8 +172,8 @@ string _xhtml_anchor_tags(const(string[]) anchor_tags) {
 
 #+name: xhtml_format_objects
 #+BEGIN_SRC d
-auto header_metadata(Dm)(
-  Dm doc_matters,
+auto header_metadata(M)(
+  M  doc_matters,
 ) {
   string _title="Title";
   string _author="Author";
@@ -227,8 +227,8 @@ auto header_metadata(Dm)(
 
 #+name: xhtml_format_objects
 #+BEGIN_SRC d
-auto site_info_button(Dm)(
-  Dm doc_matters,
+auto site_info_button(M)(
+  M  doc_matters,
 ) {
   string _locations;
   if (doc_matters.conf_make_meta.make.home_button_text.length > 0) {
@@ -257,8 +257,8 @@ auto site_info_button(Dm)(
 
 #+name: xhtml_format_objects
 #+BEGIN_SRC d
-auto inline_search_form(Dm)(
-  Dm doc_matters,
+auto inline_search_form(M)(
+  M  doc_matters,
 ) {
   string _action="http://www.sisudoc.org/cgi-bin/search.cgi";
   string _db="SiSU.7a.manual";
@@ -287,8 +287,8 @@ auto inline_search_form(Dm)(
 
 #+name: xhtml_format_objects
 #+BEGIN_SRC d
-auto html_head(Dm)(
-  Dm doc_matters,
+auto html_head(M)(
+  M  doc_matters,
   string type,
 ) {
   string o;
@@ -340,8 +340,8 @@ auto html_head(Dm)(
 
 #+name: xhtml_format_objects
 #+BEGIN_SRC d
-auto epub3_seg_head(Dm)(
-  Dm doc_matters,
+auto epub3_seg_head(M)(
+  M  doc_matters,
 ) {
   string html_base = format(q"¶
 ¶",
@@ -435,8 +435,7 @@ auto inline_images(O)(
     _img_pth = "../../../image/";
   }
   if (_txt.match(rgx.inline_image)) {
-    _txt = (_txt)
-      .replaceAll( // TODO bug where image dimensions (w or h) not given & consequently set to 0; should not be used (calculate earlier, abstraction)
+    _txt = _txt.replaceAll( // TODO bug where image dimensions (w or h) not given & consequently set to 0; should not be used (calculate earlier, abstraction)
         rgx.inline_image,
         ("$1 max_width) {
+            _w = max_width;
+            _h = round((max_width / w.to!real) * h.to!real);
+          } else {
+            _w = w;
+            _h = h;
+          }
+          obj.text = obj.text.replaceFirst(
+            rgx.inline_image_without_dimensions,
+            ("$1☼$3,w" ~ _w.to!string ~ "h" ~ _h.to!string ~ " $6")
+          );
+        }
+        debug(images) {
+          writeln("image without dimensions: ", obj.text);
+        }
+      }
+      return obj;
+    }
     foreach (ref obj; the_document_head_section) {
       if (obj.is_a == "heading") {
         debug(dom) {
@@ -1540,6 +1576,7 @@ template SiSUdocAbstraction() {
           obj = obj_heading_ancestors(obj, lv_ancestors_txt);
         } else if (obj.is_a == "para") {
            _images ~= extract_images(obj.text);
+           obj = _image_dimensions(manifest_matter, obj);
         }
       }
     }
@@ -1874,6 +1911,7 @@ template SiSUdocAbstraction() {
       document_section_keys_sequenced["seg"]    ~= "tail";
       document_section_keys_sequenced["scroll"] ~= "tail";
     }
+    auto sequenced_document_keys = docSectKeysSeq!()(document_section_keys_sequenced);
     auto segnames = html_segnames.dup;
     destroy(the_document_head_section);
     destroy(the_table_of_contents_section);
@@ -1898,7 +1936,7 @@ template SiSUdocAbstraction() {
     dom_collapsed_buffer = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,];
     auto t = tuple(
       document_the,
-      docSectKeysSeq!()(document_section_keys_sequenced),
+      sequenced_document_keys,
       segnames,
       segnames_0_4,
       images,
@@ -3980,6 +4018,7 @@ template SiSUdocAbstraction() {
     body {
       obj_txt_out = "";
       bool urls = false;
+      bool images_without_dimensions = false;
       tail = "";
       /+ special endnotes +/
       obj_txt_in = obj_txt_in.replaceAll(
@@ -3994,6 +4033,9 @@ template SiSUdocAbstraction() {
       /+ image matched +/
       if (obj_txt_in.match(rgx.smid_image_generic)) {
         obj_txt_in = images(obj_txt_in);
+        if (obj_txt_in.match(rgx.smid_mod_image_without_dimensions)) {
+          images_without_dimensions = true;
+        }
       }
       /+ url matched +/
       if (obj_txt_in.match(rgx.smid_inline_url)) {
@@ -4019,6 +4061,7 @@ template SiSUdocAbstraction() {
         ftn[2],
         ftn[3],
         urls,
+        images_without_dimensions,
       );
       return t;
     }
@@ -4179,9 +4222,10 @@ template SiSUdocAbstraction() {
       static __gshared string[] anchor_tags_ = [];
       auto x = munge.init;
       bool[string] obj_notes_and_links;
-      obj_notes_and_links["notes_reg"]  = false;
-      obj_notes_and_links["notes_star"] = false;
-      obj_notes_and_links["links"]      = false;
+      obj_notes_and_links["notes_reg"]           = false;
+      obj_notes_and_links["notes_star"]          = false;
+      obj_notes_and_links["links"]               = false;
+      obj_notes_and_links["image_no_dimensions"] = false;
       switch (obj_["is"]) {
       case "heading":
         static __gshared string anchor_tag = "";
@@ -4230,6 +4274,7 @@ template SiSUdocAbstraction() {
         obj_notes_and_links["notes_star"] = x[2];
         obj_notes_and_links["notes_plus"] = x[3];
         obj_notes_and_links["links"]      = x[4];
+        obj_notes_and_links["image_no_dimensions"] = x[5];
         break;
       }
       auto t = tuple(
@@ -4238,6 +4283,7 @@ template SiSUdocAbstraction() {
         obj_notes_and_links["notes_reg"],
         obj_notes_and_links["notes_star"],
         obj_notes_and_links["links"],
+        obj_notes_and_links["image_no_dimensions"],
       );
       anchor_tags_=[];
       return t;
diff --git a/src/sdp/meta/object_setter.d b/src/sdp/meta/object_setter.d
index e4bb05f..380bab7 100644
--- a/src/sdp/meta/object_setter.d
+++ b/src/sdp/meta/object_setter.d
@@ -17,50 +17,51 @@ template ObjectSetter() {
   }
   struct ObjGenericComposite {
     // size_t id;
-    string                 of_part                      = "";
-    string                 of_section                   = "";
-    string                 is_of                        = "";
-    string                 is_a                         = "";
-    string                 text                         = "";
-    string                 obj_cite_number              = "";
-    string                 obj_cite_number_off          = "";
-    string                 obj_cite_number_bkidx        = "";
-    int                    obj_cite_number_type         = 0;
-    string[]               anchor_tags                  = [];
-    int                    indent_base                  = 0;
-    int                    indent_hang                  = 0;
-    bool                   bullet                       = false;
-    bool                   inline_links                 = false;
-    bool                   inline_notes_reg             = false;
-    bool                   inline_notes_star            = false;
-    string                 language                     = ""; // not implemented, consider
-    string                 code_block_syntax            = "";
-    int                    table_number_of_columns      = 0;
-    double[]               table_column_widths          = [];
-    string[]               table_column_aligns          = [];
-    bool                   table_heading                = false;
-    bool                   table_walls                  = false; // not implemented
-    int                    ocn                          = 0;
-    string                 segment_anchor_tag           = "";
-    string                 segname_prev                 = "";
-    string                 segname_next                 = "";
-    int                    parent_lev_markup            = 0;
-    int                    parent_ocn                   = 0;
-    int[]                  ancestors                    = [];
-    string                 marked_up_level              = "9";
-    int                    heading_lev_markup           = 9;
-    int                    heading_lev_collapsed        = 9;
-    int[]                  dom_markedup                 = [ 0, 0, 0, 0, 0, 0, 0, 0,];
-    int[]                  dom_collapsed                = [ 0, 0, 0, 0, 0, 0, 0, 0,];
-    int[]                  heading_ancestors            = [ 0, 0, 0, 0, 0, 0, 0, 0,];
-    string[]               heading_ancestors_text       = [ "", "", "", "", "", "", "", "", ];
-    string[]               lev4_subtoc                  = [];
-    int                    heading_array_ptr            = 0;
-    int                    ptr_doc_object               = 0;
-    int                    ptr_html_segnames            = 0;
-    int                    ptr_heading                  = 0;
-    int                    array_ptr                    = 0;
-    int                    heading_array_ptr_segments   = 0;
+    string                 of_part                            = "";
+    string                 of_section                         = "";
+    string                 is_of                              = "";
+    string                 is_a                               = "";
+    string                 text                               = "";
+    string                 obj_cite_number                    = "";
+    string                 obj_cite_number_off                = "";
+    string                 obj_cite_number_bkidx              = "";
+    int                    obj_cite_number_type               = 0;
+    string[]               anchor_tags                        = [];
+    int                    indent_base                        = 0;
+    int                    indent_hang                        = 0;
+    bool                   bullet                             = false;
+    bool                   inline_links                       = false;
+    bool                   inline_notes_reg                   = false;
+    bool                   inline_notes_star                  = false;
+    bool                   contains_image_without_dimensions  = false;
+    string                 language                           = ""; // not implemented, consider
+    string                 code_block_syntax                  = "";
+    int                    table_number_of_columns            = 0;
+    double[]               table_column_widths                = [];
+    string[]               table_column_aligns                = [];
+    bool                   table_heading                      = false;
+    bool                   table_walls                        = false; // not implemented
+    int                    ocn                                = 0;
+    string                 segment_anchor_tag                 = "";
+    string                 segname_prev                       = "";
+    string                 segname_next                       = "";
+    int                    parent_lev_markup                  = 0;
+    int                    parent_ocn                         = 0;
+    int[]                  ancestors                          = [];
+    string                 marked_up_level                    = "9";
+    int                    heading_lev_markup                 = 9;
+    int                    heading_lev_collapsed              = 9;
+    int[]                  dom_markedup                       = [ 0, 0, 0, 0, 0, 0, 0, 0,];
+    int[]                  dom_collapsed                      = [ 0, 0, 0, 0, 0, 0, 0, 0,];
+    int[]                  heading_ancestors                  = [ 0, 0, 0, 0, 0, 0, 0, 0,];
+    string[]               heading_ancestors_text             = [ "", "", "", "", "", "", "", "", ];
+    string[]               lev4_subtoc                        = [];
+    int                    heading_array_ptr                  = 0;
+    int                    ptr_doc_object                     = 0;
+    int                    ptr_html_segnames                  = 0;
+    int                    ptr_heading                        = 0;
+    int                    array_ptr                          = 0;
+    int                    heading_array_ptr_segments         = 0;
     string[string][string] node;
   }
   struct TheObjects {
diff --git a/src/sdp/meta/rgx.d b/src/sdp/meta/rgx.d
index 8b6f4d2..869728f 100644
--- a/src/sdp/meta/rgx.d
+++ b/src/sdp/meta/rgx.d
@@ -153,6 +153,7 @@ static template SiSUrgxInit() {
     static smid_image_generic                              = ctRegex!(`(?:^|[ ]|[^\S]?)\{(?:~\^\s+|\s*)\S+\.(?:png|gif|jpg).+?\}(?:image|(?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)\S+?)[;:!,?.]?(?:[ )\]]|$)`, "mg");
     static smid_image_with_dimensions                      = ctRegex!(`(?P
(?:^|[ ]|[^\S]?)\{(?:~\^\s+|\s*))(?P\S+\.(?:png|gif|jpg))\s+(?P\d+)x(?P\d+)\s*(?P(?:.+?)\s*\}(?:image|(?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)\S+?)(?:[;:!,?.]?(?:[ )\]]|$)))`, "mg");
     static smid_image                                      = ctRegex!(`(?P
(?:^|[ ]|[^\S]?)\{(?:~\^\s+|\s*))(?P\S+\.(?:png|gif|jpg))\s*(?P(?:.+?)\s*\}(?:image|(?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)\S+?)(?:[;:!,?.]?(?:[ )\]]|$)))`, "mg");
+    static smid_mod_image_without_dimensions               = ctRegex!(`\{(?:~\^\s+|\s*)☼\S+\.(?:png|gif|jpg),w0h0\s+(?:.+?)\s*\}(?:image|(?:https?|git):\/\/\S+?)(?:[;:!,?.]?(?:[ )\]]|$))`, "mg");
     /+ inline markup book index +/
     static book_index                                     = ctRegex!(`^=\{\s*(.+?)\}$`, "m");
     static book_index_open                                = ctRegex!(`^=\{\s*([^}]+?)$`);
@@ -248,6 +249,7 @@ static template SiSUrgxInit() {
     static inline_text_and_note_al_                       = ctRegex!(`(.+?(?:【[*+]*\s+.+?】|$))`, "mg");
     /+ inline markup footnotes endnotes +/
     static inline_image                                   = ctRegex!(`(?P
┥)☼(?P(?P\S+?\.(?:jpg|gif|png)),w(?P\d+)h(?P\d+))\s*(?P.*?┝┤.+?├)`, "mg");
+    static inline_image_without_dimensions                = ctRegex!(`(?P
┥)☼(?P(?P\S+?\.(?:jpg|gif|png)),w(?P0)h(?P0))\s*(?P.*?┝┤.+?├)`, "mg");
     static inline_link                                    = ctRegex!(`┥(?P.+?)┝┤(?P.+?)├`, "mg");
     static inline_link_clean                              = ctRegex!(`┤(?:.+?)├|[┥┝]`, "mg");
     static inline_a_url                                   = ctRegex!(`(┤)(\S+?)(├)`, "mg");
diff --git a/src/sdp/output/html.d b/src/sdp/output/html.d
index d4770e7..ddd3c9f 100644
--- a/src/sdp/output/html.d
+++ b/src/sdp/output/html.d
@@ -180,9 +180,9 @@ template outputHTML() {
     }
     writeln(" ", pth_html.fn_scroll(doc_matters.src.filename));
   }
-  void seg(D,I)(
+  void seg(D,M)(
     auto return ref const D    doc_abstraction,
-    auto return ref I          doc_matters,
+    auto ref              M    doc_matters,
   ) {
     mixin SiSUoutputRgxInit;
     auto rgx = Rgx();
diff --git a/src/sdp/output/paths_source.d b/src/sdp/output/paths_source.d
index 8f14b8e..e7233f0 100644
--- a/src/sdp/output/paths_source.d
+++ b/src/sdp/output/paths_source.d
@@ -295,18 +295,22 @@ template PathMatters() {
             return _dir;
           }
           auto image_dir_path() {
-            string _img_pth(string _possible_img_pth) {
-              return asNormalizedPath(file_with_absolute_path.dirName ~ "/" ~ _possible_img_pth).array;
-            }
             string _paths;
             string[] _possible_img_pths = [ "./image", "../image", "../../image" ];
             string _img_pth_found = "";
-            foreach(_possible_img_pth; _possible_img_pths) {
-              if (exists(_img_pth(_possible_img_pth))) {
-                _img_pth_found = _img_pth(_possible_img_pth);
-                break;
-              } else {
-                _paths ~= " " ~ _img_pth(_possible_img_pth);
+            if (is_pod) {
+              _img_pth_found = asNormalizedPath(file_with_absolute_path.dirName ~ "/../../image").array;
+            } else {
+              string _img_pth(string _possible_img_pth) {
+                return asNormalizedPath(file_with_absolute_path.dirName ~ "/" ~ _possible_img_pth).array;
+              }
+              foreach(_possible_img_pth; _possible_img_pths) {
+                if (exists(_img_pth(_possible_img_pth))) {
+                  _img_pth_found = _img_pth(_possible_img_pth);
+                  break;
+                } else {
+                  _paths ~= " " ~ _img_pth(_possible_img_pth);
+                }
               }
             }
             if (_img_pth_found.empty) {
diff --git a/src/sdp/output/rgx.d b/src/sdp/output/rgx.d
index 60f15cf..a62791c 100644
--- a/src/sdp/output/rgx.d
+++ b/src/sdp/output/rgx.d
@@ -62,6 +62,7 @@ static template SiSUoutputRgxInit() {
     static inline_text_and_note_al_                       = ctRegex!(`(.+?(?:【[*+]*\s+.+?】|$))`, "mg");
     /+ inline markup footnotes endnotes +/
     static inline_image                                   = ctRegex!(`(?P
┥)☼(?P(?P\S+?\.(?:jpg|gif|png)),w(?P\d+)h(?P\d+))\s*(?P.*?┝┤.+?├)`, "mg");
+    static inline_image_without_dimensions                = ctRegex!(`(?P
┥)☼(?P(?P\S+?\.(?:jpg|gif|png)),w(?P0)h(?P0))\s*(?P.*?┝┤.+?├)`, "mg");
     static inline_link                                    = ctRegex!(`┥(?P.+?)┝┤(?P.+?)├`, "mg");
     static inline_link_clean                              = ctRegex!(`┤(?:.+?)├|[┥┝]`, "mg");
     static inline_a_url                                   = ctRegex!(`(┤)(\S+?)(├)`, "mg");
diff --git a/src/sdp/output/sqlite.d b/src/sdp/output/sqlite.d
index fc1843f..e9667ae 100644
--- a/src/sdp/output/sqlite.d
+++ b/src/sdp/output/sqlite.d
@@ -682,24 +682,9 @@ template SQLiteTablesReCreate() {
         ocns                             VARCHAR(6),
         clean                            TEXT NULL,
         body                             TEXT NULL,
-        book_idx                         TEXT NULL,
         seg                              VARCHAR(256) NULL,
         lev_an                           VARCHAR(1),
         lev                              SMALLINT NULL,
-        lev0                             SMALLINT,
-        lev1                             SMALLINT,
-        lev2                             SMALLINT,
-        lev3                             SMALLINT,
-        lev4                             SMALLINT,
-        lev5                             SMALLINT,
-        lev6                             SMALLINT,
-        lev7                             SMALLINT,
-        en_a                             SMALLINT NULL,
-        en_z                             SMALLINT NULL,
-        en_a_asterisk                    SMALLINT NULL,
-        en_z_asterisk                    SMALLINT NULL,
-        en_a_plus                        SMALLINT NULL,
-        en_z_plus                        SMALLINT NULL,
         t_of                             VARCHAR(16),
         t_is                             VARCHAR(16),
         node                             VARCHAR(16) NULL,
@@ -712,13 +697,6 @@ template SQLiteTablesReCreate() {
       CREATE INDEX idx_digest_clean ON doc_objects(digest_clean);
       CREATE INDEX idx_digest_all ON doc_objects(digest_all);
       CREATE INDEX idx_clean ON doc_objects(clean);
-      CREATE INDEX idx_lev0 ON doc_objects(lev0);
-      CREATE INDEX idx_lev1 ON doc_objects(lev1);
-      CREATE INDEX idx_lev2 ON doc_objects(lev2);
-      CREATE INDEX idx_lev3 ON doc_objects(lev3);
-      CREATE INDEX idx_lev4 ON doc_objects(lev4);
-      CREATE INDEX idx_lev5 ON doc_objects(lev5);
-      CREATE INDEX idx_lev6 ON doc_objects(lev6);
       CREATE INDEX idx_title ON metadata_and_text(title);
       CREATE INDEX idx_author ON metadata_and_text(creator_author);
       CREATE INDEX idx_filename ON metadata_and_text(src_filename);
@@ -1006,16 +984,13 @@ template SQLiteInsertDocObjectsLoop() {
           }
           break;
         case "backmatter":
-          assert(part == "endnotes" || "glossary" || "bibliography" || "bookindex_seg" || "blurb" || "tail", part);
+          assert(part == "glossary" || "bibliography" || "bookindex_seg" || "blurb" || "tail", part);
           switch (obj.is_of) {
           case "para":
             switch (obj.is_a) {
             case "heading":
               obj_txt = format_and_sqlite_load.heading(obj);
               break;
-            case "endnote":              assert(part == "endnotes", part);
-              obj_txt = format_and_sqlite_load.para(obj);
-              break;
             case "glossary":             assert(part == "glossary", part);
               obj_txt = format_and_sqlite_load.para(obj);
               break;
@@ -1195,24 +1170,9 @@ template SQLiteTablesCreate() {
             ocns                             VARCHAR(6),
             clean                            TEXT NULL,
             body                             TEXT NULL,
-            book_idx                         TEXT NULL,
             seg                              VARCHAR(256) NULL,
             lev_an                           VARCHAR(1),
             lev                              SMALLINT NULL,
-            lev0                             SMALLINT,
-            lev1                             SMALLINT,
-            lev2                             SMALLINT,
-            lev3                             SMALLINT,
-            lev4                             SMALLINT,
-            lev5                             SMALLINT,
-            lev6                             SMALLINT,
-            lev7                             SMALLINT,
-            en_a                             SMALLINT NULL,
-            en_z                             SMALLINT NULL,
-            en_a_asterisk                    SMALLINT NULL,
-            en_z_asterisk                    SMALLINT NULL,
-            en_a_plus                        SMALLINT NULL,
-            en_z_plus                        SMALLINT NULL,
             t_of                             VARCHAR(16),
             t_is                             VARCHAR(16),
             node                             VARCHAR(16) NULL,
@@ -1225,13 +1185,6 @@ template SQLiteTablesCreate() {
           CREATE INDEX idx_digest_clean ON doc_objects(digest_clean);
           CREATE INDEX idx_digest_all ON doc_objects(digest_all);
           CREATE INDEX idx_clean ON doc_objects(clean);
-          CREATE INDEX idx_lev0 ON doc_objects(lev0);
-          CREATE INDEX idx_lev1 ON doc_objects(lev1);
-          CREATE INDEX idx_lev2 ON doc_objects(lev2);
-          CREATE INDEX idx_lev3 ON doc_objects(lev3);
-          CREATE INDEX idx_lev4 ON doc_objects(lev4);
-          CREATE INDEX idx_lev5 ON doc_objects(lev5);
-          CREATE INDEX idx_lev6 ON doc_objects(lev6);
           CREATE INDEX idx_title ON metadata_and_text(title);
           CREATE INDEX idx_author ON metadata_and_text(creator_author);
           CREATE INDEX idx_filename ON metadata_and_text(src_filename);
diff --git a/src/sdp/output/xmls.d b/src/sdp/output/xmls.d
index 1621732..785d87e 100644
--- a/src/sdp/output/xmls.d
+++ b/src/sdp/output/xmls.d
@@ -100,8 +100,8 @@ template outputXHTMLs() {
       }
       return tags;
     }
-    auto header_metadata(Dm)(
-      Dm doc_matters,
+    auto header_metadata(M)(
+      M  doc_matters,
     ) {
       string _title="Title";
       string _author="Author";
@@ -149,8 +149,8 @@ template outputXHTMLs() {
       );
       return o;
     }
-    auto site_info_button(Dm)(
-      Dm doc_matters,
+    auto site_info_button(M)(
+      M  doc_matters,
     ) {
       string _locations;
       if (doc_matters.conf_make_meta.make.home_button_text.length > 0) {
@@ -173,8 +173,8 @@ template outputXHTMLs() {
       );
       return o;
     }
-    auto inline_search_form(Dm)(
-      Dm doc_matters,
+    auto inline_search_form(M)(
+      M  doc_matters,
     ) {
       string _action="http://www.sisudoc.org/cgi-bin/search.cgi";
       string _db="SiSU.7a.manual";
@@ -197,8 +197,8 @@ template outputXHTMLs() {
       );
       return o;
     }
-    auto html_head(Dm)(
-      Dm doc_matters,
+    auto html_head(M)(
+      M  doc_matters,
       string type,
     ) {
       string o;
@@ -244,8 +244,8 @@ template outputXHTMLs() {
       );
       return o;
     }
-    auto epub3_seg_head(Dm)(
-      Dm doc_matters,
+    auto epub3_seg_head(M)(
+      M  doc_matters,
     ) {
       string html_base = format(q"¶
     ¶",
@@ -326,8 +326,7 @@ template outputXHTMLs() {
         _img_pth = "../../../image/";
       }
       if (_txt.match(rgx.inline_image)) {
-        _txt = (_txt)
-          .replaceAll( // TODO bug where image dimensions (w or h) not given & consequently set to 0; should not be used (calculate earlier, abstraction)
+        _txt = _txt.replaceAll( // TODO bug where image dimensions (w or h) not given & consequently set to 0; should not be used (calculate earlier, abstraction)
             rgx.inline_image,
             ("$1