From 48ba380760b306077afa7a156a21d3ff98d26775 Mon Sep 17 00:00:00 2001 From: Ralph Amissah Date: Fri, 4 May 2018 21:22:39 -0400 Subject: html & epub images in place (dimensions not & other issues) --- org/default_misc.org | 3 +- org/default_paths.org | 32 +++++++-- org/default_regex.org | 8 ++- org/meta_abstraction.org | 55 +++++++++++++-- org/output_hub.org | 3 + org/output_sisupod.org | 5 +- org/output_xmls.org | 153 +++++++++++++++++++++++++++++----------- src/sdp/meta/defaults.d | 1 + src/sdp/meta/metadoc_from_src.d | 49 +++++++++++-- src/sdp/meta/rgx.d | 4 ++ src/sdp/output/defaults.d | 1 + src/sdp/output/epub3.d | 28 ++++---- src/sdp/output/html.d | 51 ++++++++++---- src/sdp/output/hub.d | 3 + src/sdp/output/paths_source.d | 32 +++++++-- src/sdp/output/rgx.d | 1 + src/sdp/output/source_sisupod.d | 5 +- src/sdp/output/xmls.d | 61 ++++++++++++---- 18 files changed, 379 insertions(+), 116 deletions(-) diff --git a/org/default_misc.org b/org/default_misc.org index d021565..582dfa9 100644 --- a/org/default_misc.org +++ b/org/default_misc.org @@ -214,7 +214,7 @@ import 21 special characters used: #+BEGIN_SRC text -【】〖〗┥┝┤├¤░┘┙┚┼┿╂┊┏┚┆■ +【】〖〗┥┝┤├¤░┘┙┚┼┿╂┊┏┚┆■☼ #+END_SRC #+name: defaults_template_markup @@ -240,6 +240,7 @@ template InternalMarkup() { auto tc_c = "┚"; auto tc_p = "┆"; auto mono = "■"; + auto img = "☼"; static string indent_by_spaces_provided(int indent, string _indent_spaces ="░░") { _indent_spaces = replicate(_indent_spaces, indent); return _indent_spaces; diff --git a/org/default_paths.org b/org/default_paths.org index 4da6a85..5c0dba4 100644 --- a/org/default_paths.org +++ b/org/default_paths.org @@ -61,7 +61,7 @@ template PodManifest() { _manifest_path = _pth; } else if (_pth.match(rgx.src_pth_contents) && exists(_pth)!=0 && _pth.isFile) { - _manifest_path = dirName(_pth); + _manifest_path = _pth.dirName; } else if (_pth.match(rgx.src_pth_pod_sst_or_ssm) && exists(_pth)!=0 && (_pth.isFile)) { if (auto m = _pth.match(rgx.src_pth_pod_sst_or_ssm)) { @@ -591,7 +591,7 @@ template SiSUpathsSRC() { static auto rgx = Rgx(); auto SiSUpathsSRC(D,Fn)( D _pwd, - Fn _fn_src_and_relative_path, + Fn _fn_src_and_path, ) { struct SisuSrcPaths { auto pwd() { @@ -600,7 +600,7 @@ template SiSUpathsSRC() { auto language() { // use command line info as well? string _k; - if (auto m = _fn_src_and_relative_path.match(rgx.language_code_and_filename)) { + if (auto m = _fn_src_and_path.match(rgx.language_code_and_filename)) { _k = m.captures[1]; } else { /+ unknown until doc_meta read, (could provide & use command line info?) +/ _k = "xx"; // original default was "en" but is not known @@ -625,11 +625,29 @@ template SiSUpathsSRC() { auto doc_src_fn_with_path_for_text_root_and_lng() { return asNormalizedPath(text_root.chainPath(language)).array; } - auto doc_src_with_relative_path() { - return asNormalizedPath(pwd.chainPath(_fn_src_and_relative_path)).array; - } auto doc_src_fn() { - return asNormalizedPath(_fn_src_and_relative_path.baseName).array; + return asNormalizedPath(_fn_src_and_path.baseName).array; + } + auto doc_src_with_path() { + return asNormalizedPath(pwd.chainPath(_fn_src_and_path)).array; + } + auto src_image_root_with_path() { + string[] _possible_img_pth = [ + asNormalizedPath(pwd.chainPath((_fn_src_and_path).dirName ~ "/image")).array, + asNormalizedPath(pwd.chainPath((_fn_src_and_path).dirName ~ "/../image")).array, + asNormalizedPath(pwd.chainPath((_fn_src_and_path).dirName ~ "/../../image")).array, + ]; + string _img_pth_found = ""; + foreach(_img_pth; _possible_img_pth) { + if (exists(_img_pth)) { + _img_pth_found = _img_pth; + break; + } + } + if (_img_pth_found.empty) { + writeln("WARNING not image path found, searched: ", _possible_img_pth); + } + return _img_pth_found; } } return SisuSrcPaths(); diff --git a/org/default_regex.org b/org/default_regex.org index 5b759b0..6b535a0 100644 --- a/org/default_regex.org +++ b/org/default_regex.org @@ -22,10 +22,10 @@ http://dlang.org/phobos/std_regex.html - Regex!char (wchar/dchar) that contains a pattern in the form of compiled bytecode. - StaticRegex!char (wchar/dchar) that contains a pattern in the form of compiled native machine code. -21 special characters used: +22 special characters used: #+BEGIN_SRC text -【】〖〗┥┝┤├¤░┘┙┚┼┿╂┊┏┚┆■ +【】〖〗┥┝┤├¤░┘┙┚┼┿╂┊┏┚┆■☼ #+END_SRC ** 0. module template @@ -269,6 +269,9 @@ static smid_inline_link_endnote_url_helper = ctRegex!(`\{~\^\s+(?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");
 #+END_SRC
 
 *** inline markup book index                             :inline:bookindex:
