/++
  extract native/orig header return associative array<BR>

  the header is passed as text (lopped off top of a sisu markup file until the
  required first heading ^A~), determine whether is a native header or sdlang one
  with a regex check if whether it contains the "native header" required tag/field
  @title: then process accordingly as a "native header" or "sdlang header"
  converting the metadata and make instructions to a common json format used by
  program internally. Moved to associative array.
+/
module sdp.meta.conf_make_meta_sdlang;
static template docHeaderMakeAndMetaTupSDLangExtractAndConvertToStruct() {
  import
    std.exception,
    std.regex,
    std.stdio,
    std.traits,
    std.typecons,
    std.utf,
    std.conv : to;
  import sdlang;
  import
    sdp.meta.conf_make_meta_sdlang,
    sdp.meta.rgx;
  mixin SiSUrgxInit;
  mixin SiSUextractSDLang;
  static auto rgx = Rgx();
  auto docHeaderMakeAndMetaTupSDLangExtractAndConvertToStruct(CCm, Src)(
    CCm     conf_composite_make,
    Src     header_src,
  ) {
    auto header_sdlang_tag = (header_src.match(rgx.sdlang_header_meta_title))
    ? extractSDL().docHeaderSDLtagGet(header_src) // sdlang.ast.Tag
    : null;
    auto header_make_and_meta_struct = extractSDL().docSDLtoStruct(conf_composite_make, header_sdlang_tag);
    return header_make_and_meta_struct;
  }
}
/++
  sdlang headers<BR>
  extract sdlang header return sdlang
