#+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)

* sdp.d   sisu document parser
[[../maker.org][maker.org makefile]]  [[./][org/]]
Deal with imports.
Take command line instructions and process files as instructed.

** TODO version, (version.txt) set version (with structure)         :version:

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

** imports                                                           :import:
[[./compile_time_info.org][compile time info]]
[[./ao_abstract_doc_source.org][ao_abstract_doc_source]]
[[./ao_assertions.org][ao_assertions]]
[[./ao_defaults.org][ao_defaults]]
[[./ao_emitter.org][ao_emitter]]
[[./ao_read_markup_source.org][ao_read_markup_source]]
[[./ao_object_setter.org][ao_object_setter]]
[[./ao_output_debugs.org][ao_output_debugs]]
[[./ao_rgx.org][ao_rgx]]
[[./ao_scan_inserts.org][ao_scan_inserts]]
[[./ao_structs.org][ao_structs]]
[[./ao_utils.org][ao_utils]]

*** std                                                          :import:std:
#+NAME: sdp_imports
#+BEGIN_SRC d
/+ sdp  sisu document parser +/
import
  std.algorithm,
  std.array,
  std.container,
  std.file,
  std.exception,
  std.json,
  // std.path,
  std.process,
  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 lib/sdp.d
#+NAME: sdp_imports_use
#+BEGIN_SRC d
/+ sdp  sisu document parser +/
import
  lib.sdp.compile_time_info,            // sdp/compile_time_info.d
  lib.sdp.ao_abstract_doc_source,       // sdp/ao_abstract_doc_source.d
  lib.sdp.ao_assertions,                // sdp/ao_assertions.d
  lib.sdp.ao_defaults,                  // sdp/ao_defaults.d
  lib.sdp.ao_emitter,                   // sdp/ao_emitter.d
  lib.sdp.ao_read_markup_source,        // sdp/ao_read_markup_source.d
  lib.sdp.ao_object_setter,             // sdp/ao_object_setter.d
  lib.sdp.ao_output_debugs,             // sdp/ao_output_debugs.d
  lib.sdp.ao_rgx,                       // sdp/ao_rgx.d
  lib.sdp.ao_scan_inserts,              // sdp/ao_scan_inserts.d
  lib.sdp.ao_structs,                   // sdp/ao_structs.d
  lib.sdp.ao_utils;                     // sdp/ao_utils.d
  // std.conv;
#+END_SRC

**** TODO lib/sdp/std.d (rdmd)                                         :rdmd:
#+NAME: sdp_imports_rdmd
#+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_assertions,                // ao_assertions.d
  ao_defaults,                  // ao_defaults.d
  ao_emitter,                   // ao_emitter.d
  ao_read_markup_source,        // sdp/ao_read_markup_source.d
  ao_object_setter,             // ao_object_setter.d
  ao_output_debugs,             // ao_output_debugs.d
  ao_rgx,                       // ao_rgx.d
  ao_scan_inserts,              // ao_scan_inserts.d
  ao_structs,                   // ao_structs.d
  ao_utils;                     // ao_utils.d
  // std.conv;
#+END_SRC

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

** argv [+3]                                                           :argv:
*** argv mixins & init
#+NAME: sdp_argv
#+BEGIN_SRC d
mixin SiSUheader;
mixin SiSUbiblio;
mixin SiSUrgxInitFlags;
mixin SiSUmarkupRaw;
mixin SiSUdocInserts;
mixin SiSUdocAbstraction;
mixin SiSUoutputDebugs;
mixin ScreenTxtColors;
auto cli = CLI();
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[string] actions;
actions = [
  "assert"  : "yes",
];
auto rgx = Rgx();
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) {
   writefln(
     "%s~ run failure ~%s",
      scr_txt_color["fuchsia"],
      scr_txt_color["off"],
   );
 }
  // stderr.writeln("1");
}
scope(exit) {
  debug(checkdoc) {
    writefln(
      "(%s  v%s)",
      __VENDOR__,
      __VERSION__,
    );
  }
}
#+END_SRC

*** argv loop
#+NAME: sdp_argv
#+BEGIN_SRC d
foreach(cmdlnins; argv) {
  if (match(cmdlnins, rgx.flag_action)) {
    flag_action ~= " " ~ cmdlnins;
    actions = cli.extract_actions(cmdlnins, actions);
  } else if (match(cmdlnins, rgx.src_pth)) {
    fns_src ~= cmdlnins;
  }
}
#+END_SRC

