#+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 = conf_file.readText; 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 (fn_src.match(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 = fn_src.readText; } } 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 = (cast(char[]) src_text).matchFirst(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 == " ~ header_and_content.length.to!string ~ "; (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 = (cast(char[]) src_text).split(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( fn_src.match(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( fn_src.match(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 = fn_src.match(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 (line.matchFirst(rgx.block_curly_code_close)) { type1["curly_code"] = 0; } contents_insert ~= line; } else if (line.matchFirst(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 (line.matchFirst(rgx.block_tic_close)) { type1["tic_code"] = 0; } contents_insert ~= line; } else if (line.matchFirst(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) && line.matchFirst(rgx.native_header_sub) ) { type1["header_make"] = 1; type1["header_meta"] = 0; } else if ( (type1["header_meta"] == 1) && line.matchFirst(rgx.native_header_sub) ) { type1["header_meta"] = 1; type1["header_make"] = 0; } else if (auto m = line.match(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 = fn_src.match(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 (line.matchFirst(rgx.block_curly_code_close)) { type["curly_code"] = 0; } contents ~= line; } else if (line.matchFirst(rgx.block_curly_code_open)) { type["curly_code"] = 1; contents ~= line; } else if (type["tic_code"] == 1) { if (line.matchFirst(rgx.block_tic_close)) { type["tic_code"] = 0; } contents ~= line; } else if (line.matchFirst(rgx.block_tic_code_open)) { type["tic_code"] = 1; contents ~= line; } else if (auto m = line.match(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 = line.match(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: