From 15d1dc27d81909b129a448ab343447180db8df38 Mon Sep 17 00:00:00 2001 From: Ralph Amissah Date: Wed, 30 Mar 2022 11:02:09 -0400 Subject: latex doc headers moved to .sty files in ./sty dir - some changes made, font selection included --- org/default_paths.org | 49 +- org/out_latex.org | 1916 ++++++++++++++++++++++++++----------------------- org/output_hub.org | 34 +- org/spine.org | 18 + 4 files changed, 1118 insertions(+), 899 deletions(-) (limited to 'org') diff --git a/org/default_paths.org b/org/default_paths.org index 4b996bc..413434c 100644 --- a/org/default_paths.org +++ b/org/default_paths.org @@ -989,6 +989,7 @@ import doc_reform.meta.rgx; <> <> <> +<> <> <> <> @@ -1540,10 +1541,14 @@ template spinePathsLaTeX() { string base_filename(string fn_src) { return fn_src.baseName.stripExtension; } + auto out_pth() { + return spineOutPaths!()(doc_matters.output_path, doc_matters.src.language); + } string base() { - auto out_pth = spineOutPaths!()(doc_matters.output_path, doc_matters.src.language); - string base_dir = "latex"; - return (((out_pth.output_root).chainPath(base_dir)).asNormalizedPath).array; + return (((out_pth.output_root).chainPath("latex")).asNormalizedPath).array; + } + string base_sty() { + return (((out_pth.output_root).chainPath("latex").chainPath("sty")).asNormalizedPath).array; } string latex_path_stuff() { return ((base.chainPath(base_filename(doc_matters.src.filename))).asNormalizedPath).array; @@ -1555,6 +1560,15 @@ template spinePathsLaTeX() { ~ ".tex") ).asNormalizedPath).array; } + string latex_sty_with_path(string paper_size_orientation) { // spineA4portrait.sty + return ((base_sty.chainPath("spine" + ~ paper_size_orientation + ~ ".sty") + ).asNormalizedPath).array; + } + string latex_sty_with_path_static() { // spineShared.sty + return ((base_sty.chainPath("spineShared.sty")).asNormalizedPath).array; + } string images() { string image_dir = "image"; return (((base).chainPath(image_dir)).asNormalizedPath).array; @@ -1565,6 +1579,35 @@ template spinePathsLaTeX() { } #+END_SRC +#+NAME: template_paths_latex_sty +#+BEGIN_SRC d +template spinePathsLaTeXsty() { + auto spinePathsLaTeXsty(string output_dir) { + struct _PathsStruct { + auto out_pth() { + return spineOutPaths!()(output_dir); + } + string base_sty() { + return (((out_pth.output_root).chainPath("latex").chainPath("sty")).asNormalizedPath).array; + } + string latex_sty_with_path(string paper_size_orientation) { // spineA4portrait.sty + return ((base_sty.chainPath("spine" + ~ paper_size_orientation + ~ ".sty") + ).asNormalizedPath).array; + } + string latex_sty_with_path_static() { // spineShared.sty + return ((base_sty.chainPath("spineShared.sty")).asNormalizedPath).array; + } + string latex_document_header_sty(string filename) { // spineShared.sty + return ((base_sty.chainPath(filename)).asNormalizedPath).array; + } + } + return _PathsStruct(); + } +} +#+END_SRC + ** _sqlite_ :sqlite: *** discrete diff --git a/org/out_latex.org b/org/out_latex.org index a03c588..9b52a26 100644 --- a/org/out_latex.org +++ b/org/out_latex.org @@ -21,17 +21,45 @@ * latex ** _module template_ :latex:pdf:module: +*** latex.d module & templates -#+HEADER: :tangle "../src/doc_reform/io_out/latex.d" :noweb yes +#+HEADER: :tangle "../src/doc_reform/io_out/latex.d" +#+HEADER: :noweb yes #+BEGIN_SRC d <> module doc_reform.io_out.latex; +<> +<> +<> +<> +<> +#+END_SRC + +*** template paperLaTeX + +#+NAME: Template_paper_latex +#+BEGIN_SRC d +template paperLaTeX() { + import + std.format, + std.conv : to; + auto paperLaTeX() { + <> + return PaperType(); + } +} +#+END_SRC + +*** template outputLaTeX + +#+NAME: Template_output_latex +#+BEGIN_SRC d template outputLaTeX() { <> - <> <> <> <> + <> <> <> <> @@ -55,9 +83,6 @@ template outputLaTeX() { <> <> <> - <> -<> -<> <> <> <> @@ -69,9 +94,11 @@ template outputLaTeX() { <> <> <> +<> <> <> <> +<> <> <> <> @@ -80,19 +107,6 @@ template outputLaTeX() { <> <> <> -<> -<> -<> -<> -<> -<> -<> -<> -<> -<> -<> -<> -%% <> <> <> <> @@ -112,6 +126,45 @@ template outputLaTeX() { } #+END_SRC +*** template outputLaTeXstyInit + +#+NAME: Template_latex_init +#+BEGIN_SRC d +template outputLaTeXstyInit() { + import doc_reform.io_out; + mixin spineRgxOut; + auto paper = paperLaTeX; + <> + <> +} +#+END_SRC + +*** template outputLaTeXstyStatic + +#+NAME: Template_latex_sty_static +#+BEGIN_SRC d +template outputLaTeXstyStatic() { + <> + string outputLaTeXstyStatic() { +<> + return latex_sty; + } +} +#+END_SRC + +*** template outputLaTeXstyPaperSizeAndOrientation + +#+NAME: Template_latex_sty_paper_dimensions +#+BEGIN_SRC d +template outputLaTeXstyPaperSizeAndOrientation() { + <> + auto outputLaTeXstyPaperSizeAndOrientation(P)(P doc_sty_info) { +<> + return latex_sty; + } +} +#+END_SRC + ** write latex output :latex:out: *** write latex output :latex:out: @@ -178,468 +231,856 @@ void outputLaTeX(D,M)( } #+END_SRC -* stuff -** output imports +*** styles :latex:out: +**** initialize -#+NAME: ImportsAndMixins_imports +#+NAME: Initialize_output_style #+BEGIN_SRC d import - std.digest.sha, - std.file, - std.outbuffer, - std.uri, + std.format, std.conv : to; -import doc_reform.io_out; -mixin InternalMarkup; // watch -mixin spineRgxOut; -static auto rgx = RgxO(); -mixin spineLanguageCodes; -auto lang = Lang(); #+END_SRC -** shared -*** paper dimensions (struct) geometry +**** write latex styles output :latex:out: +***** write -#+NAME: Function_shared_geometry_paper_dimensions +#+NAME: Function_output_style_write #+BEGIN_SRC d -auto paper() { - string mm(uint mmi) { - string _mm = format(q"┃%smm┃", mmi.to!string); - return _mm; - } - struct PaperType { - @safe auto a4() { - struct A4 { - auto portrait() { - struct V { - string papersize = "a4paper"; - string orient = "portrait"; - string fontsize = "11pt"; - const uint w = 170; - const uint h = 257; - const uint l = 30; - const uint r = 20; - const uint t = 30; - const uint b = 30; - string width = mm(w); - string height = mm(h); - string margin_left = mm(l); - string margin_right = mm(r); - string margin_top = mm(t); - string margin_bottom = mm(b); - uint img_px = 450; - bool is_portrait = true; - } - return V(); - } - auto landscape() { - struct H { - string papersize = "a4paper"; - string orient = "landscape"; - string fontsize = "11pt"; - const uint w = 238; - const uint h = 160; - const uint l = 30; - const uint r = 20; - const uint t = 30; - const uint b = 30; - string width = mm(w); - string height = mm(h); - string margin_left = mm(l); - string margin_right = mm(r); - string margin_top = mm(t); - string margin_bottom = mm(b); - uint img_px = 300; - bool is_portrait = false; - } - return H(); - } - } - return A4(); - } - @safe auto a5() { - struct A5 { - auto portrait() { - struct V { - string papersize = "a5paper"; - string orient = "portrait"; - string fontsize = "11pt"; - const uint w = 112; - const uint h = 162; - const uint l = 30; - const uint r = 20; - const uint t = 30; - const uint b = 30; - string width = mm(w); - string height = mm(h); - string margin_left = mm(l); - string margin_right = mm(r); - string margin_top = mm(t); - string margin_bottom = mm(b); - uint img_px = 280; - bool is_portrait = true; - } - return V(); - } - auto landscape() { - struct H { - string papersize = "a5paper"; - string orient = "landscape"; - string fontsize = "11pt"; - const uint w = 152; - const uint h = 100; - const uint l = 30; - const uint r = 20; - const uint t = 30; - const uint b = 30; - string width = mm(w); - string height = mm(h); - string margin_left = mm(l); - string margin_right = mm(r); - string margin_top = mm(t); - string margin_bottom = mm(b); - uint img_px = 190; - bool is_portrait = false; - } - return H(); - } - } - return A5(); - } - @safe auto b4() { - struct B4 { - auto portrait() { - struct V { - string papersize = "b4paper"; - string orient = "portrait"; - string fontsize = "11pt"; - const uint w = 140; - const uint h = 204; - const uint l = 30; - const uint r = 20; - const uint t = 30; - const uint b = 30; - string width = mm(w); - string height = mm(h); - string margin_left = mm(l); - string margin_right = mm(r); - string margin_top = mm(t); - string margin_bottom = mm(b); - uint img_px = 356; - bool is_portrait = true; - } - return V(); - } - auto landscape() { - struct H { - string papersize = "b4paper"; - string orient = "landscape"; - string fontsize = "11pt"; - const uint w = 200; - const uint h = 130; - const uint l = 30; - const uint r = 20; - const uint t = 30; - const uint b = 30; - string width = mm(w); - string height = mm(h); - string margin_left = mm(l); - string margin_right = mm(r); - string margin_top = mm(t); - string margin_bottom = mm(b); - uint img_px = 260; - bool is_portrait = false; - } - return H(); - } - } - return B4(); - } - @safe auto letter() { - struct Letter { - auto portrait() { - struct V { - string papersize = "letterpaper"; - string orient = "portrait"; - string fontsize = "11pt"; - const uint w = 166; - const uint h = 212; - const uint l = 30; - const uint r = 20; - const uint t = 30; - const uint b = 30; - string width = mm(w); - string height = mm(h); - string margin_left = mm(l); - string margin_right = mm(r); - string margin_top = mm(t); - string margin_bottom = mm(b); - uint img_px = 468; - bool is_portrait = true; - } - return V(); - } - auto landscape() { - struct H { - string papersize = "letterpaper"; - string orient = "landscape"; - string fontsize = "11pt"; - const uint w = 226; - const uint h = 166; - const uint l = 30; - const uint r = 20; - const uint t = 30; - const uint b = 30; - string width = mm(w); - string height = mm(h); - string margin_left = mm(l); - string margin_right = mm(r); - string margin_top = mm(t); - string margin_bottom = mm(b); - uint img_px = 290; - bool is_portrait = false; - } - return H(); - } - } - return Letter(); - } - @safe auto legal() { - struct Legal { - auto portrait() { - struct V { - string papersize = "legalpaper"; - string orient = "portrait"; - string fontsize = "11pt"; - const uint w = 168; - const uint h = 286; - const uint l = 30; - const uint r = 20; - const uint t = 30; - const uint b = 30; - string width = mm(w); - string height = mm(h); - string margin_left = mm(l); - string margin_right = mm(r); - string margin_top = mm(t); - string margin_bottom = mm(b); - uint img_px = 474; - bool is_portrait = true; - } - return V(); - } - auto landscape() { - struct H { - string papersize = "legalpaper"; - string orient = "landscape"; - string fontsize = "11pt"; - const uint w = 296; - const uint h = 166; - const uint l = 30; - const uint r = 20; - const uint t = 30; - const uint b = 30; - string width = mm(w); - string height = mm(h); - string margin_left = mm(l); - string margin_right = mm(r); - string margin_top = mm(t); - string margin_bottom = mm(b); - uint img_px = 420; - bool is_portrait = false; - } - return H(); - } +void writeOutputLaTeXstyStatic( + string latex_sty, + string output_dir, + string filename, +) { + if ((output_dir.length > 0) + && isValidPath(output_dir) + ) { + auto pth_latex = spinePathsLaTeXsty(output_dir); + try { + import std.file; + if (!exists(pth_latex.base_sty)) { + (pth_latex.base_sty).mkdirRecurse; } - return Legal(); + auto f = File(pth_latex.latex_document_header_sty(filename), "w"); + f.writeln(latex_sty); + } catch (ErrnoException ex) { + // handle error } } - return PaperType(); -} -#+END_SRC - -*** latex \escape special characters -**** general - -#+NAME: Function_shared_special_characters_to_escape_operations -#+BEGIN_SRC d -@safe string sp_char_ops()( - string _txt, -) { - string _unescape_sp_char_esc()(string _txt) { - _txt = _txt - .replaceAll(rgx.latex_special_char_escaped, - format(q"┃%s┃", "$1")) - .replaceAll(rgx.latex_special_char_escaped_braced, - format(q"┃%s┃", "$1")); - return _txt; - } - string _unescape_fontface_esc()(string _txt) { - _txt = _txt.replaceAll(rgx.latex_identify_inline_fontface, - format(q"┃%s%s┃", "$1", "$2")); - return _txt; - } - _txt = replaceAll!(m => "\\" ~ m[1])(_txt, rgx.latex_special_char_for_escape); - _txt = replaceAll!(m => "{\\" ~ m[1] ~ "}")(_txt, rgx.latex_special_char_for_escape_and_braces); - _txt = replaceAll!(m => "''")(_txt, rgx.quotes_open_and_close); - _txt = replaceAll!(m => "$\\cdot$")(_txt, rgx.middle_dot); - _txt = replaceAll!(m => _unescape_sp_char_esc(m[0]))(_txt, rgx.latex_identify_inline_link); - _txt = replaceAll!(m => _unescape_fontface_esc(m[0]))(_txt, rgx.latex_identify_inline_fontface); - return _txt; -} -#+END_SRC - -#+NAME: Function_shared_special_characters_to_escape_object -#+BEGIN_SRC d -@safe string sp_char_esc(O)( - string _txt, - const O obj, -) { - if (obj.metainfo.is_a != "code") { - _txt = _txt.sp_char_ops; - } - return _txt; -} -#+END_SRC - -**** string text - -#+NAME: Function_shared_special_characters_to_escape_text -#+BEGIN_SRC d -@safe string sp_char_esc_txt()( - string _txt, -) { - _txt = _txt.sp_char_ops; - return _txt; -} -#+END_SRC - -*** not used latex \escape special characters - -#+BEGIN_SRC d -@safe string sp_char_esc()( - string _txt, -) { - _txt = replaceAll!(m => "\\" ~ m[1])(_txt, rgx.latex_special_char); - return _txt; -} -#+END_SRC - -*** inline markup -**** fontface - -- bold, italics, underscore, strikethrough - -#+NAME: Function_shared_fontface -#+BEGIN_SRC d -@safe string fontface()( - string _txt, -) { -_txt = _txt - .replaceAll(rgx.inline_emphasis, format(q"┃\begin{bfseries}%s\end{bfseries}┃", "$1")) - .replaceAll(rgx.inline_bold, format(q"┃\begin{bfseries}%s\end{bfseries}┃", "$1")) - .replaceAll(rgx.inline_italics, format(q"┃\emph{%s}┃", "$1")) - .replaceAll(rgx.inline_italics, format(q"┃\uline{%s}┃", "$1")) - .replaceAll(rgx.inline_superscript, format(q"┃$$^{%s}$$┃", "$1")) - .replaceAll(rgx.inline_subscript, format(q"┃$$_{%s}$$┃", "$1")) - .replaceAll(rgx.inline_strike, format(q"┃\sout{%s}┃", "$1")) - .replaceAll(rgx.inline_insert, format(q"┃\uline{%s}┃", "$1")) - .replaceAll(rgx.inline_mono, format(q"┃\begin{monosp}%s\end{monosp}┃", "$1")) - .replaceAll(rgx.inline_italics, format(q"┃``%s''┃", "$1")); - return _txt; -} -#+END_SRC - -**** spaces -***** leading hardspace UNUSED - -#+NAME: Function_shared_leading_hardspaces -#+BEGIN_SRC d -@safe string leading_hardspaces()( - string _txt, -) { - string hardspaces(string _spaces) { - _spaces = _spaces - .replaceAll(rgx.space, "{\\s}"); - return _spaces; - } - _txt = replaceAll!(m => hardspaces(m[0]))(_txt, rgx.spaces_line_start); - return _txt; } #+END_SRC -***** nbsp character UNUSED - -#+NAME: shared_character_nbsp_to_hardspace_ -#+BEGIN_SRC d -@safe string nbsp_char_replace()(string _txt) { - if (_txt.match(rgx.nbsp_char)) { - _txt = _txt.replaceAll(rgx.nbsp_char, "{\\s}"); - } - return _txt; +***** request write (send to be written) + +#+NAME: Function_output_stylesheets_get_each_written +#+BEGIN_SRC d +void outputLaTeXstyInit()(string output_dir,) { + string latex_sty = outputLaTeXstyStatic!(); + latex_sty.writeOutputLaTeXstyStatic(output_dir, "spineShared.sty"); + auto sty_a4p = paper.a4.portrait; + auto latex_papersize_and_orientation = outputLaTeXstyPaperSizeAndOrientation!()(sty_a4p); + latex_papersize_and_orientation.writeOutputLaTeXstyStatic(output_dir, sty_a4p.stylesheet ~ ".sty"); + auto sty_a4l = paper.a4.landscape; + latex_papersize_and_orientation = outputLaTeXstyPaperSizeAndOrientation!()(sty_a4l); + latex_papersize_and_orientation.writeOutputLaTeXstyStatic(output_dir, sty_a4l.stylesheet ~ ".sty"); + auto sty_b4p = paper.b4.portrait; + latex_papersize_and_orientation = outputLaTeXstyPaperSizeAndOrientation!()(sty_b4p); + latex_papersize_and_orientation.writeOutputLaTeXstyStatic(output_dir, sty_b4p.stylesheet ~ ".sty"); + auto sty_b4l = paper.b4.landscape; + latex_papersize_and_orientation = outputLaTeXstyPaperSizeAndOrientation!()(sty_b4l); + latex_papersize_and_orientation.writeOutputLaTeXstyStatic(output_dir, sty_b4l.stylesheet ~ ".sty"); + auto sty_a5p = paper.a5.portrait; + latex_papersize_and_orientation = outputLaTeXstyPaperSizeAndOrientation!()(sty_a5p); + latex_papersize_and_orientation.writeOutputLaTeXstyStatic(output_dir, sty_a5p.stylesheet ~ ".sty"); + auto sty_a5l = paper.a5.landscape; + latex_papersize_and_orientation = outputLaTeXstyPaperSizeAndOrientation!()(sty_a5l); + latex_papersize_and_orientation.writeOutputLaTeXstyStatic(output_dir, sty_a5l.stylesheet ~ ".sty"); + auto sty_letter_p = paper.letter.portrait; + latex_papersize_and_orientation = outputLaTeXstyPaperSizeAndOrientation!()(sty_letter_p); + latex_papersize_and_orientation.writeOutputLaTeXstyStatic(output_dir, sty_letter_p.stylesheet ~ ".sty"); + auto sty_letter_l = paper.letter.landscape; + latex_papersize_and_orientation = outputLaTeXstyPaperSizeAndOrientation!()(sty_letter_l); + latex_papersize_and_orientation.writeOutputLaTeXstyStatic(output_dir, sty_letter_l.stylesheet ~ ".sty"); + auto sty_legal_p = paper.legal.portrait; + latex_papersize_and_orientation = outputLaTeXstyPaperSizeAndOrientation!()(sty_legal_p); + latex_papersize_and_orientation.writeOutputLaTeXstyStatic(output_dir, sty_legal_p.stylesheet ~ ".sty"); + auto sty_legal_l = paper.legal.landscape; + latex_papersize_and_orientation = outputLaTeXstyPaperSizeAndOrientation!()(sty_legal_l); + latex_papersize_and_orientation.writeOutputLaTeXstyStatic(output_dir, sty_legal_l.stylesheet ~ ".sty"); } #+END_SRC -***** nbsp character +**** sty: paper dimensions sty (calls static sty) -#+NAME: Function_shared_character_nbsp_to_hardspace +#+NAME: FmtTxt_output_style_paper_dimensions_set #+BEGIN_SRC d -@safe string nbsp_char()(string _txt) { - if (_txt.match(rgx.nbsp_char)) { - foreach (m; _txt.matchAll(rgx.nbsp_chars)) { - int spaces_ = 0; - foreach (n; m[0].matchAll(rgx.nbsp_char)) { - spaces_ ++; - } - _txt = _txt.replaceFirst(rgx.nbsp_chars, "\\spaces{" ~ spaces_.to!string ~ "}"); - } - } - return _txt; + string latex_sty = format(q"┃%% - called by .tex document to set paper dimensions (size and orientation) +%% - calls spineShared.sty used/shared by all spine documents +\ProvidesPackage{./sty/%s} +\usepackage{geometry} +\geometry{ + %s, + %s, + left=%s, + right=%s, + top=%s, + bottom=%s, } +\usepackage{./sty/spineShared}┃", + doc_sty_info.stylesheet, + doc_sty_info.papersize, + doc_sty_info.orient, + doc_sty_info.margin_left, + doc_sty_info.margin_right, + doc_sty_info.margin_top, + doc_sty_info.margin_bottom, +); #+END_SRC -***** keep spaces - -#+NAME: Function_shared_character_spaces_to_hardspace -#+BEGIN_SRC d -@safe string spaces_to_nbsp()(string _txt) { - if (_txt.match(rgx.spaces_keep)) { - foreach (m; _txt.matchAll(rgx.spaces_keep)) { - int spaces_ = 0; - foreach (n; m[0].matchAll(rgx.space)) { - spaces_ ++; - } - _txt = _txt.replaceFirst(rgx.spaces_keep, "\\spaces{" ~ spaces_.to!string ~ "}"); - } - } - return _txt; -} -#+END_SRC +**** sty: in common -***** remove nbsp character +fonts to try: -#+NAME: Function_shared_character_nbsp_to_space -#+BEGIN_SRC d -@safe string nbsp_char_to_space()(string _txt) { - if (_txt.match(rgx.nbsp_char)) { - _txt = _txt.replaceAll(rgx.nbsp_char, " "); - } - return _txt; -} +#+BEGIN_SRC latex +\usepackage[scaled]{dejavu} +\renewcommand*\familydefault{\sfdefault} +\usepackage{inconsolata} +\usepackage[T1]{fontenc} #+END_SRC -**** links and images -***** links / urls - -#+NAME: Function_shared_links_and_images -#+BEGIN_SRC d -@safe string links_and_images(O,M)( - string _txt, - const O obj, - M doc_matters, -) { - if (obj.has.inline_links) { // TODO some images do not have inline links ... image without link - string _width_adjust(string _width) { +#+BEGIN_SRC latex +\usepackage[scaled]{dejavu} +\usepackage[scaled]{tgheros} +\usepackage[scaled]{quattrocento} +\usepackage[scaled]{cmbright} +\usepackage[scaled]{tgadventor} +\usepackage[scaled]{bookman} +\usepackage[scaled]{libertine} +\usepackage[scaled]{bera} +\usepackage[scale=.95,type1]{arev} +\usepackage[scale=.95,type1]{cabin} +#+END_SRC + +#+NAME: FmtTxt_output_style_static_set +#+BEGIN_SRC latex + string latex_sty = format(q"┃%% - called by the .sty containing the paper dimensions (size and orientation) to be used +%% - spineShared.sty used by all spine documents (called indirectly) +\ProvidesPackage{./sty/spineShared} +\usepackage{multicol} +\setlength{\marginparsep}{4mm} +\setlength{\marginparwidth}{8mm} +\usepackage[scaled]{dejavu} +\renewcommand*\familydefault{\sfdefault} +\usepackage{inconsolata} +\usepackage[T1]{fontenc} +\usepackage{newunicodechar} +%% \usepackage[utf8]{inputenc} +\usepackage{alltt} +\usepackage[ + unicode=true, + pdfusetitle, + pdfsubject={}, + pdfkeywords={}, %% keywords list {} {} {}, + pdftoolbar=true, + pdfmenubar=true, + pdfwindowui=true, + pdffitwindow=false, %% window fit to page when opened + pdfstartview={FitH}, %% fits the width of the page to the window + pdfnewwindow=true, %% links in new window + pdfborder={0 0 1}, + plainpages=false, %% was true + bookmarks=true, + bookmarksopen=false, + bookmarksnumbered=false, + backref=false, + breaklinks=false, + colorlinks=true, + urlcolor=black, + filecolor=black, + linkcolor=black, + citecolor=black, %% links_mono_or_color_set +]{hyperref} +\PassOptionsToPackage{hyphens}{url}\usepackage{hyperref} +\usepackage[usenames]{color} +\definecolor{myblack}{rgb}{0,0,0} +\definecolor{myred}{rgb}{0.75,0,0} +\definecolor{mygreen}{rgb}{0,0.5,0} +\definecolor{myblue}{rgb}{0,0,0.5} +\definecolor{mywhite}{rgb}{1,1,1} +\usepackage{textcomp} +\usepackage[parfill]{parskip} +\usepackage[normalem]{ulem} +\usepackage{soul} +\usepackage{longtable} +\usepackage{graphicx} +\usepackage[tc]{titlepic} +\usepackage{amssymb} +\usepackage{amsmath} +\usepackage[cm]{sfmath} +\usepackage{underscore} +\usepackage{listings} +\setcounter{secnumdepth}{2} +\setcounter{tocdepth}{4} +\usepackage{bookmark} +\usepackage{microtype} +\makeatletter +\usepackage[multiple,ragged]{footmisc} +\setlength\footnotemargin{12pt} +\usepackage[para]{manyfoot} +\DeclareNewFootnote{A} +\makeatother +\chardef\txtbullet="2022 +\chardef\tilde="7E +\def\asterisk{{\rm \char42} } +\definecolor{Light}{gray}{.92} +\definecolor{listinggray}{gray}{0.9} +\definecolor{lbcolor}{rgb}{0.9,0.9,0.9} +\lstset{ + backgroundcolor=\color{lbcolor}, + tabsize=4, + rulecolor=, + language=, + basicstyle={\ttfamily\scriptsize}, + upquote=true, + columns=fixed, + showstringspaces=false, + extendedchars=true, + breaklines=true, + prebreak = \raisebox{0ex}[0ex][0ex]{\ensuremath{\hookleftarrow}}, + frame=single, + showtabs=false, + showspaces=false, + showstringspaces=false, + identifierstyle=\ttfamily, + keywordstyle=\color[rgb]{0,0,1}, + commentstyle=\color[rgb]{0.133,0.545,0.133}, + stringstyle=\color[rgb]{0.627,0.126,0.941}, +} +\DeclareTOCStyleEntry[numwidth+=8pt]{part}{part} +\DeclareTOCStyleEntry[numwidth+=4pt]{section}{section} +\DeclareTOCStyleEntry[numwidth+=3pt]{section}{paragraph} +\DeclareTOCStyleEntry[numwidth+=3pt]{section}{subparagraph} +\DeclareTOCStyleEntry[numwidth+=3pt]{section}{subsection} +\DeclareTOCStyleEntries[indent+=4pt]{section}{section,subsection,subsubsection} +\DeclareTOCStyleEntries[numwidth+=3pt]{section}{paragraph,subparagraph} +\newenvironment{ParagraphIndent}[1]{%% + \begin{list}{}{%% + \setlength\topsep{0pt}%% + \addtolength{\leftmargin}{#1} + \setlength\parsep{0pt plus 1pt}%% + } + \item[] +} {\end{list}} +\newenvironment{ParagraphHang}[2]{%% + \begin{list}{}{%% + \setlength\topsep{0pt}%% + \addtolength{\leftmargin}{#1} + \itemindent=#2 + \setlength\parsep{0pt plus 1pt}%% + } + \item[] +} {\end{list}} +\newenvironment{Bullet}[1]{%% + \begin{list}{}{%% + \setlength\topsep{0pt}%% + \addtolength{\leftmargin}{#1} + \itemindent=-1em + \setlength\parsep{0pt plus 1pt}%% + } + \item[] + $\txtbullet$\hspace{\enspace} +} {\end{list}} +\newcommand{\monosp}[1]{\normaltext\ttfamily\texbackslash#1} +\newcommand{\br}{\hfill\break} +\newcommand{\brl}[1]{%% + \ifx&%% + \hfill\break + \else + \vspace{#1ex} + \fi +} +\newcommand{\brln}{\hspace*{\fill}\linebreak} +\newcommand{\objBlockOpen}{%% + \setlength{\parskip}{0.5ex plus0.2ex minus0.1ex}\raggedright + \begin{footnotesize} +} +\newcommand{\objBlockClose}{%% + \end{footnotesize} + \setlength{\parskip}{1ex plus0.5ex minus0.2ex} +} +\newcommand{\objGroupOpen}{%% + \setlength{\parskip}{0.5ex plus0.2ex minus0.1ex} + \begin{footnotesize} +} +\newcommand{\objGroupClose}{%% + \end{footnotesize} +} +\newcommand{\objPoemVerseOpen}{%% + \setlength{\parskip}{0.1ex plus0.1ex minus0.1ex} + \begin{footnotesize} + +} +\newcommand{\objPoemVerseClose}{%% + + \end{footnotesize} + \setlength{\parskip}{1ex plus0.5ex minus0.2ex} + \linebreak +} +\newcommand{\parasep}{%% + \smallskip \begin{center}*\hspace{2em}*\hspace{2em}*\end{center} \br +} +\newcommand{\spaces}[1]{{\hspace*{#1ex}}} +\newcommand{\s}{\hspace*{1ex}} +\newcommand{\hardspace}{\hspace*{1ex}} +\newcommand{\-}{\hspace*{1ex}} +\newcommand{\caret}{{\^{~}}} +\newcommand{\pipe}{{\textbar}} +\newcommand{\curlyOpen}{{} +\newcommand{\curlyClose}{}} +\newcommand{\lt}{{UseTextSymbol{OML}{<}}} +\newcommand{\gt}{{UseTextSymbol{OML}{>}}} +\newcommand{\slash}{{/}} +\newcommand{\underscore}{\_} +\newcommand{\exclaim}{\Verbatim{!}} +\newcommand{\linktext}[2]{%% + {\href{#1} + {\;\ulcorner\,\textup{{#2}}\,\lrcorner}} +} +\newcommand{\linkurl}[2]{%% + \;{\href{#1} + {\;\scriptsize\ttfamily\ulcorner\,\textup{{#2}}\,\lrcorner}} +} +\newcommand{\link}[2]{%% + {\begin{scriptsize}\color{black}\urlstyle{tt}\href{#1} + {\;\ulcorner\,{#2}\,\lrcorner}\end{scriptsize}} +} +\newcommand{\objCodeBlock}[1]{\normaltext\raggedright\small\ttfamily\texbackslash#1} +\newcommand{\objCodeOpen}{%% + \normaltext\raggedright\small\ttfamily\texbackslash + \begin{lstlisting} +} +\newcommand{\objCodeClose}{%% + \end{lstlisting} +} +\newcommand{\ocn}[1]{%% + \setlength{\parindent}{0em} + \ifx&%% #1 is empty + \hspace{-0.5ex}{\marginpar{\begin{tiny}\end{tiny}}} + \else%% #1 is nonempty + \hspace{-0.5ex}{\marginpar{\begin{tiny}\hspace{0em}\hypertarget{#1}{#1}\end{tiny}}} + \fi +} +\newcommand{\ocnhold}[1]{%% + \begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{#1}{#1}\end{tiny}}} +} +\newcommand{\objCodeBlockHold}[1]{\normaltext\raggedright\small\ttfamily\texbackslash#1} +\newcommand{\objTableOpen}[1]{%% + \setlength{\LTleft}{0pt} + \setlength{\LTright}{\fill} + \begin{tiny} + \begin{longtable}{#1} +} +\newcommand{\objTableClose}{%% + \end{longtable} + \end{tiny} +} +%% \tolerance=300 +%% \clubpenalty=300 +%% \widowpenalty=300 +%% \usepackage{atbegshi} %% http://ctan.org/pkg/atbegshi %% (BUG tmp FIX deal with problem, remove first page which is blank) +%% \AtBeginDocument{\AtBeginShipoutNext{\AtBeginShipoutDiscard}} %% (BUG tmp FIX deal with problem, remove first page which is blank) +┃"); +#+END_SRC + +* stuff +** output imports + +#+NAME: ImportsAndMixins_imports +#+BEGIN_SRC d +import + std.digest.sha, + std.file, + std.outbuffer, + std.uri, + std.conv : to; +import doc_reform.io_out; +mixin InternalMarkup; // watch +mixin spineRgxOut; +static auto rgx = RgxO(); +mixin spineLanguageCodes; +auto lang = Lang(); +auto paper = paperLaTeX; +#+END_SRC + +** shared +*** paper dimensions (struct) geometry + +#+NAME: Struct_shared_geometry_paper_dimensions +#+BEGIN_SRC d +string mm(uint mmi) { + string _mm = format(q"┃%smm┃", mmi.to!string); + return _mm; +} +struct PaperType { + @safe auto a4() { + struct A4 { + auto portrait() { + struct V { + string stylesheet = "spineA4portrait"; + string papersize = "a4paper"; + string orient = "portrait"; + string fontsize = "11pt"; + const uint w = 170; + const uint h = 257; + const uint l = 30; + const uint r = 20; + const uint t = 30; + const uint b = 30; + string width = mm(w); + string height = mm(h); + string margin_left = mm(l); + string margin_right = mm(r); + string margin_top = mm(t); + string margin_bottom = mm(b); + uint img_px = 450; + bool is_portrait = true; + } + return V(); + } + auto landscape() { + struct H { + string stylesheet = "spineA4landscape"; + string papersize = "a4paper"; + string orient = "landscape"; + string fontsize = "11pt"; + const uint w = 238; + const uint h = 160; + const uint l = 30; + const uint r = 20; + const uint t = 30; + const uint b = 30; + string width = mm(w); + string height = mm(h); + string margin_left = mm(l); + string margin_right = mm(r); + string margin_top = mm(t); + string margin_bottom = mm(b); + uint img_px = 300; + bool is_portrait = false; + } + return H(); + } + } + return A4(); + } + @safe auto a5() { + struct A5 { + auto portrait() { + struct V { + string stylesheet = "spineA5portrait"; + string papersize = "a5paper"; + string orient = "portrait"; + string fontsize = "11pt"; + const uint w = 112; + const uint h = 162; + const uint l = 30; + const uint r = 20; + const uint t = 30; + const uint b = 30; + string width = mm(w); + string height = mm(h); + string margin_left = mm(l); + string margin_right = mm(r); + string margin_top = mm(t); + string margin_bottom = mm(b); + uint img_px = 280; + bool is_portrait = true; + } + return V(); + } + auto landscape() { + struct H { + string stylesheet = "spineA5landscape"; + string papersize = "a5paper"; + string orient = "landscape"; + string fontsize = "11pt"; + const uint w = 152; + const uint h = 100; + const uint l = 30; + const uint r = 20; + const uint t = 30; + const uint b = 30; + string width = mm(w); + string height = mm(h); + string margin_left = mm(l); + string margin_right = mm(r); + string margin_top = mm(t); + string margin_bottom = mm(b); + uint img_px = 190; + bool is_portrait = false; + } + return H(); + } + } + return A5(); + } + @safe auto b4() { + struct B4 { + auto portrait() { + struct V { + string stylesheet = "spineB4portrait"; + string papersize = "b4paper"; + string orient = "portrait"; + string fontsize = "11pt"; + const uint w = 140; + const uint h = 204; + const uint l = 30; + const uint r = 20; + const uint t = 30; + const uint b = 30; + string width = mm(w); + string height = mm(h); + string margin_left = mm(l); + string margin_right = mm(r); + string margin_top = mm(t); + string margin_bottom = mm(b); + uint img_px = 356; + bool is_portrait = true; + } + return V(); + } + auto landscape() { + struct H { + string stylesheet = "spineB4landsape"; + string papersize = "b4paper"; + string orient = "landscape"; + string fontsize = "11pt"; + const uint w = 200; + const uint h = 130; + const uint l = 30; + const uint r = 20; + const uint t = 30; + const uint b = 30; + string width = mm(w); + string height = mm(h); + string margin_left = mm(l); + string margin_right = mm(r); + string margin_top = mm(t); + string margin_bottom = mm(b); + uint img_px = 260; + bool is_portrait = false; + } + return H(); + } + } + return B4(); + } + @safe auto letter() { + struct Letter { + auto portrait() { + struct V { + string stylesheet = "spineLetterPortrait"; + string papersize = "letterpaper"; + string orient = "portrait"; + string fontsize = "11pt"; + const uint w = 166; + const uint h = 212; + const uint l = 30; + const uint r = 20; + const uint t = 30; + const uint b = 30; + string width = mm(w); + string height = mm(h); + string margin_left = mm(l); + string margin_right = mm(r); + string margin_top = mm(t); + string margin_bottom = mm(b); + uint img_px = 468; + bool is_portrait = true; + } + return V(); + } + auto landscape() { + struct H { + string stylesheet = "spineLetterLandscape"; + string papersize = "letterpaper"; + string orient = "landscape"; + string fontsize = "11pt"; + const uint w = 226; + const uint h = 166; + const uint l = 30; + const uint r = 20; + const uint t = 30; + const uint b = 30; + string width = mm(w); + string height = mm(h); + string margin_left = mm(l); + string margin_right = mm(r); + string margin_top = mm(t); + string margin_bottom = mm(b); + uint img_px = 290; + bool is_portrait = false; + } + return H(); + } + } + return Letter(); + } + @safe auto legal() { + struct Legal { + auto portrait() { + struct V { + string stylesheet = "spineLegalPortrait"; + string papersize = "legalpaper"; + string orient = "portrait"; + string fontsize = "11pt"; + const uint w = 168; + const uint h = 286; + const uint l = 30; + const uint r = 20; + const uint t = 30; + const uint b = 30; + string width = mm(w); + string height = mm(h); + string margin_left = mm(l); + string margin_right = mm(r); + string margin_top = mm(t); + string margin_bottom = mm(b); + uint img_px = 474; + bool is_portrait = true; + } + return V(); + } + auto landscape() { + struct H { + string stylesheet = "spineLegalLandscape"; + string papersize = "legalpaper"; + string orient = "landscape"; + string fontsize = "11pt"; + const uint w = 296; + const uint h = 166; + const uint l = 30; + const uint r = 20; + const uint t = 30; + const uint b = 30; + string width = mm(w); + string height = mm(h); + string margin_left = mm(l); + string margin_right = mm(r); + string margin_top = mm(t); + string margin_bottom = mm(b); + uint img_px = 420; + bool is_portrait = false; + } + return H(); + } + } + return Legal(); + } +} +#+END_SRC + +*** latex \escape special characters +**** object (string text within) + +- “” characters not directly available for use in font +- run into problems using " for quotes and modified latex header + - (m => "\"") + - \usepackage[autostyle, english = american]{csquotes} + \MakeOuterQuote{"} +- (m => "''") works alone better + +#+NAME: Function_shared_special_characters_to_escape_operations +#+BEGIN_SRC d +@safe string sp_char_ops()( + string _txt, +) { + string _unescape_sp_char_esc()(string _txt) { + _txt = _txt + .replaceAll(rgx.latex_special_char_escaped, + format(q"┃%s┃", "$1")) + .replaceAll(rgx.latex_special_char_escaped_braced, + format(q"┃%s┃", "$1")); + return _txt; + } + string _unescape_fontface_esc()(string _txt) { + _txt = _txt.replaceAll(rgx.latex_identify_inline_fontface, + format(q"┃%s%s┃", "$1", "$2")); + return _txt; + } + _txt = replaceAll!(m => "\\" ~ m[1])(_txt, rgx.latex_special_char_for_escape); + _txt = replaceAll!(m => "{\\" ~ m[1] ~ "}")(_txt, rgx.latex_special_char_for_escape_and_braces); + _txt = replaceAll!(m => "''")(_txt, rgx.quotes_open_and_close); + _txt = replaceAll!(m => "$\\cdot$")(_txt, rgx.middle_dot); + _txt = replaceAll!(m => _unescape_sp_char_esc(m[0]))(_txt, rgx.latex_identify_inline_link); + _txt = replaceAll!(m => _unescape_fontface_esc(m[0]))(_txt, rgx.latex_identify_inline_fontface); + return _txt; +} +#+END_SRC + +#+NAME: Function_shared_special_characters_to_escape_object +#+BEGIN_SRC d +@safe string sp_char_esc(O)( + string _txt, + const O obj, +) { + if (obj.metainfo.is_a != "code") { + _txt = _txt.sp_char_ops; + } + return _txt; +} +#+END_SRC + +**** string text + +#+NAME: Function_shared_special_characters_to_escape_text +#+BEGIN_SRC d +@safe string sp_char_esc_txt()( + string _txt, +) { + _txt = _txt.sp_char_ops; + return _txt; +} +#+END_SRC + +***** line breaks + +#+NAME: Function_shared_marked_linebreaks_newline_to_latex +#+BEGIN_SRC d +@safe string marked_linebreaks_newlines()( + string _txt, +) { + _txt = _txt.split(rgx.br_linebreaks_newlines).join("\\br\n").strip; + // _txt = replaceAll!(m => "\\br " ~ m[1])(_txt, rgx.br_linebreaks_newlines); + return _txt; +} +#+END_SRC + +*** not used latex \escape special characters UNUSED + +#+BEGIN_SRC d +@safe string sp_char_esc_()( + string _txt, +) { + _txt = replaceAll!(m => "\\" ~ m[1])(_txt, rgx.latex_special_char); + return _txt; +} +#+END_SRC + +*** inline markup +**** fontface + +- bold, italics, underscore, strikethrough + +#+NAME: Function_shared_fontface +#+BEGIN_SRC d +@safe string fontface()( + string _txt, +) { +_txt = _txt + .replaceAll(rgx.inline_emphasis, format(q"┃\begin{bfseries}%s\end{bfseries}┃", "$1")) + .replaceAll(rgx.inline_bold, format(q"┃\begin{bfseries}%s\end{bfseries}┃", "$1")) + .replaceAll(rgx.inline_italics, format(q"┃\emph{%s}┃", "$1")) + .replaceAll(rgx.inline_italics, format(q"┃\uline{%s}┃", "$1")) + .replaceAll(rgx.inline_superscript, format(q"┃$$^{%s}$$┃", "$1")) + .replaceAll(rgx.inline_subscript, format(q"┃$$_{%s}$$┃", "$1")) + .replaceAll(rgx.inline_strike, format(q"┃\sout{%s}┃", "$1")) + .replaceAll(rgx.inline_insert, format(q"┃\uline{%s}┃", "$1")) + .replaceAll(rgx.inline_mono, format(q"┃\begin{monosp}%s\end{monosp}┃", "$1")) + .replaceAll(rgx.inline_italics, format(q"┃``%s''┃", "$1")); + return _txt; +} +#+END_SRC + +**** spaces +***** leading hardspace UNUSED + +#+NAME: Function_shared_leading_hardspaces +#+BEGIN_SRC d +@safe string leading_hardspaces()( + string _txt, +) { + string hardspaces(string _spaces) { + _spaces = _spaces + .replaceAll(rgx.space, "{\\s}"); + return _spaces; + } + _txt = replaceAll!(m => hardspaces(m[0]))(_txt, rgx.spaces_line_start); + return _txt; +} +#+END_SRC + +***** nbsp character UNUSED + +#+NAME: output_latex_shared_character_nbsp_to_hardspace_ +#+BEGIN_SRC d +@safe string nbsp_char_replace()(string _txt) { + if (_txt.match(rgx.nbsp_char)) { + _txt = _txt.replaceAll(rgx.nbsp_char, "{\\s}"); + } + return _txt; +} +#+END_SRC + +***** nbsp character + +#+NAME: Function_shared_character_nbsp_to_hardspace +#+BEGIN_SRC d +@safe string nbsp_char()(string _txt) { + if (_txt.match(rgx.nbsp_char)) { + foreach (m; _txt.matchAll(rgx.nbsp_chars)) { + int spaces_ = 0; + foreach (n; m[0].matchAll(rgx.nbsp_char)) { + spaces_ ++; + } + _txt = _txt.replaceFirst(rgx.nbsp_chars, "\\spaces{" ~ spaces_.to!string ~ "}"); + } + } + return _txt; +} +#+END_SRC + +***** keep spaces + +#+NAME: Function_shared_character_spaces_to_hardspace +#+BEGIN_SRC d +@safe string spaces_to_nbsp()(string _txt) { + if (_txt.match(rgx.spaces_keep)) { + foreach (m; _txt.matchAll(rgx.spaces_keep)) { + int spaces_ = 0; + foreach (n; m[0].matchAll(rgx.space)) { + spaces_ ++; + } + _txt = _txt.replaceFirst(rgx.spaces_keep, "\\spaces{" ~ spaces_.to!string ~ "}"); + } + } + return _txt; +} +#+END_SRC + +***** remove nbsp character + +#+NAME: Function_shared_character_nbsp_to_space +#+BEGIN_SRC d +@safe string nbsp_char_to_space()(string _txt) { + if (_txt.match(rgx.nbsp_char)) { + _txt = _txt.replaceAll(rgx.nbsp_char, " "); + } + return _txt; +} +#+END_SRC + +**** links and images +***** links / urls + +#+NAME: Function_shared_links_and_images +#+BEGIN_SRC d +@safe string links_and_images(O,M)( + string _txt, + const O obj, + M doc_matters, +) { + if (obj.has.inline_links) { // TODO some images do not have inline links ... image without link + string _width_adjust(string _width) { if (_width.to!int > 300) { _width = "300"; } // will need to vary max with papersize & orientation return _width; } @@ -966,8 +1407,8 @@ _txt = _txt (doc_matters.conf_make_meta.meta.title_main).sp_char_esc_txt, (doc_matters.conf_make_meta.meta.title_main).sp_char_esc_txt, (doc_matters.conf_make_meta.meta.title_full).sp_char_esc_txt, - (doc_matters.conf_make_meta.meta.rights_copyright).sp_char_esc_txt, - (doc_matters.conf_make_meta.meta.rights_license).sp_char_esc_txt, + (doc_matters.conf_make_meta.meta.rights_copyright).sp_char_esc_txt.marked_linebreaks_newlines, + (doc_matters.conf_make_meta.meta.rights_license).sp_char_esc_txt.marked_linebreaks_newlines, ); } else if (obj.metainfo.heading_lev_markup < 4) { if (!(_txt.footnotes.strip == "Endnotes")) { @@ -1427,7 +1868,7 @@ citecolor=black, ); #+END_SRC -**** latex head starts +**** latex head open ***** dimensions & orientation ****** set @@ -1446,27 +1887,51 @@ if (paper_set.is_portrait) { #+NAME: FmtTxtSet_head_format_string_paper_set_format_portrait_tex #+BEGIN_SRC latex \documentclass[%s,%s,titlepage,makeidx]{scrartcl} -\usepackage{geometry} -\geometry{ - %s, - %s, - left=%s, - right=%s, - top=%s, - bottom=%s, -}┃", +\usepackage{%s} +\usepackage[%s,%s]{babel} +\usepackage[autostyle, english = american]{csquotes} +%% \MakeOuterQuote{"} %% not required, using '' as quote delimiter +\selectlanguage{%s} +\hypersetup{ + pdftitle={%s}, + pdfauthor={%s}, + pdfsubject={%s}, +} +#+END_SRC + +#+BEGIN_SRC latex +\usepackage[%s,%s]{babel} +\usepackage[autostyle, english = american]{csquotes} +\MakeOuterQuote{"} +\setmainlanguage{} +\setotherlanguage{} +\selectlanguage{%s} +%% \usepackage{polyglossia} +#+END_SRC + +#+NAME: FmtTxtSet_head_tex_set_part_section_subsection_subsubsection_paragraph_subparagraph +#+BEGIN_SRC latex +\usepackage{fancyhdr} +\lhead[ ]{ } +\chead[ \fancyplain{} \bfseries \footnotesize \leftmark ]{ \fancyplain{} \bfseries \footnotesize \rightmark } +\rhead[ ]{ } +%s +\rfoot[\tiny \href{}{}]{\textrm{\thepage}} #+END_SRC #+NAME: FmtTxtClose_head_format_string_paper_set_format_portrait_variables #+BEGIN_SRC d +┃", paper_set.fontsize, paper_set.papersize, - paper_set.papersize, - paper_set.orient, - paper_set.margin_left, - paper_set.margin_right, - paper_set.margin_top, - paper_set.margin_bottom, + "./sty/" ~ paper_set.stylesheet, + lang.codes[doc_matters.src.language]["xlp"], + "english", + lang.codes[doc_matters.src.language]["xlp"], + doc_matters.conf_make_meta.meta.title_full.strip, + doc_matters.conf_make_meta.meta.creator_author.strip, + doc_matters.conf_make_meta.meta.classify_subject.strip, + _footer(doc_matters), ); #+END_SRC @@ -1477,457 +1942,127 @@ if (paper_set.is_portrait) { #+END_SRC #+NAME: FmtTxtSet_head_format_string_paper_set_format_landscape_tex -#+BEGIN_SRC d -\documentclass[%s,%s,landscape,titlepage,twocolumn,makeidx]{scrartcl} -\usepackage{geometry} -\geometry{ - %s, - %s, - left=%s, - right=%s, - top=%s, - bottom=%s, -}┃", -#+END_SRC - -#+NAME: FmtTxtClose_head_format_string_paper_set_format_landscape_variables -#+BEGIN_SRC d - paper_set.fontsize, - paper_set.papersize, - paper_set.papersize, - paper_set.orient, - paper_set.margin_left, - paper_set.margin_right, - paper_set.margin_top, - paper_set.margin_bottom, -); -#+END_SRC - -#+NAME: MethodClose_head_format_string_paper_set_return -#+BEGIN_SRC d - } - return paper_type_description; -} -#+END_SRC - -***** (a4, a5, b4, letter, legal) * (portrait & landscape) - -#+BEGIN_SRC sh -$SpineBIN/spine --verbose --latex --set-papersize="a4,letter.portrait,b4.portrait" --output="$SpineOUT" $SpinePOD/* -#+END_SRC - -#+NAME: Switch_head_format_string_paper_set_orientation -#+BEGIN_SRC d -string paper_size_orientation_latex; -switch (paper_size_orientation) { - case "a4.portrait": paper_size_orientation_latex = set_paper(paper.a4.portrait); break; - case "a4.landscape": paper_size_orientation_latex = set_paper(paper.a4.landscape); break; - case "b4.portrait": paper_size_orientation_latex = set_paper(paper.b4.portrait); break; - case "b4.landscape": paper_size_orientation_latex = set_paper(paper.b4.landscape); break; - case "a5.portrait": paper_size_orientation_latex = set_paper(paper.a5.portrait); break; - case "a5.landscape": paper_size_orientation_latex = set_paper(paper.a5.landscape); break; - case "letter.portrait": paper_size_orientation_latex = set_paper(paper.letter.portrait); break; - case "letter.landscape": paper_size_orientation_latex = set_paper(paper.letter.landscape); break; - case "legal.portrait": paper_size_orientation_latex = set_paper(paper.legal.portrait); break; - case "legal.landscape": paper_size_orientation_latex = set_paper(paper.legal.landscape); break; - default: paper_size_orientation_latex = paper_type_latex.a4_portrait; -} -#+END_SRC - -***** set color links - -#+NAME: ConditionalSetVar_head_format_string_paper_set_color -#+BEGIN_SRC d -string links_mono_or_color_set = links.mono.strip; -if ( - (doc_matters.opt.action.latex_color_links) - || (paper_size_orientation == - "a4.landscape" || - "a5.landscape" || - "b4.landscape" || - "letter.landscape" || - "legal.landscape") -){ - links_mono_or_color_set = links.mono.strip; -} -#+END_SRC - -***** format latex head, open - -#+NAME: FmtTxtOpen_head_format_tex_set_start_latex_head -#+BEGIN_SRC d -string _latex_head = format(q"┃%%%% spine LaTeX output%s%s%s -#+END_SRC - -***** description comment - -#+NAME: FmtTxtSet_head_tex_set_generated_by -#+BEGIN_SRC latex -%%%% %s %s -#+END_SRC - -***** paper type (a4, letter, ...; ( portrait | landscape )) - -- paper_type_latex.a4_portrait -- paper_type_latex.a4_landscape -- paper_type_latex.us_letter_portrait -- paper_type_latex.us_letter_landscape - -#+NAME: FmtTxtSet_head_tex_set_paper_type -#+BEGIN_SRC latex -%s -#+END_SRC - -***** paper margins (portrait | landscape) - -- margins.portrait -- margins.landscape - -#+NAME: FmtTxtSet_head_tex_set_orintation -#+BEGIN_SRC latex -%s -#+END_SRC - -***** multicol (portrait | landscape) - -#+NAME: FmtTxtSet_head_tex_set_columns -#+BEGIN_SRC latex -%s -#+END_SRC - -***** margin shared - -#+NAME: FmtTxtSet_head_tex_set_margins -#+BEGIN_SRC latex -\setlength{\marginparsep}{4mm} -\setlength{\marginparwidth}{8mm} -#+END_SRC - -***** language & font - -#+NAME: FmtTxtSet_head_tex_set_usepackages_languages_and_font #+BEGIN_SRC latex -\usepackage[scaled]{dejavu} -\renewcommand*\familydefault{\sfdefault} -\usepackage{inconsolata} -\usepackage[T1]{fontenc} -%% \usepackage[utf8]{inputenc} +\documentclass[%s,%s,landscape,titlepage,twocolumn,makeidx]{scrartcl} +\usepackage{%s} \usepackage[english]{babel} -\usepackage{newunicodechar} -\usepackage{polyglossia} +%% \usepackage{polyglossia} \setmainlanguage{%s} \setotherlanguage{%s} -#+END_SRC - -%% \setsansfont{Liberation Sans} -%% \setromanfont{Liberation Serif} - -***** latex head - -#+NAME: FmtTxtSet_head_tex_set_usepackages_1 -#+BEGIN_SRC latex -\usepackage{alltt} -\usepackage{hyperref} +\selectlanguage{%s} \hypersetup{ -#+END_SRC - -***** hyperref metadata - -#+NAME: FmtTxtSet_head_tex_set_metadata -#+BEGIN_SRC latex - unicode=true, - pdfusetitle, pdftitle={%s}, pdfauthor={%s}, pdfsubject={%s}, - pdfkeywords={}, %% keywords list {} {} {}, - pdftoolbar=true, - pdfmenubar=true, - pdfwindowui=true, - pdffitwindow=false, %% window fit to page when opened - pdfstartview={FitH}, %% fits the width of the page to the window - pdfnewwindow=true, %% links in new window - pdfborder={0 0 1}, - plainpages=false, %% was true - bookmarks=true, - bookmarksopen=false, - bookmarksnumbered=false, - backref=false, - breaklinks=false, - %% colorlinks=true, - %% urlcolor=black, - %% filecolor=black, - %% linkcolor=black, - %% citecolor=black, -%s %% links_mono_or_color_set } -\PassOptionsToPackage{hyphens}{url}\usepackage{hyperref} -#+END_SRC - -%% pdfusetitle=true, -%% pdfpagelayout=SinglePage, -%% pdfpagelayout=TwoColumnRight, -%% pdfpagelayout=TwoColumnLeft, -%% pdfstartpage=3, - -%%%% trace lost characters -%% \tracinglostchars = 1 -%% \tracingonline = 1 - -***** define colors - -#+NAME: FmtTxtSet_head_tex_set_colors -#+BEGIN_SRC latex -\usepackage[usenames]{color} -\definecolor{myblack}{rgb}{0,0,0} -\definecolor{myred}{rgb}{0.75,0,0} -\definecolor{mygreen}{rgb}{0,0.5,0} -\definecolor{myblue}{rgb}{0,0,0.5} -\definecolor{mywhite}{rgb}{1,1,1} #+END_SRC -***** latex head - -%%\usepackage{breakurl} - -***** latex head - -#+NAME: FmtTxtSet_head_tex_set_usepackage_misc -#+BEGIN_SRC latex -\usepackage{textcomp} -\usepackage[parfill]{parskip} -\usepackage[normalem]{ulem} -\usepackage{soul} -\usepackage{longtable} -\usepackage{graphicx} -\usepackage[tc]{titlepic} -\usepackage{amssymb} -\usepackage{amsmath} -\usepackage[cm]{sfmath} -\usepackage{listings} -\setcounter{secnumdepth}{2} -\setcounter{tocdepth}{4} -\usepackage{bookmark} -\usepackage{microtype} -\makeatletter +#+NAME: FmtTxtClose_head_format_string_paper_set_format_landscape_variables +#+BEGIN_SRC d +┃", + paper_set.fontsize, + paper_set.papersize, + "./sty/" ~ paper_set.stylesheet, + lang.codes[doc_matters.src.language]["xlp"], + "english", + lang.codes[doc_matters.src.language]["xlp"], + doc_matters.conf_make_meta.meta.title_full.strip, + doc_matters.conf_make_meta.meta.creator_author.strip, + doc_matters.conf_make_meta.meta.classify_subject.strip, + _footer(doc_matters), +); #+END_SRC -***** indent, bullet, list - -#+NAME: FmtTxtSet_head_tex_set_indent_bullet_list -#+BEGIN_SRC latex -\usepackage[multiple,ragged]{footmisc} -\setlength\footnotemargin{12pt} -\usepackage[para]{manyfoot} -\DeclareNewFootnote{A} +#+NAME: MethodClose_head_format_string_paper_set_return +#+BEGIN_SRC d + } + return paper_type_description; +} #+END_SRC -%%\DeclareNewFootnote[para]{A} +***** (a4, a5, b4, letter, legal) * (portrait & landscape) -***** part, section, subsection, subsubsection, paragraph, subparagraph +#+BEGIN_SRC sh +$SpineBIN/spine --verbose --latex --set-papersize="a4,letter.portrait,b4.portrait" --output="$SpineOUT" $SpinePOD/* +#+END_SRC -#+NAME: FmtTxtSet_head_tex_set_part_section_subsection_subsubsection_paragraph_subparagraph -#+BEGIN_SRC latex -\usepackage{fancyhdr} +#+NAME: Switch_head_format_string_paper_set_orientation +#+BEGIN_SRC d +string paper_size_orientation_latex; +switch (paper_size_orientation) { + case "a4.portrait": paper_size_orientation_latex = set_paper(paper.a4.portrait); break; + case "a4.landscape": paper_size_orientation_latex = set_paper(paper.a4.landscape); break; + case "b4.portrait": paper_size_orientation_latex = set_paper(paper.b4.portrait); break; + case "b4.landscape": paper_size_orientation_latex = set_paper(paper.b4.landscape); break; + case "a5.portrait": paper_size_orientation_latex = set_paper(paper.a5.portrait); break; + case "a5.landscape": paper_size_orientation_latex = set_paper(paper.a5.landscape); break; + case "letter.portrait": paper_size_orientation_latex = set_paper(paper.letter.portrait); break; + case "letter.landscape": paper_size_orientation_latex = set_paper(paper.letter.landscape); break; + case "legal.portrait": paper_size_orientation_latex = set_paper(paper.legal.portrait); break; + case "legal.landscape": paper_size_orientation_latex = set_paper(paper.legal.landscape); break; + default: paper_size_orientation_latex = paper_type_latex.a4_portrait; +} #+END_SRC -***** latex head misc. including defined commands +***** set color links -#+NAME: FmtTxtSet_head_tex_set_misc -#+BEGIN_SRC latex -\selectlanguage{%s} -\lhead[ ]{ } -\chead[ \fancyplain{} \bfseries \footnotesize \leftmark ]{ \fancyplain{} \bfseries \footnotesize \rightmark } -\rhead[ ]{ } -%s -\rfoot[\tiny \href{}{}]{\textrm{\thepage}} -%% \tolerance=300 -%% \clubpenalty=300 -%% \widowpenalty=300 -\makeatother -\chardef\txtbullet="2022 -\chardef\tilde="7E -\def\asterisk{{\rm \char42} } -\definecolor{Light}{gray}{.92} -\definecolor{listinggray}{gray}{0.9} -\definecolor{lbcolor}{rgb}{0.9,0.9,0.9} -\lstset{ - backgroundcolor=\color{lbcolor}, - tabsize=4, - rulecolor=, - language=, - basicstyle={\ttfamily\scriptsize}, - upquote=true, - columns=fixed, - showstringspaces=false, - extendedchars=true, - breaklines=true, - prebreak = \raisebox{0ex}[0ex][0ex]{\ensuremath{\hookleftarrow}}, - frame=single, - showtabs=false, - showspaces=false, - showstringspaces=false, - identifierstyle=\ttfamily, - keywordstyle=\color[rgb]{0,0,1}, - commentstyle=\color[rgb]{0.133,0.545,0.133}, - stringstyle=\color[rgb]{0.627,0.126,0.941}, +#+NAME: ConditionalSetVar_head_format_string_paper_set_color +#+BEGIN_SRC d +string links_mono_or_color_set = links.mono.strip; +if ( + (doc_matters.opt.action.latex_color_links) + || (paper_size_orientation == + "a4.landscape" || + "a5.landscape" || + "b4.landscape" || + "letter.landscape" || + "legal.landscape") +){ + links_mono_or_color_set = links.mono.strip; } -\DeclareTOCStyleEntry[numwidth+=8pt]{part}{part} -\DeclareTOCStyleEntry[numwidth+=4pt]{section}{section} -\DeclareTOCStyleEntry[numwidth+=3pt]{section}{paragraph} -\DeclareTOCStyleEntry[numwidth+=3pt]{section}{subparagraph} -\DeclareTOCStyleEntry[numwidth+=3pt]{section}{subsection} -\DeclareTOCStyleEntries[indent+=4pt]{section}{section,subsection,subsubsection} -\DeclareTOCStyleEntries[numwidth+=3pt]{section}{paragraph,subparagraph} #+END_SRC -***** latex head new environment +***** format latex head, open -#+NAME: FmtTxtSet_head_tex_newEnvironment -#+BEGIN_SRC latex -\newenvironment{ParagraphIndent}[1]{%% - \begin{list}{}{%% - \setlength\topsep{0pt}%% - \addtolength{\leftmargin}{#1} - \setlength\parsep{0pt plus 1pt}%% - } - \item[] -} {\end{list}} -\newenvironment{ParagraphHang}[2]{%% - \begin{list}{}{%% - \setlength\topsep{0pt}%% - \addtolength{\leftmargin}{#1} - \itemindent=#2 - \setlength\parsep{0pt plus 1pt}%% - } - \item[] -} {\end{list}} -\newenvironment{Bullet}[1]{%% - \begin{list}{}{%% - \setlength\topsep{0pt}%% - \addtolength{\leftmargin}{#1} - \itemindent=-1em - \setlength\parsep{0pt plus 1pt}%% - } - \item[] - $\txtbullet$\hspace{\enspace} -} {\end{list}} +#+NAME: FmtTxtOpen_head_format_tex_set_start_latex_head +#+BEGIN_SRC d +string _latex_head = format(q"┃%%%% spine LaTeX output%s%s%s #+END_SRC -***** latex head new commands defined +***** description comment -#+NAME: FmtTxtSet_head_tex_newCommands +#+NAME: FmtTxtSet_head_tex_set_generated_by #+BEGIN_SRC latex -\newcommand{\monosp}[1]{\normaltext\ttfamily\texbackslash#1} -\newcommand{\br}{\hfill\break} -\newcommand{\brl}[1]{%% - \ifx&%% - \hfill\break - \else - \vspace{#1ex} - \fi -} -\newcommand{\brln}{\hspace*{\fill}\linebreak} -\newcommand{\objBlockOpen}{ - \setlength{\parskip}{0.5ex plus0.2ex minus0.1ex}\raggedright - \begin{footnotesize} -} -\newcommand{\objBlockClose}{%% - \end{footnotesize} - \setlength{\parskip}{1ex plus0.5ex minus0.2ex} -} -\newcommand{\objGroupOpen}{%% - \setlength{\parskip}{0.5ex plus0.2ex minus0.1ex} - \begin{footnotesize} -} -\newcommand{\objGroupClose}{%% - \end{footnotesize} -} -\newcommand{\objPoemVerseOpen}{%% - \setlength{\parskip}{0.1ex plus0.1ex minus0.1ex} - \begin{footnotesize} +%%%% %s %s +#+END_SRC -} -\newcommand{\objPoemVerseClose}{%% +***** paper type (a4, letter, ...; ( portrait | landscape )) - \end{footnotesize} - \setlength{\parskip}{1ex plus0.5ex minus0.2ex} - \linebreak -} -\newcommand{\parasep}{%% - \smallskip \begin{center}*\hspace{2em}*\hspace{2em}*\end{center} \br -} -\newcommand{\spaces}[1]{{\hspace*{#1ex}}} -\newcommand{\s}{\hspace*{1ex}} -\newcommand{\hardspace}{\hspace*{1ex}} -\newcommand{\-}{\hspace*{1ex}} -\newcommand{\caret}{{\^{~}}} -\newcommand{\pipe}{{\textbar}} -\newcommand{\curlyOpen}{{} -\newcommand{\curlyClose}{}} -\newcommand{\lt}{{UseTextSymbol{OML}{<}}} -\newcommand{\gt}{{UseTextSymbol{OML}{>}}} -\newcommand{\slash}{{/}} -\newcommand{\underscore}{\_} -\newcommand{\exclaim}{\Verbatim{!}} -\newcommand{\linktext}[2]{%% - {\href{#1} - {\;\ulcorner\,\textup{{#2}}\,\lrcorner}} -} -\newcommand{\linkurl}[2]{%% - \;{\href{#1} - {\;\scriptsize\ttfamily\ulcorner\,\textup{{#2}}\,\lrcorner}} -} -\newcommand{\link}[2]{%% - {\begin{scriptsize}\color{black}\urlstyle{tt}\href{#1} - {\;\ulcorner\,{#2}\,\lrcorner}\end{scriptsize}} -} -\newcommand{\objCodeBlock}[1]{\normaltext\raggedright\small\ttfamily\texbackslash#1} -\newcommand{\objCodeOpen}{%% - \normaltext\raggedright\small\ttfamily\texbackslash - \begin{lstlisting} -} -\newcommand{\objCodeClose}{%% - \end{lstlisting} -} -\newcommand{\ocn}[1]{%% - \setlength{\parindent}{0em} - \ifx&%% - %% #1 is empty - \hspace{-0.5ex}{\marginpar{\begin{tiny}\end{tiny}}} - \else - %% #1 is nonempty - \hspace{-0.5ex}{\marginpar{\begin{tiny}\hspace{0em}\hypertarget{#1}{#1}\end{tiny}}} - \fi -} -\newcommand{\ocnhold}[1]{%% - \begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{#1}{#1}\end{tiny}}} -} -\newcommand{\objCodeBlockHold}[1]{\normaltext\raggedright\small\ttfamily\texbackslash#1} -\newcommand{\objTableOpen}[1]{%% - \setlength{\LTleft}{0pt} - \setlength{\LTright}{\fill} - \begin{tiny} - \begin{longtable}{#1} -} -\newcommand{\objTableClose}{%% - \end{longtable} - \end{tiny} -} +- paper_type_latex.a4_portrait +- paper_type_latex.a4_landscape +- paper_type_latex.us_letter_portrait +- paper_type_latex.us_letter_landscape + +#+NAME: FmtTxtSet_head_tex_set_paper_type +#+BEGIN_SRC latex +%s #+END_SRC -%%\chardef\asterisk="2A -%%\newcommand{\hardspace}{\hspace{.5em}} +***** paper margins (portrait | landscape) -***** latex remove blank first page BUG FIX can REMOVE UNUSED +- margins.portrait +- margins.landscape -#+NAME: FmtTxtSet_head_tex_bug_remove_blank_first_page +#+NAME: FmtTxtSet_head_tex_set_orintation #+BEGIN_SRC latex -\usepackage{atbegshi} %% http://ctan.org/pkg/atbegshi %% (BUG tmp FIX deal with problem, remove first page which is blank) -\AtBeginDocument{\AtBeginShipoutNext{\AtBeginShipoutDiscard}} %% (BUG tmp FIX deal with problem, remove first page which is blank) +%s #+END_SRC -**** latex head format inclusions +***** latex head + +%%\usepackage{breakurl} + +**** latex head close (variables set) #+NAME: FmtTxtClose_head_a_format_string_variables #+BEGIN_SRC d @@ -1939,15 +2074,6 @@ string _latex_head = format(q"┃%%%% spine LaTeX output%s%s%s doc_matters.generator_program.url_home.strip, paper_size_orientation_latex.strip, margins.portrait.strip, - multicol.portrait.strip, - lang.codes[doc_matters.src.language]["xlp"], - "english", - doc_matters.conf_make_meta.meta.title_full.strip, - doc_matters.conf_make_meta.meta.creator_author.strip, - doc_matters.conf_make_meta.meta.classify_subject.strip, - links_mono_or_color_set, - lang.codes[doc_matters.src.language]["xlp"], - _footer(doc_matters), ); #+END_SRC diff --git a/org/output_hub.org b/org/output_hub.org index 7aa7fa3..11022cb 100644 --- a/org/output_hub.org +++ b/org/output_hub.org @@ -68,6 +68,24 @@ template outputHub() { <> } } +template outputHubInitialize() { + import doc_reform.io_out, + doc_reform.io_out.metadata, + doc_reform.io_out.paths_output; + @system void outputHubInitialize(O)(O opt_action) { + if ( + opt_action.latex_document_header_sty + || ( + opt_action.latex + && opt_action.output_dir_set.length > 0 + && !(isValidPath(opt_action.output_dir_set ~ "/latex/sty"))) + ) { // .sty need to be produced only once (if unchanged per output-dir of which there usually will be one) + import doc_reform.io_out.latex; + outputLaTeXstyInit!()(opt_action.output_dir_set); + } + writeln(opt_action.latex); + } +} template outputHubOp() { <> @system void outputHubOp(E,O,C)(E env, O opt_action, C config) { @@ -75,7 +93,6 @@ template outputHubOp() { static auto rgx = RgxO(); <> <> - <> } } #+END_SRC @@ -175,11 +192,26 @@ if (sched == outTask.html_stuff) { **** latex / pdf :latex:pdf: +- (unchanged) latex document headers (sty) need to be produced only once for a + given document set output directory path, but they are required + - this makes sure that the latex sty directory is produced with its doc header + .sty contents at least once for a latex output directory, it is not + subsequently modified however + - to initialize or update latex document header (sty) run --latex-init along + with the --latex command while providing the output directory + --output="[output path]" + #+NAME: output_scheduled_task_latex #+BEGIN_SRC d if (sched == outTask.latex) { msg.v("latex processing... (available for downstream processing & pdf output"); import doc_reform.io_out.latex; + import std.file; + if ((isValidPath(doc_matters.output_path ~ "/latex/sty")) + && (!(exists(doc_matters.output_path ~ "/latex/sty"))) + ) { + outputLaTeXstyInit!()(doc_matters.output_path); + } outputLaTeX!()(doc_abstraction, doc_matters); msg.vv("latex done"); } diff --git a/org/spine.org b/org/spine.org index 4423f97..94ab675 100644 --- a/org/spine.org +++ b/org/spine.org @@ -68,6 +68,7 @@ string program_name = "spine"; <> if (_manifests.length > 1 // _manifests[0] initialized dummy element && _opt_action.abstraction) { + <> if (_opt_action.parallelise) { // see else import std.parallelism; foreach(manifest; parallel(_manifests[1..$])) { @@ -359,6 +360,8 @@ bool[string] opts = [ "html-scroll" : false, "latex" : false, "latex-color-links" : false, + "latex-init" : false, + "latex-header-sty" : false, "light" : false, "manifest" : false, "hide-ocn" : false, @@ -369,6 +372,7 @@ bool[string] opts = [ "parallel-subprocesses" : false, "pdf" : false, "pdf-color-links" : false, + "pdf-init" : false, "pod" : false, "serial" : false, "show-config" : false, @@ -472,6 +476,8 @@ auto helpInfo = getopt(args, "lang", "=[lang code e.g. =en or =en,es]", &settings["lang"], "latex", "latex output (for pdfs)", &opts["latex"], "latex-color-links", "mono or color links for pdfs", &opts["latex-color-links"], + "latex-init", "initialise latex shared files (see latex-header-sty)", &opts["latex-init"], + "latex-header-sty", "latex document header sty files", &opts["latex-header-sty"], "light", "default light theme", &opts["light"], "manifest", "process manifest output", &opts["manifest"], "ocn-off", "object cite numbers", &opts["ocn-off"], @@ -482,6 +488,7 @@ auto helpInfo = getopt(args, "parallel-subprocesses", "nested parallelisation", &opts["parallel-subprocesses"], "pdf", "latex output for pdfs", &opts["pdf"], "pdf-color-links", "mono or color links for pdfs", &opts["pdf-color-links"], + "pdf-init", "initialise latex shared files (see latex-header-sty)", &opts["pdf-init"], "pod", "spine (doc reform) pod source content bundled", &opts["pod"], "quiet|q", "output to terminal", &opts["vox_is0"], "section-backmatter", "document backmatter (default)" , &opts["backmatter"], @@ -671,6 +678,9 @@ struct OptActions { @trusted bool latex_color_links() { return (opts["latex-color-links"] || opts["pdf-color-links"]) ? true : false; } + @trusted bool latex_document_header_sty() { + return (opts["latex-init"] || opts["latex-header-sty"] || opts["pdf-init"]) ? true : false; + } @trusted bool odt() { return (opts["odf"] || opts["odt"]) ? true : false; } @@ -1394,6 +1404,14 @@ if (doc_matters.opt.action.debug_do) { **** 2. _process outputs_ :outputs: - [[./output_hub.org][output_hub]] +#+NAME: spine_initialize_output +#+BEGIN_SRC d +/+ ↓ output hub +/ +if (!(_opt_action.skip_output)) { + outputHubInitialize!()(_opt_action); +} +#+END_SRC + #+NAME: spine_each_file_do_selected_output #+BEGIN_SRC d /+ ↓ output hub +/ -- cgit v1.2.3