@@ -485,6 +488,7 @@ static inline_text_and_note_al_                       = ctRegex!(`(.+?(?:【[*+]
 #+name: prgmkup_rgx
 #+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_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 27f83be..4acb481 100644
--- a/org/meta_abstraction.org
+++ b/org/meta_abstraction.org
@@ -2614,7 +2614,7 @@ auto _doc_header_and_make_substitutions_(L,CMM)(
   if (conf_make_meta.make.substitute) {
     foreach(substitution_pair; conf_make_meta.make.substitute) {
       line = line.replaceAll(
-        regex(substitution_pair[Substitute.match]),
+        regex("\b" ~ substitution_pair[Substitute.match]),
         substitution_pair[Substitute.markup]
       );
     }
@@ -2637,19 +2637,19 @@ auto _doc_header_and_make_substitutions_fontface_(L,CMM)(
   enum Substitute { match, markup, }
   if ( conf_make_meta.make.bold) {
     line = line.replaceAll(
-      regex(conf_make_meta.make.bold[Substitute.match]),
+      regex("\b" ~ conf_make_meta.make.bold[Substitute.match]),
       conf_make_meta.make.bold[Substitute.markup]
     );
   }
   if (conf_make_meta.make.emphasis) {
     line = line.replaceAll(
-      regex(conf_make_meta.make.emphasis[Substitute.match]),
+      regex("\b" ~ conf_make_meta.make.emphasis[Substitute.match]),
       conf_make_meta.make.emphasis[Substitute.markup]
     );
   }
   if (conf_make_meta.make.italics) {
     line = line.replaceAll(
-      regex(conf_make_meta.make.italics[Substitute.match]),
+      regex("\b" ~ conf_make_meta.make.italics[Substitute.match]),
       conf_make_meta.make.italics[Substitute.markup]
     );
   }
@@ -4747,7 +4747,7 @@ static struct ObjInlineMarkupMunge {
   }
 #+END_SRC
 
-******* url links
+******* url links including images
 
 #+name: meta_emitters_obj_inline_markup_munge
 #+BEGIN_SRC d
@@ -4812,6 +4812,47 @@ static struct ObjInlineMarkupMunge {
   }
 #+END_SRC
 
+#+name: meta_emitters_obj_inline_markup_munge
+#+BEGIN_SRC d
+  static auto images(Ot)(Ot obj_txt_in) {
+    debug(asserts) {
+      static assert(is(typeof(obj_txt_in) == string));
+    }
+    static auto mng = InlineMarkup();
+    obj_txt_in = obj_txt_in.replaceAll(rgx.inline_mono, (mng.mono ~ "{$1}" ~ mng.mono)); // figure
+    /+ url matched +/
+    obj_txt_in = obj_txt_in.replaceAll(rgx.inline_notes_al_special, ""); // TODO reinstate when special footnotes are implemented
+    if (obj_txt_in.match(rgx.smid_image_generic)) { /+ images with and without links +/
+      debug(images) {
+        writeln("Image: ", obj_txt_in);
+      }
+      if (obj_txt_in.match(rgx.smid_image_with_dimensions)) {
+        obj_txt_in = (obj_txt_in).replaceAll(
+            rgx.smid_image_with_dimensions,
+            ("$1"
+              ~ mkup.img ~ "$2,w$3h$4 "
+              ~ "$5")            // ("$1{ $2 }$2$3")
+          );
+        debug(images) {
+          writeln("IMAGE with size: ", obj_txt_in); // decide on representation
+        }
+      } else if (obj_txt_in.match(rgx.smid_image)) {
+        obj_txt_in = (obj_txt_in).replaceAll(
+            rgx.smid_image,
+            ("$1"
+              ~ mkup.img ~ "$2,w0h0 "
+              ~ "$3")            // ("$1{ $2 }$2$3")
+          );
+        debug(images) {
+          writeln("IMAGE: ", obj_txt_in); // decide on representation
+        }
+      }
+    }
+    obj_txt_in = obj_txt_in.replaceAll(rgx.inline_mono_box, ("#{$1}#")); // figure
+    return obj_txt_in;
+  }
+#+END_SRC
+
 ******* footnotes endnotes markup
 
 #+name: meta_emitters_obj_inline_markup_munge
@@ -4909,6 +4950,10 @@ static struct ObjInlineMarkupMunge {
         rgx.inline_notes_curly_sp_plus,
         (mkup.en_a_o ~ "+" ~ " $1" ~ mkup.en_a_c)
       );
+    /+ image matched +/
+    if (obj_txt_in.match(rgx.smid_image_generic)) {
+      obj_txt_in = images(obj_txt_in);
+    }
     /+ url matched +/
     if (obj_txt_in.match(rgx.smid_inline_url)) {
       urls = true;
diff --git a/org/output_hub.org b/org/output_hub.org
index 3129b72..bccfb01 100644
--- a/org/output_hub.org
+++ b/org/output_hub.org
@@ -160,6 +160,7 @@ if (doc_matters.opt.action.html) {
     writeln("html seg done");
   }
   outputHTML!().css(doc_matters);
+  outputHTML!().images_cp(doc_matters);
 } else if (doc_matters.opt.action.html_seg) {
   if ((doc_matters.opt.action.verbose)) {
     writeln("html seg processing... ");
@@ -170,6 +171,7 @@ if (doc_matters.opt.action.html) {
     writeln("html seg done");
   }
   outputHTML!().css(doc_matters);
+  outputHTML!().images_cp(doc_matters);
 } else if (doc_matters.opt.action.html_scroll) {
   if ((doc_matters.opt.action.verbose)) {
     writeln("html scroll processing... ");
@@ -180,6 +182,7 @@ if (doc_matters.opt.action.html) {
     writeln("html scroll done");
   }
   outputHTML!().css(doc_matters);
+  outputHTML!().images_cp(doc_matters);
 }
 #+END_SRC
 
diff --git a/org/output_sisupod.org b/org/output_sisupod.org
index a53f9c7..931f80b 100644
--- a/org/output_sisupod.org
+++ b/org/output_sisupod.org
@@ -120,10 +120,7 @@ auto fn_sisupod = pths_sisupod.sisupod_filename(doc_matters.src.filename).zpod;
         pths_sisupod.image_root(doc_matters.src.filename).zpod, "/", image
       );
     }
-    auto fn_src_in = ((doc_matters.src.is_pod)
-      ? doc_matters.src.image_dir_path
-      : pth_sisudoc_src.image_root).to!string
-      ~ "/" ~ image;
+    auto fn_src_in = doc_matters.src_path_info.src_image_root_with_path ~ "/" ~ image;
     auto fn_src_out_sisupod_zip_base
       = pths_sisupod.image_root(doc_matters.src.filename).zpod.to!string
       ~ "/" ~ image;
diff --git a/org/output_xmls.org b/org/output_xmls.org
index 0cbde63..9a27bc7 100644
--- a/org/output_xmls.org
+++ b/org/output_xmls.org
@@ -416,6 +416,36 @@ auto tail() {
 #+END_SRC
 
 *** inline markup
+**** images
+
+#+name: xhtml_format_objects
+#+BEGIN_SRC d
+auto inline_images(O)(
+  auto return ref const O obj,
+  string                  _txt,
+  string                  _suffix    = ".html",
+  string                  _xml_type = "seg",
+) {
+  string _img_pth;
+  if (_xml_type == "epub") {
+    _img_pth = "image/";
+  } else if (_xml_type == "scroll") {
+    _img_pth = "../../image/";
+  } else if (_xml_type == "seg") {
+    _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)
+        rgx.inline_image,
+        ("$1 $6"));
+  }
+  return _txt;
+}
+#+END_SRC
+
 **** links
 
 #+name: xhtml_format_objects
@@ -424,11 +454,11 @@ auto inline_links(O)(
   auto return ref const O obj,
   string                  _txt,
   string                  _suffix    = ".html",
-  string                  seg_scroll = "seg",
+  string                  _xml_type = "seg",
 ) {
   if (obj.inline_links) {
     if ((_txt.match(rgx.mark_internal_site_lnk))
-    && (seg_scroll == "scroll")) { // conditions reversed to avoid: gdc compiled program run segfault
+    && (_xml_type == "scroll")) { // conditions reversed to avoid: gdc compiled program run segfault
       _txt = (_txt).replaceAll(
         rgx.inline_seg_link,
         "$1");
@@ -551,6 +581,7 @@ auto inline_markup_scroll(O)(
   string                   _txt,
   string                   _suffix = ".html",
 ) {
+  _txt = inline_images(obj, _txt, _suffix, "scroll");
   _txt = inline_links(obj, _txt, _suffix, "scroll");
   _txt = inline_notes_scroll(obj, _txt);
   return _txt;
@@ -565,8 +596,10 @@ auto inline_markup_seg(O)(
   auto return ref const O  obj,
   string                   _txt,
   string                   _suffix = ".html",
+  string                   _xml_type = "seg",
 ) {
-  _txt = inline_links(obj, _txt, _suffix, "seg");
+  _txt = inline_images(obj, _txt, _suffix, _xml_type);
+  _txt = inline_links(obj, _txt, _suffix, _xml_type);
   auto t = inline_notes_seg(obj, _txt);
   return t;
 }
@@ -696,11 +729,11 @@ auto nav_pre_next_svg(O)(
 auto heading(O)(
   auto return ref const O    obj,
   string                     _txt,
-  string                     _type="html",
+  string                     _xml_type = "html",
 ) {
   auto tags = _xhtml_anchor_tags(obj.anchor_tags);
   string _horizontal_rule = "
"; - if ((_type != "html") + if ((_xml_type != "html") || (obj.heading_lev_markup == 0 || obj.heading_lev_markup > 4)) { _horizontal_rule = ""; } @@ -768,12 +801,12 @@ auto heading_seg(O)( auto return ref const O obj, string _txt, string _suffix = ".html", - string _type = "html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0]; string[] _endnotes = t[1]; - string o = heading(obj, _txt, _type); + string o = heading(obj, _txt, _xml_type); auto u = tuple( o, _endnotes, @@ -852,8 +885,9 @@ auto para_seg(O)( auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0].to!string; string[] _endnotes = t[1]; string o = para(obj, _txt); @@ -927,8 +961,9 @@ auto quote_seg(O)( auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0].to!string; string[] _endnotes = t[1]; string o = quote(obj, _txt); @@ -986,6 +1021,7 @@ auto group_scroll(O)( auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { auto tags = _xhtml_anchor_tags(obj.anchor_tags); _txt = inline_markup_scroll(obj, _txt, _suffix); @@ -1002,8 +1038,9 @@ auto group_seg(O)( auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0].to!string; string[] _endnotes = t[1]; string o = group(obj, _txt); @@ -1057,6 +1094,7 @@ auto block_scroll(O)( auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { auto tags = _xhtml_anchor_tags(obj.anchor_tags); _txt = inline_markup_scroll(obj, _txt, _suffix); @@ -1073,8 +1111,9 @@ auto block_seg(O)( auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0].to!string; string[] _endnotes = t[1]; string o = block(obj, _txt); @@ -1128,6 +1167,7 @@ auto verse_scroll(O)( auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { auto tags = _xhtml_anchor_tags(obj.anchor_tags); _txt = inline_markup_scroll(obj, _txt, _suffix); @@ -1144,8 +1184,9 @@ auto verse_seg(O)( auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0].to!string; string[] _endnotes = t[1]; string o = verse(obj, _txt); @@ -1304,6 +1345,7 @@ template outputHTML() { <> <> <> + <> } #+END_SRC @@ -1538,7 +1580,7 @@ void seg(D,I)( top_level_headings[3] = ""; goto default; default: - auto t = xhtml_format.heading_seg(obj, _txt, suffix); + auto t = xhtml_format.heading_seg(obj, _txt, suffix, "seg"); top_level_headings[obj.heading_lev_markup] = t[0]; break; } @@ -1553,13 +1595,13 @@ void seg(D,I)( // writeln(top_level_heading); doc_html[segment_filename] ~= top_level_heading; } - auto t = xhtml_format.heading_seg(obj, _txt, suffix); + auto t = xhtml_format.heading_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0].to!string; doc_html[segment_filename] ~= xhtml_format.lev4_heading_subtoc(obj); doc_html_endnotes[segment_filename] ~= t[1]; break; case 5: .. case 7: - auto t = xhtml_format.heading_seg(obj, _txt, suffix); + auto t = xhtml_format.heading_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0].to!string; doc_html_endnotes[segment_filename] ~= t[1]; break; @@ -1583,7 +1625,7 @@ void seg(D,I)( case "para": switch (obj.is_a) { case "toc": - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0].to!string; break; default: @@ -1605,7 +1647,7 @@ void seg(D,I)( case "para": switch (obj.is_a) { case "para": - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0].to!string; doc_html_endnotes[segment_filename] ~= t[1]; break; @@ -1619,24 +1661,24 @@ void seg(D,I)( case "block": switch (obj.is_a) { case "quote": - auto t = xhtml_format.quote_seg(obj, _txt, suffix); + auto t = xhtml_format.quote_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0].to!string; doc_html_endnotes[segment_filename] ~= t[1]; break; case "group": - auto t = xhtml_format.group_seg(obj, _txt, suffix); + auto t = xhtml_format.group_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0].to!string; doc_html_endnotes[segment_filename] ~= t[1]; break; case "block": - auto t = xhtml_format.block_seg(obj, _txt, suffix); + auto t = xhtml_format.block_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0].to!string; doc_html_endnotes[segment_filename] ~= t[1]; break; case "poem": break; case "verse": - auto t = xhtml_format.verse_seg(obj, _txt, suffix); + auto t = xhtml_format.verse_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0].to!string; doc_html_endnotes[segment_filename] ~= t[1]; break; @@ -1667,26 +1709,26 @@ void seg(D,I)( case "para": switch (obj.is_a) { case "endnote": assert(part == "endnotes"); - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0]; break; case "glossary": assert(part == "glossary"); - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0]; doc_html_endnotes[segment_filename] ~= t[1]; break; case "bibliography": assert(part == "bibliography"); - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0]; doc_html_endnotes[segment_filename] ~= t[1]; break; case "bookindex": assert(part == "bookindex_seg"); - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0]; doc_html_endnotes[segment_filename] ~= t[1]; break; case "blurb": assert(part == "blurb"); - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg"); doc_html[segment_filename] ~= t[0]; doc_html_endnotes[segment_filename] ~= t[1]; break; @@ -1782,6 +1824,35 @@ void css(M)( } #+END_SRC +** images :images: + +#+name: copy_html_images +#+BEGIN_SRC d +void images_cp(M)( + auto return ref M doc_matters, +) { + { /+ (copy html images) +/ + + auto pth_html = SiSUpathsHTML!()(doc_matters.output_path, doc_matters.src.language); + if (!exists(pth_html.image)) { + pth_html.image.mkdirRecurse; + } + foreach (image; doc_matters.srcs.image_list) { + auto fn_src_in = doc_matters.src_path_info.src_image_root_with_path ~ "/" ~ image; + auto fn_src_out = pth_html.image ~ "/" ~ image; + debug(images_html) { + writeln(fn_src_in, " -> ", fn_src_out); + } + if (exists(fn_src_in)) { + fn_src_in.copy(fn_src_out); + } else { + writeln("WARNING image not found: ", fn_src_in); + } + } + } +} +#+END_SRC + * _epub_ [#B] :module:sdp:output_epub3: |-----------------------+--------------------------+---------------------------+----------------------------------| @@ -2228,7 +2299,7 @@ void outputEPub3(D,I)( case "para": switch (obj.is_a) { case "toc": - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0]; doc_epub3_endnotes[segment_filename] ~= t[1]; break; @@ -2251,7 +2322,7 @@ void outputEPub3(D,I)( case "para": switch (obj.is_a) { case "para": - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0]; doc_epub3_endnotes[segment_filename] ~= t[1]; break; @@ -2265,24 +2336,24 @@ void outputEPub3(D,I)( case "block": switch (obj.is_a) { case "quote": - auto t = xhtml_format.quote_seg(obj, _txt, suffix); + auto t = xhtml_format.quote_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0].to!string; doc_epub3_endnotes[segment_filename] ~= t[1]; break; case "group": - auto t = xhtml_format.group_seg(obj, _txt, suffix); + auto t = xhtml_format.group_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0].to!string; doc_epub3_endnotes[segment_filename] ~= t[1]; break; case "block": - auto t = xhtml_format.block_seg(obj, _txt, suffix); + auto t = xhtml_format.block_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0].to!string; doc_epub3_endnotes[segment_filename] ~= t[1]; break; case "poem": break; case "verse": - auto t = xhtml_format.verse_seg(obj, _txt, suffix); + auto t = xhtml_format.verse_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0].to!string; doc_epub3_endnotes[segment_filename] ~= t[1]; break; @@ -2313,26 +2384,26 @@ void outputEPub3(D,I)( case "para": switch (obj.is_a) { case "endnote": assert(part == "endnotes"); - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0]; break; case "glossary": assert(part == "glossary"); - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0]; doc_epub3_endnotes[segment_filename] ~= t[1]; break; case "bibliography": assert(part == "bibliography"); - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0]; doc_epub3_endnotes[segment_filename] ~= t[1]; break; case "bookindex": assert(part == "bookindex_seg"); - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0]; doc_epub3_endnotes[segment_filename] ~= t[1]; break; case "blurb": assert(part == "blurb"); - auto t = xhtml_format.para_seg(obj, _txt, suffix); + auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub"); doc_epub3[segment_filename] ~= t[0]; doc_epub3_endnotes[segment_filename] ~= t[1]; break; @@ -2582,13 +2653,13 @@ void epub3_write_output_files(M,D,E,Mt,Mic,Otnx,Otn,Oc)( debug(epub_output) { debug(epub_images) { writeln( - doc_matters.src_path_info.image_root, image, " -> ", + doc_matters.src_path_info.src_image_root_with_path, "/", image, " -> ", pth_epub3.dbg_doc_oebps_image(doc_matters.src.filename), "/", image ); } } - auto fn_src = doc_matters.src_path_info.image_root ~ image; - auto fn_out = pth_epub3.doc_oebps_image(doc_matters.src.filename).to!string ~ "/" ~ image; + auto fn_src = doc_matters.src_path_info.src_image_root_with_path ~ "/" ~ image; + auto fn_out = pth_epub3.doc_oebps_image(doc_matters.src.filename.to!string) ~ "/" ~ image; if (exists(fn_src)) { { auto zip_arc_member_file = new ArchiveMember(); diff --git a/src/sdp/meta/defaults.d b/src/sdp/meta/defaults.d index f0137cb..2663c15 100644 --- a/src/sdp/meta/defaults.d +++ b/src/sdp/meta/defaults.d @@ -142,6 +142,7 @@ template InternalMarkup() { auto tc_c = "┚"; auto tc_p = "┆"; auto mono = "■"; + auto img = "☼"; static string indent_by_spaces_provided(int indent, string _indent_spaces ="░░") { _indent_spaces = replicate(_indent_spaces, indent); return _indent_spaces; diff --git a/src/sdp/meta/metadoc_from_src.d b/src/sdp/meta/metadoc_from_src.d index f4701dc..fb95a98 100644 --- a/src/sdp/meta/metadoc_from_src.d +++ b/src/sdp/meta/metadoc_from_src.d @@ -1995,7 +1995,7 @@ template SiSUdocAbstraction() { if (conf_make_meta.make.substitute) { foreach(substitution_pair; conf_make_meta.make.substitute) { line = line.replaceAll( - regex(substitution_pair[Substitute.match]), + regex("\b" ~ substitution_pair[Substitute.match]), substitution_pair[Substitute.markup] ); } @@ -2012,19 +2012,19 @@ template SiSUdocAbstraction() { enum Substitute { match, markup, } if ( conf_make_meta.make.bold) { line = line.replaceAll( - regex(conf_make_meta.make.bold[Substitute.match]), + regex("\b" ~ conf_make_meta.make.bold[Substitute.match]), conf_make_meta.make.bold[Substitute.markup] ); } if (conf_make_meta.make.emphasis) { line = line.replaceAll( - regex(conf_make_meta.make.emphasis[Substitute.match]), + regex("\b" ~ conf_make_meta.make.emphasis[Substitute.match]), conf_make_meta.make.emphasis[Substitute.markup] ); } if (conf_make_meta.make.italics) { line = line.replaceAll( - regex(conf_make_meta.make.italics[Substitute.match]), + regex("\b" ~ conf_make_meta.make.italics[Substitute.match]), conf_make_meta.make.italics[Substitute.markup] ); } @@ -3867,6 +3867,43 @@ template SiSUdocAbstraction() { obj_txt_in = obj_txt_in.replaceAll(rgx.inline_mono_box, ("#{$1}#")); return obj_txt_in; } + static auto images(Ot)(Ot obj_txt_in) { + debug(asserts) { + static assert(is(typeof(obj_txt_in) == string)); + } + static auto mng = InlineMarkup(); + obj_txt_in = obj_txt_in.replaceAll(rgx.inline_mono, (mng.mono ~ "{$1}" ~ mng.mono)); // figure + /+ url matched +/ + obj_txt_in = obj_txt_in.replaceAll(rgx.inline_notes_al_special, ""); // TODO reinstate when special footnotes are implemented + if (obj_txt_in.match(rgx.smid_image_generic)) { /+ images with and without links +/ + debug(images) { + writeln("Image: ", obj_txt_in); + } + if (obj_txt_in.match(rgx.smid_image_with_dimensions)) { + obj_txt_in = (obj_txt_in).replaceAll( + rgx.smid_image_with_dimensions, + ("$1" + ~ mkup.img ~ "$2,w$3h$4 " + ~ "$5") // ("$1{ $2 }$2$3") + ); + debug(images) { + writeln("IMAGE with size: ", obj_txt_in); // decide on representation + } + } else if (obj_txt_in.match(rgx.smid_image)) { + obj_txt_in = (obj_txt_in).replaceAll( + rgx.smid_image, + ("$1" + ~ mkup.img ~ "$2,w0h0 " + ~ "$3") // ("$1{ $2 }$2$3") + ); + debug(images) { + writeln("IMAGE: ", obj_txt_in); // decide on representation + } + } + } + obj_txt_in = obj_txt_in.replaceAll(rgx.inline_mono_box, ("#{$1}#")); // figure + return obj_txt_in; + } auto footnotes_endnotes_markup_and_number_or_stars(Ot)(Ot obj_txt_in, bool reset_note_numbers) { debug(asserts) { static assert(is(typeof(obj_txt_in) == string)); @@ -3954,6 +3991,10 @@ template SiSUdocAbstraction() { rgx.inline_notes_curly_sp_plus, (mkup.en_a_o ~ "+" ~ " $1" ~ mkup.en_a_c) ); + /+ image matched +/ + if (obj_txt_in.match(rgx.smid_image_generic)) { + obj_txt_in = images(obj_txt_in); + } /+ url matched +/ if (obj_txt_in.match(rgx.smid_inline_url)) { urls = true; diff --git a/src/sdp/meta/rgx.d b/src/sdp/meta/rgx.d index d15f90a..8b6f4d2 100644 --- a/src/sdp/meta/rgx.d +++ b/src/sdp/meta/rgx.d @@ -150,6 +150,9 @@ static template SiSUrgxInit() { static smid_inline_link_endnote_url_helper_punctuated = ctRegex!(`\{~\^\s+(?P.+?)\}(?P(?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)\S+?)(?P[.,;:?!]?(?:[ ]|$))`, "mg"); static smid_inline_link_endnote_url_helper = ctRegex!(`\{~\^\s+(?P.+?)\}(?P(?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)\S+)`, "mg"); static image = ctRegex!(`([a-zA-Z0-9._-]+?\.(?:png|gif|jpg))`, "mg"); + 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");
     /+ inline markup book index +/
     static book_index                                     = ctRegex!(`^=\{\s*(.+?)\}$`, "m");
     static book_index_open                                = ctRegex!(`^=\{\s*([^}]+?)$`);
@@ -244,6 +247,7 @@ static template SiSUrgxInit() {
     static inline_text_and_note_al                        = ctRegex!(`(?P.+?)【(?:[*+ ]*)(?P.+?)】`, "mg");
     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_link                                    = ctRegex!(`┥(?P.+?)┝┤(?P.+?)├`, "mg");
     static inline_link_clean                              = ctRegex!(`┤(?:.+?)├|[┥┝]`, "mg");
     static inline_a_url                                   = ctRegex!(`(┤)(\S+?)(├)`, "mg");
diff --git a/src/sdp/output/defaults.d b/src/sdp/output/defaults.d
index 418a334..0d215c7 100644
--- a/src/sdp/output/defaults.d
+++ b/src/sdp/output/defaults.d
@@ -24,6 +24,7 @@ template InternalMarkup() {
     auto tc_c = "┚";
     auto tc_p = "┆";
     auto mono = "■";
+    auto img = "☼";
     static string indent_by_spaces_provided(int indent, string _indent_spaces ="░░") {
       _indent_spaces = replicate(_indent_spaces, indent);
       return _indent_spaces;
diff --git a/src/sdp/output/epub3.d b/src/sdp/output/epub3.d
index 321ef9b..eb55593 100644
--- a/src/sdp/output/epub3.d
+++ b/src/sdp/output/epub3.d
@@ -375,7 +375,7 @@ template outputEPub3() {
             case "para":
               switch (obj.is_a) {
               case "toc":
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0];
                 doc_epub3_endnotes[segment_filename] ~= t[1];
                 break;
@@ -398,7 +398,7 @@ template outputEPub3() {
             case "para":
               switch (obj.is_a) {
               case "para":
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0];
                 doc_epub3_endnotes[segment_filename] ~= t[1];
                 break;
@@ -412,24 +412,24 @@ template outputEPub3() {
             case "block":
               switch (obj.is_a) {
               case "quote":
-                auto t = xhtml_format.quote_seg(obj, _txt, suffix);
+                auto t = xhtml_format.quote_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0].to!string;
                 doc_epub3_endnotes[segment_filename] ~= t[1];
                 break;
               case "group":
-                auto t = xhtml_format.group_seg(obj, _txt, suffix);
+                auto t = xhtml_format.group_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0].to!string;
                 doc_epub3_endnotes[segment_filename] ~= t[1];
                 break;
               case "block":
-                auto t = xhtml_format.block_seg(obj, _txt, suffix);
+                auto t = xhtml_format.block_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0].to!string;
                 doc_epub3_endnotes[segment_filename] ~= t[1];
                 break;
               case "poem":
                 break;
               case "verse":
-                auto t = xhtml_format.verse_seg(obj, _txt, suffix);
+                auto t = xhtml_format.verse_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0].to!string;
                 doc_epub3_endnotes[segment_filename] ~= t[1];
                 break;
@@ -460,26 +460,26 @@ template outputEPub3() {
             case "para":
               switch (obj.is_a) {
               case "endnote":             assert(part == "endnotes");
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0];
                 break;
               case "glossary":            assert(part == "glossary");
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0];
                 doc_epub3_endnotes[segment_filename] ~= t[1];
                 break;
               case "bibliography":        assert(part == "bibliography");
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0];
                 doc_epub3_endnotes[segment_filename] ~= t[1];
                 break;
               case "bookindex":           assert(part == "bookindex_seg");
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0];
                 doc_epub3_endnotes[segment_filename] ~= t[1];
                 break;
               case "blurb":               assert(part == "blurb");
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "epub");
                 doc_epub3[segment_filename] ~= t[0];
                 doc_epub3_endnotes[segment_filename] ~= t[1];
                 break;
@@ -723,13 +723,13 @@ template outputEPub3() {
           debug(epub_output) {
             debug(epub_images) {
               writeln(
-                doc_matters.src_path_info.image_root, image, " -> ",
+                doc_matters.src_path_info.src_image_root_with_path, "/", image, " -> ",
                 pth_epub3.dbg_doc_oebps_image(doc_matters.src.filename), "/", image
               );
             }
           }
-          auto fn_src = doc_matters.src_path_info.image_root ~ image;
-          auto fn_out =  pth_epub3.doc_oebps_image(doc_matters.src.filename).to!string ~ "/" ~ image;
+          auto fn_src = doc_matters.src_path_info.src_image_root_with_path ~ "/" ~ image;
+          auto fn_out =  pth_epub3.doc_oebps_image(doc_matters.src.filename.to!string) ~ "/" ~ image;
           if (exists(fn_src)) {
             {
               auto zip_arc_member_file = new ArchiveMember();
diff --git a/src/sdp/output/html.d b/src/sdp/output/html.d
index 35e3027..3db534b 100644
--- a/src/sdp/output/html.d
+++ b/src/sdp/output/html.d
@@ -225,7 +225,7 @@ template outputHTML() {
               top_level_headings[3] = "";
               goto default;
             default:
-              auto t = xhtml_format.heading_seg(obj, _txt, suffix);
+              auto t = xhtml_format.heading_seg(obj, _txt, suffix, "seg");
               top_level_headings[obj.heading_lev_markup] = t[0];
               break;
             }
@@ -240,13 +240,13 @@ template outputHTML() {
               // writeln(top_level_heading);
               doc_html[segment_filename] ~= top_level_heading;
             }
-            auto t = xhtml_format.heading_seg(obj, _txt, suffix);
+            auto t = xhtml_format.heading_seg(obj, _txt, suffix, "seg");
             doc_html[segment_filename] ~= t[0].to!string;
             doc_html[segment_filename] ~= xhtml_format.lev4_heading_subtoc(obj);
             doc_html_endnotes[segment_filename] ~= t[1];
             break;
           case 5: .. case 7:
-            auto t = xhtml_format.heading_seg(obj, _txt, suffix);
+            auto t = xhtml_format.heading_seg(obj, _txt, suffix, "seg");
             doc_html[segment_filename] ~= t[0].to!string;
             doc_html_endnotes[segment_filename] ~= t[1];
             break;
@@ -270,7 +270,7 @@ template outputHTML() {
             case "para":
               switch (obj.is_a) {
               case "toc":
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0].to!string;
                 break;
               default:
@@ -292,7 +292,7 @@ template outputHTML() {
             case "para":
               switch (obj.is_a) {
               case "para":
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0].to!string;
                 doc_html_endnotes[segment_filename] ~= t[1];
                 break;
@@ -306,24 +306,24 @@ template outputHTML() {
             case "block":
               switch (obj.is_a) {
               case "quote":
-                auto t = xhtml_format.quote_seg(obj, _txt, suffix);
+                auto t = xhtml_format.quote_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0].to!string;
                 doc_html_endnotes[segment_filename] ~= t[1];
                 break;
               case "group":
-                auto t = xhtml_format.group_seg(obj, _txt, suffix);
+                auto t = xhtml_format.group_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0].to!string;
                 doc_html_endnotes[segment_filename] ~= t[1];
                 break;
               case "block":
-                auto t = xhtml_format.block_seg(obj, _txt, suffix);
+                auto t = xhtml_format.block_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0].to!string;
                 doc_html_endnotes[segment_filename] ~= t[1];
                 break;
               case "poem":
                 break;
               case "verse":
-                auto t = xhtml_format.verse_seg(obj, _txt, suffix);
+                auto t = xhtml_format.verse_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0].to!string;
                 doc_html_endnotes[segment_filename] ~= t[1];
                 break;
@@ -354,26 +354,26 @@ template outputHTML() {
             case "para":
               switch (obj.is_a) {
               case "endnote":             assert(part == "endnotes");
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0];
                 break;
               case "glossary":            assert(part == "glossary");
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0];
                 doc_html_endnotes[segment_filename] ~= t[1];
                 break;
               case "bibliography":        assert(part == "bibliography");
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0];
                 doc_html_endnotes[segment_filename] ~= t[1];
                 break;
               case "bookindex":           assert(part == "bookindex_seg");
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0];
                 doc_html_endnotes[segment_filename] ~= t[1];
                 break;
               case "blurb":               assert(part == "blurb");
-                auto t = xhtml_format.para_seg(obj, _txt, suffix);
+                auto t = xhtml_format.para_seg(obj, _txt, suffix, "seg");
                 doc_html[segment_filename] ~= t[0];
                 doc_html_endnotes[segment_filename] ~= t[1];
                 break;
@@ -455,4 +455,27 @@ template outputHTML() {
       // Handle error
     }
   }
+  void images_cp(M)(
+    auto return ref M          doc_matters,
+  ) {
+    { /+ (copy html images) +/
+  
+      auto pth_html = SiSUpathsHTML!()(doc_matters.output_path, doc_matters.src.language);
+      if (!exists(pth_html.image)) {
+        pth_html.image.mkdirRecurse;
+      }
+      foreach (image; doc_matters.srcs.image_list) {
+        auto fn_src_in = doc_matters.src_path_info.src_image_root_with_path ~ "/" ~ image;
+        auto fn_src_out = pth_html.image ~ "/" ~ image;
+        debug(images_html) {
+          writeln(fn_src_in, " -> ", fn_src_out);
+        }
+        if (exists(fn_src_in)) {
+          fn_src_in.copy(fn_src_out);
+        } else {
+          writeln("WARNING image not found: ", fn_src_in);
+        }
+      }
+    }
+  }
 }
diff --git a/src/sdp/output/hub.d b/src/sdp/output/hub.d
index d395269..b86d30d 100644
--- a/src/sdp/output/hub.d
+++ b/src/sdp/output/hub.d
@@ -93,6 +93,7 @@ template outputHub() {
         writeln("html seg done");
       }
       outputHTML!().css(doc_matters);
+      outputHTML!().images_cp(doc_matters);
     } else if (doc_matters.opt.action.html_seg) {
       if ((doc_matters.opt.action.verbose)) {
         writeln("html seg processing... ");
@@ -103,6 +104,7 @@ template outputHub() {
         writeln("html seg done");
       }
       outputHTML!().css(doc_matters);
+      outputHTML!().images_cp(doc_matters);
     } else if (doc_matters.opt.action.html_scroll) {
       if ((doc_matters.opt.action.verbose)) {
         writeln("html scroll processing... ");
@@ -113,6 +115,7 @@ template outputHub() {
         writeln("html scroll done");
       }
       outputHTML!().css(doc_matters);
+      outputHTML!().images_cp(doc_matters);
     }
     if (doc_matters.opt.action.epub) {
       if ((doc_matters.opt.action.verbose)) {
diff --git a/src/sdp/output/paths_source.d b/src/sdp/output/paths_source.d
index ac5e703..9f377bc 100644
--- a/src/sdp/output/paths_source.d
+++ b/src/sdp/output/paths_source.d
@@ -30,7 +30,7 @@ template PodManifest() {
           _manifest_path = _pth;
         } else if (_pth.match(rgx.src_pth_contents)
         && exists(_pth)!=0 && _pth.isFile) {
-          _manifest_path = dirName(_pth);
+          _manifest_path = _pth.dirName;
         } else if (_pth.match(rgx.src_pth_pod_sst_or_ssm)
         && exists(_pth)!=0 && (_pth.isFile)) {
           if (auto m = _pth.match(rgx.src_pth_pod_sst_or_ssm)) {
@@ -480,7 +480,7 @@ template SiSUpathsSRC() {
   static auto rgx = Rgx();
   auto SiSUpathsSRC(D,Fn)(
     D   _pwd,
-    Fn  _fn_src_and_relative_path,
+    Fn  _fn_src_and_path,
   ) {
     struct SisuSrcPaths {
       auto pwd() {
@@ -489,7 +489,7 @@ template SiSUpathsSRC() {
       auto language() {
         // use command line info as well?
         string _k;
-        if (auto m = _fn_src_and_relative_path.match(rgx.language_code_and_filename)) {
+        if (auto m = _fn_src_and_path.match(rgx.language_code_and_filename)) {
           _k = m.captures[1];
         } else { /+ unknown until doc_meta read, (could provide & use command line info?) +/
           _k = "xx"; // original default was "en" but is not known
@@ -514,11 +514,29 @@ template SiSUpathsSRC() {
       auto doc_src_fn_with_path_for_text_root_and_lng() {
         return asNormalizedPath(text_root.chainPath(language)).array;
       }
-      auto doc_src_with_relative_path() {
-        return asNormalizedPath(pwd.chainPath(_fn_src_and_relative_path)).array;
-      }
       auto doc_src_fn() {
-        return asNormalizedPath(_fn_src_and_relative_path.baseName).array;
+        return asNormalizedPath(_fn_src_and_path.baseName).array;
+      }
+      auto doc_src_with_path() {
+        return asNormalizedPath(pwd.chainPath(_fn_src_and_path)).array;
+      }
+      auto src_image_root_with_path() {
+        string[] _possible_img_pth = [
+          asNormalizedPath(pwd.chainPath((_fn_src_and_path).dirName ~ "/image")).array,
+          asNormalizedPath(pwd.chainPath((_fn_src_and_path).dirName ~ "/../image")).array,
+          asNormalizedPath(pwd.chainPath((_fn_src_and_path).dirName ~ "/../../image")).array,
+        ];
+        string _img_pth_found = "";
+        foreach(_img_pth; _possible_img_pth) {
+          if (exists(_img_pth)) {
+            _img_pth_found = _img_pth;
+            break;
+          }
+        }
+        if (_img_pth_found.empty) {
+          writeln("WARNING not image path found, searched: ", _possible_img_pth);
+        }
+        return _img_pth_found;
       }
     }
     return SisuSrcPaths();
diff --git a/src/sdp/output/rgx.d b/src/sdp/output/rgx.d
index 0227902..60f15cf 100644
--- a/src/sdp/output/rgx.d
+++ b/src/sdp/output/rgx.d
@@ -61,6 +61,7 @@ static template SiSUoutputRgxInit() {
     static inline_text_and_note_al                        = ctRegex!(`(?P.+?)【(?:[*+ ]*)(?P.+?)】`, "mg");
     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_link                                    = ctRegex!(`┥(?P.+?)┝┤(?P.+?)├`, "mg");
     static inline_link_clean                              = ctRegex!(`┤(?:.+?)├|[┥┝]`, "mg");
     static inline_a_url                                   = ctRegex!(`(┤)(\S+?)(├)`, "mg");
diff --git a/src/sdp/output/source_sisupod.d b/src/sdp/output/source_sisupod.d
index 50b37b0..a92d087 100644
--- a/src/sdp/output/source_sisupod.d
+++ b/src/sdp/output/source_sisupod.d
@@ -65,10 +65,7 @@ template SiSUpod() {
               pths_sisupod.image_root(doc_matters.src.filename).zpod, "/", image
             );
           }
-          auto fn_src_in = ((doc_matters.src.is_pod)
-            ? doc_matters.src.image_dir_path
-            : pth_sisudoc_src.image_root).to!string
-            ~ "/" ~ image;
+          auto fn_src_in = doc_matters.src_path_info.src_image_root_with_path ~ "/" ~ image;
           auto fn_src_out_sisupod_zip_base
             = pths_sisupod.image_root(doc_matters.src.filename).zpod.to!string
             ~ "/" ~ image;
diff --git a/src/sdp/output/xmls.d b/src/sdp/output/xmls.d
index 7dd6a60..1621732 100644
--- a/src/sdp/output/xmls.d
+++ b/src/sdp/output/xmls.d
@@ -311,15 +311,39 @@ template outputXHTMLs() {
     ¶");
       return o;
     }
+    auto inline_images(O)(
+      auto return ref const O obj,
+      string                  _txt,
+      string                  _suffix    = ".html",
+      string                  _xml_type = "seg",
+    ) {
+      string _img_pth;
+      if (_xml_type == "epub") {
+        _img_pth = "image/";
+      } else if (_xml_type == "scroll") {
+        _img_pth = "../../image/";
+      } else if (_xml_type == "seg") {
+        _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)
+            rgx.inline_image,
+            ("$1 $6"));
+      }
+      return _txt;
+    }
     auto inline_links(O)(
       auto return ref const O obj,
       string                  _txt,
       string                  _suffix    = ".html",
-      string                  seg_scroll = "seg",
+      string                  _xml_type = "seg",
     ) {
       if (obj.inline_links) {
         if ((_txt.match(rgx.mark_internal_site_lnk))
-        && (seg_scroll == "scroll")) { // conditions reversed to avoid: gdc compiled program run segfault
+        && (_xml_type == "scroll")) { // conditions reversed to avoid: gdc compiled program run segfault
           _txt = (_txt).replaceAll(
             rgx.inline_seg_link,
             "$1");
@@ -424,6 +448,7 @@ template outputXHTMLs() {
       string                   _txt,
       string                   _suffix = ".html",
     ) {
+      _txt = inline_images(obj, _txt, _suffix, "scroll");
       _txt = inline_links(obj, _txt, _suffix, "scroll");
       _txt = inline_notes_scroll(obj, _txt);
       return _txt;
@@ -432,8 +457,10 @@ template outputXHTMLs() {
       auto return ref const O  obj,
       string                   _txt,
       string                   _suffix = ".html",
+      string                   _xml_type = "seg",
     ) {
-      _txt = inline_links(obj, _txt, _suffix, "seg");
+      _txt = inline_images(obj, _txt, _suffix, _xml_type);
+      _txt = inline_links(obj, _txt, _suffix, _xml_type);
       auto t = inline_notes_seg(obj, _txt);
       return t;
     }
@@ -543,11 +570,11 @@ template outputXHTMLs() {
     auto heading(O)(
       auto return ref const O    obj,
       string                     _txt,
-      string                     _type="html",
+      string                     _xml_type = "html",
     ) {
       auto tags = _xhtml_anchor_tags(obj.anchor_tags);
       string _horizontal_rule = "
"; - if ((_type != "html") + if ((_xml_type != "html") || (obj.heading_lev_markup == 0 || obj.heading_lev_markup > 4)) { _horizontal_rule = ""; } @@ -603,12 +630,12 @@ template outputXHTMLs() { auto return ref const O obj, string _txt, string _suffix = ".html", - string _type = "html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0]; string[] _endnotes = t[1]; - string o = heading(obj, _txt, _type); + string o = heading(obj, _txt, _xml_type); auto u = tuple( o, _endnotes, @@ -668,8 +695,9 @@ template outputXHTMLs() { auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0].to!string; string[] _endnotes = t[1]; string o = para(obj, _txt); @@ -724,8 +752,9 @@ template outputXHTMLs() { auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0].to!string; string[] _endnotes = t[1]; string o = quote(obj, _txt); @@ -770,6 +799,7 @@ template outputXHTMLs() { auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { auto tags = _xhtml_anchor_tags(obj.anchor_tags); _txt = inline_markup_scroll(obj, _txt, _suffix); @@ -780,8 +810,9 @@ template outputXHTMLs() { auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0].to!string; string[] _endnotes = t[1]; string o = group(obj, _txt); @@ -822,6 +853,7 @@ template outputXHTMLs() { auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { auto tags = _xhtml_anchor_tags(obj.anchor_tags); _txt = inline_markup_scroll(obj, _txt, _suffix); @@ -832,8 +864,9 @@ template outputXHTMLs() { auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0].to!string; string[] _endnotes = t[1]; string o = block(obj, _txt); @@ -874,6 +907,7 @@ template outputXHTMLs() { auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { auto tags = _xhtml_anchor_tags(obj.anchor_tags); _txt = inline_markup_scroll(obj, _txt, _suffix); @@ -884,8 +918,9 @@ template outputXHTMLs() { auto return ref const O obj, string _txt, string _suffix = ".html", + string _xml_type = "html", ) { - auto t = inline_markup_seg(obj, _txt, _suffix); + auto t = inline_markup_seg(obj, _txt, _suffix, _xml_type); _txt = t[0].to!string; string[] _endnotes = t[1]; string o = verse(obj, _txt); -- cgit v1.2.3