#+TITLE: sdp markup source raw
#+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:niu:ao:
#+TAGS: assert(a) class(c) debug(d) mixin(m) sdp(s) tangle(T) template(t) WEB(W) noexport(n)

[[./sdp.org][sdp]]  [[./][org/]]
* get config file                                                    :config:

** [#A] read config file, source string                              :string:
*** config file                                                 :file:config:
#+name: ao_config_file
#+BEGIN_SRC d
final private string readInConfigFile() {
  // enforce(
  //   exists(fn_src)!=0,
  //   "file not found"
  // );
  string[] possible_config_path_locations = [
    environment["PWD"] ~ "/.sisu",
    environment["PWD"] ~ "/_sisu",
    environment["HOME"] ~ "/.sisu",
    "/etc/sisu"
  ];
  string conf_sdl = "conf.sdl";
  string config_file_str;
  foreach(pth; possible_config_path_locations) {
    auto conf_file = format(
      "%s/%s",
      pth,
      conf_sdl,
    );
    // writeln(conf_file);
    try {
      if (exists(conf_file)) {
        writeln(conf_file);
        config_file_str = readText(conf_file);
        break;
      }
    }
    catch (ErrnoException ex) {
    //// Handle errors
    // switch(ex.errno) {
    // case EPERM:
    // case EACCES:
    //   // Permission denied
    //   break;
    // case ENOENT:
    //   // File does not exist
    //   break;
    // default:
    //   // Handle other errors
    //   break;
    // }
    }
    // catch (UTFException ex) {
    //   // Handle validation errors
    // }
    catch (FileException ex) {
      // Handle errors
    }
  }
  return config_file_str;
}
#+END_SRC

* get markup source, read file                                :source:markup:

** [#A] read file, source string                                     :string:
#+name: ao_markup_source_raw
#+BEGIN_SRC d
final private string readInMarkupSource(in string fn_src) {
  enforce(
    exists(fn_src)!=0,
    "file not found"
  );
  string source_txt_str;
  try {
    if (exists(fn_src)) {
      source_txt_str = readText(fn_src);
    }
  }
  catch (ErrnoException ex) {
  //// Handle errors
  // switch(ex.errno) {
  // case EPERM:
  // case EACCES:
  //   // Permission denied
  //   break;
  // case ENOENT:
  //   // File does not exist
  //   break;
  // default:
  //   // Handle other errors
  //   break;
  // }
  }
  catch (UTFException ex) {
    // Handle validation errors
  }
  catch (FileException ex) {
    // Handle errors
  }
  std.utf.validate(source_txt_str);
  return source_txt_str;
}
#+END_SRC

*** notes
source_txt_str = readText(fn_src); // ok
// source_txt_str = cast(string) read(fn_src); // ok
// immutable string source_txt_str = cast(string) read(fn_src);
// auto utf8Data = readText(fn_src);
// auto utf16Data = readText!(wstring)(fn_src);
// auto utf32Data = readText!(dstring)(fn_src);

catch (ErrnoException ex) {
//// Handle errors
// switch(ex.errno) {
// case EPERM:
// case EACCES:
//   // Permission denied
//   break;
// case ENOENT:
//   // File does not exist
//   break;
// default:
//   // Handle other errors
//   break;
// }
}

** array[0..1]: split header content                                        :array:
#+name: ao_markup_source_raw
#+BEGIN_SRC d
final private char[][] header0Content1(in string src_text) {
  /+ split string on first match of "^:?A~\s" into [header, content] tuple +/
  char[][] header_and_content =
    split(cast(char[]) src_text, rgx.heading_a);
  return header_and_content;
}
#+END_SRC

** source line array                                                  :array:
#+name: ao_markup_source_raw
#+BEGIN_SRC d
final private char[][] markupSourceLineArray(in char[] src_text) {
  char[][] source_line_arr =
    split(cast(char[]) src_text, rgx.line_delimiter);
  return source_line_arr;
}
#+END_SRC

** source content raw line array                                      :array:
- used for regular .sst files; master .ssm files and; .ssi inserts
- regex is passed for relevant enforce match

#+name: ao_markup_source_raw
#+BEGIN_SRC d
auto markupSourceHeaderContentRawLineTupleArray(in string fn_src, Regex!(char) rgx_file ) {
  enforce(
    match(fn_src, rgx_file),
    "not a sisu markup filename"
  );
  auto source_txt_str = readInMarkupSource(fn_src);
  auto hc = header0Content1(source_txt_str);
  auto header = hc[0];
  char[] la;
  la ~= "A~ ";
  char[] source_txt = la ~ hc[1];
  auto source_line_arr = markupSourceLineArray(source_txt);
  auto t = tuple(
    header,
    source_line_arr
  );
  return t;
}
final char[][] markupSourceContentRawLineArray(in string fn_src, Regex!(char) rgx_file ) {
  enforce(
    match(fn_src, rgx_file),
    "not a sisu markup filename"
  );
  auto source_txt_str = readInMarkupSource(fn_src);
  auto source_line_arr = markupSourceLineArray(source_txt_str);
  return source_line_arr;
}
#+END_SRC

* get markup source, master file & inserts               :masterfile:inserts:
[[./sdp.org][sdp]]  [[./][org/]]

** scan inserts (sub-document) source                       :scan_insert_src:
*** scan subdoc source
#+name: ao_inserts_scan
#+BEGIN_SRC d
char[][] contents_insert;
auto type1 = flags_type_init;
auto fn_pth_full = match(fn_src, rgx.src_pth);
auto markup_src_file_path = fn_pth_full.captures[1];
#+END_SRC

*** loop insert (sub-document)
#+name: ao_inserts_scan_loop
#+BEGIN_SRC d
if (type1["curly_code"] == 1) {
  type1["header_make"] = 0;
  type1["header_meta"] = 0;
  if (matchFirst(line, rgx.block_curly_code_close)) {
    type1["curly_code"] = 0;
  }
  contents_insert ~= line;
} else if (matchFirst(line, rgx.block_curly_code_open)) {
  type1["curly_code"] = 1;
  type1["header_make"] = 0;
  type1["header_meta"] = 0;
  contents_insert ~= line;
} else if (type1["tic_code"] == 1) {
  type1["header_make"] = 0;
  type1["header_meta"] = 0;
  if (matchFirst(line, rgx.block_tic_close)) {
    type1["tic_code"] = 0;
  }
  contents_insert ~= line;
} else if (matchFirst(line, rgx.block_tic_code_open)) {
  type1["tic_code"] = 1;
  type1["header_make"] = 0;
  type1["header_meta"] = 0;
  contents_insert ~= line;
} else if (
  (type1["header_make"] == 1)
  && matchFirst(line, rgx.native_header_sub)
) {
    type1["header_make"] = 1;
    type1["header_meta"] = 0;
    // cont_dynamic_array ~= "% " ~ line;
} else if (
  (type1["header_meta"] == 1)
  && matchFirst(line, rgx.native_header_sub)
) {
    type1["header_meta"] = 1;
    type1["header_make"] = 0;
    // cont_dynamic_array ~= "% " ~ line;
} else if (auto m = match(line, rgx.insert_src_fn_ssi_or_sst)) {
  type1["header_make"] = 0;
  type1["header_meta"] = 0;
  auto insert_fn = m.captures[2];
  auto insert_sub_pth = m.captures[1];
  auto fn_src_insert =
    to!string(markup_src_file_path ~ insert_sub_pth ~ insert_fn);
  auto raw = MarkupRawUnit();
  auto markup_sourcesubfile_insert_content =
    raw.markupSourceContentRawLineArray(fn_src_insert, rgx.src_fn_find_inserts);
  debug(insert) {                              // insert file
    tell_l("red", line);
    tell_l("red", fn_src_insert);
    tell_l("fuchsia", "ERROR");
    writeln(
      "  length contents insert array: ",
      markup_sourcesubfile_insert_content.length
    );
  }
  auto ins = Inserts();
  /+
    1. load file,
    2. read lines;
    3. scan lines,
    4. if filename insert, and insert filename
    5.   repeat 1
    6. else
    7.   add line to new array;
  +/
} else {
  type1["header_make"] = 0;
  type1["header_meta"] = 0;
  contents_insert ~= line;
}
#+END_SRC

*** post loop
#+name: ao_inserts_scan_post
#+BEGIN_SRC d
return contents_insert;
#+END_SRC

** scan document source                                            :scan_src:
*** scan doc source
#+name: ao_master_doc_scan_for_insert_filenames
#+BEGIN_SRC d
char[][] contents;
auto type = flags_type_init;
auto fn_pth_full = match(fn_src, rgx.src_pth);
auto markup_src_file_path = fn_pth_full.captures[1];
#+END_SRC
*** loop master scan for inserts (insert documents)
#+name: ao_master_doc_scan_for_insert_filenames_loop
#+BEGIN_SRC d
if (type["curly_code"] == 1) {
  if (matchFirst(line, rgx.block_curly_code_close)) {
    type["curly_code"] = 0;
  }
  contents ~= line;
} else if (matchFirst(line, rgx.block_curly_code_open)) {
  type["curly_code"] = 1;
  contents ~= line;
} else if (type["tic_code"] == 1) {
  if (matchFirst(line, rgx.block_tic_close)) {
    type["tic_code"] = 0;
  }
  contents ~= line;
} else if (matchFirst(line, rgx.block_tic_code_open)) {
  type["tic_code"] = 1;
  contents ~= line;
} else if (auto m = match(line, rgx.insert_src_fn_ssi_or_sst)) {
  auto insert_fn = m.captures[2];
  auto insert_sub_pth = m.captures[1];
  auto fn_src_insert =
    to!string(markup_src_file_path ~ insert_sub_pth ~ insert_fn);
  auto raw = MarkupRawUnit();
  auto markup_sourcefile_insert_content =
    raw.markupSourceContentRawLineArray(fn_src_insert, rgx.src_fn_find_inserts);
  debug(insert) {                              // insert file
    tell_l("red", line);
    tell_l("red", fn_src_insert);
    writeln(
      "  length contents insert array: ",
      markup_sourcefile_insert_content.length
    );
  }
  auto ins = Inserts();
  auto contents_insert = ins.scan_subdoc_source(
    markup_sourcefile_insert_content,
    to!string(fn_src_insert)
  );
  contents ~= contents_insert;
  /+
    1. load file,
    2. read lines;
    3. scan lines,
    4. if filename insert, and insert filename
    5.   repeat 1
    6. else
    7.   add line to new array;
  +/
} else {
  contents ~= line;
}
#+END_SRC

*** post loop
#+name: ao_master_doc_scan_for_insert_filenames_post
#+BEGIN_SRC d
debug(insert) {                              // insert file
  writeln(__LINE__);
  writeln(contents.length);
}
return contents;
#+END_SRC

* tangles (code structure)                                           :tangle:
** ao_markup_source_raw.d:   :ao_markup_source_raw.d:

#+BEGIN_SRC d :tangle ../src/sdp/ao_read_source_files.d
/+
  ao_read_source_files.d
  - open markup files
  - if master file scan for addional files to import/insert
+/
// module ao_read_source_files;
template SiSUmarkupRaw() {
  private import
    std.exception,
    std.regex,
    std.stdio,
    std.utf,
    std.conv : to;
  private import
    ao_rgx;       // ao_defaults.d
  mixin RgxInit;
  auto rgx = Rgx();
  struct MarkupRaw {
    auto sourceContent(in string fn_src) {
      auto raw = MarkupRawUnit();
      auto t =
        raw.markupSourceHeaderContentRawLineTupleArray(fn_src, rgx.src_pth);
      auto header_raw = t[0];
      auto sourcefile_content = t[1];
      if (match(fn_src, rgx.src_fn_master)) {
        auto ins = Inserts();
        sourcefile_content =
          ins.scan_master_src_for_insert_files_and_import_content(sourcefile_content, fn_src);
        // auto ins = SiSUdocInserts.Inserts();
      }
      t = tuple(
        header_raw,
        sourcefile_content
      );
      return t;
    }
  }
  private
  struct MarkupRawUnit {
    private import std.file;
    // enum State { off, on }
    <<ao_markup_source_raw>>
  }
  struct Inserts {
    private import ao_defaults;    // ao_defaults.d
    private import ao_ansi_colors; // ao_ansi_colors.d
    auto scan_subdoc_source(
      char[][] markup_sourcefile_insert_content,
      string fn_src
    ) {
      mixin SiSUrgxInitFlags;
      <<ao_inserts_scan>>
      foreach (line; markup_sourcefile_insert_content) {
        <<ao_inserts_scan_loop>>
      } // end src subdoc (inserts) loop
      <<ao_inserts_scan_post>>
    }
    auto scan_master_src_for_insert_files_and_import_content(
      char[][] sourcefile_content,
      string fn_src
    ) {
      mixin SiSUrgxInitFlags;
      <<ao_master_doc_scan_for_insert_filenames>>
      foreach (line; sourcefile_content) {
        <<ao_master_doc_scan_for_insert_filenames_loop>>
      } // end src doc loop
      <<ao_master_doc_scan_for_insert_filenames_post>>
    }
  }
}
#+END_SRC

INSERTS?
[[./ao_scan_inserts.org][ao_scan_inserts]]
WORK AREA

** config files:                                          :ao_config_files.d:

#+BEGIN_SRC d :tangle ../src/sdp/ao_read_config_files.d
/+
  ao_config_files.d
  - read config files
+/
template SiSUconfiguration() {
  private import
    std.exception,
    // std.regex,
    std.stdio,
    std.utf,
    std.conv : to;
  // private import
  //   ao_rgx;       // ao_defaults.d
  // mixin RgxInit;
  // auto rgx = Rgx();
  private
  struct Config {
    private import std.file;
    <<ao_config_file>>
  }
}
#+END_SRC

* figure out
** break up file here to sisu markup content and header

break up file here to sisu markup content and header

*** header
take master and single sst file, read in as header until the required header 0~
keep separate (from content) for extraction of header metadata & make detail
also now may be sdlang or old sisu markup!

*** content
from 0~ read in as content

** what
# #+NAME: sdp_each_file_do
# #+BEGIN_SRC d
/+ ↓ read file +/
// auto conf = MarkupRaw();
auto conf = Config();
auto configfile_content =
  conf.sourceConfig(fn_src);
# #+END_SRC