From 1f8b96b650ea645c1a92b40f29c8625b6228d53a Mon Sep 17 00:00:00 2001
From: Ralph Amissah <ralph.amissah@gmail.com>
Date: Wed, 1 Sep 2021 15:40:20 -0400
Subject: metadata "curate" replaces "harvest"

- "curated metadata" instead of "metadata harvest"
- css color change to related pages, light theme
---
 src/doc_reform/io_out/metadata.d               |  28 +-
 src/doc_reform/io_out/paths_output.d           |   8 +-
 src/doc_reform/io_out/xmls.d                   |   2 +-
 src/doc_reform/meta/defaults.d                 |  16 +-
 src/doc_reform/meta/metadoc_curate.d           |  92 ++++
 src/doc_reform/meta/metadoc_curate_authors.d   | 494 +++++++++++++++++++
 src/doc_reform/meta/metadoc_curate_topics.d    | 654 +++++++++++++++++++++++++
 src/doc_reform/meta/metadoc_harvest.d          |  92 ----
 src/doc_reform/meta/metadoc_harvests_authors.d | 494 -------------------
 src/doc_reform/meta/metadoc_harvests_topics.d  | 654 -------------------------
 src/doc_reform/spine.d                         |  82 ++--
 11 files changed, 1308 insertions(+), 1308 deletions(-)
 create mode 100644 src/doc_reform/meta/metadoc_curate.d
 create mode 100644 src/doc_reform/meta/metadoc_curate_authors.d
 create mode 100644 src/doc_reform/meta/metadoc_curate_topics.d
 delete mode 100644 src/doc_reform/meta/metadoc_harvest.d
 delete mode 100644 src/doc_reform/meta/metadoc_harvests_authors.d
 delete mode 100644 src/doc_reform/meta/metadoc_harvests_topics.d

(limited to 'src/doc_reform')

