diff options
Diffstat (limited to 'src/sdp')
| -rw-r--r-- | src/sdp/ao_defaults.d | 3 | ||||
| -rw-r--r-- | src/sdp/ao_doc_debugs.d | 10 | ||||
| -rw-r--r-- | src/sdp/create_zip_file.d | 16 | ||||
| -rw-r--r-- | src/sdp/defaults.d | 180 | ||||
| -rw-r--r-- | src/sdp/output_epub.d | 449 | ||||
| -rw-r--r-- | src/sdp/output_epub3.d | 717 | ||||
| -rw-r--r-- | src/sdp/output_html.d | 12 | ||||
| -rw-r--r-- | src/sdp/output_hub.d | 17 | ||||
| -rw-r--r-- | src/sdp/output_xhtmls.d | 120 | ||||
| -rw-r--r-- | src/sdp/source_sisupod.d | 201 | 
10 files changed, 1102 insertions, 623 deletions
| diff --git a/src/sdp/ao_defaults.d b/src/sdp/ao_defaults.d index 846a7d2..21352e2 100644 --- a/src/sdp/ao_defaults.d +++ b/src/sdp/ao_defaults.d @@ -394,8 +394,7 @@ template InternalMarkup() {      auto tc_o = "┏"; //"『"; // "┏" ┓      auto tc_c = "┚"; // "』"; // "┚"  table row mark #Mx[:tc_c]="』\n"      auto tc_p = "┆";   // table col/misc mark -    string indent_by_spaces_provided(int indent) { -      auto _indent_spaces ="░░";   // auto nbsp = "░"; +    string indent_by_spaces_provided(int indent, string _indent_spaces ="░░") {        _indent_spaces = replicate(_indent_spaces, indent);        return _indent_spaces;      } diff --git a/src/sdp/ao_doc_debugs.d b/src/sdp/ao_doc_debugs.d index 989a826..05e3739 100644 --- a/src/sdp/ao_doc_debugs.d +++ b/src/sdp/ao_doc_debugs.d @@ -113,7 +113,7 @@ template SiSUdebugs() {          }        }      } -    debug(dom) { +    debug(toc_nav_dom) {        enum DomTags { none, open, close, close_and_open, open_still, }        foreach (sect; doc_matters.keys_seq_seg) {          foreach (obj; contents[sect]) { @@ -125,10 +125,10 @@ template SiSUdebugs() {                  break;                case DomTags.close_and_open :                  writeln(markup.indent_by_spaces_provided(k), "</", k, ">"); -                writeln(markup.indent_by_spaces_provided(k), "<", k, ">", obj.text); +                writeln(markup.indent_by_spaces_provided(k), "<", k, ">", obj.text, " file: ", obj.segment_anchor_tag, ".xhtml#", obj.ocn);                  break;                case DomTags.open : -                writeln(markup.indent_by_spaces_provided(k), "<", k, ">", obj.text); +                writeln(markup.indent_by_spaces_provided(k), "<", k, ">", obj.text, " file: ", obj.segment_anchor_tag, ".xhtml#", obj.ocn);                  break;                default :                  break; @@ -148,10 +148,10 @@ template SiSUdebugs() {                  break;                case DomTags.close_and_open :                  writeln(markup.indent_by_spaces_provided(k), "</", k, ">"); -                writeln(markup.indent_by_spaces_provided(k), "<", k, ">", obj.text); +                writeln(markup.indent_by_spaces_provided(k), "<", k, ">", obj.text, " file: ", obj.segment_anchor_tag, ".xhtml#", obj.ocn);                  break;                case DomTags.open : -                writeln(markup.indent_by_spaces_provided(k), "<", k, ">", obj.text); +                writeln(markup.indent_by_spaces_provided(k), "<", k, ">", obj.text, " file: ", obj.segment_anchor_tag, ".xhtml#", obj.ocn);                  break;                default :                  break; diff --git a/src/sdp/create_zip_file.d b/src/sdp/create_zip_file.d new file mode 100644 index 0000000..6ea55f4 --- /dev/null +++ b/src/sdp/create_zip_file.d @@ -0,0 +1,16 @@ +template createZipFile() { +  import std.file; +  import std.outbuffer; +  import std.string; +  import std.zip; +  void createZipFile( +    string zip_file_name, +    void[] compressed_zip_data, +  ) { +    try { +      write(zip_file_name, compressed_zip_data); +    } catch (ZipException ex) { +      // Handle Errors +    } +  } +} diff --git a/src/sdp/defaults.d b/src/sdp/defaults.d index a6520a3..537b4ba 100644 --- a/src/sdp/defaults.d +++ b/src/sdp/defaults.d @@ -3,103 +3,188 @@  +/  template SiSUpaths() { -  string _base_filename(string fn_src) { -    string _fn_base = ""; -    if (extension(fn_src) == ".sst") { -      _fn_base = baseName(fn_src, ".sst"); -    } else if (extension(fn_src) == ".ssm") { -      _fn_base = baseName(fn_src, ".ssm"); -    } -    return _fn_base; -  }    struct DirPaths {      string base_filename(string fn_src) { -      return _base_filename(fn_src); +      return baseName(stripExtension(fn_src));      }    }    struct SiSUpodPaths {      string base_filename(string fn_src) { -      return _base_filename(fn_src); +      return baseName(stripExtension(fn_src)); +    } +    string sisupod_filename(string fn_src) { +      return "sisupod".chainPath(base_filename(fn_src) ~ ".zip").array; +    } +    string base(string fn_src) { +      return "sisupod".chainPath(base_filename(fn_src)).array; +    } +  } +  struct SiSUpodPathsZipped { +    auto spod_pths = SiSUpodPaths(); +    string base_filename(string fn_src) { +      return spod_pths.base_filename(fn_src); +    } +    string sisupod_filename(string fn_src) { +      return spod_pths.sisupod_filename(fn_src); +    } +    string base(string fn_src) { +      return spod_pths.base(fn_src); +    } +    auto doc_root(string fn_src) { +      return "doc"; +    } +    auto doc(string fn_src) { +      return doc_root(fn_src); +    } +    auto doc_lng(string fn_src, string lng) { +      return doc_root(fn_src).chainPath(lng).array; +    } +    auto conf(string fn_src) { +      return doc_root(fn_src).chainPath("_sisu").array; +    } +    auto image(string fn_src) { +      return conf(fn_src).chainPath("image").array; +    } +    auto css(string fn_src) { +      return conf(fn_src).chainPath("css").array; +    } +    auto fn_doc(string fn_src, string lng) { +      return (doc_lng(fn_src, lng)).chainPath(baseName(fn_src)).array; +    } +    auto fn_doc_insert(string fn_src, string fn_insert, string lng) { +      return (doc_lng(fn_src, lng)).chainPath(baseName(fn_insert)).array; +    } +  } +  struct SiSUpodPathsFilesystemArchive { +    auto spod_pths = SiSUpodPaths(); +    string base_filename(string fn_src) { +      return spod_pths.base_filename(fn_src); +    } +    string sisupod_filename(string fn_src) { +      return spod_pths.sisupod_filename(fn_src);      }      string base(string fn_src) { -      return chainPath("sisupod", _base_filename(fn_src)).array; +      return spod_pths.base(fn_src); +    } +    auto doc_root(string fn_src) { +      return base(fn_src).chainPath("doc").array;      } -    string doc(string fn_src) { -      return chainPath(base(fn_src), "doc").array; -      // return chainPath(base(fn_src), "text").array; +    auto doc(string fn_src) { +      return doc_root(fn_src);      } -    string doc_lng(string fn_src, string lng) { -      return chainPath(doc(fn_src), lng).array; +    auto doc_lng(string fn_src, string lng) { +      return doc_root(fn_src).chainPath(lng).array;      } -    string conf(string fn_src) { -      return chainPath(doc(fn_src), "_sisu").array; +    auto conf(string fn_src) { +      return doc_root(fn_src).chainPath("_sisu").array;      } -    string image(string fn_src) { -      return chainPath(conf(fn_src), "image").array; +    auto image(string fn_src) { +      return conf(fn_src).chainPath("image").array;      } -    string css(string fn_src) { -      return chainPath(conf(fn_src), "css").array; +    auto css(string fn_src) { +      return conf(fn_src).chainPath("css").array;      } -    string fn_doc(string fn_src, string lng) { -      return chainPath((doc_lng(fn_src, lng)), baseName(fn_src)).array; +    auto fn_doc(string fn_src, string lng) { +      return (doc_lng(fn_src, lng)).chainPath(baseName(fn_src)).array;      } -    string fn_doc_insert(string fn_src, string fn_insert, string lng) { -      return chainPath((doc_lng(fn_src, lng)), baseName(fn_insert)).array; +    auto fn_doc_insert(string fn_src, string fn_insert, string lng) { +      return (doc_lng(fn_src, lng)).chainPath(baseName(fn_insert)).array;      }    }    struct HtmlPaths {      string base_filename(string fn_src) { -      return _base_filename(fn_src); +      return baseName(stripExtension(fn_src));      }      string base() { -      return chainPath("en", "html").array; +      return "en".chainPath("html").array;      }      string seg(string fn_src) { -      return chainPath(base, _base_filename(fn_src)).array; +      return base.chainPath(base_filename(fn_src)).array;      }      string fn_scroll(string fn_src) { -      return chainPath(base, _base_filename(fn_src) ~ ".html").array; +      return base.chainPath(base_filename(fn_src) ~ ".html").array;      }      string fn_seg(string fn_src, string seg_filename) { -      return chainPath(seg(fn_src), seg_filename ~ ".html").array; +      return seg(fn_src).chainPath(seg_filename ~ ".html").array;      }    } -  struct EpubPaths { +  struct Epub3paths { +    string dirtop() { +      return "".chainPath("").array; +    }      string base_filename(string fn_src) { -      return _base_filename(fn_src); +      return baseName(stripExtension(fn_src));      }      string base() { -      return chainPath("en", "epub").array; +      return "en".chainPath("epub3").array; +    } +    string epub_file(string fn_src) { +      return base.chainPath(base_filename(fn_src) ~ ".epub").array;      } -    string doc(string fn_src) { -      return chainPath(base, _base_filename(fn_src)).array; +    string docdir(string fn_src) { +      return base.chainPath(base_filename(fn_src)).array;      }      string doc_meta_inf(string fn_src) { -      return chainPath(doc(fn_src), "META-INF").array; +      return dirtop.chainPath("META-INF").array;      }      string doc_oebps(string fn_src) { -      return chainPath(doc(fn_src), "OEBPS").array; +      return dirtop.chainPath("OEBPS").array;      }      string doc_oebps_css(string fn_src) { -      return chainPath(doc_oebps(fn_src), "css").array; +      return doc_oebps(fn_src).chainPath("css").array;      }      string doc_oebps_image(string fn_src) { -      return chainPath(doc_oebps(fn_src), "image").array; +      return doc_oebps(fn_src).chainPath("image").array;      }      string fn_mimetypes(string fn_src) { -      return chainPath(doc(fn_src), "mimetypes").array; +      return dirtop.chainPath("mimetypes").array;      }      string fn_dmi_container_xml(string fn_src) { -      return chainPath(doc_meta_inf(fn_src), "container.xml").array; +      return doc_meta_inf(fn_src).chainPath("container.xml").array; +    } +    string fn_oebps_toc_nav_xhtml(string fn_src) { +      return doc_oebps(fn_src).chainPath("toc_nav.xhtml").array;      }      string fn_oebps_toc_ncx(string fn_src) { -      return chainPath(doc_oebps(fn_src), "toc.ncx").array; +      return doc_oebps(fn_src).chainPath("toc.ncx").array;      }      string fn_oebps_content_opf(string fn_src) { -      return chainPath(doc_oebps(fn_src), "content.opf").array; +      return doc_oebps(fn_src).chainPath("content.opf").array;      }      string fn_oebps_content_xhtml(string fn_src, string seg_filename) { -      return chainPath(doc_oebps(fn_src), seg_filename ~ ".xhtml").array; +      return doc_oebps(fn_src).chainPath(seg_filename ~ ".xhtml").array; +    } +    debug(epub_output) { +      string dbg_doc_meta_inf(string fn_src) { +        return docdir(fn_src).chainPath("META-INF").array; +      } +      string dbg_doc_oebps(string fn_src) { +        return docdir(fn_src).chainPath("OEBPS").array; +      } +      string dbg_doc_oebps_css(string fn_src) { +        return doc_oebps(fn_src).chainPath("css").array; +      } +      string dbg_doc_oebps_image(string fn_src) { +        return doc_oebps(fn_src).chainPath("image").array; +      } +      string dbg_fn_mimetypes(string fn_src) { +        return docdir(fn_src).chainPath("mimetypes").array; +      } +      string dbg_fn_dmi_container_xml(string fn_src) { +        return doc_meta_inf(fn_src).chainPath("container.xml").array; +      } +      string dbg_fn_oebps_toc_nav_xhtml(string fn_src) { +        return doc_oebps(fn_src).chainPath("toc_nav.xhtml").array; +      } +      string dbg_fn_oebps_toc_ncx(string fn_src) { +        return doc_oebps(fn_src).chainPath("toc.ncx").array; +      } +      string dbg_fn_oebps_content_opf(string fn_src) { +        return doc_oebps(fn_src).chainPath("content.opf").array; +      } +      string dbg_fn_oebps_content_xhtml(string fn_src, string seg_filename) { +        return doc_oebps(fn_src).chainPath(seg_filename ~ ".xhtml").array; +      }      }    }  } @@ -122,8 +207,7 @@ template InternalMarkup() {      auto tc_o = "┏"; //"『"; // "┏" ┓      auto tc_c = "┚"; // "』"; // "┚"  table row mark #Mx[:tc_c]="』\n"      auto tc_p = "┆";   // table col/misc mark -    string indent_by_spaces_provided(int indent) { -      auto _indent_spaces ="░░";   // auto nbsp = "░"; +    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_epub.d b/src/sdp/output_epub.d deleted file mode 100644 index 0cc3a31..0000000 --- a/src/sdp/output_epub.d +++ /dev/null @@ -1,449 +0,0 @@ -template outputEPub() { -  private import -    std.algorithm, -    std.array, -    std.container, -    std.exception, -    std.file, -    std.getopt, -    std.json, -    std.process, -    std.stdio, -    std.path, -    std.range, -    std.regex, -    std.string, -    std.traits, -    std.typecons, -    std.uni, -    std.utf, -    std.conv : to; -  import -    defaults, -    output_rgx, -    output_xhtmls; -  mixin InternalMarkup; -  mixin outputXHTMLs; -  string epub_mimetypes() { -    string o; -    o = format(q"¶application/epub+zip¶"); -    return o; -  } -  string epub_container_xml() { -    string o; -    o = format(q"¶<?xml version='1.0' encoding='utf-8'?> -  <container version="1.0" -    xmlns="urn:oasis:names:tc:opendocument:xmlns:container"> -    <rootfiles> -      <rootfile full-path="OEBPS/content.opf" -        media-type="application/oebps-package+xml" /> -    </rootfiles> -  </container>¶"); -    return o; -  } -  string epub_oebps_content(D,I)(D doc_abstraction, I doc_matters) { -    string uuid = "18275d951861c77f78acd05672c9906924c59f18a2e0ba06dad95959693e9bd8"; // TODO shared elsewhere -    string content = format(q"¶<?xml version='1.0' encoding='utf-8'?> -  <?xml version='1.0' encoding='utf-8'?> -  <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="EPB-UUID"> -    <opf:metadata -      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" -      xmlns:opf="http://www.idpf.org/2007/opf" -      xmlns:dcterms="http://purl.org/dc/terms/" -      xmlns:dc="http://purl.org/dc/elements/1.1/" -      unique-identifier="urn:uuid:%s" version="2.0"> -      <dc:title>%s</dc:title> -      <dc:creator opf:file-as="%s" opf:role="aut">%s</dc:creator> -      <dc:language>en</dc:language> -      <dc:date opf:event="published">%s</dc:date> -      <dc:rights>Copyright: %s</dc:rights> -      <dc:identifier opf:scheme="URI">ox/current/en/epub/sisu_markup.epub</dc:identifier> -      <dc:identifier id="bookid">urn:uuid:%s</dc:identifier> -      <!-- <dc:identifier id="EPB-UUID">urn:uuid:%s</dc:identifier> --> -    </opf:metadata> -    <manifest> -      <!-- NCX --> -      <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" /> -      <!-- CSS Style Sheets --> -      <item id="main-css" href="css/xhtml.css" media-type="text/css" />¶", -      uuid, -      doc_matters.dochead_meta["title"]["full"],                                                               // title -      (doc_matters.dochead_meta["creator"]["author"].empty) ? "" : " by " ~ doc_matters.dochead_meta["creator"]["author"], // author -      (doc_matters.dochead_meta["creator"]["author"].empty) ? "" : " by " ~ doc_matters.dochead_meta["creator"]["author"], // author -      (doc_matters.dochead_meta["date"]["published"].empty) ? "" : " by " ~ doc_matters.dochead_meta["date"]["published"],  // date -      (doc_matters.dochead_meta["rights"]["copyright"].empty) ? "" : " by " ~ doc_matters.dochead_meta["rights"]["copyright"],  // rights -      uuid, -      uuid, -    ); -    foreach (sect; doc_matters.keys_seq_seg) { -      foreach (obj; doc_abstraction[sect]) { -      } -    } -    return content; -  } -  string epub_oebps_toc(D,I)(D doc_abstraction, I doc_matters) { -    int counter = 0; -    string uuid = "18275d951861c77f78acd05672c9906924c59f18a2e0ba06dad95959693e9bd8"; // TODO shared elsewhere -    auto markup = InlineMarkup(); -    enum DomTags { none, open, close, close_and_open, open_still, } -    string toc = format(q"¶<?xml version='1.0' encoding='utf-8'?> -  <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1"> -    <head> -      <!-- four required metadata items (for all NCX documents, -        (including the relaxed constraints of OPS 2.0) --> -      <title>%s%s</title> -      <link href="css/xhtml.css" rel="stylesheet" type="text/css" id="main-css" /> -      <meta name="dtb:uid" content="urn:uuid:%s" /> -      <!-- <meta name="epub-creator" content="SiSU http://www.jus.uio.no/sisu (this copy)" /> --> -      <meta name="dtb:depth" content="%s" /> -      <meta name="dtb:totalPageCount" content="0" /> -      <meta name="dtb:maxPageNumber" content="0" /> -    </head> -    <docTitle> -      <text>%s</text> -    </docTitle> -    <docAuthor> -      <text>%s</text> -    </docAuthor> -    <navMap>¶", -      doc_matters.dochead_meta["title"]["full"],                                                               // title -      (doc_matters.dochead_meta["creator"]["author"].empty) ? "" : " by " ~ doc_matters.dochead_meta["creator"]["author"], // author -      uuid,                                                                                        // uuid -      "3",                                                                                         // content depth -      doc_matters.dochead_meta["title"]["full"],                                                               // title -      (doc_matters.dochead_meta["creator"]["author"].empty) ? "" : doc_matters.dochead_meta["creator"]["author"],          // author -    ); -    foreach (sect; doc_matters.keys_seq_seg) { -      foreach (obj; doc_abstraction[sect]) { -        if (obj.is_a == "heading") { -          foreach_reverse (k; 0 .. 7) { -            switch (obj.dom_markedup[k]) { -            case DomTags.close : -  toc ~= "</navPoint>"; -              break; -            case DomTags.close_and_open : -              ++counter; -  toc ~= "</navPoint>"; -  toc ~= format(q"¶<navPoint class="chapter" id="navpoint" playOrder="%s"> -  <navLabel> -    <text>%s</text> -  </navLabel> -  <content src="%s" />¶", -  counter, -  obj.text, -  obj.segment_anchor_tag,   // lev < 4 [no link]; lev == 4 [filename] markup.xhtml; lev > 4 [filename#ocn] (links done in segment_anchor_tag) -  ); -              break; -            case DomTags.open : -              ++counter; -  toc ~= format(q"¶<navPoint class="chapter" id="navpoint" playOrder="%s"> -  <navLabel> -    <text>%s</text> -  </navLabel> -  <content src="%s" />¶", -  counter, -  obj.text, -  obj.segment_anchor_tag,   // lev < 4 [no link]; lev == 4 [filename] markup.xhtml; lev > 4 [filename#ocn] (fix links in segment_anchor_tag) -  ); -              break; -            default : -              break; -            } -          } -        } -      } -    } -    toc ~= format(q"¶  </navMap> -  </ncx>¶"); -    return toc; -  } -   -  void outputEPub(D,I)( -    auto return ref const D    doc_abstraction, -    auto return ref I          doc_matters, -  ) { -    mixin SiSUoutputRgxInit; -    auto xhtml_format = outputXHTMLs(); -    auto rgx = Rgx(); -    string[][string] doc_epub; -    string[][string] doc_epub_endnotes; -    string[] doc; -    string segment_filename; -    string[] top_level_headings = ["","","",""]; -    auto mimetypes = epub_mimetypes; -    auto meta_inf_container_xml = epub_container_xml; -    auto oebps_toc_ncx = epub_oebps_toc(doc_abstraction, doc_matters); -    auto oebps_content_opf = epub_oebps_content(doc_abstraction, doc_matters); -    string suffix = ".xhtml"; -    foreach (part; doc_matters.keys_seq_seg) { -      foreach (obj; doc_abstraction[part]) { -        if (obj.is_a == "heading") { -          switch (obj.heading_lev_markup) { -          case 0: .. case 3: -            /+ fill buffer, and replace with new levels from 1 to 3 +/ -            switch (obj.heading_lev_markup) { -            case 0: -              top_level_headings[0] = ""; -              top_level_headings[1] = ""; -              top_level_headings[2] = ""; -              top_level_headings[3] = ""; -              goto default; -            case 1: -              top_level_headings[1] = ""; -              top_level_headings[2] = ""; -              top_level_headings[3] = ""; -              goto default; -            case 2: -              top_level_headings[2] = ""; -              top_level_headings[3] = ""; -              goto default; -            case 3: -              top_level_headings[3] = ""; -              goto default; -            default: -              auto t = xhtml_format.heading_seg(obj, suffix); -              top_level_headings[obj.heading_lev_markup] = t[0]; -              break; -            } -            break; -          case 4: -            segment_filename = obj.segment_anchor_tag; -            doc_epub[segment_filename] ~= xhtml_format.seg_head(doc_matters.dochead_meta); -            foreach (top_level_heading; top_level_headings) { -              doc_epub[segment_filename] ~= top_level_heading; -            } -            auto t = xhtml_format.heading_seg(obj, suffix); -            doc_epub[segment_filename] ~= t[0]; -            doc_epub_endnotes[segment_filename] ~= t[1]; -            break; -          case 5: .. case 7: -            auto t = xhtml_format.heading_seg(obj, suffix); -            doc_epub[segment_filename] ~= t[0]; -            doc_epub_endnotes[segment_filename] ~= t[1]; -            break; -          case 8: .. case 9: // unused numbers, if remain check -            if ((doc_matters.opt_action_bool["debug"])) { -              writeln(__FILE__, ":", __LINE__, ": ", obj.is_a, ": ", obj.heading_lev_markup); -              writeln(__FILE__, ":", __LINE__, ": ", obj.text); // check -            } -            break; -          default: -            if ((doc_matters.opt_action_bool["debug"])) { -              writeln(__FILE__, ":", __LINE__, ": ", obj.is_a, ": ", obj.heading_lev_markup); -            } -            break; -          } -        } else { -          switch (obj.use) { -          case "frontmatter": -            switch (obj.is_of) { -            case "para": -              switch (obj.is_a) { -              case "toc": -                doc_epub[segment_filename] ~= xhtml_format.toc(obj); -                break; -              default: -                if ((doc_matters.opt_action_bool["debug"])) { -                  writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); -                } -                break; -              } -              break; -            default: -              if ((doc_matters.opt_action_bool["debug"])) { -                writeln(__FILE__, ":", __LINE__, ": ", obj.is_of); -              } -              break; -            } -            break; -          case "body": -            switch (obj.is_of) { -            case "para": -              switch (obj.is_a) { -              case "para": -                auto t = xhtml_format.para_seg(obj, suffix); -                doc_epub[segment_filename] ~= t[0]; -                doc_epub_endnotes[segment_filename] ~= t[1]; -                break; -              default: -                if ((doc_matters.opt_action_bool["debug"])) { -                  writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); -                } -                break; -              } -              break; -            case "block": -              switch (obj.is_a) { -              case "quote": -                auto t = xhtml_format.quote_seg(obj, suffix); -                doc_epub[segment_filename] ~= to!string(t[0]); -                doc_epub_endnotes[segment_filename] ~= t[1]; -                break; -              case "group": -                auto t = xhtml_format.group_seg(obj, suffix); -                doc_epub[segment_filename] ~= to!string(t[0]); -                doc_epub_endnotes[segment_filename] ~= t[1]; -                break; -              case "block": -                auto t = xhtml_format.block_seg(obj, suffix); -                doc_epub[segment_filename] ~= to!string(t[0]); -                doc_epub_endnotes[segment_filename] ~= t[1]; -                break; -              case "poem": -                break; -              case "verse": -                auto t = xhtml_format.verse_seg(obj, suffix); -                doc_epub[segment_filename] ~= to!string(t[0]); -                doc_epub_endnotes[segment_filename] ~= t[1]; -                break; -              case "code": -                doc_epub[segment_filename] ~= xhtml_format.code(obj); -                break; -              case "table": -                auto t = xhtml_format.para_seg(obj, suffix); -                doc_epub[segment_filename] ~= t[0]; -                doc_epub_endnotes[segment_filename] ~= t[1]; -                break; -              default: -                if ((doc_matters.opt_action_bool["debug"])) { -                  writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); -                } -                break; -              } -              break; -            default: -              if ((doc_matters.opt_action_bool["debug"])) { -                writeln(__FILE__, ":", __LINE__, ": ", obj.is_of); -              } -              break; -            } -            break; -          case "backmatter": -            switch (obj.is_of) { -            case "para": -              switch (obj.is_a) { -              case "endnote": -                auto t = xhtml_format.para_seg(obj, suffix); -                doc_epub[segment_filename] ~= t[0]; -                break; -              case "glossary": -                auto t = xhtml_format.para_seg(obj, suffix); -                doc_epub[segment_filename] ~= t[0]; -                doc_epub_endnotes[segment_filename] ~= t[1]; -                break; -              case "bibliography": -                auto t = xhtml_format.para_seg(obj, suffix); -                doc_epub[segment_filename] ~= t[0]; -                doc_epub_endnotes[segment_filename] ~= t[1]; -                break; -              case "bookindex": -                auto t = xhtml_format.para_seg(obj, suffix); -                doc_epub[segment_filename] ~= t[0]; -                doc_epub_endnotes[segment_filename] ~= t[1]; -                break; -              case "blurb": -                auto t = xhtml_format.para_seg(obj, suffix); -                doc_epub[segment_filename] ~= t[0]; -                doc_epub_endnotes[segment_filename] ~= t[1]; -                break; -              default: -                if ((doc_matters.opt_action_bool["debug"])) { -                  writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); -                } -                break; -              } -              break; -            default: -              if ((doc_matters.opt_action_bool["debug"])) { -                writeln(__FILE__, ":", __LINE__, ": ", obj.is_of); -              } -              break; -            } -            break; -          case "comment": -            break; -          default: -            if ((doc_matters.opt_action_bool["debug"])) { -              writeln(__FILE__, ":", __LINE__, ": ", obj.use); -            } -            break; -          } -        } -      } -    } -    epub_write_output_files( -      doc_matters, -      doc_epub, -      doc_epub_endnotes, -      mimetypes, -      meta_inf_container_xml, -      oebps_toc_ncx, -      oebps_content_opf, -    ); -  } -  void epub_write_output_files(M,D,E,Mt,Mic,Ot,Oc)( -    M    doc_matters, -    D    doc_epub, -    E    doc_epub_endnotes, -    Mt   mimetypes, -    Mic  meta_inf_container_xml, -    Ot   oebps_toc_ncx, -    Oc   oebps_content_opf, -  ) { -    debug(asserts){ -      static assert(is(typeof(doc_epub)               == string[][string])); -      static assert(is(typeof(mimetypes)              == string)); -      static assert(is(typeof(meta_inf_container_xml) == string)); -      static assert(is(typeof(oebps_toc_ncx)          == string)); -      static assert(is(typeof(oebps_content_opf)      == string)); -    } -    mixin SiSUpaths; -    auto pth_epub = EpubPaths(); -    auto xhtml_format = outputXHTMLs(); -    try { -      if (!exists(pth_epub.doc_meta_inf(doc_matters.source_filename))) { -        pth_epub.doc_meta_inf(doc_matters.source_filename).mkdirRecurse; -      } -      if (!exists(pth_epub.doc_oebps_css(doc_matters.source_filename))) { -        pth_epub.doc_oebps_css(doc_matters.source_filename).mkdirRecurse; -      } -      if (!exists(pth_epub.doc_oebps_image(doc_matters.source_filename))) { -        pth_epub.doc_oebps_image(doc_matters.source_filename).mkdirRecurse; -      } -      /+ OEBPS/[segments].xhtml +/ -      foreach (seg_filename; doc_matters.segnames) { -        auto f = File(pth_epub.fn_oebps_content_xhtml(doc_matters.source_filename, seg_filename), "w"); -        /+ // f.writeln(seg_head); // not needed built and inserted earlier +/ -        foreach (docseg; doc_epub[seg_filename]) { -          f.writeln(docseg); -        } -        foreach (docseg; doc_epub_endnotes[seg_filename]) { -          f.writeln(docseg); -        } -        f.writeln(xhtml_format.tail); // needed for each lev4 -      } -      /+ mimetypes +/ -      auto f = File(pth_epub.fn_mimetypes(doc_matters.source_filename), "w"); -      f.writeln(mimetypes); -      /+  META-INF/container.xml +/ -      f = File(pth_epub.fn_dmi_container_xml(doc_matters.source_filename), "w"); -      f.writeln(meta_inf_container_xml); -      /+ OEBPS/toc.ncx +/ -      f = File(pth_epub.fn_oebps_toc_ncx(doc_matters.source_filename), "w"); -      f.writeln(oebps_toc_ncx); -      /+ OEBPS/content.opf +/ -      f = File(pth_epub.fn_oebps_content_opf(doc_matters.source_filename), "w"); -      f.writeln(oebps_content_opf); -      foreach (image; doc_matters.image_list) { -        if (exists("_sisu/image/"~ image)) { -          ("_sisu/image/"~ image) -          .copy((pth_epub.doc_oebps_image(doc_matters.source_filename)) ~ "/" ~ image); -        } -      } -    } -    catch (ErrnoException ex) { -      // Handle error -    } -  } -   -} diff --git a/src/sdp/output_epub3.d b/src/sdp/output_epub3.d new file mode 100644 index 0000000..f0ac2c3 --- /dev/null +++ b/src/sdp/output_epub3.d @@ -0,0 +1,717 @@ +template outputEPub3() { +  private import +    std.algorithm, +    std.array, +    std.container, +    std.digest.sha, +    std.exception, +    std.file, +    std.getopt, +    std.json, +    std.outbuffer, +    std.path, +    std.process, +    std.range, +    std.regex, +    std.stdio, +    std.string, +    std.traits, +    std.typecons, +    std.uni, +    std.utf, +    std.zip, +    std.conv : to; +  import +    create_zip_file, +    defaults, +    output_rgx, +    output_xhtmls; +  mixin InternalMarkup; +  mixin outputXHTMLs; +  string epub3_mimetypes() { +    string o; +    o = format(q"¶application/epub+zip¶") ~ "\n"; +    return o; +  } +  string epub3_container_xml() { +    string o; +    o = format(q"¶<?xml version='1.0' encoding='utf-8'?>¶") ~ "\n"; +    o ~= format(q"¶<container version="1.0" +  xmlns="urn:oasis:names:tc:opendocument:xmlns:container"> +  <rootfiles> +    <rootfile full-path="OEBPS/content.opf" +      media-type="application/oebps-package+xml" /> +  </rootfiles>¶") ~ "\n</container>\n"; +    return o; +  } +  string epub3_oebps_content(D,I,P)(D doc_abstraction, I doc_matters, P parts) { +    string uuid = "18275d951861c77f78acd05672c9906924c59f18a2e0ba06dad95959693e9bd8"; // TODO sort uuid in doc_matters! +    string content = format(q"¶  <?xml version='1.0' encoding='utf-8'?> +  <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="EPB-UUID"> +    <metadata +      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +      xmlns:dcterms="http://purl.org/dc/terms/" +      xmlns:dc="http://purl.org/dc/elements/1.1/" +      unique-identifier="urn:uuid:%s" version="2.0"> +      <!-- <dc:title id="title">%s</dc:title> --> +      <dc:title id="title">%s</dc:title> +      <meta refines="#title" property="title-type">main</meta> +      <dc:title id="subtitle">%s</dc:title> +      <meta refines="#subtitle" property="title-type">subtitle</meta> +      <dc:creator file-as="%s" id="aut">%s</dc:creator> +      <dc:language>%s</dc:language> +      <dc:date id="published">%s</dc:date> +      <dc:rights>Copyright: %s</dc:rights> +      <dc:identifier scheme="URI">%s</dc:identifier> +      <dc:identifier id="bookid">urn:uuid:%s</dc:identifier> +      <!-- <dc:identifier id="EPB-UUID">urn:uuid:%s</dc:identifier> --> +    </metadata> +    <manifest> +      <!-- NCX epub2 navigation --> +        <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" /> +      <!-- CSS Style Sheets --> +        <item id="main-css" href="css/xhtml.css" media-type="text/css" /> +      <!-- nav epub3 navigation --> +        <item id="nav" href="toc_nav.xhtml" media-type="application/xhtml+xml" properties="nav" /> +  ¶", +      uuid, +      doc_matters.dochead_meta["title"]["full"], +      doc_matters.dochead_meta["title"]["main"], +      (doc_matters.dochead_meta["title"]["sub"].empty) +        ? "" : doc_matters.dochead_meta["title"]["sub"], +      (doc_matters.dochead_meta["creator"]["author"].empty) +        ? "" : doc_matters.dochead_meta["creator"]["author"], +      (doc_matters.dochead_meta["creator"]["author"].empty) +        ? "" : doc_matters.dochead_meta["creator"]["author"], +      doc_matters.language, +      (doc_matters.dochead_meta["date"]["published"].empty) +        ? "" : doc_matters.dochead_meta["date"]["published"], +      (doc_matters.dochead_meta["rights"]["copyright"].empty) +        ? "" : doc_matters.dochead_meta["rights"]["copyright"], +      uuid, +      uuid, +      uuid, +    ); +    content ~= "    " ~ "<!-- Content Documents -->" ~ "\n  "; +    content ~= parts["manifest_documents"]; +    // TODO sort jpg & png +    content ~= "    " ~ "<!-- Images -->" ~ "\n  "; +    foreach (image; doc_matters.image_list) { +      content ~= format(q"¶      <item id="%s" href="image/%s" media-type="image/png" /> +  ¶", +        image,                        // strip image type, remove .png .jpg suffix, use in media-type="image/" +        image, +      ); +    } +    content ~= "  " ~ "</manifest>"         ~ "\n  "; +    content ~= "  " ~ "<spine toc=\"ncx\">" ~ "\n  "; +    content ~= parts["spine"]; +    content ~= "  " ~ "</spine>"            ~ "\n  "; +    content ~= "  " ~ "<guide>"             ~ "\n  "; +    content ~= parts["guide"]; +    content ~= "  " ~ "</guide>"            ~ "\n  "; +    content ~= ""   ~ "</package>"; +    return content; +  } +  string epub3_oebps_toc_nav_xhtml(D,I)(D doc_abstraction, I doc_matters) { +    enum DomTags { none, open, close, close_and_open, open_still, } +    auto markup = InlineMarkup(); +    string toc ="<nav epub:type=\"toc\" id=\"toc\">\n"; +    foreach (sect; doc_matters.keys_seq_seg) { +      foreach (obj; doc_abstraction[sect]) { +        if (obj.is_a == "heading") { +          foreach_reverse (n; 0 .. 7) { +            string k = n.to!string; +            switch (obj.dom_collapsed[n]) { +            case DomTags.close : +              toc ~= markup.indent_by_spaces_provided((n + 1), "  ") ~ "</li>" ~ "\n"; +              toc ~= markup.indent_by_spaces_provided(n, "  ") ~ "</ol>" ~ "\n"; +              break; +            case DomTags.close_and_open : +              toc ~= markup.indent_by_spaces_provided((n + 1), "  ") ~ "</li>" ~ "\n"; +              if  (obj.dom_markedup[n] < 4) { +                toc ~= markup.indent_by_spaces_provided((n + 1), "  ") ~ "<li>" ~ "\n" +                ~ markup.indent_by_spaces_provided((n + 2), "  ") +                ~ "<span class=\"navhd\">" ~ obj.text ~ "</span>" ~ "\n"; +              } else { +                string hashtag =(obj.heading_lev_markup == 4) +                ? "" +                : ("#" ~ obj.ocn.to!string); +                toc ~= markup.indent_by_spaces_provided((n + 1), "  ") ~ "<li>" ~ "\n" +                ~ markup.indent_by_spaces_provided((n + 2), "  ") +                ~ "<a href=\"" ~ obj.segment_anchor_tag ~ ".xhtml" ~ hashtag ~ "\">" +                ~ obj.text +                ~ "</a>" ~ "\n"; +              } +              break; +            case DomTags.open : +              toc ~= markup.indent_by_spaces_provided(n, "  ") ~ "<ol>" ~ "\n"; +              if  (obj.dom_markedup[n] < 4) { +                toc ~= markup.indent_by_spaces_provided(n, "  ") +                ~ "<li><span class=\"navhd\">" ~ obj.text ~ "</span>" ~ "\n"; +              } else { +                string hashtag =(obj.heading_lev_markup == 4) +                ? "" +                : ("#" ~ obj.ocn.to!string); +                toc ~= markup.indent_by_spaces_provided((n + 1), "  ") ~ "<li>" ~ "\n" +                ~ markup.indent_by_spaces_provided((n + 2), "  ") +                ~ "<a href=\"" ~ obj.segment_anchor_tag ~ ".xhtml" ~ hashtag ~ "\">" +                ~ obj.text +                ~ "</a>" ~ "\n"; +              } +              break; +            default : +              break; +            } +          } +        } +      } +    } +    toc ~="</nav>\n"; +    return toc; +  } +  string epub2_oebps_toc_ncx(D,I)(D doc_abstraction, I doc_matters) { +    int counter = 0; +    string uuid = "18275d951861c77f78acd05672c9906924c59f18a2e0ba06dad95959693e9bd8"; // TODO shared elsewhere +    auto markup = InlineMarkup(); +    enum DomTags { none, open, close, close_and_open, open_still, } +    string toc = format(q"¶<?xml version='1.0' encoding='utf-8'?> +  <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1"> +    <head> +      <!-- four required metadata items (for all NCX documents, +        (including the relaxed constraints of OPS 2.0) --> +      <title>%s%s</title> +      <link href="css/xhtml.css" rel="stylesheet" type="text/css" id="main-css" /> +      <meta name="dtb:uid" content="urn:uuid:%s" /> +      <!-- <meta name="epub-creator" content="SiSU http://www.jus.uio.no/sisu (this copy)" /> --> +      <meta name="dtb:depth" content="%s" /> +      <meta name="dtb:totalPageCount" content="0" /> +      <meta name="dtb:maxPageNumber" content="0" /> +    </head> +    <docTitle> +      <text>%s</text> +    </docTitle> +    <docAuthor> +      <text>%s</text> +    </docAuthor> +    <navMap>¶", +      doc_matters.dochead_meta["title"]["full"],                                                               // title +      (doc_matters.dochead_meta["creator"]["author"].empty) ? "" : " by " ~ doc_matters.dochead_meta["creator"]["author"], // author +      uuid,                                                                                        // uuid +      "3",                                                                                         // content depth +      doc_matters.dochead_meta["title"]["full"],                                                               // title +      (doc_matters.dochead_meta["creator"]["author"].empty) ? "" : doc_matters.dochead_meta["creator"]["author"],          // author +    ); +    foreach (sect; doc_matters.keys_seq_seg) { +      foreach (obj; doc_abstraction[sect]) { +        if (obj.is_a == "heading") { +          foreach_reverse (k; 0 .. 7) { +            switch (obj.dom_markedup[k]) { +            case DomTags.close : +  toc ~= "</navPoint>"; +              break; +            case DomTags.close_and_open : +              ++counter; +  toc ~= "</navPoint>"; +  toc ~= format(q"¶<navPoint class="chapter" id="navpoint" playOrder="%s"> +  <navLabel> +    <text>%s</text> +  </navLabel> +  <content src="%s" />¶", +  counter, +  obj.text, +  obj.segment_anchor_tag,   // lev < 4 [no link]; lev == 4 [filename] markup.xhtml; lev > 4 [filename#ocn] (links done in segment_anchor_tag) +  ); +              break; +            case DomTags.open : +              ++counter; +  toc ~= format(q"¶<navPoint class="chapter" id="navpoint" playOrder="%s"> +  <navLabel> +    <text>%s</text> +  </navLabel> +  <content src="%s" />¶", +  counter, +  obj.text, +  obj.segment_anchor_tag,   // lev < 4 [no link]; lev == 4 [filename] markup.xhtml; lev > 4 [filename#ocn] (fix links in segment_anchor_tag) +  ); +              break; +            default : +              break; +            } +          } +        } +      } +    } +    toc ~= format(q"¶  </navMap> +  </ncx>¶"); +    return toc; +  } +   +  void outputEPub3(D,I)( +    auto return ref const D    doc_abstraction, +    auto return ref I          doc_matters, +  ) { +    mixin SiSUoutputRgxInit; +    auto xhtml_format = outputXHTMLs(); +    auto rgx = Rgx(); +    string[][string] doc_epub3; +    string[][string] doc_epub3_endnotes; +    string[] doc; +    string segment_filename; +    string[] top_level_headings = ["","","",""]; +    string[string] oepbs_content_parts; +    string suffix = ".xhtml"; +    foreach (part; doc_matters.keys_seq_seg) { +      foreach (obj; doc_abstraction[part]) { +        if (obj.is_a == "heading") { +          switch (obj.heading_lev_markup) { +          case 0: .. case 3: +            /+ fill buffer, and replace with new levels from 1 to 3 +/ +            switch (obj.heading_lev_markup) { +            case 0: +              top_level_headings[0] = ""; +              top_level_headings[1] = ""; +              top_level_headings[2] = ""; +              top_level_headings[3] = ""; +              goto default; +            case 1: +              top_level_headings[1] = ""; +              top_level_headings[2] = ""; +              top_level_headings[3] = ""; +              goto default; +            case 2: +              top_level_headings[2] = ""; +              top_level_headings[3] = ""; +              goto default; +            case 3: +              top_level_headings[3] = ""; +              goto default; +            default: +              auto t = xhtml_format.heading_seg(obj, suffix); +              top_level_headings[obj.heading_lev_markup] = t[0]; +              break; +            } +            break; +          case 4: +            segment_filename = obj.segment_anchor_tag; +            doc_epub3[segment_filename] ~= xhtml_format.seg_head(doc_matters.dochead_meta); +            foreach (top_level_heading; top_level_headings) { +              doc_epub3[segment_filename] ~= top_level_heading; +            } +            auto t = xhtml_format.heading_seg(obj, suffix); +            doc_epub3[segment_filename] ~= t[0]; +            doc_epub3_endnotes[segment_filename] ~= t[1]; +            break; +          case 5: .. case 7: +            auto t = xhtml_format.heading_seg(obj, suffix); +            doc_epub3[segment_filename] ~= t[0]; +            doc_epub3_endnotes[segment_filename] ~= t[1]; +            break; +          case 8: .. case 9: // unused numbers, if remain check +            if ((doc_matters.opt_action_bool["debug"])) { +              writeln(__FILE__, ":", __LINE__, ": ", obj.is_a, ": ", obj.heading_lev_markup); +              writeln(__FILE__, ":", __LINE__, ": ", obj.text); // check +            } +            break; +          default: +            if ((doc_matters.opt_action_bool["debug"])) { +              writeln(__FILE__, ":", __LINE__, ": ", obj.is_a, ": ", obj.heading_lev_markup); +            } +            break; +          } +        } else { +          switch (obj.use) { +          case "frontmatter": +            switch (obj.is_of) { +            case "para": +              switch (obj.is_a) { +              case "toc": +                doc_epub3[segment_filename] ~= xhtml_format.toc(obj); +                break; +              default: +                if ((doc_matters.opt_action_bool["debug"])) { +                  writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +                } +                break; +              } +              break; +            default: +              if ((doc_matters.opt_action_bool["debug"])) { +                writeln(__FILE__, ":", __LINE__, ": ", obj.is_of); +              } +              break; +            } +            break; +          case "body": +            switch (obj.is_of) { +            case "para": +              switch (obj.is_a) { +              case "para": +                auto t = xhtml_format.para_seg(obj, suffix); +                doc_epub3[segment_filename] ~= t[0]; +                doc_epub3_endnotes[segment_filename] ~= t[1]; +                break; +              default: +                if ((doc_matters.opt_action_bool["debug"])) { +                  writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +                } +                break; +              } +              break; +            case "block": +              switch (obj.is_a) { +              case "quote": +                auto t = xhtml_format.quote_seg(obj, suffix); +                doc_epub3[segment_filename] ~= to!string(t[0]); +                doc_epub3_endnotes[segment_filename] ~= t[1]; +                break; +              case "group": +                auto t = xhtml_format.group_seg(obj, suffix); +                doc_epub3[segment_filename] ~= to!string(t[0]); +                doc_epub3_endnotes[segment_filename] ~= t[1]; +                break; +              case "block": +                auto t = xhtml_format.block_seg(obj, suffix); +                doc_epub3[segment_filename] ~= to!string(t[0]); +                doc_epub3_endnotes[segment_filename] ~= t[1]; +                break; +              case "poem": +                break; +              case "verse": +                auto t = xhtml_format.verse_seg(obj, suffix); +                doc_epub3[segment_filename] ~= to!string(t[0]); +                doc_epub3_endnotes[segment_filename] ~= t[1]; +                break; +              case "code": +                doc_epub3[segment_filename] ~= xhtml_format.code(obj); +                break; +              case "table": +                auto t = xhtml_format.para_seg(obj, suffix); +                doc_epub3[segment_filename] ~= t[0]; +                doc_epub3_endnotes[segment_filename] ~= t[1]; +                break; +              default: +                if ((doc_matters.opt_action_bool["debug"])) { +                  writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +                } +                break; +              } +              break; +            default: +              if ((doc_matters.opt_action_bool["debug"])) { +                writeln(__FILE__, ":", __LINE__, ": ", obj.is_of); +              } +              break; +            } +            break; +          case "backmatter": +            switch (obj.is_of) { +            case "para": +              switch (obj.is_a) { +              case "endnote": +                auto t = xhtml_format.para_seg(obj, suffix); +                doc_epub3[segment_filename] ~= t[0]; +                break; +              case "glossary": +                auto t = xhtml_format.para_seg(obj, suffix); +                doc_epub3[segment_filename] ~= t[0]; +                doc_epub3_endnotes[segment_filename] ~= t[1]; +                break; +              case "bibliography": +                auto t = xhtml_format.para_seg(obj, suffix); +                doc_epub3[segment_filename] ~= t[0]; +                doc_epub3_endnotes[segment_filename] ~= t[1]; +                break; +              case "bookindex": +                auto t = xhtml_format.para_seg(obj, suffix); +                doc_epub3[segment_filename] ~= t[0]; +                doc_epub3_endnotes[segment_filename] ~= t[1]; +                break; +              case "blurb": +                auto t = xhtml_format.para_seg(obj, suffix); +                doc_epub3[segment_filename] ~= t[0]; +                doc_epub3_endnotes[segment_filename] ~= t[1]; +                break; +              default: +                if ((doc_matters.opt_action_bool["debug"])) { +                  writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +                } +                break; +              } +              break; +            default: +              if ((doc_matters.opt_action_bool["debug"])) { +                writeln(__FILE__, ":", __LINE__, ": ", obj.is_of); +              } +              break; +            } +            break; +          case "comment": +            break; +          default: +            if ((doc_matters.opt_action_bool["debug"])) { +              writeln(__FILE__, ":", __LINE__, ": ", obj.use); +            } +            break; +          } +        } +        if (obj.is_a == "heading") { +          if (obj.heading_lev_markup == 4) { +            oepbs_content_parts["manifest_documents"] ~= format(q"¶      <item id="%s.xhtml" href="%s.xhtml" media-type="application/xhtml+xml" /> +  ¶", +              obj.segment_anchor_tag, +              obj.segment_anchor_tag, +            ); +            oepbs_content_parts["spine"] ~= format(q"¶    <itemref idref="%s.xhtml" linear="yes" /> +  ¶", +              obj.segment_anchor_tag, +            ); +            oepbs_content_parts["guide"] ~= format(q"¶      <reference type="%s" href="%s" /> +  ¶", +              obj.segment_anchor_tag, +              obj.segment_anchor_tag, +            ); +          } else if (obj.heading_lev_markup > 4) { +            oepbs_content_parts["manifest_documents"] ~= format(q"¶      <item id="%s.xhtml#%s" href="%s.xhtml#%s" media-type="application/xhtml+xml" /> +  ¶", +              obj.segment_anchor_tag, +              obj.obj_cite_number, +              obj.segment_anchor_tag, +              obj.obj_cite_number, +            ); +            oepbs_content_parts["spine"] ~= format(q"¶    <itemref idref="%s.xhtml#%s" linear="yes" /> +  ¶", +              obj.segment_anchor_tag, +              obj.obj_cite_number, +            ); +            oepbs_content_parts["guide"] ~= format(q"¶      <reference type="%s#%s" href="%s#%s" /> +  ¶", +              obj.segment_anchor_tag, +              obj.obj_cite_number, +              obj.segment_anchor_tag, +              obj.obj_cite_number, +            ); +          } +        } +      } +    } +    /+ epub specific documents +/ +    auto mimetypes = epub3_mimetypes; +    auto meta_inf_container_xml = epub3_container_xml; +    auto oebps_toc_ncx = epub2_oebps_toc_ncx(doc_abstraction, doc_matters); +    auto oebps_toc_nav_xhtml = epub3_oebps_toc_nav_xhtml(doc_abstraction, doc_matters); +    auto oebps_content_opf = epub3_oebps_content(doc_abstraction, doc_matters, oepbs_content_parts); +    epub3_write_output_files( +      doc_matters, +      doc_epub3, +      doc_epub3_endnotes, +      mimetypes, +      meta_inf_container_xml, +      oebps_toc_nav_xhtml, +      oebps_toc_ncx, +      oebps_content_opf, +    ); +  } +  void epub3_write_output_files(M,D,E,Mt,Mic,Otnx,Otn,Oc)( +    M    doc_matters, +    D    doc_epub3, +    E    doc_epub3_endnotes, +    Mt   mimetypes, +    Mic  meta_inf_container_xml, +    Otnx oebps_toc_nav_xhtml, +    Otn  oebps_toc_ncx, +    Oc   oebps_content_opf, +  ) { +    debug(asserts) { +      static assert(is(typeof(doc_epub3)              == string[][string])); +      static assert(is(typeof(mimetypes)              == string)); +      static assert(is(typeof(meta_inf_container_xml) == string)); +      static assert(is(typeof(oebps_toc_nav_xhtml)    == string)); +      static assert(is(typeof(oebps_toc_ncx)          == string)); +      static assert(is(typeof(oebps_content_opf)      == string)); +    } +    mixin SiSUpaths; +    auto pth_epub3 = Epub3paths(); +    auto xhtml_format = outputXHTMLs(); +    /+ zip file +/ +    auto fn_epub = pth_epub3.epub_file(doc_matters.source_filename); +    auto zip = new ZipArchive(); // ZipArchive zip = new ZipArchive(); +    /+ zip archive member files +/ +    try { +      if (!exists(pth_epub3.doc_meta_inf(doc_matters.source_filename))) { +        pth_epub3.doc_meta_inf(doc_matters.source_filename).mkdirRecurse; +      } +      if (!exists(pth_epub3.doc_oebps_css(doc_matters.source_filename))) { +        pth_epub3.doc_oebps_css(doc_matters.source_filename).mkdirRecurse; +      } +      if (!exists(pth_epub3.doc_oebps_image(doc_matters.source_filename))) { +        pth_epub3.doc_oebps_image(doc_matters.source_filename).mkdirRecurse; +      } +      { /+ OEBPS/[segments].xhtml (the document contents) +/ +        foreach (seg_filename; doc_matters.segnames) { +          string fn = pth_epub3.fn_oebps_content_xhtml(doc_matters.source_filename, seg_filename); +          /+ add zip archive file members (with their content) +/ +          auto zip_arc_member_file = new ArchiveMember(); +          // add seg fn to zip archive +          zip_arc_member_file.name = fn; +          auto zip_data = new OutBuffer(); +          debug(epub_output) { +            string fn_dbg = pth_epub3.dbg_fn_oebps_content_xhtml(doc_matters.source_filename, seg_filename); +            auto f = File(fn_dbg, "w"); +          } +          /+ // f.writeln(seg_head); // not needed built and inserted earlier +/ +          foreach (docseg; doc_epub3[seg_filename]) { +            debug(epub_output) { f.writeln(docseg); } +            zip_data.write(docseg.dup); // cast as: char[] +          } +          foreach (docseg; doc_epub3_endnotes[seg_filename]) { +            debug(epub_output) { f.writeln(docseg); } +            zip_data.write(docseg.dup); // cast as: char[] +          } +          debug(epub_output) { f.writeln(xhtml_format.tail); } // needed for each lev4 +          zip_data.write(xhtml_format.tail.dup); // cast as: char[] +          zip_arc_member_file.expandedData = zip_data.toBytes(); +          zip.addMember(zip_arc_member_file); +          /+ create the zip file +/ +          createZipFile!()(fn_epub, zip.build()); +        } +      } +      string fn; +      debug(epub_output) { string fn_dbg; } +      File f; +      { /+ mimetypes (identify zip file type) +/ +        debug(epub_output) { +          fn_dbg = pth_epub3.dbg_fn_mimetypes(doc_matters.source_filename); +          File(fn_dbg, "w").writeln(mimetypes); +        } +        fn = pth_epub3.fn_mimetypes(doc_matters.source_filename); +        /+ add zip archive file members (with their content) +/ +        auto zip_arc_member_file = new ArchiveMember(); +        // add mimetypes to zip archive +        zip_arc_member_file.name = fn; +        auto zip_data = new OutBuffer(); +        zip_data.write(mimetypes.dup); // cast as: char[] +        zip_arc_member_file.expandedData = zip_data.toBytes(); +        zip.addMember(zip_arc_member_file); +        /+ create the zip file +/ +        createZipFile!()(fn_epub, zip.build()); +      } +      { /+  META-INF/container.xml (identify doc root) +/ +        debug(epub_output) { +          fn_dbg = pth_epub3.dbg_fn_dmi_container_xml(doc_matters.source_filename); +          File(fn_dbg, "w").writeln(meta_inf_container_xml); +        } +        fn = pth_epub3.fn_dmi_container_xml(doc_matters.source_filename); +        /+ add zip archive file members (with their content) +/ +        auto zip_arc_member_file = new ArchiveMember(); +        // add META-INF/container.xml to zip archive +        zip_arc_member_file.name = fn; +        auto zip_data = new OutBuffer(); +        zip_data.write(meta_inf_container_xml.dup); // cast as: char[] +        zip_arc_member_file.expandedData = zip_data.toBytes(); +        zip.addMember(zip_arc_member_file); +        /+ create the zip file +/ +        createZipFile!()(fn_epub, zip.build()); +      } +      { /+ OEBPS/toc_nav.xhtml (navigation toc epub3) +/ +        debug(epub_output) { +          fn_dbg = pth_epub3.dbg_fn_oebps_toc_nav_xhtml(doc_matters.source_filename); +          File(fn_dbg, "w").writeln(oebps_toc_nav_xhtml); +        } +        fn = pth_epub3.fn_oebps_toc_nav_xhtml(doc_matters.source_filename); +        /+ add zip archive file members (with their content) +/ +        auto zip_arc_member_file = new ArchiveMember(); +        // add OEBPS/toc_nav.xhtml to zip archive +        zip_arc_member_file.name = fn; +        auto zip_data = new OutBuffer(); +        zip_data.write(oebps_toc_nav_xhtml.dup); // cast as: char[] +        zip_arc_member_file.expandedData = zip_data.toBytes(); +        zip.addMember(zip_arc_member_file); +        /+ create the zip file +/ +        createZipFile!()(fn_epub, zip.build()); +      } +      { /+ TODO OEBPS/toc.ncx (navigation toc epub2) +/ +        debug(epub_output) { +          fn_dbg = pth_epub3.dbg_fn_oebps_toc_ncx(doc_matters.source_filename); +          File(fn_dbg, "w").writeln(oebps_toc_ncx); +        } +        fn = pth_epub3.fn_oebps_toc_ncx(doc_matters.source_filename); +        /+ add zip archive file members (with their content) +/ +        auto zip_arc_member_file = new ArchiveMember(); +        // add OEBPS/toc.ncx to zip archive +        zip_arc_member_file.name = fn; +        auto zip_data = new OutBuffer(); +        zip_data.write(oebps_toc_ncx.dup); // cast as: char[] +        zip_arc_member_file.expandedData = zip_data.toBytes(); +        zip.addMember(zip_arc_member_file); +        /+ create the zip file +/ +        createZipFile!()(fn_epub, zip.build()); +      } +      { /+ TODO OEBPS/content.opf (doc manifest) +/ +        debug(epub_output) { +          fn_dbg = pth_epub3.dbg_fn_oebps_content_opf(doc_matters.source_filename); +          File(fn_dbg, "w").writeln(oebps_content_opf); +        } +        fn = pth_epub3.fn_oebps_content_opf(doc_matters.source_filename); +        /+ add zip archive file members (with their content) +/ +        auto zip_arc_member_file = new ArchiveMember(); +        // add OEBPS/content.opf to zip archive +        zip_arc_member_file.name = fn; +        auto zip_data = new OutBuffer(); +        zip_data.write(oebps_content_opf.dup); // cast as: char[] +        zip_arc_member_file.expandedData = zip_data.toBytes(); +        zip.addMember(zip_arc_member_file); +        /+ create the zip file +/ +        createZipFile!()(fn_epub, zip.build()); +      } +      { /+ OEBPS/_sisu/image (images) +/ +        foreach (image; doc_matters.image_list) { +          if (exists("_sisu/image/"~ image)) { +            ("_sisu/image/"~ image) +            .copy((pth_epub3.doc_oebps_image(doc_matters.source_filename)) ~ "/" ~ image); +          } +        } +        foreach (image; doc_matters.image_list) { +          debug(epub_images) { +            writeln( +              "_sisu/image/", image, " -> ", +              pth_epub3.doc_oebps_image(doc_matters.source_filename), "/", image +            ); +          } +          auto fn_src = "_sisu/image/"~ image; +          auto fn_out =  pth_epub3.doc_oebps_image(doc_matters.source_filename).to!string ~ "/" ~ image; +          if (exists(fn_src)) { +            { +              auto zip_arc_member_file = new ArchiveMember(); +              zip_arc_member_file.name = fn_out; +              auto zip_data = new OutBuffer(); +              zip_data.write(cast(char[]) ((fn_src).read)); +              zip_arc_member_file.expandedData = zip_data.toBytes(); +              zip.addMember(zip_arc_member_file); +              createZipFile!()(fn_epub, zip.build()); +            } +          } +        } +      } +    } +    catch (ErrnoException ex) { +      // Handle error +    } +    debug(epub_archive) { +      if (exists(fn_epub)) { +        try { +          auto zipped = new ZipArchive((fn_epub).read); +          foreach (filename, member; zipped.directory) { +            auto data = zipped.expand(member); +            writeln(filename, " length ", data.length); // member.name +            // Use data +          } +        } +        catch (ZipException ex) { +          // Handle errors +        } +      } +    } +  } +   +} diff --git a/src/sdp/output_html.d b/src/sdp/output_html.d index ba6adc8..71faa67 100644 --- a/src/sdp/output_html.d +++ b/src/sdp/output_html.d @@ -3,22 +3,26 @@ template outputHTML() {      std.algorithm,      std.array,      std.container, +    std.digest.sha,      std.exception,      std.file,      std.getopt,      std.json, -    std.process, -    std.stdio, +    std.outbuffer,      std.path, +    std.process,      std.range,      std.regex, +    std.stdio,      std.string,      std.traits,      std.typecons,      std.uni,      std.utf, +    std.zip,      std.conv : to;    import +    create_zip_file,      defaults,      output_rgx,      output_xhtmls; @@ -169,7 +173,7 @@ template outputHTML() {      Fn fn_src,      C doc,    ) { -    debug(asserts){ +    debug(asserts) {        static assert(is(typeof(fn_src) == string));        static assert(is(typeof(doc)    == string[]));      } @@ -404,7 +408,7 @@ template outputHTML() {      D doc_html,      E doc_html_endnotes,    ) { -    debug(asserts){ +    debug(asserts) {        static assert(is(typeof(doc_html)      == string[][string]));      }      mixin SiSUoutputRgxInit; diff --git a/src/sdp/output_hub.d b/src/sdp/output_hub.d index 67275e0..65c8990 100644 --- a/src/sdp/output_hub.d +++ b/src/sdp/output_hub.d @@ -1,5 +1,5 @@  /++ -  output hub<BR> +  output hub<br>    check & generate output types requested  +/  template outputHub() { @@ -20,13 +20,14 @@ template outputHub() {      std.traits,      std.typecons,      std.uni, -    std.utf, +    std.utf; +  import      defaults, -    output_epub, +    output_epub3,      output_html,      output_xhtmls, -    source_sisupod; -  import +    source_sisupod, +    create_zip_file,      output_rgx,      output_xhtmls;    void outputHub(D,I)(D doc_abstraction, I doc_matters) { @@ -65,10 +66,10 @@ template outputHub() {        if ((doc_matters.opt_action_bool["verbose"])) {writeln("html scroll done");}      }      if (doc_matters.opt_action_bool["epub"]) { -      if ((doc_matters.opt_action_bool["verbose"])) {write("epub processing... ");} -      outputEPub!()(doc_abstraction, doc_matters); +      if ((doc_matters.opt_action_bool["verbose"])) {write("epub3 processing... ");} +      outputEPub3!()(doc_abstraction, doc_matters);        // epub.css_write; -      if ((doc_matters.opt_action_bool["verbose"])) {writeln("epub done");} +      if ((doc_matters.opt_action_bool["verbose"])) {writeln("epub3 done");}      }      if (doc_matters.opt_action_bool["pdf"]) {        /+ mixin outputPDF; +/ diff --git a/src/sdp/output_xhtmls.d b/src/sdp/output_xhtmls.d index 2a86d4c..804b82f 100644 --- a/src/sdp/output_xhtmls.d +++ b/src/sdp/output_xhtmls.d @@ -3,22 +3,26 @@ template outputXHTMLs() {      std.algorithm,      std.array,      std.container, +    std.digest.sha,      std.exception,      std.file,      std.getopt,      std.json, -    std.process, -    std.stdio, +    std.outbuffer,      std.path, +    std.process,      std.range,      std.regex, +    std.stdio,      std.string,      std.traits,      std.typecons,      std.uni,      std.utf, +    std.zip,      std.conv : to;    import +    create_zip_file,      defaults,      output_rgx,      output_xhtmls; @@ -30,7 +34,7 @@ template outputXHTMLs() {          .replaceAll(rgx.xhtml_ampersand,    "&")          .replaceAll(rgx.xhtml_less_than,    "<")          .replaceAll(rgx.xhtml_greater_than, ">") -        .replaceAll(rgx.xhtml_line_break,   "<br>"); +        .replaceAll(rgx.xhtml_line_break,   "<br />");        return _txt;      }      string font_face(string _txt){ @@ -61,7 +65,7 @@ template outputXHTMLs() {      auto scroll_head(Me)(        Me dochead_meta,      ) { -      debug(asserts){ +      debug(asserts) {          static assert(is(typeof(dochead_meta) == string[string][string]));        }        string o; @@ -69,26 +73,27 @@ template outputXHTMLs() {      <html>      <head>        <meta charset="utf-8"> -      <title> -        %s%s -      </title> -    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> -      <meta name="dc.title" content="Title" /> -      <meta name="dc.author" content="Author" /> -      <meta name="dc.publisher" content="SiSU http://www.jus.uio.no/sisu (this copy)" /> -      <meta name="dc.date" content="year" /> -      <meta name="dc.date.created" content="year" /> -      <meta name="dc.date.issued" content="year" /> -      <meta name="dc.date.available" content="year" /> -      <meta name="dc.date.valid" content="year" /> -      <meta name="dc.date.modified" content="year" /> -      <meta name="dc.language" content="US" /> -      <meta name="dc.rights" content="Copyright: Copyright (C) year holder /> -      <meta name="generator" content="sdp [SiSU 7.1.8 of 2016w08/5 (2016-02-26)] (n*x and D)" /> -        <link rel="generator" href="http://www.sisudoc.org/" /> +        <title> +          %s%s +        </title> +        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> +        <meta name="dc.title" content="Title" /> +        <meta name="dc.author" content="Author" /> +        <meta name="dc.publisher" content="SiSU http://www.jus.uio.no/sisu (this copy)" /> +        <meta name="dc.date" content="year" /> +        <meta name="dc.date.created" content="year" /> +        <meta name="dc.date.issued" content="year" /> +        <meta name="dc.date.available" content="year" /> +        <meta name="dc.date.valid" content="year" /> +        <meta name="dc.date.modified" content="year" /> +        <meta name="dc.language" content="US" /> +        <meta name="dc.rights" content="Copyright: Copyright (C) year holder /> +        <meta name="generator" content="sdp [SiSU 7.1.8 of 2016w08/5 (2016-02-26)] (n*x and D)" /> +      </meta> +      <link rel="generator" href="http://www.sisudoc.org/" />        <link rel="shortcut icon" href="../_sisu/image/rb7.ico" /> -      <link href="../../_sisu/css/html.css" rel="stylesheet"> -      <link href="../../../_sisu/css/html.css" rel="stylesheet"> +      <link href="../../_sisu/css/html.css" rel="stylesheet" /> +      <link href="../../../_sisu/css/html.css" rel="stylesheet" />      </head>      <body lang="en">      <a name="top" id="top"></a>¶", @@ -100,7 +105,7 @@ template outputXHTMLs() {      auto seg_head(Me)(        Me dochead_meta,      ) { -      debug(asserts){ +      debug(asserts) {          static assert(is(typeof(dochead_meta) == string[string][string]));        }        string o; @@ -108,26 +113,27 @@ template outputXHTMLs() {      <html>      <head>        <meta charset="utf-8"> -      <title> -        %s%s -      </title> -    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> -      <meta name="dc.title" content="Title" /> -      <meta name="dc.author" content="Author" /> -      <meta name="dc.publisher" content="SiSU http://www.jus.uio.no/sisu (this copy)" /> -      <meta name="dc.date" content="year" /> -      <meta name="dc.date.created" content="year" /> -      <meta name="dc.date.issued" content="year" /> -      <meta name="dc.date.available" content="year" /> -      <meta name="dc.date.valid" content="year" /> -      <meta name="dc.date.modified" content="year" /> -      <meta name="dc.language" content="US" /> -      <meta name="dc.rights" content="Copyright: Copyright (C) year holder /> -      <meta name="generator" content="sdp [SiSU 7.1.8 of 2016w08/5 (2016-02-26)] (n*x and D)" /> -        <link rel="generator" href="http://www.sisudoc.org/" /> +        <title> +          %s%s +        </title> +        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> +        <meta name="dc.title" content="Title" /> +        <meta name="dc.author" content="Author" /> +        <meta name="dc.publisher" content="SiSU http://www.jus.uio.no/sisu (this copy)" /> +        <meta name="dc.date" content="year" /> +        <meta name="dc.date.created" content="year" /> +        <meta name="dc.date.issued" content="year" /> +        <meta name="dc.date.available" content="year" /> +        <meta name="dc.date.valid" content="year" /> +        <meta name="dc.date.modified" content="year" /> +        <meta name="dc.language" content="US" /> +        <meta name="dc.rights" content="Copyright: Copyright (C) year holder" /> +        <meta name="generator" content="sdp [SiSU 7.1.8 of 2016w08/5 (2016-02-26)] (n*x and D)" /> +      </meta> +      <link rel="generator" href="http://www.sisudoc.org/" />        <link rel="shortcut icon" href="../_sisu/image/rb7.ico" /> -      <link href="../../_sisu/css/html.css" rel="stylesheet"> -      <link href="../../../_sisu/css/html.css" rel="stylesheet"> +      <link href="../../_sisu/css/html.css" rel="stylesheet" /> +      <link href="../../../_sisu/css/html.css" rel="stylesheet" />      </head>      <body lang="en">      <a name="top" id="top"></a>¶", @@ -192,13 +198,13 @@ template outputXHTMLs() {        return _txt;      }      auto inline_notes_scroll(O)( -      auto return ref const O         obj, -      string                  _txt, +      auto return ref const O   obj, +      string                    _txt,      ) {        if (obj.inline_notes_reg) {          _txt = (_txt).replaceAll(            rgx.inline_notes_delimiter_al_regular_number_note, -          ("<a href=\"#note_$1\"><note id=\"noteref_$1\"> <sup>$1</sup> </note></a>") +          ("<a href=\"#note_$1\"><note id=\"noteref_$1\"> <sup>$1</sup> </note></a>")          );        }        debug(markup_endnotes) { @@ -236,7 +242,7 @@ template outputXHTMLs() {              "\">",              "<note id=\"note_",              m.captures[1], -            "\"> <sup>", +            "\"> <sup>",              m.captures[1],              ".</sup></note></a>",              m.captures[2], @@ -245,7 +251,7 @@ template outputXHTMLs() {          }          _txt = (_txt).replaceAll(            rgx.inline_notes_delimiter_al_regular_number_note, -          ("<a href=\"#note_$1\"><note id=\"noteref_$1\"> <sup>$1</sup> </note></a>") +          ("<a href=\"#note_$1\"><note id=\"noteref_$1\"> <sup>$1</sup> </note></a>")          );        } else if (_txt.match(rgx.inline_notes_delimiter_al_regular_number_note)) {          debug(markup) { @@ -301,7 +307,7 @@ template outputXHTMLs() {        auto tags = _xhtml_anchor_tags(obj.anchor_tags);        string o;        if (obj.obj_cite_number.empty) { -        o = format(q"¶<br><hr /><br> +        o = format(q"¶<br /><hr /><br />        <div class="substance">          <h%s class="%s">%s            %s @@ -314,7 +320,7 @@ template outputXHTMLs() {            obj.heading_lev_markup,          );        } else { -        o = format(q"¶<br><hr /><br> +        o = format(q"¶<br /><hr /><br />        <div class="substance">          <label class="ocn"><a href="#%s" class="lnkocn">%s</a></label>          <h%s class="%s" id="%s"><a name="%s"></a>%s @@ -364,7 +370,7 @@ template outputXHTMLs() {        auto tags = _xhtml_anchor_tags(obj.anchor_tags);        _txt = font_face(_txt);        string o; -      _txt = (obj.bullet) ? ("●  " ~ _txt) : _txt; +      _txt = (obj.bullet) ? ("●  " ~ _txt) : _txt;        if (obj.obj_cite_number.empty) {          o = format(q"¶  <div class="substance">        <p class="%s" indent="h%si%s">%s @@ -541,7 +547,6 @@ template outputXHTMLs() {      </div>¶",            obj.is_a,            _txt -          // obj.text          );        } else {          o = format(q"¶  <div class="substance"> @@ -555,7 +560,6 @@ template outputXHTMLs() {            obj.is_a,            obj.obj_cite_number,            _txt -          // obj.text          );        }        return o; @@ -589,9 +593,9 @@ template outputXHTMLs() {      ) {        _txt = font_face(_txt);        _txt = (_txt) -        .replaceAll(rgx.newline, "<br>\n") -        .replaceAll(rgx.two_spaces, " " ~ " " ~ " " ~ " ") -        .replaceAll(rgx.nbsp_and_space, " " ~ " ") +        .replaceAll(rgx.newline, "<br />\n") +        .replaceAll(rgx.two_spaces, " " ~ " " ~ " " ~ " ") +        .replaceAll(rgx.nbsp_and_space, " " ~ " ")          .replaceAll(rgx.strip_br, "");        string o;        if (obj.obj_cite_number.empty) { @@ -723,8 +727,8 @@ template outputXHTMLs() {      ) {        string _txt = obj.text;        _txt = (_txt) -        .replaceAll(rgx.newline, "<br>\n") -        .replaceAll(rgx.nbsp_char, " "); +        .replaceAll(rgx.newline, "<br />\n") +        .replaceAll(rgx.nbsp_char, " ");        string o;        if (obj.obj_cite_number.empty) {            o = format(q"¶  <div class="substance"> diff --git a/src/sdp/source_sisupod.d b/src/sdp/source_sisupod.d index e6702bf..cf15348 100644 --- a/src/sdp/source_sisupod.d +++ b/src/sdp/source_sisupod.d @@ -3,103 +3,206 @@ template SiSUpod() {      std.algorithm,      std.array,      std.container, +    std.digest.sha,      std.exception,      std.file,      std.getopt,      std.json, -    std.process, -    std.stdio, +    std.outbuffer,      std.path, +    std.process,      std.range,      std.regex, +    std.stdio,      std.string,      std.traits,      std.typecons,      std.uni,      std.utf, +    std.zip,      std.conv : to;    import +    create_zip_file,      defaults,      output_rgx,      output_xhtmls;    void SiSUpod(T)(T doc_matters) { -    debug(asserts){ +    debug(asserts) {        // static assert(is(typeof(doc_matters) == tuple));      }      mixin SiSUoutputRgxInit;      mixin SiSUpaths; -    auto pth_sisupod = SiSUpodPaths(); +    auto pth_sisupod = SiSUpodPathsZipped(); +    auto pth_sisupod_filesystem = SiSUpodPathsFilesystemArchive();      mixin SiSUlanguageCodes;      auto lang = Lang();      auto rgx = Rgx();      assert (doc_matters.source_filename.match(rgx.src_fn));      try {        /+ create directory structure +/ -      if (!exists(pth_sisupod.doc(doc_matters.source_filename))) { -        pth_sisupod.doc(doc_matters.source_filename).mkdirRecurse; +      if (!exists(pth_sisupod_filesystem.doc(doc_matters.source_filename))) { +        pth_sisupod_filesystem.doc(doc_matters.source_filename).mkdirRecurse;        } -      if (!exists(pth_sisupod.conf(doc_matters.source_filename))) { -        pth_sisupod.conf(doc_matters.source_filename).mkdirRecurse; +      if (!exists(pth_sisupod_filesystem.conf(doc_matters.source_filename))) { +        pth_sisupod_filesystem.conf(doc_matters.source_filename).mkdirRecurse;        } -      if (!exists(pth_sisupod.css(doc_matters.source_filename))) { -        pth_sisupod.css(doc_matters.source_filename).mkdirRecurse; +      if (!exists(pth_sisupod_filesystem.css(doc_matters.source_filename))) { +        pth_sisupod_filesystem.css(doc_matters.source_filename).mkdirRecurse;        } -      if (!exists(pth_sisupod.image(doc_matters.source_filename))) { -        pth_sisupod.image(doc_matters.source_filename).mkdirRecurse; +      if (!exists(pth_sisupod_filesystem.image(doc_matters.source_filename))) { +        pth_sisupod_filesystem.image(doc_matters.source_filename).mkdirRecurse;        } -      if (!exists(pth_sisupod.doc_lng(doc_matters.source_filename, doc_matters.language))) { -        pth_sisupod.doc_lng(doc_matters.source_filename, doc_matters.language).mkdirRecurse; +      if (!exists(pth_sisupod_filesystem.doc_lng(doc_matters.source_filename, doc_matters.language))) { +        pth_sisupod_filesystem.doc_lng(doc_matters.source_filename, doc_matters.language).mkdirRecurse;        }        debug(sisupod) {          writeln(__LINE__, ": ", -          // doc_matters.environment["pwd"], "/", -            doc_matters.source_filename, " -> ", -          // doc_matters.environment["pwd"], "/", -            pth_sisupod.fn_doc( -              doc_matters.source_filename, -              doc_matters.language -        )); -      } -      if (exists(doc_matters.source_filename)) { -        copy( +          doc_matters.source_filename, " -> ", +          pth_sisupod_filesystem.fn_doc(            doc_matters.source_filename, -          pth_sisupod.fn_doc( -            doc_matters.source_filename, -            doc_matters.language +          doc_matters.language          ));        } -      if (doc_matters.file_insert_list.length > 0) { -        foreach (insert_file; doc_matters.file_insert_list) { -          debug(sisupod) { +      auto zip = new ZipArchive(); +      auto fn_sisupod = pth_sisupod.sisupod_filename(doc_matters.source_filename); +      { /+ bundle images +/ +        foreach (image; doc_matters.image_list) { +          debug(sisupodimages) {              writeln( +              "_sisu/image/", image, " -> ", +              pth_sisupod.image(doc_matters.source_filename), "/", image +            ); +          } +          auto fn_src = "_sisu/image/"~ image; +          auto fn_out =  pth_sisupod.image(doc_matters.source_filename).to!string ~ "/" ~ image; +          auto fn_out_filesystem =  pth_sisupod_filesystem.image(doc_matters.source_filename).to!string ~ "/" ~ image; +          if (exists(fn_src)) { +            fn_src.copy(fn_out_filesystem); +            { +              auto zip_arc_member_file = new ArchiveMember(); +              zip_arc_member_file.name = fn_out; +              auto zip_data = new OutBuffer(); +              zip_data.write(cast(char[]) ((fn_src).read)); +              zip_arc_member_file.expandedData = zip_data.toBytes(); +              zip.addMember(zip_arc_member_file); +              createZipFile!()(pth_sisupod.sisupod_filename(fn_src), zip.build()); +            } +          } +        } +      } +      { /+ bundle sisu_document_make +/ +        auto fn_src = "_sisu/sisu_document_make"; // check (_sisu/sisu_document_make) +        auto fn_out = pth_sisupod.conf(doc_matters.source_filename).to!string ~ "/" ~ "sisu_document_make"; +        auto fn_out_filesystem = pth_sisupod_filesystem.conf(doc_matters.source_filename).to!string ~ "/" ~ "sisu_document_make"; +        if (exists(fn_src)) { +          fn_src.copy(fn_out_filesystem); +          { +            auto zip_arc_member_file = new ArchiveMember(); +            zip_arc_member_file.name = fn_out; +            auto zip_data = new OutBuffer(); +            zip_data.write((fn_src).readText); +            zip_arc_member_file.expandedData = zip_data.toBytes(); +            zip.addMember(zip_arc_member_file); +            createZipFile!()(pth_sisupod.sisupod_filename(fn_src), zip.build()); +          } +        } +      } +      { /+ bundle primary file +/ +        auto fn_src = doc_matters.source_filename; +        auto fn_out = pth_sisupod.fn_doc(doc_matters.source_filename, doc_matters.language).to!string; +        auto fn_out_filesystem = pth_sisupod_filesystem.fn_doc(doc_matters.source_filename, doc_matters.language).to!string; +        if (exists(fn_src)) { +          fn_src.copy(fn_out_filesystem); +          { +            auto zip_arc_member_file = new ArchiveMember(); +            zip_arc_member_file.name = fn_out; +            auto zip_data = new OutBuffer(); +            zip_data.write((fn_src).readText); +            zip_arc_member_file.expandedData = zip_data.toBytes(); +            zip.addMember(zip_arc_member_file); +            createZipFile!()(pth_sisupod.sisupod_filename(fn_src), zip.build()); +          } +        } +      } +      { /+ bundle insert files +/ +        if (doc_matters.file_insert_list.length > 0) { +          foreach (insert_file; doc_matters.file_insert_list) { +            debug(sisupod) { +              writeln(                  insert_file, " -> ",                  pth_sisupod.fn_doc_insert(                    doc_matters.source_filename,                    insert_file,                    doc_matters.language -            )); -          } -          if (exists(insert_file)) { -            insert_file.copy( -              pth_sisupod.fn_doc_insert( -                doc_matters.source_filename, -                insert_file, -                doc_matters.language -            )); +              )); +            } +            auto fn_src = insert_file; +            auto fn_out = pth_sisupod.fn_doc_insert( +              doc_matters.source_filename, +              insert_file, +              doc_matters.language +            ).to!string; +            auto fn_out_filesystem = pth_sisupod_filesystem.fn_doc_insert( +              doc_matters.source_filename, +              insert_file, +              doc_matters.language +            ).to!string; +            if (exists(fn_src)) { +              fn_src.copy(fn_out_filesystem); +              { +                auto zip_arc_member_file = new ArchiveMember(); +                zip_arc_member_file.name = insert_file; +                auto zip_data = new OutBuffer(); +                zip_data.write((fn_src).readText); +                zip_arc_member_file.expandedData = zip_data.toBytes(); +                zip.addMember(zip_arc_member_file); +                createZipFile!()(pth_sisupod.sisupod_filename(fn_src), zip.build()); +              } +            }            }          }        } -      foreach (image; doc_matters.image_list) { -        debug(sisupod) { -          writeln( -              "_sisu/image/", image, " -> ", -              pth_sisupod.image(doc_matters.source_filename), "/", image -          ); +      if (exists(fn_sisupod)) { +        try { +          auto data = (cast(byte[]) (fn_sisupod).read); +          writefln("%-(%02x%) %s", data.sha256Of, fn_sisupod); +          debug(sisupod) { +            try { +              auto zipped = new ZipArchive((fn_sisupod).read); +              foreach (filename, member; zipped.directory) { +                auto data = zipped.expand(member); +                writeln("> ", filename, " length ", data.length); // filename == member.name +                // Use data +              } +            } +            catch (ZipException ex) { +              // Handle errors +            } +            if (doc_matters.source_filename == "en/the_wealth_of_networks.yochai_benkler.sst") { +              assert( +                ((data).sha256Of).toHexString +                == "DDE0013C13C6A4F06D4BE72087E2CDEF47697CA38A6A2D65BA7207DB6B144271", +                "\nsisupod: sha256 value for " +                ~ doc_matters.source_filename +                ~ " has changed, is now: " +                ~ ((data).sha256Of).toHexString +              ); +            } +            if (doc_matters.source_filename == "en/sisu_markup_stress_test.sst") { +              assert( +                ((data).sha256Of).toHexString +                == "112C0AEDD2518A1803D91A7CF5785274A3116C0779A631782D0C0813B212C68A", +                "\nsisupod: sha256 value for " +                ~ doc_matters.source_filename +                ~ " has changed, is now: " +                ~ ((data).sha256Of).toHexString +              ); +            } +          }          } -        if (exists("_sisu/image/"~ image)) { -          ("_sisu/image/"~ image).copy( -            (pth_sisupod.image(doc_matters.source_filename) ~ "/" ~ image) -          ); +          catch (ErrnoException ex) +        { +          // Handle errors          }        } | 