+/
static template SiSUextractSDLang() {
  import
    std.exception,
    std.regex,
    std.stdio,
    std.string,
    std.traits,
    std.typecons,
    std.utf,
    std.conv : to;
  import
    sdp.meta.conf_make_meta_structs,
    sdp.meta.rgx;
  struct extractSDL {
    mixin SiSUmakeMetaStructsSDLang;
    mixin SiSUrgxInit;
    static auto rgx = Rgx();
    private auto docHeaderSDLtagGet(Hs)(Hs src_header) {
      debug(asserts){
        static assert(is(typeof(src_header) == char[]));
      }
      char[][] source_header_arr
        = (cast(char[]) src_header).split(rgx.newline_eol_delimiter);
      char[] _src_header;
      foreach(header_line; source_header_arr) {
        if (!match(header_line, rgx.comments)) {
          _src_header ~= header_line ~ "\n";
        }
      }
      scope(failure) {
        stderr.writefln(
          "%s\n%s\n%s:%s failed here:\n  _src_header: %s",
          __MODULE__, __FUNCTION__,
          __FILE__, __LINE__,
          _src_header,
        );
      }
      Tag sdl_root_header;
      try {
        sdl_root_header = parseSource(_src_header.to!string);
      }
      catch(ParseException e) {
        stderr.writeln("SDLang problem with this document header:");
        stderr.writeln(_src_header);
        // Error messages of the form:
        // myFile.sdl(5:28): Error: Invalid integer suffix.
        stderr.writeln(e.msg);
      }
      debug(sdlang) {
        writeln("header SDL:");
        writeln(__LINE__, ": ",  sdl_root_header.toSDLDocument());
        writeln(__LINE__, ": ",  sdl_root_header.maybe.namespaces);
        writeln("header make sdlang: ", sdl_root_header.toSDLDocument());
        writeln(__LINE__, ": ", sdl_root_header.getTagValues("title"));
        writeln(__LINE__, ": ", sdl_root_header.getTagValues("creator"));
        Tag creator = sdl_root_header.getTag("creator");
        if (creator !is null) {
          if ("author" in creator.maybe.tags) {
            writeln(__LINE__, ": ", creator.getTagValues("author"));
          } else if ("author" in creator.maybe.attributes) {
            writeln(__LINE__, ": ", creator.maybe.attributes["author"][0].value);
          }
        }
      }
      return sdl_root_header; // sdlang.ast.Tag
    }
    private auto docSDLtoStruct(C,Tag)(C _conf_composite, Tag header_sdlang) { // work on
      /+ make ------------------------------------------------------------------- +/
      if ("make" in header_sdlang.maybe.tags) {
        confCompositeMakeBuild _mk;
        _conf_composite.make_str.bold                       = extractSDLangTabOrAttrib(header_sdlang, "make", "bold"); // TODO
        _conf_composite.make_str.breaks                     = extractSDLangTabOrAttrib(header_sdlang, "make", "breaks");
        _conf_composite.make_str.cover_image                = extractSDLangTabOrAttrib(header_sdlang, "make", "cover_image");
        _conf_composite.make_str.css                        = extractSDLangTabOrAttrib(header_sdlang, "make", "css");
        _conf_composite.make_str.emphasis                   = extractSDLangTabOrAttrib(header_sdlang, "make", "emphasis"); // TODO
        _conf_composite.make_str.footer                     = extractSDLangTabOrAttrib(header_sdlang, "make", "footer");
        _conf_composite.make_str.headings                   = extractSDLangTabOrAttrib(header_sdlang, "make", "headings");
        _conf_composite.make_str.home_button_image          = extractSDLangTabOrAttrib(header_sdlang, "make", "home_button_image");
        _conf_composite.make_str.home_button_text           = extractSDLangTabOrAttrib(header_sdlang, "make", "home_button_text");
        _conf_composite.make_str.italics                    = extractSDLangTabOrAttrib(header_sdlang, "make", "italics"); // TODO
        _conf_composite.make_str.num_top                    = extractSDLangTabOrAttrib(header_sdlang, "make", "num_top");
        _conf_composite.make_str.num_depth                  = extractSDLangTabOrAttrib(header_sdlang, "make", "num_depth");
        _conf_composite.make_str.substitute                 = extractSDLangTabOrAttrib(header_sdlang, "make", "substitute"); // TODO
        _conf_composite.make_str.texpdf_font                = extractSDLangTabOrAttrib(header_sdlang, "make", "texpdf_font");
        _conf_composite.make.bold_rgxmatch                  = _mk.bold_rgxmatch(_conf_composite.make_str.bold);
        _conf_composite.make.breaks                         = _mk.breaks(_conf_composite.make_str.breaks);
        _conf_composite.make.cover_image                    = _mk.cover_image(_conf_composite.make_str.cover_image);
        _conf_composite.make.css                            = _mk.css(_conf_composite.make_str.css);
        _conf_composite.make.emphasis_rgxmatch              = _mk.emphasis_rgxmatch(_conf_composite.make_str.emphasis);
        _conf_composite.make.footer                         = _mk.footer(_conf_composite.make_str.footer);
        _conf_composite.make.headings                       = _mk.headings(_conf_composite.make_str.headings);
        _conf_composite.make.home_button_image              = _mk.home_button_image(_conf_composite.make_str.home_button_image);
        _conf_composite.make.home_button_text               = _mk.home_button_text(_conf_composite.make_str.home_button_text);
        _conf_composite.make.italics_rgxmatch               = _mk.italics_rgxmatch(_conf_composite.make_str.italics);
        _conf_composite.make.num_top                        = _mk.num_top(_conf_composite.make_str.num_top);
        _conf_composite.make.num_depth                      = _mk.num_depth(_conf_composite.make_str.num_depth);
        _conf_composite.make.substitute                     = _mk.substitute(_conf_composite.make_str.substitute);
        _conf_composite.make.texpdf_font                    = _mk.texpdf_font(_conf_composite.make_str.texpdf_font);
      }
      /+ conf ------------------------------------------------------------------- +/
      if ("webserv" in header_sdlang.maybe.tags) {
        _conf_composite.conf.webserv_url_root               = extractSDLangTabOrAttrib(header_sdlang, "webserv", "url_root");
        _conf_composite.conf.webserv_path                   = extractSDLangTabOrAttrib(header_sdlang, "webserv", "path");
        _conf_composite.conf.webserv_images                 = extractSDLangTabOrAttrib(header_sdlang, "webserv", "images");
        _conf_composite.conf.webserv_cgi                    = extractSDLangTabOrAttrib(header_sdlang, "webserv", "cgi");
        _conf_composite.conf.webserv_cgi_host               = extractSDLangTabOrAttrib(header_sdlang, "webserv", "cgi_host");
        _conf_composite.conf.webserv_cgi_host_path          = extractSDLangTabOrAttrib(header_sdlang, "webserv", "cgi_host_path");
        _conf_composite.conf.webserv_cgi_port               = extractSDLangTabOrAttrib(header_sdlang, "webserv", "cgi_port");
        _conf_composite.conf.webserv_cgi_user               = extractSDLangTabOrAttrib(header_sdlang, "webserv", "cgi_user");
        _conf_composite.conf.webserv_cgi_file_links         = extractSDLangTabOrAttrib(header_sdlang, "webserv", "cgi_file_links");
      }
      if ("processing" in header_sdlang.maybe.tags) {
        _conf_composite.conf.processing_path                = extractSDLangTabOrAttrib(header_sdlang, "webserv", "processing_path");
        _conf_composite.conf.processing_dir                 = extractSDLangTabOrAttrib(header_sdlang, "webserv", "processing_dir");
        _conf_composite.conf.processing_concord_max         = extractSDLangTabOrAttrib(header_sdlang, "webserv", "processing_concord_max");
      }
      if ("flag" in header_sdlang.maybe.tags) {
        _conf_composite.conf.flag_act0                      = extractSDLangTabOrAttrib(header_sdlang, "flag", "act0");
        _conf_composite.conf.flag_act1                      = extractSDLangTabOrAttrib(header_sdlang, "flag", "act1");
        _conf_composite.conf.flag_act2                      = extractSDLangTabOrAttrib(header_sdlang, "flag", "act2");
        _conf_composite.conf.flag_act3                      = extractSDLangTabOrAttrib(header_sdlang, "flag", "act3");
        _conf_composite.conf.flag_act4                      = extractSDLangTabOrAttrib(header_sdlang, "flag", "act4");
        _conf_composite.conf.flag_act5                      = extractSDLangTabOrAttrib(header_sdlang, "flag", "act5");
        _conf_composite.conf.flag_act6                      = extractSDLangTabOrAttrib(header_sdlang, "flag", "act6");
        _conf_composite.conf.flag_act7                      = extractSDLangTabOrAttrib(header_sdlang, "flag", "act7");
        _conf_composite.conf.flag_act8                      = extractSDLangTabOrAttrib(header_sdlang, "flag", "act8");
        _conf_composite.conf.flag_act9                      = extractSDLangTabOrAttrib(header_sdlang, "flag", "act9");
      }
      if ("default" in header_sdlang.maybe.tags) {
        _conf_composite.conf.default_papersize              = extractSDLangTabOrAttrib(header_sdlang, "default", "papersize");
        _conf_composite.conf.default_text_wrap              = extractSDLangTabOrAttrib(header_sdlang, "default", "text_wrap");
        _conf_composite.conf.default_emphasis               = extractSDLangTabOrAttrib(header_sdlang, "default", "emphasis");
        _conf_composite.conf.default_language               = extractSDLangTabOrAttrib(header_sdlang, "default", "language");
        _conf_composite.conf.default_digest                 = extractSDLangTabOrAttrib(header_sdlang, "default", "digest");
      }
      if ("search" in header_sdlang.maybe.tags) {
        _conf_composite.conf.search_flag                    = extractSDLangTabOrAttrib(header_sdlang, "search", "flag");
        _conf_composite.conf.search_action                  = extractSDLangTabOrAttrib(header_sdlang, "search", "action");
        _conf_composite.conf.search_db                      = extractSDLangTabOrAttrib(header_sdlang, "search", "db");
        _conf_composite.conf.search_title                   = extractSDLangTabOrAttrib(header_sdlang, "search", "title");
      }
      /+ meta ------------------------------------------------------------------- +/
      if ("classify" in header_sdlang.maybe.tags) {
        _conf_composite.meta.classify_dewey                 = extractSDLangTabOrAttrib(header_sdlang, "classify", "dewey");
        _conf_composite.meta.classify_keywords              = extractSDLangTabOrAttrib(header_sdlang, "classify", "keywords");
        _conf_composite.meta.classify_loc                   = extractSDLangTabOrAttrib(header_sdlang, "classify", "loc");
        _conf_composite.meta.classify_subject               = extractSDLangTabOrAttrib(header_sdlang, "classify", "subject");
        _conf_composite.meta.classify_topic_register        = extractSDLangTabOrAttrib(header_sdlang, "classify", "topic_register");
      }
      if ("date" in header_sdlang.maybe.tags) {
        _conf_composite.meta.date_added_to_site             = extractSDLangTabOrAttrib(header_sdlang, "date", "added_to_site");
        _conf_composite.meta.date_available                 = extractSDLangTabOrAttrib(header_sdlang, "date", "available");
        _conf_composite.meta.date_created                   = extractSDLangTabOrAttrib(header_sdlang, "date", "created");
        _conf_composite.meta.date_issued                    = extractSDLangTabOrAttrib(header_sdlang, "date", "issued");
        _conf_composite.meta.date_modified                  = extractSDLangTabOrAttrib(header_sdlang, "date", "modified");
        _conf_composite.meta.date_published                 = extractSDLangTabOrAttrib(header_sdlang, "date", "published");
        _conf_composite.meta.date_valid                     = extractSDLangTabOrAttrib(header_sdlang, "date", "valid");
      }
      if ("identifier" in header_sdlang.maybe.tags) {
        _conf_composite.meta.identifier_isbn                = extractSDLangTabOrAttrib(header_sdlang, "identifier", "isbn");
        _conf_composite.meta.identifier_oclc                = extractSDLangTabOrAttrib(header_sdlang, "identifier", "oclc");
        _conf_composite.meta.identifier_pg                  = extractSDLangTabOrAttrib(header_sdlang, "identifier", "pg");
      }
      if ("links" in header_sdlang.maybe.tags) {
        // _conf_composite.meta.links                         = extractSDLangTabOrAttrib(header_sdlang, "links", "");
      }
      if ("notes" in header_sdlang.maybe.tags) {
        _conf_composite.meta.notes_abstract                 = extractSDLangTabOrAttrib(header_sdlang, "notes", "abstract");
        _conf_composite.meta.notes_description              = extractSDLangTabOrAttrib(header_sdlang, "notes", "description");
      }
      if ("original" in header_sdlang.maybe.tags) {
        _conf_composite.meta.original_language              = extractSDLangTabOrAttrib(header_sdlang, "original", "language");
        _conf_composite.meta.original_language_char         = extractSDLangTabOrAttrib(header_sdlang, "original", "language_char");
        _conf_composite.meta.original_source                = extractSDLangTabOrAttrib(header_sdlang, "original", "source");
        _conf_composite.meta.original_title                 = extractSDLangTabOrAttrib(header_sdlang, "original", "title");
      }
      if ("publisher" in header_sdlang.maybe.tags) {
        // _conf_composite.meta.publisher                     = extractSDLangTabOrAttrib(header_sdlang, "publisher", "");
      }
      if ("rights" in header_sdlang.maybe.tags) {
        _conf_composite.meta.rights_copyright               = extractSDLangTabOrAttrib(header_sdlang, "rights", "copyright");
        _conf_composite.meta.rights_copyright_text          = extractSDLangTabOrAttrib(header_sdlang, "rights", "copyright_text");
        _conf_composite.meta.rights_copyright_audio         = extractSDLangTabOrAttrib(header_sdlang, "rights", "copyright_audio");
        _conf_composite.meta.rights_copyright_cover         = extractSDLangTabOrAttrib(header_sdlang, "rights", "copyright_cover");
        _conf_composite.meta.rights_copyright_illustrations = extractSDLangTabOrAttrib(header_sdlang, "rights", "copyright_illustrations");
        _conf_composite.meta.rights_copyright_photographs   = extractSDLangTabOrAttrib(header_sdlang, "rights", "copyright_photographs");
        _conf_composite.meta.rights_copyright_translation   = extractSDLangTabOrAttrib(header_sdlang, "rights", "copyright_translation");
        _conf_composite.meta.rights_copyright_video         = extractSDLangTabOrAttrib(header_sdlang, "rights", "copyright_video");
        _conf_composite.meta.rights_license                 = extractSDLangTabOrAttrib(header_sdlang, "rights", "license");
      }
      if (_conf_composite.meta.creator_author.empty) {
        if ("creator" in header_sdlang.maybe.tags) {
          _conf_composite.meta.creator_author               = extractSDLangTabOrAttrib(header_sdlang, "creator", "author");
          _conf_composite.meta.creator_author_email         = extractSDLangTabOrAttrib(header_sdlang, "creator", "author_email");
          _conf_composite.meta.creator_illustrator          = extractSDLangTabOrAttrib(header_sdlang, "creator", "illustrator");
          _conf_composite.meta.creator_translator           = extractSDLangTabOrAttrib(header_sdlang, "creator", "translator");
        }
        // dochead_meta["creator"]["author_raw"] = dochead_meta["creator"]["author"];
        string[] authors_arr;
        auto authors_raw_arr = _conf_composite.meta.creator_author.split(rgx.arr_delimiter);
        foreach (author_raw; authors_raw_arr) {
          authors_arr ~= author_raw.replace(rgx.raw_author_munge, "$2 $1");
        }
        _conf_composite.meta.creator_author = join(authors_arr, ", ").chomp.chomp;
      }
      if (_conf_composite.meta.title_main.empty) {
        if ("title" in header_sdlang.maybe.tags) {
          _conf_composite.meta.title_edition                = extractSDLangTabOrAttrib(header_sdlang, "title", "edition");
          // _conf_composite.meta.title_full                  = extractSDLangTabOrAttrib(header_sdlang, "title", "full");
          _conf_composite.meta.title_language               = extractSDLangTabOrAttrib(header_sdlang, "title", "language");
          _conf_composite.meta.title_main                   = extractSDLangTabOrAttrib(header_sdlang, "title", "main");
          _conf_composite.meta.title_note                   = extractSDLangTabOrAttrib(header_sdlang, "title", "note");
          _conf_composite.meta.title_sub                    = extractSDLangTabOrAttrib(header_sdlang, "title", "sub");
          _conf_composite.meta.title_subtitle               = extractSDLangTabOrAttrib(header_sdlang, "title", "subtitle");
        }
        if (_conf_composite.meta.title_main.empty) {
          Tag _maintag = header_sdlang.getTag("title");
          if (_maintag !is null) {
            if ("main" in _maintag.maybe.tags) {
              _conf_composite.meta.title_main
                = to!string(_maintag.getTagValues("main"));
            } else if ("main" !in _maintag.maybe.attributes) {
              _conf_composite.meta.title_main
                = (_maintag.values[0]).to!string; // test that this exists
            }
          }
        }
        if ((!(_conf_composite.meta.title_subtitle.empty))
        && (_conf_composite.meta.title_sub.empty)) {
          _conf_composite.meta.title_sub = _conf_composite.meta.title_subtitle;
        }
        _conf_composite.meta.title_full = (_conf_composite.meta.title_sub.empty)
        ? _conf_composite.meta.title_main
        : format(
            "%s - %s",
            _conf_composite.meta.title_main,
            _conf_composite.meta.title_sub,
          );
      }
      return _conf_composite;
    }
  }
}
static template parseSDLangConfig() {
  import
    std.exception,
    std.regex,
    std.stdio,
    std.string,
    std.traits,
    std.typecons,
    std.utf,
    std.conv : to;
  import sdlang;
  auto parseSDLangConfig(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);
    }
    return sdl_root_conf;
  }
}
/++
  return composite make from config files
