diff options
Diffstat (limited to 'src/sisudoc/io_out')
| -rw-r--r-- | src/sisudoc/io_out/create_zip_file.d | 9 | ||||
| -rw-r--r-- | src/sisudoc/io_out/epub3.d | 28 | ||||
| -rw-r--r-- | src/sisudoc/io_out/html.d | 30 | ||||
| -rw-r--r-- | src/sisudoc/io_out/html_snippet.d | 18 | ||||
| -rw-r--r-- | src/sisudoc/io_out/hub.d | 24 | ||||
| -rw-r--r-- | src/sisudoc/io_out/latex.d | 63 | ||||
| -rw-r--r-- | src/sisudoc/io_out/metadata.d | 24 | ||||
| -rw-r--r-- | src/sisudoc/io_out/odt.d | 54 | ||||
| -rw-r--r-- | src/sisudoc/io_out/package.d | 36 | ||||
| -rw-r--r-- | src/sisudoc/io_out/paths_output.d | 63 | ||||
| -rw-r--r-- | src/sisudoc/io_out/rgx.d | 8 | ||||
| -rw-r--r-- | src/sisudoc/io_out/skel.d | 268 | ||||
| -rw-r--r-- | src/sisudoc/io_out/source_pod.d | 92 | ||||
| -rw-r--r-- | src/sisudoc/io_out/sqlite.d | 25 | ||||
| -rw-r--r-- | src/sisudoc/io_out/text.d | 470 | ||||
| -rw-r--r-- | src/sisudoc/io_out/xmls.d | 26 |
16 files changed, 1019 insertions, 219 deletions
diff --git a/src/sisudoc/io_out/create_zip_file.d b/src/sisudoc/io_out/create_zip_file.d index e468253..7bd58bc 100644 --- a/src/sisudoc/io_out/create_zip_file.d +++ b/src/sisudoc/io_out/create_zip_file.d @@ -50,11 +50,10 @@ module sisudoc.io_out.create_zip_file; @safe: template createZipFile() { - import - std.file, - std.outbuffer, - std.string, - std.zip; + import std.file; + import std.outbuffer; + import std.string; + import std.zip; void createZipFile( string zip_file_name, void[] compressed_zip_data, diff --git a/src/sisudoc/io_out/epub3.d b/src/sisudoc/io_out/epub3.d index 610d6b8..c8ca757 100644 --- a/src/sisudoc/io_out/epub3.d +++ b/src/sisudoc/io_out/epub3.d @@ -50,19 +50,17 @@ module sisudoc.io_out.epub3; @safe: template outputEPub3() { - import - std.file, - std.outbuffer, - std.uri, - std.zip, - std.conv : to; - import - sisudoc.io_out, - sisudoc.io_out.rgx, - sisudoc.io_out.rgx_xhtml, - sisudoc.io_out.create_zip_file, - sisudoc.io_out.xmls, - sisudoc.io_out.xmls_css; + import std.file; + import std.outbuffer; + import std.uri; + import std.zip; + import std.conv : to; + import sisudoc.io_out; + import sisudoc.io_out.rgx; + import sisudoc.io_out.rgx_xhtml; + import sisudoc.io_out.create_zip_file; + import sisudoc.io_out.xmls; + import sisudoc.io_out.xmls_css; mixin InternalMarkup; mixin outputXHTMLs; static auto rgx = RgxO(); @@ -739,7 +737,7 @@ template outputEPub3() { foreach (image; doc_matters.srcs.image_list) { { /+ debug +/ if (doc_matters.opt.action.debug_do_epub) { - if (doc_matters.opt.action.vox_gt2) { + if (doc_matters.opt.action.vox_gt_3) { writeln( doc_matters.src.image_dir_path, "/", image, " -> ", pth_epub3.dbg_doc_oebps_image(doc_matters.src.filename), "/", image @@ -786,7 +784,7 @@ template outputEPub3() { } catch (ErrnoException ex) { // Handle error } - if (doc_matters.opt.action.vox_gt0) { + if (doc_matters.opt.action.vox_gt_1) { writeln(" ", fn_epub); } debug(epub_archive) { diff --git a/src/sisudoc/io_out/html.d b/src/sisudoc/io_out/html.d index 6d3129a..fc9ef54 100644 --- a/src/sisudoc/io_out/html.d +++ b/src/sisudoc/io_out/html.d @@ -50,19 +50,17 @@ module sisudoc.io_out.html; @safe: template outputHTML() { - import - std.file, - std.outbuffer, - std.uri, - std.conv : to; - import - sisudoc.io_out, - sisudoc.io_out.rgx, - sisudoc.meta.rgx_files, - sisudoc.io_out.rgx_xhtml, - sisudoc.io_out.create_zip_file, - sisudoc.io_out.xmls, - sisudoc.io_out.xmls_css; + import std.file; + import std.outbuffer; + import std.uri; + import std.conv : to; + import sisudoc.io_out; + import sisudoc.io_out.rgx; + import sisudoc.meta.rgx_files; + import sisudoc.io_out.rgx_xhtml; + import sisudoc.io_out.create_zip_file; + import sisudoc.io_out.xmls; + import sisudoc.io_out.xmls_css; mixin outputXHTMLs; void scroll(D)(D doc) { mixin spineRgxOut; @@ -264,7 +262,7 @@ template outputHTML() { } catch (ErrnoException ex) { // Handle error } - if (doc_matters.opt.action.vox_gt0) { + if (doc_matters.opt.action.vox_gt_1) { writeln(" ", pth_html.fn_scroll(doc_matters.src.filename)); } } @@ -547,7 +545,7 @@ template outputHTML() { } catch (ErrnoException ex) { // handle error } - if (doc_matters.opt.action.vox_gt0) { + if (doc_matters.opt.action.vox_gt_1) { writeln(" ", pth_html.fn_seg(doc_matters.src.filename, "toc")); } } @@ -595,7 +593,7 @@ template outputHTML() { if (exists(fn_src_in)) { fn_src_in.copy(fn_src_out); } else { - if (doc_matters.opt.action.vox_gt0) { + if (doc_matters.opt.action.vox_gt_1) { writeln("WARNING image not found: ", fn_src_in); } } diff --git a/src/sisudoc/io_out/html_snippet.d b/src/sisudoc/io_out/html_snippet.d index 9cc9259..7f1edea 100644 --- a/src/sisudoc/io_out/html_snippet.d +++ b/src/sisudoc/io_out/html_snippet.d @@ -50,16 +50,14 @@ module sisudoc.io_out.html_snippet; @safe: template htmlSnippet() { - import - std.file, - std.outbuffer, - std.format, - std.uri, - std.conv : to; - import - sisudoc.io_out.rgx, - sisudoc.meta.rgx_files, - sisudoc.io_out.rgx_xhtml; + import std.file; + import std.outbuffer; + import std.format; + import std.uri; + import std.conv : to; + import sisudoc.io_out.rgx; + import sisudoc.meta.rgx_files; + import sisudoc.io_out.rgx_xhtml; auto format_html_blank_page_guide_home()( string css_style, string home_url, diff --git a/src/sisudoc/io_out/hub.d b/src/sisudoc/io_out/hub.d index 8c41ce5..f98be01 100644 --- a/src/sisudoc/io_out/hub.d +++ b/src/sisudoc/io_out/hub.d @@ -62,7 +62,7 @@ template outputHub() { @system void outputHub(D)(D doc) { mixin Msg; auto msg = Msg!()(doc.matters); - enum outTask { source_or_pod, sqlite, sqlite_multi, latex, odt, epub, html_scroll, html_seg, html_stuff } + enum outTask { source_or_pod, sqlite, sqlite_multi, latex, odt, epub, html_scroll, html_seg, html_stuff, text, skel } void Scheduled(D)(int sched, D doc) { auto msg = Msg!()(doc.matters); if (sched == outTask.source_or_pod) { @@ -118,6 +118,12 @@ template outputHub() { outputLaTeX!()(doc.abstraction, doc.matters); msg.vv("latex done"); } + if (sched == outTask.text) { + msg.v("text processing... "); + import sisudoc.io_out.text; + outputText!()(doc.abstraction, doc.matters); + msg.vv("text done"); + } if (sched == outTask.odt) { msg.v("odf:odt processing... "); import sisudoc.io_out.odt; @@ -130,8 +136,14 @@ template outputHub() { doc.SQLiteHubDiscreteBuildTablesAndPopulate!(); msg.vv("sqlite done"); } + if (sched == outTask.skel) { + msg.v("skel processing... "); + import sisudoc.io_out.skel; + outputSkel!()(doc.abstraction, doc.matters); + msg.vv("skel done"); + } } - if (doc.matters.opt.action.vox_gt0) { writeln(doc.matters.src.filename_base); } + if (doc.matters.opt.action.vox_gt_1) { writeln(doc.matters.src.filename_base); } if (!(doc.matters.opt.action.parallelise_subprocesses)) { foreach(schedule; doc.matters.opt.action.output_task_scheduler) { Scheduled!()(schedule, doc); @@ -203,23 +215,23 @@ template outputHubOp() { sisudoc.io_out.paths_output; @system void outputHubOp(E,O,C)(E env, O opt_action, C config) { if ((opt_action.sqlite_db_drop)) { - if ((opt_action.vox_gt1)) { + if ((opt_action.vox_gt_2)) { writeln("sqlite drop db..."); } import sisudoc.io_out.sqlite; SQLiteDbDrop!()(opt_action, config); - if ((opt_action.vox_gt2)) { + if ((opt_action.vox_gt_3)) { writeln("sqlite drop db done"); } } if ((opt_action.sqlite_db_create)) { - if ((opt_action.vox_gt1)) { + if ((opt_action.vox_gt_2)) { auto pth_sqlite_db = spinePathsSQLite!()(opt_action.cgi_sqlite_search_filename, opt_action.output_dir_set); writeln("sqlite create table..."); } import sisudoc.io_out.sqlite; SQLiteTablesCreate!()(env, opt_action, config); - if ((opt_action.vox_gt2)) { + if ((opt_action.vox_gt_3)) { writeln("sqlite create table done"); } } diff --git a/src/sisudoc/io_out/latex.d b/src/sisudoc/io_out/latex.d index d26d502..96511c4 100644 --- a/src/sisudoc/io_out/latex.d +++ b/src/sisudoc/io_out/latex.d @@ -50,9 +50,8 @@ module sisudoc.io_out.latex; @safe: template paperLaTeX() { - import - std.format, - std.conv : to; + import std.format; + import std.conv : to; auto paperLaTeX() { string mm(uint mmi) { string _mm = format(q"┃%smm┃", mmi.to!string); @@ -319,15 +318,13 @@ template paperLaTeX() { } } template outputLaTeX() { - import - std.file, - std.outbuffer, - std.uri, - std.conv : to; - import - sisudoc.io_out, - sisudoc.io_out.rgx, - sisudoc.io_out.rgx_latex; + import std.file; + import std.outbuffer; + import std.uri; + import std.conv : to; + import sisudoc.io_out; + import sisudoc.io_out.rgx; + import sisudoc.io_out.rgx_latex; mixin spineRgxOut; static auto rgx = RgxO(); mixin spineRgxLSC; @@ -780,6 +777,24 @@ template outputLaTeX() { } return _txt.strip; } + string quote(O,M)( + string _txt, + O obj, + M doc_matters, + ) { + if (obj.metainfo.is_a == "quote") { + string _tex_para; + _tex_para = q"┃\ocn{%s}\objBlockOpen +"%s" +\objBlockClose +┃"; + _txt = format(_tex_para, + obj.metainfo.object_number, + _txt.nbsp_char.footnotes.split(rgx.br_linebreaks_newlines).join("\\br\n").strip + ).strip; + } + return _txt; + } string group(O,M)( string _txt, O obj, @@ -793,7 +808,7 @@ template outputLaTeX() { ┃"; _txt = format(_tex_para, obj.metainfo.object_number, - _txt.footnotes.split(rgx.br_line_spaced).join("\\brl{1}").strip // provides more control (more noise, not as tidy) + _txt.footnotes.split(rgx.br_line_spaced).join(" \\brl{1} ").strip // provides more control (more noise, not as tidy) // _txt.footnotes.split(rgx.br_line_spaced).join("") // this works using a line-space, looks tidy, keep ref. ).strip; } @@ -1210,7 +1225,9 @@ template outputLaTeX() { case "block": switch (obj.metainfo.is_a) { case "quote": - goto default; // TODO + _txt = _txt.quote(obj, doc_matters) + .links_and_images(obj, doc_matters); + goto default; case "group": /+ (hardspaces not honored) [remove any hardspace marker] +/ _txt = _txt.group(obj, doc_matters) .links_and_images(obj, doc_matters); @@ -1297,7 +1314,7 @@ template outputLaTeX() { default: { /+ debug +/ if (doc_matters.opt.action.debug_do_latex - && doc_matters.opt.action.vox_gt1) { + && doc_matters.opt.action.vox_gt_2) { writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_of_part); writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_a); writeln(__FILE__, ":", __LINE__, ": ", obj.text); @@ -1335,7 +1352,7 @@ template outputLaTeX() { try { { /+ debug +/ if (doc_matters.opt.action.debug_do_latex - && doc_matters.opt.action.vox_gt1) { + && doc_matters.opt.action.vox_gt_2) { writeln(latex_content.head); writeln(latex_content.content); writeln(latex_content.tail); @@ -1344,7 +1361,7 @@ template outputLaTeX() { if (!exists(pth_latex.latex_path_stuff)) { (pth_latex.latex_path_stuff).mkdirRecurse; } - if (doc_matters.opt.action.vox_gt0) { + if (doc_matters.opt.action.vox_gt_1) { writeln(" ", pth_latex.latex_file_with_path(paper_size_orientation)); } { @@ -1411,7 +1428,7 @@ template outputLaTeX() { string content; string tail; } - auto latex = LaTeX(); + LaTeX latex = LaTeX(); foreach (paper_size_orientation; doc_matters.conf_make_meta.conf.set_papersize) { latex.head = latex_head(doc_matters, paper_size_orientation); latex.content = latex_body(doc_abstraction, doc_matters, paper_size_orientation); @@ -1487,9 +1504,8 @@ template outputLaTeXstyInit() { } } template outputLaTeXstyStatic() { - import - std.format, - std.conv : to; + import std.format; + import std.conv : to; string outputLaTeXstyStatic( bool generated_by, string name_version_and_compiler, @@ -1730,9 +1746,8 @@ template outputLaTeXstyStatic() { } } template outputLaTeXstyPaperSizeAndOrientation() { - import - std.format, - std.conv : to; + import std.format; + import std.conv : to; auto outputLaTeXstyPaperSizeAndOrientation(P)( P doc_sty_info, bool generated_by, diff --git a/src/sisudoc/io_out/metadata.d b/src/sisudoc/io_out/metadata.d index 4d540af..a89b31a 100644 --- a/src/sisudoc/io_out/metadata.d +++ b/src/sisudoc/io_out/metadata.d @@ -109,11 +109,10 @@ template outputMetadata() { } return o; } - import - std.digest.crc, - std.digest.sha, - std.file, - std.format; + import std.digest.crc; + import std.digest.sha; + import std.file; + import std.format; import sisudoc.io_out; mixin InternalMarkup; char[] metadata_; @@ -393,7 +392,7 @@ string theme_light_1 = format(q"┃ } catch (ErrnoException ex) { // Handle error } - if (doc_matters.opt.action.vox_gt0) { writeln(" ", pth_html.fn_scroll("metadata." ~ doc_matters.src.filename)); } + if (doc_matters.opt.action.vox_gt_1) { writeln(" ", pth_html.fn_scroll("metadata." ~ doc_matters.src.filename)); } } static auto mkup = InlineMarkup(); import sisudoc.io_out.html_snippet; @@ -418,6 +417,7 @@ string theme_light_1 = format(q"┃ } auto pth_html = spinePathsHTML!()(doc_matters.output_path, doc_matters.src.language); auto pth_epub = spinePathsEPUB!()(doc_matters.output_path, doc_matters.src.language); + auto pth_text = spinePathsText!()(doc_matters); auto pth_pdf = spinePathsPDF!()(doc_matters); auto pth_pod = spinePathsPods!()(doc_matters); metadata_ ~= format(q"┃<body lang="en" xml:lang="en"> @@ -443,7 +443,7 @@ string theme_light_1 = format(q"┃ metadata_ ~= "</div>" ~ inline_search_form(doc_matters) ~ "</div><hr />"; if (!(doc_matters.conf_make_meta.meta.title_full.empty)) { metadata_ ~= "<p class=\"lev0\">Title: <b><a href=\"" ~ doc_matters.src.filename_base ~ "/toc.html\">" ~ doc_matters.conf_make_meta.meta.title_full ~ "</a></b></p>"; - } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt2) { + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt_3) { writeln("ERROR no Title information provided in document header ", doc_matters.src.filename_base); } if (!(doc_matters.conf_make_meta.meta.creator_author.empty)) { @@ -454,18 +454,18 @@ string theme_light_1 = format(q"┃ metadata_ ~= "<p class=\"lev1\">Author: <b>" ~ doc_matters.conf_make_meta.meta.creator_author ~ "</b></p>"; } - } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt2) { + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt_3) { writeln("ERROR no Author information provided in document header ", doc_matters.src.filename_base); } metadata_ ~= "<p class=\"lev1\">Published: " ~ doc_matters.conf_make_meta.meta.date_published ~ "</p>"; if (!(doc_matters.conf_make_meta.meta.rights_copyright.empty)) { metadata_ ~= "<p class=\"lev1\">Copyright: " ~ special_characters_text(doc_matters.conf_make_meta.meta.rights_copyright) ~ "</p>"; - } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt2) { + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt_3) { writeln("WARNING no Copyright information provided in document header ", doc_matters.src.filename_base); } if (!(doc_matters.conf_make_meta.meta.rights_license.empty)) { metadata_ ~= "<p class=\"lev1\">License: " ~ special_characters_text(doc_matters.conf_make_meta.meta.rights_license) ~ "</p>"; - } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt2) { + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt_3) { writeln("WARNING no License information provided in document header ", doc_matters.src.filename_base); } if (!(doc_matters.conf_make_meta.meta.notes_summary.empty)) { @@ -499,6 +499,10 @@ string theme_light_1 = format(q"┃ ~ "." ~ doc_matters.src.language ~ ".letter.portrait.pdf\" class=\"lnkicon\">" ~ " □ pdf (U.S. letter) </a>] "; } + if (doc_matters.opt.action.html_link_text) { + metadata_ ~= " [<a href=\"../" ~ "text/" ~ doc_matters.src.filename_base ~ "." ~ doc_matters.src.language ~ ".txt\" class=\"lnkicon\">" + ~ " □ txt </a>] "; + } metadata_ ~= "</p>"; if (doc_matters.opt.action.html_link_markup_source) { metadata_ ~= "<hr /><p class=\"lev1\">source: " ~ doc_matters.src.filename_base ~ "</p>"; diff --git a/src/sisudoc/io_out/odt.d b/src/sisudoc/io_out/odt.d index 8740d44..c8f5fe9 100644 --- a/src/sisudoc/io_out/odt.d +++ b/src/sisudoc/io_out/odt.d @@ -50,20 +50,17 @@ module sisudoc.io_out.odt; @safe: template formatODT() { - import - sisudoc.io_out, - sisudoc.io_out.rgx, - sisudoc.io_out.rgx_xhtml; - import - std.file, - std.outbuffer, - std.uri, - std.zip, - std.conv : to; - import - sisudoc.io_out.create_zip_file, - sisudoc.io_out.xmls, - sisudoc.io_out.xmls_css; + import sisudoc.io_out; + import sisudoc.io_out.rgx; + import sisudoc.io_out.rgx_xhtml; + import std.file; + import std.outbuffer; + import std.uri; + import std.zip; + import std.conv : to; + import sisudoc.io_out.create_zip_file; + import sisudoc.io_out.xmls; + import sisudoc.io_out.xmls_css; mixin spineRgxOut; mixin spineRgxXHTML; struct formatODT { @@ -645,20 +642,17 @@ template formatODT() { } } template outputODT() { - import - sisudoc.io_out, - sisudoc.io_out.rgx, - sisudoc.io_out.rgx_xhtml; - import - std.file, - std.outbuffer, - std.uri, - std.zip, - std.conv : to; - import - sisudoc.io_out.create_zip_file, - sisudoc.io_out.xmls, - sisudoc.io_out.xmls_css; + import sisudoc.io_out; + import sisudoc.io_out.rgx; + import sisudoc.io_out.rgx_xhtml; + import std.file; + import std.outbuffer; + import std.uri; + import std.zip; + import std.conv : to; + import sisudoc.io_out.create_zip_file; + import sisudoc.io_out.xmls; + import sisudoc.io_out.xmls_css; mixin InternalMarkup; mixin spineRgxOut; mixin spineRgxXHTML; @@ -886,7 +880,7 @@ template outputODT() { default: { /+ debug +/ if (doc_matters.opt.action.debug_do - && doc_matters.opt.action.vox_gt1) { + && doc_matters.opt.action.vox_gt_2) { writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_of_part); writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_a); writeln(__FILE__, ":", __LINE__, ": ", obj.text); @@ -2099,7 +2093,7 @@ template outputODT() { } } } - if (doc_matters.opt.action.vox_gt0) { + if (doc_matters.opt.action.vox_gt_1) { writeln(" ", pth_odt.odt_file); } } diff --git a/src/sisudoc/io_out/package.d b/src/sisudoc/io_out/package.d index 1ab72b0..7cc69ff 100644 --- a/src/sisudoc/io_out/package.d +++ b/src/sisudoc/io_out/package.d @@ -48,22 +48,20 @@ +/ module sisudoc.io_out; -public import - std.algorithm, - std.array, - std.container, - std.exception, - std.path, - std.process, - std.range, - std.regex, - std.stdio, - std.string, - std.typecons, - // std.uni, - std.utf; -public import - sisudoc.share.defaults, - sisudoc.io_in.paths_source, - sisudoc.io_out.defaults, - sisudoc.io_out.paths_output; +public import std.algorithm; +public import std.array; +public import std.container; +public import std.exception; +public import std.path; +public import std.process; +public import std.range; +public import std.regex; +public import std.stdio; +public import std.string; +public import std.typecons; +// public import std.uni; +public import std.utf; +public import sisudoc.share.defaults; +public import sisudoc.io_in.paths_source; +public import sisudoc.io_out.defaults; +public import sisudoc.io_out.paths_output; diff --git a/src/sisudoc/io_out/paths_output.d b/src/sisudoc/io_out/paths_output.d index 72508fc..c3e677d 100644 --- a/src/sisudoc/io_out/paths_output.d +++ b/src/sisudoc/io_out/paths_output.d @@ -52,13 +52,11 @@ +/ module sisudoc.io_out.paths_output; @safe: -import - std.array, - std.path, - std.regex, - std.stdio; -import - sisudoc.meta.rgx_files; +import std.array; +import std.path; +import std.regex; +import std.stdio; +import sisudoc.meta.rgx_files; template spineOutPaths() { auto spineOutPaths()( string output_pth_root, @@ -473,7 +471,7 @@ template spinePathsODT() { auto spinePathsODT(M)( M doc_matters, ) { - auto out_pth = spineOutPaths!()( doc_matters.output_path, doc_matters.src.language); + auto out_pth = spineOutPaths!()(doc_matters.output_path, doc_matters.src.language); string base_dir = "odf"; struct _PathsStruct { string base_pth() { // dir will contain odt document file (also debug file tree) @@ -670,3 +668,52 @@ template spinePathsSQLite() { return _PathsStruct(); } } + +template spinePathsText() { + import std.conv; + auto spinePathsText(M)( + M doc_matters, + ) { + auto out_pth = spineOutPaths!()(doc_matters.output_path, doc_matters.src.language); + string base_dir = "text"; + struct _PathsStruct { + string base_pth() { + return (((out_pth.output_base).chainPath(base_dir)).asNormalizedPath).array; + } + string base_filename(string fn_src) { + return fn_src.baseName.stripExtension; + } + string text_file() { + return ((base_pth.chainPath(doc_matters.src.doc_uid_out ~ ".txt")).asNormalizedPath).array; + } + string dirtop() { + return "".chainPath("").array; + } + } + return _PathsStruct(); + } +} +template spinePathsSkel() { + import std.conv; + auto spinePathsSkel(M)( + M doc_matters, + ) { + auto out_pth = spineOutPaths!()(doc_matters.output_path, doc_matters.src.language); + string base_dir = "skel"; + struct _PathsStruct { + string base_pth() { + return (((out_pth.output_base).chainPath(base_dir)).asNormalizedPath).array; + } + string base_filename(string fn_src) { + return fn_src.baseName.stripExtension; + } + string skel_file() { + return ((base_pth.chainPath(doc_matters.src.doc_uid_out ~ ".skel")).asNormalizedPath).array; + } + string dirtop() { + return "".chainPath("").array; + } + } + return _PathsStruct(); + } +} diff --git a/src/sisudoc/io_out/rgx.d b/src/sisudoc/io_out/rgx.d index 9c70c1e..f54deda 100644 --- a/src/sisudoc/io_out/rgx.d +++ b/src/sisudoc/io_out/rgx.d @@ -78,9 +78,9 @@ static template spineRgxOut() { static br_empty_line = ctRegex!(`\n[ ]*\n`, "mg"); static br_linebreaks_newlines = ctRegex!(`[\n┘┙]`, "mg"); static br_linebreaks = ctRegex!(`[┘┙]`, "mg"); - static br_line = ctRegex!(`┘`, "mg"); - static br_line_inline = ctRegex!(`┙`, "mg"); - static br_line_spaced = ctRegex!(`┚`, "mg"); + static br_line = ctRegex!(`\s*┘\s*`, "mg"); + static br_line_inline = ctRegex!(`\s*┙\s*`, "mg"); + static br_line_spaced = ctRegex!(`\s*┚\s*`, "mg"); /+ quotation marks +/ static quotes_open_and_close = ctRegex!(`[“”]`, "mg"); /+ inline markup footnotes endnotes +/ @@ -95,6 +95,7 @@ static template spineRgxOut() { static inline_al_delimiter_open_symbol_star = ctRegex!(`【[*]\s`, "m"); static inline_al_delimiter_open_symbol_plus = ctRegex!(`【[+]\s`, "m"); static inline_text_and_note_al_ = ctRegex!(`(.+?(?:【[*+]*\s+.+?】|.+))`, "mg"); + static endnote_section_note = ctRegex!(`┥\s*⑆\^┨(?P<notenumber>\d+)\.┣\^┝┤(?P<link>¤?.+?)├.+`, "mg"); /+ inline markup links +/ static inline_image = ctRegex!(`(?P<pre>┥)☼(?P<imginf>(?P<img>[a-zA-Z0-9._-]+?\.(?:jpg|gif|png)),w(?P<width>\d+)h(?P<height>\d+))\s*(?P<post>.*?┝┤.*?├)`, "mg"); static inline_image_without_dimensions = ctRegex!(`(?P<pre>┥)☼(?P<imginf>(?P<img>[a-zA-Z0-9._-]+?\.(?:jpg|gif|png)),w(?P<width>0)h(?P<height>0))\s*(?P<post>.*?┝┤.*?├)`, "mg"); @@ -109,6 +110,7 @@ static template spineRgxOut() { static inline_link_seg_and_hash = ctRegex!(`┥(?P<text>.+?)┝┤(?P<link>(?P<seg>[^/#├]*)#(?P<hash>.+?))├`, "mg"); static inline_link_clean = ctRegex!(`┤(?:.+?)├|[┥┝]`, "mg"); static inline_link_toc_to_backmatter = ctRegex!(`┤#(?P<link>endnotes|bibliography|bookindex|glossary|blurb)├`, "mg"); + static find_bookindex_ocn_link_and_comma = ctRegex!(`[, ]*┥.+?┝┤#?\S+?├`, "mg"); static url = ctRegex!(`https?://`, "mg"); static uri = ctRegex!(`(?:https?|git)://`, "mg"); static uri_identify_components = ctRegex!(`(?P<type>(?:https?|git)://)(?P<path>\S+?/)(?P<file>[^/]+)$`, "mg"); diff --git a/src/sisudoc/io_out/skel.d b/src/sisudoc/io_out/skel.d new file mode 100644 index 0000000..b616695 --- /dev/null +++ b/src/sisudoc/io_out/skel.d @@ -0,0 +1,268 @@ +/+ +- Name: SisuDoc Spine, Doc Reform [a part of] + - Description: documents, structuring, processing, publishing, search + - static content generator + + - Author: Ralph Amissah + [ralph.amissah@gmail.com] + + - Copyright: (C) 2015 - 2025 Ralph Amissah, All Rights Reserved. + + - License: AGPL 3 or later: + + Spine (SiSU), a framework for document structuring, publishing and + search + + Copyright (C) Ralph Amissah + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU AFERO General Public License as published by the + Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program. If not, see [https://www.gnu.org/licenses/]. + + If you have Internet connection, the latest version of the AGPL should be + available at these locations: + [https://www.fsf.org/licensing/licenses/agpl.html] + [https://www.gnu.org/licenses/agpl.html] + + - Spine (by Doc Reform, related to SiSU) uses standard: + - docReform markup syntax + - standard SiSU markup syntax with modified headers and minor modifications + - docReform object numbering + - standard SiSU object citation numbering & system + + - Homepages: + [https://www.sisudoc.org] + [https://www.doc-reform.org] + + - Git + [https://git.sisudoc.org/] + ++/ +module sisudoc.io_out.skel; +@safe: +template outputSkel() { + template munge() { + import std.stdio; + import std.conv; + void puts(string _obj_is) { + writeln(__FILE__, ":", __LINE__, ": ", _obj_is); + } + string newline = "\n"; + string newlines = "\n\n"; + string toc(O)(O obj) { + // puts(obj.metainfo.is_a); + // return "toc\n"; + return obj.text ~ newline; + } + string heading(O)(O obj) { + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newline ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + } + string para(O)(O obj) { + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newline ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + } + string group(O)(O obj) { + /+ + The "group" is different from the "block" mark in that "group" does not + preserve whitespace, the "block" mark does. The text falling within the + block is a single object. + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newline ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + } + string block(O)(O obj) { + /+ + The "block" is different from the "group" mark in that the "block" mark + (like the "poem" mark) preserves whitespace, the "group" mark does not. + The text falling within the "block" is a single object, which is different + from the "poem" mark where each identified verse is an object. + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newline ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + } + string poem(O)(O obj) { + /+ + The "poem" mark like the "block" preserves whitespace. Text followed by + two newlines are identified as verse and each verse is an object i.e. a + poem may consist of multiple verse each of which is identified as an + object, unlike a text "block" which is identified as a single object. + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + // return obj.text ~ newline ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + return obj.text ~ newlines; + } + string verse(O)(O obj) { + /+ + See description of poem, the poem is demarkated but the verse is the + object. + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newline ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + } + string code(O)(O obj) { + /+ + "Code" blocks are a single text object, in which the original text is + preserved. + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newline ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + } + string quote(O)(O obj) { + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newline ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + } + string table(O)(O obj) { + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newline ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + } + string endnote(O)(O obj) { + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newlines; + } + string bookindex(O)(O obj) { + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newlines; + } + string bibliography(O)(O obj) { + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newlines; + } + string glossary(O)(O obj) { + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newlines; + } + string blurb(O)(O obj) { + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newlines; + } + string comment(O)(O obj) { + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newlines; + } + } + template theDocument() { + import std.stdio; + import sisudoc.io_out; + // static auto rgx = RgxO(); + string skel_head(M)( + M doc_matters, + ) { + return "head"; + } + string skel_body(D,M)( + const D doc_abstraction, + M doc_matters, + ) { + string doc_object = ""; + foreach (section; doc_matters.has.keys_seq.scroll) { + foreach (obj; doc_abstraction[section]) { + if (obj.metainfo.is_a == "toc") { doc_object ~= munge!().toc(obj); } + if (obj.metainfo.is_a == "heading") { doc_object ~= munge!().heading(obj); } + if (obj.metainfo.is_a == "para") { doc_object ~= munge!().para(obj); } + if (obj.metainfo.is_a == "group") { doc_object ~= munge!().group(obj); } + if (obj.metainfo.is_a == "block") { doc_object ~= munge!().block(obj); } + if (obj.metainfo.is_a == "poem") { doc_object ~= munge!().poem(obj); } + if (obj.metainfo.is_a == "verse") { doc_object ~= munge!().verse(obj); } + if (obj.metainfo.is_a == "code") { doc_object ~= munge!().code(obj); } + if (obj.metainfo.is_a == "quote") { doc_object ~= munge!().quote(obj); } + if (obj.metainfo.is_a == "table") { doc_object ~= munge!().table(obj); } + if (obj.metainfo.is_a == "endnote") { doc_object ~= munge!().endnote(obj); } + if (obj.metainfo.is_a == "bookindex") { doc_object ~= munge!().bookindex(obj); } + if (obj.metainfo.is_a == "bibliography") { doc_object ~= munge!().bibliography(obj); } + if (obj.metainfo.is_a == "glossary") { doc_object ~= munge!().glossary(obj); } + if (obj.metainfo.is_a == "blurb") { doc_object ~= munge!().blurb(obj); } + if (obj.metainfo.is_a == "comment") { doc_object ~= munge!().comment(obj); } + } + } + return doc_object; + } + string skel_tail(M)( + M doc_matters, + ) { + return "tail"; + } + } + void outputSkel(D,M) ( + const D doc_abstraction, + M doc_matters, + ) { + import std.stdio; + import sisudoc.io_out; + void skel_out(D,M)( + const D doc_abstraction, + M doc_matters, + ) { + struct Skel { + string head; + string content; + string tail; + } + auto skel = Skel(); + skel.head = theDocument!().skel_head(doc_matters); + skel.content = theDocument!().skel_body(doc_abstraction, doc_matters); + skel.tail = theDocument!().skel_tail(doc_matters); + auto pth_skel = spinePathsSkel(doc_matters); + try { + import std.file; + if (!exists(pth_skel.base_pth)) { + (pth_skel.base_pth).mkdirRecurse; + } + } catch (ErrnoException ex) { + } + if (doc_matters.opt.action.vox_gt_1) { + writeln(" ", pth_skel.skel_file); + } + // writeln(pth_skel.base_pth); + auto f = File(pth_skel.skel_file, "w"); + f.writeln(skel.head); + f.writeln(skel.content); + f.writeln(skel.tail); + } + skel_out(doc_abstraction, doc_matters); + } +} diff --git a/src/sisudoc/io_out/source_pod.d b/src/sisudoc/io_out/source_pod.d index a6253ab..bfc2fac 100644 --- a/src/sisudoc/io_out/source_pod.d +++ b/src/sisudoc/io_out/source_pod.d @@ -50,18 +50,15 @@ module sisudoc.io_out.source_pod; @system: // is not @safe: use: @system: or @trusted: template spinePod() { - import - sisudoc.meta.rgx_files, - sisudoc.io_out; - import - std.digest.sha, - std.file, - std.outbuffer, - std.zip, - std.conv : to; - import - sisudoc.io_out.create_zip_file, - sisudoc.io_out.xmls; + import std.digest.sha; + import std.file; + import std.outbuffer; + import std.zip; + import std.conv : to; + import sisudoc.meta.rgx_files; + import sisudoc.io_out; + import sisudoc.io_out.create_zip_file; + import sisudoc.io_out.xmls; void spinePod(T)(T doc_matters) { debug(asserts) { // static assert(is(typeof(doc_matters) == tuple)); @@ -73,7 +70,7 @@ template spinePod() { auto lang = Lang(); static auto rgx_files = RgxFiles(); assert (doc_matters.src.filename.match(rgx_files.src_fn)); - if (doc_matters.opt.action.pod) { + if (doc_matters.opt.action.source_or_pod) { try { { podArchive_directory_tree(doc_matters, pths_pod); @@ -104,7 +101,7 @@ template spinePod() { pths_pod.pod_dir_().mkdirRecurse; } if (doc_matters.opt.action.source_or_pod) { - // if (doc_matters.opt.action.vox_gt0) { writeln(" ", pths_pod.fn_pod_filelist(doc_matters.src.filename).filesystem_open_zpod); } + // if (doc_matters.opt.action.vox_gt_1) { writeln(" ", pths_pod.fn_pod_filelist(doc_matters.src.filename).filesystem_open_zpod); } if (!exists(pths_pod.text_root(doc_matters.src.filename).filesystem_open_zpod)) { pths_pod.text_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse; } @@ -139,8 +136,8 @@ template spinePod() { } auto pod_zipMakeReady(M,P,S)(M doc_matters, P pths_pod, S _st) { auto pth_dr_doc_src = doc_matters.src_path_info; - if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt1) { - writeln(__LINE__, ": ", + if (doc_matters.opt.action.vox_gt_3) { // correct + writeln(__LINE__, ":", __FILE__, ":\n", doc_matters.src.filename, " -> ", pths_pod.fn_doc(doc_matters.src.filename, doc_matters.src.language).filesystem_open_zpod ); @@ -150,7 +147,7 @@ template spinePod() { string[string][string] _digests; { // bundle images - get digest foreach (image; doc_matters.srcs.image_list) { - debug(podimages) { + if (doc_matters.opt.action.vox_gt_3) { writeln( pth_dr_doc_src.image_root.to!string, "/", image, " -> ", pths_pod.image_root(doc_matters.src.filename).zpod, "/", image @@ -173,11 +170,11 @@ template spinePod() { if (doc_matters.opt.action.source_or_pod) { fn_src_in.copy(fn_src_out_filesystem); } - if (doc_matters.opt.action.pod) { + if (doc_matters.opt.action.source_or_pod) { zip = podArchive("file_path_bin", fn_src_in, fn_src_out_pod_zip_base, zip); } } else { - if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt1) { + if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt_2) { writeln("WARNING (io) src out NOT found (image): ", fn_src_in); } } @@ -197,11 +194,11 @@ template spinePod() { if (doc_matters.opt.action.source_or_pod) { fn_src_in.copy(fn_src_out_filesystem); } - if (doc_matters.opt.action.pod) { + if (doc_matters.opt.action.source_or_pod) { zip = podArchive("file_path_text", fn_src_in, fn_src_out_pod_zip_base, zip); } } else { - if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt1) { + if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt_2) { writeln("WARNING (io) src out NOT found (document make): ", fn_src_in); } } @@ -225,7 +222,7 @@ template spinePod() { = File(pths_pod.fn_pod_filelist(doc_matters.src.filename).filesystem_open_zpod, "w"); Node _pmy; string _pm = "doc:\n filename: " ~ doc_matters.src.filename ~ "\n language: " ~ doc_matters.pod.manifest_list_of_languages.to!string ~ "\n"; - if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt1) { + if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt_2) { try { _pmy = Loader.fromString(_pm).load(); } catch (ErrnoException ex) { @@ -242,7 +239,7 @@ template spinePod() { if (doc_matters.opt.action.source_or_pod) { pod_filelist_yaml_string.writeln(_pm); } - if (doc_matters.opt.action.pod) { + if (doc_matters.opt.action.source_or_pod) { zip = podArchive("string", _pm, fn_src_out_pod_zip_base, zip); } } @@ -262,11 +259,14 @@ template spinePod() { string fn_src_out_filesystem_lng = pths_pod.fn_doc(doc_matters.src.filename, _lang).filesystem_open_zpod.to!string; string _sstm = (doc_matters.pod.manifest_path ~ "/media/text/" ~ _lang ~ "/" ~ doc_matters.src.filename); - // writeln(_sstm); - if (exists(_sstm)) { // what of language? - debug(io) { writeln("(io debug) src in found: ", _sstm); } + string _pth_file_sstm; + if (exists(_sstm)) { _pth_file_sstm = _sstm; + } else if (exists(fn_src_in)) { _pth_file_sstm = fn_src_in; + } + if (exists(_pth_file_sstm)) { // what of language? + debug(io) { writeln("(io debug) src in found: ", _pth_file_sstm); } { // take DIGEST write to pod file digests.txt - auto data = (cast(byte[]) (_sstm).read); + auto data = (cast(byte[]) (_pth_file_sstm).read); _digests[_lang]["sstm"] ~= data.sha256Of.toHexString ~ "::" ~ data.length.to!string ~ " - " ~ doc_matters.src.filename ~ " - [" ~ _lang ~ "]"; // writeln(data.sha256Of.toHexString, "::", data.length, " - ", doc_matters.src.filename); } @@ -274,11 +274,11 @@ template spinePod() { filelist_src_zpod_arr ~= fn_src_out_inside_pod; string _pod_to_markup_file = doc_matters.src.pod_name ~ "/" ~ "media/text/" ~ _lang ~ "/" ~ doc_matters.src.filename; if (doc_matters.opt.action.source_or_pod) { - _sstm.copy(fn_src_out_filesystem_lng); + _pth_file_sstm.copy(fn_src_out_filesystem_lng); } - if (doc_matters.opt.action.pod) { + if (doc_matters.opt.action.source_or_pod) { auto _rgx_sstm = regex(r"(?P<path_to_pod>\S+?)(?P<podname>[a-z_-]+)/(?P<from_root>media/text/)(?P<language>\S+?)/(?P<filename>\S+?\.ss[mt])"); - if (auto _x = _sstm.match(_rgx_sstm)){ + if (auto _x = _pth_file_sstm.match(_rgx_sstm)){ if (doc_matters.src.lng == doc_matters.pod.manifest_list_of_languages[$-1]) { // again wait until all language versions of .ssm parsed string _path_to_pod = _x.captures["path_to_pod"]; string _podname = _x.captures["podname"]; @@ -293,12 +293,12 @@ template spinePod() { } } } else { - zip = podArchive("file_path_text", _sstm, fn_src_out_pod_zip_base, zip); + zip = podArchive("file_path_text", _pth_file_sstm, fn_src_out_pod_zip_base, zip); } } } else { - if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt1) { - writeln("WARNING (io) src in NOT found (markup source): ", _sstm); + if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt_2) { + writeln("WARNING (io) src in NOT found (markup source): \n", _sstm, "or in", fn_src_in); } } } @@ -342,11 +342,11 @@ template spinePod() { ).filesystem_open_zpod.to!string; _pth_mkup_src_in.copy(fn_src_out_filesystem); // check why here, thought dealt with elsewhere } - if (doc_matters.opt.action.pod) { + if (doc_matters.opt.action.source_or_pod) { zip = podArchive("file_path_text", _pth_mkup_src_in, _pth_mkup_src_out, zip); } } else { - if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt1) { + if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt_2) { writeln("WARNING (io) src out NOT found (insert file): ", _pth_mkup_src_in); } } @@ -376,11 +376,11 @@ template spinePod() { if (doc_matters.opt.action.source_or_pod) { fn_src_in.copy(fn_src_out_filesystem); } - if (doc_matters.opt.action.pod) { + if (doc_matters.opt.action.source_or_pod) { zip = podArchive("file_path_text", fn_src_in, fn_src_out_pod_zip_base, zip); } } else { - if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt1) { + if (doc_matters.opt.action.debug_do_pod && doc_matters.opt.action.vox_gt_2) { writeln("WARNING (io) src out NOT found (insert file): ", fn_src_in); } } @@ -446,19 +446,19 @@ template spinePod() { // Handle error } try { - // if (doc_matters.opt.action.vox_gt1) { writeln(" ", pths_pod.pod_dir_(), "/", doc_matters.src.filename_base, ".digests.txt"); } + // if (doc_matters.opt.action.vox_gt_2) { writeln(" ", pths_pod.pod_dir_(), "/", doc_matters.src.filename_base, ".digests.txt"); } string _digest_fn = pths_pod.pod_dir_() ~ "/" ~ doc_matters.src.filename_base ~ ".digests.txt"; - // if (doc_matters.opt.action.vox_gt1) { writeln(_digest_fn); } + // if (doc_matters.opt.action.vox_gt_2) { writeln(_digest_fn); } auto f = File(_digest_fn, "w"); if (exists(fn_pod)) { try { auto data = (cast(byte[]) (fn_pod).read); - // if (doc_matters.opt.action.vox_gt1) { writeln(" ", doc_matters.src.filename, " > ", doc_matters.src.filename_base, ".zip"); } + // if (doc_matters.opt.action.vox_gt_2) { writeln(" ", doc_matters.src.filename, " > ", doc_matters.src.filename_base, ".zip"); } if (doc_matters.opt.action.pod) { _zip_digest = (data.sha256Of.toHexString ~ "::" ~ data.length.to!string ~ " - " ~ doc_matters.src.filename_base ~ ".zip"); - if (doc_matters.opt.action.vox_gt0) { writeln(" ", _zip_digest); } - if (doc_matters.opt.action.vox_gt0) { writeln(" ", pths_pod.pod_dir_(), "/", doc_matters.src.filename_base, "/"); } - if (doc_matters.opt.action.vox_gt0) { writeln(" ", _digest_fn); } + if (doc_matters.opt.action.vox_gt_1) { writeln(" ", _zip_digest); } + if (doc_matters.opt.action.vox_gt_1) { writeln(" ", pths_pod.pod_dir_(), "/", doc_matters.src.filename_base, "/"); } + if (doc_matters.opt.action.vox_gt_1) { writeln(" ", _digest_fn); } f.writeln(_zip_digest); } } catch (ErrnoException ex) { @@ -468,18 +468,18 @@ template spinePod() { foreach (_lang; doc_matters.pod.manifest_list_of_languages) { if (_lang in _digests) { if (("sstm" in _digests[_lang]) && (_digests[_lang]["sstm"].length > 0)) { - // if (doc_matters.opt.action.vox_gt1) { writeln(_digests[_lang]["sstm"]); } + // if (doc_matters.opt.action.vox_gt_2) { writeln(_digests[_lang]["sstm"]); } f.writeln(_digests[_lang]["sstm"]); } if (("ssi" in _digests[_lang]) && (_digests[_lang]["ssi"].length > 0)) { - // if (doc_matters.opt.action.vox_gt1) { writeln(_digests[_lang]["ssi"]); } + // if (doc_matters.opt.action.vox_gt_2) { writeln(_digests[_lang]["ssi"]); } f.writeln(_digests[_lang]["ssi"]); } } } if ("shared" in _digests) { if (("images" in _digests["shared"]) && (_digests["shared"]["images"].length > 0)) { - // if (doc_matters.opt.action.vox_gt1) { writeln(_digests["shared"]["images"]); } + // if (doc_matters.opt.action.vox_gt_2) { writeln(_digests["shared"]["images"]); } f.writeln(_digests["shared"]["images"]); } } diff --git a/src/sisudoc/io_out/sqlite.d b/src/sisudoc/io_out/sqlite.d index 8776c9f..a62e658 100644 --- a/src/sisudoc/io_out/sqlite.d +++ b/src/sisudoc/io_out/sqlite.d @@ -48,13 +48,12 @@ +/ module sisudoc.io_out.sqlite; -import - sisudoc.io_out, - sisudoc.io_out.rgx, - sisudoc.io_out.rgx_xhtml; -import - std.file, - std.uri; +import sisudoc.io_out; +import sisudoc.io_out.rgx; +import sisudoc.io_out.rgx_xhtml; +import std.file; +import std.uri; +// import std.digest.sha; import std.conv : to; import std.typecons : Nullable; import d2sqlite3; @@ -113,7 +112,7 @@ template SQLiteHubBuildTablesAndPopulate() { _db_statement = []; } db.close; - if (doc.matters.opt.action.vox_gt0) { + if (doc.matters.opt.action.vox_gt_1) { writeln(" ", pth_sqlite.sqlite_file); } } @@ -196,7 +195,7 @@ template SQLiteHubDiscreteBuildTablesAndPopulate() { import core.runtime; core.runtime.Runtime.terminate(); } - if (doc.matters.opt.action.vox_gt0) { + if (doc.matters.opt.action.vox_gt_1) { writeln(" ", pth_sqlite.sqlite_file(doc.matters.src.filename)); } } @@ -228,7 +227,7 @@ template SQLiteDbRun() { { /+ debug +/ if (opt_action.debug_do_sqlite) { writeln(note); - if (opt_action.vox_gt2) { + if (opt_action.vox_gt_3) { writeln(db_statement); } } @@ -481,7 +480,7 @@ template SQLiteFormatAndLoadObject() { ); } } else { - if (doc_matters.opt.action.vox_gt0) { + if (doc_matters.opt.action.vox_gt_1) { writeln( "WARNING on internal document links, anchor to link <<" ~ m.captures["hash"] @@ -1659,12 +1658,12 @@ template SQLiteTablesCreate() { ? config.conf.w_srv_db_sqlite_path : ""; if (db_filename.length > 0 && db_path.length > 0) { - if (opt_action.vox_gt2) { + if (opt_action.vox_gt_3) { writeln("db name: ", db_filename); writeln("db path: ", db_path); writeln("db name & path: ", db_path, "/", db_filename); } - if (opt_action.vox_gt1) { + if (opt_action.vox_gt_2) { writeln("attempting to create db: ", db_path, "/", db_filename); } auto pth_sqlite = spinePathsSQLite!()(db_filename, db_path); diff --git a/src/sisudoc/io_out/text.d b/src/sisudoc/io_out/text.d new file mode 100644 index 0000000..9401bae --- /dev/null +++ b/src/sisudoc/io_out/text.d @@ -0,0 +1,470 @@ +/+ +- Name: SisuDoc Spine, Doc Reform [a part of] + - Description: documents, structuring, processing, publishing, search + - static content generator + + - Author: Ralph Amissah + [ralph.amissah@gmail.com] + + - Copyright: (C) 2015 - 2025 Ralph Amissah, All Rights Reserved. + + - License: AGPL 3 or later: + + Spine (SiSU), a framework for document structuring, publishing and + search + + Copyright (C) Ralph Amissah + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU AFERO General Public License as published by the + Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program. If not, see [https://www.gnu.org/licenses/]. + + If you have Internet connection, the latest version of the AGPL should be + available at these locations: + [https://www.fsf.org/licensing/licenses/agpl.html] + [https://www.gnu.org/licenses/agpl.html] + + - Spine (by Doc Reform, related to SiSU) uses standard: + - docReform markup syntax + - standard SiSU markup syntax with modified headers and minor modifications + - docReform object numbering + - standard SiSU object citation numbering & system + + - Homepages: + [https://www.sisudoc.org] + [https://www.doc-reform.org] + + - Git + [https://git.sisudoc.org/] + ++/ +module sisudoc.io_out.text; +@safe: +template outputText() { + template munge() { + import sisudoc.io_out; + import sisudoc.io_out.rgx; + import std.stdio; + import std.conv; + import std.conv : to; + import std.typecons : Nullable; + mixin spineRgxOut; + static auto rgx = RgxO(); + void puts(string _obj_is) { + writeln(__FILE__, ":", __LINE__, ": ", _obj_is); + } + string newline = "\n"; + string newlines = "\n\n"; + template special_characters_and_font_face() { + string code(string _txt){ + _txt = _txt.replaceAll(rgx.nbsp_char, " "); + return _txt; + } + string general(string _txt) { + _txt = _txt + .replaceAll(rgx.nbsp_char, " ") + .replaceAll(rgx.br_line, "\n") + .replaceAll(rgx.br_line_inline, "\n") + .replaceAll(rgx.br_line_spaced, "\n\n") + .replaceAll(rgx.inline_strike, "-{$1}-") + .replaceAll(rgx.inline_insert, "+{$1}+") + .replaceAll(rgx.inline_cite, "\"{$1}\"") + .replaceAll(rgx.inline_emphasis, "!{$1}!") + .replaceAll(rgx.inline_bold, "*{$1}*") + .replaceAll(rgx.inline_italics, "/{$1}/") + .replaceAll(rgx.inline_underscore, "_{$1}_") + .replaceAll(rgx.inline_superscript, "^{$1}^") + .replaceAll(rgx.inline_subscript, ",{$1},") + .replaceAll(rgx.inline_mono, "#{$1}#"); + return _txt; + } + string links_and_images(string _txt){ + if (_txt.match(rgx.inline_link)) { + foreach (m; _txt.matchAll(rgx.inline_link)) { + _txt = (m.captures[3] == "0") + ? _txt.replaceFirst(rgx.inline_link, (m.captures[1])) + : _txt.replaceFirst(rgx.inline_link, (m.captures[1] ~ " ≫" ~ m.captures[3])); + } + } + if (_txt.matchFirst(rgx.inline_image)) { + foreach (m; _txt.matchAll(rgx.inline_image)) { + _txt = _txt.replaceFirst(rgx.inline_image, (m.captures[3])); + } + } + return _txt; + } + } + string generalMunge(O,M)(O obj, M doc_matters) { + string _txt = obj.text; + string _notes; + string _ocn; + string general_munge; + _ocn = (obj.metainfo.ocn == 0 || doc_matters.opt.action.ocn_off) + ? "" : "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newline; + if (_txt.matchFirst(rgx.inline_notes_al_gen)) { + foreach (m; _txt.matchAll(rgx.inline_notes_al_regular_number_note)) { + _notes ~= newlines ~ m["num"] ~ ". " + ~ special_characters_and_font_face!().general(m["note"].replaceAll(rgx.inline_link, ("$1"))); + } + } + _txt = _txt.replaceAll(rgx.inline_notes_al_regular_number_note, "[$1]"); + _txt = (obj.metainfo.is_a == "code") + ? special_characters_and_font_face!().code(_txt) + : special_characters_and_font_face!().general(_txt); + _txt = special_characters_and_font_face!().links_and_images(_txt); + general_munge = (obj.metainfo.is_a == "heading") + ? newline ~ _txt ~ _notes ~ newline ~ _ocn ~ newline + : _txt ~ _notes ~ newline ~ _ocn ~ newline; + return general_munge; + } + string toc(O,M)(O obj, M doc_matters) { + // puts(obj.metainfo.is_a); + // return "toc\n"; + // _txt = _special_characters_and_font_face(obj.text); + string _txt = special_characters_and_font_face!().general(obj.text); + string _spaces; + switch (obj.attrib.indent_hang) { + case 1: _spaces = ""; + break; + case 2: _spaces = ":"; + break; + case 3: _spaces = "∴"; + break; + case 4: _spaces = " "; + break; + case 5: _spaces = " "; + break; + case 6: _spaces = " "; + break; + case 7: _spaces = " "; + break; + case 8: _spaces = " "; + break; + default: + break; + } + _txt = (doc_matters.opt.action.ocn_off) + ? _txt.replaceAll(rgx.inline_link, (_spaces ~ "$1")) + : _txt.replaceAll(rgx.inline_link, (_spaces ~ "$1 ≫ $3")); + return _txt ~ newline; + } + string heading(O,M)(O obj, M doc_matters) { + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _general_munge = generalMunge(obj,doc_matters); + return _general_munge; + } + string para(O,M)(O obj, M doc_matters) { + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _general_munge = generalMunge(obj,doc_matters); + return _general_munge; + } + string group(O,M)(O obj, M doc_matters) { + /+ + The "group" is different from the "block" mark in that "group" does not + preserve whitespace, the "block" mark does. The text falling within the + block is a single object. + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _general_munge = generalMunge(obj,doc_matters); + return _general_munge; + } + string block(O,M)(O obj, M doc_matters) { + /+ + The "block" is different from the "group" mark in that the "block" mark + (like the "poem" mark) preserves whitespace, the "group" mark does not. + The text falling within the "block" is a single object, which is different + from the "poem" mark where each identified verse is an object. + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _general_munge = generalMunge(obj,doc_matters); + return _general_munge; + } + string poem(O,M)(O obj, M doc_matters) { // LATER + /+ + The "poem" mark like the "block" preserves whitespace. Text followed by + two newlines are identified as verse and each verse is an object i.e. a + poem may consist of multiple verse each of which is identified as an + object, unlike a text "block" which is identified as a single object. + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newlines; + } + string verse(O,M)(O obj, M doc_matters) { + /+ + See description of poem, the poem is demarkated but the verse is the + object. + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _general_munge = generalMunge(obj,doc_matters); + return _general_munge; + } + string code(O,M)(O obj, M doc_matters) { + /+ + "Code" blocks are a single text object, in which the original text is + preserved. + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _general_munge = generalMunge(obj,doc_matters); + return _general_munge; + } + string quote(O,M)(O obj, M doc_matters) { // LATER + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newline ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + } + string table(O,M)(O obj, M doc_matters) { + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + auto tablarize(O)( + string _txt, + const O obj, + ) { + string[] _table_rows = (_txt).split(rgx.table_delimiter_row); + string[] _table_cols; + string _table = ""; + string _tablenote = ""; + int[] _col_width; + _col_width.length = obj.table.number_of_columns.to!ulong; + foreach(row_idx, row; _table_rows) { + _table_cols = row.split(rgx.table_delimiter_col); + _table ~= ""; + foreach(col_idx, cell; _table_cols) { + if (!((_table_cols.length == 1) + && (_table_rows.length <= row_idx+2))) { + if (_col_width[col_idx] < (cell.length.to!int)) { + _col_width[col_idx] = cell.length.to!int; + } + } + } + } + foreach(row_idx, row; _table_rows) { + _table_cols = row.split(rgx.table_delimiter_col); + foreach(col_idx, cell; _table_cols) { + if ((_table_cols.length == 1) + && (_table_rows.length <= row_idx+2)) { // check row_idx+2 (rather than == ++row_idx) + _tablenote ~= cell ~ newline; + } else { + if (obj.table.column_aligns[col_idx] == "l") { + _table ~= format(q"┃%-*s%s┃", + _col_width[col_idx], + cell, + (_table_cols.length > (col_idx + 1)) ? " ┊ " : "" + ); + } else { + _table ~= format(q"┃%*s%s┃", + _col_width[col_idx], + cell, + (_table_cols.length > (col_idx + 1)) ? " ┊ " : "" + ); + } + _table = _table + .replaceAll(regex("\\s*$"), ""); + } + } + _table ~= newline; + } + Tuple!(string, string) t = tuple( + _table, + _tablenote, + ); + return t; + } + // string _txt = obj.text; + // writeln(obj.table.column_widths); + auto _t = tablarize(obj.text, obj); + string _txt = _t[0]; + string _tablenote = _t[1]; + return _txt ~ _tablenote ~ "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newlines; + } + string endnote(O,M)(O obj, M doc_matters) { + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _ocn; + _ocn = "「" ~ obj.metainfo.ocn.to!string ~ "」"; + string _txt = obj.text; + string _parent_ocn; + _txt = _txt + .replaceAll(rgx.inline_link, ("$1")) // consider + .replaceFirst(rgx.inline_superscript, ("$1")); + _parent_ocn = (obj.metainfo.parent_ocn == 0 || doc_matters.opt.action.ocn_off) + ? "" : " ≫" ~ obj.metainfo.parent_ocn.to!string; + _txt = special_characters_and_font_face!().general(_txt) ~ _parent_ocn; + return _txt ~ newlines; + } + string bookindex(O,M)(O obj, M doc_matters) { + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _txt = obj.text; + _txt = (doc_matters.opt.action.ocn_off) + ? _txt.replaceAll(rgx.find_bookindex_ocn_link_and_comma, "") + .replaceAll(regex("\\s*\\\\"), "") + : _txt.replaceAll(rgx.inline_link, ("≫$1")) + .replaceAll(regex("\\s*\\\\"), ""); + _txt = special_characters_and_font_face!().general(_txt); + return _txt ~ newlines; + } + string bibliography(O,M)(O obj, M doc_matters) { + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _txt = obj.text; + _txt = special_characters_and_font_face!().general(_txt); + return _txt ~ newlines; + // ALT: + // string _general_munge = generalMunge(obj,doc_matters); + // return _general_munge; + } + string glossary(O,M)(O obj, M doc_matters) { + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _txt = obj.text; + _txt = special_characters_and_font_face!().general(_txt); + return _txt; + } + string blurb(O,M)(O obj, M doc_matters) { + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + string _general_munge = generalMunge(obj,doc_matters); + return _general_munge; + } + string comment(O,M)(O obj, M doc_matters) { // LATER + /+ + +/ + // puts(obj.metainfo.is_a); + // return obj.metainfo.is_a; + return obj.text ~ newlines; + } + } + template theDocument() { + import std.stdio; + import sisudoc.io_out; + string text_head(M)( + M doc_matters, + ) { + return "head"; + } + string text_body(D,M)( + const D doc_abstraction, + M doc_matters, + ) { + string doc_object = ""; + foreach (section; doc_matters.has.keys_seq.scroll) { + foreach (obj; doc_abstraction[section]) { + if (obj.metainfo.is_a == "toc") { doc_object ~= munge!().toc(obj, doc_matters); } + if (obj.metainfo.is_a == "heading") { doc_object ~= munge!().heading(obj, doc_matters); } + if (obj.metainfo.is_a == "para") { doc_object ~= munge!().para(obj, doc_matters); } + if (obj.metainfo.is_a == "group") { doc_object ~= munge!().group(obj, doc_matters); } + if (obj.metainfo.is_a == "block") { doc_object ~= munge!().block(obj, doc_matters); } + if (obj.metainfo.is_a == "poem") { doc_object ~= munge!().poem(obj, doc_matters); } // CHECK + if (obj.metainfo.is_a == "verse") { doc_object ~= munge!().verse(obj, doc_matters); } // CHECK + if (obj.metainfo.is_a == "code") { doc_object ~= munge!().code(obj, doc_matters); } + if (obj.metainfo.is_a == "quote") { doc_object ~= munge!().quote(obj, doc_matters); } // LATER + if (obj.metainfo.is_a == "table") { doc_object ~= munge!().table(obj, doc_matters); } + if (obj.metainfo.is_a == "endnote") { doc_object ~= munge!().endnote(obj, doc_matters); } + if (obj.metainfo.is_a == "bookindex") { doc_object ~= munge!().bookindex(obj, doc_matters); } // CHECK + if (obj.metainfo.is_a == "bibliography") { doc_object ~= munge!().bibliography(obj, doc_matters); } // CHECK + if (obj.metainfo.is_a == "glossary") { doc_object ~= munge!().glossary(obj, doc_matters); } // CHECK + if (obj.metainfo.is_a == "blurb") { doc_object ~= munge!().blurb(obj, doc_matters); } // CHECK + if (obj.metainfo.is_a == "comment") { doc_object ~= munge!().comment(obj, doc_matters); } // LATER + } + } + return doc_object; + } + string text_tail(M)( + M doc_matters, + ) { + string metadata_; + if (doc_matters.opt.action.debug_do) { + writeln(doc_matters.src.filename_base); + writeln("Title: ", doc_matters.conf_make_meta.meta.title_full); + writeln(" Author: ", doc_matters.conf_make_meta.meta.creator_author); + writeln(" Published: ", doc_matters.conf_make_meta.meta.date_published); + writeln(" Copyright: ", doc_matters.conf_make_meta.meta.rights_copyright); + writeln(" License: ", doc_matters.conf_make_meta.meta.rights_license); + } + if (!(doc_matters.conf_make_meta.meta.title_full.empty)) { + metadata_ ~= "Title: " ~ doc_matters.conf_make_meta.meta.title_full ~ "\n\n"; + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt_3) { + writeln("ERROR no Title information provided in document header ", doc_matters.src.filename_base); + } + if (!(doc_matters.conf_make_meta.meta.creator_author.empty)) { + if (doc_matters.opt.action.html_link_curate) { + metadata_ ~= "Author: " ~ doc_matters.conf_make_meta.meta.creator_author_surname.translate([' ' : "_"]) + ~ doc_matters.conf_make_meta.meta.creator_author ~ "\n\n"; + } else { + metadata_ ~= "Author: " + ~ doc_matters.conf_make_meta.meta.creator_author ~ "\n\n"; + } + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt_3) { + writeln("ERROR no Author information provided in document header ", doc_matters.src.filename_base); + } + metadata_ ~= "Published: " ~ doc_matters.conf_make_meta.meta.date_published ~ "\n\n"; + if (!(doc_matters.conf_make_meta.meta.rights_copyright.empty)) { + metadata_ ~= "Copyright: " ~ doc_matters.conf_make_meta.meta.rights_copyright ~ "\n\n"; + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt_3) { + writeln("WARNING no Copyright information provided in document header ", doc_matters.src.filename_base); + } + if (!(doc_matters.conf_make_meta.meta.rights_license.empty)) { + metadata_ ~= "License: " ~ doc_matters.conf_make_meta.meta.rights_license ~ "\n\n"; + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt_3) { + writeln("WARNING no License information provided in document header ", doc_matters.src.filename_base); + } + metadata_ ~= doc_matters.generator_program.project_name.strip ~ "\n"; + metadata_ ~= doc_matters.generator_program.url_home.strip; + return metadata_; + } + } + void outputText(D,M) ( + const D doc_abstraction, + M doc_matters, + ) { + import std.stdio; + import sisudoc.io_out; + void text_out(D,M)( + const D doc_abstraction, + M doc_matters, + ) { + struct Text { + string head; + string content; + string tail; + } + auto text = Text(); + // text.head = theDocument!().text_head(doc_matters); + text.content = theDocument!().text_body(doc_abstraction, doc_matters); + text.tail = theDocument!().text_tail(doc_matters); + auto pth_text = spinePathsText(doc_matters); + try { + import std.file; + if (!exists(pth_text.base_pth)) { + (pth_text.base_pth).mkdirRecurse; + } + } catch (ErrnoException ex) { + } + if (doc_matters.opt.action.vox_gt_1) { + writeln(" ", pth_text.text_file); + } + // writeln(pth_text.base_pth); + auto f = File(pth_text.text_file, "w"); + // f.writeln(text.head); + f.writeln(text.content); + f.writeln(text.tail); + } + text_out(doc_abstraction, doc_matters); + } +} diff --git a/src/sisudoc/io_out/xmls.d b/src/sisudoc/io_out/xmls.d index 7fc5e51..bf52524 100644 --- a/src/sisudoc/io_out/xmls.d +++ b/src/sisudoc/io_out/xmls.d @@ -50,19 +50,17 @@ module sisudoc.io_out.xmls; @safe: template outputXHTMLs() { - import - std.file, - std.outbuffer, - std.uri, - std.conv : to; - import - sisudoc.io_out, - sisudoc.io_out.rgx, - sisudoc.meta.rgx_files, - sisudoc.io_out.rgx_xhtml, - sisudoc.io_out.create_zip_file, - sisudoc.io_out.xmls, - sisudoc.io_out.xmls_css; + import std.file; + import std.outbuffer; + import std.uri; + import std.conv : to; + import sisudoc.io_out; + import sisudoc.io_out.rgx; + import sisudoc.meta.rgx_files; + import sisudoc.io_out.rgx_xhtml; + import sisudoc.io_out.create_zip_file; + import sisudoc.io_out.xmls; + import sisudoc.io_out.xmls_css; mixin spineRgxOut; mixin spineRgxXHTML; struct outputXHTMLs { @@ -577,7 +575,7 @@ string tail(M)(M doc_matters) { ); } } else { - if (doc_matters.opt.action.vox_gt0) { + if (doc_matters.opt.action.vox_gt_1) { writeln( "WARNING on internal document links, anchor to link <<" ~ m.captures["hash"] |