diff --git a/src/doc_reform/io_out/metadata.d b/src/doc_reform/io_out/metadata.d
index 58d8b33..89e82bd 100644
--- a/src/doc_reform/io_out/metadata.d
+++ b/src/doc_reform/io_out/metadata.d
@@ -163,26 +163,26 @@ string theme_dark_1 = format(q"┃
 string theme_light_1 = format(q"┃
   h1 {
     color                    : #FFFFFF;
-    background               : #000088;
+    background               : #1A3A7A;
   }
   p.letter {
     color                    : #FFFFFF;
-    background               : #880000;
+    background               : #1A3A7A;
   }
 ┃");
       metadata_ ~= format(q"┃<!DOCTYPE html>
 <html>
 <head>
 <meta charset="utf-8">
-<title>Metadata Harvest - Topics</title>
+<title>Curated metadata - 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.title" content= "metadata curate, 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="spine" />
 <link rel="generator" href="https://sisudoc.org" />
-<link href="./css/harvest.css" rel="stylesheet">
+<link href="./css/curate.css" rel="stylesheet">
 <style TYPE="text/css">
-/* spine harvest css default stylesheet */%s
+/* spine curate css default stylesheet */%s
   .norm, .bold {
     line-height              : 150%%;
     margin-left              : 1em;
@@ -351,8 +351,8 @@ string theme_light_1 = format(q"┃
     <a name="start" id="start"></a>
     ┃");
     metadata_ ~= "<div class=\"flex-menu-bar\"><div class=\"flex-menu-option\">";
-    if (doc_matters.opt.action.html_harvest_link) {
-      metadata_ ~= format(q"┃<p>[<a href="../../index.html">&nbsp;HOME&nbsp;</a>] Metadata Harvest
+    if (doc_matters.opt.action.html_curate_link) {
+      metadata_ ~= format(q"┃<p>[<a href="../../index.html">&nbsp;HOME&nbsp;</a>] Curated metadata
        [<a href="../../authors.html">&nbsp;Authors&nbsp;</a>]
        [<a href="../../topics.html">&nbsp;Topics&nbsp;</a>]</p>
     ┃");
@@ -367,7 +367,7 @@ string theme_light_1 = format(q"┃
       writeln("ERROR no Title information provided in document header ", doc_matters.src.filename_base);
     }
     if (!(doc_matters.conf_make_meta.meta.creator_author.empty)) {
-      if (doc_matters.opt.action.html_harvest_link) {
+      if (doc_matters.opt.action.html_curate_link) {
         metadata_ ~= "<p class=\"lev1\">Author: <b><a href=\"../../authors.html#" ~ doc_matters.conf_make_meta.meta.creator_author_surname.translate([' ' : "_"]) ~ "\">"
                                                    ~ doc_matters.conf_make_meta.meta.creator_author   ~ "</a></b></p>";
       } else {
@@ -412,7 +412,7 @@ string theme_light_1 = format(q"┃
         if (subject_tree.length > 0) {
           if (subject_tree[0] != _top[0]) {
             _top[0] = subject_tree[0];
-            if (doc_matters.opt.action.html_harvest_link) {
+            if (doc_matters.opt.action.html_curate_link) {
               metadata_ ~=
                 "<p class=\"lev1\"><a href=\"../../topics.html#"
                   ~ subject_tree[0].translate([' ' : "_"]) ~ "\">"
@@ -427,7 +427,7 @@ string theme_light_1 = format(q"┃
             if (subject_tree[1] != _top[1]) {
               _top[1] = subject_tree[1];
               _top[2] = ""; _top[3] = ""; _top[4] = "";
-              if (doc_matters.opt.action.html_harvest_link) {
+              if (doc_matters.opt.action.html_curate_link) {
                 metadata_ ~=
                   "<p class=\"lev2\"><a href=\"../../topics.html#"
                     ~ subject_tree[0].translate([' ' : "_"]) ~ "."
@@ -443,7 +443,7 @@ string theme_light_1 = format(q"┃
               if (subject_tree[2] != _top[2]) {
                 _top[2] = subject_tree[2];
                 _top[3] = ""; _top[4] = "";
-                if (doc_matters.opt.action.html_harvest_link) {
+                if (doc_matters.opt.action.html_curate_link) {
                   metadata_ ~=
                     "<p class=\"lev3\"><a href=\"../../topics.html#"
                       ~ subject_tree[0].translate([' ' : "_"]) ~ "."
@@ -460,7 +460,7 @@ string theme_light_1 = format(q"┃
                 if (subject_tree[3] != _top[3]) {
                   _top[3] = subject_tree[3];
                   _top[4] = "";
-                  if (doc_matters.opt.action.html_harvest_link) {
+                  if (doc_matters.opt.action.html_curate_link) {
                     metadata_ ~=
                       "<p class=\"lev4\"><a href=\"../../topics.html#"
                         ~ subject_tree[0].translate([' ' : "_"]) ~ "."
@@ -477,7 +477,7 @@ string theme_light_1 = format(q"┃
                 if (subject_tree.length > 4) {
                   if (subject_tree[4] != _top[4]) {
                     _top[4] = subject_tree[4];
-                    if (doc_matters.opt.action.html_harvest_link) {
+                    if (doc_matters.opt.action.html_curate_link) {
                       metadata_ ~=
                         "<p class=\"lev5\"><a href=\"../../topics.html#"
                           ~ subject_tree[0].translate([' ' : "_"]) ~ "."
diff --git a/src/doc_reform/io_out/paths_output.d b/src/doc_reform/io_out/paths_output.d
index 86f418a..2fe7c50 100644
--- a/src/doc_reform/io_out/paths_output.d
+++ b/src/doc_reform/io_out/paths_output.d
@@ -222,8 +222,8 @@ template spinePathsHTML() {
       string doc_root() {
         return ((output_path_root.chainPath(doc_tree.doc_root)).asNormalizedPath).array;
       }
-      string harvest(string fn_harvest) {
-        return doc_root ~ "/" ~ fn_harvest;
+      string curate(string fn_curate) {
+        return doc_root ~ "/" ~ fn_curate;
       }
       string internal_base() {
         return ((doc_tree.base).asNormalizedPath).array;
@@ -283,10 +283,10 @@ template spineUrlsHTML() {
       string doc_root() {
         return url_doc_root ~ ((doc_tree.doc_root).asNormalizedPath).array;
       }
-      string harvest(string fn_harvest) {
+      string curate(string fn_curate) {
         return format(q"┃%s/%s┃",
           doc_root,
-          fn_harvest,
+          fn_curate,
         );
       }
       string base() {
diff --git a/src/doc_reform/io_out/xmls.d b/src/doc_reform/io_out/xmls.d
index ab80a09..3857969 100644
--- a/src/doc_reform/io_out/xmls.d
+++ b/src/doc_reform/io_out/xmls.d
@@ -236,7 +236,7 @@ template outputXHTMLs() {
       string type,
     ) {
       string o;
-      string metadata_links = ((doc_matters.opt.action.html_harvest_link)
+      string metadata_links = ((doc_matters.opt.action.html_curate_link)
         ? format(q"┃<p class="tiny">[<a href="%smetadata.%s.html">&nbsp;m&nbsp;</a>|<a href="%s../../authors.html">&nbsp;A&nbsp;</a>|<a href="%s../../topics.html">&nbsp;T&nbsp;</a>]</p>┃",
             (type == "seg") ? "../" : "",
             doc_matters.src.filename_base,
diff --git a/src/doc_reform/meta/defaults.d b/src/doc_reform/meta/defaults.d
index 4429f80..ec6ba49 100644
--- a/src/doc_reform/meta/defaults.d
+++ b/src/doc_reform/meta/defaults.d
@@ -95,10 +95,10 @@ template spineNode() {
     return _node;
   }
 }
-template spineHarvest() {
-  @safe auto spineHarvest() {
-    struct _Harvest {
-      struct Harvest {
+template spineCurateMetadata() {
+  @safe auto spineCurateMetadata() {
+    struct _Curate {
+      struct Curate {
         string   title                = "";
         string[] author_arr           = [];
         string   author               = "";
@@ -120,11 +120,11 @@ template spineHarvest() {
         string   url_html_scroll      = "";
         string   url_epub             = "";
       }
-      Harvest harvest;
-      Harvest[] harvests;
-      Harvest[][string][string][string][string] subject_trees;
+      Curate curate;
+      Curate[] curates;
+      Curate[][string][string][string][string] subject_trees;
     }
-    return _Harvest();
+    return _Curate();
   }
 }
 template spineBiblio() {
diff --git a/src/doc_reform/meta/metadoc_curate.d b/src/doc_reform/meta/metadoc_curate.d
new file mode 100644
index 0000000..8190a9d
--- /dev/null
+++ b/src/doc_reform/meta/metadoc_curate.d
@@ -0,0 +1,92 @@
+/+
+- Name: Spine, Doc Reform [a part of]
+  - Description: documents, structuring, processing, publishing, search
+    - static content generator
+
+  - Author: Ralph Amissah
+    [ralph.amissah@gmail.com]
+
+  - Copyright: (C) 2015 - 2021 Ralph Amissah, All Rights
+    Reserved.
+
+  - License: AGPL 3 or later:
+
+    Spine (SiSU), a framework for document structuring, publishing and
+    search
+
+    Copyright (C) Ralph Amissah
+
+    This program is free software: you can redistribute it and/or modify it
+    under the terms of the GNU AFERO General Public License as published by the
+    Free Software Foundation, either version 3 of the License, or (at your
+    option) any later version.
+
+    This program is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+    more details.
+
+    You should have received a copy of the GNU General Public License along with
+    this program. If not, see [https://www.gnu.org/licenses/].
+
+    If you have Internet connection, the latest version of the AGPL should be
+    available at these locations:
+    [https://www.fsf.org/licensing/licenses/agpl.html]
+    [https://www.gnu.org/licenses/agpl.html]
+
+  - Spine (by Doc Reform, related to SiSU) uses standard:
+    - docReform markup syntax
+      - standard SiSU markup syntax with modified headers and minor modifications
+    - docReform object numbering
+      - standard SiSU object citation numbering & system
+
+  - Hompages:
+    [https://www.doc_reform.org]
+    [https://www.sisudoc.org]
+
+  - Git
+    [https://git.sisudoc.org/projects/?p=software/spine.git;a=summary]
+
++/
+module doc_reform.meta.metadoc_curate;
+template spineMetaDocCurate() {
+  @safe auto spineMetaDocCurate(T,H)(
+    T  doc_matters,
+    H  hvst,
+  ) {
+    import
+      doc_reform.meta.defaults,
+      doc_reform.meta.rgx;
+    import
+      std.array,
+      std.exception,
+      std.regex,
+      std.stdio,
+      std.string,
+      std.typecons,
+      std.uni,
+      std.utf,
+      std.conv : to;
+    mixin InternalMarkup;
+    static auto mkup = InlineMarkup();
+    import doc_reform.io_out.paths_output;
+    auto pth_html_abs                  = spinePathsHTML!()(doc_matters.output_path, doc_matters.src.language);
+    auto pth_html_rel                  = spineDocRootTreeHTML!()(doc_matters.src.language);
+    hvst.curate.title                 = doc_matters.conf_make_meta.meta.title_full;
+    hvst.curate.author                = doc_matters.conf_make_meta.meta.creator_author;
+    hvst.curate.author_surname        = doc_matters.conf_make_meta.meta.creator_author_surname;
+    hvst.curate.author_surname_fn     = doc_matters.conf_make_meta.meta.creator_author_surname_fn;
+    hvst.curate.author_arr            = doc_matters.conf_make_meta.meta.creator_author_arr;
+    hvst.curate.language_original     = doc_matters.conf_make_meta.meta.original_language;
+    hvst.curate.language              = doc_matters.src.language;
+    hvst.curate.uid                   = doc_matters.src.doc_uid;
+    hvst.curate.date_published        = doc_matters.conf_make_meta.meta.date_published;
+    hvst.curate.topic_register_arr    = doc_matters.conf_make_meta.meta.classify_topic_register_arr;
+    hvst.curate.path_html_metadata    = pth_html_rel.fn_metadata(doc_matters.src.filename);
+    hvst.curate.path_html_scroll      = pth_html_rel.fn_scroll(doc_matters.src.filename);
+    hvst.curate.path_html_segtoc      = pth_html_rel.fn_seg(doc_matters.src.filename, "toc");
+    hvst.curate.path_abs_html_scroll  = pth_html_abs.fn_scroll(doc_matters.src.filename);
+    hvst.curate.path_abs_html_segtoc  = pth_html_abs.fn_seg(doc_matters.src.filename, "toc");
+    return hvst.curate;
+  }
+}
diff --git a/src/doc_reform/meta/metadoc_curate_authors.d b/src/doc_reform/meta/metadoc_curate_authors.d
new file mode 100644
index 0000000..8c64f0c
--- /dev/null
+++ b/src/doc_reform/meta/metadoc_curate_authors.d
@@ -0,0 +1,494 @@
+/+
+- Name: Spine, Doc Reform [a part of]
+  - Description: documents, structuring, processing, publishing, search
+    - static content generator
+
+  - Author: Ralph Amissah
+    [ralph.amissah@gmail.com]
+
+  - Copyright: (C) 2015 - 2021 Ralph Amissah, All Rights
+    Reserved.
+
+  - License: AGPL 3 or later:
+
+    Spine (SiSU), a framework for document structuring, publishing and
+    search
+
+    Copyright (C) Ralph Amissah
+
+    This program is free software: you can redistribute it and/or modify it
+    under the terms of the GNU AFERO General Public License as published by the
+    Free Software Foundation, either version 3 of the License, or (at your
+    option) any later version.
+
+    This program is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+    more details.
+
+    You should have received a copy of the GNU General Public License along with
+    this program. If not, see [https://www.gnu.org/licenses/].
+
+    If you have Internet connection, the latest version of the AGPL should be
+    available at these locations:
+    [https://www.fsf.org/licensing/licenses/agpl.html]
+    [https://www.gnu.org/licenses/agpl.html]
+
+  - Spine (by Doc Reform, related to SiSU) uses standard:
+    - docReform markup syntax
+      - standard SiSU markup syntax with modified headers and minor modifications
+    - docReform object numbering
+      - standard SiSU object citation numbering & system
+
+  - Hompages:
+    [https://www.doc_reform.org]
+    [https://www.sisudoc.org]
+
+  - Git
+    [https://git.sisudoc.org/projects/?p=software/spine.git;a=summary]
+
++/
+module doc_reform.meta.metadoc_curate_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 spineCurateMetadata;
+  mixin InternalMarkup;
+template spineMetaDocCuratesAuthors() {
+  static auto mkup = InlineMarkup();
+  void spineMetaDocCuratesAuthors(H,M,O)(
+    H  curates,
+    M  _make_and_meta_struct,
+    O  _opt_action,
+  ) {
+      @safe string inline_search_form(M)(
+        M  _make_and_meta_truct,
+      ) {
+        string o;
+        string _form;
+        if (_opt_action.html_search_link) {
+          o = format(q"┃
+      <div class="flex-menu-option">
+      <!-- SiSU Spine Search -->
+      <form action="%s" target="_top" method="POST" accept-charset="UTF-8" id="search">
+      <font size="2">
+      <input type="text" name="sf" size="24" maxlength="255">%s
+      <input type="hidden" name="sml" value="1000">
+      <input type="hidden" name="ec" value="on">
+      <input type="hidden" name="url" value="on">
+      <button type="submit" form="search">db</button>
+      </font></form>
+      <!-- SiSU Spine Search -->
+      </div>┃",
+          _make_and_meta_struct.conf.w_srv_cgi_action,
+          (_make_and_meta_struct.conf.w_srv_db_sqlite_filename.empty)
+            ? ""
+            : "\n    <input type=\"hidden\" name=\"db\" value=\""
+              ~ _make_and_meta_struct.conf.w_srv_db_sqlite_filename
+              ~ "\">",
+          );
+        } else {
+          o = "";
+        }
+        return o;
+      }
+string theme_dark_0 = format(q"┃
+  body {
+    color                    : #CCCCCC;
+    background               : #000000;
+    background-color         : #000000;
+  }
+  a:link {
+    color                    : #FFFFFF;
+    text-decoration          : none;
+  }
+  a:visited {
+    color                    : #999999;
+    text-decoration          : none;
+  }
+  a:hover {
+    color                    : #000000;
+    background-color         : #555555;
+  }
+  a:hover img {
+    background-color         : #000000;
+  }
+  a:active {
+    color                    : #888888;
+    text-decoration          : underline;
+  }
+  a.lev0:hover {
+    color                    : #FFFFFF;
+    background-color         : #000000;
+  }
+  a.lev1:hover {
+    color                    : #FFFFFF;
+    background               : #333333;
+  }
+  a.lev2:hover {
+    color                    : #FFFFFF;
+    background               : #555555;
+  }
+  a.lev3:hover {
+    color                    : #FFFFFF;
+    background               : #777777;
+  }
+  input {
+    color                    : #FFFFFF;
+    background-color         : #777777;
+  }
+┃");
+string theme_light_0 = format(q"┃
+  body {
+    color                    : #000000;
+    background               : #FFFFFF;
+    background-color         : #FFFFFF;
+  }
+  a:link {
+    color                    : #003399;
+    text-decoration          : none;
+  }
+  a:visited {
+    color                    : #003399;
+    text-decoration          : none;
+  }
+  a:hover {
+    color                    : #000000;
+    background-color         : #f9f9aa;
+  }
+  a:hover img {
+    background-color         : #FFFFFF;
+  }
+  a:active {
+    color                    : #003399;
+    text-decoration          : underline;
+  }
+  a.lev0:hover {
+    color                    : #000000;
+    background-color         : #FFFFFF;
+  }
+  a.lev1:hover {
+    color                    : #FFFFFF;
+    background               : #444444;
+  }
+  a.lev2:hover {
+    background               : #888888;
+  }
+  a.lev3:hover {
+    background               : #BBBBBB;
+  }
+  input {
+    color                    : #000000;
+    background-color         : #FFFFFF;
+  }
+┃");
+string theme_dark_1 = format(q"┃
+  h1 {
+    color                    : #FFFFFF;
+    background               : #000000;
+  }
+  p.letter {
+    color                    : #FFFFFF;
+    background               : #333333;
+  }
+  p.lev0 {
+    color                    : #FFFFFF;
+    background               : #000000;
+  }
+  p.lev1 {
+    color                    : #FFFFFF;
+    background               : #333333;
+  }
+  p.lev2 {
+    background               : #555555;
+  }
+  p.lev3 {
+    background               : #777777;
+  }
+  p.lev4 {
+    background               : #AAAAAA;
+  }
+  p.lev5 {
+  }
+┃");
+string theme_light_1 = format(q"┃
+  h1 {
+    color                    : #FFFFFF;
+    background               : #1A3A7A;
+  }
+  p.letter {
+    color                    : #FFFFFF;
+    background               : #1A3A7A;
+  }
+  p.lev0 {
+    color                    : #FFFFFF;
+    background               : #000000;
+  }
+  p.lev1 {
+    color                    : #FFFFFF;
+    background               : #444444;
+  }
+  p.lev2 {
+    background               : #888888;
+  }
+  p.lev3 {
+    background               : #BBBBBB;
+  }
+  p.lev4 {
+    background               : #EEEEEE;
+  }
+  p.lev5 {
+  }
+┃");
+      string[] authors = [];
+      authors ~= format(q"┃
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Curated metadata - Authors</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<meta name="dc.title" content= "metadata curate, 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="spine" />
+<link rel="generator" href="https://sisudoc.org" />
+<link href="./css/curate.css" rel="stylesheet">
+<style TYPE="text/css">
+/* spine curate css default stylesheet */%s
+  .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;
+  }
+  h0, h1, h2, h3, h4, h5, h6, h7 { text-shadow: .2em .2em .3em #999999; }
+  h1 {
+    font-size                : 120%%;
+    font-weight              : bold;
+    color                    : #FFFFFF;
+    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;
+  }
+  p.lev0 {
+    font-size                : 120%%;
+    margin-left              : 1em;
+  }
+  p.lev1 {
+    font-size                : 110%%;
+    margin-left              : 2em;
+  }
+  p.lev2 {
+    font-size                : 100%%;
+    margin-left              : 3em;
+  }
+  p.lev3 {
+    font-size                : 90%%;
+    margin-left              : 4em;
+  }
+  p.lev4 {
+    font-size                : 80%%;
+    margin-left              : 5em;
+  }
+  p.lev5 {
+    font-size                : 80%%;
+    margin-left              : 6em;
+  }%s
+  /* flex */
+  .flex-menu-bar {
+    display                  : -webkit-flex;
+    display                  : flex;
+    -webkit-flex-wrap        : wrap;
+    -webkit-align-items      : center;
+    align-items              : center;
+    width                    : 100%%;
+    margin-left              : 0%%;
+    margin-right             : 2%%;
+    background-color         : inherited;
+  }
+  .flex-menu-option {
+    background-color         : inherited;
+    margin-right             : 4px;
+  }
+  .flex-list {
+    display                  : -webkit-flex;
+    display                  : flex;
+    -webkit-align-items      : center;
+    display                  : block;
+    align-items              : center;
+    width                    : 100%%;
+    background-color         : inherited;
+  }
+  .flex-list-item {
+    background-color         : inherited;
+    margin                   : 4px;
+  }
+</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>Curated metadata - Authors (output organised by language &amp; filetype)</h1>
+<div class="flex-menu-bar">
+<div class="flex-menu-option">
+<p>[<a href="../../index.html">&nbsp;HOME&nbsp;</a>]
+ [<a href="topics.html">&nbsp;Curated&nbsp;metadata&nbsp;-&nbsp;Topics&nbsp;</a>]
+</p>
+</div>
+%s
+</div>
+<p></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;
+┃",
+  _opt_action.css_theme_default ? theme_light_0 : theme_dark_0,
+  _opt_action.css_theme_default ? theme_light_1 : theme_dark_1,
+  inline_search_form(_make_and_meta_struct),
+) ~ "\n";
+      string[string] _au;
+      string[] _auth_date_title;
+      string[] _author_date_title;
+      string _prev_auth = "";
+      char _prev_k = "_".to!char;
+      foreach(doc_curate;
+        curates
+        .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_curate.author_surname_fn != _prev_auth) {
+          _au[doc_curate.author_surname_fn]
+          = format(q"┃<p class="author"><a name="%s" class="lev0">%s</a></p> <p class="publication">%s "<a href="%s">%s</a>" [<a href="%s">&nbsp;%s&nbsp;</a>]</p>┃",
+            doc_curate.author_surname.translate([' ' : "_"]),
+            doc_curate.author_surname_fn,
+            (doc_curate.date_published.length > 0)
+              ? doc_curate.date_published : "",
+            doc_curate.path_html_segtoc,
+            doc_curate.title,
+            doc_curate.path_html_metadata,
+            doc_curate.language,
+          );
+          _prev_auth = doc_curate.author_surname_fn;
+        } else {
+          _au[doc_curate.author_surname_fn]
+          ~= format(q"┃<p class="publication">%s "<a href="%s">%s</a>" [<a href="%s">&nbsp;%s&nbsp;</a>]</p>┃",
+            (doc_curate.date_published.length > 0)
+              ? doc_curate.date_published : "",
+            doc_curate.path_html_segtoc,
+            doc_curate.title,
+            doc_curate.path_html_metadata,
+            doc_curate.language,
+          );
+        }
+        _author_date_title ~= format(q"┃%s %s "%s" [<a href="%s">&nbsp;%s&nbsp;</a>]%s┃",
+          doc_curate.author_surname_fn,
+          (doc_curate.date_published.length > 0)
+            ? "(" ~ doc_curate.date_published ~ ")" : "",
+          doc_curate.title,
+          doc_curate.path_html_metadata,
+          doc_curate.language,
+          (_opt_action.very_verbose) ? "\n  " ~ doc_curate.path_abs_html_scroll : "",
+        );
+      }
+      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";
+    import doc_reform.io_out.paths_output;
+    auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
+    try {
+      auto f       = File(out_pth.curate("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_curate_topics.d b/src/doc_reform/meta/metadoc_curate_topics.d
new file mode 100644
index 0000000..1fdc760
--- /dev/null
+++ b/src/doc_reform/meta/metadoc_curate_topics.d
@@ -0,0 +1,654 @@
+/+
+- Name: Spine, Doc Reform [a part of]
+  - Description: documents, structuring, processing, publishing, search
+    - static content generator
+
+  - Author: Ralph Amissah
+    [ralph.amissah@gmail.com]
+
+  - Copyright: (C) 2015 - 2021 Ralph Amissah, All Rights
+    Reserved.
+
+  - License: AGPL 3 or later:
+
+    Spine (SiSU), a framework for document structuring, publishing and
+    search
+
+    Copyright (C) Ralph Amissah
+
+    This program is free software: you can redistribute it and/or modify it
+    under the terms of the GNU AFERO General Public License as published by the
+    Free Software Foundation, either version 3 of the License, or (at your
+    option) any later version.
+
+    This program is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+    more details.
+
+    You should have received a copy of the GNU General Public License along with
+    this program. If not, see [https://www.gnu.org/licenses/].
+
+    If you have Internet connection, the latest version of the AGPL should be
+    available at these locations:
+    [https://www.fsf.org/licensing/licenses/agpl.html]
+    [https://www.gnu.org/licenses/agpl.html]
+
+  - Spine (by Doc Reform, related to SiSU) uses standard:
+    - docReform markup syntax
+      - standard SiSU markup syntax with modified headers and minor modifications
+    - docReform object numbering
+      - standard SiSU object citation numbering & system
+
+  - Hompages:
+    [https://www.doc_reform.org]
+    [https://www.sisudoc.org]
+
+  - Git
+    [https://git.sisudoc.org/projects/?p=software/spine.git;a=summary]
+
++/
+module doc_reform.meta.metadoc_curate_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 spineCurateMetadata;
+  mixin InternalMarkup;
+template spineMetaDocCuratesTopics() {
+  static auto mkup = InlineMarkup();
+  void spineMetaDocCuratesTopics(H,M,O)(
+    H  hvst,
+    M  _make_and_meta_struct,
+    O  _opt_action,
+  ) {
+      @safe string inline_search_form(M)(
+        M  _make_and_meta_truct,
+      ) {
+        string o;
+        string _form;
+        if (_opt_action.html_search_link) {
+          o = format(q"┃
+      <div class="flex-menu-option">
+      <!-- SiSU Spine Search -->
+      <form action="%s" target="_top" method="POST" accept-charset="UTF-8" id="search">
+      <font size="2">
+      <input type="text" name="sf" size="24" maxlength="255">%s
+      <input type="hidden" name="sml" value="1000">
+      <input type="hidden" name="ec" value="on">
+      <input type="hidden" name="url" value="on">
+      <button type="submit" form="search">db</button>
+      </font></form>
+      <!-- SiSU Spine Search -->
+      </div>┃",
+          _make_and_meta_struct.conf.w_srv_cgi_action,
+          (_make_and_meta_struct.conf.w_srv_db_sqlite_filename.empty)
+            ? ""
+            : "\n    <input type=\"hidden\" name=\"db\" value=\""
+              ~ _make_and_meta_struct.conf.w_srv_db_sqlite_filename
+              ~ "\">",
+          );
+        } else {
+          o = "";
+        }
+        return o;
+      }
+      auto min_repeat_number = 42;
+      string[] _document_topic_register;
+      string[] _topic_register;
+      string[] _sub_topic_register;
+      string[] topics = [];
+      string _auth = "";
+      foreach(k, doc_curate; hvst.curates) {
+        _topic_register = [];
+        foreach(topic; doc_curate.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_curate;
+            break;
+          case 2:
+            hvst.subject_trees[subject_tree[0]][subject_tree[1]]["_a"]["_a"] ~= doc_curate;
+            break;
+          case 3:
+            hvst.subject_trees[subject_tree[0]][subject_tree[1]][subject_tree[2]]["_a"] ~= doc_curate;
+            break;
+          case 4:
+            hvst.subject_trees[subject_tree[0]][subject_tree[1]][subject_tree[2]][subject_tree[3]] ~= doc_curate;
+            break;
+          default:
+            break;
+          }
+          _topic_register ~= _sub_topic_register.join("\n");
+        }
+        auto char_repeat_number = (doc_curate.title.length
+          + doc_curate.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_curate.title,
+          doc_curate.author,
+          (doc_curate.date_published.length > 0) ? " (" ~ doc_curate.date_published ~ ")" : "",
+          _topic_register.sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable).release.join("\n"),
+        );
+      }
+string theme_dark_0 = format(q"┃
+  body {
+    color                    : #CCCCCC;
+    background               : #000000;
+    background-color         : #000000;
+  }
+  a:link {
+    color                    : #FFFFFF;
+    text-decoration          : none;
+  }
+  a:visited {
+    color                    : #999999;
+    text-decoration          : none;
+  }
+  a:hover {
+    color                    : #000000;
+    background-color         : #555555;
+  }
+  a:hover img {
+    background-color         : #000000;
+  }
+  a:active {
+    color                    : #888888;
+    text-decoration          : underline;
+  }
+  a.lev0:hover {
+    color                    : #FFFFFF;
+    background-color         : #000000;
+  }
+  a.lev1:hover {
+    color                    : #FFFFFF;
+    background               : #333333;
+  }
+  a.lev2:hover {
+    color                    : #FFFFFF;
+    background               : #555555;
+  }
+  a.lev3:hover {
+    color                    : #FFFFFF;
+    background               : #777777;
+  }
+  input {
+    color                    : #FFFFFF;
+    background-color         : #777777;
+  }
+┃");
+string theme_light_0 = format(q"┃
+  body {
+    color                    : #000000;
+    background               : #FFFFFF;
+    background-color         : #FFFFFF;
+  }
+  a:link {
+    color                    : #003399;
+    text-decoration          : none;
+  }
+  a:visited {
+    color                    : #003399;
+    text-decoration          : none;
+  }
+  a:hover {
+    color                    : #000000;
+    background-color         : #f9f9aa;
+  }
+  a:hover img {
+    background-color         : #FFFFFF;
+  }
+  a:active {
+    color                    : #003399;
+    text-decoration          : underline;
+  }
+  a.lev0:hover {
+    color                    : #000000;
+    background-color         : #FFFFFF;
+  }
+  a.lev1:hover {
+    color                    : #FFFFFF;
+    background               : #444444;
+  }
+  a.lev2:hover {
+    background               : #888888;
+  }
+  a.lev3:hover {
+    background               : #BBBBBB;
+  }
+  input {
+    color                    : #000000;
+    background-color         : #FFFFFF;
+  }
+┃");
+string theme_dark_1 = format(q"┃
+  h1 {
+    color                    : #FFFFFF;
+    background               : #000000;
+  }
+  p.letter {
+    color                    : #FFFFFF;
+    background               : #333333;
+  }
+  p.lev0 {
+    color                    : #FFFFFF;
+    background               : #000000;
+  }
+  p.lev1 {
+    color                    : #FFFFFF;
+    background               : #333333;
+  }
+  p.lev2 {
+    background               : #555555;
+  }
+  p.lev3 {
+    background               : #777777;
+  }
+  p.lev4 {
+    background               : #AAAAAA;
+  }
+  p.lev5 {
+  }
+┃");
+string theme_light_1 = format(q"┃
+  h1 {
+    color                    : #FFFFFF;
+    background               : #1A3A7A;
+  }
+  p.letter {
+    color                    : #FFFFFF;
+    background               : #1A3A7A;
+  }
+  p.lev0 {
+    color                    : #FFFFFF;
+    background               : #000000;
+  }
+  p.lev1 {
+    color                    : #FFFFFF;
+    background               : #444444;
+  }
+  p.lev2 {
+    background               : #888888;
+  }
+  p.lev3 {
+    background               : #BBBBBB;
+  }
+  p.lev4 {
+    background               : #EEEEEE;
+  }
+  p.lev5 {
+  }
+┃");
+      topics ~= format(q"┃<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Curated metadata - Topics</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<meta name="dc.title" content= "metadata curate, 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="spine" />
+<link rel="generator" href="https://sisudoc.org" />
+<link href="./css/curate.css" rel="stylesheet">
+<style TYPE="text/css">
+/* spine curate css default stylesheet */%s
+  .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;
+  }
+  h0, h1, h2, h3, h4, h5, h6, h7 { text-shadow: .2em .2em .3em #999999; }
+  h1 {
+    font-size                : 120%%;
+    font-weight              : bold;
+    color                    : #FFFFFF;
+    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;
+  }
+  p.lev0 {
+    font-size                : 120%%;
+    margin-left              : 1em;
+  }
+  p.lev1 {
+    font-size                : 110%%;
+    margin-left              : 2em;
+  }
+  p.lev2 {
+    font-size                : 100%%;
+    margin-left              : 3em;
+  }
+  p.lev3 {
+    font-size                : 90%%;
+    margin-left              : 4em;
+  }
+  p.lev4 {
+    font-size                : 80%%;
+    margin-left              : 5em;
+  }
+  p.lev5 {
+    font-size                : 80%%;
+    margin-left              : 6em;
+  }%s
+  /* flex */
+  .flex-menu-bar {
+    display                  : -webkit-flex;
+    display                  : flex;
+    -webkit-flex-wrap        : wrap;
+    -webkit-align-items      : center;
+    align-items              : center;
+    width                    : 100%%;
+    margin-left              : 0%%;
+    margin-right             : 2%%;
+    background-color         : inherited;
+  }
+  .flex-menu-option {
+    background-color         : inherited;
+    margin-right             : 4px;
+  }
+  .flex-list {
+    display                  : -webkit-flex;
+    display                  : flex;
+    -webkit-align-items      : center;
+    display                  : block;
+    align-items              : center;
+    width                    : 100%%;
+    background-color         : inherited;
+  }
+  .flex-list-item {
+    background-color         : inherited;
+    margin                   : 4px;
+  }
+</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>Curated metadata - Topics (output organised by language &amp; filetype)</h1>
+<div class="flex-menu-bar">
+<div class="flex-menu-option">
+<p>[<a href="../../index.html">&nbsp;HOME&nbsp;</a>]
+ [<a href="authors.html">&nbsp;Curated&nbsp;metadata&nbsp;-&nbsp;Authors&nbsp;</a>]
+</p>
+</div>
+ %s
+</div>
+<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 />
+┃",
+  _opt_action.css_theme_default ? theme_light_0 : theme_dark_0,
+  _opt_action.css_theme_default ? theme_light_1 : theme_dark_1,
+  inline_search_form(_make_and_meta_struct),
+) ~ "\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" class="lev0">%s</a></p>┃",
+            k0.translate([' ' : "_"]), 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.translate([' ' : "_"]),
+                  t_a_.author,
+                );
+              } else {
+                foreach (a; t_a_.author_arr) {
+                  _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
+                    t_a_.author_surname.translate([' ' : "_"]),
+                    a,
+                  );
+                }
+              }
+              topics ~= format(q"┃<p class="work"><a href="%s">"%s"</a> - %s [<a href="%s">&nbsp;%s&nbsp;</a>]┃",
+                t_a_.path_html_segtoc,
+                t_a_.title,
+                _auth,
+                t_a_.path_html_metadata,
+                t_a_.language,
+              ) ~ "\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" class="lev1">%s</a></p>┃",
+                k0.translate([' ' : "_"]),
+                k1.translate([' ' : "_"]), 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.translate([' ' : "_"]),
+                      t_a_.author,
+                    );
+                  } else {
+                    foreach (a; t_a_.author_arr) {
+                      _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
+                        t_a_.author_surname.translate([' ' : "_"]),
+                        a,
+                      );
+                    }
+                  }
+                  topics ~= format(q"┃<p class="work"><a href="%s">%s</a> - %s [<a href="%s">&nbsp;%s&nbsp;</a>]┃",
+                    t_a_.path_html_segtoc,
+                    t_a_.title,
+                    _auth,
+                    t_a_.path_html_metadata,
+                    t_a_.language,
+                  ) ~ "\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.%s" class="lev2">%s</a></p>┃",
+                  k0.translate([' ' : "_"]), k1.translate([' ' : "_"]),
+                  k2.translate([' ' : "_"]), 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.translate([' ' : "_"]),
+                        t_a_.author,
+                      );
+                    } else {
+                      foreach (a; t_a_.author_arr) {
+                        _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
+                          t_a_.author_surname.translate([' ' : "_"]),
+                          a,
+                        );
+                      }
+                    }
+                    topics ~= format(q"┃<p class="work"><a href="%s">%s</a> - %s [<a href="%s">&nbsp;%s&nbsp;</a>]┃",
+                      t_a_.path_html_segtoc,
+                      t_a_.title,
+                      _auth,
+                      t_a_.path_html_metadata,
+                      t_a_.language,
+                    ) ~ "\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.%s.%s" class="lev3">%s</a></p>┃",
+                    k0.translate([' ' : "_"]), k1.translate([' ' : "_"]), k2.translate([' ' : "_"]),
+                    k3.translate([' ' : "_"]), 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.translate([' ' : "_"]),
+                          t_a_.author,
+                        );
+                      } else {
+                        foreach (a; t_a_.author_arr) {
+                          _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
+                            t_a_.author_surname.translate([' ' : "_"]),
+                            a,
+                          );
+                        }
+                      }
+                      topics ~= format(q"┃ <p class="work"><a href="%s">%s</a> - %s [<a href="%s">&nbsp;%s&nbsp;</a>]┃",
+                        t_a_.path_html_segtoc,
+                        t_a_.title,
+                        _auth,
+                        t_a_.path_html_metadata,
+                        t_a_.language,
+                      ) ~ "\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";
+    import doc_reform.io_out.paths_output;
+    auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
+    try {
+      auto f       = File(out_pth.curate("topics.html"), "w");
+      foreach (o; topics) {
+        f.writeln(o);
+      }
+    } catch (ErrnoException ex) {
+      // Handle error
+    }
+  }
+}
diff --git a/src/doc_reform/meta/metadoc_harvest.d b/src/doc_reform/meta/metadoc_harvest.d
deleted file mode 100644
index 3135323..0000000
--- a/src/doc_reform/meta/metadoc_harvest.d
+++ /dev/null
@@ -1,92 +0,0 @@
-/+
-- Name: Spine, Doc Reform [a part of]
-  - Description: documents, structuring, processing, publishing, search
-    - static content generator
-
-  - Author: Ralph Amissah
-    [ralph.amissah@gmail.com]
-
-  - Copyright: (C) 2015 - 2021 Ralph Amissah, All Rights
-    Reserved.
-
-  - License: AGPL 3 or later:
-
-    Spine (SiSU), a framework for document structuring, publishing and
-    search
-
-    Copyright (C) Ralph Amissah
-
-    This program is free software: you can redistribute it and/or modify it
-    under the terms of the GNU AFERO General Public License as published by the
-    Free Software Foundation, either version 3 of the License, or (at your
-    option) any later version.
-
-    This program is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-    more details.
-
-    You should have received a copy of the GNU General Public License along with
-    this program. If not, see [https://www.gnu.org/licenses/].
-
-    If you have Internet connection, the latest version of the AGPL should be
-    available at these locations:
-    [https://www.fsf.org/licensing/licenses/agpl.html]
-    [https://www.gnu.org/licenses/agpl.html]
-
-  - Spine (by Doc Reform, related to SiSU) uses standard:
-    - docReform markup syntax
-      - standard SiSU markup syntax with modified headers and minor modifications
-    - docReform object numbering
-      - standard SiSU object citation numbering & system
-
-  - Hompages:
-    [https://www.doc_reform.org]
-    [https://www.sisudoc.org]
-
-  - Git
-    [https://git.sisudoc.org/projects/?p=software/spine.git;a=summary]
-
-+/
-module doc_reform.meta.metadoc_harvest;
-template spineMetaDocHarvest() {
-  @safe auto spineMetaDocHarvest(T,H)(
-    T  doc_matters,
-    H  hvst,
-  ) {
-    import
-      doc_reform.meta.defaults,
-      doc_reform.meta.rgx;
-    import
-      std.array,
-      std.exception,
-      std.regex,
-      std.stdio,
-      std.string,
-      std.typecons,
-      std.uni,
-      std.utf,
-      std.conv : to;
-    mixin InternalMarkup;
-    static auto mkup = InlineMarkup();
-    import doc_reform.io_out.paths_output;
-    auto pth_html_abs                  = spinePathsHTML!()(doc_matters.output_path, doc_matters.src.language);
-    auto pth_html_rel                  = spineDocRootTreeHTML!()(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_metadata    = pth_html_rel.fn_metadata(doc_matters.src.filename);
-    hvst.harvest.path_html_scroll      = pth_html_rel.fn_scroll(doc_matters.src.filename);
-    hvst.harvest.path_html_segtoc      = pth_html_rel.fn_seg(doc_matters.src.filename, "toc");
-    hvst.harvest.path_abs_html_scroll  = pth_html_abs.fn_scroll(doc_matters.src.filename);
-    hvst.harvest.path_abs_html_segtoc  = pth_html_abs.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
deleted file mode 100644
index 182b1cd..0000000
--- a/src/doc_reform/meta/metadoc_harvests_authors.d
+++ /dev/null
@@ -1,494 +0,0 @@
-/+
-- Name: Spine, Doc Reform [a part of]
-  - Description: documents, structuring, processing, publishing, search
-    - static content generator
-
-  - Author: Ralph Amissah
-    [ralph.amissah@gmail.com]
-
-  - Copyright: (C) 2015 - 2021 Ralph Amissah, All Rights
-    Reserved.
-
-  - License: AGPL 3 or later:
-
-    Spine (SiSU), a framework for document structuring, publishing and
-    search
-
-    Copyright (C) Ralph Amissah
-
-    This program is free software: you can redistribute it and/or modify it
-    under the terms of the GNU AFERO General Public License as published by the
-    Free Software Foundation, either version 3 of the License, or (at your
-    option) any later version.
-
-    This program is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-    more details.
-
-    You should have received a copy of the GNU General Public License along with
-    this program. If not, see [https://www.gnu.org/licenses/].
-
-    If you have Internet connection, the latest version of the AGPL should be
-    available at these locations:
-    [https://www.fsf.org/licensing/licenses/agpl.html]
-    [https://www.gnu.org/licenses/agpl.html]
-
-  - Spine (by Doc Reform, related to SiSU) uses standard:
-    - docReform markup syntax
-      - standard SiSU markup syntax with modified headers and minor modifications
-    - docReform object numbering
-      - standard SiSU object citation numbering & system
-
-  - Hompages:
-    [https://www.doc_reform.org]
-    [https://www.sisudoc.org]
-
-  - Git
-    [https://git.sisudoc.org/projects/?p=software/spine.git;a=summary]
-
-+/
-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 spineHarvest;
-  mixin InternalMarkup;
-template spineMetaDocHarvestsAuthors() {
-  static auto mkup = InlineMarkup();
-  void spineMetaDocHarvestsAuthors(H,M,O)(
-    H  harvests,
-    M  _make_and_meta_struct,
-    O  _opt_action,
-  ) {
-      @safe string inline_search_form(M)(
-        M  _make_and_meta_truct,
-      ) {
-        string o;
-        string _form;
-        if (_opt_action.html_search_link) {
-          o = format(q"┃
-      <div class="flex-menu-option">
-      <!-- SiSU Spine Search -->
-      <form action="%s" target="_top" method="POST" accept-charset="UTF-8" id="search">
-      <font size="2">
-      <input type="text" name="sf" size="24" maxlength="255">%s
-      <input type="hidden" name="sml" value="1000">
-      <input type="hidden" name="ec" value="on">
-      <input type="hidden" name="url" value="on">
-      <button type="submit" form="search">db</button>
-      </font></form>
-      <!-- SiSU Spine Search -->
-      </div>┃",
-          _make_and_meta_struct.conf.w_srv_cgi_action,
-          (_make_and_meta_struct.conf.w_srv_db_sqlite_filename.empty)
-            ? ""
-            : "\n    <input type=\"hidden\" name=\"db\" value=\""
-              ~ _make_and_meta_struct.conf.w_srv_db_sqlite_filename
-              ~ "\">",
-          );
-        } else {
-          o = "";
-        }
-        return o;
-      }
-string theme_dark_0 = format(q"┃
-  body {
-    color                    : #CCCCCC;
-    background               : #000000;
-    background-color         : #000000;
-  }
-  a:link {
-    color                    : #FFFFFF;
-    text-decoration          : none;
-  }
-  a:visited {
-    color                    : #999999;
-    text-decoration          : none;
-  }
-  a:hover {
-    color                    : #000000;
-    background-color         : #555555;
-  }
-  a:hover img {
-    background-color         : #000000;
-  }
-  a:active {
-    color                    : #888888;
-    text-decoration          : underline;
-  }
-  a.lev0:hover {
-    color                    : #FFFFFF;
-    background-color         : #000000;
-  }
-  a.lev1:hover {
-    color                    : #FFFFFF;
-    background               : #333333;
-  }
-  a.lev2:hover {
-    color                    : #FFFFFF;
-    background               : #555555;
-  }
-  a.lev3:hover {
-    color                    : #FFFFFF;
-    background               : #777777;
-  }
-  input {
-    color                    : #FFFFFF;
-    background-color         : #777777;
-  }
-┃");
-string theme_light_0 = format(q"┃
-  body {
-    color                    : #000000;
-    background               : #FFFFFF;
-    background-color         : #FFFFFF;
-  }
-  a:link {
-    color                    : #003399;
-    text-decoration          : none;
-  }
-  a:visited {
-    color                    : #003399;
-    text-decoration          : none;
-  }
-  a:hover {
-    color                    : #000000;
-    background-color         : #f9f9aa;
-  }
-  a:hover img {
-    background-color         : #FFFFFF;
-  }
-  a:active {
-    color                    : #003399;
-    text-decoration          : underline;
-  }
-  a.lev0:hover {
-    color                    : #000000;
-    background-color         : #FFFFFF;
-  }
-  a.lev1:hover {
-    color                    : #FFFFFF;
-    background               : #444444;
-  }
-  a.lev2:hover {
-    background               : #888888;
-  }
-  a.lev3:hover {
-    background               : #BBBBBB;
-  }
-  input {
-    color                    : #000000;
-    background-color         : #FFFFFF;
-  }
-┃");
-string theme_dark_1 = format(q"┃
-  h1 {
-    color                    : #FFFFFF;
-    background               : #000000;
-  }
-  p.letter {
-    color                    : #FFFFFF;
-    background               : #333333;
-  }
-  p.lev0 {
-    color                    : #FFFFFF;
-    background               : #000000;
-  }
-  p.lev1 {
-    color                    : #FFFFFF;
-    background               : #333333;
-  }
-  p.lev2 {
-    background               : #555555;
-  }
-  p.lev3 {
-    background               : #777777;
-  }
-  p.lev4 {
-    background               : #AAAAAA;
-  }
-  p.lev5 {
-  }
-┃");
-string theme_light_1 = format(q"┃
-  h1 {
-    color                    : #FFFFFF;
-    background               : #000088;
-  }
-  p.letter {
-    color                    : #FFFFFF;
-    background               : #880000;
-  }
-  p.lev0 {
-    color                    : #FFFFFF;
-    background               : #000000;
-  }
-  p.lev1 {
-    color                    : #FFFFFF;
-    background               : #444444;
-  }
-  p.lev2 {
-    background               : #888888;
-  }
-  p.lev3 {
-    background               : #BBBBBB;
-  }
-  p.lev4 {
-    background               : #EEEEEE;
-  }
-  p.lev5 {
-  }
-┃");
-      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="spine" />
-<link rel="generator" href="https://sisudoc.org" />
-<link href="./css/harvest.css" rel="stylesheet">
-<style TYPE="text/css">
-/* spine harvest css default stylesheet */%s
-  .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;
-  }
-  h0, h1, h2, h3, h4, h5, h6, h7 { text-shadow: .2em .2em .3em #999999; }
-  h1 {
-    font-size                : 120%%;
-    font-weight              : bold;
-    color                    : #FFFFFF;
-    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;
-  }
-  p.lev0 {
-    font-size                : 120%%;
-    margin-left              : 1em;
-  }
-  p.lev1 {
-    font-size                : 110%%;
-    margin-left              : 2em;
-  }
-  p.lev2 {
-    font-size                : 100%%;
-    margin-left              : 3em;
-  }
-  p.lev3 {
-    font-size                : 90%%;
-    margin-left              : 4em;
-  }
-  p.lev4 {
-    font-size                : 80%%;
-    margin-left              : 5em;
-  }
-  p.lev5 {
-    font-size                : 80%%;
-    margin-left              : 6em;
-  }%s
-  /* flex */
-  .flex-menu-bar {
-    display                  : -webkit-flex;
-    display                  : flex;
-    -webkit-flex-wrap        : wrap;
-    -webkit-align-items      : center;
-    align-items              : center;
-    width                    : 100%%;
-    margin-left              : 0%%;
-    margin-right             : 2%%;
-    background-color         : inherited;
-  }
-  .flex-menu-option {
-    background-color         : inherited;
-    margin-right             : 4px;
-  }
-  .flex-list {
-    display                  : -webkit-flex;
-    display                  : flex;
-    -webkit-align-items      : center;
-    display                  : block;
-    align-items              : center;
-    width                    : 100%%;
-    background-color         : inherited;
-  }
-  .flex-list-item {
-    background-color         : inherited;
-    margin                   : 4px;
-  }
-</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>
-<div class="flex-menu-bar">
-<div class="flex-menu-option">
-<p>[<a href="../../index.html">&nbsp;HOME&nbsp;</a>]
- [<a href="topics.html">&nbsp;Metadata&nbsp;Harvest&nbsp;-&nbsp;Topics&nbsp;</a>]
-</p>
-</div>
-%s
-</div>
-<p></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;
-┃",
-  _opt_action.css_theme_default ? theme_light_0 : theme_dark_0,
-  _opt_action.css_theme_default ? theme_light_1 : theme_dark_1,
-  inline_search_form(_make_and_meta_struct),
-) ~ "\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" class="lev0">%s</a></p> <p class="publication">%s "<a href="%s">%s</a>" [<a href="%s">&nbsp;%s&nbsp;</a>]</p>┃",
-            doc_harvest.author_surname.translate([' ' : "_"]),
-            doc_harvest.author_surname_fn,
-            (doc_harvest.date_published.length > 0)
-              ? doc_harvest.date_published : "",
-            doc_harvest.path_html_segtoc,
-            doc_harvest.title,
-            doc_harvest.path_html_metadata,
-            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>" [<a href="%s">&nbsp;%s&nbsp;</a>]</p>┃",
-            (doc_harvest.date_published.length > 0)
-              ? doc_harvest.date_published : "",
-            doc_harvest.path_html_segtoc,
-            doc_harvest.title,
-            doc_harvest.path_html_metadata,
-            doc_harvest.language,
-          );
-        }
-        _author_date_title ~= format(q"┃%s %s "%s" [<a href="%s">&nbsp;%s&nbsp;</a>]%s┃",
-          doc_harvest.author_surname_fn,
-          (doc_harvest.date_published.length > 0)
-            ? "(" ~ doc_harvest.date_published ~ ")" : "",
-          doc_harvest.title,
-          doc_harvest.path_html_metadata,
-          doc_harvest.language,
-          (_opt_action.very_verbose) ? "\n  " ~ doc_harvest.path_abs_html_scroll : "",
-        );
-      }
-      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";
-    import doc_reform.io_out.paths_output;
-    auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
-    try {
-      auto f       = File(out_pth.harvest("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
deleted file mode 100644
index 5848723..0000000
--- a/src/doc_reform/meta/metadoc_harvests_topics.d
+++ /dev/null
@@ -1,654 +0,0 @@
-/+
-- Name: Spine, Doc Reform [a part of]
-  - Description: documents, structuring, processing, publishing, search
-    - static content generator
-
-  - Author: Ralph Amissah
-    [ralph.amissah@gmail.com]
-
-  - Copyright: (C) 2015 - 2021 Ralph Amissah, All Rights
-    Reserved.
-
-  - License: AGPL 3 or later:
-
-    Spine (SiSU), a framework for document structuring, publishing and
-    search
-
-    Copyright (C) Ralph Amissah
-
-    This program is free software: you can redistribute it and/or modify it
-    under the terms of the GNU AFERO General Public License as published by the
-    Free Software Foundation, either version 3 of the License, or (at your
-    option) any later version.
-
-    This program is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-    more details.
-
-    You should have received a copy of the GNU General Public License along with
-    this program. If not, see [https://www.gnu.org/licenses/].
-
-    If you have Internet connection, the latest version of the AGPL should be
-    available at these locations:
-    [https://www.fsf.org/licensing/licenses/agpl.html]
-    [https://www.gnu.org/licenses/agpl.html]
-
-  - Spine (by Doc Reform, related to SiSU) uses standard:
-    - docReform markup syntax
-      - standard SiSU markup syntax with modified headers and minor modifications
-    - docReform object numbering
-      - standard SiSU object citation numbering & system
-
-  - Hompages:
-    [https://www.doc_reform.org]
-    [https://www.sisudoc.org]
-
-  - Git
-    [https://git.sisudoc.org/projects/?p=software/spine.git;a=summary]
-
-+/
-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 spineHarvest;
-  mixin InternalMarkup;
-template spineMetaDocHarvestsTopics() {
-  static auto mkup = InlineMarkup();
-  void spineMetaDocHarvestsTopics(H,M,O)(
-    H  hvst,
-    M  _make_and_meta_struct,
-    O  _opt_action,
-  ) {
-      @safe string inline_search_form(M)(
-        M  _make_and_meta_truct,
-      ) {
-        string o;
-        string _form;
-        if (_opt_action.html_search_link) {
-          o = format(q"┃
-      <div class="flex-menu-option">
-      <!-- SiSU Spine Search -->
-      <form action="%s" target="_top" method="POST" accept-charset="UTF-8" id="search">
-      <font size="2">
-      <input type="text" name="sf" size="24" maxlength="255">%s
-      <input type="hidden" name="sml" value="1000">
-      <input type="hidden" name="ec" value="on">
-      <input type="hidden" name="url" value="on">
-      <button type="submit" form="search">db</button>
-      </font></form>
-      <!-- SiSU Spine Search -->
-      </div>┃",
-          _make_and_meta_struct.conf.w_srv_cgi_action,
-          (_make_and_meta_struct.conf.w_srv_db_sqlite_filename.empty)
-            ? ""
-            : "\n    <input type=\"hidden\" name=\"db\" value=\""
-              ~ _make_and_meta_struct.conf.w_srv_db_sqlite_filename
-              ~ "\">",
-          );
-        } else {
-          o = "";
-        }
-        return o;
-      }
-      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"),
-        );
-      }
-string theme_dark_0 = format(q"┃
-  body {
-    color                    : #CCCCCC;
-    background               : #000000;
-    background-color         : #000000;
-  }
-  a:link {
-    color                    : #FFFFFF;
-    text-decoration          : none;
-  }
-  a:visited {
-    color                    : #999999;
-    text-decoration          : none;
-  }
-  a:hover {
-    color                    : #000000;
-    background-color         : #555555;
-  }
-  a:hover img {
-    background-color         : #000000;
-  }
-  a:active {
-    color                    : #888888;
-    text-decoration          : underline;
-  }
-  a.lev0:hover {
-    color                    : #FFFFFF;
-    background-color         : #000000;
-  }
-  a.lev1:hover {
-    color                    : #FFFFFF;
-    background               : #333333;
-  }
-  a.lev2:hover {
-    color                    : #FFFFFF;
-    background               : #555555;
-  }
-  a.lev3:hover {
-    color                    : #FFFFFF;
-    background               : #777777;
-  }
-  input {
-    color                    : #FFFFFF;
-    background-color         : #777777;
-  }
-┃");
-string theme_light_0 = format(q"┃
-  body {
-    color                    : #000000;
-    background               : #FFFFFF;
-    background-color         : #FFFFFF;
-  }
-  a:link {
-    color                    : #003399;
-    text-decoration          : none;
-  }
-  a:visited {
-    color                    : #003399;
-    text-decoration          : none;
-  }
-  a:hover {
-    color                    : #000000;
-    background-color         : #f9f9aa;
-  }
-  a:hover img {
-    background-color         : #FFFFFF;
-  }
-  a:active {
-    color                    : #003399;
-    text-decoration          : underline;
-  }
-  a.lev0:hover {
-    color                    : #000000;
-    background-color         : #FFFFFF;
-  }
-  a.lev1:hover {
-    color                    : #FFFFFF;
-    background               : #444444;
-  }
-  a.lev2:hover {
-    background               : #888888;
-  }
-  a.lev3:hover {
-    background               : #BBBBBB;
-  }
-  input {
-    color                    : #000000;
-    background-color         : #FFFFFF;
-  }
-┃");
-string theme_dark_1 = format(q"┃
-  h1 {
-    color                    : #FFFFFF;
-    background               : #000000;
-  }
-  p.letter {
-    color                    : #FFFFFF;
-    background               : #333333;
-  }
-  p.lev0 {
-    color                    : #FFFFFF;
-    background               : #000000;
-  }
-  p.lev1 {
-    color                    : #FFFFFF;
-    background               : #333333;
-  }
-  p.lev2 {
-    background               : #555555;
-  }
-  p.lev3 {
-    background               : #777777;
-  }
-  p.lev4 {
-    background               : #AAAAAA;
-  }
-  p.lev5 {
-  }
-┃");
-string theme_light_1 = format(q"┃
-  h1 {
-    color                    : #FFFFFF;
-    background               : #000088;
-  }
-  p.letter {
-    color                    : #FFFFFF;
-    background               : #880000;
-  }
-  p.lev0 {
-    color                    : #FFFFFF;
-    background               : #000000;
-  }
-  p.lev1 {
-    color                    : #FFFFFF;
-    background               : #444444;
-  }
-  p.lev2 {
-    background               : #888888;
-  }
-  p.lev3 {
-    background               : #BBBBBB;
-  }
-  p.lev4 {
-    background               : #EEEEEE;
-  }
-  p.lev5 {
-  }
-┃");
-      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="spine" />
-<link rel="generator" href="https://sisudoc.org" />
-<link href="./css/harvest.css" rel="stylesheet">
-<style TYPE="text/css">
-/* spine harvest css default stylesheet */%s
-  .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;
-  }
-  h0, h1, h2, h3, h4, h5, h6, h7 { text-shadow: .2em .2em .3em #999999; }
-  h1 {
-    font-size                : 120%%;
-    font-weight              : bold;
-    color                    : #FFFFFF;
-    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;
-  }
-  p.lev0 {
-    font-size                : 120%%;
-    margin-left              : 1em;
-  }
-  p.lev1 {
-    font-size                : 110%%;
-    margin-left              : 2em;
-  }
-  p.lev2 {
-    font-size                : 100%%;
-    margin-left              : 3em;
-  }
-  p.lev3 {
-    font-size                : 90%%;
-    margin-left              : 4em;
-  }
-  p.lev4 {
-    font-size                : 80%%;
-    margin-left              : 5em;
-  }
-  p.lev5 {
-    font-size                : 80%%;
-    margin-left              : 6em;
-  }%s
-  /* flex */
-  .flex-menu-bar {
-    display                  : -webkit-flex;
-    display                  : flex;
-    -webkit-flex-wrap        : wrap;
-    -webkit-align-items      : center;
-    align-items              : center;
-    width                    : 100%%;
-    margin-left              : 0%%;
-    margin-right             : 2%%;
-    background-color         : inherited;
-  }
-  .flex-menu-option {
-    background-color         : inherited;
-    margin-right             : 4px;
-  }
-  .flex-list {
-    display                  : -webkit-flex;
-    display                  : flex;
-    -webkit-align-items      : center;
-    display                  : block;
-    align-items              : center;
-    width                    : 100%%;
-    background-color         : inherited;
-  }
-  .flex-list-item {
-    background-color         : inherited;
-    margin                   : 4px;
-  }
-</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>
-<div class="flex-menu-bar">
-<div class="flex-menu-option">
-<p>[<a href="../../index.html">&nbsp;HOME&nbsp;</a>]
- [<a href="authors.html">&nbsp;Metadata&nbsp;Harvest&nbsp;-&nbsp;Authors&nbsp;</a>]
-</p>
-</div>
- %s
-</div>
-<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 />
-┃",
-  _opt_action.css_theme_default ? theme_light_0 : theme_dark_0,
-  _opt_action.css_theme_default ? theme_light_1 : theme_dark_1,
-  inline_search_form(_make_and_meta_struct),
-) ~ "\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" class="lev0">%s</a></p>┃",
-            k0.translate([' ' : "_"]), 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.translate([' ' : "_"]),
-                  t_a_.author,
-                );
-              } else {
-                foreach (a; t_a_.author_arr) {
-                  _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
-                    t_a_.author_surname.translate([' ' : "_"]),
-                    a,
-                  );
-                }
-              }
-              topics ~= format(q"┃<p class="work"><a href="%s">"%s"</a> - %s [<a href="%s">&nbsp;%s&nbsp;</a>]┃",
-                t_a_.path_html_segtoc,
-                t_a_.title,
-                _auth,
-                t_a_.path_html_metadata,
-                t_a_.language,
-              ) ~ "\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" class="lev1">%s</a></p>┃",
-                k0.translate([' ' : "_"]),
-                k1.translate([' ' : "_"]), 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.translate([' ' : "_"]),
-                      t_a_.author,
-                    );
-                  } else {
-                    foreach (a; t_a_.author_arr) {
-                      _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
-                        t_a_.author_surname.translate([' ' : "_"]),
-                        a,
-                      );
-                    }
-                  }
-                  topics ~= format(q"┃<p class="work"><a href="%s">%s</a> - %s [<a href="%s">&nbsp;%s&nbsp;</a>]┃",
-                    t_a_.path_html_segtoc,
-                    t_a_.title,
-                    _auth,
-                    t_a_.path_html_metadata,
-                    t_a_.language,
-                  ) ~ "\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.%s" class="lev2">%s</a></p>┃",
-                  k0.translate([' ' : "_"]), k1.translate([' ' : "_"]),
-                  k2.translate([' ' : "_"]), 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.translate([' ' : "_"]),
-                        t_a_.author,
-                      );
-                    } else {
-                      foreach (a; t_a_.author_arr) {
-                        _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
-                          t_a_.author_surname.translate([' ' : "_"]),
-                          a,
-                        );
-                      }
-                    }
-                    topics ~= format(q"┃<p class="work"><a href="%s">%s</a> - %s [<a href="%s">&nbsp;%s&nbsp;</a>]┃",
-                      t_a_.path_html_segtoc,
-                      t_a_.title,
-                      _auth,
-                      t_a_.path_html_metadata,
-                      t_a_.language,
-                    ) ~ "\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.%s.%s" class="lev3">%s</a></p>┃",
-                    k0.translate([' ' : "_"]), k1.translate([' ' : "_"]), k2.translate([' ' : "_"]),
-                    k3.translate([' ' : "_"]), 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.translate([' ' : "_"]),
-                          t_a_.author,
-                        );
-                      } else {
-                        foreach (a; t_a_.author_arr) {
-                          _auth ~= format(q"┃ <a href="authors.html#%s">%s</a>,┃",
-                            t_a_.author_surname.translate([' ' : "_"]),
-                            a,
-                          );
-                        }
-                      }
-                      topics ~= format(q"┃ <p class="work"><a href="%s">%s</a> - %s [<a href="%s">&nbsp;%s&nbsp;</a>]┃",
-                        t_a_.path_html_segtoc,
-                        t_a_.title,
-                        _auth,
-                        t_a_.path_html_metadata,
-                        t_a_.language,
-                      ) ~ "\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";
-    import doc_reform.io_out.paths_output;
-    auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
-    try {
-      auto f       = File(out_pth.harvest("topics.html"), "w");
-      foreach (o; topics) {
-        f.writeln(o);
-      }
-    } catch (ErrnoException ex) {
-      // Handle error
-    }
-  }
-}
diff --git a/src/doc_reform/spine.d b/src/doc_reform/spine.d
index 752d3ee..0893572 100755
--- a/src/doc_reform/spine.d
+++ b/src/doc_reform/spine.d
@@ -66,9 +66,9 @@ import
   doc_reform.conf.compile_time_info,
   doc_reform.meta,
   doc_reform.meta.metadoc,
-  doc_reform.meta.metadoc_harvest,
-  doc_reform.meta.metadoc_harvests_authors,
-  doc_reform.meta.metadoc_harvests_topics,
+  doc_reform.meta.metadoc_curate,
+  doc_reform.meta.metadoc_curate_authors,
+  doc_reform.meta.metadoc_curate_topics,
   doc_reform.meta.metadoc_from_src,
   doc_reform.meta.conf_make_meta_structs,
   doc_reform.meta.conf_make_meta_json,
@@ -88,7 +88,7 @@ string program_name = "spine";
   mixin spineRgxIn;
   mixin spineBiblio;
   mixin outputHub;
-  auto hvst = spineHarvest!();
+  auto hvst = spineCurateMetadata!();
   string flag_action;
   string arg_unrecognized;
   enum dAM { abstraction, matters }
@@ -119,11 +119,11 @@ string program_name = "spine";
     "debug"                       : false,
     "digest"                      : false,
     "epub"                        : false,
-    "harvest"                     : false,
-    "harvest-authors"             : false,
-    "harvest-topics"              : false,
+    "curate"                     : false,
+    "curate-authors"             : false,
+    "curate-topics"              : false,
     "html"                        : false,
-    "html-link-harvest"           : false,
+    "html-link-curate"           : false,
     "html-link-search"            : false,
     "html-seg"                    : false,
     "html-scroll"                 : false,
@@ -202,16 +202,16 @@ string program_name = "spine";
     "cgi-url-action",             "url to post to cgi-bin search form",                             &settings["cgi-url-action"],
     "cgi-search-title",           "title for cgi-bin search form",                                  &settings["cgi-search-title"],
     "concordance",                "file for document",                                              &opts["concordance"],
+    "curate",                    "extract info on authors & topics from document header metadata",  &opts["curate"],
+    "curate-authors",            "extract info on authors from document header metadata",           &opts["curate-authors"],
+    "curate-topics",             "extract info on topics from document header metadata",            &opts["curate-topics"],
     "dark",                       "alternative dark theme",                                         &opts["dark"],
     "debug",                      "debug",                                                          &opts["debug"],
     "digest",                     "hash digest for each object",                                    &opts["digest"],
     "epub",                       "process epub output",                                            &opts["epub"],
-    "harvest",                    "extract info on authors & topics from document header metadata", &opts["harvest"],
-    "harvest-authors",            "extract info on authors from document header metadata",          &opts["harvest-authors"],
-    "harvest-topics",             "extract info on topics from document header metadata",           &opts["harvest-topics"],
     "hide-ocn",                   "object cite numbers",                                            &opts["hide-ocn"],
     "html",                       "process html output",                                            &opts["html"],
-    "html-link-harvest",          "place links back to harvest in segmented html",                  &opts["html-link-harvest"],
+    "html-link-curate",           "place links back to curate in segmented html",                   &opts["html-link-curate"],
     "html-link-search",           "html embedded search submission",                                &opts["html-link-search"],
     "html-seg",                   "process html output",                                            &opts["html-seg"],
     "html-scroll",                "process html output",                                            &opts["html-scroll"],
@@ -314,20 +314,20 @@ string program_name = "spine";
     @trusted bool epub() {
       return opts["epub"];
     }
-    @trusted bool html_harvest_link() {
-      return (opts["html-link-harvest"]) ? true : false;
+    @trusted bool html_curate_link() {
+      return (opts["html-link-curate"]) ? true : false;
     }
     @trusted bool html_search_link() {
       return (opts["html-link-search"]) ? true : false;
     }
-    @trusted bool harvest() {
-      return (opts["harvest"] || opts["harvest-authors"] || opts["harvest-topics"]) ? true : false;
+    @trusted bool curate() {
+      return (opts["curate"] || opts["curate-authors"] || opts["curate-topics"]) ? true : false;
     }
-    @trusted bool harvest_authors() {
-      return (opts["harvest"] || opts["harvest-authors"]) ? true : false;
+    @trusted bool curate_authors() {
+      return (opts["curate"] || opts["curate-authors"]) ? true : false;
     }
-    @trusted bool harvest_topics() {
-      return (opts["harvest"] || opts["harvest-topics"]) ? true : false;
+    @trusted bool curate_topics() {
+      return (opts["curate"] || opts["curate-topics"]) ? true : false;
     }
     @trusted bool html() {
       return (opts["html"] || opts["html-seg"] || opts["html-scroll"]) ? true : false;
@@ -520,7 +520,7 @@ string program_name = "spine";
       } else if (
         opts["abstraction"]
         || concordance
-        || harvest
+        || curate
         || html
         || epub
         || odt
@@ -569,7 +569,7 @@ string program_name = "spine";
         opts["abstraction"]
         || concordance
         || source_or_pod
-        || harvest
+        || curate
         || html
         || epub
         || odt
@@ -584,7 +584,7 @@ string program_name = "spine";
       return (
         opts["abstraction"]
         || epub
-        || harvest
+        || curate
         || html
         || html_seg
         || html_scroll
@@ -604,7 +604,7 @@ string program_name = "spine";
     @trusted bool meta_processing_general() {
       return (
         opts["abstraction"]
-        || harvest
+        || curate
         || html
         || epub
         || odt
@@ -921,18 +921,18 @@ string program_name = "spine";
             import doc_reform.meta.metadoc_show_config;
             spineShowConfig!()(doc_matters);
           }
-          if (doc_matters.opt.action.harvest) {
-            auto _hvst = spineMetaDocHarvest!()(doc_matters, hvst);
+          if (doc_matters.opt.action.curate) {
+            auto _hvst = spineMetaDocCurate!()(doc_matters, hvst);
             if (
               _hvst.title.length > 0
               && _hvst.author_surname_fn.length > 0
             ) {
-              hvst.harvests ~= _hvst;
+              hvst.curates ~= _hvst;
             } else {
               if ((doc_matters.opt.action.debug_do)
               || (doc_matters.opt.action.very_verbose)
               ) {
-                writeln("WARNING harvest: document header yaml does not contain information related to: title or author: ", _hvst.path_html_segtoc);
+                writeln("WARNING curate: document header yaml does not contain information related to: title or author: ", _hvst.path_html_segtoc);
               }
             }
           }
@@ -1035,18 +1035,18 @@ string program_name = "spine";
             import doc_reform.meta.metadoc_show_config;
             spineShowConfig!()(doc_matters);
           }
-          if (doc_matters.opt.action.harvest) {
-            auto _hvst = spineMetaDocHarvest!()(doc_matters, hvst);
+          if (doc_matters.opt.action.curate) {
+            auto _hvst = spineMetaDocCurate!()(doc_matters, hvst);
             if (
               _hvst.title.length > 0
               && _hvst.author_surname_fn.length > 0
             ) {
-              hvst.harvests ~= _hvst;
+              hvst.curates ~= _hvst;
             } else {
               if ((doc_matters.opt.action.debug_do)
               || (doc_matters.opt.action.very_verbose)
               ) {
-                writeln("WARNING harvest: document header yaml does not contain information related to: title or author: ", _hvst.path_html_segtoc);
+                writeln("WARNING curate: document header yaml does not contain information related to: title or author: ", _hvst.path_html_segtoc);
               }
             }
           }
@@ -1086,21 +1086,21 @@ string program_name = "spine";
       }
     }
   }
-  if (hvst.harvests.length > 0) {
-    if (_opt_action.harvest_topics) {
-      spineMetaDocHarvestsTopics!()(hvst, _make_and_meta_struct, _opt_action);
+  if (hvst.curates.length > 0) {
+    if (_opt_action.curate_topics) {
+      spineMetaDocCuratesTopics!()(hvst, _make_and_meta_struct, _opt_action);
     }
-    if (_opt_action.harvest_authors) {
-      spineMetaDocHarvestsAuthors!()(hvst.harvests, _make_and_meta_struct, _opt_action);
+    if (_opt_action.curate_authors) {
+      spineMetaDocCuratesAuthors!()(hvst.curates, _make_and_meta_struct, _opt_action);
     }
     if (!(_opt_action.quiet)) {
       import doc_reform.io_out.paths_output;
       auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, "");
-      if (_opt_action.harvest_authors) {
-        writeln("- ", out_pth.harvest("authors.html"));
+      if (_opt_action.curate_authors) {
+        writeln("- ", out_pth.curate("authors.html"));
       }
-      if (_opt_action.harvest_topics) {
-        writeln("- ", out_pth.harvest("topics.html"));
+      if (_opt_action.curate_topics) {
+        writeln("- ", out_pth.curate("topics.html"));
       }
     }
   } else { writeln("NO HARVESTS"); }
-- 
cgit v1.2.3