+/

template confFilesSDLtoStruct() {
  import
    std.exception,
    std.regex,
    std.stdio,
    std.string,
    std.traits,
    std.typecons,
    std.utf,
    std.conv : to;
  import
    sdp.meta.conf_make_meta_structs,
    sdp.meta.rgx;
  auto configParseSDL(T)(
    T _text
  ){
    Tag sdl_root;
    try {
      sdl_root = parseSource(_text.to!string);
    }
    catch(ParseException e) {
      stderr.writeln("SDLang problem with this document header:");
      stderr.writeln(_src_header);
      // Error messages of the form:
      // myFile.sdl(5:28): Error: Invalid integer suffix.
      stderr.writeln(e.msg);
    }
    debug(sdlang) {
      writeln("header SDL:");
      writeln(__LINE__, ": ",  sdl_root.toSDLDocument());
      writeln(__LINE__, ": ",  sdl_root.maybe.namespaces);
      writeln("header make sdlang: ", sdl_root.toSDLDocument());
      writeln(__LINE__, ": ", sdl_root.getTagValues("title"));
      writeln(__LINE__, ": ", sdl_root.getTagValues("creator"));
      Tag creator = sdl_root.getTag("creator");
      if (creator !is null) {
        if ("author" in creator.maybe.tags) {
          writeln(__LINE__, ": ", creator.getTagValues("author"));
        } else if ("author" in creator.maybe.attributes) {
          writeln(__LINE__, ": ", creator.maybe.attributes["author"][0].value);
        }
      }
    }
    return sdl_root; // sdlang.ast.Tag
  }
  auto confFilesSDLtoStruct(S,L)(
    S sdl_root_config_share,
    L sdl_root_config_local,
  ){
    mixin SiSUmakeMetaStructsSDLang;
    ConfCompositePlus _conf_composite;
    foreach (conf_sdlang; [sdl_root_config_share, sdl_root_config_local]) {
      if ("make" in conf_sdlang.maybe.tags) {
        confCompositeMakeBuild _mk;
        _conf_composite.make_str.bold               = extractSDLangTabOrAttrib(conf_sdlang, "make", "bold"); // TODO
        _conf_composite.make_str.breaks             = extractSDLangTabOrAttrib(conf_sdlang, "make", "breaks");
        _conf_composite.make_str.cover_image        = extractSDLangTabOrAttrib(conf_sdlang, "make", "cover_image");
        _conf_composite.make_str.css                = extractSDLangTabOrAttrib(conf_sdlang, "make", "css");
        _conf_composite.make_str.emphasis           = extractSDLangTabOrAttrib(conf_sdlang, "make", "emphasis"); // TODO
        _conf_composite.make_str.footer             = extractSDLangTabOrAttrib(conf_sdlang, "make", "footer");
        _conf_composite.make_str.headings           = extractSDLangTabOrAttrib(conf_sdlang, "make", "headings");
        _conf_composite.make_str.home_button_image  = extractSDLangTabOrAttrib(conf_sdlang, "make", "home_button_image");
        _conf_composite.make_str.home_button_text   = extractSDLangTabOrAttrib(conf_sdlang, "make", "home_button_text");
        _conf_composite.make_str.italics            = extractSDLangTabOrAttrib(conf_sdlang, "make", "italics"); // TODO
        _conf_composite.make_str.num_top            = extractSDLangTabOrAttrib(conf_sdlang, "make", "num_top");
        _conf_composite.make_str.num_depth          = extractSDLangTabOrAttrib(conf_sdlang, "make", "num_depth");
        _conf_composite.make_str.substitute         = extractSDLangTabOrAttrib(conf_sdlang, "make", "substitute"); // TODO
        _conf_composite.make_str.texpdf_font        = extractSDLangTabOrAttrib(conf_sdlang, "make", "texpdf_font");
        _conf_composite.make.bold_rgxmatch          = _mk.bold_rgxmatch(_conf_composite.make_str.bold); //
        _conf_composite.make.breaks                 = _mk.breaks(_conf_composite.make_str.breaks);
        _conf_composite.make.cover_image            = _mk.cover_image(_conf_composite.make_str.cover_image);
        _conf_composite.make.css                    = _mk.css(_conf_composite.make_str.css);
        _conf_composite.make.emphasis_rgxmatch      = _mk.emphasis_rgxmatch(_conf_composite.make_str.emphasis);
        _conf_composite.make.footer                 = _mk.footer(_conf_composite.make_str.footer);
        _conf_composite.make.headings               = _mk.headings(_conf_composite.make_str.headings);
        _conf_composite.make.home_button_image      = _mk.home_button_image(_conf_composite.make_str.home_button_image);
        _conf_composite.make.home_button_text       = _mk.home_button_text(_conf_composite.make_str.home_button_text);
        _conf_composite.make.italics_rgxmatch       = _mk.italics_rgxmatch(_conf_composite.make_str.italics);
        _conf_composite.make.num_top                = _mk.num_top(_conf_composite.make_str.num_top);
        _conf_composite.make.num_depth              = _mk.num_depth(_conf_composite.make_str.num_depth);
        _conf_composite.make.substitute             = _mk.substitute(_conf_composite.make_str.substitute); // TODO
        _conf_composite.make.texpdf_font            = _mk.texpdf_font(_conf_composite.make_str.texpdf_font);
      }
    }
    return _conf_composite;
  }
}
/++
  default settings
