diff options
Diffstat (limited to 'org')
| -rw-r--r-- | org/ao_debugs.org | 10 | ||||
| -rw-r--r-- | org/ao_doc_abstraction.org | 38 | ||||
| -rw-r--r-- | org/defaults.org | 218 | ||||
| -rw-r--r-- | org/output.org | 932 | ||||
| -rw-r--r-- | org/sdp.org | 8 | 
5 files changed, 902 insertions, 304 deletions
| diff --git a/org/ao_debugs.org b/org/ao_debugs.org index c35ff2e..39fdbac 100644 --- a/org/ao_debugs.org +++ b/org/ao_debugs.org @@ -301,7 +301,7 @@ debug(section_body) {  #+name: ao_output_debugs  #+BEGIN_SRC d -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]) { @@ -313,10 +313,10 @@ debug(dom) {              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; @@ -336,10 +336,10 @@ debug(dom) {              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/org/ao_doc_abstraction.org b/org/ao_doc_abstraction.org index 355c126..240b8df 100644 --- a/org/ao_doc_abstraction.org +++ b/org/ao_doc_abstraction.org @@ -14,6 +14,22 @@  [[./sdp.org][sdp]]  [[./][org/]]  * 0. the document notes +** abstraction +- abstract for downstream processing +  - identify document structure and objects +    - identify document structure (headings/levels/sections) +    - identify objects +  - set document, generate common abstraction for downstream parsing +    - set different document sections, toc, body, endnotes, book index, etc. +    - object numbers, heading/ chapter numbering etc, endnote numbers +  - unify object representations +    - multiple markups for same object type given single representation +  - extract object attributes +  - unify inline markup on objects +    - inline markup made easier to identify + +- simplify downstream parsing +  ** document sections  |--------------+--------------+---+---+--------------------------------------------------+---+---+---| @@ -1784,6 +1800,12 @@ this can be extracted earlier)  Build here:  - DOM structure  - ancestors and decendants +  - ancestors could be determined earlier, but convenient to have here +  - descendants could be in the form of: headings contained under current +    heading, and/or; the range of objects under the current heading +- you could decide on a sequential object list, containing all objects (both +  substantive and non-substantive objects), in addition to ocn, which are for +  substantive/ citable objects within the document  (as needed) up to document heading 1~, lev4 html: @@ -3126,6 +3148,22 @@ void _poem_block_(L,O,T,C,N,Ma)(  ***** table block                                                 :table: +there are 3 types of table markup that need to be nomalized (given a single representation) here + +- curly brace block +- tic block +- special notation block + +you need: +- identify the type for the munging to create uniform presentation +  - curly, tick, special +  - table heading row, bool +- present table header info in uniform way +  - table_number_of_columns, int (count) +  - table_column_widths, int[] column widths (as given or calculate average) +  - show table walls, bool +- table content marked up in uniform way +  #+name: abs_functions_block_table  #+BEGIN_SRC d  void _table_block_(L,O,T,Ma)( diff --git a/org/defaults.org b/org/defaults.org index cb4ee80..b83308d 100644 --- a/org/defaults.org +++ b/org/defaults.org @@ -911,103 +911,226 @@ private import  #+name: defaults_template_paths  #+BEGIN_SRC d  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; -  } +#+END_SRC + +**** base + +#+name: defaults_template_paths +#+BEGIN_SRC d    struct DirPaths {      string base_filename(string fn_src) { -      return _base_filename(fn_src); +      return baseName(stripExtension(fn_src));      }    } +#+END_SRC + +**** sisupod + +***** pod + +#+name: defaults_template_paths +#+BEGIN_SRC d    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; +    } +  } +#+END_SRC + +***** pod zipped + +#+name: defaults_template_paths +#+BEGIN_SRC d +  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 chainPath("sisupod", _base_filename(fn_src)).array; +      return spod_pths.base(fn_src);      } -    string doc(string fn_src) { -      return chainPath(base(fn_src), "doc").array; -      // return chainPath(base(fn_src), "text").array; +    auto doc_root(string fn_src) { +      return "doc";      } -    string doc_lng(string fn_src, string lng) { -      return chainPath(doc(fn_src), lng).array; +    auto doc(string fn_src) { +      return doc_root(fn_src);      } -    string conf(string fn_src) { -      return chainPath(doc(fn_src), "_sisu").array; +    auto doc_lng(string fn_src, string lng) { +      return doc_root(fn_src).chainPath(lng).array;      } -    string image(string fn_src) { -      return chainPath(conf(fn_src), "image").array; +    auto conf(string fn_src) { +      return doc_root(fn_src).chainPath("_sisu").array;      } -    string css(string fn_src) { -      return chainPath(conf(fn_src), "css").array; +    auto image(string fn_src) { +      return conf(fn_src).chainPath("image").array;      } -    string fn_doc(string fn_src, string lng) { -      return chainPath((doc_lng(fn_src, lng)), baseName(fn_src)).array; +    auto css(string fn_src) { +      return conf(fn_src).chainPath("css").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(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;      }    } +#+END_SRC + +***** pod unzipped archive + +#+name: defaults_template_paths +#+BEGIN_SRC d +  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 spod_pths.base(fn_src); +    } +    auto doc_root(string fn_src) { +      return base(fn_src).chainPath("doc").array; +    } +    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; +    } +  } +#+END_SRC + +**** html5 + +#+name: defaults_template_paths +#+BEGIN_SRC d    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 { +#+END_SRC + +**** epub3 + +#+name: defaults_template_paths +#+BEGIN_SRC d +  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 doc(string fn_src) { -      return chainPath(base, _base_filename(fn_src)).array; +    string epub_file(string fn_src) { +      return base.chainPath(base_filename(fn_src) ~ ".epub").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; +      }      }    }  } @@ -1072,8 +1195,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/org/output.org b/org/output.org index e84796d..a9fdc74 100644 --- a/org/output.org +++ b/org/output.org @@ -17,7 +17,7 @@  #+BEGIN_SRC d :tangle ../src/sdp/output_hub.d  /++ -  output hub<BR> +  output hub<br>    check & generate output types requested  +/  template outputHub() { @@ -38,13 +38,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) { @@ -83,10 +84,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; +/ @@ -117,27 +118,53 @@ private import    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;  #+END_SRC +** _zip_ +*** template                                                     :template: + +#+BEGIN_SRC d :tangle ../src/sdp/create_zip_file.d +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 +    } +  } +} +#+END_SRC +  ** _sisupod_                                                         :sisupod:  *** template                                                     :template: @@ -162,12 +189,13 @@ template SiSUpod() {  #+name: source_sisupod_init  #+BEGIN_SRC d -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(); @@ -177,20 +205,20 @@ assert (doc_matters.source_filename.match(rgx.src_fn));  #+name: source_sisupod_mkdirs  #+BEGIN_SRC d  /+ 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;  }  #+END_SRC @@ -200,54 +228,158 @@ if (!exists(pth_sisupod.doc_lng(doc_matters.source_filename, doc_matters.languag  #+BEGIN_SRC d  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 -    ); +#+END_SRC + +*** sha256 of sisupod.zip, zip debug, read zip archive + +#+name: source_sisupod_copy +#+BEGIN_SRC d +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    }  }  #+END_SRC @@ -279,7 +411,7 @@ string special_characters(string _txt){      .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;  }  #+END_SRC @@ -329,7 +461,7 @@ string _xhtml_anchor_tags(const(string[]) anchor_tags) {  auto scroll_head(Me)(    Me dochead_meta,  ) { -  debug(asserts){ +  debug(asserts) {      static assert(is(typeof(dochead_meta) == string[string][string]));    }    string o; @@ -337,26 +469,27 @@ auto scroll_head(Me)(  <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>¶", @@ -374,7 +507,7 @@ dochead_meta["title"]["full"],  auto seg_head(Me)(    Me dochead_meta,  ) { -  debug(asserts){ +  debug(asserts) {      static assert(is(typeof(dochead_meta) == string[string][string]));    }    string o; @@ -382,26 +515,27 @@ auto seg_head(Me)(  <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>¶", @@ -485,13 +619,13 @@ auto inline_links(O)(  #+name: xhtml_format_objects  #+BEGIN_SRC d  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) { @@ -535,7 +669,7 @@ auto inline_notes_seg(O)(          "\">",          "<note id=\"note_",          m.captures[1], -        "\"> <sup>", +        "\"> <sup>",          m.captures[1],          ".</sup></note></a>",          m.captures[2], @@ -544,7 +678,7 @@ auto inline_notes_seg(O)(      }      _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) { @@ -625,7 +759,7 @@ auto heading(O)(    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 @@ -638,7 +772,7 @@ auto heading(O)(        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 @@ -707,7 +841,7 @@ auto para(O)(    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 @@ -942,7 +1076,6 @@ auto block(O)(  </div>¶",        obj.is_a,        _txt -      // obj.text      );    } else {      o = format(q"¶  <div class="substance"> @@ -956,7 +1089,6 @@ auto block(O)(        obj.is_a,        obj.obj_cite_number,        _txt -      // obj.text      );    }    return o; @@ -1008,9 +1140,9 @@ auto verse(O)(                           // using code from code block, review  ) {    _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) { @@ -1084,8 +1216,8 @@ auto verse_seg(O)(      ) {        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"> @@ -1388,7 +1520,7 @@ void scroll_write_output(Fn,C)(    Fn fn_src,    C doc,  ) { -  debug(asserts){ +  debug(asserts) {      static assert(is(typeof(fn_src) == string));      static assert(is(typeof(doc)    == string[]));    } @@ -1636,7 +1768,7 @@ void seg_write_output(M,D,E)(    D doc_html,    E doc_html_endnotes,  ) { -  debug(asserts){ +  debug(asserts) {      static assert(is(typeof(doc_html)      == string[][string]));    }    mixin SiSUoutputRgxInit; @@ -2523,104 +2655,225 @@ auto css_write() {  #+END_SRC  *** _epub_ [#B]                                                        :epub: + +|-----------------------+--------------------------+---------------------------+----------------------------------| +| function              | filename                 | module                    | variable                         | +|-----------------------+--------------------------+---------------------------+----------------------------------| +| identify doc filetype | mimetype                 | epub3_mimetypes           | mimetypes                        | +|-----------------------+--------------------------+---------------------------+----------------------------------| +| identify doc root     | META-INF/container.xml   | epub3_container_xml       | meta_inf_container_xml           | +|-----------------------+--------------------------+---------------------------+----------------------------------| +| doc manifest          | OEBPS/content.opf        | epub3_oebps_content       | oebps_content_opf                | +|-----------------------+--------------------------+---------------------------+----------------------------------| +| doc navigation        | OEBPS/toc_nav.xhtml      | epub3_oebps_toc_nav_xhtml | oebps_toc_nav_xhtml              | +|                       | OEBPS/toc.ncx            | epub2_oebps_toc_ncx       | oebps_toc_ncx                    | +|-----------------------+--------------------------+---------------------------+----------------------------------| +| doc contents          | OEBPS/[files ... ].xhtml | outputEPub3               | doc_epub3[seg_filename]          | +|                       |                          |                           | doc_epub3_endnotes[seg_filename] | +|-----------------------+--------------------------+---------------------------+----------------------------------| +  **** template                                                   :template: -#+BEGIN_SRC d :tangle ../src/sdp/output_epub.d -template outputEPub() { +#+BEGIN_SRC d :tangle ../src/sdp/output_epub3.d +template outputEPub3() {    <<output_imports>>    mixin InternalMarkup;    mixin outputXHTMLs; -  <<output_epub_fixed>> -  <<output_epub_constructs>> -  <<output_epub_xhtml>> -  <<output_epub_xhtml_seg>> -  <<output_epub_css>> +  <<output_epub3_fixed>> +  <<output_epub3_constructs>> +  <<output_epub3_xhtml>> +  <<output_epub3_xhtml_seg>> +  <<output_epub3_css>>  }  #+END_SRC -**** epub special files                                           :format: -***** static -****** mimetype (file) +**** special (epub) files                                         :format: +***** DONE static +****** _identify doc filetype_ (mimetype) [static] + +- mimetype file indicating that zip file contains an EPUB -#+name: output_epub_fixed +#+name: output_epub3_fixed  #+BEGIN_SRC d -string epub_mimetypes() { +string epub3_mimetypes() {    string o; -  o = format(q"¶application/epub+zip¶"); +  o = format(q"¶application/epub+zip¶") ~ "\n";    return o;  }  #+END_SRC -****** META-INF/container.xml (file) +****** _identify doc root_ (META-INF/container.xml) [static] rootfile: contains document root path -#+name: output_epub_fixed +- identifies the root package document (so systems can find it), [unchanged from epub2] + +#+name: output_epub3_fixed  #+BEGIN_SRC d -string epub_container_xml() { +string epub3_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>¶"); +  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;  }  #+END_SRC -***** constructs (in OEBPS) -****** TODO OEBPS/content.opf (register content: files, images etc.) +***** constructs (in dir: OEBPS) +****** TODO _doc manifest_ (OEBPS/content.opf) manifest, register content: files, images etc. + +- manifest, listing all resources +- provides the default reading order +- identifies the navigation document -#+name: output_epub_constructs +#+name: output_epub3_constructs  #+BEGIN_SRC d -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'?> +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"> -  <opf:metadata +  <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: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 opf:scheme="URI">ox/current/en/epub/sisu_markup.epub</dc:identifier> +    <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> --> -  </opf:metadata> +  </metadata>    <manifest> -    <!-- NCX --> -    <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" /> +    <!-- 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" />¶", +      <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, -    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,    ); +  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; +} +#+END_SRC + +****** _doc navigation epub3_ (OEBPS/toc_nav.xhtml) epub3 navigable toc using Dom structure + +- toc_nav.xhtml declared as nav file in content.opf (epub3 navigation document) + +#+name: output_epub3_constructs +#+BEGIN_SRC d +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; +          } +        } +      }      }    } -  return content; +  toc ~="</nav>\n"; +  return toc;  }  #+END_SRC -****** TODO OEBPS/toc.ncx (navigable toc using Dom structure) +****** TODO _doc navigation epub2_ (OEBPS/toc.ncx) navigable toc using Dom structure -#+name: output_epub_constructs +- toc.ncx (epub2 navigation document) +  - (replaced in epub3 by a declared xhtml nav file, in our case toc_nav.xhtml) + +#+name: output_epub3_constructs  #+BEGIN_SRC d -string epub_oebps_toc(D,I)(D doc_abstraction, I doc_matters) { +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(); @@ -2698,27 +2951,24 @@ obj.segment_anchor_tag,   // lev < 4 [no link]; lev == 4 [filename] markup.xhtml  }  #+END_SRC -**** seg                                                             :seg: -***** switch (sections & objects) format epub xhtml output +**** the document contents                                           :seg: +***** switch (sections & objects) format epub3 xhtml output -#+name: output_epub_xhtml_seg +#+name: output_epub3_xhtml_seg  #+BEGIN_SRC d -void outputEPub(D,I)( +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_epub; -  string[][string] doc_epub_endnotes; +  string[][string] doc_epub3; +  string[][string] doc_epub3_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[string] oepbs_content_parts;    string suffix = ".xhtml";    foreach (part; doc_matters.keys_seq_seg) {      foreach (obj; doc_abstraction[part]) { @@ -2753,18 +3003,18 @@ void outputEPub(D,I)(            break;          case 4:            segment_filename = obj.segment_anchor_tag; -          doc_epub[segment_filename] ~= xhtml_format.seg_head(doc_matters.dochead_meta); +          doc_epub3[segment_filename] ~= xhtml_format.seg_head(doc_matters.dochead_meta);            foreach (top_level_heading; top_level_headings) { -            doc_epub[segment_filename] ~= top_level_heading; +            doc_epub3[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]; +          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_epub[segment_filename] ~= t[0]; -          doc_epub_endnotes[segment_filename] ~= t[1]; +          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"])) { @@ -2785,7 +3035,7 @@ void outputEPub(D,I)(            case "para":              switch (obj.is_a) {              case "toc": -              doc_epub[segment_filename] ~= xhtml_format.toc(obj); +              doc_epub3[segment_filename] ~= xhtml_format.toc(obj);                break;              default:                if ((doc_matters.opt_action_bool["debug"])) { @@ -2807,8 +3057,8 @@ void outputEPub(D,I)(              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]; +              doc_epub3[segment_filename] ~= t[0]; +              doc_epub3_endnotes[segment_filename] ~= t[1];                break;              default:                if ((doc_matters.opt_action_bool["debug"])) { @@ -2821,33 +3071,33 @@ void outputEPub(D,I)(              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]; +              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_epub[segment_filename] ~= to!string(t[0]); -              doc_epub_endnotes[segment_filename] ~= t[1]; +              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_epub[segment_filename] ~= to!string(t[0]); -              doc_epub_endnotes[segment_filename] ~= t[1]; +              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_epub[segment_filename] ~= to!string(t[0]); -              doc_epub_endnotes[segment_filename] ~= t[1]; +              doc_epub3[segment_filename] ~= to!string(t[0]); +              doc_epub3_endnotes[segment_filename] ~= t[1];                break;              case "code": -              doc_epub[segment_filename] ~= xhtml_format.code(obj); +              doc_epub3[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]; +              doc_epub3[segment_filename] ~= t[0]; +              doc_epub3_endnotes[segment_filename] ~= t[1];                break;              default:                if ((doc_matters.opt_action_bool["debug"])) { @@ -2869,27 +3119,27 @@ void outputEPub(D,I)(              switch (obj.is_a) {              case "endnote":                auto t = xhtml_format.para_seg(obj, suffix); -              doc_epub[segment_filename] ~= t[0]; +              doc_epub3[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]; +              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_epub[segment_filename] ~= t[0]; -              doc_epub_endnotes[segment_filename] ~= t[1]; +              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_epub[segment_filename] ~= t[0]; -              doc_epub_endnotes[segment_filename] ~= t[1]; +              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_epub[segment_filename] ~= t[0]; -              doc_epub_endnotes[segment_filename] ~= t[1]; +              doc_epub3[segment_filename] ~= t[0]; +              doc_epub3_endnotes[segment_filename] ~= t[1];                break;              default:                if ((doc_matters.opt_action_bool["debug"])) { @@ -2914,14 +3164,59 @@ void outputEPub(D,I)(            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_write_output_files( +  /+ 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_epub, -    doc_epub_endnotes, +    doc_epub3, +    doc_epub3_endnotes,      mimetypes,      meta_inf_container_xml, +    oebps_toc_nav_xhtml,      oebps_toc_ncx,      oebps_content_opf,    ); @@ -2930,71 +3225,214 @@ void outputEPub(D,I)(  **** write output files -#+name: output_epub_xhtml_seg +#+name: output_epub3_xhtml_seg  #+BEGIN_SRC d -void epub_write_output_files(M,D,E,Mt,Mic,Ot,Oc)( +void epub3_write_output_files(M,D,E,Mt,Mic,Otnx,Otn,Oc)(    M    doc_matters, -  D    doc_epub, -  E    doc_epub_endnotes, +  D    doc_epub3, +  E    doc_epub3_endnotes,    Mt   mimetypes,    Mic  meta_inf_container_xml, -  Ot   oebps_toc_ncx, +  Otnx oebps_toc_nav_xhtml, +  Otn  oebps_toc_ncx,    Oc   oebps_content_opf,  ) { -  debug(asserts){ -    static assert(is(typeof(doc_epub)               == string[][string])); +  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_epub = EpubPaths(); +  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_epub.doc_meta_inf(doc_matters.source_filename))) { -      pth_epub.doc_meta_inf(doc_matters.source_filename).mkdirRecurse; +    if (!exists(pth_epub3.doc_meta_inf(doc_matters.source_filename))) { +      pth_epub3.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_epub3.doc_oebps_css(doc_matters.source_filename))) { +      pth_epub3.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; +    if (!exists(pth_epub3.doc_oebps_image(doc_matters.source_filename))) { +      pth_epub3.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); +    { /+ 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());        } -      foreach (docseg; doc_epub_endnotes[seg_filename]) { -        f.writeln(docseg); +    } +    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);        } -      f.writeln(xhtml_format.tail); // needed for each lev4 +      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());      } -    /+ 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); +    { /+ 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    } +#+END_SRC + +*** zip debug, read zip  archive + +#+name: output_epub3_xhtml_seg +#+BEGIN_SRC d +  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 +      } +    } +  }  }  #+END_SRC diff --git a/org/sdp.org b/org/sdp.org index ff989c9..6ef3d06 100644 --- a/org/sdp.org +++ b/org/sdp.org @@ -23,7 +23,7 @@ struct Version {    int minor;    int patch;  } -enum ver = Version(0, 13, 8); +enum ver = Version(0, 13, 9);  #+END_SRC  * 1. sdp (sisu document parser)                                         :sdp: @@ -72,9 +72,9 @@ void main(string[] args) {  }  unittest {    /++ -	name        "sdp" -	description "A SiSU document parser writen in D." -	homepage    "http://sisudoc.org" +  name        "sdp" +  description "A SiSU document parser writen in D." +  homepage    "http://sisudoc.org"    +/  }  #+END_SRC | 
