From 2dd7d2083c23fe9e79a984c534c2283fc4d7e581 Mon Sep 17 00:00:00 2001
From: Ralph Amissah <ralph.amissah@gmail.com>
Date: Thu, 20 Jun 2019 13:45:58 -0400
Subject: harvest reorganized

---
 src/doc_reform/doc_reform.d                    | 678 +------------------------
 src/doc_reform/meta/defaults.d                 |  28 +
 src/doc_reform/meta/metadoc.d                  |   4 +-
 src/doc_reform/meta/metadoc_harvest.d          |  30 +-
 src/doc_reform/meta/metadoc_harvests_authors.d | 255 ++++++++++
 src/doc_reform/meta/metadoc_harvests_topics.d  | 408 +++++++++++++++
 src/doc_reform/output/paths_output.d           |   5 +-
 src/doc_reform/source/paths_source.d           |   7 -
 8 files changed, 735 insertions(+), 680 deletions(-)
 create mode 100644 src/doc_reform/meta/metadoc_harvests_authors.d
 create mode 100644 src/doc_reform/meta/metadoc_harvests_topics.d

(limited to 'src/doc_reform')

diff --git a/src/doc_reform/doc_reform.d b/src/doc_reform/doc_reform.d
index 550ee28..d48851b 100755
--- a/src/doc_reform/doc_reform.d
+++ b/src/doc_reform/doc_reform.d
@@ -62,6 +62,8 @@ import
   std.process;
 import
   doc_reform.meta,
+  doc_reform.meta.metadoc_harvests_authors,
+  doc_reform.meta.metadoc_harvests_topics,
   doc_reform.meta.metadoc_summary,
   doc_reform.meta.metadoc_harvest,
   doc_reform.meta.metadoc_from_src,