+/
template SiSUmakeMetaStructsSDLang() {
  import
    std.algorithm,
    std.array,
    std.container,
    std.exception,
    std.file,
    std.getopt,
    std.json,
    std.path,
    std.process,
    std.range,
    std.regex,
    std.stdio,
    std.string,
    std.traits,
    std.typecons,
    std.uni,
    std.utf,
    std.conv : to;
  import sdp.meta.conf_make_meta_structs;
  string extractSDLangTabOrAttrib(S)(
    S conf_sdlang,
    string maintab,
    string atab
  ) {
    string _conf_composite_string = "";
    if (maintab in conf_sdlang.maybe.tags) {
      auto _maintag = conf_sdlang.getTag(maintab);
      if (
        (atab in _maintag.maybe.tags)
        && (_maintag.getTagValues(atab).length > 0)
      ) {
        debug(configsdlang) {
          writeln(
            "  ", __LINE__,
            ": sdl tag, ",
            maintab, ":", atab, ": ",
            _maintag.getTagValues(atab)[0]
          );
        }
        if (_maintag.getTagValues(atab).length == 1) {
          writeln((_maintag.getTagValues(atab)[0]).to!string);
          _conf_composite_string
            = (_maintag.getTagValues(atab)[0]).to!string;
        } else if (_maintag.getTagValues(atab).length > 1) {
          string _tmp = "";
          foreach (st; _maintag.getTagValues(atab)) {
            writeln(st.to!string, ";");
            _tmp ~= st.to!string ~ ";";
          }
          _conf_composite_string = _tmp;
        }
      } else if (
        (atab in _maintag.maybe.attributes)
        && (_maintag.attributes[atab][0].value.length > 0)
      ) {
        debug(configsdlang) {
          writeln(
            "  ", __LINE__,
            ": sdl attrib, ",
            maintab, ":", atab, ": ",
            _maintag.attributes[atab][0].value
          );
        }
        _conf_composite_string
          = (_maintag.attributes[atab][0].value).to!string;
      }
    }
    return _conf_composite_string;
  }
}