diff options
Diffstat (limited to 'src/sdp/output_epub.d')
| -rw-r--r-- | src/sdp/output_epub.d | 364 | 
1 files changed, 364 insertions, 0 deletions
diff --git a/src/sdp/output_epub.d b/src/sdp/output_epub.d new file mode 100644 index 0000000..90f0ca4 --- /dev/null +++ b/src/sdp/output_epub.d @@ -0,0 +1,364 @@ +template SiSUoutputEPub() { +  struct SDPoutputEPub { +    mixin InternalMarkup; +    mixin SiSUoutputXHTMLs; +    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( +      // string[string][string]   dochead_meta, +    ) { +      // string[] toc; +      // int counter = 0; +      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; contents[sect]) { +        } +      } +      return content; +    } +    string epub_oebps_toc() { +      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; contents[sect]) { +          if (obj.is_a == "heading") { +            foreach_reverse (k; 0 .. 7) { +              switch (obj.dom_markedup[k]) { +              case DomTags.close : +                writeln(markup.indent_by_spaces_provided(k), "</", k, ">"); +    toc ~= "</navPoint>"; +                break; +              case DomTags.close_and_open : +                writeln(markup.indent_by_spaces_provided(k), "</", k, ">"); +                writeln(markup.indent_by_spaces_provided(k), "<", k, ">", obj.text); +                ++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 : +                writeln(markup.indent_by_spaces_provided(k), "<", k, ">", obj.text); +                ++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 doc_content(C,T)( +      auto ref const C         contents, +      auto ref T               doc_matters, +    ) { +      auto xhtml_format = SDPoutputXHTMLs(); +      auto rgx = Rgx(); +      // string[] toc; +      string[][string] doc_epub; +      string[] doc; +      string segment_filename; +      string[] seg_filenames; +      string[] top_level_headings = ["","","",""]; +      auto mimetypes = epub_mimetypes; +      auto meta_inf_container_xml = epub_container_xml; +      auto oebps_toc_ncx = epub_oebps_toc; +      auto oebps_content_opf = epub_oebps_content; +      foreach (part; doc_matters.keys_seq_seg) { +        foreach (obj; contents[part]) { +          if (obj.is_a == "heading") { +            switch (obj.heading_lev_markup) { +            // case 0: +            //   break; +            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: +                top_level_headings[obj.heading_lev_markup] = xhtml_format.heading(obj); +                break; +              } +              break; +            case 4: +              seg_filenames ~= obj.segment_anchor_tag; +              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) { +                // writeln(top_level_heading); +                doc_epub[segment_filename] ~= top_level_heading; +              } +              doc_epub[segment_filename] ~= xhtml_format.heading(obj); +              break; +            case 5: .. case 7: +              doc_epub[segment_filename] ~= xhtml_format.heading(obj); +              break; +            default: +              writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +              break; +            } +          } else if (obj.use == "frontmatter") { +            switch (obj.is_of) { +            case "para": +              switch (obj.is_a) { +              case "toc": +                  doc_epub[segment_filename] ~= xhtml_format.toc(obj); +              //   doc_epub ~= xhtml_toc(obj); +              break; +              default: +                // writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +                break; +              } +              break; +            default: +              // writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +              break; +            } +          } else if (obj.use == "body") { +            switch (obj.is_of) { +            case "para": +              switch (obj.is_a) { +              case "para": +                doc_epub[segment_filename] ~= xhtml_format.para(obj); +                break; +              default: +                // writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +                break; +              } +              break; +            case "block": +              switch (obj.is_a) { +              case "poem":                        // double check why both poem & verse +                break; +              case "verse": +                doc_epub[segment_filename] ~= xhtml_format.nugget(obj); +                // doc_epub ~= xhtml_verse(obj); +                break; +              case "group": +                doc_epub[segment_filename] ~= xhtml_format.nugget(obj); +                // doc_epub ~= xhtml_group(obj); +                break; +              case "block": +                doc_epub[segment_filename] ~= xhtml_format.nugget(obj); +                // doc_epub ~= xhtml_block(obj); +                break; +              case "quote": +                doc_epub[segment_filename] ~= xhtml_format.nugget(obj); +                // doc_epub ~= xhtml_quote(obj); +                break; +              case "table": +                doc_epub[segment_filename] ~= xhtml_format.para(obj); // +                // doc_epub ~= xhtml_table(obj); +                break; +              case "code": +                doc_epub[segment_filename] ~= xhtml_format.code(obj); +                break; +              default: +                writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +                break; +              } +              break; +            default: +              // writeln(__FILE__, ":", __LINE__, ": ", obj.is_of); +              break; +            } +          } else if (obj.use == "backmatter") { +            switch (obj.is_of) { +            case "para": +              switch (obj.is_a) { +              case "endnote": +                doc_epub[segment_filename] ~= xhtml_format.endnote(obj); +                break; +              case "glossary": +                doc_epub[segment_filename] ~= xhtml_format.para(obj); +                break; +              case "bibliography": +                doc_epub[segment_filename] ~= xhtml_format.para(obj); +                break; +              case "bookindex": +                doc_epub[segment_filename] ~= xhtml_format.para(obj); +                break; +              case "blurb": +                doc_epub[segment_filename] ~= xhtml_format.para(obj); +                break; +              default: +                // writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +                break; +              } +              break; +            default: +              writeln(__FILE__, ":", __LINE__, ": ", obj.is_a); +              break; +            } +          } +        } +      } +      writeln(doc_matters.keys_seq_seg); +      epub_write_output_files( +        doc_matters.source_filename, +        seg_filenames, +        doc_epub, +        mimetypes, +        meta_inf_container_xml, +        oebps_toc_ncx, +        oebps_content_opf, +      ); +    } +    void epub_write_output_files( +      string fn_src, +      string[] seg_filenames, +      string[][string] doc_epub, +      string mimetypes, +      string meta_inf_container_xml, +      string oebps_toc_ncx, +      string oebps_content_opf, +    ) { +      mixin SiSUpaths; +      auto pth_epub = EpubPaths(); +      // doc = xhtml_format.scroll_head ~ doc_epub ~  xhtml_format.tail; +      auto xhtml_format = SDPoutputXHTMLs(); +      try { +        mkdirRecurse(pth_epub.doc_meta_inf(fn_src)); +        mkdirRecurse(pth_epub.doc_oebps_css(fn_src)); +        mkdirRecurse(pth_epub.doc_oebps_image(fn_src)); +        /+ OEBPS/[segments].xhtml +/ +        foreach (seg_filename; seg_filenames) { +          auto f = File(pth_epub.fn_oebps_content_xhtml(fn_src, seg_filename), "w"); +          /+ // f.writeln(seg_head); // not needed built and inserted earlier +/ +          foreach (docseg; doc_epub[seg_filename]) { +            f.writeln(docseg); +          } +          f.writeln(xhtml_format.tail); // needed for each lev4 +        } +        /+ mimetypes +/ +        auto f = File(pth_epub.fn_mimetypes(fn_src), "w"); +        f.writeln(mimetypes); +        /+  META-INF/container.xml +/ +        f = File(pth_epub.fn_dmi_container_xml(fn_src), "w"); +        f.writeln(meta_inf_container_xml); +        /+ OEBPS/toc.ncx +/ +        f = File(pth_epub.fn_oebps_toc_ncx(fn_src), "w"); +        f.writeln(oebps_toc_ncx); +        /+ OEBPS/content.opf +/ +        f = File(pth_epub.fn_oebps_content_opf(fn_src), "w"); +        f.writeln(oebps_content_opf); +      } +      catch (ErrnoException ex) { +        // Handle error +      } +    } +     +  } +}  | 