@@ -91,26 +93,7 @@ void main(string[] args) {
   mixin DocReformBiblio;
   mixin DocReformRgxInitFlags;
   mixin outputHub;
-  struct Harvest {
-    string   title                = "";
-    string[] author_arr          = [];
-    string   author               = "";
-    string   author_surname       = "";
-    string   author_surname_fn    = "";
-    string   language             = "";
-    string   language_original    = "";
-    string   uid                  = "";
-    string   date_published       = "";
-    string[] topic_register_arr   = [];
-    string   path_html_seg        = "";
-    string   path_html_scroll     = "";
-    string   path_epub            = "";
-    string   url_html_seg         = "";
-    string   url_html_scroll      = "";
-    string   url_epub             = "";
-  }
-  Harvest harvested;
-  Harvest[] harvests;
+  auto hvst = DocReformHarvest!();
   string flag_action;
   string arg_unrecognized;
   enum dAM { abstraction, matters }
@@ -282,15 +265,24 @@ void main(string[] args) {
         || opts["harvest-authors"]
         || opts["harvest-topics"]
       )
-      ? true
-      : false;
+      ? true : false;
       return _is;
     }
     bool harvest_authors() {
-      return opts["harvest-authors"];
+      bool _is = (
+        opts["harvest"]
+        || opts["harvest-authors"]
+      )
+      ? true : false;
+      return _is;
     }
     bool harvest_topics() {
-      return opts["harvest-topics"];
+      bool _is = (
+        opts["harvest"]
+        || opts["harvest-topics"]
+      )
+      ? true : false;
+      return _is;
     }
     bool html() {
       bool _is;
@@ -441,6 +433,7 @@ void main(string[] args) {
         _is = false;
       } else if (opts["abstraction"]
         || concordance
+        || harvest
         || html
         || epub
         || odt
@@ -494,6 +487,7 @@ void main(string[] args) {
         || concordance
         || source
         || pod
+        || harvest
         || html
         || epub
         || odt
@@ -682,19 +676,7 @@ void main(string[] args) {
             DocReformMetaDocSummary!()(doc_abstraction, doc_matters);
           }
           if (doc_matters.opt.action.harvest) {
-            if (doc_matters.opt.action.harvest_authors) {
-            }
-            if (doc_matters.opt.action.harvest_topics) {
-            }
-            Harvest[] DocReformMetaDocHarvests()(
-              Harvest    harvested,
-              Harvest[]  harvests,
-            ) {
-              harvests ~= harvested;
-              return harvests;
-            }
-            harvested = DocReformMetaDocHarvest!()(doc_matters, harvested);
-            harvests = DocReformMetaDocHarvests!()(harvested, harvests);
+            hvst.harvests ~= DocReformMetaDocHarvest!()(doc_matters, hvst);
           }
           /+ ↓ debugs +/
           if (doc_matters.opt.action.debug_do) {
@@ -777,19 +759,7 @@ void main(string[] args) {
             DocReformMetaDocSummary!()(doc_abstraction, doc_matters);
           }
           if (doc_matters.opt.action.harvest) {
-            if (doc_matters.opt.action.harvest_authors) {
-            }
-            if (doc_matters.opt.action.harvest_topics) {
-            }
-            Harvest[] DocReformMetaDocHarvests()(
-              Harvest    harvested,
-              Harvest[]  harvests,
-            ) {
-              harvests ~= harvested;
-              return harvests;
-            }
-            harvested = DocReformMetaDocHarvest!()(doc_matters, harvested);
-            harvests = DocReformMetaDocHarvests!()(harvested, harvests);
+            hvst.harvests ~= DocReformMetaDocHarvest!()(doc_matters, hvst);
           }
           /+ ↓ debugs +/
           if (doc_matters.opt.action.debug_do) {
@@ -827,610 +797,12 @@ void main(string[] args) {
       }
     }
   }
-  if (_opt_action.very_verbose
-    && harvests.length > 0
-  ) {
-    auto min_repeat_number = 42;
-    string[] _document_topic_register;
-    string[] _topic_register;
-    string[] _sub_topic_register;
-    Harvest[][string][string][string][string] subject_trees;
-    string[] topics = [];
-    string _auth = "";
-    foreach(k, doc_harvest; harvests) {
-      _topic_register = [];
-      foreach(topic; doc_harvest.topic_register_arr.sort) {
-        _sub_topic_register = [];
-        string _spaces;
-        string[] subject_tree = topic.split(mkup.sep);
-        switch (subject_tree.length) {
-        case 1:
-          subject_trees[subject_tree[0]]["_a"]["_a"]["_a"] ~= doc_harvest;
-          break;
-        case 2:
-          subject_trees[subject_tree[0]][subject_tree[1]]["_a"]["_a"] ~= doc_harvest;
-          break;
-        case 3:
-          subject_trees[subject_tree[0]][subject_tree[1]][subject_tree[2]]["_a"] ~= doc_harvest;
-          break;
-        case 4:
-          subject_trees[subject_tree[0]][subject_tree[1]][subject_tree[2]][subject_tree[3]] ~= doc_harvest;
-          break;
-        default:
-          break;
-        }
-        _topic_register ~= _sub_topic_register.join("\n");
-      }
-      auto char_repeat_number = (doc_harvest.title.length
-        + doc_harvest.author.length + 16);
-      char_repeat_number = (char_repeat_number > min_repeat_number)
-      ? char_repeat_number
-      : min_repeat_number;
-      _document_topic_register ~= format(
-        "\"%s\", %s%s\n%s",
-        doc_harvest.title,
-        doc_harvest.author,
-        (doc_harvest.date_published.length > 0) ? " (" ~ doc_harvest.date_published ~ ")" : "",
-        _topic_register.sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable).release.join("\n"),
-      );
-    }
-    topics ~= format(q"┃<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<title>Metadata Harvest - Topics</title>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
-<meta name="dc.title" content= "metadata harvest, Topics - information Structuring Universe, Structured information Serialised Units" />
-<meta name="dc.subject" content= "document structuring, ebook, publishing, PDF, LaTeX, XML, ODF, SQL, postgresql, sqlite, electronic book, electronic publishing, electronic document, electronic citation, data structure, citation systems, granular search, digital library" />
-<meta name="generator" content="doc_reform" />
-<link rel="generator" href="http://sisudoc.org" />
-<link href="../../_sisu/css/harvest.css" rel="stylesheet">
-<style TYPE="text/css">
-/* DocReform harvest css default stylesheet */
-  body {
-    color: black;
-    background: #ffffff;
-    background-color: #ffffff;
-  }
-  a:link {
-    color: #003399;
-    text-decoration: none;
-  }
-  a:visited {
-    color: #003399;
-    text-decoration: none;
-  }
-  a:hover {
-    color: #000000;
-    background-color: #f9f9aa;
-  }
-  a:hover img {
-    background-color: #ffffff;
-  }
-  a:active {
-    color: #003399;
-    text-decoration: underline;
-  }
-
-  .norm, .bold {
-    line-height: 150%%;
-    margin-left: 1em;
-    margin-right: 2em;
-    margin-top: 10px;
-    margin-bottom: 0px;
-    text-indent: 0mm;
-  }
-  p, h0, h1, h2, h3, h4, h5, h6, h7 {
-    display: block;
-    font-family: verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman;
-    font-size: 100%%;
-    font-weight: normal;
-    line-height: 150%%;
-    /* text-align: justify; */
-    margin-left: 1em;
-    text-indent: 0mm;
-    margin-top: 2px;
-    margin-bottom: 2px;
-    margin-right: 6px;
-    text-align: left;
-  }
-  h1 {
-    font-size: 120%%;
-    font-weight: bold;
-    color: white;
-    background: #000088;
-    margin-left: 0em;
-  }
-  p.work {
-    font-size: 80%%;
-    margin-left: 5em;
-    margin-top: 0px;
-    margin-bottom: 0px;
-    margin-right: 6px;
-    text-align: left;
-  }
-  p.author {
-    font-size: 100%%;
-    margin-left: 2em;
-    margin-top: 0px;
-    margin-bottom: 0px;
-    margin-right: 6px;
-    text-align: left;
-  }
-  p.publication {
-    font-size: 80%%;
-    margin-left: 4em;
-    margin-top: 0px;
-    margin-bottom: 0px;
-    margin-right: 6px;
-    text-align: left;
-  }
-  p.letter {
-    font-weight: bold;
-    font-size: 60%%;
-    margin-left: 1em;
-    margin-top: 0px;
-    margin-bottom: 0px;
-    margin-right: 6px;
-    text-align: left;
-    color: white;
-    background: #880000;
-  }
-  p.lev0 {
-    font-size: 120%%;
-    margin-left: 1em;
-    color: white;
-    background: #000000;
-  }
-
-  p.lev1 {
-    font-size: 110%%;
-    margin-left: 2em;
-    color: white;
-    background: #444444;
-  }
-  p.lev2 {
-    font-size: 100%%;
-    margin-left: 3em;
-    background: #888888;
-  }
-  p.lev3 {
-    font-size: 90%%;
-    margin-left: 4em;
-    background: #bbbbbb;
-  }
-  p.lev4 {
-    font-size: 80%%;
-    margin-left: 5em;
-    background: #eeeeee;
-  }
-  p.lev5 {
-    font-size: 80%%;
-    margin-left: 6em;
-  }
-</style>
-<link rel="shortcut icon" href="../_sisu/image/rb7.ico" />
-</head>
-<body lang="en" xml:lang="en">
-<a name="top" id="top"></a>
-<a name="up" id="up"></a>
-<a name="start" id="start"></a>
-<h1>Metadata Harvest - Topics (output organised by language &amp; filetype)</h1>
-<p>[<a href="../../index.html">&nbsp;HOME&nbsp;</a>] also see <a href="authors.html">Metadata Harvest - Authors</a></p>
-<p><a href="#A">A</a>,&nbsp;<a href="#B">B</a>,&nbsp;<a href="#C">C</a>,&nbsp;<a href="#D">D</a>,&nbsp;<a href="#E">E</a>,&nbsp;<a href="#F">F</a>,&nbsp;<a href="#G">G</a>,&nbsp;<a href="#H">H</a>,&nbsp;<a href="#I">I</a>,&nbsp;<a href="#J">J</a>,&nbsp;<a href="#K">K</a>,&nbsp;<a href="#L">L</a>,&nbsp;<a href="#M">M</a>,&nbsp;<a href="#N">N</a>,&nbsp;<a href="#O">O</a>,&nbsp;<a href="#P">P</a>,&nbsp;<a href="#Q">Q</a>,&nbsp;<a href="#R">R</a>,&nbsp;<a href="#S">S</a>,&nbsp;<a href="#T">T</a>,&nbsp;<a href="#U">U</a>,&nbsp;<a href="#V">V</a>,&nbsp;<a href="#W">W</a>,&nbsp;<a href="#X">X</a>,&nbsp;<a href="#Y">Y</a>,&nbsp;<a href="#Z">Z</a>,&nbsp;
-<p></p>
-<hr />
-<p class="tiny"><a href="../../en/manifest/topics.html">English</a>&nbsp;&nbsp;&nbsp;</p>
-<hr />
-┃") ~ "\n";
-    char _prev_k = "_".to!char;
-    int _kn;
-    foreach(k0;
-      subject_trees.keys
-      .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable)
-    ) {
-      if (k0.toUpper.to!(char[])[0] != _prev_k) {
-        topics ~= format(q"┃<p class="letter"><a name="%s">%s</a></p><p class="book_index_lev1"><a name="a"></a></p>┃",
-          k0.toUpper.to!(char[])[0],
-          k0.toUpper.to!(char[])[0],
-        );
-        _prev_k = k0.toUpper.to!(char[])[0];
-      }
-      if (k0 != "_a") {
-        topics ~= format(q"┃<p class="lev0"><a name="%s">%s</a></p>┃",
-          k0, k0,) ~ "\n";
-        writeln("", k0);
-        if ("_a" in subject_trees[k0]) {
-          foreach (t_a_;
-            subject_trees[k0]["_a"]["_a"]["_a"]
-            .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable)
-          ) {
-            _auth = [];
-            if (t_a_.author_arr.length < 2) {
-              _auth = format(q"┃ <a href="authors.html#%s">%s</a>┃",
-                t_a_.author_surname,
-                t_a_.author,
-              );
-            } else {
-              foreach (a; t_a_.author_arr) {
-                _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
-                  t_a_.author_surname,
-                  a,
-                );
-              }
-            }
-            topics ~= format(q"┃<p class="work"><a href="%s">"%s"</a> -%s┃",
-              "url",
-              t_a_.title,
-              _auth,
-            ) ~ "\n";
-            writeln("- ", t_a_.title, " - ", t_a_.author);
-          }
-        }
-        foreach(k1;
-          subject_trees[k0].keys
-          .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable)
-        ) {
-          if (k1 != "_a") {
-            topics ~= format(q"┃<p class="lev1"><a name="%s">%s</a></p>┃",
-              k1, k1,) ~ "\n";
-            writeln("  ", k1);
-            if ("_a" in subject_trees[k0][k1]) {
-              foreach (t_a_;
-                subject_trees[k0][k1]["_a"]["_a"]
-                .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable)
-              ) {
-                _auth = [];
-                if (t_a_.author_arr.length < 2) {
-                  _auth = format(q"┃ <a href="authors.html#%s">%s</a>┃",
-                    t_a_.author_surname,
-                    t_a_.author,
-                  );
-                } else {
-                  foreach (a; t_a_.author_arr) {
-                    _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
-                      t_a_.author_surname,
-                      a,
-                    );
-                  }
-                }
-                topics ~= format(q"┃<p class="work"><a href="%s">%s</a> -%s┃",
-                  "url",
-                  t_a_.title,
-                  _auth,
-                ) ~ "\n";
-                writeln("  - ", t_a_.title, " - ", t_a_.author);
-              }
-            }
-          }
-          foreach(k2;
-            subject_trees[k0][k1].keys
-            .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable)
-          ) {
-            if (k2 != "_a") {
-              topics ~= format(q"┃<p class="lev2"><a name="%s">%s</a></p>┃",
-                k2, k2,) ~ "\n";
-              writeln("    ", k2);
-              if ("_a" in subject_trees[k0][k1][k2]) {
-                foreach (t_a_;
-                  subject_trees[k0][k1][k2]["_a"]
-                  .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable)
-                ) {
-                  _auth = [];
-                  if (t_a_.author_arr.length < 2) {
-                    _auth = format(q"┃ <a href="authors.html#%s">%s</a>┃",
-                      t_a_.author_surname,
-                      t_a_.author,
-                    );
-                  } else {
-                    foreach (a; t_a_.author_arr) {
-                      _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
-                        t_a_.author_surname,
-                        a,
-                      );
-                    }
-                  }
-                  topics ~= format(q"┃<p class="work"><a href="%s">%s</a> -%s┃",
-                    "url",
-                    t_a_.title,
-                    _auth,
-                  ) ~ "\n";
-                  writeln("    - ", t_a_.title, " - ", t_a_.author);
-                }
-              }
-            }
-            foreach(k3;
-              subject_trees[k0][k1][k2].keys
-              .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable)
-            ) {
-              if (k3 != "_a") {
-                topics ~= format(q"┃<p class="lev3"><a name="%s">%s</a></p>┃",
-                  k3, k3,) ~ "\n";
-                writeln("      ", k3);
-                {
-                  foreach (t_a_;
-                    subject_trees[k0][k1][k2][k3]
-                    .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable)
-                  ) {
-                    _auth = [];
-                    if (t_a_.author_arr.length < 2) {
-                      _auth = format(q"┃<a href="authors.html#%s">%s</a>┃",
-                        t_a_.author_surname,
-                        t_a_.author,
-                      );
-                    } else {
-                      foreach (a; t_a_.author_arr) {
-                        _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
-                          t_a_.author_surname,
-                          a,
-                        );
-                      }
-                    }
-                    topics ~= format(q"┃ <p class="work"><a href="%s">%s</a> -%s┃",
-                      "url",
-                      t_a_.title,
-                      _auth,
-                    ) ~ "\n";
-                    writeln("      - ", t_a_.title, " - ", t_a_.author);
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    topics ~= format(q"┃
-<hr />
-<a name="bottom" id="bottom"></a>
-<a name="down" id="down"></a>
-<a name="end" id="end"></a>
-<a name="finish" id="finish"></a>
-<a name="stop" id="stop"></a>
-<a name="credits"></a>
-</body>
-</html>
-┃") ~ "\n";
-    try {
-      auto f = File("topics.html", "w");
-      foreach (o; topics) {
-        f.writeln(o);
-      }
-    } catch (ErrnoException ex) {
-      // Handle error
-    }
-  }
-  if ((_opt_action.verbose
-    || _opt_action.very_verbose)
-    && harvests.length > 0
-  ) {
-    string[] authors = [];
-    authors ~= format(q"┃
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<title>Metadata Harvest - Authors</title>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
-<meta name="dc.title" content= "metadata harvest, Authors - information Structuring Universe, Structured information Serialised Units" />
-<meta name="dc.subject" content= "document structuring, ebook, publishing, PDF, LaTeX, XML, ODF, SQL, postgresql, sqlite, electronic book, electronic publishing, electronic document, electronic citation, data structure, citation systems, granular search, digital library" />
-<meta name="generator" content="doc_reform" />
-<link rel="generator" href="http://sisudoc.org" />
-<link href="../../_sisu/css/harvest.css" rel="stylesheet" >
-<style TYPE="text/css">
-/* DocReform harvest css default stylesheet */
-  body {
-    color: black;
-    background: #ffffff;
-    background-color: #ffffff;
-  }
-  a:link {
-    color: #003399;
-    text-decoration: none;
-  }
-  a:visited {
-    color: #003399;
-    text-decoration: none;
-  }
-  a:hover {
-    color: #000000;
-    background-color: #f9f9aa;
-  }
-  a:hover img {
-    background-color: #ffffff;
-  }
-  a:active {
-    color: #003399;
-    text-decoration: underline;
-  }
-
-  .norm, .bold {
-    line-height: 150%%;
-    margin-left: 1em;
-    margin-right: 2em;
-    margin-top: 10px;
-    margin-bottom: 0px;
-    text-indent: 0mm;
-  }
-  p, h0, h1, h2, h3, h4, h5, h6, h7 {
-    display: block;
-    font-family: verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman;
-    font-size: 100%%;
-    font-weight: normal;
-    line-height: 150%%;
-    /* text-align: justify; */
-    margin-left: 1em;
-    text-indent: 0mm;
-    margin-top: 2px;
-    margin-bottom: 2px;
-    margin-right: 6px;
-    text-align: left;
-  }
-  h1 {
-    font-size: 120%%;
-    font-weight: bold;
-    color: white;
-    background: #000088;
-    margin-left: 0em;
-  }
-  p.work {
-    font-size: 80%%;
-    margin-left: 5em;
-    margin-top: 0px;
-    margin-bottom: 0px;
-    margin-right: 6px;
-    text-align: left;
-  }
-  p.author {
-    font-size: 100%%;
-    margin-left: 2em;
-    margin-top: 0px;
-    margin-bottom: 0px;
-    margin-right: 6px;
-    text-align: left;
-  }
-  p.publication {
-    font-size: 80%%;
-    margin-left: 4em;
-    margin-top: 0px;
-    margin-bottom: 0px;
-    margin-right: 6px;
-    text-align: left;
-  }
-  p.letter {
-    font-weight: bold;
-    font-size: 60%%;
-    margin-left: 1em;
-    margin-top: 0px;
-    margin-bottom: 0px;
-    margin-right: 6px;
-    text-align: left;
-    color: white;
-    background: #880000;
-  }
-  p.lev0 {
-    font-size: 120%%;
-    margin-left: 1em;
-    color: white;
-    background: #000000;
-  }
-
-  p.lev1 {
-    font-size: 110%%;
-    margin-left: 2em;
-    color: white;
-    background: #444444;
-  }
-  p.lev2 {
-    font-size: 100%%;
-    margin-left: 3em;
-    background: #888888;
-  }
-  p.lev3 {
-    font-size: 90%%;
-    margin-left: 4em;
-    background: #bbbbbb;
-  }
-  p.lev4 {
-    font-size: 80%%;
-    margin-left: 5em;
-    background: #eeeeee;
-  }
-  p.lev5 {
-    font-size: 80%%;
-    margin-left: 6em;
-  }
-</style>
-<link rel="shortcut icon" href="../_sisu/image/rb7.ico" />
-</head>
-<body lang="en" xml:lang="en">
-<a name="top" id="top"></a>
-<a name="up" id="up"></a>
-<a name="start" id="start"></a>
-<h1>Metadata Harvest - Authors (output organised by language &amp; filetype)</h1>
-<p>[<a href="../../index.html">&nbsp;HOME&nbsp;</a>] also see <a href="topics.html">Metadata Harvest - Topics</a></p>
-<p></p>
-<hr />
-<p class="tiny"><a href="../../en/manifest/authors.html">English</a>&nbsp;&nbsp;&nbsp;</p>
-<hr />
-<p><a href="#A">A</a>,&nbsp;<a href="#B">B</a>,&nbsp;<a href="#C">C</a>,&nbsp;<a href="#D">D</a>,&nbsp;<a href="#E">E</a>,&nbsp;<a href="#F">F</a>,&nbsp;<a href="#G">G</a>,&nbsp;<a href="#H">H</a>,&nbsp;<a href="#I">I</a>,&nbsp;<a href="#J">J</a>,&nbsp;<a href="#K">K</a>,&nbsp;<a href="#L">L</a>,&nbsp;<a href="#M">M</a>,&nbsp;<a href="#N">N</a>,&nbsp;<a href="#O">O</a>,&nbsp;<a href="#P">P</a>,&nbsp;<a href="#Q">Q</a>,&nbsp;<a href="#R">R</a>,&nbsp;<a href="#S">S</a>,&nbsp;<a href="#T">T</a>,&nbsp;<a href="#U">U</a>,&nbsp;<a href="#V">V</a>,&nbsp;<a href="#W">W</a>,&nbsp;<a href="#X">X</a>,&nbsp;<a href="#Y">Y</a>,&nbsp;<a href="#Z">Z</a>,&nbsp;
-┃") ~ "\n";
-    string[string] _au;
-    string[] _auth_date_title;
-    string[] _author_date_title;
-    string _prev_auth = "";
-    char _prev_k = "_".to!char;
-    foreach(doc_harvest;
-      harvests
-      .multiSort!(
-        "toUpper(a.author_surname_fn) < toUpper(b.author_surname_fn)",
-        "a.date_published < b.date_published",
-        "a.title < b.title",
-        SwapStrategy.unstable
-      )
-    ) {
-      if (doc_harvest.author_surname_fn != _prev_auth) {
-        _au[doc_harvest.author_surname_fn]
-        = format(q"┃<p class="author"><a name="%s">%s</a></p> <p class="publication">%s "<a href="%s">%s</a>" [%s]</p>┃",
-          doc_harvest.author_surname,
-          doc_harvest.author_surname_fn,
-          (doc_harvest.date_published.length > 0)
-            ? doc_harvest.date_published : "",
-          "url",
-          doc_harvest.title,
-          doc_harvest.language,
-        );
-        _prev_auth = doc_harvest.author_surname_fn;
-      } else {
-        _au[doc_harvest.author_surname_fn]
-        ~= format(q"┃<p class="publication">%s "<a href="%s">%s</a>" [%s]</p>┃",
-          (doc_harvest.date_published.length > 0)
-            ? doc_harvest.date_published : "",
-          "url",
-          doc_harvest.title,
-          doc_harvest.language,
-        );
-      }
-      _author_date_title ~= format(q"┃%s %s "%s" [%s]┃",
-        doc_harvest.author_surname_fn,
-        (doc_harvest.date_published.length > 0)
-          ? "(" ~ doc_harvest.date_published ~ ")" : "",
-        doc_harvest.title,
-        doc_harvest.language,
-      );
-      // writeln(doc_harvest.author_date_title);
-    }
-    foreach (k; _au.keys.sort) {
-      if (k.toUpper.to!(char[])[0] != _prev_k) {
-        authors ~= format(q"┃<p class="letter"><a name="%s">%s</a></p><p class="book_index_lev1"><a name="a"></a></p>┃",
-          k.toUpper.to!(char[])[0],
-          k.toUpper.to!(char[])[0],
-        );
-        _prev_k = k.toUpper.to!(char[])[0];
-      }
-      authors ~= _au[k];
-    }
-     authors ~= format(q"┃
-<hr />
-<a name="bottom" id="bottom"></a>
-<a name="down" id="down"></a>
-<a name="end" id="end"></a>
-<a name="finish" id="finish"></a>
-<a name="stop" id="stop"></a>
-<a name="credits"></a>
-</body>
-</html>
-┃") ~ "\n";
-    try {
-      auto f = File("authors.html", "w");
-      foreach (o; authors) {
-        f.writeln(o);
-      }
-    } catch (ErrnoException ex) {
-      // Handle error
+  if (hvst.harvests.length > 0) {
+    if (_opt_action.harvest_topics) {
+      DocReformMetaDocHarvestsTopics!()(hvst, _opt_action);
     }
-    foreach(_adt; _author_date_title.sort) {
-      writeln(_adt);
+    if (_opt_action.harvest_authors) {
+      DocReformMetaDocHarvestsAuthors!()(hvst.harvests, _opt_action);
     }
   }
 }
diff --git a/src/doc_reform/meta/defaults.d b/src/doc_reform/meta/defaults.d
index fc5e5d1..4a4ae8f 100644
--- a/src/doc_reform/meta/defaults.d
+++ b/src/doc_reform/meta/defaults.d
@@ -87,6 +87,34 @@ template DocReformNode() {
     return _node;
   }
 }
+template DocReformHarvest() {
+  auto DocReformHarvest() {
+    struct _Harvest {
+      struct Harvest {
+        string   title                = "";
+        string[] author_arr           = [];
+        string   author               = "";
+        string   author_surname       = "";
+        string   author_surname_fn    = "";
+        string   language             = "";
+        string   language_original    = "";
+        string   uid                  = "";
+        string   date_published       = "";
+        string[] topic_register_arr   = [];
+        string   path_html_seg        = "";
+        string   path_html_scroll     = "";
+        string   path_epub            = "";
+        string   url_html_seg         = "";
+        string   url_html_scroll      = "";
+        string   url_epub             = "";
+      }
+      Harvest harvest;
+      Harvest[] harvests;
+      Harvest[][string][string][string][string] subject_trees;
+    }
+    return _Harvest();
+  }
+}
 template DocReformBiblio() {
   // required: deemed_author (author || editor); year; fulltitle;
   struct BibJsnStr {
diff --git a/src/doc_reform/meta/metadoc.d b/src/doc_reform/meta/metadoc.d
index a26756b..88c4a2b 100644
--- a/src/doc_reform/meta/metadoc.d
+++ b/src/doc_reform/meta/metadoc.d
@@ -8,6 +8,8 @@ template DocReformAbstraction() {
     std.process;
   import
     doc_reform.meta,
+    doc_reform.meta.metadoc_harvests_authors,
+    doc_reform.meta.metadoc_harvests_topics,
     doc_reform.meta.metadoc_summary,
     doc_reform.meta.metadoc_harvest,
     doc_reform.meta.metadoc_from_src,
@@ -147,7 +149,7 @@ template DocReformAbstraction() {
           ~ ":" ~ _st.second.to!string;
         return _time;
       }
-      auto conf_make_meta() { // TODO meld with all make instructions
+      auto conf_make_meta() {
         return _make_and_meta_struct;
       }
       auto has() {
diff --git a/src/doc_reform/meta/metadoc_harvest.d b/src/doc_reform/meta/metadoc_harvest.d
index 26f2b38..2a83814 100644
--- a/src/doc_reform/meta/metadoc_harvest.d
+++ b/src/doc_reform/meta/metadoc_harvest.d
@@ -2,7 +2,7 @@ module doc_reform.meta.metadoc_harvest;
 template DocReformMetaDocHarvest() {
   auto DocReformMetaDocHarvest(T,H)(
     T  doc_matters,
-    H  harvest,
+    H  hvst,
   ) {
     import
       doc_reform.meta.defaults,
@@ -21,19 +21,19 @@ template DocReformMetaDocHarvest() {
     mixin InternalMarkup;
     auto markup = InlineMarkup();
     import doc_reform.output.paths_output;
-    auto pth_html              = DocReformPathsHTML!()(doc_matters.output_path, doc_matters.src.language);
-    harvest.title              = doc_matters.conf_make_meta.meta.title_full;
-    harvest.author             = doc_matters.conf_make_meta.meta.creator_author;
-    harvest.author_surname     = doc_matters.conf_make_meta.meta.creator_author_surname;
-    harvest.author_surname_fn  = doc_matters.conf_make_meta.meta.creator_author_surname_fn;
-    harvest.author_arr         = doc_matters.conf_make_meta.meta.creator_author_arr;
-    harvest.language_original  = doc_matters.conf_make_meta.meta.original_language;
-    harvest.language           = doc_matters.src.language;
-    harvest.uid                = doc_matters.src.doc_uid;
-    harvest.date_published     = doc_matters.conf_make_meta.meta.date_published;
-    harvest.topic_register_arr = doc_matters.conf_make_meta.meta.classify_topic_register_arr;
-    harvest.path_html_scroll   = pth_html.fn_scroll(doc_matters.src.filename);
-    harvest.path_html_seg      = pth_html.fn_seg(doc_matters.src.filename, "toc");
-    return harvest;
+    auto pth_html                   = DocReformPathsHTML!()(doc_matters.output_path, doc_matters.src.language);
+    hvst.harvest.title              = doc_matters.conf_make_meta.meta.title_full;
+    hvst.harvest.author             = doc_matters.conf_make_meta.meta.creator_author;
+    hvst.harvest.author_surname     = doc_matters.conf_make_meta.meta.creator_author_surname;
+    hvst.harvest.author_surname_fn  = doc_matters.conf_make_meta.meta.creator_author_surname_fn;
+    hvst.harvest.author_arr         = doc_matters.conf_make_meta.meta.creator_author_arr;
+    hvst.harvest.language_original  = doc_matters.conf_make_meta.meta.original_language;
+    hvst.harvest.language           = doc_matters.src.language;
+    hvst.harvest.uid                = doc_matters.src.doc_uid;
+    hvst.harvest.date_published     = doc_matters.conf_make_meta.meta.date_published;
+    hvst.harvest.topic_register_arr = doc_matters.conf_make_meta.meta.classify_topic_register_arr;
+    hvst.harvest.path_html_scroll   = pth_html.fn_scroll(doc_matters.src.filename);
+    hvst.harvest.path_html_seg      = pth_html.fn_seg(doc_matters.src.filename, "toc");
+    return hvst.harvest;
   }
 }
diff --git a/src/doc_reform/meta/metadoc_harvests_authors.d b/src/doc_reform/meta/metadoc_harvests_authors.d
new file mode 100644
index 0000000..d780221
--- /dev/null
+++ b/src/doc_reform/meta/metadoc_harvests_authors.d
@@ -0,0 +1,255 @@
+module doc_reform.meta.metadoc_harvests_authors;
+  import
+    std.algorithm,
+    std.array,
+    std.exception,
+    std.regex,
+    std.stdio,
+    std.string,
+    std.conv : to;
+  import
+    doc_reform.meta.defaults,
+    doc_reform.meta.rgx;
+  mixin DocReformHarvest;
+  mixin InternalMarkup;
+  mixin DocReformRgxInit;
+template DocReformMetaDocHarvestsAuthors() {
+  auto mkup = InlineMarkup();
+  void DocReformMetaDocHarvestsAuthors(H,O)(
+    H  harvests,
+    O  _opt_action,
+  ) {
+      string[] authors = [];
+      authors ~= format(q"┃
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Metadata Harvest - Authors</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<meta name="dc.title" content= "metadata harvest, Authors & Topics - information Structuring Universe, Structured information Serialised Units" />
+<meta name="dc.subject" content= "document structuring, ebook, publishing, PDF, LaTeX, XML, ODF, SQL, postgresql, sqlite, electronic book, electronic publishing, electronic document, electronic citation, data structure, citation systems, granular search, digital library" />
+<meta name="generator" content="doc_reform" />
+<link rel="generator" href="http://sisudoc.org" />
+<link href="../../_sisu/css/harvest.css" rel="stylesheet">
+<style TYPE="text/css">
+/* DocReform harvest css default stylesheet */
+  body {
+    color: black;
+    background: #ffffff;
+    background-color: #ffffff;
+  }
+  a:link {
+    color: #003399;
+    text-decoration: none;
+  }
+  a:visited {
+    color: #003399;
+    text-decoration: none;
+  }
+  a:hover {
+    color: #000000;
+    background-color: #f9f9aa;
+  }
+  a:hover img {
+    background-color: #ffffff;
+  }
+  a:active {
+    color: #003399;
+    text-decoration: underline;
+  }
+
+  .norm, .bold {
+    line-height: 150%%;
+    margin-left: 1em;
+    margin-right: 2em;
+    margin-top: 10px;
+    margin-bottom: 0px;
+    text-indent: 0mm;
+  }
+  p, h0, h1, h2, h3, h4, h5, h6, h7 {
+    display: block;
+    font-family: verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman;
+    font-size: 100%%;
+    font-weight: normal;
+    line-height: 150%%;
+    /* text-align: justify; */
+    margin-left: 1em;
+    text-indent: 0mm;
+    margin-top: 2px;
+    margin-bottom: 2px;
+    margin-right: 6px;
+    text-align: left;
+  }
+  h1 {
+    font-size: 120%%;
+    font-weight: bold;
+    color: white;
+    background: #000088;
+    margin-left: 0em;
+  }
+  p.work {
+    font-size: 80%%;
+    margin-left: 5em;
+    margin-top: 0px;
+    margin-bottom: 0px;
+    margin-right: 6px;
+    text-align: left;
+  }
+  p.author {
+    font-size: 100%%;
+    margin-left: 2em;
+    margin-top: 0px;
+    margin-bottom: 0px;
+    margin-right: 6px;
+    text-align: left;
+  }
+  p.publication {
+    font-size: 80%%;
+    margin-left: 4em;
+    margin-top: 0px;
+    margin-bottom: 0px;
+    margin-right: 6px;
+    text-align: left;
+  }
+  p.letter {
+    font-weight: bold;
+    font-size: 60%%;
+    margin-left: 1em;
+    margin-top: 0px;
+    margin-bottom: 0px;
+    margin-right: 6px;
+    text-align: left;
+    color: white;
+    background: #880000;
+  }
+  p.lev0 {
+    font-size: 120%%;
+    margin-left: 1em;
+    color: white;
+    background: #000000;
+  }
+
+  p.lev1 {
+    font-size: 110%%;
+    margin-left: 2em;
+    color: white;
+    background: #444444;
+  }
+  p.lev2 {
+    font-size: 100%%;
+    margin-left: 3em;
+    background: #888888;
+  }
+  p.lev3 {
+    font-size: 90%%;
+    margin-left: 4em;
+    background: #bbbbbb;
+  }
+  p.lev4 {
+    font-size: 80%%;
+    margin-left: 5em;
+    background: #eeeeee;
+  }
+  p.lev5 {
+    font-size: 80%%;
+    margin-left: 6em;
+  }
+</style>
+<link rel="shortcut icon" href="../_sisu/image/rb7.ico" />
+</head>
+<body lang="en" xml:lang="en">
+<a name="top" id="top"></a>
+<a name="up" id="up"></a>
+<a name="start" id="start"></a>
+<h1>Metadata Harvest - Authors (output organised by language &amp; filetype)</h1>
+<p>[<a href="../../index.html">&nbsp;HOME&nbsp;</a>] also see <a href="topics.html">Metadata Harvest - Topics</a></p>
+<p></p>
+<hr />
+<p class="tiny"><a href="../../en/manifest/authors.html">English</a>&nbsp;&nbsp;&nbsp;</p>
+<hr />
+<p><a href="#A">A</a>,&nbsp;<a href="#B">B</a>,&nbsp;<a href="#C">C</a>,&nbsp;<a href="#D">D</a>,&nbsp;<a href="#E">E</a>,&nbsp;<a href="#F">F</a>,&nbsp;<a href="#G">G</a>,&nbsp;<a href="#H">H</a>,&nbsp;<a href="#I">I</a>,&nbsp;<a href="#J">J</a>,&nbsp;<a href="#K">K</a>,&nbsp;<a href="#L">L</a>,&nbsp;<a href="#M">M</a>,&nbsp;<a href="#N">N</a>,&nbsp;<a href="#O">O</a>,&nbsp;<a href="#P">P</a>,&nbsp;<a href="#Q">Q</a>,&nbsp;<a href="#R">R</a>,&nbsp;<a href="#S">S</a>,&nbsp;<a href="#T">T</a>,&nbsp;<a href="#U">U</a>,&nbsp;<a href="#V">V</a>,&nbsp;<a href="#W">W</a>,&nbsp;<a href="#X">X</a>,&nbsp;<a href="#Y">Y</a>,&nbsp;<a href="#Z">Z</a>,&nbsp;
+┃") ~ "\n";
+      string[string] _au;
+      string[] _auth_date_title;
+      string[] _author_date_title;
+      string _prev_auth = "";
+      char _prev_k = "_".to!char;
+      foreach(doc_harvest;
+        harvests
+        .multiSort!(
+          "toUpper(a.author_surname_fn) < toUpper(b.author_surname_fn)",
+          "a.date_published < b.date_published",
+          "a.title < b.title",
+          SwapStrategy.unstable
+        )
+      ) {
+        if (doc_harvest.author_surname_fn != _prev_auth) {
+          _au[doc_harvest.author_surname_fn]
+          = format(q"┃<p class="author"><a name="%s">%s</a></p> <p class="publication">%s "<a href="%s">%s</a>" [%s]</p>┃",
+            doc_harvest.author_surname,
+            doc_harvest.author_surname_fn,
+            (doc_harvest.date_published.length > 0)
+              ? doc_harvest.date_published : "",
+            "url",
+            doc_harvest.title,
+            doc_harvest.language,
+          );
+          _prev_auth = doc_harvest.author_surname_fn;
+        } else {
+          _au[doc_harvest.author_surname_fn]
+          ~= format(q"┃<p class="publication">%s "<a href="%s">%s</a>" [%s]</p>┃",
+            (doc_harvest.date_published.length > 0)
+              ? doc_harvest.date_published : "",
+            "url",
+            doc_harvest.title,
+            doc_harvest.language,
+          );
+        }
+        _author_date_title ~= format(q"┃%s %s "%s" [%s]┃",
+          doc_harvest.author_surname_fn,
+          (doc_harvest.date_published.length > 0)
+            ? "(" ~ doc_harvest.date_published ~ ")" : "",
+          doc_harvest.title,
+          doc_harvest.language,
+        );
+      }
+      foreach (k; _au.keys.sort) {
+        if (k.toUpper.to!(char[])[0] != _prev_k) {
+          authors ~= format(q"┃<p class="letter"><a name="%s">%s</a></p><p class="book_index_lev1"><a name="a"></a></p>┃",
+            k.toUpper.to!(char[])[0],
+            k.toUpper.to!(char[])[0],
+          );
+          _prev_k = k.toUpper.to!(char[])[0];
+        }
+        authors ~= _au[k];
+      }
+      authors
+      ~= format(q"┃
+<hr />
+<a name="bottom" id="bottom"></a>
+<a name="down" id="down"></a>
+<a name="end" id="end"></a>
+<a name="finish" id="finish"></a>
+<a name="stop" id="stop"></a>
+<a name="credits"></a>
+</body>
+</html>
+┃") ~ "\n";
+    try {
+      auto f = File("authors.html", "w");
+      foreach (o; authors) {
+        f.writeln(o);
+      }
+    } catch (ErrnoException ex) {
+      // Handle error
+    }
+    if (_opt_action.verbose
+      || _opt_action.very_verbose
+    ) {
+      foreach(_adt; _author_date_title.sort) {
+        writeln(_adt);
+      }
+    }
+  }
+}
diff --git a/src/doc_reform/meta/metadoc_harvests_topics.d b/src/doc_reform/meta/metadoc_harvests_topics.d
new file mode 100644
index 0000000..f0aed57
--- /dev/null
+++ b/src/doc_reform/meta/metadoc_harvests_topics.d
@@ -0,0 +1,408 @@
+module doc_reform.meta.metadoc_harvests_topics;
+  import
+    std.algorithm,
+    std.array,
+    std.exception,
+    std.regex,
+    std.stdio,
+    std.string,
+    std.conv : to;
+  import
+    doc_reform.meta.defaults,
+    doc_reform.meta.rgx;
+  mixin DocReformHarvest;
+  mixin InternalMarkup;
+  mixin DocReformRgxInit;
+template DocReformMetaDocHarvestsTopics() {
+  auto mkup = InlineMarkup();
+  void DocReformMetaDocHarvestsTopics(H,O)(
+    H  hvst,
+    O  _opt_action,
+  ) {
+      auto min_repeat_number = 42;
+      string[] _document_topic_register;
+      string[] _topic_register;
+      string[] _sub_topic_register;
+      string[] topics = [];
+      string _auth = "";
+      foreach(k, doc_harvest; hvst.harvests) {
+        _topic_register = [];
+        foreach(topic; doc_harvest.topic_register_arr.sort) {
+          _sub_topic_register = [];
+          string _spaces;
+          string[] subject_tree = topic.split(mkup.sep);
+          switch (subject_tree.length) {
+          case 1:
+            hvst.subject_trees[subject_tree[0]]["_a"]["_a"]["_a"] ~= doc_harvest;
+            break;
+          case 2:
+            hvst.subject_trees[subject_tree[0]][subject_tree[1]]["_a"]["_a"] ~= doc_harvest;
+            break;
+          case 3:
+            hvst.subject_trees[subject_tree[0]][subject_tree[1]][subject_tree[2]]["_a"] ~= doc_harvest;
+            break;
+          case 4:
+            hvst.subject_trees[subject_tree[0]][subject_tree[1]][subject_tree[2]][subject_tree[3]] ~= doc_harvest;
+            break;
+          default:
+            break;
+          }
+          _topic_register ~= _sub_topic_register.join("\n");
+        }
+        auto char_repeat_number = (doc_harvest.title.length
+          + doc_harvest.author.length + 16);
+        char_repeat_number = (char_repeat_number > min_repeat_number)
+        ? char_repeat_number
+        : min_repeat_number;
+        _document_topic_register ~= format(
+          "\"%s\", %s%s\n%s",
+          doc_harvest.title,
+          doc_harvest.author,
+          (doc_harvest.date_published.length > 0) ? " (" ~ doc_harvest.date_published ~ ")" : "",
+          _topic_register.sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable).release.join("\n"),
+        );
+      }
+      topics ~= format(q"┃<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Metadata Harvest - Topics</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<meta name="dc.title" content= "metadata harvest, Authors & Topics - information Structuring Universe, Structured information Serialised Units" />
+<meta name="dc.subject" content= "document structuring, ebook, publishing, PDF, LaTeX, XML, ODF, SQL, postgresql, sqlite, electronic book, electronic publishing, electronic document, electronic citation, data structure, citation systems, granular search, digital library" />
+<meta name="generator" content="doc_reform" />
+<link rel="generator" href="http://sisudoc.org" />
+<link href="../../_sisu/css/harvest.css" rel="stylesheet">
+<style TYPE="text/css">
+/* DocReform harvest css default stylesheet */
+  body {
+    color: black;
+    background: #ffffff;
+    background-color: #ffffff;
+  }
+  a:link {
+    color: #003399;
+    text-decoration: none;
+  }
+  a:visited {
+    color: #003399;
+    text-decoration: none;
+  }
+  a:hover {
+    color: #000000;
+    background-color: #f9f9aa;
+  }
+  a:hover img {
+    background-color: #ffffff;
+  }
+  a:active {
+    color: #003399;
+    text-decoration: underline;
+  }
+
+  .norm, .bold {
+    line-height: 150%%;
+    margin-left: 1em;
+    margin-right: 2em;
+    margin-top: 10px;
+    margin-bottom: 0px;
+    text-indent: 0mm;
+  }
+  p, h0, h1, h2, h3, h4, h5, h6, h7 {
+    display: block;
+    font-family: verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman;
+    font-size: 100%%;
+    font-weight: normal;
+    line-height: 150%%;
+    /* text-align: justify; */
+    margin-left: 1em;
+    text-indent: 0mm;
+    margin-top: 2px;
+    margin-bottom: 2px;
+    margin-right: 6px;
+    text-align: left;
+  }
+  h1 {
+    font-size: 120%%;
+    font-weight: bold;
+    color: white;
+    background: #000088;
+    margin-left: 0em;
+  }
+  p.work {
+    font-size: 80%%;
+    margin-left: 5em;
+    margin-top: 0px;
+    margin-bottom: 0px;
+    margin-right: 6px;
+    text-align: left;
+  }
+  p.author {
+    font-size: 100%%;
+    margin-left: 2em;
+    margin-top: 0px;
+    margin-bottom: 0px;
+    margin-right: 6px;
+    text-align: left;
+  }
+  p.publication {
+    font-size: 80%%;
+    margin-left: 4em;
+    margin-top: 0px;
+    margin-bottom: 0px;
+    margin-right: 6px;
+    text-align: left;
+  }
+  p.letter {
+    font-weight: bold;
+    font-size: 60%%;
+    margin-left: 1em;
+    margin-top: 0px;
+    margin-bottom: 0px;
+    margin-right: 6px;
+    text-align: left;
+    color: white;
+    background: #880000;
+  }
+  p.lev0 {
+    font-size: 120%%;
+    margin-left: 1em;
+    color: white;
+    background: #000000;
+  }
+
+  p.lev1 {
+    font-size: 110%%;
+    margin-left: 2em;
+    color: white;
+    background: #444444;
+  }
+  p.lev2 {
+    font-size: 100%%;
+    margin-left: 3em;
+    background: #888888;
+  }
+  p.lev3 {
+    font-size: 90%%;
+    margin-left: 4em;
+    background: #bbbbbb;
+  }
+  p.lev4 {
+    font-size: 80%%;
+    margin-left: 5em;
+    background: #eeeeee;
+  }
+  p.lev5 {
+    font-size: 80%%;
+    margin-left: 6em;
+  }
+</style>
+<link rel="shortcut icon" href="../_sisu/image/rb7.ico" />
+</head>
+<body lang="en" xml:lang="en">
+<a name="top" id="top"></a>
+<a name="up" id="up"></a>
+<a name="start" id="start"></a>
+<h1>Metadata Harvest - Topics (output organised by language &amp; filetype)</h1>
+<p>[<a href="../../index.html">&nbsp;HOME&nbsp;</a>] also see <a href="authors.html">Metadata Harvest - Authors</a></p>
+<p><a href="#A">A</a>,&nbsp;<a href="#B">B</a>,&nbsp;<a href="#C">C</a>,&nbsp;<a href="#D">D</a>,&nbsp;<a href="#E">E</a>,&nbsp;<a href="#F">F</a>,&nbsp;<a href="#G">G</a>,&nbsp;<a href="#H">H</a>,&nbsp;<a href="#I">I</a>,&nbsp;<a href="#J">J</a>,&nbsp;<a href="#K">K</a>,&nbsp;<a href="#L">L</a>,&nbsp;<a href="#M">M</a>,&nbsp;<a href="#N">N</a>,&nbsp;<a href="#O">O</a>,&nbsp;<a href="#P">P</a>,&nbsp;<a href="#Q">Q</a>,&nbsp;<a href="#R">R</a>,&nbsp;<a href="#S">S</a>,&nbsp;<a href="#T">T</a>,&nbsp;<a href="#U">U</a>,&nbsp;<a href="#V">V</a>,&nbsp;<a href="#W">W</a>,&nbsp;<a href="#X">X</a>,&nbsp;<a href="#Y">Y</a>,&nbsp;<a href="#Z">Z</a>,&nbsp;
+<p></p>
+<hr />
+<p class="tiny"><a href="../../en/manifest/topics.html">English</a>&nbsp;&nbsp;&nbsp;</p>
+<hr />
+┃") ~ "\n";
+      char _prev_k = "_".to!char;
+      int _kn;
+      foreach(k0;
+        hvst.subject_trees.keys
+        .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable)
+      ) {
+        if (k0.toUpper.to!(char[])[0] != _prev_k) {
+          topics ~= format(q"┃<p class="letter"><a name="%s">%s</a></p><p class="book_index_lev1"><a name="a"></a></p>┃",
+            k0.toUpper.to!(char[])[0],
+            k0.toUpper.to!(char[])[0],
+          );
+          _prev_k = k0.toUpper.to!(char[])[0];
+        }
+        if (k0 != "_a") {
+          topics ~= format(q"┃<p class="lev0"><a name="%s">%s</a></p>┃",
+            k0, k0,) ~ "\n";
+          if (_opt_action.very_verbose) {
+            writeln("", k0);
+          }
+          if ("_a" in hvst.subject_trees[k0]) {
+            foreach (t_a_;
+              hvst.subject_trees[k0]["_a"]["_a"]["_a"]
+              .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable)
+            ) {
+              _auth = [];
+              if (t_a_.author_arr.length < 2) {
+                _auth = format(q"┃ <a href="authors.html#%s">%s</a>┃",
+                  t_a_.author_surname,
+                  t_a_.author,
+                );
+              } else {
+                foreach (a; t_a_.author_arr) {
+                  _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
+                    t_a_.author_surname,
+                    a,
+                  );
+                }
+              }
+              topics ~= format(q"┃<p class="work"><a href="%s">"%s"</a> -%s┃",
+                "url",
+                t_a_.title,
+                _auth,
+              ) ~ "\n";
+              if (_opt_action.very_verbose) {
+                writeln("- ", t_a_.title, " - ", t_a_.author);
+              }
+            }
+          }
+          foreach(k1;
+            hvst.subject_trees[k0].keys
+            .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable)
+          ) {
+            if (k1 != "_a") {
+              topics ~= format(q"┃<p class="lev1"><a name="%s">%s</a></p>┃",
+                k1, k1,) ~ "\n";
+              if (_opt_action.very_verbose) {
+                writeln("  ", k1);
+              }
+              if ("_a" in hvst.subject_trees[k0][k1]) {
+                foreach (t_a_;
+                  hvst.subject_trees[k0][k1]["_a"]["_a"]
+                  .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable)
+                ) {
+                  _auth = [];
+                  if (t_a_.author_arr.length < 2) {
+                    _auth = format(q"┃ <a href="authors.html#%s">%s</a>┃",
+                      t_a_.author_surname,
+                      t_a_.author,
+                    );
+                  } else {
+                    foreach (a; t_a_.author_arr) {
+                      _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
+                        t_a_.author_surname,
+                        a,
+                      );
+                    }
+                  }
+                  topics ~= format(q"┃<p class="work"><a href="%s">%s</a> -%s┃",
+                    "url",
+                    t_a_.title,
+                    _auth,
+                  ) ~ "\n";
+                  if (_opt_action.very_verbose) {
+                    writeln("  - ", t_a_.title, " - ", t_a_.author);
+                  }
+                }
+              }
+            }
+            foreach(k2;
+              hvst.subject_trees[k0][k1].keys
+              .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable)
+            ) {
+              if (k2 != "_a") {
+                topics ~= format(q"┃<p class="lev2"><a name="%s">%s</a></p>┃",
+                  k2, k2,) ~ "\n";
+                if (_opt_action.very_verbose) {
+                  writeln("    ", k2);
+                }
+                if ("_a" in hvst.subject_trees[k0][k1][k2]) {
+                  foreach (t_a_;
+                    hvst.subject_trees[k0][k1][k2]["_a"]
+                    .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable)
+                  ) {
+                    _auth = [];
+                    if (t_a_.author_arr.length < 2) {
+                      _auth = format(q"┃ <a href="authors.html#%s">%s</a>┃",
+                        t_a_.author_surname,
+                        t_a_.author,
+                      );
+                    } else {
+                      foreach (a; t_a_.author_arr) {
+                        _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
+                          t_a_.author_surname,
+                          a,
+                        );
+                      }
+                    }
+                    topics ~= format(q"┃<p class="work"><a href="%s">%s</a> -%s┃",
+                      "url",
+                      t_a_.title,
+                      _auth,
+                    ) ~ "\n";
+                    if (_opt_action.very_verbose) {
+                      writeln("    - ", t_a_.title, " - ", t_a_.author);
+                    }
+                  }
+                }
+              }
+              foreach(k3;
+                hvst.subject_trees[k0][k1][k2].keys
+                .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable)
+              ) {
+                if (k3 != "_a") {
+                  topics ~= format(q"┃<p class="lev3"><a name="%s">%s</a></p>┃",
+                    k3, k3,) ~ "\n";
+                  if (_opt_action.very_verbose) {
+                    writeln("      ", k3);
+                  }
+                  {
+                    foreach (t_a_;
+                      hvst.subject_trees[k0][k1][k2][k3]
+                      .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable)
+                    ) {
+                      _auth = [];
+                      if (t_a_.author_arr.length < 2) {
+                        _auth = format(q"┃<a href="authors.html#%s">%s</a>┃",
+                          t_a_.author_surname,
+                          t_a_.author,
+                        );
+                      } else {
+                        foreach (a; t_a_.author_arr) {
+                          _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
+                            t_a_.author_surname,
+                            a,
+                          );
+                        }
+                      }
+                      topics ~= format(q"┃ <p class="work"><a href="%s">%s</a> -%s┃",
+                        "url",
+                        t_a_.title,
+                        _auth,
+                      ) ~ "\n";
+                      if (_opt_action.very_verbose) {
+                        writeln("      - ", t_a_.title, " - ", t_a_.author);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+      topics
+      ~= format(q"┃
+<hr />
+<a name="bottom" id="bottom"></a>
+<a name="down" id="down"></a>
+<a name="end" id="end"></a>
+<a name="finish" id="finish"></a>
+<a name="stop" id="stop"></a>
+<a name="credits"></a>
+</body>
+</html>
+┃") ~ "\n";
+    try {
+      auto f = File("topics.html", "w");
+      foreach (o; topics) {
+        f.writeln(o);
+      }
+    } catch (ErrnoException ex) {
+      // Handle error
+    }
+  }
+}
diff --git a/src/doc_reform/output/paths_output.d b/src/doc_reform/output/paths_output.d
index 305aa17..c11d31e 100644
--- a/src/doc_reform/output/paths_output.d
+++ b/src/doc_reform/output/paths_output.d
@@ -172,7 +172,7 @@ template DocReformPathsEPUB() {
     Po  output_pth_root,
     Lng lng,
   ) {
-    auto out_pth = DocReformOutPaths!()( output_pth_root, lng);
+    auto out_pth = DocReformOutPaths!()(output_pth_root, lng);
     string base_dir = "epub";
     struct _PathsStruct {
       string base() {
@@ -276,9 +276,6 @@ template DocReformPathsODT() {
       string base_pth() { // dir will contain odt document file (also debug file tree)
         return asNormalizedPath((out_pth.output_base).chainPath(base_dir)).array;
       }
-      // string base_filename() {
-      //   return doc_matters.src.filename_base;
-      // }
       string odt_file() {
         return asNormalizedPath(base_pth.chainPath(doc_matters.src.filename_base ~ ".odt")).array;
       }
diff --git a/src/doc_reform/source/paths_source.d b/src/doc_reform/source/paths_source.d
index 6efca00..bf4ee55 100644
--- a/src/doc_reform/source/paths_source.d
+++ b/src/doc_reform/source/paths_source.d
@@ -200,13 +200,6 @@ template PathMatters() {
             return _uid;
           }
           string docname_composite_unique_per_src_doc() {
-          /+
-            z pod name if any + src filename + lng code
-             filename ~ "." ~  lng
-             * unique per src doc
-             used by
-             - sqlite discrete index (multilingual, each language of a document)
-          +/
             string _fn;
             if (pod_name_with_path.baseName == filename_base) {
               _fn = filename_base ~ mkup.sep ~ filename_extension ~ mkup.sep ~ lng;
-- 
cgit v1.2.3