From 90873fabd7451e1dd8c4b39303906e19bdc481f7 Mon Sep 17 00:00:00 2001
From: Ralph Amissah
");
+ string[] pair = pair_str.split("=");
+ canned_query[pair[0]] = pair[1];
+ }
+ // foreach (field, content; canned_query) {
+ // cgi.write(field ~ ": " ~ content ~ "
");
+ // }
+ }
+ static struct Rgx {
+ // static canned_query = ctRegex!(`\A(?P
");
+ } else if (environment.get("REQUEST_METHOD", "POST") == "GET") {
+ got.canned_query = environment.get("QUERY_STRING", "");
+ // cgi.write("f.canned_query: " ~ got.canned_query ~ "
");
+ got.search_text_area = "";
+ if ("sf" in canned_query && !(canned_query["sf"]).empty) {
+ got.text = canned_query["sf"].split("%%20").join(" ");
+ got.search_text_area ~= "text: " ~ got.text ~ "\n";
+ }
+ if ("au" in canned_query && !(canned_query["au"]).empty) {
+ got.author = canned_query["au"].split("%%20").join(" ");
+ got.search_text_area ~= "author: " ~ got.author ~ "\n";
+ }
+ if ("ti" in canned_query && !(canned_query["ti"]).empty) {
+ got.title = canned_query["ti"].split("%%20").join(" ");
+ got.search_text_area ~= "title: " ~ got.title ~ "\n";
+ }
+ if ("uid" in canned_query && !(canned_query["uid"]).empty) {
+ got.uid = canned_query["uid"].split("%%20").join(" ");
+ got.search_text_area ~= "uid: " ~ got.uid ~ "\n";
+ }
+ if ("fn" in canned_query && !(canned_query["fn"]).empty) {
+ got.fn = canned_query["fn"].split("%%20").join(" ");
+ got.search_text_area ~= "fn: " ~ got.fn ~ "\n";
+ }
+ if ("kw" in canned_query && !(canned_query["kw"]).empty) {
+ got.keywords = canned_query["kw"].split("%%20").join(" ");
+ got.search_text_area ~= "keywords: " ~ got.keywords ~ "\n";
+ }
+ if ("tr" in canned_query && !(canned_query["tr"]).empty) {
+ got.topic_register = canned_query["tr"].split("%%20").join(" ");
+ got.search_text_area ~= "topic_register: " ~ got.topic_register ~ "\n";
+ }
+ if ("su" in canned_query && !(canned_query["su"]).empty) {
+ got.subject = canned_query["su"].split("%%20").join(" ");
+ got.search_text_area ~= "subject: " ~ got.subject ~ "\n";
+ }
+ if ("de" in canned_query && !(canned_query["de"]).empty) {
+ got.description = canned_query["de"].split("%%20").join(" ");
+ got.search_text_area ~= "description: " ~ got.description ~ "\n";
+ }
+ if ("pb" in canned_query && !(canned_query["pb"]).empty) {
+ got.publisher = canned_query["pb"].split("%%20").join(" ");
+ got.search_text_area ~= "publisher: " ~ got.publisher ~ "\n";
+ }
+ if ("ed" in canned_query && !(canned_query["ed"]).empty) {
+ got.editor = canned_query["ed"].split("%%20").join(" ");
+ got.search_text_area ~= "editor: " ~ got.editor ~ "\n";
+ }
+ if ("ct" in canned_query && !(canned_query["ct"]).empty) {
+ got.contributor = canned_query["ct"].split("%%20").join(" ");
+ got.search_text_area ~= "contributor: " ~ got.contributor ~ "\n";
+ }
+ if ("dt" in canned_query && !(canned_query["dt"]).empty) {
+ got.date = canned_query["dt"].split("%%20").join(" ");
+ got.search_text_area ~= "date: " ~ got.date ~ "\n";
+ }
+ if ("rt" in canned_query && !(canned_query["rt"]).empty) {
+ got.results_type = canned_query["rt"].split("%%20").join(" ");
+ // got.search_text_area ~= "results_type: " ~ got.results_type ~ "\n";
+ }
+ if ("fmt" in canned_query && !(canned_query["fmt"]).empty) {
+ got.format = canned_query["fmt"].split("%%20").join(" ");
+ got.search_text_area ~= "format: " ~ got.format ~ "\n";
+ }
+ if ("src" in canned_query && !(canned_query["src"]).empty) {
+ got.source = canned_query["src"].split("%%20").join(" ");
+ got.search_text_area ~= "source: " ~ got.source ~ "\n";
+ }
+ if ("lng" in canned_query && !(canned_query["lng"]).empty) {
+ got.language = canned_query["lng"].split("%%20").join(" ");
+ got.search_text_area ~= "language: " ~ got.language ~ "\n";
+ }
+ if ("rl" in canned_query && !(canned_query["rl"]).empty) {
+ got.relation = canned_query["rl"].split("%%20").join(" ");
+ got.search_text_area ~= "relation: " ~ got.relation ~ "\n";
+ }
+ if ("cv" in canned_query && !(canned_query["cv"]).empty) {
+ got.coverage = canned_query["cv"].split("%%20").join(" ");
+ got.search_text_area ~= "coverage: " ~ got.coverage ~ "\n";
+ }
+ if ("rgt" in canned_query && !(canned_query["rgt"]).empty) {
+ got.rights = canned_query["rgt"].split("%%20").join(" ");
+ got.search_text_area ~= "rights: " ~ got.rights ~ "\n";
+ }
+ if ("cmt" in canned_query && !(canned_query["cmt"]).empty) {
+ got.comment = canned_query["cmt"].split("%%20").join(" ");
+ got.search_text_area ~= "comment: " ~ got.comment ~ "\n";
+ }
+ // if ("abstract" in canned_query && !(canned_query["abstract"]).empty) {
+ // got.abstract = canned_query["abstract"];
+ // }
+ if ("bfn" in canned_query && !(canned_query["bfn"]).empty) { // search_field
+ got.src_filename_base = canned_query["bfn"].split("%%20").join(" ");
+ got.search_text_area ~= "src_filename_base: " ~ got.src_filename_base ~ "\n";
+ }
+ if ("sml" in canned_query && !(canned_query["sml"]).empty) {
+ got.sql_match_limit = canned_query["sml"].split("%%20").join(" ");
+ // got.search_text_area ~= "sql_match_limit: " ~ got.sql_match_limit ~ "\n";
+ }
+ // cgi.write("f.search_text_area: " ~ got.search_text_area ~ "
");
+ }
+ return got;
+ }
+ auto tf = text_fields; //
+ struct SQL_select {
+ string the_body = "";
+ string the_range = "";
+ }
+ auto sql_select = SQL_select();
+ string canned_url () {
+ string _url = "";
+ if (environment.get("REQUEST_METHOD", "POST") == "POST") {
+ _url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ tf.canned_query;
+ } else if (environment.get("REQUEST_METHOD", "POST") == "GET") {
+ _url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ environment.get("QUERY_STRING", "");
+ }
+ return _url;
+ }
+ auto regex_canned_search () {
+ static struct RgxCS {
+ static track_offset = ctRegex!(`(?P
" ~ arrow_previous ~ arrow_next;
+ return _previous_next;
+ }
+ {
+ header = format(q"┃
+
+
+
+
+
+
+┃");
+ }
+ {
+ string post_value(string field_name, string type="box", string set="on") {
+ string val = "";
+ switch (type) {
+ case "field":
+ val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
+ ? cgi.post[field_name]
+ : (field_name in cgi.get)
+ ? cgi.get[field_name]
+ : "");
+ val = tf.search_text_area;
+ break;
+ case "box": // generic for checkbox or radio; checkbox set == "on" radio set == "name set"
+ val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
+ ? (cgi.post[field_name] == set ? "checked" : "off")
+ : (field_name in cgi.get)
+ ? (cgi.get[field_name] == set ? "checked" : "off")
+ : "off");
+ break;
+ case "radio": // used generic bo
+ val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
+ ? (cgi.post[field_name] == set ? "checked" : "off")
+ : (field_name in cgi.get)
+ ? (cgi.get[field_name] == set ? "checked" : "off")
+ : "checked");
+ break;
+ case "checkbox": // used generic bo
+ val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
+ ? (cgi.post[field_name] == set ? "checked" : "off")
+ : (field_name in cgi.get)
+ ? (cgi.get[field_name] == set ? "checked" : "off")
+ : "checked");
+ break;
+ default:
+ }
+ return val;
+ }
+ string the_can(string fv) {
+ string show_the_can = post_value("url");
+ string _the_can = "";
+ if (show_the_can == "checked") {
+ tf = text_fields;
+ string method_get_url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ environment.get("QUERY_STRING", "");
+ string method_post_url_construct = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ tf.canned_query;
+ // assert(method_get_url == environment.get("HTTP_REFERER", conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ conf.query_string));
+ if (conf.request_method == "POST") {
+ _the_can =
+ ""
+ ~ "POST: "
+ ~ ""
+ ~ method_post_url_construct
+ ~ ""
+ ~ "
+
+
+
+
+
+
+ %s
+
+
";
+ } else if (conf.request_method == "GET") {
+ _the_can =
+ ""
+ ~ "GET: "
+ ~ ""
+ ~ method_get_url
+ ~ "";
+ }
+ conf.http_url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ tf.canned_query;
+ }
+ return _the_can;
+ }
+ string provide_tip() {
+ string searched_tip = post_value("se");
+ string tip = "";
+ if (searched_tip == "checked") {
+ string search_field = post_value("sf", "field");
+ tf = text_fields;
+ tip = format(q"┃
+
+database: %%s; selected view: index
+search string: %%s %%s %%s %%s %%s %%s
+%%s %%s %%s %%s %%s %%s
+
+┃",
+ cv.db_selected,
+ (tf.text.empty ? "" : "\"text: " ~ tf.text ~ "; "),
+ (tf.title.empty ? "" : "\"title: " ~ tf.title ~ "; "),
+ (tf.author.empty ? "" : "\"author: " ~ tf.author ~ "; "),
+ (tf.date.empty ? "" : "\"date " ~ tf.date ~ "; "),
+ (tf.uid.empty ? "" : "\"uid: " ~ tf.uid ~ "; "),
+ (tf.fn.empty ? "" : "\"fn: " ~ tf.fn ~ "; "),
+ (tf.text.empty ? "" : "text: " ~ tf.text ~ "
"),
+ (tf.title.empty ? "" : "title: " ~ tf.title ~ "
"),
+ (tf.author.empty ? "" : "author: " ~ tf.author ~ "
"),
+ (tf.date.empty ? "" : "date: " ~ tf.date ~ "
"),
+ (tf.uid.empty ? "" : "\"uid: " ~ tf.uid ~ "; "),
+ (tf.fn.empty ? "" : "\"fn: " ~ tf.fn ~ "; "),
+ );
+ }
+ return tip;
+ }
+ form = format(q"┃
+
+┃",
+ "%s",
+ (post_value("ec") == "checked") ? post_value("sf", "field") : "",
+ provide_tip,
+ search_note,
+ the_can(post_value("sf", "field")),
+ cv.db_selected,
+ post_value("rt", "box", "idx"),
+ post_value("rt", "box", "txt"),
+ post_value("sml", "box", "1000"),
+ post_value("sml", "box", "2500"),
+ post_value("ec"),
+ post_value("url"),
+ post_value("se"),
+ post_value("sql"),
+ );
+ {
+ string set_value(string field_name, string default_val) {
+ string val;
+ if (field_name in cgi.post) {
+ val = cgi.post[field_name];
+ } else if (field_name in cgi.get) {
+ val = cgi.get[field_name];
+ } else { val = default_val; }
+ return val;
+ }
+ bool set_bool(string field_name) {
+ bool val;
+ if (field_name in cgi.post
+ && cgi.post[field_name] == "on") {
+ val = true;
+ } else if (field_name in cgi.get
+ && cgi.get[field_name] == "on") {
+ val = true;
+ } else { val = false; }
+ return val;
+ }
+ cv.db_selected = set_value("selected_db", "%s"); // selected_db_name == db (spine.search.db or whatever)
+ cv.sql_match_limit = set_value("sml", "1000");
+ cv.sql_match_offset = set_value("smo", "0");
+ cv.search_text = set_value("sf", "");
+ cv.results_type = set_value("rt", "idx");
+ cv.checked_echo = set_bool("ec");
+ cv.checked_stats = set_bool("sts");
+ cv.checked_url = set_bool("url");
+ cv.checked_searched = set_bool("se");
+ cv.checked_tip = set_bool("tip");
+ cv.checked_sql = set_bool("sql");
+ tf = text_fields;
+ }
+ }
+ {
+ cgi.write(header);
+ cgi.write(table);
+ cgi.write(form);
+ // cgi.write(previous_next);
+ { // debug environment
+ // foreach (k, d; environment.toAA) {
+ // cgi.write(k ~ ": " ~ d ~ "
");
+ // }
+ }
+ { // debug cgi info
+ // cgi.write("db_selected: " ~ cv.db_selected ~ "
\n");
+ // cgi.write("search_text: " ~ cv.search_text ~ "
\n");
+ // cgi.write("sql_match_limit: " ~ cv.sql_match_limit ~ ";\n");
+ // cgi.write("sql_match_offset: " ~ cv.sql_match_offset ~ ";\n");
+ // cgi.write("results_type: " ~ cv.results_type ~ "
\n");
+ // cgi.write("cv.checked_echo: " ~ (cv.checked_echo ? "checked" : "off") ~ "; \n");
+ // cgi.write("cv.checked_stats: " ~ (cv.checked_stats ? "checked" : "off") ~ "; \n");
+ // cgi.write("cv.checked_url: " ~ (cv.checked_url ? "checked" : "off") ~ "; \n");
+ // cgi.write("cv.checked_searched: " ~ (cv.checked_searched ? "checked" : "off") ~ ";
\n");
+ // cgi.write("cv.checked_tip: " ~ (cv.checked_tip ? "checked" : "off") ~ "; \n");
+ // cgi.write("cv.checked_sql: " ~ (cv.checked_sql ? "checked" : "off") ~ "
\n");
+ }
+ }
+ auto db = Database(conf.db_path ~ cv.db_selected);
+ {
+ uint sql_match_offset_counter(T)(T cv) {
+ sql_match_offset_count += cv.sql_match_limit.to!uint;
+ return sql_match_offset_count;
+ }
+ void sql_search_query() {
+ string highlight_text_matched(string _txt, string search_field) {
+ string _mark_open = "┤";
+ string _mark_close = "├";
+ string _span_match = "";
+ string _span_close = "";
+ string _sf_str = search_field.strip.split("%%20").join(" ").strip;
+ string[] _sf_arr = _sf_str.split(regex(r"\s+AND\s+|\s+OR\s+"));
+ auto rgx_url = regex(r"]+?>");
+ foreach (_sf; _sf_arr) {
+ auto rgx_matched_text = regex(_sf, "i");
+ auto rgx_marked_pair = regex(r"┤(?P
"
+ ~ sql_select.the_body.strip.split("\n ").join(" ").split("\n").join("
")
+ ~ "\n"
+ )
+ : "";
+ cgi.write(previous_next);
+ auto select_query_results = db.execute(sql_select.the_body).cached;
+ string _old_uid = "";
+ if (!select_query_results.empty) {
+ string _date_published = "0000";
+ string _close_para = "";
+ string _matched_ocn_open = "";
+ foreach (idx, row; select_query_results) {
+ if (row["uid"].as!string != _old_uid) {
+ _close_para = (idx == 1) ? "" : "
"; + _old_uid = row["uid"].as!string; + _date_published = (row["date_published"].as!string.match(regex(r"^([0-9]{4})"))) + ? row["date_published"].as!string : "0000"; // used in regex that breaks if no match + auto m = _date_published.match(regex(r"^([0-9]{4})")); + string _date = (m.hit == "0000") ? "(year?) " : "(" ~ m.hit ~ ") "; + cgi.write( + _close_para + ~ "
\"" + ~ row["title"].as!string ~ "\"" + ~ " " + ~ _date + ~ "[" ~ row["language_document_char"].as!string ~ "] " + ~ row["creator_author_last_first"].as!string + ~ " " + ~ show_matched_objects(row["src_filename_base"].as!string) + ~ "
" + ~ "\n");
+ }
+ cgi.write("
Title: " ~ doc_matters.conf_make_meta.meta.title_full ~ "
"; + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt2) { + 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 ~ "
"; + } else { + metadata_ ~= "Author: " + ~ doc_matters.conf_make_meta.meta.creator_author ~ "
"; + } + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt2) { + writeln("ERROR no Author information provided in document header ", doc_matters.src.filename_base); + } + metadata_ ~= "Published: " ~ doc_matters.conf_make_meta.meta.date_published ~ "
"; + if (!(doc_matters.conf_make_meta.meta.rights_copyright.empty)) { + metadata_ ~= "Copyright: " ~ special_characters_text(doc_matters.conf_make_meta.meta.rights_copyright) ~ "
"; + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt2) { + 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: " ~ special_characters_text(doc_matters.conf_make_meta.meta.rights_license) ~ "
"; + } else if (doc_matters.opt.action.debug_do || doc_matters.opt.action.vox_gt2) { + writeln("WARNING no License information provided in document header ", doc_matters.src.filename_base); + } + if (!(doc_matters.conf_make_meta.meta.notes_summary.empty)) { + metadata_ ~= "Summary:
" ~ special_characters_text(doc_matters.conf_make_meta.meta.notes_summary) ~ "
"; + } else if (doc_matters.opt.action.debug_do) { + writeln("WARNING no summary of text provided in document header ", doc_matters.src.filename_base); + } + metadata_ ~= "source: " ~ doc_matters.src.filename_base ~ "
"; + if (doc_matters.opt.action.html_link_markup_source) { + metadata_ ~= "● markup source: the pod [" + ~ " 🫛 zipped | " + ~ "" + ~ " 🫛 tree ] "; + } + metadata_ ~= "
● outputs: [ html: " + ~ " ▤ scroll " + ~ "|" + ~ " ※ seg ] " + ~ "[" + ~ " ◆ epub ] "; + if ((doc_matters.opt.action.html_link_pdf) || (doc_matters.opt.action.html_link_pdf_a4)) { + metadata_ ~= "[ pdf: " + ~ " □ a4  " + ~ "|" + ~ " □ U.S. letter ] "; + } else if (doc_matters.opt.action.html_link_pdf_a4) { + metadata_ ~= "[" + ~ " □ pdf (a4) ] "; + } else if (doc_matters.opt.action.html_link_pdf_letter) { + metadata_ ~= "[" + ~ " □ pdf (U.S. letter) ] "; + } + metadata_ ~= "
"; + if (doc_matters.conf_make_meta.meta.classify_topic_register_arr.length > 0) { + metadata_ ~= "Topics:
"; + string[] _top = ["", "", "", "", ""]; + foreach (topic; doc_matters.conf_make_meta.meta.classify_topic_register_arr.sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable)) { + string[] subject_tree = topic.split(mkup.sep); + if (subject_tree.length > 0) { + if (subject_tree[0] != _top[0]) { + _top[0] = subject_tree[0]; + if (doc_matters.opt.action.html_link_curate) { + metadata_ ~= + ""; + } else { + metadata_ ~= + "" ~ subject_tree[0] ~ "
"; + } + } + if (subject_tree.length > 1) { + if (subject_tree[1] != _top[1]) { + _top[1] = subject_tree[1]; + _top[2] = ""; _top[3] = ""; _top[4] = ""; + if (doc_matters.opt.action.html_link_curate) { + metadata_ ~= + ""; + } else { + metadata_ ~= + "" ~ subject_tree[1] ~ "
"; + } + } + if (subject_tree.length > 2) { + if (subject_tree[2] != _top[2]) { + _top[2] = subject_tree[2]; + _top[3] = ""; _top[4] = ""; + if (doc_matters.opt.action.html_link_curate) { + metadata_ ~= + ""; + } else { + metadata_ ~= + "" ~ subject_tree[2] ~ "
"; + } + } + if (subject_tree.length > 3) { + if (subject_tree[3] != _top[3]) { + _top[3] = subject_tree[3]; + _top[4] = ""; + if (doc_matters.opt.action.html_link_curate) { + metadata_ ~= + ""; + } else { + metadata_ ~= + "" ~ subject_tree[3] ~ "
"; + } + } + if (subject_tree.length > 4) { + if (subject_tree[4] != _top[4]) { + _top[4] = subject_tree[4]; + if (doc_matters.opt.action.html_link_curate) { + metadata_ ~= + ""; + } else { + metadata_ ~= + "" ~ subject_tree[4] ~ "
"; + } + } + } + } + } + } + } + } + } else if (doc_matters.opt.action.debug_do) { + writeln("WARNING no topic_register classification of text provided in document header ", doc_matters.src.filename_base); + } + metadata_write_output(doc_matters, metadata_); + } +} diff --git a/src/sisudoc/io_out/odt.d b/src/sisudoc/io_out/odt.d new file mode 100644 index 0000000..d6ac27d --- /dev/null +++ b/src/sisudoc/io_out/odt.d @@ -0,0 +1,2162 @@ +/+ +- 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 - 2024 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.odt; +@safe: +template formatODT() { + import + sisudoc.io_out, + sisudoc.io_out.rgx, + sisudoc.io_out.rgx_xhtml; + import + std.digest.sha, + 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; + mixin spineRgxOut; + mixin spineRgxXHTML; + struct formatODT { + static auto rgx = RgxO(); + static auto rgx_xhtml = RgxXHTML(); + string _tags(O)(const O obj) { + string _tags = ""; + if (obj.tags.anchor_tags.length > 0) { + foreach (tag_; obj.tags.anchor_tags) { + if (tag_.length > 0) { + _tags ~= format(q"┃┥)☼(?P(?P[a-zA-Z0-9._-]+?\.(?:jpg|gif|png)),w(?P \d+)h(?P \d+))\s*(?P .*?┝┤.*?├)`, "mg"); + static inline_image_without_dimensions = ctRegex!(`(?P ┥)☼(?P(?P[a-zA-Z0-9._-]+?\.(?:jpg|gif|png)),w(?P 0)h(?P 0))\s*(?P .*?┝┤.*?├)`, "mg"); + static inline_image_info = ctRegex!(`☼?(?P[a-zA-Z0-9._-]+?\.(?:jpg|gif|png)),w(?P \d+)h(?P \d+)`, "mg"); + static inline_link_anchor = ctRegex!(`┃(?P \S+?)┃`, "mg"); // TODO *~text_link_anchor + static inline_link = ctRegex!(`┥(?P .+?)┝┤(?P#?(\S+?))├`, "mg"); + static inline_link_empty = ctRegex!(`┥(?P .+?)┝┤├`, "mg"); + static inline_link_number = ctRegex!(`┥(?P .+?)┝┤(?P [0-9]+)├`, "mg"); // not used + static inline_link_number_only = ctRegex!(`(?P ┥.+?┝)┤(?P [0-9]+)├`, "mg"); + static inline_link_stow_uri = ctRegex!(`┥(?P .+?)┝┤(?P[^ 0-9#┥┝┤├][^ 0-9┥┝┤├]+)├`, "mg"); // will not stow (stowed links) or object number internal links + static inline_link_hash = ctRegex!(`┥(?P .+?)┝┤(?P#(?P \S+?))├`, "mg"); + static inline_link_seg_and_hash = ctRegex!(`┥(?P .+?)┝┤(?P(?P [^/#├]*)#(?P .+?))├`, "mg"); + static inline_link_clean = ctRegex!(`┤(?:.+?)├|[┥┝]`, "mg"); + static inline_link_toc_to_backmatter = ctRegex!(`┤#(?Pendnotes|bibliography|bookindex|glossary|blurb)├`, "mg"); + static url = ctRegex!(`https?://`, "mg"); + static uri = ctRegex!(`(?:https?|git)://`, "mg"); + static uri_identify_components = ctRegex!(`(?P (?:https?|git)://)(?P \S+?/)(?P [^/]+)$`, "mg"); + static inline_link_subtoc = ctRegex!(`^(?P [5-7])~ ┥(?P .+?)┝┤(?P.+?)├`, "mg"); + static inline_link_fn_suffix = ctRegex!(`¤(.+?)(\.fnSuffix)`, "mg"); + static inline_seg_link = ctRegex!(`(¤)(?:.+?)\.fnSuffix`, "mg"); + static mark_internal_site_lnk = ctRegex!(`¤`, "mg"); + static quotation_mark_sql_insert_delimiter = ctRegex!("[']", "mg"); + /+ inline markup font face mod +/ + static inline_emphasis = ctRegex!(`⑆[*]┨(?P .+?)┣[*]`, "mg"); + static inline_bold = ctRegex!(`⑆[!]┨(?P .+?)┣[!]`, "mg"); + static inline_underscore = ctRegex!(`⑆[_]┨(?P .+?)┣[_]`, "mg"); + static inline_italics = ctRegex!(`⑆[/]┨(?P .+?)┣[/]`, "mg"); + static inline_superscript = ctRegex!(`⑆\^┨(?P .+?)┣\^`, "mg"); + static inline_subscript = ctRegex!(`⑆[,]┨(?P .+?)┣[,]`, "mg"); + static inline_strike = ctRegex!(`⑆[-]┨(?P .+?)┣[-]`, "mg"); + static inline_insert = ctRegex!(`⑆[+]┨(?P .+?)┣[+]`, "mg"); + static inline_mono = ctRegex!(`⑆[■]┨(?P .+?)┣[■]`, "mg"); + static inline_cite = ctRegex!(`⑆[‖]┨(?P .+?)┣[‖]`, "mg"); + /+ table delimiters +/ + static table_delimiter_col = ctRegex!("[ ]*[┊][ ]*", "mg"); + static table_delimiter_row = ctRegex!("[ ]*\n", "mg"); + /+ paragraph operators +/ + static grouped_para_indent_1 = ctRegex!(`^_1[ ]`, "m"); + static grouped_para_indent_2 = ctRegex!(`^_2[ ]`, "m"); + static grouped_para_indent_3 = ctRegex!(`^_3[ ]`, "m"); + static grouped_para_indent_4 = ctRegex!(`^_4[ ]`, "m"); + static grouped_para_indent_5 = ctRegex!(`^_5[ ]`, "m"); + static grouped_para_indent_6 = ctRegex!(`^_6[ ]`, "m"); + static grouped_para_indent_7 = ctRegex!(`^_7[ ]`, "m"); + static grouped_para_indent_8 = ctRegex!(`^_8[ ]`, "m"); + static grouped_para_indent_9 = ctRegex!(`^_9[ ]`, "m"); + static grouped_para_bullet = ctRegex!(`^_[*] `, "m"); + static grouped_para_bullet_indent_1 = ctRegex!(`^_1[*] `, "m"); + static grouped_para_bullet_indent_2 = ctRegex!(`^_2[*] `, "m"); + static grouped_para_bullet_indent_3 = ctRegex!(`^_3[*] `, "m"); + static grouped_para_bullet_indent_4 = ctRegex!(`^_4[*] `, "m"); + static grouped_para_bullet_indent_5 = ctRegex!(`^_5[*] `, "m"); + static grouped_para_bullet_indent_6 = ctRegex!(`^_6[*] `, "m"); + static grouped_para_bullet_indent_7 = ctRegex!(`^_7[*] `, "m"); + static grouped_para_bullet_indent_8 = ctRegex!(`^_8[*] `, "m"); + static grouped_para_bullet_indent_9 = ctRegex!(`^_9[*] `, "m"); + static grouped_para_bullet_indent = ctRegex!(`^_(?P [1-9])[*] `, "m"); + static grouped_para_indent_hang = ctRegex!(`^_(?P [0-9])_(?P [0-9])[ ]`, "m"); + } +} diff --git a/src/sisudoc/io_out/rgx_latex.d b/src/sisudoc/io_out/rgx_latex.d new file mode 100644 index 0000000..826455c --- /dev/null +++ b/src/sisudoc/io_out/rgx_latex.d @@ -0,0 +1,68 @@ +/+ +- 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 - 2024 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/] + ++/ +/++ + regex: regular expressions used in sisu document parser ++/ +module sisudoc.io_out.rgx_latex; +@safe: +static template spineRgxLSC() { + static struct RgxLSC { + static latex_special_char = ctRegex!(`([%${}_#&\\])`); + static latex_special_char_for_escape = ctRegex!(`([%${}_#\\])`); + static latex_special_char_for_escape_and_braces = ctRegex!(`([&])`); + static latex_special_char_for_escape_url = ctRegex!(`([%])`); + static latex_special_char_escaped = ctRegex!(`\\([%${}_#\\])`); + static latex_special_char_escaped_braced = ctRegex!(`[{]\\([&])[}]`); + static latex_identify_inline_link = ctRegex!(`┥.+?┝┤\S+?├`, "mg"); + static latex_identify_inline_fontface = ctRegex!(`\\([_#$]┨.+?┣)\\([_#$])`, "mg"); + static latex_clean_internal_link = ctRegex!(`^(?:#|¤\S+?#)`, "m"); + static latex_clean_bookindex_linebreak = ctRegex!(`\s*\\\\\\\\\s*`, "m"); + } +} diff --git a/src/sisudoc/io_out/rgx_xhtml.d b/src/sisudoc/io_out/rgx_xhtml.d new file mode 100644 index 0000000..1c33b0e --- /dev/null +++ b/src/sisudoc/io_out/rgx_xhtml.d @@ -0,0 +1,63 @@ +/+ +- 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 - 2024 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/] + ++/ +/++ + regex: regular expressions used in sisu document parser ++/ +module sisudoc.io_out.rgx_xhtml; +@safe: +static template spineRgxXHTML() { + static struct RgxXHTML { + static ampersand = ctRegex!(`[&]`, "m"); // & + static quotation = ctRegex!(`["]`, "m"); // " + static less_than = ctRegex!(`[<]`, "m"); // < + static greater_than = ctRegex!(`[>]`, "m"); // > + static line_break = ctRegex!(` [\\]{2}`, "m"); //
+ } +} diff --git a/src/sisudoc/io_out/source_pod.d b/src/sisudoc/io_out/source_pod.d new file mode 100644 index 0000000..97e31af --- /dev/null +++ b/src/sisudoc/io_out/source_pod.d @@ -0,0 +1,424 @@ +/+ +- 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 - 2024 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.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; + void spinePod(T)(T doc_matters) { + debug(asserts) { + // static assert(is(typeof(doc_matters) == tuple)); + } + mixin spineRgxFiles; + string pwd = doc_matters.env.pwd; + auto src_path_info = doc_matters.src_path_info; + auto pth_dr_doc_src = doc_matters.src_path_info; + auto pths_pod = spinePathsPods!()(doc_matters); + mixin spineLanguageCodes; + auto lang = Lang(); + static auto rgx_files = RgxFiles(); + assert (doc_matters.src.filename.match(rgx_files.src_fn)); + @system auto pod_archive(Z)( + string _source_type, + string _data_in, + string _pth_out, + Z zip + ) { + auto zip_arc_member_file = new ArchiveMember(); + zip_arc_member_file.name = _pth_out; + auto zip_data = new OutBuffer(); + switch (_source_type) { + case "file_path_bin": + zip_data.write(cast(char[]) ((_data_in).read)); + goto default; + case "file_path_text": + zip_data.write((_data_in).readText); + goto default; + case "string": + zip_data.write(_data_in); + goto default; + default: + zip_arc_member_file.expandedData = zip_data.toBytes(); + zip.addMember(zip_arc_member_file); + } + return zip; + } + try { + /+ create directory structure +/ + if (!exists(pths_pod.pod_dir_())) { + // used both by pod zipped (& pod filesystem (unzipped) which makes its own recursive dirs) + 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 (!exists(pths_pod.text_root(doc_matters.src.filename).filesystem_open_zpod)) { + pths_pod.text_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse; + } + if (!exists(pths_pod.conf_root(doc_matters.src.filename).filesystem_open_zpod)) { + pths_pod.conf_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse; + } + if (!exists(pths_pod.media_root(doc_matters.src.filename).filesystem_open_zpod)) { + pths_pod.media_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse; + } + if (!exists(pths_pod.css(doc_matters.src.filename).filesystem_open_zpod)) { + pths_pod.css(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse; + } + if (!exists(pths_pod.image_root(doc_matters.src.filename).filesystem_open_zpod)) { + pths_pod.image_root(doc_matters.src.filename).filesystem_open_zpod.mkdirRecurse; + } + if (!exists(pths_pod.doc_lng(doc_matters.src.filename, doc_matters.src.language).filesystem_open_zpod)) { + pths_pod.doc_lng(doc_matters.src.filename, doc_matters.src.language).filesystem_open_zpod.mkdirRecurse; + } + } + if (!exists(pths_pod.pod_dir_() ~ "/index.html")) { + import sisudoc.io_out.html_snippet; + mixin htmlSnippet; + auto f = File(pths_pod.pod_dir_() ~"/index.html", "w"); + f.writeln(format_html_blank_page_guide_home( + "../../css/html_scroll.css", + (doc_matters.opt.action.webserver_url_doc_root.length > 0) + ? doc_matters.opt.action.webserver_url_doc_root + : doc_matters.conf_make_meta.conf.w_srv_data_root_url, + "../../index.html", + )); + } + if (doc_matters.opt.action.debug_do_pod + && doc_matters.opt.action.vox_gt1) { + writeln(__LINE__, ": ", + doc_matters.src.filename, " -> ", + pths_pod.fn_doc(doc_matters.src.filename, doc_matters.src.language).filesystem_open_zpod + ); + } + auto zip = new ZipArchive(); + auto fn_pod = pths_pod.pod_filename(doc_matters.src.filename).zpod; + { /+ bundle images +/ + foreach (image; doc_matters.srcs.image_list) { + debug(podimages) { + writeln( + pth_dr_doc_src.image_root.to!string, "/", image, " -> ", + pths_pod.image_root(doc_matters.src.filename).zpod, "/", image + ); + } + auto fn_src_in = doc_matters.src.image_dir_path ~ "/" ~ image; + auto fn_src_out_pod_zip_base + = pths_pod.image_root(doc_matters.src.filename).zpod.to!string + ~ "/" ~ image; + auto fn_src_out_filesystem + = pths_pod.image_root(doc_matters.src.filename).filesystem_open_zpod.to!string + ~ "/" ~ image; + if (exists(fn_src_in)) { + debug(io) { + writeln("(io debug) src out found: ", fn_src_in); + } + if (doc_matters.opt.action.source_or_pod) { + fn_src_in.copy(fn_src_out_filesystem); + } + if (doc_matters.opt.action.pod) { + zip = pod_archive("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) { + writeln("WARNING (io) src out NOT found (image): ", fn_src_in); + } + } + } + } { /+ bundle dr_document_make +/ + auto fn_src_in = ((doc_matters.src.is_pod) + ? doc_matters.src.conf_dir_path + : pth_dr_doc_src.conf_root).to!string + ~ "/" ~ "dr_document_make"; + auto fn_src_out_pod_zip_base + = pths_pod.conf_root(doc_matters.src.filename).zpod.to!string ~ "/" ~ "dr_document_make"; + auto fn_src_out_filesystem + = pths_pod.conf_root(doc_matters.src.filename).filesystem_open_zpod.to!string + ~ "/" ~ "dr_document_make"; + if (exists(fn_src_in)) { + debug(io) { + writeln("(io debug) src out found: ", fn_src_in); + } + if (doc_matters.opt.action.source_or_pod) { + fn_src_in.copy(fn_src_out_filesystem); + } + if (doc_matters.opt.action.pod) { + zip = pod_archive("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) { + writeln("WARNING (io) src out NOT found (document make): ", fn_src_in); + } + } + } { /+ pod manifest +/ + auto fn_src_in = doc_matters.src.file_with_absolute_path.to!string; + auto fn_src_out_pod_zip_base + = pths_pod.pod_manifest(doc_matters.src.filename).zpod.to!string; + auto fn_src_out_filesystem + = pths_pod.pod_manifest(doc_matters.src.filename).filesystem_open_zpod.to!string; // needed without root path + auto fn_src_out_inside_pod + = pths_pod.pod_manifest(doc_matters.src.filename).zpod.to!string; // needed without root path + string[] filelist_src_out_pod_arr; + string[] filelist_src_zpod_arr; + if (exists(fn_src_in)) { + debug(io) { + writeln("(io debug) src in found: ", fn_src_in); + } + filelist_src_out_pod_arr ~= fn_src_out_pod_zip_base; + filelist_src_zpod_arr ~= fn_src_out_inside_pod; + { + import dyaml; + auto pod_filelist_yaml_string + = 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) { + try { + _pmy = Loader.fromString(_pm).load(); + } catch (ErrnoException ex) { + } catch (Throwable) { + writeln("ERROR failed to read config file content, not parsed as yaml"); + } + writeln("pod filename: ", _pmy["doc"]["filename"].get!string); + writeln("pod languages: ", doc_matters.pod.manifest_list_of_languages.to!string); + writeln("pod languages: ", doc_matters.src.language); + // foreach(string _l; _pmy["doc"]["language"]) { + // writeln("language: ", _l); + // } + } + if (doc_matters.opt.action.source_or_pod) { + pod_filelist_yaml_string.writeln(_pm); + } + if (doc_matters.opt.action.pod) { + zip = pod_archive("string", _pm, fn_src_out_pod_zip_base, zip); + } + } + } + } { /+ bundle primary file (.ssm/.sst) +/ + auto fn_src_in = doc_matters.src.file_with_absolute_path.to!string; + auto fn_src_out_pod_zip_base + = pths_pod.fn_doc(doc_matters.src.filename, doc_matters.src.language).zpod.to!string; + auto fn_src_out_filesystem + = pths_pod.fn_doc(doc_matters.src.filename, doc_matters.src.language).filesystem_open_zpod.to!string; // needed without root path: + auto fn_src_out_inside_pod + = pths_pod.fn_doc(doc_matters.src.filename, doc_matters.src.language).zpod.to!string; // needed without root path: + string[] filelist_src_out_pod_arr; + string[] filelist_src_zpod_arr; + if (exists(fn_src_in)) { + debug(io) { + writeln("(io debug) src in found: ", fn_src_in); + } + filelist_src_out_pod_arr ~= fn_src_out_pod_zip_base; + filelist_src_zpod_arr ~= fn_src_out_inside_pod; + string _pod_to_markup_file = doc_matters.src.pod_name ~ "/" ~ "media/text/" ~ doc_matters.src.language ~ "/" ~ doc_matters.src.filename; + if (doc_matters.opt.action.source_or_pod) { + fn_src_in.copy(fn_src_out_filesystem); + } + if (doc_matters.opt.action.pod) { + auto _rgx = regex(r"(?P\S+?)(?P [a-z_-]+)/(?P media/text/)(?P \S+?)/(?P \S+?\.ss[mt])"); + if (auto _x = fn_src_in.match(_rgx)){ + if (doc_matters.src.lng == doc_matters.pod.manifest_list_of_languages[$-1]) { + string _path_to_pod = _x.captures["path_to_pod"]; + string _podname = _x.captures["podname"]; + string _root_to_lang = _x.captures["from_root"]; + string _language = _x.captures["language"]; + string _filename = _x.captures["filename"]; + foreach (_lang; doc_matters.pod.manifest_list_of_languages) { + string _pth_mkup_src_in = _path_to_pod ~ _podname ~ "/" ~ _root_to_lang ~ _lang ~ "/" ~ _filename; + string _pth_mkup_src_out = "pod/" ~ _root_to_lang ~ _lang ~ "/" ~ _filename; + zip = pod_archive("file_path_text", _pth_mkup_src_in, _pth_mkup_src_out, zip); + } + } + } else { + zip = pod_archive("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) { + writeln("WARNING (io) src in NOT found (markup source): ", fn_src_in); + } + } + } { /+ bundle insert files (.ssi) +/ + if (doc_matters.srcs.file_insert_list.length > 0) { + auto _rgx = regex(r"(?P \S+?)(?P [a-z_-]+)/(?P media/text/)(?P \S+?)/(?P \S+?\.ss[i])"); + foreach (insert_file; doc_matters.srcs.file_insert_list) { + debug(pod) { + writeln( + insert_file, " -> ", + pths_pod.fn_doc_insert( + doc_matters.src.filename, + insert_file, + doc_matters.src.language, + ).zpod + ); + } + if (auto _x = insert_file.match(_rgx)){ + if (doc_matters.src.lng == doc_matters.pod.manifest_list_of_languages[$-1]) { + string _path_to_pod = _x.captures["path_to_pod"]; + string _podname = _x.captures["podname"]; + string _root_to_lang = _x.captures["from_root"]; + string _language = _x.captures["language"]; + string _filename = _x.captures["filename"]; + foreach (_lang; doc_matters.pod.manifest_list_of_languages) { + string _pth_mkup_src_in = _path_to_pod ~ _podname ~ "/" ~ _root_to_lang ~ _lang ~ "/" ~ _filename; + string _pth_mkup_src_out = "pod/" ~ _root_to_lang ~ _lang ~ "/" ~ _filename; + if (exists(_pth_mkup_src_in)) { + if (doc_matters.opt.action.source_or_pod) { + auto fn_src_out_filesystem // you need to change language sources + = pths_pod.fn_doc_insert( + doc_matters.src.filename, // doc_matters.src.filename + _pth_mkup_src_in, // insert_file + _lang, + ).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) { + zip = pod_archive("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) { + writeln("WARNING (io) src out NOT found (insert file): ", _pth_mkup_src_in); + } + } + } + } + } else { + auto fn_src_in = insert_file; + auto fn_src_out_pod_zip_base + = pths_pod.fn_doc_insert( + doc_matters.src.filename, + insert_file, + doc_matters.src.language, + ).zpod.to!string; + auto fn_src_out_filesystem + = pths_pod.fn_doc_insert( + doc_matters.src.filename, + insert_file, + doc_matters.src.language, + ).filesystem_open_zpod.to!string; + if (exists(fn_src_in)) { + debug(io) { + writeln("(io debug) src out found: ", fn_src_in); + } + if (doc_matters.opt.action.source_or_pod) { + fn_src_in.copy(fn_src_out_filesystem); + } + if (doc_matters.opt.action.pod) { + zip = pod_archive("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) { + writeln("WARNING (io) src out NOT found (insert file): ", fn_src_in); + } + } + } + } + } + } { + auto fn_src_in = doc_matters.src.filename; + if (doc_matters.opt.action.pod) { + if (exists(doc_matters.src.file_with_absolute_path)) { + createZipFile!()(fn_pod, zip.build()); + } else { + writeln("WARNING check missing source file(s): ", doc_matters.opt.action.pod); + } + if (!(exists(fn_pod))) { + writeln("WARNING failed to create pod zip archive: ", fn_pod); + } + } + } + if (exists(fn_pod)) { + try { + if (doc_matters.opt.action.vox_gt0 + && doc_matters.opt.action.pod) { + auto data = (cast(byte[]) (fn_pod).read); + if (doc_matters.opt.action.vox_gt1) { + writeln(" ", doc_matters.src.filename, " > "); + } + if (doc_matters.opt.action.pod) { + writefln("%s\n. %-(%02x%)::%s . %s.zip", fn_pod, data.sha256Of, data.length, doc_matters.src.filename_base); + } + } + if (doc_matters.opt.action.debug_do_pod) { + try { + auto zipped = new ZipArchive((fn_pod).read); + foreach (filename, member; zipped.directory) { + auto data = zipped.expand(member); + writeln(". ", ((data).sha256Of).toHexString, "::", data.length, " . ", filename); + } + } catch (ZipException ex) { + // Handle errors + } + } + } catch (ErrnoException ex) { + // Handle errors + } + } + // source pod zip + } catch (ErrnoException ex) { + // Handle error + } + } +} diff --git a/src/sisudoc/io_out/sqlite.d b/src/sisudoc/io_out/sqlite.d new file mode 100644 index 0000000..bee9cad --- /dev/null +++ b/src/sisudoc/io_out/sqlite.d @@ -0,0 +1,1761 @@ +/+ +- 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 - 2024 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.sqlite; +import + sisudoc.io_out, + sisudoc.io_out.rgx, + sisudoc.io_out.rgx_xhtml; +import + std.file, + std.uri; +import std.conv : to; +import std.typecons : Nullable; +import d2sqlite3; +mixin spineRgxOut; +mixin spineRgxXHTML; +mixin InternalMarkup; +static auto rgx = RgxO(); +static auto rgx_xhtml = RgxXHTML(); +static auto mkup = InlineMarkup(); +long _metadata_tid_lastrowid; +template SQLiteHubBuildTablesAndPopulate() { + void SQLiteHubBuildTablesAndPopulate(D,M)( + const D doc_abstraction, + M doc_matters, + ) { + auto pth_sqlite = spinePathsSQLite!()(doc_matters.sqlite.filename, doc_matters.sqlite.path); + if ((isValidPath(pth_sqlite.base) && exists(pth_sqlite.base) != 0 && pth_sqlite.base.isDir)) { + } else { + try { + pth_sqlite.base.mkdirRecurse; + } catch (FileException ex) { } + } + template SQLiteDbStatementComposite() { + void SQLiteDbStatementComposite(Db,D,M)( + Db db, + const D doc_abstraction, + M doc_matters, + ) { + string _db_statement; + if ((doc_matters.opt.action.sqlite_db_create)) { + auto pth_sqlite = spinePathsSQLite!()(doc_matters.sqlite.filename, doc_matters.sqlite.path); + if ((isValidPath(pth_sqlite.base) && exists(pth_sqlite.base) != 0 && pth_sqlite.base.isDir)) { + } else { + try { + pth_sqlite.base.mkdirRecurse; + } catch (FileException ex) { } + } + _db_statement ~= SQLiteTablesReCreate!()(); + SQLiteDbRun!()(db, _db_statement, doc_matters.opt.action, "TABLE RE-CREATE"); + _db_statement = []; + } + if (doc_matters.opt.action.sqlite_delete) { + _db_statement ~= SQLiteDeleteDocument!()(doc_matters); + SQLiteDbRun!()(db, _db_statement, doc_matters.opt.action, "DELETE Document"); + _db_statement = []; + } + if (doc_matters.opt.action.sqlite_update) { + _db_statement ~= SQLiteDeleteDocument!()(doc_matters); + SQLiteDbRun!()(db, _db_statement, doc_matters.opt.action, "DELETE Document"); + _db_statement = []; + _db_statement ~= SQLiteInsertMetadata!()(doc_matters); + SQLiteDbRun!()(db, _db_statement, doc_matters.opt.action, "INSERT MetaData"); + _db_statement = []; + /+ get tid (lastrowid or max) for use in doc_objects table +/ + _db_statement ~= doc_abstraction.SQLiteInsertDocObjectsLoop!()(doc_matters); + SQLiteDbRun!()(db, _db_statement, doc_matters.opt.action, "INSERT DocObjects"); + _db_statement = []; + _db_statement ~= SQLiteInsertMetadataTopics!()(doc_matters); + SQLiteDbRun!()(db, _db_statement, doc_matters.opt.action, "INSERT MetaDataTopics"); + _db_statement = []; + } + db.close; + if (doc_matters.opt.action.vox_gt0) { + writeln(" ", pth_sqlite.sqlite_file); + } + } + } + try { + auto db = Database(pth_sqlite.sqlite_file); + SQLiteDbStatementComposite!()(db, doc_abstraction, doc_matters); + } + catch (FileException e) { + writeln("Failed (FileException): ", e.msg, " ", pth_sqlite.sqlite_file); + writeln(e.file, " line: ", e.line); + import core.runtime; + core.runtime.Runtime.terminate(); + } + catch (ErrnoException e) { + writeln("Failed (ErrnoException): ", e.msg, " ", pth_sqlite.sqlite_file); + writeln(e.file, " line: ", e.line); + import core.runtime; + core.runtime.Runtime.terminate(); + } + catch (Exception e) { + writeln("Failed (Exception): ", e.msg, " ", pth_sqlite.sqlite_file); + writeln(e.file, " line: ", e.line); + import core.runtime; + core.runtime.Runtime.terminate(); + } + catch (Throwable) { + writeln("Failed (Trowable): ", pth_sqlite.sqlite_file); + import core.runtime; + core.runtime.Runtime.terminate(); + } + } +} +template SQLiteHubDiscreteBuildTablesAndPopulate() { + void SQLiteHubDiscreteBuildTablesAndPopulate(D,M)( + const D doc_abstraction, + M doc_matters, + ) { + auto url_html = spineUrlsHTML!()(doc_matters.conf_make_meta.conf.w_srv_data_root_url_html, doc_matters.src.language); + auto pth_sqlite = spinePathsSQLiteDiscrete!()(doc_matters.output_path, doc_matters.src.language); // doc_matters.db_path + if ((isValidPath(pth_sqlite.base) && exists(pth_sqlite.base) != 0 && pth_sqlite.base.isDir)) { + } else { + try { + pth_sqlite.base.mkdirRecurse; + } catch (FileException ex) { } + } + auto db = Database(pth_sqlite.sqlite_file(doc_matters.src.filename)); + template SQLiteDiscreteDbStatementComposite() { + void SQLiteDiscreteDbStatementComposite(Db,D,M)( + Db db, + const D doc_abstraction, + M doc_matters, + ) { + try { + { + string _db_statement; + _db_statement ~= SQLiteTablesReCreate!()(); + _db_statement ~= SQLiteInsertMetadata!()(doc_matters); + _db_statement ~= SQLiteInsertMetadataTopics!()(doc_matters); + _db_statement ~= doc_abstraction.SQLiteInsertDocObjectsLoop!()(doc_matters); + SQLiteDbRun!()(db, _db_statement, doc_matters.opt.action, "table CREATE Tables, INSERT DocObjects"); + } + db.close; + } + catch (FileException e) { + writeln("Failed (FileException): ", e.msg); + writeln(e.file, " line: ", e.line); + import core.runtime; + core.runtime.Runtime.terminate(); + } + catch (ErrnoException e) { + writeln("Failed (ErrnoException): ", e.msg); + writeln(e.file, " line: ", e.line); + import core.runtime; + core.runtime.Runtime.terminate(); + } + catch (Exception e) { + writeln("Failed (Exception): ", e.msg); + writeln(e.file, " line: ", e.line); + import core.runtime; + core.runtime.Runtime.terminate(); + } + catch (Throwable) { + import core.runtime; + core.runtime.Runtime.terminate(); + } + if (doc_matters.opt.action.vox_gt0) { + writeln(" ", pth_sqlite.sqlite_file(doc_matters.src.filename)); + } + } + } + SQLiteDiscreteDbStatementComposite!()(db, doc_abstraction, doc_matters); + } +} +template SQLiteDbRun() { + void SQLiteDbRun(Db,St,O)( + Db db, + St db_statement, + O opt_action, + string note, + ) { + debug(sql_statement) { + writeln(db_statement); + } + try { + db.run( + "\nBEGIN TRANSACTION;\n" ~ + db_statement ~ + "\nCOMMIT TRANSACTION;\n" + ); + } catch (ErrnoException ex) { + writeln("ERROR SQLite : ", ex); + } catch (Exception ex) { + writeln("ERROR SQLite : ", ex); + } + { /+ debug +/ + if (opt_action.debug_do_sqlite) { + writeln(note); + if (opt_action.vox_gt2) { + writeln(db_statement); + } + } + } + } +} +template SQLinsertDelimiter() { + string SQLinsertDelimiter(string _txt) { + _txt = _txt + .replaceAll(rgx.quotation_mark_sql_insert_delimiter, "$0$0"); + return _txt; + } +} +template SQLiteFormatAndLoadObject() { + auto SQLiteFormatAndLoadObject(M)( + M doc_matters, + ) { + mixin spineRgxOut; + mixin spineRgxXHTML; + struct sqlite_format_and_load_objects { + string generic_munge_sanitize_text_for_search( + string _txt, + ) { + string _notes; + string _urls; + if (_txt.matchFirst(rgx.inline_notes_al_gen)) { + foreach (m; _txt.matchAll(rgx.inline_notes_al_gen_text)) { + _notes ~= "\n" ~ m["text"]; + } + _txt = _txt.replaceAll(rgx.inline_notes_al_gen, ""); + } + if (_txt.matchFirst(rgx.inline_link)) { + foreach (m; _txt.matchAll(rgx.inline_link)) { + if (m["link"].match(rgx.url)) { + _urls ~= "\n" ~ m["link"]; + } + } + _txt = _txt.replaceAll(rgx.inline_link_clean, ""); + } + if (_notes.length > 0) { + _txt ~= _notes; + } + if (_urls.length > 0) { + _txt ~= _urls; + } + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + writeln(_txt, "\n"); + } + } + debug(sql_text_clean) { + writeln(_txt); + } + return _txt; + } + string munge_html(M,O)( + M doc_matters, + const O obj, + ) { + string _html_special_characters(string _txt){ + _txt = _txt + .replaceAll(rgx_xhtml.ampersand, "&") + .replaceAll(rgx_xhtml.quotation, """) + .replaceAll(rgx_xhtml.less_than, "<") + .replaceAll(rgx_xhtml.greater_than, ">") + .replaceAll(rgx.nbsp_char, " ") + .replaceAll(rgx.br_line_inline, "
") + .replaceAll(rgx.br_line, "
") + .replaceAll(rgx.br_line_spaced, "
") + .replaceAll(rgx_xhtml.line_break, "
"); + return _txt; + } + string _html_font_face(string _txt){ + _txt = _txt + .replaceAll(rgx.inline_emphasis, "$1") + .replaceAll(rgx.inline_bold, "$1") + .replaceAll(rgx.inline_underscore, "$1") + .replaceAll(rgx.inline_italics, "$1") + .replaceAll(rgx.inline_superscript, "$1") + .replaceAll(rgx.inline_subscript, "$1") + .replaceAll(rgx.inline_strike, "$1") + .replaceAll(rgx.inline_insert, "$1") + .replaceAll(rgx.inline_mono, "$1") + .replaceAll(rgx.inline_cite, "$1"); + return _txt; + } + string _notes; + string _urls; + string _txt = _html_font_face(_html_special_characters(obj.text)); + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + writeln(_txt, "\n"); + } + } + return _txt; + } + string html_special_characters(string _txt){ + _txt = _txt + .replaceAll(rgx_xhtml.ampersand, "&") + .replaceAll(rgx_xhtml.quotation, """) + .replaceAll(rgx_xhtml.less_than, "<") + .replaceAll(rgx_xhtml.greater_than, ">") + .replaceAll(rgx.nbsp_char, " ") + .replaceAll(rgx.br_line_inline, "
") + .replaceAll(rgx.br_line, "
") + .replaceAll(rgx.br_line_spaced, "
") + .replaceAll(rgx_xhtml.line_break, "
"); + return _txt; + } + string html_special_characters_code(string _txt){ + _txt = _txt + .replaceAll(rgx_xhtml.ampersand, "&") + .replaceAll(rgx_xhtml.quotation, """) + .replaceAll(rgx_xhtml.less_than, "<") + .replaceAll(rgx_xhtml.greater_than, ">") + .replaceAll(rgx.nbsp_char, " "); + return _txt; + } + string html_font_face(string _txt){ + _txt = _txt + .replaceAll(rgx.inline_emphasis, "$1") + .replaceAll(rgx.inline_bold, "$1") + .replaceAll(rgx.inline_underscore, "$1") + .replaceAll(rgx.inline_italics, "$1") + .replaceAll(rgx.inline_superscript, "$1") + .replaceAll(rgx.inline_subscript, "$1") + .replaceAll(rgx.inline_strike, "$1") + .replaceAll(rgx.inline_insert, "$1") + .replaceAll(rgx.inline_mono, "$1") + .replaceAll(rgx.inline_cite, "$1"); + return _txt; + } + string inline_grouped_text_bullets_indents(M,O)( + M doc_matters, + const O obj, + string _txt, + string _suffix = ".html", + string _xml_type = "seg", + ) { + static auto rgx = RgxO(); + static auto rgx_xhtml = RgxXHTML(); + if (obj.metainfo.is_a == "group") { + _txt = (_txt) + .replaceAll(rgx.grouped_para_indent_1, + " ") + .replaceAll(rgx.grouped_para_indent_2, + " ") + .replaceAll(rgx.grouped_para_indent_3, + " ") + .replaceAll(rgx.grouped_para_indent_4, + " ") + .replaceAll(rgx.grouped_para_indent_5, + " ") + .replaceAll(rgx.grouped_para_indent_6, + " ") + .replaceAll(rgx.grouped_para_indent_7, + " ") + .replaceAll(rgx.grouped_para_indent_8, + " ") + .replaceAll(rgx.grouped_para_indent_9, + " ") + .replaceAll(rgx.grouped_para_indent_hang, " ") + .replaceAll(rgx.grouped_para_bullet, "● ") + .replaceAll(rgx.grouped_para_bullet_indent_1, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_2, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_3, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_4, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_5, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_6, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_7, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_8, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_9, + " ● "); + } + return _txt; + } + string inline_images(M,O)( + M doc_matters, + const O obj, + string _txt, + string _suffix = ".html", + string _xml_type = "seg", + ) { + string _img_pth; + if (_xml_type == "epub") { + _img_pth = "image/"; + } else if (_xml_type == "scroll") { + _img_pth = "../../image/"; + } else if (_xml_type == "seg") { + _img_pth = "../../../image/"; + } + if (_txt.match(rgx.inline_image)) { + _txt = _txt.replaceAll( // TODO bug where image dimensions (w or h) not given & consequently set to 0; should not be used (calculate earlier, abstraction) + rgx.inline_image, + ("$1 $6")); + } + return _txt; + } + string inline_links(M,O)( + M doc_matters, + const O obj, + string _txt, + string _xml_type = "seg", + ) { + if (obj.has.inline_links) { + if (obj.metainfo.is_a != "code") { + _txt = replaceAll!(m => + m["linked_text"] ~ "┤" ~ to!string((obj.stow.link[m["num"].to!ulong])).encode ~ "├" + )(_txt, rgx.inline_link_number_only); + } + if ((_txt.match(rgx.mark_internal_site_lnk)) + && (_xml_type == "scroll")) { // conditions reversed to avoid: gdc compiled program run segfault + _txt = _txt.replaceAll( + rgx.inline_seg_link, + "$1"); + } + auto pth_html = spinePathsHTML!()(doc_matters.output_path, doc_matters.src.language); + if (_xml_type == "seg") { + foreach (m; _txt.matchAll(rgx.inline_link_seg_and_hash)) { + if (m.captures["hash"] in doc_matters.has.tag_associations) { + if (m.captures["hash"] == doc_matters.has.tag_associations[(m.captures["hash"])]["seg_lv4"]) { + _txt = _txt.replaceFirst( + rgx.inline_link_seg_and_hash, + "┥$1┝┤" + ~ doc_matters.conf_make_meta.conf.w_srv_data_root_url_html + ~ "/" + ~ pth_html.tail_fn_seg(doc_matters.src.filename, "$2.html") + ~ "├" + ); + } else { + _txt = _txt.replaceFirst( + rgx.inline_link_seg_and_hash, + "┥$1┝┤" + ~ doc_matters.conf_make_meta.conf.w_srv_data_root_url_html + ~ "/" + ~ doc_matters.src.filename_base + ~ "/" + ~ doc_matters.has.tag_associations[(m.captures["hash"])]["seg_lv4"] + ~ ".html" + ~ "#" ~ m.captures["hash"] + ~ "├" + ); + } + } else { + if (doc_matters.opt.action.vox_gt0) { + writeln( + "WARNING on internal document links, anchor to link <<" + ~ m.captures["hash"] + ~ ">> not found in document, " + ~ "anchor: " ~ m.captures["hash"] + ~ " document: " ~ doc_matters.src.filename + ); + } + } + } + } else { + if (auto m = _txt.match(rgx.inline_link_seg_and_hash)) { + _txt = _txt.replaceFirst( + rgx.inline_link_seg_and_hash, + "┥$1┝┤" + ~ doc_matters.conf_make_meta.conf.w_srv_data_root_url_html + ~ "/" + ~ pth_html.tail_fn_scroll(doc_matters.src.filename) + ~ "#" ~ m.captures["hash"] + ~ "├" + ); + } + } + _txt = _txt + .replaceAll( + rgx.inline_link_fn_suffix, + ("$1.html")) + .replaceAll( + rgx.inline_link, + ("$1")) + .replaceAll( + rgx.mark_internal_site_lnk, + ""); + } + debug(markup_links) { + if (_txt.match(rgx.inline_link)) { + writeln(__LINE__, + " (missed) markup link identified (", + obj.has.inline_links, + "): ", obj.metainfo.is_a, ": ", + obj.text + ); + } + // if (obj.metainfo.is_a == "bookindex") { // DEBUG LINE + // if (_txt.match(regex(r"" + ~ "" ~ m.captures["num"] ~ "." + ~ m.captures["note"] + ~ ""; + } + _txt = replaceAll!(m => + (" " ~ "" ~ m["num"] ~ "")) + (_txt, rgx.inline_notes_al_regular_number_note) + ~ _endnotes.join("\n"); + } + debug(markup_endnotes) { + if (_txt.match(rgx.inline_notes_al_regular_number_note)) { + writeln(__LINE__, " (missed) markup endnote: ", obj.metainfo.is_a, ": ", obj.text); + } + } + debug(markup) { + if (_txt.match(rgx.inline_notes_al_regular_number_note)) { + writeln(__LINE__, " (missed) markup endnote: ", obj.metainfo.is_a, ": ", obj.text); + } + } + return _txt; + } + string xml_type="seg"; /+ set html document type to be linked to here (seg|scroll) +/ + string inline_markup(M,O)( + M doc_matters, + const O obj, + string _txt, + ) { + if (obj.metainfo.is_a == "group") { + _txt = inline_grouped_text_bullets_indents(doc_matters, obj, _txt, xml_type); + } + _txt = inline_images(doc_matters, obj, _txt, xml_type); + _txt = inline_links(doc_matters, obj, _txt, xml_type); + _txt = inline_notes_scroll(doc_matters, obj, _txt); + return _txt; + } + string html_heading(M,O)( + M doc_matters, + const O obj, + ) { + assert(obj.metainfo.is_of_part == "body" || "frontmatter" || "backmatter"); + assert(obj.metainfo.is_of_section == "body" || "toc" || "endnotes" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "para"); + assert(obj.metainfo.is_a == "heading"); + string _txt = munge_html(doc_matters, obj); + _txt = inline_markup(doc_matters, obj, _txt); + string o = format(q"┃+ %s +
┃", + obj.metainfo.is_a, + _txt, + ); + return o; + } + string html_para(M,O)( + M doc_matters, + const O obj, + ) { + assert(obj.metainfo.is_of_part == "body" || "frontmatter" || "backmatter"); + assert(obj.metainfo.is_of_section == "body" || "toc" || "endnotes" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "para"); + assert(obj.metainfo.is_a == "para" || "toc" || "endnote" || "glossary" || "bibliography" || "bookindex" || "blurb"); + string _txt = munge_html(doc_matters, obj); + _txt = (obj.attrib.bullet) ? ("● " ~ _txt) : _txt; + _txt = inline_markup(doc_matters, obj, _txt); + string o = format(q"┃+ %s +
┃", + obj.metainfo.is_a, + obj.attrib.indent_hang, + obj.attrib.indent_base, + _txt + ); + return o; + } + string html_quote(M,O)( + M doc_matters, + const O obj, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "quote"); + string _txt = munge_html(doc_matters, obj); + string o = format(q"┃+ %s +
┃", + obj.metainfo.is_a, + _txt + ); + return o; + } + string html_group(M,O)( + M doc_matters, + const O obj, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "group"); + string _txt = munge_html(doc_matters, obj); + _txt = inline_markup(doc_matters, obj, _txt); + string o = format(q"┃+ %s +
┃", + obj.metainfo.is_a, + _txt + ); + return o; + } + string html_block(M,O)( + M doc_matters, + const O obj, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "block"); + string _txt = munge_html(doc_matters, obj); + _txt = inline_markup(doc_matters, obj, _txt); + string o = format(q"┃ +%s
┃", + obj.metainfo.is_a, + _txt.stripRight + ); + return o; + } + string html_verse(M,O)( + M doc_matters, + const O obj, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "verse"); + string _txt = munge_html(doc_matters, obj); + string o = format(q"┃%s
┃", + obj.metainfo.is_a, + _txt + ); + return o; + } + string html_code(O)( + const O obj, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "code"); + string _txt = html_special_characters_code(obj.text); + string o = format(q"┃%s
┃", + obj.metainfo.is_a, + _txt + ); + return o; + } + string html_table(M,O)( + M doc_matters, + const O obj, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "table"); + Tuple!(string, string) _tablarize(O)( + const O obj, + string _txt, + ) { + string[] _table_rows = _txt.split(rgx.table_delimiter_row); + string[] _table_cols; + string _table; + string _tablenote; + 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)) { // check row_idx+2 (rather than == ++row_idx) + _tablenote ~= cell; + } else { + string _col_is = (row_idx == 0 && obj.table.heading) ? "th" : "td"; + string _align = ("style=\"text-align:" + ~ ((obj.table.column_aligns[col_idx] == "l") + ? "left\"" : "right\"")); + _table ~= "<" + ~ _col_is + ~ " width=\"" + ~ obj.table.column_widths[col_idx].to!string + ~ "%\" " + ~ _align + ~ ">"; + _table ~= cell; + _table ~= "" + ~ _col_is + ~ ">"; + } + } + _table ~= " "; + } + Tuple!(string, string) t = tuple( + _table, + _tablenote, + ); + return t; + } + string _txt = munge_html(doc_matters, obj); + Tuple!(string, string) t = _tablarize(obj, _txt); + _txt = t[0]; + string _note = t[1]; + string o = format(q"┃+
+ %s +
+ %s + ┃", + obj.metainfo.is_a, + _txt, + _note + ); + return o; + } + string sqlite_load_string(M,O)( + M doc_matters, + const O obj, + ) { + string o; + return o; + } + string sqlite_statement(O)( + const O obj, + string _txt, + string _html, + ) { + void _sql_exe(O)( + string _sql, + ) { + writeln(_html); + writeln(_sql); + } + string _sql; + return _sql; + } + string[string] heading(M,O)( + M doc_matters, + const O obj, + ) { + string[string] obj_txt = [ + "text": generic_munge_sanitize_text_for_search(obj.text), + "html": html_heading(doc_matters, obj) + ]; + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + debug(sql_txt) { + writeln(obj_txt["text"]); + } + debug(sql_html) { + writeln(obj_txt["html"]); + } + } else { + // load sql + } + } + return obj_txt; + } + string[string] para(M,O)( + M doc_matters, + const O obj, + ) { + string[string] obj_txt = [ + "text": generic_munge_sanitize_text_for_search(obj.text), + "html": html_para(doc_matters, obj) + ]; + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + debug(sql_txt) { + writeln(obj_txt["text"]); + } + debug(sql_html) { + writeln(obj_txt["html"]); + } + } else { + // load sql + } + } + return obj_txt; + } + string[string] quote(M,O)( + M doc_matters, + const O obj, + ) { + string[string] obj_txt = [ + "text": generic_munge_sanitize_text_for_search(obj.text), + "html": html_quote(doc_matters, obj) + ]; + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + debug(sql_txt) { + writeln(obj_txt["text"]); + } + debug(sql_html) { + writeln(obj_txt["html"]); + } + } else { + // load sql + } + } + return obj_txt; + } + string[string] group(M,O)( + M doc_matters, + const O obj, + ) { + string[string] obj_txt = [ + "text": generic_munge_sanitize_text_for_search(obj.text), + "html": html_group(doc_matters, obj) + ]; + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + debug(sql_txt) { + writeln(obj_txt["text"]); + } + debug(sql_html) { + writeln(obj_txt["html"]); + } + } else { + // load sql + } + } + return obj_txt; + } + string[string] block(M,O)( + M doc_matters, + const O obj, + ) { + string[string] obj_txt = [ + "text": generic_munge_sanitize_text_for_search(obj.text), + "html": html_block(doc_matters, obj) + ]; + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + debug(sql_txt) { + writeln(obj_txt["text"]); + } + debug(sql_html) { + writeln(obj_txt["html"]); + } + } else { + // load sql + } + } + return obj_txt; + } + string[string] verse(M,O)( + M doc_matters, + const O obj, + ) { + string[string] obj_txt = [ + "text": generic_munge_sanitize_text_for_search(obj.text), + "html": html_verse(doc_matters, obj) + ]; + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + debug(sql_txt) { + writeln(obj_txt["text"]); + } + debug(sql_html) { + writeln(obj_txt["html"]); + } + } else { + // load sql + } + } + return obj_txt; + } + string[string] code(M,O)( + M doc_matters, + const O obj, + ) { + string[string] obj_txt = [ + "text": generic_munge_sanitize_text_for_search(obj.text), + "html": html_code(obj) + ]; + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + debug(sql_txt) { + writeln(obj_txt["text"]); + } + debug(sql_html) { + writeln(obj_txt["html"]); + } + } else { + // load sql + } + } + return obj_txt; + } + string[string] table(M,O)( + M doc_matters, + const O obj, + ) { + string[string] obj_txt = [ + "text": generic_munge_sanitize_text_for_search(obj.text), + "html": html_table(doc_matters, obj) + ]; + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + debug(sql_txt) { + writeln(obj_txt["text"]); + } + debug(sql_html) { + writeln(obj_txt["html"]); + } + } else { + // load sql + } + } + return obj_txt; + } + } + return sqlite_format_and_load_objects(); + } +} +template SQLiteTablesReCreate() { + string SQLiteTablesReCreate()() { + string _sql_instruct; + _sql_instruct = format(q"┃ + DROP INDEX IF EXISTS idx_ocn; + DROP INDEX IF EXISTS idx_uid; + DROP INDEX IF EXISTS idx_digest_clean; + DROP INDEX IF EXISTS idx_digest_all; + DROP INDEX IF EXISTS idx_clean; + DROP INDEX IF EXISTS idx_title; + DROP INDEX IF EXISTS idx_author; + DROP INDEX IF EXISTS src_filename_base; + DROP INDEX IF EXISTS idx_language_document_char; + DROP INDEX IF EXISTS idx_classify_topic_register; + DROP INDEX IF EXISTS idx_topic_list; + DROP TABLE IF EXISTS metadata_and_text; + DROP TABLE IF EXISTS topic_register; + DROP TABLE IF EXISTS doc_objects; + DROP TABLE IF EXISTS urls; + CREATE TABLE IF NOT EXISTS metadata_and_text ( + uid VARCHAR(256) UNIQUE, -- filename, language char, pod/txt (decide on delimiter [,;:/]) + src_composite_id_per_txt VARCHAR(256) NOT NULL, -- UNIQUE, z pod name if any + src filename + language code + src_composite_id_per_pod VARCHAR(256) NOT NULL, -- z pod name if any + src filename + title VARCHAR(800) NOT NULL, + title_main VARCHAR(400) NOT NULL, + title_sub VARCHAR(400) NULL, + title_short VARCHAR(400) NULL, + title_edition VARCHAR(10) NULL, + title_language VARCHAR(100) NULL, + title_language_char VARCHAR(6) NULL, + creator_author VARCHAR(600) NOT NULL, + creator_author_last_first VARCHAR(600) NOT NULL, + creator_author_email VARCHAR(100) NULL, + creator_author_hon VARCHAR(100) NULL, + creator_author_nationality VARCHAR(100) NULL, + creator_editor VARCHAR(600) NULL, + creator_contributor VARCHAR(600) NULL, + creator_illustrator VARCHAR(600) NULL, + creator_photographer VARCHAR(600) NULL, + creator_translator VARCHAR(600) NULL, + creator_prepared_by VARCHAR(600) NULL, + creator_digitized_by VARCHAR(600) NULL, + creator_audio VARCHAR(600) NULL, + creator_video VARCHAR(600) NULL, + language_document VARCHAR(100) NULL, + language_document_char VARCHAR(6) NOT NULL, + language_original VARCHAR(100) NULL, + language_original_char VARCHAR(6) NULL, + date_added_to_site VARCHAR(10) NULL, + date_available VARCHAR(10) NULL, + date_created VARCHAR(10) NULL, + date_issued VARCHAR(10) NULL, + date_modified VARCHAR(10) NULL, + date_published VARCHAR(10) NULL, + date_valid VARCHAR(10) NULL, + date_translated VARCHAR(10) NULL, + date_original_publication VARCHAR(10) NULL, + date_generated VARCHAR(10) NULL, + original_title VARCHAR(800) NULL, + original_publisher VARCHAR(600) NULL, + original_language VARCHAR(100) NULL, + original_language_char VARCHAR(6) NULL, + original_source VARCHAR(600) NULL, + original_institution VARCHAR(600) NULL, + original_nationality VARCHAR(100) NULL, + rights_copyright VARCHAR(2500) NULL, + rights_copyright_audio VARCHAR(2500) NULL, + rights_copyright_cover VARCHAR(2500) NULL, + rights_copyright_illustrations VARCHAR(2500) NULL, + rights_copyright_photographs VARCHAR(2500) NULL, + rights_copyright_text VARCHAR(2500) NULL, + rights_copyright_translation VARCHAR(2500) NULL, + rights_copyright_video VARCHAR(2500) NULL, + rights_license VARCHAR(2500) NULL, + identifier_oclc VARCHAR(30) NULL, + identifier_isbn VARCHAR(16) NULL, + classify_topic_register VARCHAR(2500) NULL, + classify_subject VARCHAR(600) NULL, + classify_loc VARCHAR(30) NULL, + classify_dewey VARCHAR(30) NULL, + classify_keywords VARCHAR(600) NULL, + notes_abstract TEXT NULL, + notes_description TEXT NULL, + notes_comment TEXT NULL, + notes_coverage VARCHAR(200) NULL, + notes_relation VARCHAR(200) NULL, + notes_history VARCHAR(600) NULL, + notes_type VARCHAR(600) NULL, + notes_format VARCHAR(600) NULL, + notes_prefix TEXT NULL, + notes_prefix_a TEXT NULL, + notes_prefix_b TEXT NULL, + notes_suffix TEXT NULL, + publisher VARCHAR(600) NULL, + src_filename_base VARCHAR(256) NOT NULL, + src_filename_suffix VARCHAR(6) NOT NULL, + src_fingerprint VARCHAR(256) NULL, + src_filesize VARCHAR(10) NULL, + src_wordcount VARCHAR(10) NULL, + pod_name VARCHAR(256) NULL, -- zipped pod, work to be done here + pod_fingerprint VARCHAR(256) NULL, -- zipped pod, work to be done here + pod_size VARCHAR(10) NULL, -- zipped pod, work to be done here + site_url_doc_root VARCHAR(256) NULL, -- url path to doc root + site_url_html_toc VARCHAR(256) NULL, + site_url_html_scroll VARCHAR(256) NULL, + site_url_epub VARCHAR(256) NULL, + links TEXT NULL + ); + CREATE TABLE IF NOT EXISTS topic_register ( + -- tid BIGINT PRIMARY KEY, + uid_metadata_and_text VARCHAR(256) REFERENCES metadata_and_text(uid) ON DELETE CASCADE, + -- src_composite_id_per_txt VARCHAR(256) NOT NULL, - UNIQUE, - z pod name if any + src filename + language code + -- src_composite_id_per_pod VARCHAR(256) NOT NULL, - z pod name if any + src filename + topic_register VARCHAR(250) NOT NULL, + site_url_doc_root VARCHAR(256) NULL, -- url path to doc root + site_url_html_toc VARCHAR(256) NULL, + site_url_html_scroll VARCHAR(256) NULL + ); + CREATE TABLE IF NOT EXISTS doc_objects ( + lid BIGINT PRIMARY KEY, + uid_metadata_and_text VARCHAR(256) REFERENCES metadata_and_text(uid) ON DELETE CASCADE, + ocn SMALLINT, + obj_id VARCHAR(6) NULL, + clean TEXT NULL, + body TEXT NULL, + seg VARCHAR(256) NULL, + lev_an VARCHAR(1), + is_of_type VARCHAR(16), + is_a VARCHAR(16), + lev SMALLINT NULL, + node VARCHAR(16) NULL, + parent VARCHAR(16) NULL, + last_descendant VARCHAR(16) NULL, -- headings only + digest_clean CHAR(256), + digest_all CHAR(256), + seg_name CHAR(256), + types CHAR(1) NULL + ); + CREATE INDEX IF NOT EXISTS idx_ocn ON doc_objects(ocn); + CREATE INDEX IF NOT EXISTS idx_digest_clean ON doc_objects(digest_clean); + CREATE INDEX IF NOT EXISTS idx_digest_all ON doc_objects(digest_all); + CREATE INDEX IF NOT EXISTS idx_clean ON doc_objects(clean); + CREATE INDEX IF NOT EXISTS idx_title ON metadata_and_text(title); + CREATE INDEX IF NOT EXISTS idx_author ON metadata_and_text(creator_author_last_first); + CREATE INDEX IF NOT EXISTS idx_uid ON metadata_and_text(uid); + CREATE INDEX IF NOT EXISTS idx_filename ON metadata_and_text(src_filename_base); + CREATE INDEX IF NOT EXISTS idx_language ON metadata_and_text(language_document_char); + CREATE INDEX IF NOT EXISTS idx_topics ON metadata_and_text(classify_topic_register); + CREATE INDEX IF NOT EXISTS idx_topic_list ON topic_register(topic_register); + ┃",); + return _sql_instruct; + } +} +template SQLiteDeleteDocument() { + string SQLiteDeleteDocument(M)( + M doc_matters, + ) { + string _uid = doc_matters.src.doc_uid; + string _delete_uid = format(q"┃ + DELETE FROM metadata_and_text + WHERE uid = '%s'; + DELETE FROM doc_objects + WHERE uid_metadata_and_text = '%s'; + ┃", + _uid, + _uid, + ); + return _delete_uid; + } +} +template SQLiteInsertMetadata() { + string SQLiteInsertMetadata(M)( + M doc_matters, + ) { + string _uid = SQLinsertDelimiter!()(doc_matters.src.doc_uid); + string _insert_metadata = format(q"┃ + INSERT INTO metadata_and_text ( + uid, + src_filename_base, + src_filename_suffix, + src_composite_id_per_txt, + src_composite_id_per_pod, + title, + title_main, + title_sub, + title_short, + title_edition, + title_language, + creator_author, + creator_author_last_first, + creator_author_email, + creator_illustrator, + creator_translator, + language_document, + language_document_char, + date_added_to_site, + date_available, + date_created, + date_issued, + date_modified, + date_published, + date_valid, + rights_copyright, + rights_copyright_audio, + rights_copyright_cover, + rights_copyright_illustrations, + rights_copyright_photographs, + rights_copyright_text, + rights_copyright_translation, + rights_copyright_video, + rights_license, + identifier_oclc, + identifier_isbn, + classify_dewey, + classify_keywords, + classify_loc, + classify_subject, + classify_topic_register, + original_title, + original_publisher, + original_language, + original_language_char, + original_source, + notes_abstract, + notes_description, + publisher, + site_url_doc_root + ) + VALUES ( + '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' + ); + ┃", + _uid, + SQLinsertDelimiter!()(doc_matters.src.filename_base), + SQLinsertDelimiter!()(doc_matters.src.filename_extension), + SQLinsertDelimiter!()(doc_matters.src.docname_composite_unique_per_src_doc), + SQLinsertDelimiter!()(doc_matters.src.docname_composite_unique_per_src_pod), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.title_full), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.title_main), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.title_subtitle), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.title_short), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.title_edition), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.title_language), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.creator_author), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.creator_author_surname_fn), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.creator_author_email), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.creator_illustrator), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.creator_translator), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.language_document), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.language_document_char), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.date_added_to_site), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.date_available), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.date_created), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.date_issued), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.date_modified), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.date_published), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.date_valid), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.rights_copyright), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.rights_copyright_audio), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.rights_copyright_cover), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.rights_copyright_illustrations), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.rights_copyright_photographs), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.rights_copyright_text), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.rights_copyright_translation), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.rights_copyright_video), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.rights_license), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.identifier_oclc), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.identifier_isbn), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.classify_dewey), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.classify_keywords), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.classify_loc), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.classify_subject), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.classify_topic_register), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.notes_abstract), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.notes_description), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.original_title), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.original_publisher), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.original_language), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.original_language_char), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.original_source), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.meta.publisher), + SQLinsertDelimiter!()(doc_matters.conf_make_meta.conf.w_srv_data_root_url_html) + ); + return _insert_metadata; + } +} +template SQLiteInsertMetadataTopics() { + string SQLiteInsertMetadataTopics(M)( + M doc_matters, + ) { + string _uid = SQLinsertDelimiter!()(doc_matters.src.doc_uid); + string[] _insert_topics; + foreach (topic_line; doc_matters.conf_make_meta.meta.classify_topic_register_expanded_arr) { + // writeln(topic_line); + _insert_topics ~= format(q"┃ + INSERT INTO topic_register ( + uid_metadata_and_text, + topic_register + ) + VALUES ( + '%s', + '%s' + ); + ┃", + _uid, + SQLinsertDelimiter!()(topic_line) + ); + } + return _insert_topics.join.to!(char[]).toUTF8; + } +} +template SQLiteInsertDocObjectsLoop() { + string SQLiteInsertDocObjectsLoop(D,M)( + const D doc_abstraction, + M doc_matters, + ) { + string _uid = SQLinsertDelimiter!()(doc_matters.src.doc_uid); + auto url_html = spineUrlsHTML!()(doc_matters.conf_make_meta.conf.w_srv_data_root_url_html, doc_matters.src.language); + string insertDocObjectsRow(O)(O obj) { + string _insert_doc_objects_row = format(q"┃ + INSERT INTO doc_objects ( + uid_metadata_and_text, + ocn, + obj_id, + clean, + body, + lev, + is_of_type, + is_a, + seg_name + ) + VALUES ( + '%s', %s, '%s', '%s', '%s', %s, '%s', '%s', '%s' + ); + ┃", + _uid, + obj.metainfo.ocn, + obj.metainfo.identifier, + SQLinsertDelimiter!()(obj_txt["text"]), + SQLinsertDelimiter!()(obj_txt["html"]), + obj.metainfo.heading_lev_markup, + obj.metainfo.is_of_type, + obj.metainfo.is_a, + obj.tags.html_segment_anchor_tag_is + ); + return _insert_doc_objects_row; + } + auto format_and_sqlite_load = SQLiteFormatAndLoadObject!()(doc_matters); + string[string] obj_txt; + string doc_text; + string[] _insert_doc_objects; + foreach (part; doc_matters.has.keys_seq.sql) { + foreach (obj; doc_abstraction[part]) { + switch (obj.metainfo.is_of_part) { + case "frontmatter": assert(part == "head", part); + switch (obj.metainfo.is_of_type) { + case "para": + switch (obj.metainfo.is_a) { + case "heading": + obj_txt = format_and_sqlite_load.heading(doc_matters, obj); + break; + default: + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_a); + } + } + break; + } + break; + default: + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_of_type); + } + } + break; + } + break; + case "body": // assert(part == "body", part); + switch (obj.metainfo.is_of_type) { + case "para": + switch (obj.metainfo.is_a) { + case "heading": + debug (asserts) { + if (part != "body") { + writeln(__LINE__, ": ", obj.text); + } + } + obj_txt = format_and_sqlite_load.heading(doc_matters, obj); + break; + case "para": + obj_txt = format_and_sqlite_load.para(doc_matters, obj); + break; + default: + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_a); + } + } + break; + } + break; + case "block": + switch (obj.metainfo.is_a) { + case "quote": + obj_txt = format_and_sqlite_load.quote(doc_matters, obj); + break; + case "group": + obj_txt = format_and_sqlite_load.group(doc_matters, obj); + break; + case "block": + obj_txt = format_and_sqlite_load.block(doc_matters, obj); + break; + case "poem": // double check on keeping both poem & verse + break; + case "verse": + obj_txt = format_and_sqlite_load.verse(doc_matters, obj); + break; + case "code": + obj_txt = format_and_sqlite_load.code(doc_matters, obj); + break; + case "table": + obj_txt = format_and_sqlite_load.table(doc_matters, obj); + break; + default: + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_a); + } + } + break; + } + break; + default: + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_of_type); + } + } + break; + } + break; + case "backmatter": + assert(part == "glossary" || "bibliography" || "bookindex" || "blurb" || "tail", part); + switch (obj.metainfo.is_of_type) { + case "para": + switch (obj.metainfo.is_a) { + case "heading": + obj_txt = format_and_sqlite_load.heading(doc_matters, obj); + break; + case "glossary": assert(part == "glossary", part); + obj_txt = format_and_sqlite_load.para(doc_matters, obj); + break; + case "bibliography": assert(part == "bibliography", part); + obj_txt = format_and_sqlite_load.para(doc_matters, obj); + break; + case "bookindex": assert(part == "bookindex", part); + obj_txt = format_and_sqlite_load.para(doc_matters, obj); + break; + case "blurb": assert(part == "blurb", part); + obj_txt = format_and_sqlite_load.para(doc_matters, obj); + break; + default: + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_a); + } + } + break; + } + break; + default: + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_of_type); + } + } + break; + } + break; + case "comment": + break; + default: + { /+ debug +/ + if (doc_matters.opt.action.debug_do_sqlite) { + writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_of_part); // check where empty value could come from + writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_a); + writeln(__FILE__, ":", __LINE__, ": ", obj.text); // check where empty value could come from + } + } + break; + } + if (obj.metainfo.is_a == "heading") { + if (doc_matters.opt.action.show_sqlite) { + if (obj.metainfo.heading_lev_markup == 0) { + writeln(doc_matters.src.filename); + } + writeln( + "markup: ", obj.metainfo.heading_lev_markup, + "> ", obj.metainfo.dom_structure_markedup_tags_status, + "; collapsed: ", obj.metainfo.heading_lev_collapsed, + "> ", obj.metainfo.dom_structure_collapsed_tags_status, + "; ocn: ", obj.metainfo.ocn, + " node: ", obj.metainfo.node, + "; parent: ", obj.metainfo.parent_lev_markup, + "; ocn: ", obj.metainfo.parent_ocn, + "; ", + ); + } + } + if (!(obj.metainfo.is_a == "comment")) { + _insert_doc_objects ~= insertDocObjectsRow(obj); + } + } // loop closes + } + return _insert_doc_objects.join.to!(char[]).toUTF8; + } +} +template SQLiteTablesCreate() { + void SQLiteTablesCreate(E,O,C)(E env, O opt_action, C config) { + import d2sqlite3; + template SQLiteTablesReCreate() { + string SQLiteTablesReCreate()() { + string _sql_instruct; + _sql_instruct = format(q"┃ + DROP INDEX IF EXISTS idx_ocn; + DROP INDEX IF EXISTS idx_uid; + DROP INDEX IF EXISTS idx_digest_clean; + DROP INDEX IF EXISTS idx_digest_all; + DROP INDEX IF EXISTS idx_clean; + DROP INDEX IF EXISTS idx_title; + DROP INDEX IF EXISTS idx_author; + DROP INDEX IF EXISTS src_filename_base; + DROP INDEX IF EXISTS idx_language_document_char; + DROP INDEX IF EXISTS idx_classify_topic_register; + DROP INDEX IF EXISTS idx_topic_list; + DROP TABLE IF EXISTS metadata_and_text; + DROP TABLE IF EXISTS topic_register; + DROP TABLE IF EXISTS doc_objects; + DROP TABLE IF EXISTS urls; + CREATE TABLE IF NOT EXISTS metadata_and_text ( + uid VARCHAR(256) UNIQUE, -- filename, language char, pod/txt (decide on delimiter [,;:/]) + src_composite_id_per_txt VARCHAR(256) NOT NULL, -- UNIQUE, z pod name if any + src filename + language code + src_composite_id_per_pod VARCHAR(256) NOT NULL, -- z pod name if any + src filename + title VARCHAR(800) NOT NULL, + title_main VARCHAR(400) NOT NULL, + title_sub VARCHAR(400) NULL, + title_short VARCHAR(400) NULL, + title_edition VARCHAR(10) NULL, + title_language VARCHAR(100) NULL, + title_language_char VARCHAR(6) NULL, + creator_author VARCHAR(600) NOT NULL, + creator_author_last_first VARCHAR(600) NOT NULL, + creator_author_email VARCHAR(100) NULL, + creator_author_hon VARCHAR(100) NULL, + creator_author_nationality VARCHAR(100) NULL, + creator_editor VARCHAR(600) NULL, + creator_contributor VARCHAR(600) NULL, + creator_illustrator VARCHAR(600) NULL, + creator_photographer VARCHAR(600) NULL, + creator_translator VARCHAR(600) NULL, + creator_prepared_by VARCHAR(600) NULL, + creator_digitized_by VARCHAR(600) NULL, + creator_audio VARCHAR(600) NULL, + creator_video VARCHAR(600) NULL, + language_document VARCHAR(100) NULL, + language_document_char VARCHAR(6) NOT NULL, + language_original VARCHAR(100) NULL, + language_original_char VARCHAR(6) NULL, + date_added_to_site VARCHAR(10) NULL, + date_available VARCHAR(10) NULL, + date_created VARCHAR(10) NULL, + date_issued VARCHAR(10) NULL, + date_modified VARCHAR(10) NULL, + date_published VARCHAR(10) NULL, + date_valid VARCHAR(10) NULL, + date_translated VARCHAR(10) NULL, + date_original_publication VARCHAR(10) NULL, + date_generated VARCHAR(10) NULL, + original_title VARCHAR(800) NULL, + original_publisher VARCHAR(600) NULL, + original_language VARCHAR(100) NULL, + original_language_char VARCHAR(6) NULL, + original_source VARCHAR(600) NULL, + original_institution VARCHAR(600) NULL, + original_nationality VARCHAR(100) NULL, + rights_copyright VARCHAR(2500) NULL, + rights_copyright_audio VARCHAR(2500) NULL, + rights_copyright_cover VARCHAR(2500) NULL, + rights_copyright_illustrations VARCHAR(2500) NULL, + rights_copyright_photographs VARCHAR(2500) NULL, + rights_copyright_text VARCHAR(2500) NULL, + rights_copyright_translation VARCHAR(2500) NULL, + rights_copyright_video VARCHAR(2500) NULL, + rights_license VARCHAR(2500) NULL, + identifier_oclc VARCHAR(30) NULL, + identifier_isbn VARCHAR(16) NULL, + classify_topic_register VARCHAR(2500) NULL, + classify_subject VARCHAR(600) NULL, + classify_loc VARCHAR(30) NULL, + classify_dewey VARCHAR(30) NULL, + classify_keywords VARCHAR(600) NULL, + notes_abstract TEXT NULL, + notes_description TEXT NULL, + notes_comment TEXT NULL, + notes_coverage VARCHAR(200) NULL, + notes_relation VARCHAR(200) NULL, + notes_history VARCHAR(600) NULL, + notes_type VARCHAR(600) NULL, + notes_format VARCHAR(600) NULL, + notes_prefix TEXT NULL, + notes_prefix_a TEXT NULL, + notes_prefix_b TEXT NULL, + notes_suffix TEXT NULL, + publisher VARCHAR(600) NULL, + src_filename_base VARCHAR(256) NOT NULL, + src_filename_suffix VARCHAR(6) NOT NULL, + src_fingerprint VARCHAR(256) NULL, + src_filesize VARCHAR(10) NULL, + src_wordcount VARCHAR(10) NULL, + pod_name VARCHAR(256) NULL, -- zipped pod, work to be done here + pod_fingerprint VARCHAR(256) NULL, -- zipped pod, work to be done here + pod_size VARCHAR(10) NULL, -- zipped pod, work to be done here + site_url_doc_root VARCHAR(256) NULL, -- url path to doc root + site_url_html_toc VARCHAR(256) NULL, + site_url_html_scroll VARCHAR(256) NULL, + site_url_epub VARCHAR(256) NULL, + links TEXT NULL + ); + CREATE TABLE IF NOT EXISTS topic_register ( + -- tid BIGINT PRIMARY KEY, + uid_metadata_and_text VARCHAR(256) REFERENCES metadata_and_text(uid) ON DELETE CASCADE, + -- src_composite_id_per_txt VARCHAR(256) NOT NULL, - UNIQUE, - z pod name if any + src filename + language code + -- src_composite_id_per_pod VARCHAR(256) NOT NULL, - z pod name if any + src filename + topic_register VARCHAR(250) NOT NULL, + site_url_doc_root VARCHAR(256) NULL, -- url path to doc root + site_url_html_toc VARCHAR(256) NULL, + site_url_html_scroll VARCHAR(256) NULL + ); + CREATE TABLE IF NOT EXISTS doc_objects ( + lid BIGINT PRIMARY KEY, + uid_metadata_and_text VARCHAR(256) REFERENCES metadata_and_text(uid) ON DELETE CASCADE, + ocn SMALLINT, + obj_id VARCHAR(6) NULL, + clean TEXT NULL, + body TEXT NULL, + seg VARCHAR(256) NULL, + lev_an VARCHAR(1), + is_of_type VARCHAR(16), + is_a VARCHAR(16), + lev SMALLINT NULL, + node VARCHAR(16) NULL, + parent VARCHAR(16) NULL, + last_descendant VARCHAR(16) NULL, -- headings only + digest_clean CHAR(256), + digest_all CHAR(256), + seg_name CHAR(256), + types CHAR(1) NULL + ); + CREATE INDEX IF NOT EXISTS idx_ocn ON doc_objects(ocn); + CREATE INDEX IF NOT EXISTS idx_digest_clean ON doc_objects(digest_clean); + CREATE INDEX IF NOT EXISTS idx_digest_all ON doc_objects(digest_all); + CREATE INDEX IF NOT EXISTS idx_clean ON doc_objects(clean); + CREATE INDEX IF NOT EXISTS idx_title ON metadata_and_text(title); + CREATE INDEX IF NOT EXISTS idx_author ON metadata_and_text(creator_author_last_first); + CREATE INDEX IF NOT EXISTS idx_uid ON metadata_and_text(uid); + CREATE INDEX IF NOT EXISTS idx_filename ON metadata_and_text(src_filename_base); + CREATE INDEX IF NOT EXISTS idx_language ON metadata_and_text(language_document_char); + CREATE INDEX IF NOT EXISTS idx_topics ON metadata_and_text(classify_topic_register); + CREATE INDEX IF NOT EXISTS idx_topic_list ON topic_register(topic_register); + ┃",); + return _sql_instruct; + } + } + try { + if (opt_action.sqlite_db_create) { + string _db_statement; + string db_filename = (opt_action.sqliteDB_filename.length > 0) + ? opt_action.sqliteDB_filename + : (config.conf.w_srv_db_sqlite_filename.length > 0) + ? config.conf.w_srv_db_sqlite_filename + : ""; + string db_path = (opt_action.sqliteDB_path.length > 0) + ? opt_action.sqliteDB_path + : (config.conf.w_srv_db_sqlite_path.length > 0) + ? config.conf.w_srv_db_sqlite_path + : ""; + if (db_filename.length > 0 && db_path.length > 0) { + if (opt_action.vox_gt2) { + writeln("db name: ", db_filename); + writeln("db path: ", db_path); + writeln("db name & path: ", db_path, "/", db_filename); + } + if (opt_action.vox_gt1) { + writeln("attempting to create db: ", db_path, "/", db_filename); + } + auto pth_sqlite = spinePathsSQLite!()(db_filename, db_path); + if ((isValidPath(pth_sqlite.base) && exists(pth_sqlite.base) != 0 && pth_sqlite.base.isDir)) { + } else { + try { + pth_sqlite.base.mkdirRecurse; + } catch (FileException ex) { } + } + auto db = Database(pth_sqlite.sqlite_file); + { + _db_statement ~= SQLiteTablesReCreate!()(); + } + SQLiteDbRun!()(db, _db_statement, opt_action, "TABLE RE-CREATE"); + } else { + writeln("must provide db name & output root path either on the command line or in configuration file"); + writeln("db name: ", db_filename); + writeln("db path: ", db_path); + } + } + } + catch (FileException e) { + writeln("Failed (FileException): ", e.msg); + writeln(e.file, " line: ", e.line); + import core.runtime; + core.runtime.Runtime.terminate(); + } + catch (ErrnoException e) { + writeln("Failed (ErrnoException): ", e.msg); + writeln(e.file, " line: ", e.line); + import core.runtime; + core.runtime.Runtime.terminate(); + } + catch (Exception e) { + writeln("Failed (Exception): ", e.msg); + writeln(e.file, " line: ", e.line); + import core.runtime; + core.runtime.Runtime.terminate(); + } + catch (Throwable) { + import core.runtime; + core.runtime.Runtime.terminate(); + } + } +} +template SQLiteDbDrop() { + void SQLiteDbDrop(O,C)(O opt_action, C config) { + writeln("db drop"); + if ((opt_action.sqlite_db_drop)) { + string db_filename = (opt_action.sqliteDB_filename.length > 0) + ? opt_action.sqliteDB_filename + : (config.conf.w_srv_db_sqlite_filename.length > 0) + ? config.conf.w_srv_db_sqlite_filename + : ""; + string db_path = (opt_action.sqliteDB_path.length > 0) // + ? opt_action.sqliteDB_path + : (config.conf.w_srv_db_sqlite_path.length > 0) + ? config.conf.w_srv_db_sqlite_path + : ""; + if (db_filename.length > 0 && db_path.length > 0) { + auto pth_sqlite = spinePathsSQLite!()(db_filename, db_path); + writeln("remove(", pth_sqlite.sqlite_file, ")"); + try { + remove(pth_sqlite.sqlite_file); + } catch (FileException ex) { + // handle error + } + } else { + writeln("must provide db name & output root path either on the command line or in configuration file"); + writeln("db name: ", db_filename); + writeln("db path: ", db_path); + } + } + } +} diff --git a/src/sisudoc/io_out/xmls.d b/src/sisudoc/io_out/xmls.d new file mode 100644 index 0000000..c268bb7 --- /dev/null +++ b/src/sisudoc/io_out/xmls.d @@ -0,0 +1,1424 @@ +/+ +- 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 - 2024 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.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; + mixin spineRgxOut; + mixin spineRgxXHTML; + struct outputXHTMLs { + static auto rgx = RgxO(); + static auto rgx_xhtml = RgxXHTML(); + string div_delimit( + string section, + return ref string previous_section + ) { + string delimit = ""; + string delimit_ = ""; + if (section != previous_section) { + switch (section) { + case "head": + delimit_ ~= "\n\n" ; + break; + case "toc": + delimit_ ~= "\n\n" ; + break; + case "bookindex": + delimit_ ~= "\n\n" ; + break; + default: + delimit_ ~= "\n┃"); + return o; +} +string tail(M)(M doc_matters) { + string o; + o = format(q"┃\n" ; + break; + } + if (previous_section.length > 0) { + delimit ~= "\n"; + } + previous_section = section; + delimit ~= delimit_; + } + // you also need to close the last div, introduce a footer? + return delimit; + } + string special_characters_text(string _txt) { + _txt = _txt + .replaceAll(rgx_xhtml.ampersand, "&") // "&" + .replaceAll(rgx_xhtml.quotation, """) // """ + .replaceAll(rgx_xhtml.less_than, "<") // "<" + .replaceAll(rgx_xhtml.greater_than, ">") // ">" + .replaceAll(rgx.br_line, "
") + .replaceAll(rgx.br_line_inline, "
") + .replaceAll(rgx.br_line_spaced, "
\n
") + .replaceAll(rgx.nbsp_char, " "); + return _txt; + } + string special_characters_date(string _txt) { + _txt = _txt + .replaceAll(regex(r"(?:-00)+"), "") + .replaceAll(rgx.br_line, "
") + .replaceAll(rgx.br_line_inline, "
") + .replaceAll(rgx.br_line_spaced, "
\n
") + .replaceAll(rgx.nbsp_char, " "); + return _txt; + } + string special_characters_breaks_indents_bullets(O)( + const O obj, + ) { + string _txt = special_characters_text(obj.text); + if (obj.metainfo.is_a == "group") { + _txt = (_txt) + .replaceAll(rgx.grouped_para_indent_1, + " ") + .replaceAll(rgx.grouped_para_indent_2, + " ") + .replaceAll(rgx.grouped_para_indent_3, + " ") + .replaceAll(rgx.grouped_para_indent_4, + " ") + .replaceAll(rgx.grouped_para_indent_5, + " ") + .replaceAll(rgx.grouped_para_indent_6, + " ") + .replaceAll(rgx.grouped_para_indent_7, + " ") + .replaceAll(rgx.grouped_para_indent_8, + " ") + .replaceAll(rgx.grouped_para_indent_9, + " ") + .replaceAll(rgx.grouped_para_indent_hang, " ") + .replaceAll(rgx.grouped_para_bullet, "● ") + .replaceAll(rgx.grouped_para_bullet_indent_1, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_2, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_3, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_4, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_5, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_6, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_7, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_8, + " ● ") + .replaceAll(rgx.grouped_para_bullet_indent_9, + " ● "); + } + if (!(obj.metainfo.is_a == "code")) { + _txt = (_txt) + .replaceAll(rgx_xhtml.line_break, "
"); + } + return _txt; + } + string font_face(string _txt) { + _txt = _txt + .replaceAll(rgx.inline_emphasis, ("$1")) + .replaceAll(rgx.inline_bold, ("$1")) + .replaceAll(rgx.inline_underscore, ("$1")) + .replaceAll(rgx.inline_italics, ("$1")) + .replaceAll(rgx.inline_superscript, ("$1")) + .replaceAll(rgx.inline_subscript, ("$1")) + .replaceAll(rgx.inline_strike, ("$1")) + .replaceAll(rgx.inline_insert, ("$1")) + .replaceAll(rgx.inline_mono, ("$1")) + .replaceAll(rgx.inline_cite, ("$1")); + return _txt; + } + string _xhtml_anchor_tags(O)(O obj) { + string tags=""; + if (obj.tags.anchor_tags.length > 0) { + foreach (tag; obj.tags.anchor_tags) { + if (!(tag.empty)) { + tags ~= ""; + } + } + } + return tags; + } + string header_metadata(M)( + M doc_matters, + ) { + string _publisher="Publisher"; // TODO + string o; + o = format(q"┃ + + + + + + + + + + + + + + + ┃", + special_characters_text(doc_matters.conf_make_meta.meta.title_full), + special_characters_text(doc_matters.conf_make_meta.meta.creator_author), + _publisher, + special_characters_date(doc_matters.conf_make_meta.meta.date_published), + special_characters_text(doc_matters.conf_make_meta.meta.date_created), + special_characters_text(doc_matters.conf_make_meta.meta.date_issued), + special_characters_text(doc_matters.conf_make_meta.meta.date_available), + special_characters_text(doc_matters.conf_make_meta.meta.date_valid), + special_characters_text(doc_matters.conf_make_meta.meta.date_modified), + doc_matters.src.language, + special_characters_text(doc_matters.conf_make_meta.meta.rights_copyright), + doc_matters.opt.action.generated_by ? special_characters_text(doc_matters.generator_program.name_and_version) : "", + special_characters_text(doc_matters.generator_program.url_home), + ); + return o; + } + string site_info_button(M)( + M doc_matters, + ) { + string _locations; + if (doc_matters.conf_make_meta.make.home_button_text.length > 0) { + _locations = (doc_matters.conf_make_meta.make.home_button_text) + .replaceAll( + rgx.inline_link, + ("")) + .replaceAll( + rgx.br_line, "") + .replaceAll( + rgx.br_line_inline, ""); + } else { + _locations = "\n\n"; + } + string o; + o = format(q"┃ ┃", + _locations, + ); + return o; + } + string inline_search_form(M)( + M doc_matters, + ) { + string o; + string _form; + if (doc_matters.opt.action.html_link_search) { + o = format(q"┃ + + ┃", + doc_matters.conf_make_meta.conf.w_srv_cgi_action, + (doc_matters.conf_make_meta.conf.w_srv_db_sqlite_filename.empty) + ? "" + : "\n 🔎 ", + (doc_matters.conf_make_meta.conf.w_srv_db_sqlite_filename.empty) + ? "" + : "\n ", + doc_matters.src.filename_base, + doc_matters.conf_make_meta.conf.w_srv_cgi_action, + (doc_matters.conf_make_meta.conf.w_srv_db_sqlite_filename.empty) + ? "" + : "\n ", + doc_matters.src.filename_base, + ); + } else { + o = ""; + } + return o; + } + string html_head(M)( + M doc_matters, + string type, + ) { + string o; + string metadata_links = ((doc_matters.opt.action.html_link_curate) + ? format(q"┃┃", + (doc_matters.opt.action.webserver_url_doc_root.length > 0) + ? doc_matters.opt.action.webserver_url_doc_root + : doc_matters.conf_make_meta.conf.w_srv_data_root_url + , // HOME index.html equivalent _cfg.www_url_doc_root, + (type == "seg") + ? "../" ~ doc_matters.src.filename_base ~ ".html" + : "./" ~ doc_matters.src.filename_base ~ "/toc.html", + (type == "seg") ? "▤" : "※", + (type == "seg") ? "../../" : "../", + doc_matters.src.filename_base, + doc_matters.src.lng, + (doc_matters.opt.action.html_link_pdf || doc_matters.opt.action.html_link_pdf_a4) + ? (" □ ") + : "", + (doc_matters.opt.action.html_link_pdf || doc_matters.opt.action.html_link_pdf_letter) + ? (" □ ") + : "", + (type == "seg") ? "../" : "", + doc_matters.src.filename_base, + (type == "seg") ? "../" : "", + (type == "seg") ? "../" : "", + (type == "seg") ? "../" : "", + ) + : ""); + o = format(q"┃ + + + ++ %s%s + + + %s + + + + + + + ++┃", + special_characters_text(doc_matters.conf_make_meta.meta.title_full), + (doc_matters.conf_make_meta.meta.creator_author.empty) ? "" + : ", " ~ special_characters_text(doc_matters.conf_make_meta.meta.creator_author), + header_metadata(doc_matters), + ((type == "seg") ? "../" : ""), + ((type == "seg") + ? "../../../css/html_seg.css" + : "../../css/html_scroll.css"), + doc_matters.src.language, + site_info_button(doc_matters), + metadata_links, + inline_search_form(doc_matters), + ); + return o; + } + string epub3_seg_head(M)( + M doc_matters, + ) { + string html_base = format(q"┃ + ┃", + ); + string html_simple = format(q"┃ + ┃", + doc_matters.src.language, + doc_matters.src.language, + ); + string html_strict = format(q"┃ + ┃", + doc_matters.src.language, + doc_matters.src.language, + ); + string o; + o = format(q"┃%s + + ++ %s%s + + + + + + + + + + + + + + + + + + + + ┃", + html_simple, + special_characters_text(doc_matters.conf_make_meta.meta.title_full), + (doc_matters.conf_make_meta.meta.creator_author.empty) ? "" + : ", " ~ special_characters_text(doc_matters.conf_make_meta.meta.creator_author), + special_characters_text(doc_matters.conf_make_meta.meta.title_full), + (doc_matters.conf_make_meta.meta.creator_author.empty) ? "" + : ", " ~ special_characters_text(doc_matters.conf_make_meta.meta.creator_author), + special_characters_date(doc_matters.conf_make_meta.meta.date_published), + special_characters_text(doc_matters.conf_make_meta.meta.date_created), + special_characters_text(doc_matters.conf_make_meta.meta.date_issued), + special_characters_text(doc_matters.conf_make_meta.meta.date_available), + special_characters_text(doc_matters.conf_make_meta.meta.date_valid), + special_characters_text(doc_matters.conf_make_meta.meta.date_modified), + doc_matters.src.language, + special_characters_text(doc_matters.conf_make_meta.meta.rights_copyright), + special_characters_text(doc_matters.generator_program.name_and_version), + special_characters_text(doc_matters.generator_program.url_home), + doc_matters.src.language, + ); + return o; + } +string dom_close() { + string o; + o = format(q"┃
+ + %s + +
+++ + + + +┃", + special_characters_text(doc_matters.conf_make_meta.meta.rights_copyright), + ((doc_matters.conf_make_meta.meta.rights_license).empty) ? "" : "+ ≅ SiSU Spine ፨ (object numbering & object search) +
++ (web 1993, object numbering 1997, object search 2002 ...) 2024 +
+
", + ((doc_matters.conf_make_meta.meta.rights_license).empty) ? "" + : "License: " ~ special_characters_text(doc_matters.conf_make_meta.meta.rights_license) + ); + return o; +} + string inline_images(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "seg", + ) { + string _img_pth; + switch (_xml_type) { + case "epub": _img_pth = "image/"; break; + case "scroll": _img_pth = format(q"┃%s/image/┃", "../.."); break; + case "seg": _img_pth = format(q"┃%s/image/┃", "../../.."); break; + default: break; + } + if (_txt.match(rgx.inline_image)) { + _txt = _txt + .replaceAll(rgx.inline_image, + ("$1 $6")) + .replaceAll( + rgx.inline_link_empty, + ("$1")); + } + return _txt; + } + string inline_links(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "seg", + ) { + string seg_lvs; + if (obj.has.inline_links) { + if (obj.metainfo.is_a != "code") { + _txt = replaceAll!(m => + m[1] ~ "┤" + ~ (replaceAll!(n => + n["type"] ~ n["path"] ~ (n["file"].encodeComponent) + )((obj.stow.link[m["num"].to!ulong]).to!string, rgx.uri_identify_components)) + ~ "├" + )(_txt, rgx.inline_link_number_only); + } + if ((_txt.match(rgx.mark_internal_site_lnk)) + && (_xml_type == "scroll")) { // conditions reversed to avoid: gdc compiled program run segfault + _txt = _txt.replaceAll( + rgx.inline_seg_link, + "$1"); + } + if (_xml_type == "seg" || _xml_type == "epub") { + seg_lvs = (_xml_type == "epub") ? "seg_lv1to4" : "seg_lv4"; + foreach (m; _txt.match(rgx.inline_link_hash)) { + if (m.captures["hash"] in doc_matters.has.tag_associations) { + if ( + m.captures["hash"] + == doc_matters.has.tag_associations[(m.captures["hash"])][seg_lvs] + ) { + _txt = _txt.replaceFirst( + rgx.inline_link_hash, + "┥$1┝┤$3" ~ _suffix ~ "├" + ); + } else { + _txt = _txt.replaceFirst( + rgx.inline_link_hash, + "┥$1┝┤" + ~ doc_matters.has.tag_associations[(m.captures["hash"])][seg_lvs] + ~ _suffix ~ "#" ~ "$3" + ~ "├" + ); + } + } else { + if (doc_matters.opt.action.vox_gt0) { + writeln( + "WARNING on internal document links, anchor to link <<" + ~ m.captures["hash"] + ~ ">> not found in document, " + ~ "anchor: " ~ m.captures["hash"] + ~ " document: " ~ doc_matters.src.filename + ); + } + } + } + } + _txt = _txt + .replaceAll( + rgx.inline_link_fn_suffix, + ("$1" ~ _suffix)) + .replaceAll( + rgx.inline_link, + ("$1")) + .replaceAll( + rgx.mark_internal_site_lnk, + ""); + } + debug(markup_links) { + if (_txt.match(rgx.inline_link)) { + writeln(__LINE__, + " (missed) markup link identified (", + obj.has.inline_links, + "): ", obj.metainfo.is_a, ": ", + obj.text + ); + } + } + debug(markup) { + if (_txt.match(rgx.inline_link)) { + writeln(__LINE__, + " (missed) markup link identified (", + obj.has.inline_links, + "): ", obj.metainfo.is_a, ": ", + obj.text + ); + } + } + return _txt; + } + string inline_notes_scroll(O,M)( + string _txt, + const O obj, + M doc_matters, + ) { + if (obj.has.inline_notes_reg) { + _txt = font_face(_txt); + _txt = _txt.replaceAll( + rgx.inline_notes_al_regular_number_note, + ("$1 ") + ); + } + if (obj.has.inline_notes_star) { + _txt = font_face(_txt); + _txt = _txt.replaceAll( + rgx.inline_notes_al_special_char_note, + ("$1 ") + ); + } + debug(markup_endnotes) { + if (_txt.match(rgx.inline_notes_al_regular_number_note)) { + writeln(__LINE__, " (missed) markup endnote: ", obj.metainfo.is_a, ": ", obj.text); + } + } + debug(markup) { + if (_txt.match(rgx.inline_notes_al_regular_number_note)) { + writeln(__LINE__, " (missed) markup endnote: ", obj.metainfo.is_a, ": ", obj.text); + } + } + return _txt; + } + Tuple!(string, string[]) inline_notes_seg(O,M)( + string _txt, + const O obj, + M doc_matters, + ) { + string[] _endnotes; + if (obj.has.inline_notes_star) { + _txt = font_face(_txt); + /+ need markup for text, and separated footnote +/ + foreach(m; _txt.matchAll(rgx.inline_notes_al_special_char_note)) { + _endnotes ~= format( + "%s%s%s%s\n %s%s%s%s%s %s\n%s", + "", + "", + "
" + ); + } + _txt = _txt.replaceAll( + rgx.inline_notes_al_special_char_note, + ("", + m.captures[1], + ". ", + m.captures[2], + "$1 ") + ); + } + if (obj.has.inline_notes_reg) { + _txt = font_face(_txt); + /+ need markup for text, and separated footnote +/ + foreach(m; _txt.matchAll(rgx.inline_notes_al_regular_number_note)) { + _endnotes ~= format( + "%s%s%s%s\n %s%s%s%s%s %s\n%s", + "", + "", + "
" + ); + } + _txt = _txt.replaceAll( + rgx.inline_notes_al_regular_number_note, + ("", + m.captures[1], + ". ", + m.captures[2], + "$1 ") + ); + } else if (_txt.match(rgx.inline_notes_al_regular_number_note)) { + debug(markup) { + writeln(__LINE__, " endnote: ", obj.metainfo.is_a, ": ", obj.text); + } + } + Tuple!(string, string[]) t = tuple( + _txt, + _endnotes, + ); + return t; + } + string inline_markup_scroll(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + ) { + if (obj.metainfo.dummy_heading + && (obj.metainfo.is_a == "toc" || obj.metainfo.is_a == "heading")) { + _txt = ""; + } else { + _txt = inline_images(_txt, obj, doc_matters, _suffix, "scroll"); + _txt = inline_links(_txt, obj, doc_matters, _suffix, "scroll"); + _txt = inline_notes_scroll(_txt, obj, doc_matters); + } + return _txt; + } + Tuple!(string, string[]) inline_markup_seg(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "seg", + ) { + if (obj.metainfo.dummy_heading + && ((_xml_type == "epub" + && (obj.metainfo.is_a == "toc" || obj.metainfo.is_a == "heading")) + || obj.metainfo.is_a == "heading") + ) { + _txt = ""; + } else { + _txt = inline_images(_txt, obj, doc_matters, _suffix, _xml_type); // TODO + _txt = inline_links(_txt, obj, doc_matters, _suffix, _xml_type); // TODO + } + Tuple!(string, string[]) t = inline_notes_seg(_txt, obj, doc_matters); + return t; + } + string lev4_heading_subtoc(O,M)( + const O obj, + M doc_matters, + ) { + char[] lev4_subtoc; + lev4_subtoc ~= "\n"; + foreach (subtoc; obj.tags.lev4_subtoc) { + if (auto m = subtoc.match(rgx.inline_link_subtoc)) { + auto indent = (m.captures[1].to!int - 3).to!string; // css assumptions based on use of em for left margin & indent + auto text = m.captures[2].to!string; + text = font_face(text); + auto link = m.captures[3].to!string; + lev4_subtoc ~= subtoc.replaceFirst(rgx.inline_link_subtoc, + format(q"┃\n"; + return lev4_subtoc.to!string; + } + auto nav_pre_next_svg(O,M)( + const O obj, + M doc_matters, + ) { + string prev, next, toc; + if (obj.tags.segment_anchor_tag_epub == "toc") { + toc = ""; + prev = ""; + } else { + toc = format(q"┃ + ┃", + ); + } + if (obj.tags.segname_prev == "") { + prev = ""; + } else { + prev = format(q"┃ + + ┃", + obj.tags.segname_prev, + ); + } + if (obj.tags.segname_next == "") { + next = ""; + } else { + next = format(q"┃ + + ┃", + obj.tags.segname_next, + ); + } + string _toc_pre_next = format(q"┃ + ┃", + toc, + prev, + next, + ); + string _pre_next = format(q"┃ ┃", + prev, + next, + ); + struct bar { + string toc_pre_next() { + return _toc_pre_next; + } + string pre_next() { + return _pre_next; + } + } + return bar(); + } + string heading(O,M)( + string _txt, + const O obj, + M doc_matters, + string _xml_type = "html", + ) { + assert(obj.metainfo.is_of_part == "body" || "frontmatter" || "backmatter"); + assert(obj.metainfo.is_of_section == "body" || "toc" || "endnotes" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "para"); + assert(obj.metainfo.is_a == "heading"); + string tags = _xhtml_anchor_tags(obj); + string heading_lev_anchor_tag; + string _horizontal_rule = "+ ۰ %s +
+ ┃", + indent, + indent, + link, + text, + )); + } + } + lev4_subtoc ~= "
"; + if ((_xml_type != "html") + || (obj.metainfo.heading_lev_markup == 0 || obj.metainfo.heading_lev_markup > 4)) { + _horizontal_rule = ""; + } + _txt = font_face(_txt); + string o; + heading_lev_anchor_tag = (obj.tags.heading_lev_anchor_tag.empty) + ? "" + : ""; + if (_txt.empty) { + o = format(q"┃%s + ┃", + _horizontal_rule, + ); + } else { + o = ""; + if (obj.metainfo.is_of_section == "toc") { + o ~= format(q"┃ + ┃", + special_characters_text(doc_matters.conf_make_meta.meta.rights_copyright), + special_characters_text(doc_matters.conf_make_meta.meta.rights_license) + ); + } + } + if (!(obj.metainfo.identifier.empty)) { + o ~= format(q"┃%s + ┃", + _horizontal_rule, + obj.metainfo.identifier, + (doc_matters.opt.action.ocn_off) + ? "" : ((obj.metainfo.object_number.empty) + ? "" : obj.metainfo.identifier), + ((_xml_type == "epub" && obj.metainfo.heading_lev_markup == 0) ? 1 + : obj.metainfo.heading_lev_markup), + obj.metainfo.is_a, + obj.metainfo.identifier, + obj.metainfo.identifier, + tags, + heading_lev_anchor_tag, + _txt, + ((_xml_type == "epub" && obj.metainfo.heading_lev_markup == 0) ? 1 + : obj.metainfo.heading_lev_markup), + ); + } else { + o ~= format(q"┃%s ++┃", + _horizontal_rule, + ((_xml_type == "epub" && obj.metainfo.heading_lev_markup == 0) ? 1 + : obj.metainfo.heading_lev_markup), + obj.metainfo.is_a, + tags, + heading_lev_anchor_tag, + _txt, + ((_xml_type == "epub" && obj.metainfo.heading_lev_markup == 0) ? 1 + : obj.metainfo.heading_lev_markup), + ); + } + return o; + } + string heading_scroll(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + ) { + _txt = inline_markup_scroll(_txt, obj, doc_matters, _suffix); + string o = heading(_txt, obj, doc_matters); + return o; + } + Tuple!(string, string[]) heading_seg(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "html", + ) { + Tuple!(string, string[]) t = inline_markup_seg(_txt, obj, doc_matters, _suffix, _xml_type); + _txt = t[0]; + string[] _endnotes = t[1]; + string o = heading(_txt, obj, doc_matters, _xml_type); + Tuple!(string, string[]) u = tuple( + o, + _endnotes, + ); + return u; + } + string para(O,M)( + string _txt, + const O obj, + M doc_matters, + ) { + assert(obj.metainfo.is_of_part == "body" || "frontmatter" || "backmatter"); + assert(obj.metainfo.is_of_section == "body" || "toc" || "endnotes" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "para"); + assert(obj.metainfo.is_a == "para" || "toc" || "endnote" || "glossary" || "bibliography" || "bookindex" || "blurb"); + string tags = _xhtml_anchor_tags(obj); + _txt = font_face(_txt); + string o; + _txt = (obj.attrib.bullet) ? ("● " ~ _txt) : _txt; + _txt = _txt.replaceFirst(rgx.inline_link_anchor, + ""); + if (!(obj.metainfo.identifier.empty)) { + o = format(q"┃%s%s + %s + ++ +┃", + obj.metainfo.identifier, + (doc_matters.opt.action.ocn_off) + ? "" + : ((obj.metainfo.object_number.empty) + ? "" + : obj.metainfo.identifier), + obj.metainfo.is_a, + obj.attrib.indent_hang, + obj.attrib.indent_base, + obj.metainfo.identifier, + tags, + _txt + ); + } else { + o = format(q"┃%s + %s +
++┃", + obj.metainfo.is_a, + obj.attrib.indent_hang, + obj.attrib.indent_base, + tags, + _txt + ); + } + return o; + } + string para_scroll(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + ) { + if (obj.metainfo.is_a == "toc" && _txt.match(rgx.inline_link_toc_to_backmatter)) { + _txt = _txt.replaceAll(rgx.inline_link_toc_to_backmatter, "┤#section_$1├"); + } + _txt = inline_markup_scroll(_txt, obj, doc_matters, _suffix); + string o = para(_txt, obj, doc_matters); + return o; + } + Tuple!(string, string[]) para_seg(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "html", + ) { + Tuple!(string, string[]) t = inline_markup_seg(_txt, obj, doc_matters, _suffix, _xml_type); + _txt = t[0].to!string; + string[] _endnotes = t[1]; + string o = para(_txt, obj, doc_matters); + Tuple!(string, string[]) u = tuple( + o, + _endnotes, + ); + return u; + } + string quote(O,M)( + string _txt, + const O obj, + M doc_matters, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "quote"); + _txt = font_face(_txt); + string o; + if (!(obj.metainfo.identifier.empty)) { + o = format(q"┃%s + %s +
++ +┃", + obj.metainfo.identifier, + (doc_matters.opt.action.ocn_off) ? "" : ((obj.metainfo.object_number.empty) ? "" : obj.metainfo.identifier), + obj.metainfo.is_a, + obj.metainfo.identifier, + _txt + ); + } else { + o = format(q"┃+ %s +
++┃", + obj.metainfo.is_a, + _txt + ); + } + return o; + } + string quote_scroll(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + ) { + _txt = inline_markup_scroll(_txt, obj, doc_matters, _suffix); + string o = quote(_txt, obj, doc_matters); + return o; + } + Tuple!(string, string[]) quote_seg(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "html", + ) { + Tuple!(string, string[]) t = inline_markup_seg(_txt, obj, doc_matters, _suffix, _xml_type); + _txt = t[0].to!string; + string[] _endnotes = t[1]; + string o = quote(_txt, obj, doc_matters); + Tuple!(string, string[]) u = tuple( + o, + _endnotes, + ); + return u; + } + string group(O,M)( + string _txt, + const O obj, + M doc_matters, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "group"); + _txt = font_face(_txt); + string o; + if (!(obj.metainfo.identifier.empty)) { + o = format(q"┃+ %s +
++ +┃", + obj.metainfo.identifier, + (doc_matters.opt.action.ocn_off) ? "" + : ((obj.metainfo.object_number.empty) ? "" + : obj.metainfo.identifier), + obj.metainfo.is_a, + obj.metainfo.identifier, + _txt + ); + } else { + o = format(q"┃+ %s +
++┃", + obj.metainfo.is_a, + _txt + ); + } + return o; + } + string group_scroll(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "html", + ) { + _txt = inline_markup_scroll(_txt, obj, doc_matters, _suffix); + string o = group(_txt, obj, doc_matters); + return o; + } + Tuple!(string, string[]) group_seg(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "html", + ) { + Tuple!(string, string[]) t = inline_markup_seg(_txt, obj, doc_matters, _suffix, _xml_type); + _txt = t[0].to!string; + string[] _endnotes = t[1]; + string o = group(_txt, obj, doc_matters); + Tuple!(string, string[]) u = tuple( + o, + _endnotes, + ); + return u; + } + string block(O,M)( + string _txt, + const O obj, + M doc_matters, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "block"); + _txt = font_face(_txt); + string o; + if (!(obj.metainfo.identifier.empty)) { + o = format(q"┃+ %s +
++ +┃", + obj.metainfo.identifier, + (doc_matters.opt.action.ocn_off) ? "" + : ((obj.metainfo.object_number.empty) ? "" + : obj.metainfo.identifier), + obj.metainfo.is_a, + obj.metainfo.identifier, + _txt.stripRight + ); + } else { + o = format(q"┃%s
++┃", + obj.metainfo.is_a, + _txt.stripRight + ); + } + return o; + } + string block_scroll(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "html", + ) { + _txt = inline_markup_scroll(_txt, obj, doc_matters, _suffix); + string o = block(_txt, obj, doc_matters); + return o; + } + Tuple!(string, string[]) block_seg(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "html", + ) { + Tuple!(string, string[]) t = inline_markup_seg(_txt, obj, doc_matters, _suffix, _xml_type); + _txt = t[0].to!string; + string[] _endnotes = t[1]; + string o = block(_txt, obj, doc_matters); + Tuple!(string, string[]) u = tuple( + o, + _endnotes, + ); + return u; + } + string verse(O,M)( + string _txt, + const O obj, + M doc_matters, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body" || "glossary" || "bibliography" || "bookindex" || "blurb"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "verse"); + _txt = font_face(_txt); + string o; + if (!(obj.metainfo.identifier.empty)) { + o = format(q"┃%s
++ +┃", + obj.metainfo.identifier, + (doc_matters.opt.action.ocn_off) ? "" : ((obj.metainfo.object_number.empty) ? "" : obj.metainfo.identifier), + obj.metainfo.is_a, + obj.metainfo.identifier, + _txt + ); + } else { + o = format(q"┃%s
++┃", + obj.metainfo.is_a, + _txt + ); + } + return o; + } + string verse_scroll(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "html", + ) { + _txt = inline_markup_scroll(_txt, obj, doc_matters, _suffix); + string o = verse(_txt, obj, doc_matters); + return o; + } + Tuple!(string, string[]) verse_seg(O,M)( + string _txt, + const O obj, + M doc_matters, + string _suffix = ".html", + string _xml_type = "html", + ) { + Tuple!(string, string[]) t = inline_markup_seg(_txt, obj, doc_matters, _suffix, _xml_type); + _txt = t[0].to!string; + string[] _endnotes = t[1]; + string o = verse(_txt, obj, doc_matters); + Tuple!(string, string[]) u = tuple( + o, + _endnotes, + ); + return u; + } + Tuple!(string, string) tablarize(O)( + string _txt, + const O obj, + ) { + string[] _table_rows = (_txt).split(rgx.table_delimiter_row); + string[] _table_cols; + string _table; + string _tablenote; + foreach(row_idx, row; _table_rows) { + _table_cols = row.split(rgx.table_delimiter_col); + _table ~= "%s
+"; + foreach(col_idx, cell; _table_cols) { + if ((_table_cols.length == 1) + && (_table_rows.length <= row_idx+2)) { + _tablenote ~= cell; + } else { + string _col_is = (row_idx == 0 && obj.table.heading) ? "th" : "td"; + string _align = ("style=\"text-align:" + ~ ((obj.table.column_aligns[col_idx] == "l") + ? "left\"" : "right\"")); + _table ~= "<" ~ _col_is ~ " width=\"" ~ obj.table.column_widths[col_idx].to!string ~ "%\" " ~ _align ~ ">"; + _table ~= cell; + _table ~= "" ~ _col_is ~ ">"; + } + } + _table ~= " "; + } + Tuple!(string, string) t = tuple( + _table, + _tablenote, + ); + return t; + } + string table(O,M)( + string _txt, + const O obj, + M doc_matters, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "table"); + string tags = _xhtml_anchor_tags(obj); + _txt = font_face(_txt); + auto t = tablarize(_txt, obj); + _txt = t[0]; + string _note = t[1]; + string o; + o = format(q"┃+ +┃", + obj.metainfo.object_number, + (doc_matters.opt.action.ocn_off) ? "" : ((obj.metainfo.object_number.empty) ? "" : obj.metainfo.identifier), + obj.metainfo.is_a, + obj.metainfo.object_number, + tags, + _txt, + _note + ); + return o; + } + string code(O,M)( + string _txt, + const O obj, + M doc_matters, + ) { + assert(obj.metainfo.is_of_part == "body"); + assert(obj.metainfo.is_of_section == "body"); + assert(obj.metainfo.is_of_type == "block"); + assert(obj.metainfo.is_a == "code"); + string o; + string codelines(string _txt) { + string _codelines; + if (obj.code_block.linenumbers) { + string[] _block_lines = (_txt).split(rgx.br_linebreaks_newlines); + _codelines = "%s +
+ %s +
+ %s + +\n"; + foreach (k, _line; _block_lines) { + if (k == 1) { + _codelines ~= format(q"┃"; + } else { + _codelines = "%s + ┃", + _line, + ); + } else { + _codelines ~= format(q"┃%s + ┃", + _line, + ); + } + } + _codelines ~= "\n"; + _codelines ~= _txt; + _codelines ~= ""; + } + return _codelines; + } + if (!(obj.metainfo.identifier.empty)) { + o = format(q"┃+ +┃", + obj.metainfo.identifier, + (doc_matters.opt.action.ocn_off) ? "" : ((obj.metainfo.object_number.empty) ? "" : obj.metainfo.identifier), + obj.metainfo.is_a, + obj.metainfo.identifier, + codelines(_txt) + ); + } else { + o = format(q"┃%s
++┃", + obj.metainfo.is_a, + codelines(_txt) + ); + } + return o; + } + } +} diff --git a/src/sisudoc/io_out/xmls_css.d b/src/sisudoc/io_out/xmls_css.d new file mode 100644 index 0000000..e9f38e6 --- /dev/null +++ b/src/sisudoc/io_out/xmls_css.d @@ -0,0 +1,4451 @@ +/+ +- 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 - 2024 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/] + ++/ +/++ + default css settings ++/ +module sisudoc.io_out.xmls_css; +@safe: +template spineCss() { + import std.format; + auto spineCss(M)(M doc_matters) { + string _css_indent = format(q"┃ +/* indent */ +p.norm { } +p.i1 { padding-left : 1em; } +p.i2 { padding-left : 2em; } +p.i3 { padding-left : 3em; } +p.i4 { padding-left : 4em; } +p.i5 { padding-left : 5em; } +p.i6 { padding-left : 6em; } +p.i7 { padding-left : 7em; } +p.i8 { padding-left : 8em; } +p.i9 { padding-left : 9em; } +/* hanging indent */ +p[indent="h0i0"] { + padding-left : 0em; + text-indent : 0em; +} +p[indent="h0i1"] { + padding-left : 1em; + text-indent : -1em; +} +p[indent="h0i2"] { + padding-left : 2em; + text-indent : -2em; +} +p[indent="h0i3"] { + padding-left : 3em; + text-indent : -3em; +} +p[indent="h0i4"] { + padding-left : 4em; + text-indent : -4em; +} +p[indent="h0i5"] { + padding-left : 5em; + text-indent : -5em; +} +p[indent="h0i6"] { + padding-left : 6em; + text-indent : -6em; +} +p[indent="h0i7"] { + padding-left : 7em; + text-indent : -7em; +} +p[indent="h0i8"] { + padding-left : 8em; + text-indent : -8em; +} +p[indent="h0i9"] { + padding-left : 9em; + text-indent : -9em; +} +p[indent="h1i0"] { + padding-left : 0em; + text-indent : 1em; +} +p[indent="h1i1"] { + padding-left : 1em; + text-indent : 0em; +} +p[indent="h1i2"] { + padding-left : 2em; + text-indent : -1em; +} +p[indent="h1i3"] { + padding-left : 3em; + text-indent : -2em; +} +p[indent="h1i4"] { + padding-left : 4em; + text-indent : -3em; +} +p[indent="h1i5"] { + padding-left : 5em; + text-indent : -4em; +} +p[indent="h1i6"] { + padding-left : 6em; + text-indent : -5em; +} +p[indent="h1i7"] { + padding-left : 7em; + text-indent : -6em; +} +p[indent="h1i8"] { + padding-left : 8em; + text-indent : -7em; +} +p[indent="h1i9"] { + padding-left : 9em; + text-indent : -8em; +} +p[indent="h2i0"] { + padding-left : 0em; + text-indent : 2em; +} +p[indent="h2i1"] { + padding-left : 1em; + text-indent : 1em; +} +p[indent="h2i2"] { + padding-left : 2em; + text-indent : 0em; +} +p[indent="h2i3"] { + padding-left : 3em; + text-indent : -1em; +} +p[indent="h2i4"] { + padding-left : 4em; + text-indent : -2em; +} +p[indent="h2i5"] { + padding-left : 5em; + text-indent : -3em; +} +p[indent="h2i6"] { + padding-left : 6em; + text-indent : -4em; +} +p[indent="h2i7"] { + padding-left : 7em; + text-indent : -5em; +} +p[indent="h2i8"] { + padding-left : 8em; + text-indent : -6em; +} +p[indent="h2i9"] { + padding-left : 9em; + text-indent : -7em; +} +p[indent="h3i0"] { + padding-left : 0em; + text-indent : 3em; +} +p[indent="h3i1"] { + padding-left : 1em; + text-indent : 2em; +} +p[indent="h3i2"] { + padding-left : 2em; + text-indent : 1em; +} +p[indent="h3i3"] { + padding-left : 3em; + text-indent : 0em; +} +p[indent="h3i4"] { + padding-left : 4em; + text-indent : -1em; +} +p[indent="h3i5"] { + padding-left : 5em; + text-indent : -2em; +} +p[indent="h3i6"] { + padding-left : 6em; + text-indent : -3em; +} +p[indent="h3i7"] { + padding-left : 7em; + text-indent : -4em; +} +p[indent="h3i8"] { + padding-left : 8em; + text-indent : -5em; +} +p[indent="h3i9"] { + padding-left : 9em; + text-indent : -6em; +} +p[indent="h4i0"] { + padding-left : 0em; + text-indent : 4em; +} +p[indent="h4i1"] { + padding-left : 1em; + text-indent : 3em; +} +p[indent="h4i2"] { + padding-left : 2em; + text-indent : 2em; +} +p[indent="h4i3"] { + padding-left : 3em; + text-indent : 1em; +} +p[indent="h4i4"] { + padding-left : 4em; + text-indent : 0em; +} +p[indent="h4i5"] { + padding-left : 5em; + text-indent : -1em; +} +p[indent="h4i6"] { + padding-left : 6em; + text-indent : -2em; +} +p[indent="h4i7"] { + padding-left : 7em; + text-indent : -3em; +} +p[indent="h4i8"] { + padding-left : 8em; + text-indent : -4em; +} +p[indent="h4i9"] { + padding-left : 9em; + text-indent : -5em; +} +p[indent="h5i0"] { + padding-left : 0em; + text-indent : 5em; +} +p[indent="h5i1"] { + padding-left : 1em; + text-indent : 4em; +} +p[indent="h5i2"] { + padding-left : 2em; + text-indent : 3em; +} +p[indent="h5i3"] { + padding-left : 3em; + text-indent : 2em; +} +p[indent="h5i4"] { + padding-left : 4em; + text-indent : 1em; +} +p[indent="h5i5"] { + padding-left : 5em; + text-indent : 0em; +} +p[indent="h5i6"] { + padding-left : 6em; + text-indent : -1em; +} +p[indent="h5i7"] { + padding-left : 7em; + text-indent : -2em; +} +p[indent="h5i8"] { + padding-left : 8em; + text-indent : -3em; +} +p[indent="h5i9"] { + padding-left : 9em; + text-indent : -4em; +} +p[indent="h6i0"] { + padding-left : 0em; + text-indent : 6em; +} +p[indent="h6i1"] { + padding-left : 1em; + text-indent : 5em; +} +p[indent="h6i2"] { + padding-left : 2em; + text-indent : 4em; +} +p[indent="h6i3"] { + padding-left : 3em; + text-indent : 3em; +} +p[indent="h6i4"] { + padding-left : 4em; + text-indent : 2em; +} +p[indent="h6i5"] { + padding-left : 5em; + text-indent : 1em; +} +p[indent="h6i6"] { + padding-left : 6em; + text-indent : 0em; +} +p[indent="h6i7"] { + padding-left : 7em; + text-indent : -1em; +} +p[indent="h6i8"] { + padding-left : 8em; + text-indent : -2em; +} +p[indent="h6i9"] { + padding-left : 9em; + text-indent : -3em; +} +p[indent="h7i0"] { + padding-left : 0em; + text-indent : 7em; +} +p[indent="h7i1"] { + padding-left : 1em; + text-indent : 6em; +} +p[indent="h7i2"] { + padding-left : 2em; + text-indent : 5em; +} +p[indent="h7i3"] { + padding-left : 3em; + text-indent : 4em; +} +p[indent="h7i4"] { + padding-left : 4em; + text-indent : 3em; +} +p[indent="h7i5"] { + padding-left : 5em; + text-indent : 2em; +} +p[indent="h7i6"] { + padding-left : 6em; + text-indent : 1em; +} +p[indent="h7i7"] { + padding-left : 7em; + text-indent : 0em; +} +p[indent="h7i8"] { + padding-left : 8em; + text-indent : -1em; +} +p[indent="h7i9"] { + padding-left : 9em; + text-indent : -2em; +} +p[indent="h8i0"] { + padding-left : 0em; + text-indent : 8em; +} +p[indent="h8i1"] { + padding-left : 1em; + text-indent : 7em; +} +p[indent="h8i2"] { + padding-left : 2em; + text-indent : 6em; +} +p[indent="h8i3"] { + padding-left : 3em; + text-indent : 5em; +} +p[indent="h8i4"] { + padding-left : 4em; + text-indent : 4em; +} +p[indent="h8i5"] { + padding-left : 5em; + text-indent : 3em; +} +p[indent="h8i6"] { + padding-left : 6em; + text-indent : 2em; +} +p[indent="h8i7"] { + padding-left : 7em; + text-indent : 1em; +} +p[indent="h8i8"] { + padding-left : 8em; + text-indent : 0em; +} +p[indent="h8i9"] { + padding-left : 9em; + text-indent : -1em; +} +p[indent="h9i0"] { + padding-left : 0em; + text-indent : 9em; +} +p[indent="h9i1"] { + padding-left : 1em; + text-indent : 8em; +} +p[indent="h9i2"] { + padding-left : 2em; + text-indent : 7em; +} +p[indent="h9i3"] { + padding-left : 3em; + text-indent : 6em; +} +p[indent="h9i4"] { + padding-left : 4em; + text-indent : 5em; +} +p[indent="h9i5"] { + padding-left : 5em; + text-indent : 4em; +} +p[indent="h9i6"] { + padding-left : 6em; + text-indent : 3em; +} +p[indent="h9i7"] { + padding-left : 7em; + text-indent : 2em; +} +p[indent="h9i8"] { + padding-left : 8em; + text-indent : 1em; +} +p[indent="h9i9"] { + padding-left : 9em; + text-indent : 0em; +} +┃"); +string _color_ocn_light = (doc_matters.opt.action.ocn_hidden) ? "#FFFFFF" : "#777777"; +string _color_ocn_dark = (doc_matters.opt.action.ocn_hidden) ? "#000000" : "#BBBBBB"; + string _css_light_html_seg = format(q"┃ +html { + font-size : 62.5%%; +} +*{ + padding : 0px; + margin : 0px; +} +body { + height : 100vh; + font-size : 1.6rem; + background-color : #FFFFFF; + color : #000000; + background : #FFFFFF; + background-color : #FFFFFF; +} +a:link { + color : #003399; + text-decoration : none; +} +a:visited { + color : #003399; + text-decoration : none; +} +a:hover { + color : #000000; + background-color : #F9F9AA; +} +a.lnkocn:link { + color : %s; + text-decoration : none; +} +a.lnkocn:visited { + color : #32CD32; + text-decoration : none; +} +a.lnkocn:hover { + color : #777777; + font-size : 1.8rem; +} +a.lnkicon:link { + text-decoration : none; +} +a.lnkicon:visited { + text-decoration : none; +} +a.lnkicon:hover { + font-size : 160%%; +} +a:hover img { + background-color : #FFFFFF; +} +a:active { + color : #003399; + text-decoration : underline; +} +input { + color : #000000; + background-color : #FFFFFF; +} +div { + margin-left : 0; + margin-right : 0; +} +div.p { + margin-left : 5%%; + margin-right : 1%%; +} +div.substance { + width : 100%%; + background-color : #FFFFFF; +} +div.ocn { + width : 5%%; + float : right; + top : 0; + background-color : #FFFFFF; +} +div.endnote { + width : 95%%; + background-color : #FFFFFF; +} +div.toc { + position : absolute; + float : left; + margin : 0; + padding : 0; + padding-top : 0.5em; + border : 0; + width : 13em; + background-color : #EEEEEE; + margin-right : 1em; +} +div.summary { + margin : 0; + padding : 0; + border-left : 13em solid #EEEEEE; + padding-left : 1em; + background-color : #EEEEEE; +} +div.content, div.main_column { + margin : 0; + padding : 0; + border-left : 13em solid #FFFFFF; + padding-left : 1em; + padding-right : 1em; +} +div.content0, div.main_column0 { + margin : 0; + padding : 0; + border-left : 0%% solid #FFFFFF; + padding-left : 5%%; +} +div.scroll { + margin : 0; + padding : 0; + padding-left : 1em; + padding-right : 1em; +} +div.content:after { + content : ' '; + clear : both; + display : block; + height : 0; + overflow : hidden; +} +div.footer { + clear : left; + padding : 0.5em; + font-size : 1.4rem; + margin : 0; +} +div.toc ul { + list-style : none; + padding : 0; + margin : 0; +} +div.toc li ul a, li ul span.currentlink +{ + font-weight : normal; + font-size : 1.5rem; + padding-left : 2em; + background-color : #EEEEEE; +} +div.toc a, span.currentlink{ + display : block; + text-decoration : none; + padding-left : 0.5em; + color : #0000aa; +} +hr { + width : 90%%; + margin-left : 5%%; + margin-right : 2em; + margin-top : 1.8em; + margin-bottom : 1.8em; +} +span.currentlink { + text-decoration : none; + background-color : #AAAAAA; +} +div.toc a:visited { + color : #0000aa; +} +div.toc a:hover { + color : #000000; + background-color : #F9F9AA; +} +nav#toc ol { + list-style-type : none; +} +.norm, .bold, .verse, .group, .block, .alt { + line-height : 133%%; + margin-top : 12px; + margin-bottom : 0px; + padding-left : 0em; + text-indent : 0em; +} +p, h0, h1, h2, h3, h4, h5, h6, h7, ul, li { + display : block; + font-family : verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; + margin-left : 5%%; + margin-right : 2em; +} +p { + font-size : 1.6rem; + font-weight : normal; + line-height : 133%%; + text-align : justify; + text-indent : 0mm; + margin-top : 0.8em; + margin-bottom : 0.8em; +} +img { + max-width : 100%%; + height : auto; +} +pre { + width : auto; + display : block; + clear : both; + color : #555555; +} +pre.codeline { + display : table; + clear : both; + table-layout : fixed; + margin-left : 5%%; + margin-right : 5%%; + width : 90%%; + white-space : pre-wrap; + border-style : none; + border-radius : 5px 5px 5px 5px; + box-shadow : 0 2px 5px #AAAAAA inset; + margin-bottom : 1em; + padding : 0.5em 1em; + page-break-inside : avoid; + word-wrap : break-word; + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + white-space : pre; + white-space : pre-wrap; + white-space : -moz-pre-wrap; + white-space : -o-pre-wrap; + background-color : #EEEEEE; + color : #000000; + font-size : 1.5rem; + line-height : 100%%; +} +pre.codeline::before { + counter-reset : linenum; +} +pre.codeline span.tr { + display : table-row; + counter-increment : linenum; +} +pre.codeline span.th { + display : table-cell; + user-select : none; + -moz-user-select : none; + -webkit-user-select : none; + padding : 0.5em 0.5em; + /* background-color : #666666; */ +} +pre.codeline span.th::before { + content : counter(linenum) "."; + color : #999999; + text-align : right; + display : block; +} +pre.codeline span.th { + width : 4em; +} +pre.codeline code { + display : table-cell; +} +p.code { + border-style : none; +} +p.spaced { white-space : pre; } +p.block { + white-space : pre; +} +p.group { } +p.alt { } +p.verse { + white-space : pre; + margin-bottom : 6px; +} +p.caption { + text-align : left; + font-size : 1.4rem; + display : inline; +} +p.endnote { + font-size : 1.55rem; + line-height : 120%%; + text-align : left; + margin-right : 15mm; + padding-left : 1em; + text-indent : -1em; +} +p.center { + text-align : center; +} +p.bold { + font-weight : bold; +} +p.bold_left { + font-weight : bold; + text-align : left; +} +p.centerbold { + text-align : center; + font-weight : bold; +} +p.em { + font-weight : bold; + font-style : normal; + background : #FFF3B6; +} +.small, .small_center { + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 0px; + margin-right : 6px; +} +p.small { + text-align : left; +} +p.small_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +.tiny, .tiny_left, .tiny_right, .tiny_center { + font-size : 1.2rem; + margin-top : 0px; + margin-bottom : 0px; + color : #777777; + margin-right : 6px; + text-align : left; +} +p.tiny { } +p.tiny_left { + margin-left : 0px; + margin-right : 0px; + text-align : left; +} +p.tiny_right { + margin-right : 1em; + text-align : right; +} +p.tiny_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +p.icons, .icons_center { + font-size : 100%%; + margin-top : 0px; + margin-bottom : 0px; + margin-right : 6px; +} +p.icons { + text-align : left; +} +p.concordance_word { + line-height : 150%%; + font-weight : bold; + display : inline; + margin-top : 4px; + margin-bottom : 1px; +} +p.concordance_count { + font-size : 1.4rem; + color : #777777; + display : inline; + margin-left : 0em; +} +p.concordance_object { + font-size : 1.4rem; + line-height : 120%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +p.book_index_lev1 { + line-height : 100%%; + margin-top : 4px; + margin-bottom : 1px; +} +p.book_index_lev2 { + line-height : 100%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +tt { + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + background-color : #EEEEEE; + color : #000000; +} +%s +note { white-space : pre; } +label.ocn { + width : 2%%; + float : right; + top : 0; + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 6px; + margin-right : 6px; + text-align : right; + color : %s; + -khtml-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + -o-user-select : none; + -webkit-user-select : none; + user-select : none; +} +table { + display : block; + margin-left : 5%%; + margin-right : 2em; + background-color : inherit; +} +tr { } +th,td { + vertical-align : top; + text-align : left; +} +th { + font-weight : bold; +} +em { + font-weight : bold; + font-style : italic; +} +p.left,th.left,td.left { + text-align : left; +} +p.small_left,th.small_left,td.small_left { + text-align : left; + font-size : 1.4rem; +} +p.right,th.right,td.right { + text-align : right; +} +ul, li { + list-style-type : none; + list-style : none; + padding-left : 20px; + font-weight : normal; + line-height : 150%%; + text-align : left; + text-indent : 0mm; + margin-left : 1em; + margin-right : 2em; + margin-top : 3px; + margin-bottom : 3px; +} +li { + background : url(../image_sys/bullet_09.png) no-repeat 0px 6px; +} +ul { } +h0, h1, h2, h3, h4, h5, h6, h7 { + font-weight : bold; + line-height : 120%%; + text-align : left; + margin-top : 20px; + margin-bottom : 10px; +} +h4.norm, h5.norm, h6.norm, h7.norm { + margin-top : 10px; + margin-bottom : 0px; +} +h0 { font-size : 1.85rem; } +h1 { font-size : 1.8rem; } +h2 { font-size : 1.75rem; } +h3 { font-size : 1.7rem; } +h4 { font-size : 1.65rem; } +h5 { font-size : 1.6rem; } +h6 { font-size : 1.55rem; } +h7 { font-size : 1.5rem; } +h0, h1, h2, h3, h4, h5, h6, h7 { + text-shadow : .2em .2em .3em #808080; +} +h1.i { margin-left : 2em; } +h2.i { margin-left : 3em; } +h3.i { margin-left : 4em; } +h4.i { margin-left : 5em; } +h5.i { margin-left : 6em; } +h6.i { margin-left : 7em; } +h7.i { margin-left : 8em; } +h8.i { margin-left : 9em; } +h9.i { margin-left : 10em; } +.toc { + font-weight : normal; + margin-top : 6px; + margin-bottom : 6px; +} +h0.toc { + margin-left : 1em; + font-size : 1.85rem; + line-height : 150%%; +} +h1.toc { + margin-left : 1em; + font-size : 1.8rem; + line-height : 150%%; +} +h2.toc { + margin-left : 2em; + font-size : 1.75rem; + line-height : 140%%; +} +h3.toc { + margin-left : 3em; + font-size : 1.7rem; + line-height : 120%%; +} +h4.toc { + margin-left : 4em; + font-size : 1.65rem; + line-height : 120%%; +} +h5.toc { + margin-left : 5em; + font-size : 1.6rem; + line-height : 110%%; +} +h6.toc { + margin-left : 6em; + font-size : 1.55rem; + line-height : 110%%; +} +h7.toc { + margin-left : 7em; + font-size : 1.5rem; + line-height : 100%%; +} +.subtoc { + margin-right : 34%%; + font-weight : normal; +} +h5.subtoc { + margin-left : 2em; + font-size : 1.45rem; + margin-top : 2px; + margin-bottom : 2px; +} +h6.subtoc { + margin-left : 3em; + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 0px; +} +h7.subtoc { + margin-left : 4em; + font-size : 1.35rem; + margin-top : 0px; + margin-bottom : 0px; +} +input, select, textarea { + font-size : 2.2rem; +} +input[type="text"] { + font-size : 1.8rem; + line-height : 120%%; +} +button[type="submit"] { + font-size : 1.8rem; + line-height : 120%%; +} +p.form { + font-size : 2.2rem; + line-height : 150%%; +} +.icon-bar { + width : 100%%; + overflow : auto; + margin : 0em 0em 0em; +} +.left-bar { + width : 85%%; + float : left; + display : inline; + overflow : auto; +} +.toc-button { + position : absolute; + top : 8px; + width : 3em; + height : 3em; + border-radius : 50%%; + background : #CCCCCC; + fill : #333333; + box-shadow : 0 2px 5px #AAAAAA inset; +} +.toc-button svg { + position : relative; + left : 25%%; + top : 25%%; + width : 150%%; + height : 150%%; +} +.toc-button p { + vertical-align : center; + font-size : 1.8rem; +} +.prev-next-button { + position : absolute; + top : 8px; + width : 3em; + height : 3em; + border-radius : 50%%; + background : #CCCCCC; + box-shadow : 0 2px 5px #AAAAAA inset; +} +.prev-next-button svg { + position : relative; + left : 20%%; + top : 20%%; + width : 60%%; + height : 60%%; +} +.menu { + right : 8em; + } +.previous { + right : 4em; + } +.next { + right : 0em; + } +.arrow { + fill : #333333; +} +.minitoc { + line-height : 120%%; + font-size : 1.6rem; + margin-top : 6px; + margin-bottom : 0px; + padding-left : 0em; + text-indent : 0em; + -khtml-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + -o-user-select : none; + -webkit-user-select : none; + user-select : none; +} +/* flex */ +.flex-menu-bar { + display : -webkit-flex; + display : flex; + -webkit-flex-wrap : wrap; + -webkit-align-items : center; + align-items : center; + width : 100%%; + margin-left : 5%%; + margin-right : 2%%; + background-color : #FFFFFF; +} +.flex-menu-option { + background-color : #FFFFFF; + margin-right : 4px; +} +.flex-list { + display : -webkit-flex; + display : flex; + -webkit-align-items : center; + display : block; + align-items : center; + width : 100%%; + background-color : #FFFFFF; +} +.flex-list-item { + background-color : #FFFFFF; + margin : 4px; +} +/* grid */ +.wrapper { + display : grid; + grid-template-columns : 100%%; + grid-template-areas : + "headband" + "doc_header" + "doc_title" + "doc_toc" + "doc_prefix" + "doc_intro" + "doc_body" + "doc_endnotes" + "doc_glossary" + "doc_biblio" + "doc_bookindex" + "doc_blurb" + "doc_suffix"; + margin : 0px; + padding : 0px; + background-color : #FFFFFF; +} +.delimit { + border-style : none; + border-color : #FFFFFF; + padding : 10px; +} +.headband { + grid-area : headband; + background-color : #FFFFFF; +} +.doc_header { + grid-area : doc_header; +} +.doc_title { + grid-area : doc_title; +} +.doc_toc { + grid-area : doc_toc; +} +.doc_prefix { + grid-area : doc_prefix; +} +.doc_intro { + grid-area : doc_intro; +} +.doc_body { + grid-area : doc_body; +} +.doc_endnotes { + grid-area : doc_endnotes; +} +.doc_glossary { + grid-area : doc_glossary; +} +.doc_biblio { + grid-area : doc_biblio; +} +.doc_bookindex { + grid-area : doc_bookindex; +} +.doc_blurb { + grid-area : doc_blurb; +} +.doc_suffix { + grid-area : doc_suffix; +} +.nav-ul { + list-style : none; + float : left; +} +.nav-li { + float : left; + padding-right : 0.7em; +} +.nav-li a { + text-decoration : none; + color : #FFFFFF; +} +footer { + background-color : #00704E; +} +┃", + _color_ocn_light, + _css_indent, + _color_ocn_light, +); + string _css_dark_html_seg = format(q"┃ +html { +} +*{ + padding : 0px; + margin : 0px; +} +body { + height : 100vh; + background-color : #000000; + color : #CCCCCC; + background : #000000; + background-color : #000000; +} +a:link { + color : #FFFFFF; + text-decoration : none; +} +a:visited { + color : #999999; + text-decoration : none; +} +a:hover { + color : #000000; + background-color : #555555; +} +a.lnkocn:link { + color : %s; + text-decoration : none; +} +a.lnkocn:visited { + color : #9ACD32; + text-decoration : none; +} +a.lnkocn:hover { + color : #BBBBBB; + font-size : 1.8rem; +} +a.lnkicon:link { + text-decoration : none; +} +a.lnkicon:visited { + text-decoration : none; +} +a.lnkicon:hover { + color : #BBBBBB; + font-size : 120%%; +} +a:hover img { + background-color : #000000; +} +a:active { + color : #888888; + text-decoration : underline; +} +input { + color : #FFFFFF; + background-color : #777777; +} +div { + margin-left : 0; + margin-right : 0; +} +div.p { + margin-left : 5%%; + margin-right : 1%%; +} +div.substance { + width : 100%%; + background-color : #000000; +} +div.ocn { + width : 5%%; + float : right; + top : 0; + background-color : #000000; +} +div.endnote { + width : 95%%; + background-color : #000000; +} +div.toc { + position : absolute; + float : left; + margin : 0; + padding : 0; + padding-top : 0.5em; + border : 0; + width : 13em; + background-color : #111111; + margin-right : 1em; +} +div.summary { + margin : 0; + padding : 0; + border-left : 13em solid #111111; + padding-left : 1em; + background-color : #111111; +} +div.content, div.main_column { + margin : 0; + padding : 0; + border-left : 13em solid #000000; + padding-left : 1em; + padding-right : 1em; +} +div.content0, div.main_column0 { + margin : 0; + padding : 0; + border-left : 0%% solid #000000; + padding-left : 5%%; +} +div.scroll { + margin : 0; + padding : 0; + padding-left : 1em; + padding-right : 1em; +} +div.content:after { + content : ' '; + clear : both; + display : block; + height : 0; + overflow : hidden; +} +div.footer { + clear : left; + padding : 0.5em; + font-size : 1.4rem; + margin : 0; +} +div.toc ul { + list-style : none; + padding : 0; + margin : 0; +} +div.toc li ul a, li ul span.currentlink +{ + font-weight : normal; + font-size : 1.5rem; + padding-left : 2em; + background-color : #111111; +} +div.toc a, span.currentlink{ + display : block; + text-decoration : none; + padding-left : 0.5em; + color : #FF00AA; +} +hr { + width : 90%%; + margin-left : 5%%; + margin-right : 2em; + margin-top : 1.8em; + margin-bottom : 1.8em; +} +span.currentlink { + text-decoration : none; + background-color : #AAAAF9; +} +div.toc a:visited { + color : #FF00AA; +} +div.toc a:hover { + color : #CCCCCC; + background-color : #F9F9AA; +} +nav#toc ol { + list-style-type : none; +} +.norm, .bold, .verse, .group, .block, .alt { + line-height : 133%%; + margin-top : 12px; + margin-bottom : 0px; + padding-left : 0em; + text-indent : 0em; +} +p, h0, h1, h2, h3, h4, h5, h6, h7, ul, li { + display : block; + font-family : verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; + margin-left : 5%%; + margin-right : 2em; +} +p { + font-size : 1.6rem; + font-weight : normal; + line-height : 133%%; + text-align : justify; + text-indent : 0mm; + margin-top : 0.8em; + margin-bottom : 0.8em; +} +img { + max-width : 100%%; + height : auto; +} +pre { + width : auto; + display : block; + clear : both; + color : #555555; +} +pre.codeline { + display : table; + clear : both; + table-layout : fixed; + margin-left : 5%%; + margin-right : 5%%; + width : 90%%; + white-space : pre-wrap; + border-style : none; + border-radius : 5px 5px 5px 5px; + box-shadow : 0 2px 5px #AAAAAA inset; + margin-bottom : 1em; + padding : 0.5em 1em; + page-break-inside : avoid; + word-wrap : break-word; + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + white-space : pre; + white-space : pre-wrap; + white-space : -moz-pre-wrap; + white-space : -o-pre-wrap; + background-color : #555555; + color : #DDDDDD; + font-size : 1.5rem; + line-height : 100%%; +} +pre.codeline::before { + counter-reset : linenum; +} +pre.codeline span.tr { + display : table-row; + counter-increment : linenum; +} +pre.codeline span.th { + display : table-cell; + user-select : none; + -moz-user-select : none; + -webkit-user-select : none; + padding : 0.5em 0.5em; +} +pre.codeline span.th::before { + content : counter(linenum) "."; + color : #999999; + text-align : right; + display : block; +} +pre.codeline span.th { + width : 4em; +} +pre.codeline code { + display : table-cell; +} +p.code { + border-style : none; +} +p.spaced { white-space : pre; } +p.block { + white-space : pre; +} +p.group { } +p.alt { } +p.verse { + white-space : pre; + margin-bottom : 6px; +} +p.caption { + text-align : left; + font-size : 1.4rem; + display : inline; +} +p.endnote { + font-size : 1.5rem; + line-height : 120%%; + text-align : left; + margin-right : 15mm; + padding-left : 1em; + text-indent : -1em; +} +p.center { + text-align : center; +} +p.bold { + font-weight : bold; +} +p.bold_left { + font-weight : bold; + text-align : left; +} +p.centerbold { + text-align : center; + font-weight : bold; +} +p.em { + font-weight : bold; + font-style : normal; + background : #FFF3B6; +} +.small, .small_center { + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 0px; + margin-right : 6px; +} +p.small { + text-align : left; +} +p.small_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +.tiny, .tiny_left, .tiny_right, .tiny_center { + font-size : 1.35rem; + margin-top : 0px; + margin-bottom : 0px; + color : #EEEEEE; + margin-right : 6px; + text-align : left; +} +p.tiny { } +p.tiny_left { + margin-left : 0px; + margin-right : 0px; + text-align : left; +} +p.tiny_right { + margin-right : 1em; + text-align : right; +} +p.tiny_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +p.concordance_word { + line-height : 150%%; + font-weight : bold; + display : inline; + margin-top : 4px; + margin-bottom : 1px; +} +p.concordance_count { + font-size : 1.4rem; + color : #555555; + display : inline; + margin-left : 0em; +} +p.concordance_object { + font-size : 1.4rem; + line-height : 120%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +p.book_index_lev1 { + line-height : 100%%; + margin-top : 4px; + margin-bottom : 1px; +} +p.book_index_lev2 { + line-height : 100%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +tt { + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + background-color : #555555; + color : #DDDDDD; +} +%s +note { white-space : pre; } +label.ocn { + width : 2%%; + float : right; + top : 0; + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 6px; + margin-right : 6px; + text-align : right; + color : %s; + -khtml-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + -o-user-select : none; + -webkit-user-select : none; + user-select : none; +} +table { + display : block; + margin-left : 5%%; + margin-right : 2em; + background-color : inherit; +} +tr { } +th,td { + vertical-align : top; + text-align : left; +} +th { + font-weight : bold; +} +em { + font-weight : bold; + font-style : italic; +} +p.left,th.left,td.left { + text-align : left; +} +p.small_left,th.small_left,td.small_left { + text-align : left; + font-size : 1.4rem; +} +p.right,th.right,td.right { + text-align : right; +} +ul, li { + list-style-type : none; + list-style : none; + padding-left : 20px; + font-weight : normal; + line-height : 150%%; + text-align : left; + text-indent : 0mm; + margin-left : 1em; + margin-right : 2em; + margin-top : 3px; + margin-bottom : 3px; +} +li { + background : (../image_sys/bullet_09.png) no-repeat 0px 6px; +} +ul { } +h0, h1, h2, h3, h4, h5, h6, h7 { + font-weight : bold; + line-height : 120%%; + text-align : left; + margin-top : 20px; + margin-bottom : 10px; +} +h4.norm, h5.norm, h6.norm, h7.norm { + margin-top : 10px; + margin-bottom : 0px; +} +h0 { font-size : 1.9rem; } +h1 { font-size : 1.8rem; } +h2 { font-size : 1.75rem; } +h3 { font-size : 1.7rem; } +h4 { font-size : 1.65rem; } +h5 { font-size : 1.6rem; } +h6 { font-size : 1.55rem; } +h7 { font-size : 1.5rem; } +h0, h1, h2, h3, h4, h5, h6, h7 { + text-shadow : .2em .2em .3em #999999; +} +h1.i { margin-left : 2em; } +h2.i { margin-left : 3em; } +h3.i { margin-left : 4em; } +h4.i { margin-left : 5em; } +h5.i { margin-left : 6em; } +h6.i { margin-left : 7em; } +h7.i { margin-left : 8em; } +h8.i { margin-left : 9em; } +h9.i { margin-left : 10em; } +.toc { + font-weight : normal; + margin-top : 6px; + margin-bottom : 6px; +} +h0.toc { + margin-left : 1em; + font-size : 1.8rem; + line-height : 150%%; +} +h1.toc { + margin-left : 1em; + font-size : 1.75rem; + line-height : 150%%; +} +h2.toc { + margin-left : 2em; + font-size : 1.7rem; + line-height : 140%%; +} +h3.toc { + margin-left : 3em; + font-size : 1.65rem; + line-height : 120%%; +} +h4.toc { + margin-left : 4em; + font-size : 1.6rem; + line-height : 120%%; +} +h5.toc { + margin-left : 5em; + font-size : 1.5rem; + line-height : 110%%; +} +h6.toc { + margin-left : 6em; + font-size : 1.5rem; + line-height : 110%%; +} +h7.toc { + margin-left : 7em; + font-size : 1.45rem; + line-height : 100%%; +} +.subtoc { + margin-right : 34%%; + font-weight : normal; +} +h5.subtoc { + margin-left : 2em; + font-size : 1.4rem; + margin-top : 2px; + margin-bottom : 2px; +} +h6.subtoc { + margin-left : 3em; + font-size : 1.35; + margin-top : 0px; + margin-bottom : 0px; +} +h7.subtoc { + margin-left : 4em; + font-size : 1.3rem; + margin-top : 0px; + margin-bottom : 0px; +} +input, select, textarea { + font-size : 2.2rem; +} +input[type="text"] { + font-size : 1.8rem; + line-height : 120%%; +} +button[type="submit"] { + font-size : 1.8rem; + line-height : 120%%; +} +p.form { + font-size : 2.2rem; + line-height : 150%%; +} +.icon-bar { + width : 100%%; + overflow : auto; + margin : 0em 0em 0em; +} +.left-bar { + width : 85%%; + float : left; + display : inline; + overflow : auto; +} +.toc-button { + position : absolute; + top : 8px; + width : 3em; + height : 3em; + border-radius : 50%%; + background : #555555; + fill : #DDDDDD; + box-shadow : 0 2px 5px #EEEEEE inset; +} +.toc-button svg { + position : relative; + left : 25%%; + top : 25%%; + width : 150%%; + height : 150%%; +} +.toc-button p { + vertical-align : center; + font-size : 1.8rem; +} +.prev-next-button { + position : absolute; + top : 8px; + width : 3em; + height : 3em; + border-radius : 50%%; + background : #555555; + box-shadow : 0 2px 5px #AAAAAA inset; +} +.prev-next-button svg { + position : relative; + left : 20%%; + top : 20%%; + width : 60%%; + height : 60%%; +} +.menu { + right : 8em; + } +.previous { + right : 4em; + } +.next { + right : 0em; + } +.arrow { + fill : #DDDDDD; +} +.minitoc { + line-height : 120%%; + font-size : 1.6rem; + margin-top : 6px; + margin-bottom : 0px; + padding-left : 0em; + text-indent : 0em; + -khtml-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + -o-user-select : none; + -webkit-user-select : none; + user-select : none; +} +/* flex */ +.flex-menu-bar { + display : -webkit-flex; + display : flex; + -webkit-flex-wrap : wrap; + -webkit-align-items : center; + align-items : center; + width : 100%%; + margin-left : 5%%; + margin-right : 2%%; + background-color : #000000; +} +.flex-menu-option { + background-color : #000000; + margin-right : 4px; +} +.flex-list { + display : -webkit-flex; + display : flex; + -webkit-align-items : center; + display : block; + align-items : center; + width : 100%%; + background-color : #000000; +} +.flex-list-item { + background-color : #000000; + margin : 4px; +} +/* grid */ +.wrapper { + display : grid; + grid-template-columns : 100%%; + grid-template-areas : + "headband" + "doc_header" + "doc_title" + "doc_toc" + "doc_prefix" + "doc_intro" + "doc_body" + "doc_endnotes" + "doc_glossary" + "doc_biblio" + "doc_bookindex" + "doc_blurb" + "doc_suffix"; + margin : 0px; + padding : 0px; + background-color : #000000; +} +.delimit { + border-style : none; + border-color : #000000; + padding : 10px; +} +.headband { + grid-area : headband; + background-color : #000000; +} +.doc_header { + grid-area : doc_header; +} +.doc_title { + grid-area : doc_title; +} +.doc_toc { + grid-area : doc_toc; +} +.doc_prefix { + grid-area : doc_prefix; +} +.doc_intro { + grid-area : doc_intro; +} +.doc_body { + grid-area : doc_body; +} +.doc_endnotes { + grid-area : doc_endnotes; +} +.doc_glossary { + grid-area : doc_glossary; +} +.doc_biblio { + grid-area : doc_biblio; +} +.doc_bookindex { + grid-area : doc_bookindex; +} +.doc_blurb { + grid-area : doc_blurb; +} +.doc_suffix { + grid-area : doc_suffix; +} +.nav-ul { + list-style : none; + float : left; +} +.nav-li { + float : left; + padding-right : 0.7em; +} +.nav-li a { + text-decoration : none; + color : #000000; +} +footer { + background-color : #FF704E; +} +┃", + _color_ocn_dark, + _css_indent, + _color_ocn_dark, +); + string _css_light_html_scroll = format(q"┃ +html { + font-size : 62.5%%; +} +*{ + padding : 0px; + margin : 0px; +} +body { + height : 100vh; + font-size : 1.6rem; + background-color : #FFFFFF; + color : #000000; + background : #FFFFFF; + background-color : #FFFFFF; +} +a:link { + color : #003399; + text-decoration : none; +} +a:visited { + color : #003399; + text-decoration : none; +} +a:hover { + color : #000000; + background-color : #F9F9AA; +} +a.lnkocn:link { + color : %s; + text-decoration : none; +} +a.lnkocn:visited { + color : #32CD32; + text-decoration : none; +} +a.lnkocn:hover { + color : #777777; + font-size : 1.8rem; +} +a.lnkicon:link { + text-decoration : none; +} +a.lnkicon:visited { + text-decoration : none; +} +a.lnkicon:hover { + font-size : 160%%; +} +a:hover img { + background-color : #FFFFFF; +} +a:active { + color : #003399; + text-decoration : underline; +} +input { + color : #000000; + background-color : #FFFFFF; +} +div { + margin-left : 0; + margin-right : 0; +} +div.p { + margin-left : 5%%; + margin-right : 1%%; +} +div.substance { + width : 100%%; + background-color : #FFFFFF; +} +div.ocn { + width : 5%%; + float : right; + top : 0; + background-color : #FFFFFF; +} +div.endnote { + width : 95%%; + background-color : #FFFFFF; +} +div.toc { + position : absolute; + float : left; + margin : 0; + padding : 0; + padding-top : 0.5em; + border : 0; + width : 13em; + background-color : #EEEEEE; + margin-right : 1em; +} +div.summary { + margin : 0; + padding : 0; + border-left : 13em solid #EEEEEE; + padding-left : 1em; + background-color : #EEEEEE; +} +div.content, div.main_column { + margin : 0; + padding : 0; + border-left : 13em solid #FFFFFF; + padding-left : 1em; + padding-right : 1em; +} +div.content0, div.main_column0 { + margin : 0; + padding : 0; + border-left : 0%% solid #FFFFFF; + padding-left : 5%%; +} +div.scroll { + margin : 0; + padding : 0; + padding-left : 1em; + padding-right : 1em; +} +div.content:after { + content : ' '; + clear : both; + display : block; + height : 0; + overflow : hidden; +} +div.footer { + clear : left; + padding : 0.5em; + font-size : 1.4rem; + margin : 0; +} +div.toc ul { + list-style : none; + padding : 0; + margin : 0; +} +div.toc li ul a, li ul span.currentlink +{ + font-weight : normal; + font-size : 1.5rem; + padding-left : 2em; + background-color : #EEEEEE; +} +div.toc a, span.currentlink{ + display : block; + text-decoration : none; + padding-left : 0.5em; + color : #0000aa; +} +hr { + width : 90%%; + margin-left : 5%%; + margin-right : 2em; + margin-top : 1.8em; + margin-bottom : 1.8em; +} +span.currentlink { + text-decoration : none; + background-color : #AAAAAA; +} +div.toc a:visited { + color : #0000aa; +} +div.toc a:hover { + color : #000000; + background-color : #F9F9AA; +} +nav#toc ol { + list-style-type : none; +} +.norm, .bold, .verse, .group, .block, .alt { + line-height : 133%%; + margin-top : 12px; + margin-bottom : 0px; + padding-left : 0em; + text-indent : 0em; +} +p, h0, h1, h2, h3, h4, h5, h6, h7, ul, li { + display : block; + font-family : verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; + margin-left : 5%%; + margin-right : 2em; +} +p { + font-size : 1.6rem; + font-weight : normal; + line-height : 133%%; + text-align : justify; + text-indent : 0mm; + margin-top : 0.8em; + margin-bottom : 0.8em; +} +img { + max-width : 100%%; + height : auto; +} +pre { + width : auto; + display : block; + clear : both; + color : #555555; +} +pre.codeline { + display : table; + clear : both; + table-layout : fixed; + margin-left : 5%%; + margin-right : 5%%; + width : 90%%; + white-space : pre-wrap; + border-style : none; + border-radius : 5px 5px 5px 5px; + box-shadow : 0 2px 5px #AAAAAA inset; + margin-bottom : 1em; + padding : 0.5em 1em; + page-break-inside : avoid; + word-wrap : break-word; + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + white-space : pre; + white-space : pre-wrap; + white-space : -moz-pre-wrap; + white-space : -o-pre-wrap; + background-color : #EEEEEE; + color : #000000; + font-size : 1.5rem; + line-height : 100%%; +} +pre.codeline::before { + counter-reset : linenum; +} +pre.codeline span.tr { + display : table-row; + counter-increment : linenum; +} +pre.codeline span.th { + display : table-cell; + user-select : none; + -moz-user-select : none; + -webkit-user-select : none; + padding : 0.5em 0.5em; + /* background-color : #666666; */ +} +pre.codeline span.th::before { + content : counter(linenum) "."; + color : #999999; + text-align : right; + display : block; +} +pre.codeline span.th { + width : 4em; +} +pre.codeline code { + display : table-cell; +} +p.code { + border-style : none; +} +p.spaced { white-space : pre; } +p.block { + white-space : pre; +} +p.group { } +p.alt { } +p.verse { + white-space : pre; + margin-bottom : 6px; +} +p.caption { + text-align : left; + font-size : 1.4rem; + display : inline; +} +p.endnote { + font-size : 1.55rem; + line-height : 120%%; + text-align : left; + margin-right : 15mm; + padding-left : 1em; + text-indent : -1em; +} +p.center { + text-align : center; +} +p.bold { + font-weight : bold; +} +p.bold_left { + font-weight : bold; + text-align : left; +} +p.centerbold { + text-align : center; + font-weight : bold; +} +p.em { + font-weight : bold; + font-style : normal; + background : #FFF3B6; +} +.small, .small_center { + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 0px; + margin-right : 6px; +} +p.small { + text-align : left; +} +p.small_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +.tiny, .tiny_left, .tiny_right, .tiny_center { + font-size : 1.2rem; + margin-top : 0px; + margin-bottom : 0px; + color : #777777; + margin-right : 6px; + text-align : left; +} +p.tiny { } +p.tiny_left { + margin-left : 0px; + margin-right : 0px; + text-align : left; +} +p.tiny_right { + margin-right : 1em; + text-align : right; +} +p.tiny_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +p.icons, .icons_center { + font-size : 100%%; + margin-top : 0px; + margin-bottom : 0px; + margin-right : 6px; +} +p.icons { + text-align : left; +} +p.concordance_word { + line-height : 150%%; + font-weight : bold; + display : inline; + margin-top : 4px; + margin-bottom : 1px; +} +p.concordance_count { + font-size : 1.4rem; + color : #777777; + display : inline; + margin-left : 0em; +} +p.concordance_object { + font-size : 1.4rem; + line-height : 120%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +p.book_index_lev1 { + line-height : 100%%; + margin-top : 4px; + margin-bottom : 1px; +} +p.book_index_lev2 { + line-height : 100%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +tt { + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + background-color : #EEEEEE; + color : #000000; +} +%s +note { white-space : pre; } +label.ocn { + width : 2%%; + float : right; + top : 0; + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 6px; + margin-right : 6px; + text-align : right; + color : %s; + -khtml-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + -o-user-select : none; + -webkit-user-select : none; + user-select : none; +} +table { + display : block; + margin-left : 5%%; + margin-right : 2em; + background-color : inherit; +} +tr { } +th,td { + vertical-align : top; + text-align : left; +} +th { + font-weight : bold; +} +em { + font-weight : bold; + font-style : italic; +} +p.left,th.left,td.left { + text-align : left; +} +p.small_left,th.small_left,td.small_left { + text-align : left; + font-size : 1.4rem; +} +p.right,th.right,td.right { + text-align : right; +} +ul, li { + list-style-type : none; + list-style : none; + padding-left : 20px; + font-weight : normal; + line-height : 150%%; + text-align : left; + text-indent : 0mm; + margin-left : 1em; + margin-right : 2em; + margin-top : 3px; + margin-bottom : 3px; +} +li { + background : url(../image_sys/bullet_09.png) no-repeat 0px 6px; +} +ul { } +h0, h1, h2, h3, h4, h5, h6, h7 { + font-weight : bold; + line-height : 120%%; + text-align : left; + margin-top : 20px; + margin-bottom : 10px; +} +h4.norm, h5.norm, h6.norm, h7.norm { + margin-top : 10px; + margin-bottom : 0px; +} +h0 { font-size : 1.85rem; } +h1 { font-size : 1.8rem; } +h2 { font-size : 1.75rem; } +h3 { font-size : 1.7rem; } +h4 { font-size : 1.65rem; } +h5 { font-size : 1.6rem; } +h6 { font-size : 1.55rem; } +h7 { font-size : 1.5rem; } +h0, h1, h2, h3, h4, h5, h6, h7 { + text-shadow : .2em .2em .3em #808080; +} +h1.i { margin-left : 2em; } +h2.i { margin-left : 3em; } +h3.i { margin-left : 4em; } +h4.i { margin-left : 5em; } +h5.i { margin-left : 6em; } +h6.i { margin-left : 7em; } +h7.i { margin-left : 8em; } +h8.i { margin-left : 9em; } +h9.i { margin-left : 10em; } +.toc { + font-weight : normal; + margin-top : 6px; + margin-bottom : 6px; +} +h0.toc { + margin-left : 1em; + font-size : 1.85rem; + line-height : 150%%; +} +h1.toc { + margin-left : 1em; + font-size : 1.8rem; + line-height : 150%%; +} +h2.toc { + margin-left : 2em; + font-size : 1.75rem; + line-height : 140%%; +} +h3.toc { + margin-left : 3em; + font-size : 1.7rem; + line-height : 120%%; +} +h4.toc { + margin-left : 4em; + font-size : 1.65rem; + line-height : 120%%; +} +h5.toc { + margin-left : 5em; + font-size : 1.6rem; + line-height : 110%%; +} +h6.toc { + margin-left : 6em; + font-size : 1.55rem; + line-height : 110%%; +} +h7.toc { + margin-left : 7em; + font-size : 1.5rem; + line-height : 100%%; +} +.subtoc { + margin-right : 34%%; + font-weight : normal; +} +h5.subtoc { + margin-left : 2em; + font-size : 1.45rem; + margin-top : 2px; + margin-bottom : 2px; +} +h6.subtoc { + margin-left : 3em; + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 0px; +} +h7.subtoc { + margin-left : 4em; + font-size : 1.35rem; + margin-top : 0px; + margin-bottom : 0px; +} +input, select, textarea { + font-size : 2.2rem; +} +input[type="text"] { + font-size : 1.8rem; + line-height : 120%%; +} +button[type="submit"] { + font-size : 1.8rem; + line-height : 120%%; +} +p.form { + font-size : 2.2rem; + line-height : 150%%; +} +/* flex */ +.flex-menu-bar { + display : -webkit-flex; + display : flex; + -webkit-flex-wrap : wrap; + -webkit-align-items : center; + align-items : center; + width : 100%%; + margin-left : 5%%; + margin-right : 2%%; + background-color : #FFFFFF; +} +.flex-menu-option { + background-color : #FFFFFF; + margin-right : 4px; +} +.flex-list { + display : -webkit-flex; + display : flex; + -webkit-align-items : center; + display : block; + align-items : center; + width : 100%%; + background-color : #FFFFFF; +} +.flex-list-item { + background-color : #FFFFFF; + margin : 4px; +} +/* grid */ +.wrapper { + display : grid; + grid-template-columns : 100%%; + grid-template-areas : + "headband" + "doc_header" + "doc_title" + "doc_toc" + "doc_prefix" + "doc_intro" + "doc_body" + "doc_endnotes" + "doc_glossary" + "doc_biblio" + "doc_bookindex" + "doc_blurb" + "doc_suffix"; + margin : 0px; + padding : 0px; + background-color : #FFFFFF; +} +.delimit { + border-style : none; + border-color : #FFFFFF; + padding : 10px; +} +.headband { + grid-area : headband; + background-color : #FFFFFF; +} +.doc_header { + grid-area : doc_header; +} +.doc_title { + grid-area : doc_title; +} +.doc_toc { + grid-area : doc_toc; +} +.doc_prefix { + grid-area : doc_prefix; +} +.doc_intro { + grid-area : doc_intro; +} +.doc_body { + grid-area : doc_body; +} +.doc_endnotes { + grid-area : doc_endnotes; +} +.doc_glossary { + grid-area : doc_glossary; +} +.doc_biblio { + grid-area : doc_biblio; +} +.doc_bookindex { + grid-area : doc_bookindex; +} +.doc_blurb { + grid-area : doc_blurb; +} +.doc_suffix { + grid-area : doc_suffix; +} +.nav-ul { + list-style : none; + float : left; +} +.nav-li { + float : left; + padding-right : 0.7em; +} +.nav-li a { + text-decoration : none; + color : #FFFFFF; +} +footer { + background-color : #00704E; +} +┃", + _color_ocn_light, + _css_indent, + _color_ocn_light, +); + string _css_dark_html_scroll = format(q"┃ +html { +} +*{ + padding : 0px; + margin : 0px; +} +body { + height : 100vh; + background-color : #000000; + color : #CCCCCC; + background : #000000; + background-color : #000000; +} +a:link { + color : #FFFFFF; + text-decoration : none; +} +a:visited { + color : #999999; + text-decoration : none; +} +a:hover { + color : #000000; + background-color : #555555; +} +a.lnkocn:link { + color : %s; + text-decoration : none; +} +a.lnkocn:visited { + color : #9ACD32; + text-decoration : none; +} +a.lnkocn:hover { + color : #BBBBBB; + font-size : 1.8rem; +} +a.lnkicon:link { + text-decoration : none; +} +a.lnkicon:visited { + text-decoration : none; +} +a.lnkicon:hover { + color : #BBBBBB; + font-size : 120%%; +} +a:hover img { + background-color : #000000; +} +a:active { + color : #888888; + text-decoration : underline; +} +input { + color : #FFFFFF; + background-color : #777777; +} +div { + margin-left : 0; + margin-right : 0; +} +div.p { + margin-left : 5%%; + margin-right : 1%%; +} +div.substance { + width : 100%%; + background-color : #000000; +} +div.ocn { + width : 5%%; + float : right; + top : 0; + background-color : #000000; +} +div.endnote { + width : 95%%; + background-color : #000000; +} +div.toc { + position : absolute; + float : left; + margin : 0; + padding : 0; + padding-top : 0.5em; + border : 0; + width : 13em; + background-color : #111111; + margin-right : 1em; +} +div.summary { + margin : 0; + padding : 0; + border-left : 13em solid #111111; + padding-left : 1em; + background-color : #111111; +} +div.content, div.main_column { + margin : 0; + padding : 0; + border-left : 13em solid #000000; + padding-left : 1em; + padding-right : 1em; +} +div.content0, div.main_column0 { + margin : 0; + padding : 0; + border-left : 0%% solid #000000; + padding-left : 5%%; +} +div.scroll { + margin : 0; + padding : 0; + padding-left : 1em; + padding-right : 1em; +} +div.content:after { + content : ' '; + clear : both; + display : block; + height : 0; + overflow : hidden; +} +div.footer { + clear : left; + padding : 0.5em; + font-size : 1.4rem; + margin : 0; +} +div.toc ul { + list-style : none; + padding : 0; + margin : 0; +} +div.toc li ul a, li ul span.currentlink +{ + font-weight : normal; + font-size : 1.5rem; + padding-left : 2em; + background-color : #111111; +} +div.toc a, span.currentlink{ + display : block; + text-decoration : none; + padding-left : 0.5em; + color : #FF00AA; +} +hr { + width : 90%%; + margin-left : 5%%; + margin-right : 2em; + margin-top : 1.8em; + margin-bottom : 1.8em; +} +span.currentlink { + text-decoration : none; + background-color : #AAAAF9; +} +div.toc a:visited { + color : #FF00AA; +} +div.toc a:hover { + color : #CCCCCC; + background-color : #F9F9AA; +} +nav#toc ol { + list-style-type : none; +} +.norm, .bold, .verse, .group, .block, .alt { + line-height : 133%%; + margin-top : 12px; + margin-bottom : 0px; + padding-left : 0em; + text-indent : 0em; +} +p, h0, h1, h2, h3, h4, h5, h6, h7, ul, li { + display : block; + font-family : verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; + margin-left : 5%%; + margin-right : 2em; +} +p { + font-size : 1.6rem; + font-weight : normal; + line-height : 133%%; + text-align : justify; + text-indent : 0mm; + margin-top : 0.8em; + margin-bottom : 0.8em; +} +img { + max-width : 100%%; + height : auto; +} +pre { + width : auto; + display : block; + clear : both; + color : #555555; +} +pre.codeline { + display : table; + clear : both; + table-layout : fixed; + margin-left : 5%%; + margin-right : 5%%; + width : 90%%; + white-space : pre-wrap; + border-style : none; + border-radius : 5px 5px 5px 5px; + box-shadow : 0 2px 5px #AAAAAA inset; + margin-bottom : 1em; + padding : 0.5em 1em; + page-break-inside : avoid; + word-wrap : break-word; + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + white-space : pre; + white-space : pre-wrap; + white-space : -moz-pre-wrap; + white-space : -o-pre-wrap; + background-color : #555555; + color : #DDDDDD; + font-size : 1.5rem; + line-height : 100%%; +} +pre.codeline::before { + counter-reset : linenum; +} +pre.codeline span.tr { + display : table-row; + counter-increment : linenum; +} +pre.codeline span.th { + display : table-cell; + user-select : none; + -moz-user-select : none; + -webkit-user-select : none; + padding : 0.5em 0.5em; +} +pre.codeline span.th::before { + content : counter(linenum) "."; + color : #999999; + text-align : right; + display : block; +} +pre.codeline span.th { + width : 4em; +} +pre.codeline code { + display : table-cell; +} +p.code { + border-style : none; +} +p.spaced { white-space : pre; } +p.block { + white-space : pre; +} +p.group { } +p.alt { } +p.verse { + white-space : pre; + margin-bottom : 6px; +} +p.caption { + text-align : left; + font-size : 1.4rem; + display : inline; +} +p.endnote { + font-size : 1.5rem; + line-height : 120%%; + text-align : left; + margin-right : 15mm; + padding-left : 1em; + text-indent : -1em; +} +p.center { + text-align : center; +} +p.bold { + font-weight : bold; +} +p.bold_left { + font-weight : bold; + text-align : left; +} +p.centerbold { + text-align : center; + font-weight : bold; +} +p.em { + font-weight : bold; + font-style : normal; + background : #FFF3B6; +} +.small, .small_center { + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 0px; + margin-right : 6px; +} +p.small { + text-align : left; +} +p.small_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +.tiny, .tiny_left, .tiny_right, .tiny_center { + font-size : 1.35rem; + margin-top : 0px; + margin-bottom : 0px; + color : #EEEEEE; + margin-right : 6px; + text-align : left; +} +p.tiny { } +p.tiny_left { + margin-left : 0px; + margin-right : 0px; + text-align : left; +} +p.tiny_right { + margin-right : 1em; + text-align : right; +} +p.tiny_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +p.concordance_word { + line-height : 150%%; + font-weight : bold; + display : inline; + margin-top : 4px; + margin-bottom : 1px; +} +p.concordance_count { + font-size : 1.4rem; + color : #555555; + display : inline; + margin-left : 0em; +} +p.concordance_object { + font-size : 1.4rem; + line-height : 120%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +p.book_index_lev1 { + line-height : 100%%; + margin-top : 4px; + margin-bottom : 1px; +} +p.book_index_lev2 { + line-height : 100%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +tt { + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + background-color : #555555; + color : #DDDDDD; +} +%s +note { white-space : pre; } +label.ocn { + width : 2%%; + float : right; + top : 0; + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 6px; + margin-right : 6px; + text-align : right; + color : %s; + -khtml-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + -o-user-select : none; + -webkit-user-select : none; + user-select : none; +} +table { + display : block; + margin-left : 5%%; + margin-right : 2em; + background-color : inherit; +} +tr { } +th,td { + vertical-align : top; + text-align : left; +} +th { + font-weight : bold; +} +em { + font-weight : bold; + font-style : italic; +} +p.left,th.left,td.left { + text-align : left; +} +p.small_left,th.small_left,td.small_left { + text-align : left; + font-size : 1.4rem; +} +p.right,th.right,td.right { + text-align : right; +} +ul, li { + list-style-type : none; + list-style : none; + padding-left : 20px; + font-weight : normal; + line-height : 150%%; + text-align : left; + text-indent : 0mm; + margin-left : 1em; + margin-right : 2em; + margin-top : 3px; + margin-bottom : 3px; +} +li { + background : (../image_sys/bullet_09.png) no-repeat 0px 6px; +} +ul { } +h0, h1, h2, h3, h4, h5, h6, h7 { + font-weight : bold; + line-height : 120%%; + text-align : left; + margin-top : 20px; + margin-bottom : 10px; +} +h4.norm, h5.norm, h6.norm, h7.norm { + margin-top : 10px; + margin-bottom : 0px; +} +h0 { font-size : 1.9rem; } +h1 { font-size : 1.8rem; } +h2 { font-size : 1.75rem; } +h3 { font-size : 1.7rem; } +h4 { font-size : 1.65rem; } +h5 { font-size : 1.6rem; } +h6 { font-size : 1.55rem; } +h7 { font-size : 1.5rem; } +h0, h1, h2, h3, h4, h5, h6, h7 { + text-shadow : .2em .2em .3em #999999; +} +h1.i { margin-left : 2em; } +h2.i { margin-left : 3em; } +h3.i { margin-left : 4em; } +h4.i { margin-left : 5em; } +h5.i { margin-left : 6em; } +h6.i { margin-left : 7em; } +h7.i { margin-left : 8em; } +h8.i { margin-left : 9em; } +h9.i { margin-left : 10em; } +.toc { + font-weight : normal; + margin-top : 6px; + margin-bottom : 6px; +} +h0.toc { + margin-left : 1em; + font-size : 1.8rem; + line-height : 150%%; +} +h1.toc { + margin-left : 1em; + font-size : 1.75rem; + line-height : 150%%; +} +h2.toc { + margin-left : 2em; + font-size : 1.7rem; + line-height : 140%%; +} +h3.toc { + margin-left : 3em; + font-size : 1.65rem; + line-height : 120%%; +} +h4.toc { + margin-left : 4em; + font-size : 1.6rem; + line-height : 120%%; +} +h5.toc { + margin-left : 5em; + font-size : 1.5rem; + line-height : 110%%; +} +h6.toc { + margin-left : 6em; + font-size : 1.5rem; + line-height : 110%%; +} +h7.toc { + margin-left : 7em; + font-size : 1.45rem; + line-height : 100%%; +} +.subtoc { + margin-right : 34%%; + font-weight : normal; +} +h5.subtoc { + margin-left : 2em; + font-size : 1.4rem; + margin-top : 2px; + margin-bottom : 2px; +} +h6.subtoc { + margin-left : 3em; + font-size : 1.35; + margin-top : 0px; + margin-bottom : 0px; +} +h7.subtoc { + margin-left : 4em; + font-size : 1.3rem; + margin-top : 0px; + margin-bottom : 0px; +} +input, select, textarea { + font-size : 2.2rem; +} +input[type="text"] { + font-size : 1.8rem; + line-height : 120%%; +} +button[type="submit"] { + font-size : 1.8rem; + line-height : 120%%; +} +p.form { + font-size : 2.2rem; + line-height : 150%%; +} +/* flex */ +.flex-menu-bar { + display : -webkit-flex; + display : flex; + -webkit-flex-wrap : wrap; + -webkit-align-items : center; + align-items : center; + width : 100%%; + margin-left : 5%%; + margin-right : 2%%; + background-color : #000000; +} +.flex-menu-option { + background-color : #000000; + margin-right : 4px; +} +.flex-list { + display : -webkit-flex; + display : flex; + -webkit-align-items : center; + display : block; + align-items : center; + width : 100%%; + background-color : #000000; +} +.flex-list-item { + background-color : #000000; + margin : 4px; +} +/* grid */ +.wrapper { + display : grid; + grid-template-columns : 100%%; + grid-template-areas : + "headband" + "doc_header" + "doc_title" + "doc_toc" + "doc_prefix" + "doc_intro" + "doc_body" + "doc_endnotes" + "doc_glossary" + "doc_biblio" + "doc_bookindex" + "doc_blurb" + "doc_suffix"; + margin : 0px; + padding : 0px; + background-color : #000000; +} +.delimit { + border-style : none; + border-color : #000000; + padding : 10px; +} +.headband { + grid-area : headband; + background-color : #000000; +} +.doc_header { + grid-area : doc_header; +} +.doc_title { + grid-area : doc_title; +} +.doc_toc { + grid-area : doc_toc; +} +.doc_prefix { + grid-area : doc_prefix; +} +.doc_intro { + grid-area : doc_intro; +} +.doc_body { + grid-area : doc_body; +} +.doc_endnotes { + grid-area : doc_endnotes; +} +.doc_glossary { + grid-area : doc_glossary; +} +.doc_biblio { + grid-area : doc_biblio; +} +.doc_bookindex { + grid-area : doc_bookindex; +} +.doc_blurb { + grid-area : doc_blurb; +} +.doc_suffix { + grid-area : doc_suffix; +} +.nav-ul { + list-style : none; + float : left; +} +.nav-li { + float : left; + padding-right : 0.7em; +} +.nav-li a { + text-decoration : none; + color : #000000; +} +footer { + background-color : #FF704E; +} +┃", + _color_ocn_dark, + _css_indent, + _color_ocn_dark, +); + string _css_light_epub = format(q"┃ +html { + font-size : 62.5%%; +} +*{ + padding : 0px; + margin : 0px; +} +body { + height : 100vh; + font-size : 1.6rem; + background-color : #FFFFFF; + color : #000000; + background : #FFFFFF; + background-color : #FFFFFF; +} +a:link { + color : #003399; + text-decoration : none; +} +a:visited { + color : #003399; + text-decoration : none; +} +a:hover { + color : #000000; + background-color : #F9F9AA; +} +a.lnkocn:link { + color : %s; + text-decoration : none; +} +a.lnkocn:visited { + color : #32CD32; + text-decoration : none; +} +a.lnkocn:hover { + color : #777777; + font-size : 1.8rem; +} +a.lnkicon:link { + text-decoration : none; +} +a.lnkicon:visited { + text-decoration : none; +} +a.lnkicon:hover { + font-size : 160%%; +} +a:hover img { + background-color : #FFFFFF; +} +a:active { + color : #003399; + text-decoration : underline; +} +input { + color : #000000; + background-color : #FFFFFF; +} +div { + margin-left : 0; + margin-right : 0; +} +div.p { + margin-left : 5%%; + margin-right : 1%%; +} +div.substance { + width : 100%%; + background-color : #FFFFFF; +} +div.ocn { + width : 5%%; + float : right; + top : 0; + background-color : #FFFFFF; +} +div.endnote { + width : 95%%; + background-color : #FFFFFF; +} +div.toc { + position : absolute; + float : left; + margin : 0; + padding : 0; + padding-top : 0.5em; + border : 0; + width : 13em; + background-color : #EEEEEE; + margin-right : 1em; +} +div.summary { + margin : 0; + padding : 0; + border-left : 13em solid #EEEEEE; + padding-left : 1em; + background-color : #EEEEEE; +} +div.content, div.main_column { + margin : 0; + padding : 0; + border-left : 13em solid #FFFFFF; + padding-left : 1em; + padding-right : 1em; +} +div.content0, div.main_column0 { + margin : 0; + padding : 0; + border-left : 0%% solid #FFFFFF; + padding-left : 5%%; +} +div.scroll { + margin : 0; + padding : 0; + padding-left : 1em; + padding-right : 1em; +} +div.content:after { + content : ' '; + clear : both; + display : block; + height : 0; + overflow : hidden; +} +div.footer { + clear : left; + padding : 0.5em; + font-size : 1.4rem; + margin : 0; +} +div.toc ul { + list-style : none; + padding : 0; + margin : 0; +} +div.toc li ul a, li ul span.currentlink +{ + font-weight : normal; + font-size : 1.5rem; + padding-left : 2em; + background-color : #EEEEEE; +} +div.toc a, span.currentlink{ + display : block; + text-decoration : none; + padding-left : 0.5em; + color : #0000aa; +} +hr { + width : 90%%; + margin-left : 5%%; + margin-right : 2em; + margin-top : 1.8em; + margin-bottom : 1.8em; +} +span.currentlink { + text-decoration : none; + background-color : #AAAAAA; +} +div.toc a:visited { + color : #0000aa; +} +div.toc a:hover { + color : #000000; + background-color : #F9F9AA; +} +nav#toc ol { + list-style-type : none; +} +.norm, .bold, .verse, .group, .block, .alt { + line-height : 133%%; + margin-top : 12px; + margin-bottom : 0px; + padding-left : 0em; + text-indent : 0em; +} +p, h0, h1, h2, h3, h4, h5, h6, h7, ul, li { + display : block; + font-family : verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; + margin-left : 5%%; + margin-right : 2em; +} +p { + font-size : 1.6rem; + font-weight : normal; + line-height : 133%%; + text-align : justify; + text-indent : 0mm; + margin-top : 0.8em; + margin-bottom : 0.8em; +} +img { + max-width : 100%%; + height : auto; +} +pre { + width : auto; + display : block; + clear : both; + color : #555555; +} +pre.codeline { + display : table; + clear : both; + table-layout : fixed; + margin-left : 5%%; + margin-right : 5%%; + width : 90%%; + white-space : pre-wrap; + border-style : none; + border-radius : 5px 5px 5px 5px; + box-shadow : 0 2px 5px #AAAAAA inset; + margin-bottom : 1em; + padding : 0.5em 1em; + page-break-inside : avoid; + word-wrap : break-word; + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + white-space : pre; + white-space : pre-wrap; + white-space : -moz-pre-wrap; + white-space : -o-pre-wrap; + background-color : #EEEEEE; + color : #000000; + font-size : 1.5rem; + line-height : 100%%; +} +pre.codeline::before { + counter-reset : linenum; +} +pre.codeline span.tr { + display : table-row; + counter-increment : linenum; +} +pre.codeline span.th { + display : table-cell; + user-select : none; + -moz-user-select : none; + -webkit-user-select : none; + padding : 0.5em 0.5em; + /* background-color : #666666; */ +} +pre.codeline span.th::before { + content : counter(linenum) "."; + color : #999999; + text-align : right; + display : block; +} +pre.codeline span.th { + width : 4em; +} +pre.codeline code { + display : table-cell; +} +p.code { + border-style : none; +} +p.spaced { white-space : pre; } +p.block { + white-space : pre; +} +p.group { } +p.alt { } +p.verse { + white-space : pre; + margin-bottom : 6px; +} +p.caption { + text-align : left; + font-size : 1.4rem; + display : inline; +} +p.endnote { + font-size : 1.55rem; + line-height : 120%%; + text-align : left; + margin-right : 15mm; + padding-left : 1em; + text-indent : -1em; +} +p.center { + text-align : center; +} +p.bold { + font-weight : bold; +} +p.bold_left { + font-weight : bold; + text-align : left; +} +p.centerbold { + text-align : center; + font-weight : bold; +} +p.em { + font-weight : bold; + font-style : normal; + background : #FFF3B6; +} +.small, .small_center { + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 0px; + margin-right : 6px; +} +p.small { + text-align : left; +} +p.small_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +.tiny, .tiny_left, .tiny_right, .tiny_center { + font-size : 1.2rem; + margin-top : 0px; + margin-bottom : 0px; + color : #777777; + margin-right : 6px; + text-align : left; +} +p.tiny { } +p.tiny_left { + margin-left : 0px; + margin-right : 0px; + text-align : left; +} +p.tiny_right { + margin-right : 1em; + text-align : right; +} +p.tiny_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +p.icons, .icons_center { + font-size : 100%%; + margin-top : 0px; + margin-bottom : 0px; + margin-right : 6px; +} +p.icons { + text-align : left; +} +p.concordance_word { + line-height : 150%%; + font-weight : bold; + display : inline; + margin-top : 4px; + margin-bottom : 1px; +} +p.concordance_count { + font-size : 1.4rem; + color : #777777; + display : inline; + margin-left : 0em; +} +p.concordance_object { + font-size : 1.4rem; + line-height : 120%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +p.book_index_lev1 { + line-height : 100%%; + margin-top : 4px; + margin-bottom : 1px; +} +p.book_index_lev2 { + line-height : 100%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +tt { + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + background-color : #EEEEEE; + color : #000000; +} +%s +note { white-space : pre; } +label.ocn { + width : 2%%; + float : right; + top : 0; + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 6px; + margin-right : 6px; + text-align : right; + color : %s; + -khtml-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + -o-user-select : none; + -webkit-user-select : none; + user-select : none; +} +table { + display : block; + margin-left : 5%%; + margin-right : 2em; + background-color : inherit; +} +tr { } +th,td { + vertical-align : top; + text-align : left; +} +th { + font-weight : bold; +} +em { + font-weight : bold; + font-style : italic; +} +p.left,th.left,td.left { + text-align : left; +} +p.small_left,th.small_left,td.small_left { + text-align : left; + font-size : 1.4rem; +} +p.right,th.right,td.right { + text-align : right; +} +ul, li { + list-style-type : none; + list-style : none; + padding-left : 20px; + font-weight : normal; + line-height : 150%%; + text-align : left; + text-indent : 0mm; + margin-left : 1em; + margin-right : 2em; + margin-top : 3px; + margin-bottom : 3px; +} +li { + background : url(../image_sys/bullet_09.png) no-repeat 0px 6px; +} +ul { } +h0, h1, h2, h3, h4, h5, h6, h7 { + font-weight : bold; + line-height : 120%%; + text-align : left; + margin-top : 20px; + margin-bottom : 10px; +} +h4.norm, h5.norm, h6.norm, h7.norm { + margin-top : 10px; + margin-bottom : 0px; +} +h0 { font-size : 1.85rem; } +h1 { font-size : 1.8rem; } +h2 { font-size : 1.75rem; } +h3 { font-size : 1.7rem; } +h4 { font-size : 1.65rem; } +h5 { font-size : 1.6rem; } +h6 { font-size : 1.55rem; } +h7 { font-size : 1.5rem; } +h0, h1, h2, h3, h4, h5, h6, h7 { + text-shadow : .2em .2em .3em #808080; +} +h1.i { margin-left : 2em; } +h2.i { margin-left : 3em; } +h3.i { margin-left : 4em; } +h4.i { margin-left : 5em; } +h5.i { margin-left : 6em; } +h6.i { margin-left : 7em; } +h7.i { margin-left : 8em; } +h8.i { margin-left : 9em; } +h9.i { margin-left : 10em; } +.toc { + font-weight : normal; + margin-top : 6px; + margin-bottom : 6px; +} +h0.toc { + margin-left : 1em; + font-size : 1.85rem; + line-height : 150%%; +} +h1.toc { + margin-left : 1em; + font-size : 1.8rem; + line-height : 150%%; +} +h2.toc { + margin-left : 2em; + font-size : 1.75rem; + line-height : 140%%; +} +h3.toc { + margin-left : 3em; + font-size : 1.7rem; + line-height : 120%%; +} +h4.toc { + margin-left : 4em; + font-size : 1.65rem; + line-height : 120%%; +} +h5.toc { + margin-left : 5em; + font-size : 1.6rem; + line-height : 110%%; +} +h6.toc { + margin-left : 6em; + font-size : 1.55rem; + line-height : 110%%; +} +h7.toc { + margin-left : 7em; + font-size : 1.5rem; + line-height : 100%%; +} +.subtoc { + margin-right : 34%%; + font-weight : normal; +} +h5.subtoc { + margin-left : 2em; + font-size : 1.45rem; + margin-top : 2px; + margin-bottom : 2px; +} +h6.subtoc { + margin-left : 3em; + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 0px; +} +h7.subtoc { + margin-left : 4em; + font-size : 1.35rem; + margin-top : 0px; + margin-bottom : 0px; +} +input, select, textarea { + font-size : 2.2rem; +} +input[type="text"] { + font-size : 1.8rem; + line-height : 120%%; +} +button[type="submit"] { + font-size : 1.8rem; + line-height : 120%%; +} +p.form { + font-size : 2.2rem; + line-height : 150%%; +} + +┃", + _color_ocn_light, + _css_indent, + _color_ocn_light, +); + string _css_dark_epub = format(q"┃ +html { +} +*{ + padding : 0px; + margin : 0px; +} +body { + height : 100vh; + background-color : #000000; + color : #CCCCCC; + background : #000000; + background-color : #000000; +} +a:link { + color : #FFFFFF; + text-decoration : none; +} +a:visited { + color : #999999; + text-decoration : none; +} +a:hover { + color : #000000; + background-color : #555555; +} +a.lnkocn:link { + color : %s; + text-decoration : none; +} +a.lnkocn:visited { + color : #9ACD32; + text-decoration : none; +} +a.lnkocn:hover { + color : #BBBBBB; + font-size : 1.8rem; +} +a.lnkicon:link { + text-decoration : none; +} +a.lnkicon:visited { + text-decoration : none; +} +a.lnkicon:hover { + color : #BBBBBB; + font-size : 120%%; +} +a:hover img { + background-color : #000000; +} +a:active { + color : #888888; + text-decoration : underline; +} +input { + color : #FFFFFF; + background-color : #777777; +} +div { + margin-left : 0; + margin-right : 0; +} +div.p { + margin-left : 5%%; + margin-right : 1%%; +} +div.substance { + width : 100%%; + background-color : #000000; +} +div.ocn { + width : 5%%; + float : right; + top : 0; + background-color : #000000; +} +div.endnote { + width : 95%%; + background-color : #000000; +} +div.toc { + position : absolute; + float : left; + margin : 0; + padding : 0; + padding-top : 0.5em; + border : 0; + width : 13em; + background-color : #111111; + margin-right : 1em; +} +div.summary { + margin : 0; + padding : 0; + border-left : 13em solid #111111; + padding-left : 1em; + background-color : #111111; +} +div.content, div.main_column { + margin : 0; + padding : 0; + border-left : 13em solid #000000; + padding-left : 1em; + padding-right : 1em; +} +div.content0, div.main_column0 { + margin : 0; + padding : 0; + border-left : 0%% solid #000000; + padding-left : 5%%; +} +div.scroll { + margin : 0; + padding : 0; + padding-left : 1em; + padding-right : 1em; +} +div.content:after { + content : ' '; + clear : both; + display : block; + height : 0; + overflow : hidden; +} +div.footer { + clear : left; + padding : 0.5em; + font-size : 1.4rem; + margin : 0; +} +div.toc ul { + list-style : none; + padding : 0; + margin : 0; +} +div.toc li ul a, li ul span.currentlink +{ + font-weight : normal; + font-size : 1.5rem; + padding-left : 2em; + background-color : #111111; +} +div.toc a, span.currentlink{ + display : block; + text-decoration : none; + padding-left : 0.5em; + color : #FF00AA; +} +hr { + width : 90%%; + margin-left : 5%%; + margin-right : 2em; + margin-top : 1.8em; + margin-bottom : 1.8em; +} +span.currentlink { + text-decoration : none; + background-color : #AAAAF9; +} +div.toc a:visited { + color : #FF00AA; +} +div.toc a:hover { + color : #CCCCCC; + background-color : #F9F9AA; +} +nav#toc ol { + list-style-type : none; +} +.norm, .bold, .verse, .group, .block, .alt { + line-height : 133%%; + margin-top : 12px; + margin-bottom : 0px; + padding-left : 0em; + text-indent : 0em; +} +p, h0, h1, h2, h3, h4, h5, h6, h7, ul, li { + display : block; + font-family : verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; + margin-left : 5%%; + margin-right : 2em; +} +p { + font-size : 1.6rem; + font-weight : normal; + line-height : 133%%; + text-align : justify; + text-indent : 0mm; + margin-top : 0.8em; + margin-bottom : 0.8em; +} +img { + max-width : 100%%; + height : auto; +} +pre { + width : auto; + display : block; + clear : both; + color : #555555; +} +pre.codeline { + display : table; + clear : both; + table-layout : fixed; + margin-left : 5%%; + margin-right : 5%%; + width : 90%%; + white-space : pre-wrap; + border-style : none; + border-radius : 5px 5px 5px 5px; + box-shadow : 0 2px 5px #AAAAAA inset; + margin-bottom : 1em; + padding : 0.5em 1em; + page-break-inside : avoid; + word-wrap : break-word; + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + white-space : pre; + white-space : pre-wrap; + white-space : -moz-pre-wrap; + white-space : -o-pre-wrap; + background-color : #555555; + color : #DDDDDD; + font-size : 1.5rem; + line-height : 100%%; +} +pre.codeline::before { + counter-reset : linenum; +} +pre.codeline span.tr { + display : table-row; + counter-increment : linenum; +} +pre.codeline span.th { + display : table-cell; + user-select : none; + -moz-user-select : none; + -webkit-user-select : none; + padding : 0.5em 0.5em; +} +pre.codeline span.th::before { + content : counter(linenum) "."; + color : #999999; + text-align : right; + display : block; +} +pre.codeline span.th { + width : 4em; +} +pre.codeline code { + display : table-cell; +} +p.code { + border-style : none; +} +p.spaced { white-space : pre; } +p.block { + white-space : pre; +} +p.group { } +p.alt { } +p.verse { + white-space : pre; + margin-bottom : 6px; +} +p.caption { + text-align : left; + font-size : 1.4rem; + display : inline; +} +p.endnote { + font-size : 1.5rem; + line-height : 120%%; + text-align : left; + margin-right : 15mm; + padding-left : 1em; + text-indent : -1em; +} +p.center { + text-align : center; +} +p.bold { + font-weight : bold; +} +p.bold_left { + font-weight : bold; + text-align : left; +} +p.centerbold { + text-align : center; + font-weight : bold; +} +p.em { + font-weight : bold; + font-style : normal; + background : #FFF3B6; +} +.small, .small_center { + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 0px; + margin-right : 6px; +} +p.small { + text-align : left; +} +p.small_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +.tiny, .tiny_left, .tiny_right, .tiny_center { + font-size : 1.35rem; + margin-top : 0px; + margin-bottom : 0px; + color : #EEEEEE; + margin-right : 6px; + text-align : left; +} +p.tiny { } +p.tiny_left { + margin-left : 0px; + margin-right : 0px; + text-align : left; +} +p.tiny_right { + margin-right : 1em; + text-align : right; +} +p.tiny_center { + margin-left : 0px; + margin-right : 0px; + text-align : center; +} +p.concordance_word { + line-height : 150%%; + font-weight : bold; + display : inline; + margin-top : 4px; + margin-bottom : 1px; +} +p.concordance_count { + font-size : 1.4rem; + color : #555555; + display : inline; + margin-left : 0em; +} +p.concordance_object { + font-size : 1.4rem; + line-height : 120%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +p.book_index_lev1 { + line-height : 100%%; + margin-top : 4px; + margin-bottom : 1px; +} +p.book_index_lev2 { + line-height : 100%%; + text-align : left; + margin-left : 3em; + margin-top : 1px; + margin-bottom : 3px; +} +tt { + font-family : inconsolata, "liberation mono", "bitstream vera mono", "dejavu mono", monaco, consolas, "andale mono", "courier new", "courier 10 pitch", courier, monospace; + background-color : #555555; + color : #DDDDDD; +} +%s +note { white-space : pre; } +label.ocn { + width : 2%%; + float : right; + top : 0; + font-size : 1.4rem; + margin-top : 0px; + margin-bottom : 6px; + margin-right : 6px; + text-align : right; + color : %s; + -khtml-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + -o-user-select : none; + -webkit-user-select : none; + user-select : none; +} +table { + display : block; + margin-left : 5%%; + margin-right : 2em; + background-color : inherit; +} +tr { } +th,td { + vertical-align : top; + text-align : left; +} +th { + font-weight : bold; +} +em { + font-weight : bold; + font-style : italic; +} +p.left,th.left,td.left { + text-align : left; +} +p.small_left,th.small_left,td.small_left { + text-align : left; + font-size : 1.4rem; +} +p.right,th.right,td.right { + text-align : right; +} +ul, li { + list-style-type : none; + list-style : none; + padding-left : 20px; + font-weight : normal; + line-height : 150%%; + text-align : left; + text-indent : 0mm; + margin-left : 1em; + margin-right : 2em; + margin-top : 3px; + margin-bottom : 3px; +} +li { + background : (../image_sys/bullet_09.png) no-repeat 0px 6px; +} +ul { } +h0, h1, h2, h3, h4, h5, h6, h7 { + font-weight : bold; + line-height : 120%%; + text-align : left; + margin-top : 20px; + margin-bottom : 10px; +} +h4.norm, h5.norm, h6.norm, h7.norm { + margin-top : 10px; + margin-bottom : 0px; +} +h0 { font-size : 1.9rem; } +h1 { font-size : 1.8rem; } +h2 { font-size : 1.75rem; } +h3 { font-size : 1.7rem; } +h4 { font-size : 1.65rem; } +h5 { font-size : 1.6rem; } +h6 { font-size : 1.55rem; } +h7 { font-size : 1.5rem; } +h0, h1, h2, h3, h4, h5, h6, h7 { + text-shadow : .2em .2em .3em #999999; +} +h1.i { margin-left : 2em; } +h2.i { margin-left : 3em; } +h3.i { margin-left : 4em; } +h4.i { margin-left : 5em; } +h5.i { margin-left : 6em; } +h6.i { margin-left : 7em; } +h7.i { margin-left : 8em; } +h8.i { margin-left : 9em; } +h9.i { margin-left : 10em; } +.toc { + font-weight : normal; + margin-top : 6px; + margin-bottom : 6px; +} +h0.toc { + margin-left : 1em; + font-size : 1.8rem; + line-height : 150%%; +} +h1.toc { + margin-left : 1em; + font-size : 1.75rem; + line-height : 150%%; +} +h2.toc { + margin-left : 2em; + font-size : 1.7rem; + line-height : 140%%; +} +h3.toc { + margin-left : 3em; + font-size : 1.65rem; + line-height : 120%%; +} +h4.toc { + margin-left : 4em; + font-size : 1.6rem; + line-height : 120%%; +} +h5.toc { + margin-left : 5em; + font-size : 1.5rem; + line-height : 110%%; +} +h6.toc { + margin-left : 6em; + font-size : 1.5rem; + line-height : 110%%; +} +h7.toc { + margin-left : 7em; + font-size : 1.45rem; + line-height : 100%%; +} +.subtoc { + margin-right : 34%%; + font-weight : normal; +} +h5.subtoc { + margin-left : 2em; + font-size : 1.4rem; + margin-top : 2px; + margin-bottom : 2px; +} +h6.subtoc { + margin-left : 3em; + font-size : 1.35; + margin-top : 0px; + margin-bottom : 0px; +} +h7.subtoc { + margin-left : 4em; + font-size : 1.3rem; + margin-top : 0px; + margin-bottom : 0px; +} +input, select, textarea { + font-size : 2.2rem; +} +input[type="text"] { + font-size : 1.8rem; + line-height : 120%%; +} +button[type="submit"] { + font-size : 1.8rem; + line-height : 120%%; +} +p.form { + font-size : 2.2rem; + line-height : 150%%; +} + +┃", + _color_ocn_dark, + _css_indent, + _color_ocn_dark, +); + auto css_() { + struct _CSS { + string html_seg = "/* spine css html seg stylesheet */\n"; + string html_scroll = "/* spine css html scroll stylesheet */\n"; + string epub = "/* spine css epub stylesheet */\n"; + } + return _CSS(); + } + auto css = css_(); + if (doc_matters.opt.action.css_theme_default) { + css.html_seg ~= _css_light_html_seg; + css.html_scroll ~= _css_light_html_scroll; + css.epub ~= _css_light_epub; + } else { + css.html_seg ~= _css_dark_html_seg; + css.html_scroll ~= _css_dark_html_scroll; + css.epub ~= _css_dark_epub; + } + return css; + } +} -- cgit v1.2.3%s
+