#+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:rel:ao:
#+TAGS: assert(a) class(c) debug(d) mixin(m) sdp(s) tangle(T) template(t) WEB(W) noexport(n)
[[./sdp.org][sdp]] [[./][org/]]
* 1. get config file :config:
** 0. config files, read in
#+BEGIN_SRC d :tangle ../src/sdp/ao_read_config_files.d
/++
read configuration files
- read config files
ao_config_files.d
+/
template ConfigIn() {
<>
import std.file;
<>
}
#+END_SRC
** read config file, source string (conf.sdl & sisu_document_make) :file:config:
#+name: ao_config_file_in
#+BEGIN_SRC d
final string ConfigIn(C,E)(C conf_sdl, E env) {
string dot_pwd = chainPath(to!string(env["pwd"]), ".sisu").array;
string underscore_pwd = chainPath(to!string(env["pwd"]), "_sisu").array;
string dot_home = chainPath(to!string(env["home"]), ".sisu").array;
string[] possible_config_path_locations = [
dot_pwd,
underscore_pwd,
dot_home,
"/etc/sisu"
];
string config_file_str;
foreach(pth; possible_config_path_locations) {
auto conf_file = format(
"%s/%s",
pth,
conf_sdl,
);
try {
if (exists(conf_file)) {
debug(configfile) {
writeln(conf_file);
}
config_file_str = readText(conf_file);
break;
}
}
catch (ErrnoException ex) {
}
catch (FileException ex) {
}
}
return config_file_str;
}
#+END_SRC
** 0. config files get sdlang root tag
#+BEGIN_SRC d :tangle ../src/sdp/ao_read_config_files.d
/+
+/
template ConfigSDLang() {
import sdlang;
<>
<>
}
#+END_SRC
** config file get sdl root tag :file:conf:sdlang:
#+name: ao_config_file_sdlang
#+BEGIN_SRC d
auto ConfigSDLang(string configuration, string conf_sdl_filename) {
Tag sdl_root_conf;
try {
sdl_root_conf = parseSource(configuration);
}
catch(ParseException e) {
stderr.writeln("SDLang problem with content for ", conf_sdl_filename);
stderr.writeln(e.msg);
}
debug(sdlang) {
Value output_dir_structure_by = sdl_root_conf.tags["output_dir_structure_by"][0].values[0];
assert(output_dir_structure_by.type == typeid(string));
writeln(output_dir_structure_by);
writeln("conf SDL:");
writeln(sdl_root_conf.toSDLDocument());
}
return sdl_root_conf;
}
#+END_SRC
** config file (conf.sdl & sisu_document_make) :file:config:hub:
*** config hub template
#+BEGIN_SRC d :tangle ../src/sdp/ao_read_config_files.d
/+
+/
template ConfigHub() {
<>
<>
<>
}
#+END_SRC
*** imports
#+name: imports_std
#+BEGIN_SRC d
private import
std.algorithm,
std.array,
std.container,
std.exception,
std.stdio,
std.file,
std.path,
std.range,
std.regex,
std.string,
std.traits,
std.typecons,
std.uni,
std.utf,
std.conv : to;
#+END_SRC
*** config hub import sdlang
#+name: ao_config_file_import_mixin
#+BEGIN_SRC d
private import sdlang;
#+END_SRC
*** config hub function
#+name: ao_config_file_sdlang_hub
#+BEGIN_SRC d
final auto ConfigHub(C,E)(C conf_sdl, E env) {
auto configuration = ConfigIn!()(conf_sdl, env);
auto sdl_root = ConfigSDLang!()(configuration, conf_sdl);
return sdl_root;
}
#+END_SRC
* 2. get markup source, read file
** 0. ao_markup_source_raw.d: :ao_markup_source_raw:
#+BEGIN_SRC d :tangle ../src/sdp/ao_read_source_files.d
/++
module ao_read_source_files;
- open markup files
- if master file scan for addional files to import/insert
+/
template SiSUrawMarkupContent() {
private import
ao_rgx;
<>
mixin SiSUrgxInit;
auto rgx = Rgx();
auto rawsrc = RawMarkupContent();
auto SiSUrawMarkupContent(Fn)(Fn fn_src) {
auto _0_header_1_body_content_2_insert_filelist_tuple =
rawsrc.sourceContentSplitIntoHeaderAndBody(rawsrc.sourceContent(fn_src), fn_src);
return _0_header_1_body_content_2_insert_filelist_tuple;
}
struct RawMarkupContent {
final sourceContent(in string fn_src) {
auto raw = MarkupRawUnit();
auto source_txt_str =
raw.markupSourceReadIn(fn_src);
return source_txt_str;
}
final auto sourceContentSplitIntoHeaderAndBody(in string source_txt_str, in string fn_src="") {
auto raw = MarkupRawUnit();
string[] insert_file_list;
auto t =
raw.markupSourceHeaderContentRawLineTupleArray(source_txt_str);
auto header_raw = t[0];
auto sourcefile_body_content = t[1];
if (match(fn_src, rgx.src_fn_master)) { // filename with path needed if master file (.ssm) not otherwise
auto ins = Inserts();
auto tu =
ins.scan_master_src_for_insert_files_and_import_content(sourcefile_body_content, fn_src);
static assert(!isTypeTuple!(tu));
sourcefile_body_content = tu[0];
insert_file_list = tu[1].dup;
}
t = tuple(
header_raw,
sourcefile_body_content,
insert_file_list
);
static assert(t.length==3);
return t;
}
}
struct MarkupRawUnit {
private import std.file;
<>
<>
<>
<>
<>
<>
}
struct Inserts {
private import ao_defaults;
auto scan_subdoc_source(
char[][] markup_sourcefile_insert_content,
string fn_src
) {
mixin SiSUrgxInitFlags;
<>
foreach (line; markup_sourcefile_insert_content) {
<>
} // end src subdoc (inserts) loop
<>
}
auto scan_master_src_for_insert_files_and_import_content(
char[][] sourcefile_body_content,
string fn_src
) {
mixin SiSUrgxInitFlags;
<>
foreach (line; sourcefile_body_content) {
<>
} // end src doc loop
<>
}
}
}
#+END_SRC
** get markup source, read file :source:markup:
*** [#A] read file, source string :string:
#+name: ao_markup_source_raw_read_file_source_string
#+BEGIN_SRC d
final private string readInMarkupSource(in char[] 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) {
}
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
catch (ErrnoException ex) {
}
*** [#A] document header & content, array.length == 2 :array:
here you split document header and body, an array.length == 2
split is on first match of level A~ (which is required)
#+name: ao_markup_source_raw_doc_header_and_content_split
#+BEGIN_SRC d
final private char[][] header0Content1(in string src_text) {
/+ split string on _first_ match of "^:?A~\s" into [header, content] array/tuple +/
char[][] header_and_content;
auto m = matchFirst(cast(char[]) src_text, rgx.heading_a);
header_and_content ~= m.pre;
header_and_content ~= m.hit ~ m.post;
assert(header_and_content.length == 2,
"document markup is broken, header body split == " ~ to!string(header_and_content.length) ~
"; (header / body array split should == 2 (split is on level A~))"
);
return header_and_content;
}
#+END_SRC
*** source line array :array:
#+name: ao_markup_source_raw_source_line_array
#+BEGIN_SRC d
final private char[][] markupSourceLineArray(in char[] src_text) {
char[][] source_line_arr =
split(cast(char[]) src_text, rgx.newline_eol_strip_preceding);
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
**** read in file
#+name: ao_markup_source_raw_read_in_file
#+BEGIN_SRC d
auto markupSourceReadIn(in string fn_src) {
auto rgx = Rgx();
enforce(
match(fn_src, rgx.src_pth),
"not a sisu markup filename"
);
auto source_txt_str = readInMarkupSource(fn_src);
return source_txt_str;
}
#+END_SRC
**** tuple header and body content
#+name: ao_markup_source_raw_tuple_of_header_and_body
#+BEGIN_SRC d
auto markupSourceHeaderContentRawLineTupleArray(in string source_txt_str) {
string[] file_insert_list = [];
auto hc = header0Content1(source_txt_str);
auto header = hc[0];
char[] source_txt = hc[1];
auto source_line_arr = markupSourceLineArray(source_txt);
auto t = tuple(
header,
source_line_arr,
file_insert_list
);
return t;
}
#+END_SRC
**** get insert source line array
#+name: ao_markup_source_raw_get_insert_source_line_array
#+BEGIN_SRC d
final char[][] getInsertMarkupSourceContentRawLineArray(
in char[] 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;
} else if (
(type1["header_meta"] == 1)
&& matchFirst(line, rgx.native_header_sub)
) {
type1["header_meta"] = 1;
type1["header_make"] = 0;
} 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 =
chainPath(markup_src_file_path, insert_sub_pth ~ insert_fn).array;
auto raw = MarkupRawUnit();
auto markup_sourcesubfile_insert_content =
raw.getInsertMarkupSourceContentRawLineArray(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];
string[] insert_file_list =[];
#+END_SRC
**** include inserts: _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 =
chainPath(markup_src_file_path, insert_sub_pth ~ insert_fn).array;
insert_file_list ~= to!string(fn_src_insert);
auto raw = MarkupRawUnit();
/+ TODO +/
if (auto ma = match(line, rgx.src_fn_text)) {
/+ .sst when inserted, not used: headers and heading level ^:?A~ so remove +/
writeln(__LINE__); writeln(ma);
}
auto markup_sourcefile_insert_content =
raw.getInsertMarkupSourceContentRawLineArray(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);
}
auto t = tuple(
contents,
insert_file_list
);
return t;
#+END_SRC
* 3. config files (conf.sdl & sisu_document_make) :ao_config_files: