#+TITLE: sdp hub
#+AUTHOR: Ralph Amissah
#+EMAIL: ralph.amissah@gmail.com
#+STARTUP: indent
#+LANGUAGE: en
#+OPTIONS: H:3 num:nil toc:t \n:nil @:t ::t |:t ^:nil _:nil -:t f:t *:t <:t
#+OPTIONS: TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc
#+OPTIONS: author:nil email:nil creator:nil timestamp:nil
#+PROPERTY: header-args :padline no :exports code :noweb yes
#+EXPORT_SELECT_TAGS: export
#+EXPORT_EXCLUDE_TAGS: noexport
#+FILETAGS: :sdp:rel:hub:
#+TAGS: assert(a) class(c) debug(d) mixin(m) sdp(s) tangle(T) template(t) WEB(W) noexport(n)

[[../maker.org][maker.org makefile]]  [[./][org/]]

* sdp.d   sisu document parser                                       :sdp.d:
Deal with imports.
Take command line instructions and process files as instructed.

** TODO version.txt: set version                                    :version:

#+NAME: version_txt
#+BEGIN_SRC d
struct Version {
  int major;
  int minor;
  int patch;
}
enum ver = Version(1, 0, 0);
#+END_SRC

** pre loop init
*** imports                                                          :import:
[[./compile_time_info.org][compile time info]]
[[./ao_abstract_doc_source.org][ao_abstract_doc_source]]
[[./ao_ansi_colors.org][ao_ansi_colors]]
[[./ao_defaults.org][ao_defaults]]
[[./ao_output_debugs.org][ao_output_debugs]]
[[./ao_read_source_files.org][ao_read_source_files]]

**** std                                                         :import:std:
#+NAME: sdp_imports
#+BEGIN_SRC d
/+ sdp  sisu document parser +/
private import
  std.getopt,
  std.process,
  std.stdio,
  std.algorithm,
  std.array,
  std.container,
  std.exception,
  std.json,
  // std.path,
  std.range,
  std.regex,
  // std.stdio,
  std.string,
  std.traits,
  std.typecons,
  std.utf,
  // std.variant,
  std.conv : to;
#+END_SRC

**** sdp                                                      :import:sdp:
***** TODO src/sdp.d

├── src
│   ├── sdp.d
│   └── sdp
│       ├── ao_abstract_doc_source.d
│       ├── ...
│       └── compile_time_info.d
└── views
    └── version.txt

#+NAME: sdp_imports_use
#+BEGIN_SRC d
/+ sdp  sisu document parser +/
import
  compile_time_info,            // compile_time_info.d
  ao_abstract_doc_source,       // ao_abstract_doc_source.d
  ao_defaults,                  // ao_defaults.d
  ao_read_source_files,         // ao_read_source_files.d
  ao_output_debugs,             // ao_output_debugs.d
  ao_rgx,                       // ao_rgx.d
  ao_ansi_colors;               // ao_ansi_colors.d
  // std.conv;
#+END_SRC

**** version.txt                                                 :version:

#+NAME: sdp_version_mixin
#+BEGIN_SRC d
mixin(import("version.txt"));
#+END_SRC

*** mixin                                                             :mixin:

#+NAME: sdp_args
#+BEGIN_SRC d
mixin SiSUheader;
mixin SiSUbiblio;
mixin SiSUrgxInitFlags;
mixin SiSUmarkupRaw;
mixin SiSUdocAbstraction;
mixin SiSUoutputDebugs;
mixin ScreenTxtColors;
#+END_SRC

*** init                                                               :init:

#+NAME: sdp_args
#+BEGIN_SRC d
auto raw = MarkupRaw();
auto abs = Abstraction();
auto dbg = SDPoutputDebugs();
/+
struct DocumentParts {
  string[string][] contents;
  JSONValue[string] metadata_json;
  JSONValue[string] make_json;
  string[][string][string] bookindex_unordered_hashes;
  JSONValue[] biblio;
}
+/
string[] fns_src;
string flag_action;
string arg_unrecognized;
auto rgx = Rgx();
#+END_SRC