*** each file [+2]                                                     :file:
**** filename provided [+1]
***** scope                                                           :scope:
#+NAME: sdp_each_file_do
#+BEGIN_SRC d
scope(success) {
  debug(checkdoc) {
    writefln(
      "%s~ document complete, ok ~%s %s",
      scr_txt_color["green"],
      scr_txt_color["off"],
      fn_src
    );
  }
  // stderr.writeln("0");
}
scope(failure) {
  debug(checkdoc) {
    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");
}
scope(exit) {
  debug(checkdoc) {
    writeln(
      fn_src
    );
  }
}
enforce(
  match(fn_src, rgx.src_pth),
  "not a sisu markup filename"
);
#+END_SRC

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

#+NAME: sdp_each_file_do
#+BEGIN_SRC d
auto markup_sourcefile_content =
  raw.markupSourceContentRawLineArray(fn_src); // alternative call
  // raw.markupSourceLineArray(raw.markupSourceString(fn_src)); // alternative calls (milliseconds faster?)
debug(insert) {
  string[string] sysenv;
  sysenv["pwd"] = shell("pwd");
  writeln(sysenv["pwd"]);
  auto m = match(fn_src, rgx.src_pth);
  // auto m = match(fn_src, rgx.src_pth);
  auto markup_src_file_path = m.captures[1];
  writefln(
    "markup source file path: %s",
    markup_src_file_path
  ); // writeln(m.captures[1]);
  writeln(m.captures[2]);
}
#+END_SRC

****** incorporate any inserts
[[./ao_scan_inserts.org][ao_scan_inserts]]

#+NAME: sdp_each_file_do
#+BEGIN_SRC d
if (match(fn_src, rgx.src_fn_master)) {
/+ if master file .ssm
  scan document source for document imports
  (inserted sub-documents)
+/
  auto ins = Inserts();
  markup_sourcefile_content =
    ins.scan_doc_source(markup_sourcefile_content, fn_src);
} else if (!match(fn_src, rgx.src_fn)) {
  writeln("not a recognized filename");
}
debug(raw) {
  foreach (line; markup_sourcefile_content) {
    writeln(line);
  }
}
#+END_SRC

***** send for processing                                        :processing:
#+NAME: sdp_each_file_do
#+BEGIN_SRC d
/+ process document ao_abstract_doc_source
  SiSUdocAbstraction::Abstraction
  return abstraction as tuple
+/
auto t =
  abs.abstract_doc_source(markup_sourcefile_content);
static assert(!isTypeTuple!(t));
auto contents = t[0];
// static assert(!isIterable!(contents));
auto metadata_json = t[1];
auto make_json = t[2];
auto bookindex_unordered_hashes = t[3];
auto biblio = t[4];
// destroy(t);
#+END_SRC

***** debug document parts (checkdoc)
#+NAME: sdp_each_file_do
#+BEGIN_SRC d
// DocumentParts
debug(checkdoc) {
  dbg.abstract_doc_source_debugs(
    contents,
    make_json,
    metadata_json,
    bookindex_unordered_hashes,
    biblio,
    fn_src,
    actions
  );
}
// compose abstract document markup state
// append book index
#+END_SRC

***** on exit
#+NAME: sdp_each_file_do
#+BEGIN_SRC d
scope(exit) {
  destroy(markup_sourcefile_content);
  destroy(t);
  destroy(contents);
  destroy(make_json);
  destroy(metadata_json);
  destroy(bookindex_unordered_hashes);
  destroy(fn_src);
  destroy(biblio);
}
#+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                                                            :tangle:
** sdp code structure                                                    :sdp.d:
*** TODO lib/sdp.d
#+BEGIN_SRC d  :tangle ../lib/sdp.d :shebang #!/usr/bin/env rdmd
/+
  sdp
  sdp.d
+/
<<sdp_imports>>
<<sdp_imports_use>>
<<sdp_version_mixin>>
mixin CompileTimeInfo;
mixin RgxInit; mixin Emitters;
void main(string[] argv) {
  <<sdp_compilation>>
  <<sdp_argv>>
  foreach(fn_src; fns_src) {
    if (!empty(fn_src)) {
      <<sdp_each_file_do>>
    } else {
      <<sdp_no_filename_provided>>
    }
  }
}
#+end_src

** version.txt                                                      :version:

*** TODO lib/version.txt
#+BEGIN_SRC d  :tangle ../lib/version.txt
/+ obt - org generated file +/
<<version_txt>>
#+END_SRC

*** TODO lib/sdp/version.txt                                           :rdmd:
#+BEGIN_SRC d  :tangle ../lib/sdp/version.txt
/+ obt - org generated file +/
// [used by rdmd]
<<version_txt>>
#+END_SRC