using System.Reflection; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; namespace Whalers{ public class WMarkDown{ public class Module{ public int environment; public Regex pattern; public Module(int environment, Regex pattern){ this.environment = environment; this.pattern = pattern; } }; public class Item{ public bool exists = true; public int from = -1; public int length = -1; public Match? matches = null; }; public class ListStructure{ public int separator; public char type; public char? subtype; public ListStructure(int separator, bool unordenered, char? subtype){ this.separator = separator; this.type = unordenered ? 'u' : 'o'; this.subtype = subtype; } } public class ProcessResults{ public string results; public Dictionary variables; public ProcessResults(string results, Dictionary variables){ this.results = results; this.variables = variables; } }; public class ItemMark{ public string start; public string end; public Regex pattern; public ItemMark(string start, string end, string pattern){ this.start = start; this.end = end; this.pattern = new Regex(pattern); } }; public class LinkPresententationModel{ public string title; public List avatars = new List(); public List links = new List(); public LinkPresententationModel(string title) { this.title = title; } } // Languages public const int HTML = 1 << 0; // Analyse modes public const int RAW = 0; public const int SUBITEM = 1 << 0; public const int LINKED = 1 << 1; public static Dictionary html_special_characters = new Dictionary { {"<", "lt" }, {">", "gt" }, {"&", "amp" } }; public static Dictionary quote_special = new Dictionary { { "?", "ask"}, {"!", "warning" }, {">", "answer" }, {"Q", "comment" }, {"#", "note" } }; public static WMarkDown.ItemMark item_mark = new WMarkDown.ItemMark("###@&&_", "_&&@###", @"\#{3}\@\&{2}_([0-9]+)_\&{2}\@\#{3}"); public static string re_block_html_pattern = @"^[ \t]*<\!\-{2}[ \t]*\[{2}[\t ]*(wmd|wmarkdown)[ \t]*\]{2}[\t ]*\-{2}>"; public static Regex re_block_html = new Regex(WMarkDown.re_block_html_pattern, RegexOptions.Multiline); public static Regex re_block_mark = new Regex(@"^[ \t]*(("" ?){3}|(' ?){3}|(` ?){3})[ \t]*(wmd|wmarkdown)|" + WMarkDown.re_block_html_pattern, RegexOptions.Multiline); public static Regex re_new_lines = new Regex(@"[\r\n]+"); public static Regex re_new_line = new Regex(@"\n|\r\n|\r"); public static Regex re_started_white_spaces = new Regex(@"^[ \t]*"); public static Regex re_lines = new Regex(@"^[^\r\n]+", RegexOptions.Multiline); public static Regex re_list_line = new Regex(@"^([ \t]*)(([\-\*#\+]+)|([0-9]+|[a-z]+)\.)?(.*)$", RegexOptions.IgnoreCase | RegexOptions.Multiline); public static Regex re_table_line = new Regex(@"^\|([^\r\n""']+|""([^""\\\\]+|\\\\(.|[\r\n])|[\r\n]+)*""|'([^'\\\\]+|\\\\(.|[\r\n])|[\r\n]+)*')*[\r\n]*", RegexOptions.Multiline); public static Regex re_table_item = new Regex(@"(\|+)(([^\|'""]+|""([^""\\\\]+|\\\\(.|[\r\n])|[\r\n]+)*""|'([^'\\\\]+|\\\\(.|[\r\n])|[\r\n]+)*')*)"); public static Regex re_options = new Regex(@"`{3}[ \t]*(wmd|wmarkdown)\-options[ \t]*(\n|\r\n|\r)(([^\r\n`]+|[\r\n]+|`{1,2}[^`])*)`{3}"); public static Regex re_option = new Regex(@"^([^=\r\n]+)=([^\r\n]*)$", RegexOptions.Multiline); public static Regex re_extension = new Regex(@"(([^\.\/\\\\]+)\.)?([^\.\/\\\\]+)$"); public static Regex re_characters_no_id = new Regex(@"[^a-z0-9]+", RegexOptions.Multiline); public static Regex re_phone_number = new Regex(@"^\+?[0-9 ]{5,22}$"); public static Regex re_email_address = new Regex(@"^[a-z\.0-9_\-]+@[a-z\.0-9_\-]+\.[a-z0-9]+$"); public static Regex re_class_attribute = new Regex(@"(?]+)>|(""[^""]*""|'[^']*')"); public static Regex re_start_with_white_spaces = new Regex(@"^[ \t]", RegexOptions.Multiline); public static Regex re_domain = new Regex(@"^[^\:]+\:\/{2}[^\/]+"); public static Regex re_protocol = new Regex(@"^([a-z0-9_\-]+)\:", RegexOptions.IgnoreCase); public Dictionary modules = new Dictionary { {"special_characters", new WMarkDown.Module(WMarkDown.SUBITEM, new Regex(@"\\([\(\{\[\*\\])"))}, {"title", new WMarkDown.Module(WMarkDown.RAW, new Regex(@"^((#{1,6})[\t ]*([^\r\n]+)|(={1,6})[\t ]*([^\r\n=]+)={1,6})(\n|\r\n|\r){2,}", RegexOptions.Multiline))}, {"list", new WMarkDown.Module(WMarkDown.RAW, new Regex(@"^([\-\*#\+]+|([0-9]+|[a-z]+)\.)[^\r\n]*(\n|\r\n|\r)([\t ]*(([\-\*#\+]+|([0-9]+|[a-z]+)\.)[^\r\n]*)(\n|\r\n|\r)?)*", RegexOptions.IgnoreCase| RegexOptions.Multiline))}, {"code_block", new WMarkDown.Module(WMarkDown.RAW, new Regex(@"^(""{3}([^\r\n]*)(((?!""{3})(.|[\r\n]))+)""{3}|"" "" ""([^\r\n]*)(((?!"" "" "")(.|[\r\n]))+)"" "" ""|'{3}([^\r\n]*)(((?!'{3})(.|[\r\n]))+)'{3}|' ' '([^\r\n]*)(((?!' ' ')(.|[\r\n]))+)' ' '|`{3}([^\r\n]*)(((?!`{3})(.|[\r\n]))+)`{3}|` ` `([^\r\n]*)(((?!` ` `)(.|[\r\n]))+)` ` `)", RegexOptions.Multiline))}, {"table", new WMarkDown.Module(WMarkDown.RAW, new Regex(@"^\[\|([^\r\n]*)[\r\n]+((^\|([^\]]([^\r\n""']|""([^""\\\\]+|\\\\(.|[\r\n])|[\r\n]+)*""|'([^'\\\\]+|\\\\(.|[\r\n])|[\r\n]+)*')*)?[\r\n]+)*)^\|\]", RegexOptions.Multiline))}, {"quote", new WMarkDown.Module(WMarkDown.RAW, new Regex(@"^>[ \t]*(\[\![\t ]*([^\] \t]+)([ \t]+([^\]]+))?\])?(([^\r\n]+(\r\n|[\r\n])?)*)", RegexOptions.Multiline))}, {"include", new WMarkDown.Module(WMarkDown.RAW, new Regex(@"^\[{2}include[ \t]+([^\]]+)\]{2}", RegexOptions.Multiline))}, {"media", new WMarkDown.Module(WMarkDown.SUBITEM | WMarkDown.LINKED, new Regex(@"\({2}\!(image|icon|video|audio|sound|picture)[ \t]+(""(([^""]+|[\r\n]+))""|'(([^']+|[\r\n]+))'|([^ \t\)]+))([ \t]*|[ \t]+(""(([^\\\\""]+|\\\\.|[\r\n]+)*)""|'(([^'\\\\]+|\\\\.|[\r\n]+)*)'|([^\)]+)))\){2}", RegexOptions.IgnoreCase))}, {"code_doc", new WMarkDown.Module(WMarkDown.RAW, new Regex(@"^\[{2}@(([^\]]+|\][^\]])+)\]{2}", RegexOptions.Multiline))}, {"presentation_links", new WMarkDown.Module(WMarkDown.RAW, new Regex(@"^\[{2}""{3}(([^""]+|[\r\n]+|""{1,2}[^""])*)""{3}\]{2}", RegexOptions.Multiline))}, {"paragraph", new WMarkDown.Module(WMarkDown.RAW, new Regex(@"^(([^\r\n]+(\n|\r\n|\r)?)+)", RegexOptions.Multiline))}, {"bold", new WMarkDown.Module(WMarkDown.RAW, new Regex(@"(?]+|[a-z\.0-9_\-]+@[a-z\.0-9_\-]+\.[a-z0-9]+)", RegexOptions.IgnoreCase))} }; private List ids_cache = new List(); public WMarkDown() { } private string id(string _string) { string id = WMarkDown.re_characters_no_id.Replace(_string, "-"); if (id[0] == '-') id = id.Substring(1); if (id[id.Length - 1] == '-') id = id.Substring(0, id.Length - 1); if (this.ids_cache.Contains(id)) { int i = 1; while (this.ids_cache.Contains(id + "-" + ++i)) ; id += "-" + i; } this.ids_cache.Add(id); return id; } public void reset_ids() => this.ids_cache = new List(); public string? module_title(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) { int level = ("" + (matches.Groups[2] ?? matches.Groups[4])).Length; string content = ("" + (matches.Groups[3] ?? matches.Groups[5])).Trim(); string id = this.id(content); return ("" + "" + this.analyse(content, language, WMarkDown.SUBITEM, path) + "" + "" + "" + "" + ""); } return null; } public string? module_paragraph(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return "

" + this.analyse(("" + matches.Groups[0]).Trim(), language, WMarkDown.SUBITEM, path) + "

"; return null; } public string? module_bold_italic(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return "" + this.analyse(("" + matches.Groups[1]).Trim(), language, WMarkDown.SUBITEM, path) + ""; return null; } public string? module_bold(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return "" + this.analyse(("" + matches.Groups[1]).Trim(), language, WMarkDown.SUBITEM, path) + ""; return null; } public string? module_italic(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return "" + this.analyse(("" + matches.Groups[1]).Trim(), language, WMarkDown.SUBITEM, path) + ""; return null; } public string? module_strike(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return "" + this.analyse(("" + matches.Groups[1]).Trim(), language, WMarkDown.SUBITEM, path) + ""; return null; } public string? module_underline(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return "" + this.analyse(("" + matches.Groups[1]).Trim(), language, WMarkDown.SUBITEM, path) + ""; return null; } public string? module_code_item(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return "" + this.analyse(("" + matches.Groups[1]).Trim(), language, WMarkDown.SUBITEM, path) + ""; return null; } private static string check_html_module(string type, Match matches) { bool is_radio = type == "radio"; return (""); } public string? module_checkbox(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return WMarkDown.check_html_module("checkbox", matches); return null; } public string? module_radio(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return WMarkDown.check_html_module("radio", matches); return null; } public string? module_tick(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return WMarkDown.check_html_module("tick", matches); return null; } private static string list_deployed(WMarkDown.ListStructure level, string? last_mark, int l) { string type = l != 0 && !String.IsNullOrEmpty(last_mark) ? last_mark : "" + level.subtype; bool deployable = l != 0 && type != "" && "+-".Contains(type); string deployed = ( !deployable ? "null" : type == "-" ? "false" : "true"); return " data-deployed=\"" + deployed + "\"" + (deployable ? " data-list-unprocessed=\"true\"" : ""); } private static string list_start(bool unordered, string type) { if (!unordered) { type = type.Substring(0, type.Length - 1); if (WMarkDown.re_integer.Match(type) != null) return " start=\"" + type + "\""; } return ""; } public string? module_list(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) { string html = ""; List levels = new List { new ListStructure(0, true, null) }; int l = 0; string? last_mark = null; char[] roman_number_marks = new char[] { 'a', 'A', 'i', 'I' }; char? subtype = null; foreach (string line in WMarkDown.re_new_line.Split("" + matches.Groups[0])) { Match line_matches = WMarkDown.re_list_line.Match(line); if (line_matches == null) continue; int separator_by_marks = (line_matches.Groups[3] == null ? "" : "" + line_matches.Groups[3]).Length; int separator = separator_by_marks > 1 ? separator_by_marks : ("" + line_matches.Groups[1]).Length; string type = "" + line_matches.Groups[2]; string key = "" + line_matches.Groups[4]; string _string = this.analyse("" + line_matches.Groups[5], language, WMarkDown.SUBITEM, path).Trim(); bool has_type = type != ""; bool unordered = has_type && new char[] { '-', '*', '+' }.Contains(type[type.Length - 1]); subtype = has_type ? type[type.Length - 1] : null; if (has_type) { if (levels[l].separator == separator) { levels[l].type = unordered ? 'u' : 'o'; levels[l].subtype = subtype; html += (html != "" ? "
  • " : "<" + levels[l].type + "l class=\"wmd-list\"" + WMarkDown.list_start(unordered, type) + WMarkDown.list_deployed(levels[l - 1], last_mark, l) + ( key != "" && !unordered && roman_number_marks.Contains(key[0]) ? " type=\"" + key[0] + "\"" : "") + ">") + "
  • " + _string; } else if (levels[l].separator < separator) { levels.Add(new ListStructure(separator, unordered, subtype)); html += "<" + levels[++l].type + "l class=\"wmd-list\"" + WMarkDown.list_start(unordered, type) + WMarkDown.list_deployed(levels[l - 1], last_mark, l) + ( key != "" && !unordered && roman_number_marks.Contains(key[0]) ? " type=\"" + key[0] + "\"" : "") + ">
  • " + _string; } else { while (levels[l].separator > separator) { html += "
  • "; levels.Remove(levels[l + 1]); if (l == 0) break; } html += "
  • " + _string; } } else html += " " + _string; last_mark = subtype == null ? "" : "" + subtype; } while (levels.Count != 0) { WMarkDown.ListStructure level = levels[levels.Count - 1]; html += "
  • "; levels.Remove(level); } return html; } return null; } public static string set_class(string html, string[] _class) { if (!html.Contains("class=\"")) html = (html != "" ? " " : "") + "class=\"" + String.Join(" ", _class) + "\""; return WMarkDown.re_class_attribute.Replace(html, (Match matches) => { string attribute = "" + matches.Groups[1]; string classes_str = "" + matches.Groups[2]; string closer = "" + matches.Groups[3]; string[] classes = WMarkDown.re_white_spaces.Split(classes_str); string subclasses = ""; foreach (string class_key in _class) if (!classes.Contains(class_key)) subclasses += (subclasses == "" ? "" : " ") + class_key; return attribute + classes_str + (classes_str != "" ? " " : "") + subclasses + closer; }); } public static string set_class(string html, string _class) => WMarkDown.set_class(html, [_class]); public string? module_table(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) { Dictionary html = new Dictionary { {"thead", "" }, {"tbody", "" }, {"tfoot", "" } }; string attributes = matches.Groups[1] == null ? "" : ("" + matches.Groups[1]).Trim(); string data = ("" + matches.Groups[3]).Trim(); char[] header_type_marks = new char[] { '^', '_', '=' }; string[] string_empty = new string[] { "''", "\"\"" }; string table_body = ""; while (true) { Match line_matches = WMarkDown.re_table_line.Match(data); if (line_matches == null) break; string line = "" + line_matches.Groups[0]; char cell_type = header_type_marks.Contains(line[1]) ? 'h' : 'd'; string[] tags = ( line[1] == '^' ? ["thead"] : line[1] == '_' ? ["tfoot"] : line[1] == '=' ? ["thead", "tfoot"] : ["tbody"]); string row = ""; if (cell_type == 'h') line = line[0] + line.Substring(2); while (true) { Match cell_matches = WMarkDown.re_table_item.Match(line); if (cell_matches == null) break; int column_span_i = ("" + cell_matches.Groups[1]).Length; string colunm_span = column_span_i > 1 ? " colspan=\"" + column_span_i + "\"" : ""; string content = cell_matches.Groups[2] == null ? "" : ("" + cell_matches.Groups[2]).Trim(); row += "" + this.analyse( content != "" && string_empty.Contains("" + content[0] + content[content.Length - 1]) ? content.Substring(1, content.Length - 2) : content, WMarkDown.HTML, WMarkDown.SUBITEM, path ) + ""; line = line.Substring(cell_matches.Index + cell_matches.Length); } row += ""; for (int i = 0, l = tags.Length; i < l; i++) { if (i != 0) html[tags[i]] = row + html[tags[i]]; else html[tags[i]] += row; } data = data.Substring(line_matches.Index + line_matches.Length); } foreach (string tag in html.Keys) if (html[tag] != "") table_body += "<" + tag + ">" + html[tag] + ""; return ("
    " + "" + table_body + "
    " + "
    "); } return null; } public string? module_exclude(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return "" + (matches.Groups[1] == null ? "" : "" + matches.Groups[1]) + ""; return null; } public string? module_link(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) { string raw_url = ("" + (matches.Groups[4] ?? matches.Groups[11] ?? matches.Groups[14])).Trim(); string url = ( WMarkDown.re_phone_number.Match(raw_url) != null ? "tel:" + raw_url.Replace(" ", "") : WMarkDown.re_email_address.Match(raw_url) != null ? "mailto:" + raw_url : raw_url); string text = ( matches.Groups[2] != null ? "" + matches.Groups[2] : matches.Groups[13] != null ? "" + matches.Groups[13] : raw_url); Match protocol_matches = WMarkDown.re_protocol.Match(url); return "" + this.analyse(text.Trim(), language, WMarkDown.SUBITEM | WMarkDown.LINKED, path) + ""; } return null; } public string? module_quote(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) { string? type = matches.Groups[2] == null ? null : "" + matches.Groups[2]; string? type_text = matches.Groups[4] == null ? null : "" + matches.Groups[4]; bool has_type = !String.IsNullOrEmpty(type); if (has_type && WMarkDown.quote_special.ContainsKey(type)) type = WMarkDown.quote_special[type]; return ("
    " + (has_type ? ("
    " + (type[0] == '@' ? ( "" + "" + type.Substring(1) + "" ) : ( "" + (type_text != "" ? "" + type_text + "" : "") )) + "
    ") : "") + "
    " + this.analyse("" + matches.Groups[5], language, WMarkDown.SUBITEM, path) + "
    " + "
    "); } return null; } public static string? code_block_data(string key, string value, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return ("
  • " + "" + "" + key + "" + "" + value + "" + "
  • "); return null; } public static string? code_block_data(string key, int value, int language = WMarkDown.HTML, string? path = null) => WMarkDown.code_block_data(key, value, language, path); public static string filter_html_special_characters(string _string) { int l = _string.Length; int?[] index = Enumerable.Repeat(-1, l).ToArray(); string response = ""; string[] characters = WMarkDown.html_special_characters.Keys.ToArray(); int m = characters.Length; while (true) { int? i = null; for(int j = 0; j < l; j++) { if (index[j] == null) continue; if (index[j] < 0 && (index[j] = _string.IndexOf(characters[j])) < 0) index[j] = null; if(i == null || index[i ?? 0] > index[j]) i = j; } if(i == null) { response += _string; break; } int length = index[i ?? 0] ?? 0; response += _string.Substring(0, length) + "&" + WMarkDown.html_special_characters[characters[i ?? 0]] + ";"; _string = _string.Substring(length + 1); for (int j = 0; j < l; j++) if (index[j] != null) index[j] -= length + 1; } return response; } public static string? module_code_block(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) { string type = ""; string content = ""; for(int i = 2; i < 6; i += 4) { type = "" + matches.Groups[i]; content = "" + matches.Groups[i + 1]; if(type != "" || content != "") { type = (type == "" ? "unamed" : type.Trim().ToLower()); break; } } if(type != "") { string[] lines = WMarkDown.re_new_line.Split(content).Skip(2).ToArray(); string lines_string = ""; foreach (string line in lines) lines_string += "
  • "; return ("
    " + "
      " + "
    • " + WMarkDown.code_block_data("type", type, language) + WMarkDown.code_block_data("characters", content.Length, language) + WMarkDown.code_block_data("lines", lines.Length, language) + "
    " + "
    " + "
      " + lines_string + "
    " + "
    " + WMarkDown.filter_html_special_characters(content) + "
    " + "
    " + "
    "); } return "UNKNOWN_BLOCK"; } return null; } public string? module_special_characters(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) return "" + matches.Groups[1]; return null; } public static string? load_file(string path) { if(File.Exists(path)) try { return File.ReadAllText(path); }catch(Exception exception) { }; return null; } public string? module_include(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) { string relative_path = "" + matches.Groups[1]; string new_path = path + relative_path; string[] extension = Array.ConvertAll(WMarkDown.re_extension.Match(new_path).Groups.Values.Skip(1).ToArray(), (Group group) => "" + group); string? content = WMarkDown.load_file(new_path); string directory = (Path.GetDirectoryName(new_path) ?? "") + "/"; string? results = ( content == null ? null : String.Join('.', extension) == "w.md" ? this.process(content, language, directory).results : extension[extension.Length - 1] == "md" ? this.analyse(content, language, WMarkDown.RAW, directory) : content); return ("
    " + "" + (results ?? "") + "
    "); } return null; } public static string build_html_image(List links, string type = "image", string? title = null) { bool has_title = !String.IsNullOrEmpty(title); string attributes = has_title ? " title=\"" + title + "\" alt=\"" + title + "\"" : ""; string links_html = ""; foreach (string link in links) links_html += ""; return ("" + "" + "" + "" + (has_title ? "" + title + "" : "") + ""); } public string? module_media(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) { string type = ("" + matches.Groups[1]).ToLower(); List links = WMarkDown.re_white_spaces.Split("" + (matches.Groups[3] ?? matches.Groups[5] ?? matches.Groups[7])).ToList(); string text = ("" + (matches.Groups[10] ?? matches.Groups[12] ?? matches.Groups[14])).Trim(); switch (type) { case "image": case "picture": case "icon": return WMarkDown.build_html_image(links, type, text); case "video": switch (links[0]) { case "youtube.com": case "youtu.be": type = "youtube"; break; case "vimeo.com": type = "vimeo"; break; } return ("" + "" + ( type == "youtube" ? "YOUTUBE" : type == "vimeo" ? "VIMEO" : "") + ""); case "sound": case "audio": switch (links[0]) { case "soundcloud.com": type = "soundcloud"; break; } return ("" + "" + ( type == "soundcloud" ? "SOUNDCLOUD" : "") + ""); } return null; } return null; } public static string mark_replace(string _string, Match matches, List fragments) { if(matches != null) { _string = _string.Substring(0, matches.Index) + WMarkDown.item_mark.start + fragments.Count + WMarkDown.item_mark.end + _string.Substring(matches.Index + matches.Length); fragments.Add("" + matches.Groups[0]); } return _string; } public static string restore_marks(string _string, List fragments) { while (true) { Match matches = WMarkDown.item_mark.pattern.Match(_string); if (matches == null) break; int i = ("" + matches.Groups[1]).Length; _string = _string.Substring(0, matches.Index) + (i >= 0 && i < fragments.Count ? fragments[i] : "") + _string.Substring(matches.Index + matches.Length); } return _string; } private static string doc_typed_format(string typed) => WMarkDown.filter_html_special_characters(typed.Replace(" ", "").Replace(",", ", ")); public string? module_code_doc(Match matches, int language = WMarkDown.HTML, string? path = null) { if((language & WMarkDown.HTML) != 0) { string data = ("" + matches.Groups[1]).Trim(); Match _base = WMarkDown.re_code_doc.Match(data); string return_type = WMarkDown.doc_typed_format(_base.Groups[2] == null ? "void" : "" + _base.Groups[2]); string access = _base.Groups[3] == null ? "public" : "" + _base.Groups[3]; string? name_space = _base.Groups[5] == null ? null : "" + _base.Groups[5]; string environment = _base.Groups[6] == null ? "global" : "" + _base.Groups[6]; string method = "" + _base.Groups[7]; string? parameters = _base.Groups[8] == null ? null : "" + _base.Groups; bool has_parameters = parameters != null; string? default_value = _base.Groups[11] == null ? null : "" + _base.Groups[11]; string full_method = (String.IsNullOrEmpty(name_space) ? "" : name_space + ".") + method.Trim(); string arguments = ""; string arguments_definition = ""; string header = ("" + "Name" + "Required" + "Nullable" + "Typed" + "Default Value" + ""); List fragments = new List(); int arguments_l = 0; switch (access) { case "?": access = "protected"; break; case "!": access = "protected"; break; }; switch (environment) { case ":": environment = "static"; break; case ".": environment = "object"; break; }; if (parameters != "") { while (true) { matches = WMarkDown.re_code_doc_subarguments.Match(parameters); if (matches != null) parameters = WMarkDown.mark_replace(parameters, matches, fragments); else break; } } else parameters = ""; foreach(string parameter in parameters.Split(",")) { matches = WMarkDown.re_code_doc_arguments.Match(parameter.Trim()); if(matches != null) { string scopes = "" + matches.Groups[1]; bool required = scopes.Contains("!"); bool nullish = scopes.Contains("?"); string typed = WMarkDown.doc_typed_format(WMarkDown.restore_marks("" + matches.Groups[2], fragments)); string name = ("" + matches.Groups[3]).Trim(); string default_subvalue = WMarkDown.filter_html_special_characters(WMarkDown.restore_marks(("" + matches.Groups[5]).Trim(), fragments)); arguments += ("" + (required ? "Required" : "") + (nullish ? "Nullish" : "") + "" + typed + "" + "" + name + "" + (default_subvalue != "" ? "" + default_subvalue + "" : "") + ""); arguments_definition = ("" + "" + name + "" + "" + (required ? "True" : "False") + "" + "" + (nullish ? "True" : "False") + "" + "" + typed + "" + "" + default_subvalue + "" + ""); arguments_l++; } } return ("
    " + "" + full_method + "" + "
    " + "" + return_type + "" + "" + environment + "" + "" + access + "" + "" + full_method + "" + (has_parameters ? "" + arguments + "" : "") + (default_value != "" ? "" + default_value + "" : "") + "
    " + "
    " + "" + "" + header + "" + "" + arguments_definition + "" + "" + header + "" + "
    " + "
    " + "
    "); } return null; } public string? module_color_sample(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) { string color = "" + (matches.Groups[2] ?? matches.Groups[3]); return ("" + "" + "" + color + "" + ""); } return null; } public string? module_presentation_links(Match matches, int language = WMarkDown.HTML, string? path = null) { if ((language & WMarkDown.HTML) != 0) { List items = new List(); int j = -1; string html_avatars = ""; string html_list = ""; foreach (string line in WMarkDown.re_new_lines.Split("" + matches.Groups[1])) { bool has_spaces = WMarkDown.re_start_with_white_spaces.Match(line) != null; string data = line.Trim(); if (data == "") continue; if (has_spaces) { if (j == -1) continue; if (data[0] == '*') { items[j].avatars.Add(data.Substring(1)); if (data.Contains(".k3y.pw/")) items[j].avatars.Add(data.Substring(1).Replace(".k3y.pw/", ".local/")); } else items[j].links.Add(data); } else { j++; items.Add(new LinkPresententationModel(line)); } } for(int i = 0, l = items.Count; i < l; i++) { string avatars_html = ""; string links_html = ""; foreach (string avatar in items[i].avatars) avatars_html += ""; foreach (string link in items[i].links) links_html += "
  • <" + link + "
  • "; html_avatars += ("
  • " + (items[i].links.Count != 0 ? "" + WMarkDown.build_html_image(items[i].avatars) + "" : WMarkDown.build_html_image(items[i].avatars)) + avatars_html + "
  • "); html_list += ("
  • " + "" + items[i].title + "" + "
      " + links_html + "
    " + "
  • "); } return ("
    " + "
      " + html_avatars + "
    " + "
      " + html_list + "
    " + "
    "); } return null; } public static string remove_default_tabulations(string data) { int spaces = data.Length; foreach(string line in WMarkDown.re_new_lines.Split(data)) { if (line == "") continue; int white_spaces = ("" + WMarkDown.re_started_white_spaces.Match(line).Groups[0]).Length; if (white_spaces < spaces) spaces = white_spaces; } return WMarkDown.re_lines.Replace(data, (Match matches) => ("" + matches.Groups[0]).Substring(spaces)); } private string build(string data, int language, string? path) { return ("
    " + this.analyse(WMarkDown.remove_default_tabulations(data), language, WMarkDown.RAW, path) + "
    " + "
    "); } public WMarkDown.ProcessResults process(string data, int language = WMarkDown.HTML, string? path = null) { string results = ""; Dictionary variables = new Dictionary(); Match options = WMarkDown.re_options.Match(data); if(options != null) { string options_data = "" + options.Groups[3]; while (true) { Match option = WMarkDown.re_option.Match(options_data); if (option == null) break; variables[("" + option.Groups[1]).Trim()] = ("" + option.Groups[2]).Trim(); options_data = options_data.Substring(option.Index); } data = data.Substring(0, options.Index) + data.Substring(options.Index + options.Length); } while (true) { Match matches = WMarkDown.re_block_mark.Match(data); if(matches == null) { results += data; break; } string mark = "" + matches.Groups[1]; Regex re_close = mark != "" ? new Regex(@"^\s*" + mark, RegexOptions.Multiline) : WMarkDown.re_block_html; results += data.Substring(0, matches.Index); data = data.Substring(matches.Index + matches.Length); Match close_matches = re_close.Match(data); if(close_matches != null) { results += this.build(data.Substring(0, close_matches.Index), language, path); data = data.Substring(close_matches.Index + close_matches.Length); } else { results += this.build(data, language, path); break; } } return new WMarkDown.ProcessResults(results, variables); } public string analyse(string data, int language = WMarkDown.HTML, int mode = WMarkDown.RAW, string? path = null) { string response = ""; string[] keys = this.modules.Keys.ToArray(); int l = keys.Length; Dictionary items = new Dictionary(); for (int i = 0; i < l; i++) items[keys[i]] = new WMarkDown.Item(); while (true) { string? selected = null; l = data.Length; foreach(KeyValuePair block in items) { string key = block.Key; WMarkDown.Item item = block.Value; if (!item.exists) continue; if(item.from < 0) { if((item.matches = this.modules[key].pattern.Match(data)) != null) item.length = (item.from = item.matches.Index) + item.matches.Length; else { item.exists = false; continue; } } if (item.from < l) { l = item.from; selected = key; } } if(selected == null) { response += data; break; } MethodInfo? method = this.GetType().GetMethod("module_" + (selected ?? "")); int to = items[selected].from + items[selected].length; if (method != null) { string fragment = data.Substring(items[selected].from, items[selected].length); response += data.Substring(0, items[selected].from) + method.Invoke(this, [items[selected].matches, language, path]); } else response += data.Substring(0, to); foreach (WMarkDown.Item item in items.Values) if (item.exists) item.from -= to; } return response; } } }