*** scope                                                             :scope:

#+NAME: sdp_args
#+BEGIN_SRC d
scope(success) {
  debug(checkdoc) {
    writefln(
      "%s~ run complete, ok ~ %s (sdp-%s.%s.%s, %s v%s, %s %s)",
      scr_txt_color["cyan"], scr_txt_color["off"],
      ver.major, ver.minor, ver.patch,
      __VENDOR__, __VERSION__,
      bits, os,
    );
  }
  // stderr.writeln("0");
}
scope(failure) {
  debug(checkdoc) {
    stderr.writefln(
      "%s~ run failure ~%s",
       scr_txt_color["fuchsia"], scr_txt_color["off"],
    );
  }
}
#+END_SRC

*** getopt args for loop                                        :args:getopt:

look into using getopt
[[http://dlang.org/phobos/std_getopt.html][getopt]]
[[http://dlang.org/library/std/getopt.html][getopt]]

#+NAME: sdp_args
#+BEGIN_SRC d

bool[string] opt_action_bool = [
  "assertions"          : false,
  "html"                : false,
  "no_obj_cite_number"  : false,
  "verbose"             : false,
];
auto helpInfo = getopt(args,
  std.getopt.config.passThrough,
  "assert",    "--assert set optional assertions on",          &opt_action_bool["assertions"],
  "html",      "--html process html output",                   &opt_action_bool["html"],
  "no-ocn",    "--no-ocn suppress object cite number output",  &opt_action_bool["no_obj_cite_number"],
  "verbose|v", "--verbose output to terminal",                 &opt_action_bool["verbose"],
);
if (helpInfo.helpWanted) {
  defaultGetoptPrinter("Some information about the program.", helpInfo.options);
}
foreach(arg; args) {
  if (match(arg, rgx.flag_action)) {
    flag_action ~= " " ~ arg;   // flags not taken by getopt
  } else if (match(arg, rgx.src_pth)) {
    fns_src ~= arg;             // gather input markup source file names for processing
  } else {                      // anything remaining, unused
    arg_unrecognized ~= " " ~ arg;
  }
}
#+END_SRC

** loop each file [+2]                                           :loop:files:
*** filename provided [+1]                                     :file:process:
**** loop scope                                                       :scope:
#+NAME: sdp_each_file_do
#+BEGIN_SRC d
scope(success) {
  debug(checkdoc) {
    writefln(
      "%s~ document complete, ok ~%s",
      scr_txt_color["green"], scr_txt_color["off"],
    );
  }
  // stderr.writeln("0");
}
scope(failure) {
  debug(checkdoc) {
    stderr.writefln(
      "%s~ document run failure ~%s (%s  v%s)\n\t%s",
      scr_txt_color["red"], scr_txt_color["off"],
      __VENDOR__, __VERSION__,
      fn_src
    );
  }
  // stderr.writeln("1");
}
enforce(
  match(fn_src, rgx.src_pth),
  "not a sisu markup filename"
);
#+END_SRC

**** [#A] read file                                               :file:read:
[[./ao_markup_source_raw.org][ao_markup_source_raw]]

#+NAME: sdp_each_file_do
#+BEGIN_SRC d
/+ ↓ read file +/
auto sourcefile_content =
  raw.sourceContent(fn_src);
#+END_SRC

**** [#A] processing: document abstraction, tuple                :processing:
#+NAME: sdp_each_file_do
#+BEGIN_SRC d
/+ ↓ porcess document, return abstraction as tuple +/
auto t =
  abs.abstract_doc_source(sourcefile_content);
static assert(!isTypeTuple!(t));
auto doc_ao_contents = t[0]; // contents ~ endnotes ~ bookindex;
// static assert(!isIterable!(doc_ao_contents));
auto doc_ao_metadata_json = t[1];
auto doc_ao_make_json = t[2];
auto doc_ao_bookindex_unordered_hashes = t[3];
auto doc_ao_biblio = t[4];
// destroy(t);
#+END_SRC

**** TODO debug                                                       :debug:
***** [#A] debug document parts (checkdoc)                         :checkdoc:
#+NAME: sdp_each_file_do
#+BEGIN_SRC d
/+ ↓ document parts +/
debug(checkdoc) { // checkbook & dumpdoc
  dbg.abstract_doc_source_debugs(
    doc_ao_contents,
    doc_ao_make_json,
    doc_ao_metadata_json,
    doc_ao_bookindex_unordered_hashes,
    doc_ao_biblio,
    fn_src,
    opt_action_bool
  );
}
#+END_SRC

**** on exit                                                     :scope:exit:
#+NAME: sdp_each_file_do
#+BEGIN_SRC d
scope(exit) {
  debug(checkdoc) {
    writefln(
      "processed file: %s",
      fn_src
    );
  }
  destroy(sourcefile_content);
  destroy(t);
  destroy(doc_ao_contents);
  destroy(doc_ao_make_json);
  destroy(doc_ao_metadata_json);
  destroy(doc_ao_bookindex_unordered_hashes);
  destroy(doc_ao_biblio);
  destroy(fn_src);
}
#+END_SRC

*** no filename provided
#+NAME: sdp_no_filename_provided
#+BEGIN_SRC d
/+ no recognized filename provided +/
writeln("no recognized filename");
break;
// terminate, stop
#+END_SRC

* tangles (code structure)                                           :tangle:
** sdp                                                              :sdp.d:
*** TODO src/sdp.d

├── src
│   ├── sdp.d
│   └── sdp
│       ├── ao_abstract_doc_source.d
│       ├── ...
│       └── compile_time_info.d
├── views
│   └── version.txt

├── src
│   ├── sdp
│   │   ├── ao_abstract_doc_source.d
│   │   ├── ...
│   │   └── compile_time_info.d
│   └── sdp.d
├── views
│   └── version.txt

#+BEGIN_SRC d  :tangle ../src/sdp.d :shebang #!/usr/bin/env rdmd
/+
  sdp
  sdp.d
+/
<<sdp_imports>>
<<sdp_imports_use>>
<<sdp_version_mixin>>
mixin CompileTimeInfo;
mixin RgxInit;
void main(string[] args) {
  <<sdp_compilation>>
  <<sdp_args>>
  foreach(fn_src; fns_src) {
  // foreach(fn_src; fns_src) {
    if (!empty(fn_src)) {
      <<sdp_each_file_do>>
    } else {
      <<sdp_no_filename_provided>>
    }
  }
}
#+END_SRC

* TODO work on
- figure out best program dir structure, issue with rdmd

|---------------------+------------------------------------------+------------------------+--------|
| header              | sisu /header markup/                       | markup                 |        |
| - metadata          |                                          |                        |        |
| - make instructions |                                          |                        |        |
|---------------------+------------------------------------------+------------------------+--------|
| table of contents   | markup of headings                       | (regular content)      | output |
|---------------------+------------------------------------------+------------------------+--------|
| substantive content | sisu /content markup/                      | markup                 | output |
|                     | headings (providing document structure), | (regular content)      |        |
|                     | paragraphs, blocks                       |                        |        |
|                     | blocks (code, poem, group, table)        |                        |        |
|---------------------+------------------------------------------+------------------------+--------|
| endnotes            | markup within substantive content        | markup                 | output |
|                     | (extracted from sisu /content markup/)     | (from regular content) |        |
|---------------------+------------------------------------------+------------------------+--------|
| glossary            | identify special section                 | markup                 | output |
|                     | regular /content markup/                   |                        |        |
|---------------------+------------------------------------------+------------------------+--------|
| bibliography        | identify section,                        | markup (special)       | output |
|                     | special /bibliography markup/              |                        |        |
|---------------------+------------------------------------------+------------------------+--------|
| book index          | extracted from markup attached to        | markup                 | output |
|                     | related substantive content objects      |                        |        |
|                     | (special tags in sisu /content markup/)    | (from regular content) |        |
|---------------------+------------------------------------------+------------------------+--------|
| metadata            |                                          | (from regular header)  | output |
|---------------------+------------------------------------------+------------------------+--------|