diff options
Diffstat (limited to 'org')
| -rw-r--r-- | org/default_paths.org | 36 | ||||
| -rw-r--r-- | org/default_regex.org | 18 | ||||
| -rw-r--r-- | org/doc_reform.org | 20 | ||||
| -rw-r--r-- | org/meta_abstraction.org | 9 | ||||
| -rw-r--r-- | org/output_hub.org | 14 | ||||
| -rw-r--r-- | org/output_latex.org | 1832 | 
6 files changed, 1926 insertions, 3 deletions
| diff --git a/org/default_paths.org b/org/default_paths.org index 5e4f958..859415c 100644 --- a/org/default_paths.org +++ b/org/default_paths.org @@ -926,6 +926,7 @@ import doc_reform.meta.rgx;  <<template_paths_html>>  <<template_paths_epub>>  <<template_paths_odf>> +<<template_paths_latex>>  <<template_paths_sqlite>>  #+END_SRC @@ -1297,6 +1298,41 @@ template DocReformPathsODT() {  }  #+END_SRC +** _latex_                                                             :latex: + +#+name: template_paths_latex +#+BEGIN_SRC d +template DocReformPathsLaTeX() { +  mixin DocReformRgxInit; +  static auto rgx = Rgx(); +  auto DocReformPathsLaTeX(M)( +    M  doc_matters, +  ) { +    struct _PathsStruct { +      string base_filename(string fn_src) { +        return fn_src.baseName.stripExtension; +      } +      string base() { +        auto out_pth = DocReformOutPaths!()(doc_matters.output_path, doc_matters.src.language); +        string base_dir = "latex"; +        return asNormalizedPath((out_pth.output_root).chainPath(base_dir)).array; +      } +      string latex_path_stuff() { +        return asNormalizedPath(base.chainPath(base_filename(doc_matters.src.filename))).array; +      } +      string latex_file_with_path() { +        return asNormalizedPath(base.chainPath(base_filename(doc_matters.src.filename) ~ "." ~ doc_matters.src.language ~ ".tex")).array; +      } +      string images() { +        string image_dir = "image"; +        return asNormalizedPath((base).chainPath(image_dir)).array; +      } +    } +    return _PathsStruct(); +  } +} +#+END_SRC +  ** _sqlite_                                                           :sqlite:  *** discrete diff --git a/org/default_regex.org b/org/default_regex.org index e8b6b3f..2958027 100644 --- a/org/default_regex.org +++ b/org/default_regex.org @@ -415,6 +415,24 @@ static xhtml_greater_than                         = ctRegex!(`[>]`, "m");      /  static xhtml_line_break                           = ctRegex!(` [\\]{2}`, "m"); // <br />  #+END_SRC +*** latex special characters + +#+name: sp_ch_xhtml_rgx +#+BEGIN_SRC d +static latex_special_char_shortlist               = ctRegex!(`([%$_#&\\])`); +static latex_special_char_curlybraces             = ctRegex!(`([{}])`); +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_clean_internal_link                  = ctRegex!(`^(?:#|¤\S+?#)`, "m"); +static latex_identify_inline_fontface             = ctRegex!(`\\([_#$]┨.+?┣)\\([_#$])`, "mg"); +static latex_clean_bookindex_linebreak            = ctRegex!(`\s*\\\\\\\\\s*`, "m"); +#+END_SRC +  * 2. ctRegex defaults shared by meta & output (generic)  ** misc generic diff --git a/org/doc_reform.org b/org/doc_reform.org index ac0aa4d..12eb46a 100644 --- a/org/doc_reform.org +++ b/org/doc_reform.org @@ -27,7 +27,7 @@ struct Version {    int minor;    int patch;  } -enum _ver = Version(0, 7, 1); +enum _ver = Version(0, 7, 2);  #+END_SRC  ** compilation restrictions (supported compilers) @@ -314,6 +314,7 @@ bool[string] opts = [    "html"               : false,    "html-seg"           : false,    "html-scroll"        : false, +  "latex"              : false,    "light"              : false,    "manifest"           : false,    "ocn"                : true, @@ -321,6 +322,7 @@ bool[string] opts = [    "odt"                : false,    "parallel"           : false,    "parallel-subprocesses" : false, +  "pdf"                : false,    "quiet"              : false,    "pod"                : false,    "serial"             : false, @@ -367,6 +369,7 @@ auto helpInfo = getopt(args,    "html",               "--html process html output",                                               &opts["html"],    "html-seg",           "--html-seg process html output",                                           &opts["html-seg"],    "html-scroll",        "--html-seg process html output",                                           &opts["html-scroll"], +  "latex",              "--latex output for pdfs",                                                  &opts["latex"],    "light",              "--light default light theme",                                              &opts["light"],    "manifest",           "--manifest process manifest output",                                       &opts["manifest"],    "ocn",                "--ocn object cite numbers (default)",                                      &opts["ocn"], @@ -375,6 +378,7 @@ auto helpInfo = getopt(args,    "parallel",           "--parallel parallelisation",                                               &opts["parallel"],    "parallel-subprocesses", "--parallel-subprocesses nested parallelisation",                        &opts["parallel-subprocesses"],    "quiet|q",            "--quiet output to terminal",                                               &opts["quiet"], +  "pdf",                "--pdf latex output for pdfs",                                              &opts["pdf"],    "pod",                "--pod doc reform pod source content bundled",                              &opts["pod"],    "serial",             "--serial serial processing",                                               &opts["serial"],    "source",             "--source markup source text content",                                      &opts["source"], @@ -417,7 +421,7 @@ if (helpInfo.helpWanted) {  #+NAME: doc_reform_args  #+BEGIN_SRC d -enum outTask { pod, source, sqlite, sqlite_multi, odt, epub, html_scroll, html_seg, html_stuff } +enum outTask { pod, source, sqlite, sqlite_multi, latex, odt, epub, html_scroll, html_seg, html_stuff }  struct OptActions {    bool assertions() {      return opts["assertions"]; @@ -469,6 +473,12 @@ struct OptActions {        { _is = true; } else { _is = false; }      return _is;    } +  bool latex() { +    bool _is; +    if ( opts["latex"] || opts["pdf"]) +      { _is = true; } else { _is = false; } +    return _is; +  }    bool odt() {      bool _is;      if ( opts["odf"] || opts["odt"]) @@ -591,6 +601,7 @@ struct OptActions {        || html        || epub        || odt +      || latex        || manifest        || pod        || source @@ -629,6 +640,9 @@ struct OptActions {      if (odt) {        schedule ~= outTask.odt;      } +    if (latex) { +      schedule ~= outTask.latex; +    }      return schedule.sort().uniq;    }    bool abstraction() { @@ -640,6 +654,7 @@ struct OptActions {        || html        || epub        || odt +      || latex        || manifest        || sqlite_discrete        || sqlite_delete @@ -653,6 +668,7 @@ struct OptActions {        || html        || epub        || odt +      || latex        || sqlite_discrete        || sqlite_update      ) { _is = true; } else { _is = false; } diff --git a/org/meta_abstraction.org b/org/meta_abstraction.org index 4192d3b..317be72 100644 --- a/org/meta_abstraction.org +++ b/org/meta_abstraction.org @@ -2916,30 +2916,36 @@ string[][string] document_section_keys_sequenced = [    "scroll": ["head", "toc", "body",],    "seg":    ["head", "toc", "body",],    "sql":    ["head", "body",], +  "latex":  ["head", "toc", "body",]  ];  if (document_the["endnotes"].length > 1) {    document_section_keys_sequenced["scroll"] ~= "endnotes";    document_section_keys_sequenced["seg"]    ~= "endnotes"; +  document_section_keys_sequenced["latex"]  ~= "endnotes";  }  if (document_the["glossary"].length > 1) {    document_section_keys_sequenced["scroll"] ~= "glossary";    document_section_keys_sequenced["seg"]    ~= "glossary";    document_section_keys_sequenced["sql"]    ~= "glossary"; +  document_section_keys_sequenced["latex"]  ~= "glossary";  }  if (document_the["bibliography"].length > 1) {    document_section_keys_sequenced["scroll"] ~= "bibliography";    document_section_keys_sequenced["seg"]    ~= "bibliography";    document_section_keys_sequenced["sql"]    ~= "bibliography"; +  document_section_keys_sequenced["latex"]  ~= "bibliography";  }  if (document_the["bookindex"].length > 1) {    document_section_keys_sequenced["scroll"] ~= "bookindex";    document_section_keys_sequenced["seg"]    ~= "bookindex";    document_section_keys_sequenced["sql"]    ~= "bookindex"; +  document_section_keys_sequenced["latex"]  ~= "bookindex";  }  if (document_the["blurb"].length > 1) {    document_section_keys_sequenced["scroll"] ~= "blurb";    document_section_keys_sequenced["seg"]    ~= "blurb";    document_section_keys_sequenced["sql"]    ~= "blurb"; +  document_section_keys_sequenced["latex"]  ~= "blurb";  }  if ((opt_action.html)  || (opt_action.html_scroll) @@ -7540,6 +7546,9 @@ template docSectKeysSeq() {        string[] sql() {          return document_section_keys_sequenced["sql"];        } +      string[] latex() { +        return document_section_keys_sequenced["latex"]; +      }      }      return doc_sect_keys_seq();    } diff --git a/org/output_hub.org b/org/output_hub.org index bd56940..d974516 100644 --- a/org/output_hub.org +++ b/org/output_hub.org @@ -33,7 +33,7 @@ template outputHub() {      mixin Msg;      auto msg = Msg!()(doc_matters);      static auto rgx = Rgx(); -    enum outTask { pod, source, sqlite, sqlite_multi, odt, epub, html_scroll, html_seg, html_stuff } +    enum outTask { pod, source, sqlite, sqlite_multi, latex, odt, epub, html_scroll, html_seg, html_stuff }      void Scheduled(D,I)(int sched, D doc_abstraction, I doc_matters) {        auto msg = Msg!()(doc_matters);        <<output_scheduled_task>> @@ -138,6 +138,18 @@ if (sched == outTask.html_stuff) {  }  #+END_SRC +**** latex / pdf                                               :latex:pdf: + +#+name: output_scheduled_task +#+BEGIN_SRC d +if (sched == outTask.latex) { +  msg.v("latex processing... (available for downstream processing & pdf output"); +  import doc_reform.output.latex; +  outputLaTeX!()(doc_abstraction, doc_matters); +  msg.vv("latex done"); +} +#+END_SRC +  **** odf / odt                                                   :odf:odt:  #+name: output_scheduled_task diff --git a/org/output_latex.org b/org/output_latex.org new file mode 100644 index 0000000..be0e653 --- /dev/null +++ b/org/output_latex.org @@ -0,0 +1,1832 @@ +#+TITLE:       doc_reform output latex +#+DESCRIPTION: documents - structuring, publishing in multiple formats & search +#+FILETAGS:    :doc_reform:output:latex:pdf: +#+AUTHOR:      Ralph Amissah +#+EMAIL:       [[mailto:ralph.amissah@gmail.com][ralph.amissah@gmail.com]] +#+COPYRIGHT:   Copyright (C) 2015 - 2019 Ralph Amissah +#+LANGUAGE:    en +#+STARTUP:     indent content hideblocks hidestars +#+OPTIONS:     H:3 num:nil toc:t \n:nil @:t ::t |:t ^:nil _:nil -:t f:t *:t <:t +#+OPTIONS:     TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc +#+OPTIONS:     author:nil email:nil creator:nil timestamp:nil +#+PROPERTY:    header-args :results silent :padline no :exports code :cache no :noweb yes +#+EXPORT_SELECT_TAGS:  export + +- [[./doc_reform.org][doc_reform]]  [[./][org/]] +- [[./output_hub.org][output_hub]] + +* latex +** module template                                        :latex:pdf:module: + +#+BEGIN_SRC d :tangle "../src/doc_reform/output/latex.d" :noweb yes +module doc_reform.output.latex; +template outputLaTeX() { +  <<output_latex_imports>> +  mixin InternalMarkup; // watch +  mixin DocReformOutputRgxInit; +  auto rgx = Rgx(); +  <<output_latex_shared>> +<<output_latex_shared_0>> +  <<output_latex_head>> +  <<output_latex_head_1>> +<<output_latex_head_1_tex>> +  <<output_latex_head_1_close>> +  <<output_latex_head_0>> +<<output_latex_head_0_tex>> +  <<output_latex_head_0_close>> +  <<output_latex_head_close>> +  <<output_latex_body>> +  <<output_latex_tail>> +<<output_latex_tail_tex>> +  <<output_latex_tail_close>> +  <<output_latex>> +} +#+END_SRC + +** write latex output                                            :latex:out: + +#+name: output_latex +#+BEGIN_SRC d +void writeOutputLaTeX(T,M)( +  const T    latex_content, +        M    doc_matters, +) { +  auto pth_latex = DocReformPathsLaTeX(doc_matters); +  try { +    { /+ debug +/ +      if (doc_matters.opt.action.debug_do +      && doc_matters.opt.action.verbose) { +        writeln(latex_content.head); +        writeln(latex_content.content); +        writeln(latex_content.tail); +      } +    } +    if (!exists(pth_latex.latex_path_stuff)) { +      (pth_latex.latex_path_stuff).mkdirRecurse; +    } +    writeln(pth_latex.latex_file_with_path); +    auto f = File(pth_latex.latex_file_with_path, "w"); +    f.writeln(latex_content.head); +    f.writeln(latex_content.content); +    f.writeln(latex_content.tail); +    foreach (image; doc_matters.srcs.image_list) { +      auto fn_src_in = doc_matters.src.image_dir_path ~ "/" ~ image; +      auto fn_src_out_file = pth_latex.latex_path_stuff ~ "/" ~ image; +      if (exists(fn_src_in)) { +        fn_src_in.copy(fn_src_out_file); +      } +    } +  } catch (ErrnoException ex) { +    // handle error +  } +} +#+END_SRC + +** latex output hub [#A]                                     :latex:pdf:out: + +#+name: output_latex +#+BEGIN_SRC d +void outputLaTeX(D,M)( +  const    D   doc_abstraction, +           M   doc_matters, +) { +  struct LaTeX { +    string head; +    string content; +    string tail; +  } +  auto latex           = LaTeX(); +  latex.head           = latex_head(doc_matters); +  latex.content        = latex_body(doc_abstraction, doc_matters); +  latex.tail           = latex_tail(doc_matters); +  latex.writeOutputLaTeX(doc_matters); +} +#+END_SRC + +* stuff +** output imports + +#+name: output_latex_imports +#+BEGIN_SRC d +import doc_reform.output; +import +  std.digest.sha, +  std.file, +  std.outbuffer, +  std.uri, +  std.conv : to; +#+END_SRC + +** shared +*** paper dimensions (struct) + +#+name: output_latex_shared +#+BEGIN_SRC d +    auto paper() { +      struct PaperType { +        auto a4() { +          struct A4 { +            auto portrait() { +              struct V { +                uint w      = 160; +                uint h      = 228; +                uint img_px = 450; +              } +              return V(); +            } +            auto landscape() { +              struct H { +                uint w      = 238; +                uint h      = 160; +                uint img_px = 300; +              } +              return H(); +            } +          } +          return A4(); +        } +        auto a5() { +          struct A5 { +            auto portrait() { +              struct V { +                uint w      = 112; +                uint h      = 162; +                uint img_px = 280; +              } +              return V(); +            } +            auto landscape() { +              struct H { +                uint w      = 152; +                uint h      = 100; +                uint img_px = 190; +              } +              return H(); +            } +          } +          return A5(); +        } +        auto b4() { +          struct B4 { +            auto portrait() { +              struct V { +                uint w      = 140; +                uint h      = 204; +                uint img_px = 356; +              } +              return V(); +            } +            auto landscape() { +              struct H { +                uint w      = 200; +                uint h      = 130; +                uint img_px = 260; +              } +              return H(); +            } +          } +          return B4(); +        } +        auto letter() { +          struct Letter { +            auto portrait() { +              struct V { +                uint w      = 166; +                uint h      = 212; +                uint img_px = 468; +              } +              return V(); +            } +            auto landscape() { +              struct H { +                uint w      = 226; +                uint h      = 166; +                uint img_px = 290; +              } +              return H(); +            } +          } +          return Letter(); +        } +        auto legal() { +          struct Legal { +            auto portrait() { +              struct V { +                uint w      = 168; +                uint h      = 286; +                uint img_px = 474; +              } +              return V(); +            } +            auto landscape() { +              struct H { +                uint w      = 296; +                uint h      = 166; +                uint img_px = 420; +              } +              return H(); +            } +          } +          return Legal(); +        } +      } +      return PaperType(); +    } +#+END_SRC + +*** latex \escape special characters +**** general + +#+name: output_latex_shared +#+BEGIN_SRC d +string sp_char_esc(O)( +  string      _txt, +  const    O  obj, +) { +  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; +  } +  if (obj.metainfo.is_a != "code") { +    _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 => _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: output_latex_shared +#+BEGIN_SRC d +string sp_char_esc_txt()( +  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 => _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 + +*** not used latex \escape special characters + +#+BEGIN_SRC d +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: output_latex_shared +#+BEGIN_SRC d +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"┃$$^{\textrm{%s}}$$┃",               "$1")) +  .replaceAll(rgx.inline_subscript,   format(q"┃$$_{\textrm{%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 + +#+name: output_latex_shared +#+BEGIN_SRC d +string leading_hardspaces()( +  string      _txt, +) { +  string hardspaces(string _spaces) { +    _spaces  = _spaces +      .replaceAll(rgx.space, "\\hardspace "); +    return _spaces; +  } +  _txt = replaceAll!(m => hardspaces(m[0]))(_txt, rgx.spaces_line_start); +  return _txt; +} +#+END_SRC + +***** nbsp character + +#+name: output_latex_shared +#+BEGIN_SRC d +string nbsp_char()(string _txt) { +  if (_txt.match(rgx.nbsp_char)) { +    _txt  = _txt.replaceAll(rgx.nbsp_char, "\\hardspace "); +  } +  return _txt; +} +#+END_SRC + +***** remove nbsp character + +#+name: output_latex_shared +#+BEGIN_SRC d +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: output_latex_shared +#+BEGIN_SRC d +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; +    } +    string _latex_image_path(string _image_path) { +      auto pth_latex = DocReformPathsLaTeX(doc_matters); +      _image_path = pth_latex.latex_path_stuff ~ "/" ~ _image_path; +      return _image_path; +    } +    string _if_images(string _linked_content) { +      if (_linked_content.match(rgx.inline_image_info)) { +        _linked_content = replaceAll!(m => +            format(q"┃\includegraphics*[width=%spt]{%s}%s┃", +              _width_adjust(m[2]), _latex_image_path(m[1]), " \\\\\n") +          )(_linked_content, rgx.inline_image_info); +      } +      return _linked_content; +    } +    string _check_link(string _link) { +      _link = _link +        .replaceFirst(rgx.latex_clean_internal_link, "") +        .replaceAll(rgx.latex_special_char_for_escape_url, "\\$1"); +      return _link; +    } +    if  (obj.metainfo.is_a != "code") { +      _txt = replaceAll!(m => +          m[1] ~ "┤" ~ to!string((obj.stow.link[m[2].to!ulong])).encode ~ "├" +        )(_txt, rgx.inline_link_number_only); +      _txt = replaceAll!(m => +          ((m[1] == m[2]) && (m[2].match(rgx.uri))) +          ? format(q"┃\begin{scriptsize}\lefthalfcap\url{%s}\righthalfcup\end{scriptsize}┃", _check_link(m[1])) +          : (m[2].match(rgx.uri)) // ERROR +            ? format(q"┃%s\href{%s}%s{%s}┃", "\\\\\n", _check_link(m[2]), "\n", _if_images(m[1])) +            : format(q"┃\hyperlink{%s}{%s}┃", _check_link(m[2]), _if_images(m[1])) +        )(_txt, rgx.inline_link); +    } +  } +  return _txt; +} +#+END_SRC + +*** footnotes +**** footnotes + +#+name: output_latex_shared +#+BEGIN_SRC d +string footnotes()( +  string      _txt, +) { +  if (_txt.match(rgx.inline_notes_al_gen)) { +    string _tex_note = q"┃\hypertarget{noteref_%s}{}\footnote[%s]{%% +\label{note_%s}%s}┃"; +    _txt = _txt.replaceAll(rgx.inline_notes_al_regular_number_note, +      format(_tex_note, +        "$1", "$1", "$1", +        "$2".strip +      ).strip +    ); +  } +  return _txt; +} +#+END_SRC + +**** footnote remove + +#+name: output_latex_shared +#+BEGIN_SRC d +string remove_footnotes()( +  string      _txt, +) { +  if (_txt.match(rgx.inline_notes_al_gen)) { +    _txt = replaceAll!(m => "")(_txt, rgx.inline_notes_al_gen); +  } +  return _txt; +} +#+END_SRC + +*** para +**** para + +#+name: output_latex_shared +#+BEGIN_SRC d +string para(O)( +  string      _txt, +  O           obj, +) { +  if (obj.metainfo.is_of_type == "para") { +    string _tex_para; +    _tex_para = q"┃\begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{%s}{%s}\end{tiny}}}%s┃"; +    _txt  = format(_tex_para, +      obj.metainfo.object_number, +      obj.metainfo.object_number, +      _txt.footnotes +    ).strip; +  } +  return _txt; +} +#+END_SRC + +**** bookindex para + +#+name: output_latex_shared +#+BEGIN_SRC d +string bookindex(O)( +  string      _txt, +  O           obj, +) { +  if (obj.metainfo.is_of_type == "para" +    && obj.metainfo.is_a == "bookindex" +  ) { +    string _tex_para; +    _tex_para = q"┃%s┃"; +    _txt  = format(_tex_para, +      _txt.replaceAll(rgx.latex_clean_bookindex_linebreak, "\n") ~ "\n\\\\\n" +    ); +  } +  return _txt; +} +#+END_SRC + +*** bullets & indentation + +#+name: output_latex_head +#+BEGIN_SRC d +string bullets_and_indentation(O)( +  string      _txt, +  O           obj, +) { +  string _tex_para; +  string _hang; string _indent; +  int _paper_margin = -10; +  int _indent_increment = 8; // 5; 10; +  if (obj.attrib.bullet) { +    int _bullet_space = 5; +    _indent = ((obj.attrib.indent_base * _indent_increment) + _paper_margin + _bullet_space).to!string; +    _txt  = format(q"┃\begin{Bullet}{%smm}$\txtbullet$\hspace{\enspace}%s\end{Bullet}┃", +      _indent, +      _txt.footnotes +    ).strip; +  } else if ( +    obj.attrib.indent_base != 0 +    && obj.attrib.indent_base == obj.attrib.indent_hang +  ) { +    _indent = ((obj.attrib.indent_base * _indent_increment) + _paper_margin).to!string; +    _tex_para = q"┃\begin{ParagraphIndent}{%smm}%s \end{ParagraphIndent}┃"; +    _txt = format(_tex_para, +      _indent, +      _txt.footnotes +    ).strip; +  } else if ( +    obj.attrib.indent_base != 0 +    || obj.attrib.indent_hang != 0 +  ) { +    _indent = ((obj.attrib.indent_base * _indent_increment) + _paper_margin).to!string; +    _hang = (((obj.attrib.indent_hang - obj.attrib.indent_base) * _indent_increment)).to!string; +    _txt = format(q"┃\begin{ParagraphHang}{%smm}{%smm}%s \end{ParagraphHang}┃", +      _indent, _hang, +      _txt.footnotes +    ).strip; +  } +  return _txt; +} +#+END_SRC + +*** heading + +#+name: output_latex_shared_0 +#+BEGIN_SRC d +  string heading(O,M)( +    string      _txt, +    O           obj, +    M           doc_matters, +    string      _part = "" +  ) { +    if (obj.metainfo.is_a == "heading") { +      string _tex_para; +      string _pg_break; +      string _sect; +      string _post; +      string _title_add; +      string _columns = ""; +      switch (obj.metainfo.heading_lev_markup) { +      case 0: // A == TITLE +        _pg_break = "\\begin{document}\n"; +        goto default; +      case 1: // B == part: section heading level +        _pg_break = "\\clearpage\n"; +        goto default; +      case 2: // C == part: section heading level +        _pg_break = "\\clearpage\n"; +        goto default; +      case 3: // D == part: section heading level +        _pg_break = "\\clearpage\n"; +        goto default; +      case 4: // 1 == section +        _columns = (_part != "bookindex") +          ? "" : "\n\\\\\n\\begin{multicols}{2}"; +        _pg_break = "\\clearpage\n"; +        _sect = "section"; +        _post = ""; +        _title_add = format(q"┃ +\markboth{%s}{%s}┃", +          doc_matters.conf_make_meta.meta.title_full, +          doc_matters.conf_make_meta.meta.title_full, +        ); +        goto default; +      case 5: // 2 == subsection +        _pg_break = ""; +        // _pg_break = "newpage"; // doubt this is necessary +        _sect = "subsection"; +        _post = " \\\n"; +        _title_add = ""; +        goto default; +      case 6: // 3 == subsubsection +        _pg_break = ""; +        // _pg_break = "newpage"; // doubt this is necessary +        _sect = "subsubsection"; +        _post = " \\\n"; +        _title_add = ""; +        goto default; +      default: +        if (obj.metainfo.heading_lev_markup == 0) { +          _tex_para = q"┃\begin{document} +\title{%s} +\author{ \textnormal{%s}} +\date{\begin{tiny}%s\end{tiny}} +\pagenumbering{roman}\maketitle +\pagestyle{fancy} +\newpage +\markboth{%s}{%s} +\\\\[3]\ \linebreak Copyright {\begin{small}{\copyright\end{small}} %s \\ +%s +\pagestyle{fancy} +\clearpage┃"; +          _txt = format(_tex_para, +            (doc_matters.conf_make_meta.meta.title_full).sp_char_esc_txt, +            (doc_matters.conf_make_meta.meta.creator_author).sp_char_esc_txt, +            (doc_matters.conf_make_meta.meta.date_published).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, +          ); +        } else if (obj.metainfo.heading_lev_markup < 4) { +          _tex_para = q"┃%s\part*{\begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{%s}{%s}\end{tiny}}}%s} +\addcontentsline{toc}{part}{%s} +\markboth{%s}┃"; +          _txt = format(_tex_para, +            _pg_break, +            obj.metainfo.object_number, +            obj.metainfo.object_number, +            _txt.strip.footnotes, +            _txt.strip.remove_footnotes, +            (doc_matters.conf_make_meta.meta.title_main).sp_char_esc_txt, +          ); +        } else if (obj.metainfo.heading_lev_markup > 3) { +          if (obj.metainfo.heading_lev_markup == 4 +          && _txt.match(regex(r"^Table of Contents$"))) { +            _tex_para = q"┃ +\pagenumbering{none} +\setcounter{page}{1} +\setlength{\parskip}{1ex plus0.5ex minus0.2ex} +\part*{\begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{1}{1}\end{tiny}}}%s \newline %s} + +\clearpage +\markboth{%s}{%s} +\pagenumbering{gobble} +\renewcommand{\contentsname}{} +\tableofcontents +\markboth{%s}{%s} + +\clearpage +\pagenumbering{arabic} +\setcounter{page}{1} +\markboth{%s}{%s} +%% \null +\clearpage +\setcounter{page}{1}┃"; +            _txt = format(_tex_para, +              (doc_matters.conf_make_meta.meta.title_full).sp_char_esc_txt, +              (doc_matters.conf_make_meta.meta.creator_author).sp_char_esc_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.title_full).sp_char_esc_txt, +              (doc_matters.conf_make_meta.meta.title_full).sp_char_esc_txt, +              (doc_matters.conf_make_meta.meta.title_full).sp_char_esc_txt, +            ); +          } else if (obj.metainfo.heading_lev_markup == 4 +            && _part == "bookindex" +            && _txt.match(regex(r"^Index$")) +          ) { +            _tex_para = q"┃%s\%s*{\begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{%s}{%s}\end{tiny}}}%s} +\addcontentsline{toc}{%s}{%s%s}%s%s┃"; +            _txt = format(_tex_para, +              _pg_break, +              _sect.strip, +              obj.metainfo.object_number, +              obj.metainfo.object_number, +              _txt.footnotes.strip, +              _sect, +              _txt.remove_footnotes.strip, +              _post, +              _title_add, +              _columns, +            ); +          } else if (obj.metainfo.dummy_heading +            && obj.metainfo.heading_lev_markup == 4 +          ) { /+ dummy headings completely omitted +/ +            _txt = ""; +          } else { +            _tex_para = q"┃%s\%s*{\begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{%s}{%s}\end{tiny}}}%s} +\addcontentsline{toc}{%s}{%s%s}%s┃"; +            _txt = format(_tex_para, +              _pg_break, +              _sect.strip, +              obj.metainfo.object_number, +              obj.metainfo.object_number, +              _txt.footnotes.strip, +              _sect, +              _txt.remove_footnotes.strip, +              _post, +              _title_add, +            ); +          } +        } +        break; +      } +    } +    return _txt.strip; +  } +#+END_SRC + +*** grouped text +**** group + +- (hardspace not honored) clear hardspace marker + +#+name: output_latex_shared_0 +#+BEGIN_SRC d +string group(O,M)( +  string      _txt, +  O           obj, +  M           doc_matters, +) { +  if (obj.metainfo.is_a == "group") { +    string _tex_para; +    _tex_para = q"┃\begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{%s}{%s}\end{tiny}}}\setlength{\parskip}{0.5ex plus0.2ex minus0.1ex} +\begin{footnotesize} +%s +\end{footnotesize} +┃"; +    _txt  = format(_tex_para, +      obj.metainfo.object_number, +      obj.metainfo.object_number, +      _txt.footnotes.strip +    ).strip; +  } +  return _txt; +} +#+END_SRC + +**** block + +- (hardspace honored) \hardspace + +#+name: output_latex_shared_0 +#+BEGIN_SRC d +string block(O,M)( +  string      _txt, +  O           obj, +  M           doc_matters, +) { +  if (obj.metainfo.is_a == "block") { +    // _txt = _txt.nbsp_char; +    string _tex_para; +    _tex_para = q"┃\begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{%s}{%s}\end{tiny}}}\setlength{\parskip}{0.5ex plus0.2ex minus0.1ex} +\begin{footnotesize} +%s +\end{footnotesize} +\setlength{\parskip}{1ex plus0.5ex minus0.2ex} +┃"; // \hardspace +    /+ try both: +/ +    _txt = _txt.split(rgx.br_newlines_linebreaks).join("\n\n"); // _txt = _txt.split(rgx.br_newlines_linebreaks).join(" \\\n"); +    _txt  = format(_tex_para, +      obj.metainfo.object_number, +      obj.metainfo.object_number, +      _txt.nbsp_char.footnotes.strip +    ).strip; +  } +  return _txt; +} +#+END_SRC + +**** verse + +- (hardspace honored) \hardspace + +#+name: output_latex_shared_0 +#+BEGIN_SRC d +string verse(O,M)( +  string      _txt, +  O           obj, +  M           doc_matters, +) { +  if (obj.metainfo.is_a == "verse") { +    string _tex_para; +    _tex_para = q"┃\begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{%s}{%s}\end{tiny}}}\setlength{\parskip}{0.1ex plus0.1ex minus0.1ex} +\begin{footnotesize} + +%s + +\end{footnotesize} +\setlength{\parskip}{1ex plus0.5ex minus0.2ex} +\linebreak +┃"; // \hardspace +    _txt  = format(_tex_para, +      obj.metainfo.object_number, +      obj.metainfo.object_number, +      _txt.nbsp_char.footnotes.split("\n").join("\n\n").strip +    ).strip; +  } +  return _txt; +} +#+END_SRC + +**** codeblock + +- (hardspace honored) \begin{lstlisting} clear hardspace marker + +#+name: output_latex_shared_0 +#+BEGIN_SRC d +string codeblock(O,M)( +  string      _txt, +  O           obj, +  M           doc_matters, +) { +  if (obj.metainfo.is_a == "code") { +    string _tex_para; +    _tex_para = q"┃\begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{%s}{%s}\end{tiny}}}\setlength{\parskip}{0.5ex plus0.2ex minus0.1ex}\begin{Codeblock} +\begin{lstlisting} +%s +\end{lstlisting} +\end{Codeblock} +\setlength{\parskip}{1ex plus0.5ex minus0.2ex} +┃"; +    _txt  = format(_tex_para, +      obj.metainfo.object_number, +      obj.metainfo.object_number, +      _txt.nbsp_char_to_space +    ).strip; +  } +  return _txt; +} +#+END_SRC + +**** table + +- own set of rules + +***** tablarize + +#+name: output_latex_shared_0 +#+BEGIN_SRC d +auto 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 ~= ""; +      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 { +          // // _table ~= "\\bfseries "; +          // _table ~= cell; +          // _table ~= (_table_cols.length > (col_idx + 1)) ? "&" : ""; +          _table ~= format(q"┃%s%s┃", +            cell, +            (_table_cols.length > (col_idx + 1)) ? "&" : "" +          ); +        } +      } +      _table ~= "\\\\"; +    } +  auto t = tuple( +    _table, +    _tablenote, +  ); +  return t; +} +#+END_SRC + +***** table + +#+name: output_latex_shared_0 +#+BEGIN_SRC d +string table(O,M)( +  string      _txt, +  O           obj, +  M           doc_matters, +) { +  if (obj.metainfo.is_a == "table") { +    auto _t = _txt.tablarize(obj); +    string _table = _t[0]; +    string _t_n = _t[1]; +    string papertype = "a4"; +    uint pw = 0; +    switch (papertype) { +    case "a4":     pw = (paper.a4.portrait.w     - 20); break; +    case "a5":     pw = (paper.a5.portrait.w     - 20); break; +    case "b4":     pw = (paper.b4.portrait.w     - 20); break; +    case "letter": pw = (paper.letter.portrait.w - 20); break; +    case "legal":  pw = (paper.legal.portrait.w  - 20); break; +    default:       pw = 0;                              break; +    } +    // auto textwidth = (pw - 24); +    string _colw = ""; +    foreach (w; obj.table.column_widths) { +      _colw ~= format(q"┃p{%.0fmm}┃", +        (w * pw / 100) +        // (w * (pw - 24)/ 100) +        // (w * textwidth / 100) +      ); +    } +    string _tex_para; +    _tex_para = q"┃\begin{tiny}\hspace{0mm}\end{tiny}{\marginpar{\begin{tiny}\hspace{0mm}\hypertarget{%s}{%s}\end{tiny}}} +\setlength{\LTleft}{0pt} +\setlength{\LTright}{\fill} +\begin{tiny} +\begin{longtable}{%s} +%s +\end{longtable} +\end{tiny} +┃"; +    _txt  = format(_tex_para, +      obj.metainfo.object_number, +      obj.metainfo.object_number, +      _colw, +      _table, +    ).strip; +  } +  return _txt; +} +#+END_SRC + +** latex parts +*** latex head                                                         :head: +**** latex head function + +#+name: output_latex_head +#+BEGIN_SRC d +string latex_head(M)( +                        M    doc_matters, +) { +#+END_SRC + +**** latex head options +***** paper type dimensions +****** struct + +#+name: output_latex_head +#+BEGIN_SRC d +  struct paperType { +    string a4_portrait; +    string a4_landscape; +    string us_letter_portrait; +    string us_letter_landscape; +  } +  auto paper           = paperType(); +#+END_SRC + +****** a4, portrait + +#+name: output_latex_head_1 +#+BEGIN_SRC d +  paper.a4_portrait    = format(q"┃ +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC latex +\documentclass[12pt,a4paper,titlepage]{scrartcl} +\setlength{\textheight}{228mm} \setlength{\textwidth}{160mm} +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +┃", +  ); +#+END_SRC + +****** a4, landscape + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  paper.a4_landscape    = format(q"┃ +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC latex +\documentclass[11pt,a4paper,landscape,titlepage,twocolumn]{scrartcl} +\setlength{\textheight}{160mm} \setlength{\textwidth}{238mm} +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +┃", +  ); +#+END_SRC + +****** us letter, portrait + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  paper.us_letter_portrait    = format(q"┃ +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC latex +\documentclass[12pt,letterpaper,titlepage]{scrartcl} +\setlength{\textheight}{212mm} \setlength{\textwidth}{166mm} +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +┃", +  ); +#+END_SRC + +****** us letter, landscape + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  paper.us_letter_landscape    = format(q"┃ +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC latex +\documentclass[11pt,letterpaper,landscape,titlepage,twocolumn]{scrartcl} +\setlength{\textheight}{166mm} \setlength{\textwidth}{226mm} +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +┃", +  ); +#+END_SRC + +***** paper margins +****** struct + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  struct paperMargins { +    string portrait; +    string landscape; +  } +  auto margins           = paperMargins(); +#+END_SRC + +****** portrait + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  margins.portrait    = format(q"┃ +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC latex +\setlength{\oddsidemargin}{0mm} \setlength{\evensidemargin}{0mm} +\setlength{\topmargin}{-12pt} \setlength{\headheight}{12pt} +\setlength{\headsep}{35pt} +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +┃", +  ); +#+END_SRC + +****** landscape + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  margins.landscape    = format(q"┃ +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC latex +\setlength{\oddsidemargin}{6mm} \setlength{\evensidemargin}{6mm} +\setlength{\topmargin}{-12mm} \setlength{\headheight}{12pt} +\setlength{\headsep}{20pt} +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +┃", +  ); +#+END_SRC + +***** multicol +****** struct + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  struct columnsMulti { +    string portrait; +    string landscape; +  } +  auto multicol           = columnsMulti(); +#+END_SRC + +****** portrait + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  multicol.portrait    = format(q"┃ +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC latex +\usepackage{multicol} +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +┃", +  ); +#+END_SRC + +****** landscape + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  multicol.landscape    = ""; +#+END_SRC + +***** color links +****** struct + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  struct colorLinks { +    string mono; +    string color; +  } +  auto links           = colorLinks(); +#+END_SRC + +****** mono + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  links.mono    = format(q"┃ +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC latex +\usepackage[xetex, +  colorlinks=true, +  urlcolor=myblack, +  filecolor=myblack, +  linkcolor=myblack, +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +┃", +  ); +#+END_SRC + +****** color + +#+name: output_latex_head_1_tex +#+BEGIN_SRC d +  links.color    = format(q"┃ +#+END_SRC + +#+name: output_latex_head_1_tex +#+BEGIN_SRC latex +\usepackage[xetex, +  colorlinks=true, +  urlcolor=myblue,    %% \href{...}{...}   external url +  filecolor=mygreen,  %% \href{...}        local file +  linkcolor=myred,    %% \href{...} and \pageref{...} +#+END_SRC + +#+name: output_latex_head_1_close +#+BEGIN_SRC d +┃", +  ); +#+END_SRC + +**** latex head starts + +#+name: output_latex_head_0 +#+BEGIN_SRC d +  string _latex_head = format(q"┃%%%% DocReform LaTeX output +#+END_SRC + +***** description comment + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +%%%% Generated by: %s +%%%% D version: ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux-gnu] +%%%% LaTeX output +%%%% Last Generated on: +%%%% SiSU http://www.jus.uio.no/sisu +#+END_SRC + +***** paper type (a4, letter, ...; ( portrait | landscape )) + +- paper.a4_portrait +- paper.a4_landscape +- paper.us_letter_portrait +- paper.us_letter_landscape + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +%s +#+END_SRC + +***** paper margins (portrait | landscape) + +- margins.portrait +- margins.landscape + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +%s +#+END_SRC + +***** margin shared + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +\setlength{\marginparsep}{4mm} +\setlength{\marginparwidth}{8mm} +#+END_SRC + +***** multicol (portrait | landscape) + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +%s +#+END_SRC + +***** language & font + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +\usepackage{polyglossia, ucs, fontspec, xltxtra, xunicode} +\setmainlanguage{english} +\setotherlanguage{} +\setmainfont{Liberation Sans} +\setmonofont[Scale=0.85]{Liberation Mono} +#+END_SRC + +%% \setsansfont{Liberation Sans} +%% \setromanfont{Liberation Serif} + +***** latex head + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +\usepackage{alltt} +\usepackage{thumbpdf} +#+END_SRC + +***** color links: no = mono | yes = color + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +%s +#+END_SRC + +***** metadata + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +  pdftitle={%s}, +  pdfauthor={%s}, +  pdfsubject={%s}, +  pdfkeywords={}, +  pageanchor=true, +  plainpages=true, +  pdfpagelabels=true, +  pagebackref, +  bookmarks=true, +  bookmarksopen=true, +  pdfmenubar=true, +  pdfpagemode=UseOutline, +  pdffitwindow=true, +  pdfwindowui=true, +  plainpages=false, +  pdfstartview=FitH +] +{hyperref} +#+END_SRC + +%%  pdfusetitle=true, +%%  pdfpagelayout=SinglePage, +%%  pdfpagelayout=TwoColumnRight, +%%  pdfpagelayout=TwoColumnLeft, +%%  pdfstartpage=3, + +%%%% trace lost characters +%% \tracinglostchars = 1 +%% \tracingonline = 1 + +***** define colors + +#+name: output_latex_head_0_tex +#+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 + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +\usepackage{url} +\urlstyle{sf} +#+END_SRC + +%%\usepackage{breakurl} + +***** latex head + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +\usepackage{textcomp} +\usepackage[parfill]{parskip} +\usepackage[normalem]{ulem} +\usepackage{soul} +\usepackage{longtable} +\usepackage[tc]{titlepic} +\usepackage{graphicx} +\makeatletter +\parindent0pt +\usepackage{amssymb} +\usepackage{listings} +\usepackage{color} +\usepackage{textcomp} +\setcounter{secnumdepth}{2} +\setcounter{tocdepth}{4} +\makeatletter +#+END_SRC + +***** indent, bullet, list + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +\usepackage[multiple,ragged]{footmisc} +\setlength\footnotemargin{12pt} +\usepackage[para]{manyfoot} +\DeclareNewFootnote{A} +\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[] +} +{\end{list}} +#+END_SRC + +%%\DeclareNewFootnote[para]{A} + +***** part, section, subsection, paragraph, subparagraph + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +\usepackage{fancyhdr} +\lhead{} +\renewcommand{\part}{\@startsection +  {part}{1}{-2mm}%% +  {-\baselineskip}{0.5\baselineskip}%% +  {\bfseries\large\upshape\raggedright}} +\renewcommand{\section}{\@startsection +  {section}{2}{-2mm}%% +  {-\baselineskip}{0.5\baselineskip}%% +  {\bfseries\large\upshape\raggedright}} +\renewcommand{\subsection}{\@startsection +  {subsection}{3}{-2mm}%% +  {-\baselineskip}{0.5\baselineskip}%% +  {\bfseries\large\upshape\raggedright}} +\renewcommand{\subsubsection}{\@startsection +  {subsubsection}{4}{-2mm}%% +  {-\baselineskip}{0.5\baselineskip}%% +  {\normalfont\normalsize\bfseries\raggedright}} +\renewcommand{\paragraph}{\@startsection +  {paragraph}{5}{-2mm}%% +  {-\baselineskip}{0.5\baselineskip}%% +  {\normalfont\normalsize\itshape\raggedright}} +\renewcommand{\subparagraph}{\@startsection +  {subparagraph}%%{6}%%{-2mm}%% +  {-\baselineskip}{0.5\baselineskip}%% +  {\normalfont\normalsize\itshape\raggedright}} +#+END_SRC + +%% \makeatother + +***** latex head misc. including defined commands + +#+name: output_latex_head_0_tex +#+BEGIN_SRC latex +\selectlanguage{english} +\lhead[ ]{ } +\chead[ \fancyplain{} \bfseries \footnotesize \leftmark ]{ \fancyplain{} \bfseries \footnotesize \rightmark } +\rhead[ ]{ } +\lfoot[\textrm{\thepage}]{\tiny \href{http://sisudoc.org}{SiSU}} +\cfoot{\href{http://git.sisudoc.org}{git}} +\rfoot[\tiny \href{}{}]{\textrm{\thepage}} +\tolerance=300 +\clubpenalty=300 +\widowpenalty=300 +\makeatother +\makeatother +\chardef\txtbullet="2022 +\chardef\tilde="7E +\def\asterisk{{\rm \char42} } +\definecolor{Light}{gray}{.92} +\newcommand{\Codeblock}[1]{\normaltext\raggedright\small\ttfamily\texbackslash#1} +\newcommand{\monosp}[1]{\normaltext\ttfamily\texbackslash#1} +\newcommand{\parasep}{\\ \begin{center}*\hspace{2em}*\hspace{2em}*\end{center} \\} +\newcommand{\hardspace}{{~}} +\newcommand{\caret}{{\^{~}}} +\newcommand{\pipe}{{\textbar}} +\newcommand{\curlyopen}{{} +\newcommand{\curlyclose}{}} +\newcommand{\lt}{{UseTextSymbol{OML}{<}}} +\newcommand{\gt}{{UseTextSymbol{OML}{>}}} +\newcommand{\slash}{{/}} +\newcommand{\underscore}{\_} +\newcommand{\exclaim}{\Verbatim{!}} +\definecolor{listinggray}{gray}{0.9} +\definecolor{lbcolor}{rgb}{0.9,0.9,0.9} +\lstset{ +  backgroundcolor=\color{lbcolor}, +  tabsize=4, +  rulecolor=, +  language=, +  basicstyle=\scriptsize, +  upquote=true, +  aboveskip={1.5\baselineskip}, +  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}, +} +#+END_SRC + +%%\chardef\asterisk="2A +%%\newcommand{\hardspace}{\hspace{.5em}} + +**** latex head format inclusions + +#+name: output_latex_head_0_close +#+BEGIN_SRC d +┃", +  doc_matters.opt.action.debug_do ? "" : doc_matters.generator_program.name_and_version.strip, +  paper.a4_portrait.strip, +  margins.portrait.strip, +  multicol.portrait.strip, +  links.mono.strip, // links.color.strip, +  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, +); +#+END_SRC + +**** latex head return + +#+name: output_latex_head_close +#+BEGIN_SRC d +  return _latex_head.strip; +} +#+END_SRC + +*** ↻ latex body                                             :content:body: +**** latex body function + +#+name: output_latex_body +#+BEGIN_SRC d +string latex_body(D,M)( +  const    D   doc_abstraction, +           M   doc_matters, +) { +  string _latex_body = ""; +  bool _multicolumns = false; +  string _txt; +#+END_SRC + +**** ↻ loop open + +#+name: output_latex_body +#+BEGIN_SRC d +  foreach (part; doc_matters.has.keys_seq.latex) { +    foreach (obj; doc_abstraction[part]) { +      switch (obj.metainfo.is_of_part) { +#+END_SRC + +**** ↻ within loop +***** frontmatter + +#+name: output_latex_body +#+BEGIN_SRC d +      case "frontmatter":              assert(part == "head" || "toc"); +        _txt = obj.text +          .sp_char_esc(obj) +          .fontface; +        switch (obj.metainfo.is_of_type) { +        case "para": +          switch (obj.metainfo.is_a) { +          case "heading": +            _txt = _txt.heading(obj, doc_matters); +            goto default; +          case "toc": +            break; +          default: +            _latex_body ~= _txt ~ "\n\n"; +            _txt = ""; +            break; +          } +          break; +        default: break; +        } +        break; +#+END_SRC + +***** body + +#+name: output_latex_body +#+BEGIN_SRC d +      case "body":                     assert(part == "body" || "head"); // surprise +        _txt = obj.text +          .sp_char_esc(obj) +          .fontface; +        switch (obj.metainfo.is_of_type) { +        case "para": +          switch (obj.metainfo.is_a) { +          case "heading": +            _txt = _txt.heading(obj, doc_matters); +            goto default; +          case "para": +            _txt = _txt.para(obj) +              .bullets_and_indentation(obj) +              .links_and_images(obj, doc_matters); +            goto default; +          default: +            _latex_body ~= _txt ~ "\n\n"; +            _txt = ""; +            break; +          } +          break; +        case "block": +          switch (obj.metainfo.is_a) { +          case "quote": +            goto default; // TODO +          case "group": +            /+ (hardspaces not honored) [remove any hardspace marker] +/ +            _txt = _txt.group(obj, doc_matters) +              .links_and_images(obj, doc_matters); +            goto default; +          case "block": +            /+ (hardspace honored) \hardspace +/ +            _txt = _txt.block(obj, doc_matters) +              .links_and_images(obj, doc_matters); +            goto default; +          case "verse": +            /+ (hardspace honored) \hardspace +/ +            _txt = _txt.verse(obj, doc_matters) +              .links_and_images(obj, doc_matters); +            goto default; +          case "code": +            /+ (hardspace honored) \begin{lstlisting} clear hardspace marker +/ +            _txt = _txt.codeblock(obj, doc_matters); +            goto default; +          case "table": +            _txt = _txt.table(obj, doc_matters); +            goto default; // TODO +          default: +            _latex_body ~= _txt ~ "\n\n"; +            _txt = ""; +            break; +          } +          break; +        default: break; +        } +        break; +#+END_SRC + +***** backmatter + +#+name: output_latex_body +#+BEGIN_SRC d +      case "backmatter": +        assert(part == "endnotes" || "glossary" || "bibliography" || "bookindex" || "blurb" || "tail"); +        _txt = obj.text +          .sp_char_esc(obj) +          .fontface; +        switch (obj.metainfo.is_of_type) { +        case "para": +          if (part != "bookindex" && _multicolumns) { +            _multicolumns = false; +            _latex_body ~= "\n\\end{multicols}\n"; +          } +          switch (obj.metainfo.is_a) { +          case "heading": +            if (part == "bookindex") { +              _multicolumns = true; +            } +            _txt = _txt.heading(obj, doc_matters, part); +            goto default; +          case "endnote":              assert(part == "endnotes"); +            _txt = _txt.para(obj) +              .bullets_and_indentation(obj) +              .links_and_images(obj, doc_matters); +            goto default; +          case "glossary":             assert(part == "glossary"); +            _txt = _txt.para(obj) +              .bullets_and_indentation(obj) +              .links_and_images(obj, doc_matters); +            goto default; +          case "bibliography":         assert(part == "bibliography"); +            _txt = _txt.para(obj) +              .bullets_and_indentation(obj); +            goto default; +          case "bookindex":            assert(part == "bookindex"); +            /+ two column, special section +/ +            _txt = _txt.bookindex(obj) +              .links_and_images(obj, doc_matters); +            goto default; +          case "blurb":                assert(part == "blurb"); +            _txt = _txt.para(obj) +              .bullets_and_indentation(obj) +              .links_and_images(obj, doc_matters); +            goto default; +          default: +            _latex_body ~= (part == "bookindex" && obj.metainfo.is_a != "heading") +              ? _txt : (_txt ~ "\n\n"); +            _txt = ""; +            break; +          } +          break; +        default: break; +        } +        break; +#+END_SRC + +***** after + +#+name: output_latex_body +#+BEGIN_SRC d +      case "comment": +        break; +      default: +        { /+ debug +/ +          if (doc_matters.opt.action.debug_do +          && doc_matters.opt.action.verbose) { +            writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_of_part); +            writeln(__FILE__, ":", __LINE__, ": ", obj.metainfo.is_a); +            writeln(__FILE__, ":", __LINE__, ": ", obj.text); +          } +        } +        break; +      } +    } +  } +  if (_multicolumns) { +    _multicolumns = false; +    _latex_body ~= "\n\\end{multicols}\n"; +  } +#+END_SRC + +**** latex body return + +#+name: output_latex_body +#+BEGIN_SRC d +  return _latex_body; +} +#+END_SRC + +*** latex tail                                                       :tail: +**** latex tail function + +#+name: output_latex_tail +#+BEGIN_SRC d +string latex_tail(M)( +                        M    doc_matters, +) { +#+END_SRC + +**** latex tail starts + +#+name: output_latex_tail +#+BEGIN_SRC d +  string _latex_tail = format(q"┃ +#+END_SRC + +***** latex tail format inclusions + + +***** latex document end + +#+name: output_latex_tail_tex +#+BEGIN_SRC latex + +\end{document} +#+END_SRC + +**** latex tail format inclusions + +#+name: output_latex_tail_close +#+BEGIN_SRC d +┃", +  // doc_matters.conf_make_meta.meta.title_full, +  // doc_matters.conf_make_meta.meta.creator_author, +); +#+END_SRC + +**** latex tail return + +#+name: output_latex_tail_close +#+BEGIN_SRC d +  return _latex_tail; +} +#+END_SRC + +* latex system command helper script +** latex command, ruby script + +#+BEGIN_SRC ruby :tangle "../util/dr_tex.rb"  :tangle-mode (identity #o755) :shebang #!/usr/bin/env ruby +require 'fileutils' +pwd = Dir.pwd +argv,texfiles_with_path,flags=[],[],[] +lngs = %{(am|bg|bn|br|ca|cs|cy|da|de|el|en|eo|es|et|eu|fi|fr|ga|gl|he|hi|hr|hy|ia|is|it|ja|ko|la|lo|lt|lv|ml|mr|nl|no|nn|oc|pl|pt|pt_BR|ro|ru|sa|se|sk|sl|sq|sr|sv|ta|te|th|tk|tr|uk|ur|vi|zh)} +Regexp.new(lngs, Regexp::IGNORECASE) +argv=$* +argv.sort.each{|y| (y =~/^--\S+$/i) ? (flags << y) : (texfiles_with_path << y) } +if flags.length==0 \ +|| flags.inspect =~/"--help"/ +  cmd=(/([^\/]+)$/).match($0)[1] +  puts <<WOK +#{cmd} --help +#{cmd} --out=[output path] +#{cmd} --paper-size=a5 --out=~/test +WOK +end +paper_size = (flags.inspect.match(/"--paper-size=(a4|a5|b5|letter|legal)"/)) ? $1 : "a4" +out_path = Dir.pwd +if (flags.inspect.match(/"--out=\S+"/)) +  out_path = flags.inspect.match(/"--out=(\S+)"/)[1] +  unless (FileTest.directory?(out_path)) +    puts "Creating output directory: --out=#{out_path}" +    FileUtils::mkdir_p(out_path) +    unless (FileTest.directory?(out_path)) +      puts "FAILS unable to create directory: #{out_path}" +      exit +    end +  end +end +if texfiles_with_path.length == 0 +  texfiles_with_path=Dir.glob('*.tex') +end +if texfiles_with_path.length > 0 +  texfiles_with_path.each do |texfile_with_path| +    if texfile_with_path =~/.+\.tex/ +      #puts texfile_with_path +      if FileTest.file?(texfile_with_path) +        file_basename_with_path = texfile_with_path.sub(/\.tex$/,'') +        file_basename = file_basename_with_path.sub(/.*?([^\/]+)$/,'\1') +        _out_path = out_path +        if file_basename =~ /\.#{lngs}$/ +          lng = file_basename.match(/\.#{lngs}$/)[1] +          puts file_basename +          puts lng +          puts _out_path +          unless _out_path.match(/\/#{lng}\/pdf$/) +            _out_path = "#{out_path}/#{lng}/pdf" +            FileUtils::mkdir_p(_out_path) +          end +        end +        texpdf_cmd = %{xetex -interaction=batchmode -fmt=xelatex -papersize=#{paper_size} #{texfile_with_path}\n} +        puts texpdf_cmd +        2.times { |i| system(texpdf_cmd) } +        if (FileTest.file?(%{#{pwd}/#{file_basename}.pdf})) && (FileTest.directory?(_out_path)) +          FileUtils::Verbose::mv(%{#{pwd}/#{file_basename}.pdf}, %{#{_out_path}/#{file_basename}.pdf}) +          puts (%{#{_out_path}/#{file_basename}.pdf}) +        else +          puts "issue with pdf file or output directory" +          puts "pdf file:   #{pwd}/#{file_basename}.pdf}" +          puts "output dir: #{_out_path}/" +        end +        suffix = ['log', 'out', 'toc', 'aux'] +        suffix.each { |s| FileUtils::rm_f(%{#{pwd}/#{file_basename}.#{s}})} +      end +    end +  end +end +Dir.chdir(pwd) +__END__ +#+END_SRC | 
