diff --git a/CSharp/WMarkDown.cs b/CSharp/WMarkDown.cs new file mode 100644 index 0000000..3810c16 --- /dev/null +++ b/CSharp/WMarkDown.cs @@ -0,0 +1,1209 @@ +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; + } + + } +} \ No newline at end of file diff --git a/Public/ecma/WMarkDown.ecma.js b/Public/ecma/WMarkDown.ecma.js index c073c22..0b402eb 100644 --- a/Public/ecma/WMarkDown.ecma.js +++ b/Public/ecma/WMarkDown.ecma.js @@ -282,6 +282,17 @@ const WMarkDown = function(inputs){ return box; }; + this.get_anp = item => { + + while(!item.classList.contains("anp") && (item = item.parentNode)) + if(!item.classList){ + item = null; + break; + }; + + return item; + }; + /** * @returns {void} * @access private @@ -298,10 +309,21 @@ const WMarkDown = function(inputs){ /** @type {HTMLElement} */ content = block.querySelector(".content"), /** @type {String} */ - type = block.getAttribute("data-type").toLowerCase(); + type = block.getAttribute("data-type").toLowerCase(), + /** @type {HTMLElement|null} */ + anp_item = self.get_anp(block), + /** @type {Boolean} */ + dark_mode = ( + anp_item ? (anp_item.getAttribute("data-gui_mode") == "dark" || (anp_item.getAttribute("data-gui-mode") == "default" && anp_item.getAttribute("data-dark-mode") == "true")) : + window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches); block.setAttribute("data-processed", true); + mermaid.initialize({ + theme : dark_mode ? "dark" : "default", + themeVariables : {fontSize : "16px"} + }); + if(["math", "maths", "mathjax"].includes(language)){ build_special_type(content, "MathJax").innerHTML = MathJax.tex2chtml(content.innerText).outerHTML; MathJax.startup.document.clear(); diff --git a/Public/json/WMarkDown.dict.es.kyman.json b/Public/json/WMarkDown.dict.es.kyman.json index b3a87b2..b09e02e 100644 --- a/Public/json/WMarkDown.dict.es.kyman.json +++ b/Public/json/WMarkDown.dict.es.kyman.json @@ -657,4 +657,11 @@ "https://x.com/litecoin", "https://www.reddit.com/r/litecoin/" ] +], [ + [ + ["/\\bsrx06\\b/gi", "Grillo Team"], + ["/\\bgri(ll+|y)o[ \t]*t(e[ae]|i)[mn]\\b/gi", "Grillo Team"] + ], [ + "Grupo profesional de las TIC." + ], [] ]] \ No newline at end of file diff --git a/Public/json/WMarkDown.dict.es.kyman.padron.json b/Public/json/WMarkDown.dict.es.kyman.padron.json new file mode 100644 index 0000000..750bd13 --- /dev/null +++ b/Public/json/WMarkDown.dict.es.kyman.padron.json @@ -0,0 +1,144 @@ +[[ + [ + ["/\\bpadr[oó]n *municipal *(de *)?habitantes\\b/ig", "Padrón Municipal de Habitantes"], + ["/\\bpadr[oó]n *(de *)?habitantes\\b/ig", "Padrón de Habitantes"], + ["/\\bpadr[oó]n\\b/ig", "Padrón"], + ["/(? *, .wmarkdown-web footer > * { flex: auto; align-self: center; } diff --git a/Public/scss/WMarkDown.web.css.map b/Public/scss/WMarkDown.web.css.map index 131d1a9..8891335 100644 --- a/Public/scss/WMarkDown.web.css.map +++ b/Public/scss/WMarkDown.web.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "AAAA,UAAS;EACL,MAAM,EAAG,IAAI;EACb,MAAM,EAAG,GAAG;EACZ,QAAQ,EAAG,MAAM;;AAQrB,cAAc;ECiBV,QAAQ,EAAG,QAAQ;EACnB,GAAG,EAAG,GAAG;EACT,IAAI,EAAG,GAAG;EACV,KAAK,EAAG,IAAI;EACZ,MAAM,EAAG,IAAI;EACb,QAAQ,EAAG,MAAM;EA4Hb,gBAAgB,ECzJV,OAAO;ED0Jb,KAAK,EC3JC,IAAI;EDgCd,kFAAqB;IAAC,WAAW,ECtBtB,QAAQ;EDuBnB;;;6CAG0B;IAAC,WAAW,ECxB7B,aAAa;EDyBtB,kCAAmB;IAAC,WAAW,ECvBtB,OAAO;EDwBhB,2FAA4B;IAAC,SAAS,EAAG,GAAG;EAE5C,sEAAuC;IAAC,OAAO,EAAG,IAAI;EAEtD,sBAAO;IACH,eAAe,EAAG,IAAI;IACtB,UAAU,EAAG,UAAU;EAE3B,4NAA6F;IACzF,MAAM,EAAG,OAAO;IAChB,mBAAmB,ECpBT,EAAE;IDqBZ,4QAAO;MAAC,mBAAmB,ECtBlB,IAAG;EDwBhB,4NAA6F;IACzF,KAAK,EDhDI,OAAO;ICiDhB,mBAAmB,EAAG,KAAK;IAC3B,4QAAO;MAAC,KAAK,EDjDF,OAAO;ECmDtB,0DAA2B;IACvB,KAAK,EAAG,OAAqC;IAC7C,mBAAmB,EAAG,KAAK;IAC3B,sEAAO;MAAC,KAAK,EAAG,OAAuC;EAO3D,gDAAiB;IAAC,mBAAmB,EAAG,KAAK;EAC7C,8GAA+C;IAC3C,YAAY,EAAG,mBAAyB;IACxC,UAAU,EAAG,qBAA2B;IACxC,mBAAmB,EAAG,6BAA6B;IACnD,sIAAO;MACH,YAAY,EAAG,mBAA2B;MAC1C,UAAU,EAAG,qBAA6B;EAIlD,mCAAoB;IAChB,KAAK,EAAG,OAAqC;IAC7C,yCAAO;MAAC,KAAK,EAAG,OAAuC;EAIvD,iBAAM;IAAC,SAAS,EAAG,KAAmB;EAAtC,iBAAM;IAAC,SAAS,EAAG,KAAmB;EAAtC,iBAAM;IAAC,SAAS,EAAG,KAAmB;EAAtC,iBAAM;IAAC,SAAS,EAAG,KAAmB;EAAtC,iBAAM;IAAC,SAAS,EAAG,GAAmB;EAG1C,oCAAK;IACD,OAAO,EAAG,OAAO;EAGrB,iEAAkB;IACd,QAAQ,EAAG,QAAQ;IACnB,IAAI,EAAG,GAAG;IACV,KAAK,EAAG,IAAI;EAEhB,4CAAa;IACT,QAAQ,EAAG,MAAM;IACjB,OAAO,EAAG,IAAI;IACd,cAAc,EAAG,GAAG;IAxFxB,UAAU,EACN,gHAIuB;IAqFvB,oDAAG;MACC,IAAI,EAAG,IAAI;MACX,UAAU,EAAG,MAAM;EAG3B,qBAAM;IACF,GAAG,EAAG,GAAG;IACT,MAAM,EC1FG,GAAG;ID2FZ,OAAO,EAAG,EAAE;IACZ,wBAAE;MACE,MAAM,EAAG,QAAQ;MACjB,OAAO,EAAG,GAAG;MACb,SAAS,EAAG,GAAG;MACf,SAAS,EAAG,MAAM;MAClB,+BAAM;QAAC,MAAM,EAAG,KAAyB;MACzC,4BAAG;QACC,KAAK,EAAG,IAAI;QACZ,MAAM,EAAG,KAAyB;QAClC,mCAAM;UAAC,OAAO,EAAG,IAAI;MAEzB,oCAAS;QACL,SAAS,EAAG,KAAyB;QACrC,MAAM,EAAG,cAAiE;MAE9E,iCAAM;QACF,OAAO,EAAG,YAAY;QACtB,cAAc,EAAG,GAAG;EAIhC,mBAAI;IACA,GAAG,EClHM,GAAG;IDmHZ,MAAM,EClHG,KAAK;IDmHd,OAAO,EAAG,KAAK;IACf,OAAO,EAAG,EAAE;IACZ,QAAQ,EAAG,IAAI;IACf,UAAU,EAAG,UAAU;EAE3B,qBAAM;IACF,MAAM,EAAG,GAAG;IACZ,MAAM,EC1HG,KAAK;ID2Hd,OAAO,EAAG,EAAE;EAiBhB,yBAAU;IACN,KAAK,EAAG,IAAI;IACZ,UAAU,EAAG,MAAM;IACnB,4BAAE;MACE,eAAe,EAAG,IAAI;MACtB,MAAM,EAAG,GAAG;MACZ,OAAO,EAAG,GAAG;IAEjB,4BAAE;MACE,OAAO,EAAG,YAAY;MACtB,MAAM,EAAG,QAAQ;EAIzB,wBAAS;IACL,OAAO,EAAG,IAAI;IACd,cAAc,EAAG,GAAG;IACpB,eAAe,EAAG,MAAM;IACxB,QAAQ,EAAG,QAAQ;IACnB,IAAI,EAAG,GAAG;IACV,MAAM,EAAG,GAAG;IACZ,KAAK,EAAG,IAAI;IACZ,UAAU,EAAG,MAAM;IACnB,OAAO,EAAG,SAAS;IACnB,WAAW,EAAG,GAAG;IACjB,SAAS,EAAG,KAAK;IACjB,UAAU,EAAG,UAAU;EAG3B,uBAAQ;IACJ,OAAO,EAAG,IAAI;IACd,cAAc,EAAG,GAAG;IACpB,UAAU,EAAG,MAAM;IACnB,MAAM,EAAG,QAAQ;IACjB,UAAU,EAAG,MAAM;IACnB,UAAU,EAAG,UAAU;IACvB,4BAAI;MACA,IAAI,EAAG,IAAI;MACX,UAAU,EAAG,MAAM;IAEvB,2BAAG;MAAC,cAAc,EAAG,MAAM;IAC3B,2BAAG;MACC,KAAK,EAAG,IAAI;MACZ,MAAM,EAAG,KAAK;MACd,MAAM,EAAG,SAAS;EDhM1B,mBAAI;IAAC,QAAQ,EAAG,IAAI;EACpB,iCAAgB;IAAC,SAAS,EAAG,IAAI", +"mappings": "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", "sources": ["WMarkDown.web.scss","../../../AnP/Public/scss/AnP.common.scss","../../../AnP/Public/scss/AnP.settings.scss"], "names": [], "file": "WMarkDown.web.css" diff --git a/Python/WMarkDown.py b/Python/WMarkDown.py index afcd26b..bf92666 100644 --- a/Python/WMarkDown.py +++ b/Python/WMarkDown.py @@ -66,38 +66,38 @@ class WMarkDown: def __init__(self) -> None: self.modules:dict[str, tuple[int, REPattern]] = { - "special_characters" : (self.SUBITEM, RECompile(r'\\([\(\{\[\*\\])')), - "title" : (self.RAW, RECompile(r'^((#{1,6})[\t ]*([^\r\n]+)|(={1,6})[\t ]*([^\r\n=]+)={1,6})(\n|\r\n|\r){2,}', RE_MULTILINE)), - "list" : (self.RAW, RECompile(r'^([\-\*#\+]+|([0-9]+|[a-z]+)\.)[^\r\n]*(\n|\r\n|\r)([\t ]*(([\-\*#\+]+|([0-9]+|[a-z]+)\.)[^\r\n]*)(\n|\r\n|\r)?)*', RE_IGNORE_CASE | RE_MULTILINE)), - "code_block" : (self.RAW, RECompile(r'^("{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]))+)` ` `)', RE_MULTILINE)), - "table" : (self.RAW, RECompile(r'^\[\|([^\r\n]*)[\r\n]+((^\|([^\]]([^\r\n"\']|"([^"\\\\]+|\\\\(.|[\r\n])|[\r\n]+)*"|\'([^\'\\\\]+|\\\\(.|[\r\n])|[\r\n]+)*\')*)?[\r\n]+)*)^\|\]', RE_MULTILINE)), - "quote" : (self.RAW, RECompile(r'^>[ \t]*(\[\![\t ]*([^\] \t]+)([ \t]+([^\]]+))?\])?(([^\r\n]+(\r\n|[\r\n])?)*)', RE_MULTILINE)), - "include" : (self.RAW, RECompile(r'^\[{2}include[ \t]+([^\]]+)\]{2}', RE_MULTILINE)), - "media" : (self.SUBITEM | self.LINKED, RECompile(r'\({2}\!(image|icon|video|audio|sound|picture)[ \t]+("(([^"]+|[\r\n]+))"|\'(([^\']+|[\r\n]+))\'|([^ \t\)]+))([ \t]*|[ \t]+("(([^\\\\"]+|\\\\.|[\r\n]+)*)"|\'(([^\\\\\']+|\\\\.|[\r\n]+)*)\'|([^\)]+)))\){2}', RE_IGNORE_CASE)), - "code_doc" : (self.RAW, RECompile(r'^\[{2}@(([^\]]+|\][^\]])+)\]{2}', RE_MULTILINE)), - "presentation_links" : (self.RAW, RECompile(r'^\[{2}"{3}(([^"]+|[\r\n]+|"{1,2}[^"])*)"{3}\]{2}', RE_MULTILINE)), - "paragraph" : (self.RAW, RECompile(r'^(([^\r\n]+(\n|\r\n|\r)?)+)', RE_MULTILINE)), - # "bold_italic" : (self.SUBITEM | self.LINKED, RECompile(r'\*{3}(([^\*]+|\*{1,2}[^\*]|[\r\n]+|\\\*)*)\*{3}')), - # "bold_italic" : (self.SUBITEM | self.LINKED, RECompile(r'(?]+|[a-z\.0-9_\-]+@[a-z\.0-9_\-]+\.[a-z0-9]+)', RE_IGNORE_CASE)) + "special_characters" : (WMarkDown.SUBITEM, RECompile(r'\\([\(\{\[\*\\])')), + "title" : (WMarkDown.RAW, RECompile(r'^((#{1,6})[\t ]*([^\r\n]+)|(={1,6})[\t ]*([^\r\n=]+)={1,6})(\n|\r\n|\r){2,}', RE_MULTILINE)), + "list" : (WMarkDown.RAW, RECompile(r'^([\-\*#\+]+|([0-9]+|[a-z]+)\.)[^\r\n]*(\n|\r\n|\r)([\t ]*(([\-\*#\+]+|([0-9]+|[a-z]+)\.)[^\r\n]*)(\n|\r\n|\r)?)*', RE_IGNORE_CASE | RE_MULTILINE)), + "code_block" : (WMarkDown.RAW, RECompile(r'^("{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]))+)` ` `)', RE_MULTILINE)), + "table" : (WMarkDown.RAW, RECompile(r'^\[\|([^\r\n]*)[\r\n]+((^\|([^\]]([^\r\n"\']|"([^"\\\\]+|\\\\(.|[\r\n])|[\r\n]+)*"|\'([^\'\\\\]+|\\\\(.|[\r\n])|[\r\n]+)*\')*)?[\r\n]+)*)^\|\]', RE_MULTILINE)), + "quote" : (WMarkDown.RAW, RECompile(r'^>[ \t]*(\[\![\t ]*([^\] \t]+)([ \t]+([^\]]+))?\])?(([^\r\n]+(\r\n|[\r\n])?)*)', RE_MULTILINE)), + "include" : (WMarkDown.RAW, RECompile(r'^\[{2}include[ \t]+([^\]]+)\]{2}', RE_MULTILINE)), + "media" : (WMarkDown.SUBITEM | WMarkDown.LINKED, RECompile(r'\({2}\!(image|icon|video|audio|sound|picture)[ \t]+("(([^"]+|[\r\n]+))"|\'(([^\']+|[\r\n]+))\'|([^ \t\)]+))([ \t]*|[ \t]+("(([^\\\\"]+|\\\\.|[\r\n]+)*)"|\'(([^\\\\\']+|\\\\.|[\r\n]+)*)\'|([^\)]+)))\){2}', RE_IGNORE_CASE)), + "code_doc" : (WMarkDown.RAW, RECompile(r'^\[{2}@(([^\]]+|\][^\]])+)\]{2}', RE_MULTILINE)), + "presentation_links" : (WMarkDown.RAW, RECompile(r'^\[{2}"{3}(([^"]+|[\r\n]+|"{1,2}[^"])*)"{3}\]{2}', RE_MULTILINE)), + "paragraph" : (WMarkDown.RAW, RECompile(r'^(([^\r\n]+(\n|\r\n|\r)?)+)', RE_MULTILINE)), + # "bold_italic" : (WMarkDown.SUBITEM | WMarkDown.LINKED, RECompile(r'\*{3}(([^\*]+|\*{1,2}[^\*]|[\r\n]+|\\\*)*)\*{3}')), + # "bold_italic" : (WMarkDown.SUBITEM | WMarkDown.LINKED, RECompile(r'(?]+|[a-z\.0-9_\-]+@[a-z\.0-9_\-]+\.[a-z0-9]+)', RE_IGNORE_CASE)) } self.__ids_cache:tuple[str] = tuple() def __id(self, string:str) -> str: - id:str = self.re_characters_no_id.sub(r'-', string).lower() + id:str = WMarkDown.re_characters_no_id.sub(r'-', string).lower() if id[0] == '-': id = id[1:] @@ -121,14 +121,14 @@ class WMarkDown: self.__ids_cache = tuple() def module_title(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: level:str = str(len(matches.group(2) or matches.group(4))) content:str = (matches.group(3) or matches.group(5)).strip() id:str = self.__id(content) return ('' + - '' + self.analyse(content, language, self.SUBITEM, path) + '' + + '' + self.analyse(content, language, WMarkDown.SUBITEM, path) + '' + '' + '' + '' + @@ -136,38 +136,38 @@ class WMarkDown: return None def module_paragraph(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: - return '

    ' + self.analyse(matches.group(0).strip(), language, self.SUBITEM, path) + '

    ' + if language & WMarkDown.HTML: + return '

    ' + self.analyse(matches.group(0).strip(), language, WMarkDown.SUBITEM, path) + '

    ' return None def module_bold_italic(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: - return '' + self.analyse(matches.group(1), language, self.SUBITEM, path) + '' + if language & WMarkDown.HTML: + return '' + self.analyse(matches.group(1), language, WMarkDown.SUBITEM, path) + '' return None def module_bold(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: - return '' + self.analyse(matches.group(1), language, self.SUBITEM, path) + '' + if language & WMarkDown.HTML: + return '' + self.analyse(matches.group(1), language, WMarkDown.SUBITEM, path) + '' return None def module_italic(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: - return '' + self.analyse(matches.group(1), language, self.SUBITEM, path) + '' + if language & WMarkDown.HTML: + return '' + self.analyse(matches.group(1), language, WMarkDown.SUBITEM, path) + '' return None def module_strike(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: - return '' + self.analyse(matches.group(1), language, self.SUBITEM, path) + '' + if language & WMarkDown.HTML: + return '' + self.analyse(matches.group(1), language, WMarkDown.SUBITEM, path) + '' return None def module_underline(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: - return '' + self.analyse(matches.group(1), language, self.SUBITEM, path) + '' + if language & WMarkDown.HTML: + return '' + self.analyse(matches.group(1), language, WMarkDown.SUBITEM, path) + '' return None def module_code_item(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: - return '' + self.analyse(matches.group(1), language, self.SUBITEM, path) + '' + if language & WMarkDown.HTML: + return '' + self.analyse(matches.group(1), language, WMarkDown.SUBITEM, path) + '' return None @staticmethod @@ -185,20 +185,20 @@ class WMarkDown: @classmethod def module_checkbox(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: - return self.__check_html_module("checkbox", matches) + if language & WMarkDown.HTML: + return WMarkDown.__check_html_module("checkbox", matches) return None @classmethod def module_radio(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: - return self.__check_html_module("radio", matches) + if language & WMarkDown.HTML: + return WMarkDown.__check_html_module("radio", matches) return None @classmethod def module_tick(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: - return self.__check_html_module("tick", matches) + if language & WMarkDown.HTML: + return WMarkDown.__check_html_module("tick", matches) return None @staticmethod @@ -217,46 +217,48 @@ class WMarkDown: def __list_start(self, unordered:bool, _type:str) -> str: if not unordered: _type = _type[:-1] - if self.re_integer.search(_type): + if WMarkDown.re_integer.search(_type): return ' start="' + _type + '"' return '' def module_list(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: html:str = '' - lines:list[str] = self.re_new_line.split(matches.group(0)) + lines:list[str] = WMarkDown.re_new_line.split(matches.group(0)) levels:list[list[int, str, str|None]] = [[0, 'u', None]] l:int = 0 line:str last_mark:str|None = None + subtype:str|None = None for line in lines: - matches:REMatch = self.re_list_line.search(line) + matches:REMatch = WMarkDown.re_list_line.search(line) if not matches: continue - separator_by_marks:str = len(matches.group(3) or "") - separator:str = separator_by_marks if separator_by_marks > 1 else len(matches.group(1)) + separator_by_marks:int = len(matches.group(3) or "") + separator:int = separator_by_marks if separator_by_marks > 1 else len(matches.group(1)) _type:str = matches.group(2) key:str = matches.group(4) - string:str = self.analyse(matches.group(5), language, self.SUBITEM, path).strip() + string:str = self.analyse(matches.group(5), language, WMarkDown.SUBITEM, path).strip() unordered:bool = _type and _type[-1] in ('-', '*', '+') - subtype:str = _type[-1] if _type else None + + subtype = _type[-1] if _type else None if _type: if levels[l][0] == separator: levels[l][1] = 'u' if unordered else 'o' levels[l][2] = subtype - html += ('' if html else '<' + str(levels[l][1]) + 'l class="wmd-list"' + self.__list_start(unordered, _type) + self.__list_deployed(levels[l - 1], last_mark, l) + ( + html += ('' if html else '<' + str(levels[l][1]) + 'l class="wmd-list"' + WMarkDown.__list_start(unordered, _type) + WMarkDown.__list_deployed(levels[l - 1], last_mark, l) + ( ' type="' + key[0] + '"' if key and not unordered and key[0] in ('a', 'A', 'i', 'I') else '') + '>') + '
  • ' + string elif levels[l][0] < separator: l += 1 levels += [[separator, "u" if unordered else "o", subtype]] - html += '<' + levels[l][1] + 'l class="wmd-list"' + self.__list_start(unordered, _type) + self.__list_deployed(levels[l - 1], last_mark, l) + ( + html += '<' + levels[l][1] + 'l class="wmd-list"' + WMarkDown.__list_start(unordered, _type) + WMarkDown.__list_deployed(levels[l - 1], last_mark, l) + ( ' type="' + key[0] + '"' if key and not unordered and key[0] in ('a', 'A', 'i', 'I') else '') + '>
  • ' + string else: @@ -295,16 +297,16 @@ class WMarkDown: class_key:str attribute, classes_str, closer = matches.groups() - classes = self.re_white_spaces.split(classes_str) + classes = WMarkDown.re_white_spaces.split(classes_str) return attribute + classes_str + (' ' if classes_str else '') + " ".join([ class_key for class_key in _class if class_key not in classes ]) + closer - return self.re_class_attribute.sub(callback, html) + return WMarkDown.re_class_attribute.sub(callback, html) def module_table(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: html:dict[str, str] = { "thead" : '', @@ -316,7 +318,7 @@ class WMarkDown: while True: - line_matches:REMatch = self.re_table_line.search(data) + line_matches:REMatch = WMarkDown.re_table_line.search(data) if not line_matches: break @@ -336,7 +338,7 @@ class WMarkDown: while True: - cell_matches:REMatch = self.re_table_item.search(line) + cell_matches:REMatch = WMarkDown.re_table_item.search(line) if not cell_matches: break @@ -347,8 +349,8 @@ class WMarkDown: row += '' + self.analyse( content[1:-1] if content and content[0] + content[-1] in ("''", '""') else content, - self.HTML, - self.SUBITEM, + WMarkDown.HTML, + WMarkDown.SUBITEM, path ) + '' @@ -373,36 +375,36 @@ class WMarkDown: @classmethod def module_exclude(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: return '' + (matches.group(1) or "") + '' return None def module_link(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: raw_url:str = (matches.group(4) or matches.group(11) or matches.group(14) or "").strip() url = ( - "tel:" + raw_url.replace(" ", "") if self.re_phone_number.search(raw_url) else - "mailto:" + raw_url if self.re_email_address.search(raw_url) else + "tel:" + raw_url.replace(" ", "") if WMarkDown.re_phone_number.search(raw_url) else + "mailto:" + raw_url if WMarkDown.re_email_address.search(raw_url) else raw_url) - text:str|None = matches.group(2) or matches.group(13) or raw_url + text:str = matches.group(2) or matches.group(13) or raw_url protocol_matches:REMatch|None = WMarkDown.re_protocol.search(url) - return '' + self.analyse(text.strip(), language, self.SUBITEM | self.LINKED, path) + '' + ) + '">' + self.analyse(text.strip(), language, WMarkDown.SUBITEM | self.LINKED, path) + '' return None def module_quote(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: _type:str|None = matches.group(2) type_text:str|None = matches.group(4) - if _type in self.quote_special: - _type = self.quote_special[_type] + if _type in WMarkDown.quote_special: + _type = WMarkDown.quote_special[_type] return ('
    ' + (('
    ' + (( @@ -412,13 +414,13 @@ class WMarkDown: '' + ('' + type_text + '' if type_text else '') )) + '
    ') if _type else '') + - '
    ' + self.analyse(matches.group(5), language, self.SUBITEM, path) + '
    ' + + '
    ' + self.analyse(matches.group(5), language, WMarkDown.SUBITEM, path) + '
    ' + '
    ') return None @classmethod - def code_block_data(self, key:str, value:str|int, language:Optional[int] = HTML, path:Optional[str] = None) -> str: - if language & self.HTML: + def code_block_data(self, key:str, value:str|int, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: + if language & WMarkDown.HTML: return ('
  • ' + '' + '' + key + '' + @@ -429,11 +431,11 @@ class WMarkDown: @classmethod def filter_html_special_characters(self, string:str) -> str: - l:int = len(self.html_special_characters) + l:int = len(WMarkDown.html_special_characters) _:int index:list[int] = [-1 for _ in range(l)] response:str = '' - characters:tuple[str] = tuple(self.html_special_characters.keys()) + characters:tuple[str] = tuple(WMarkDown.html_special_characters.keys()) while True: @@ -461,7 +463,7 @@ class WMarkDown: length:int = index[i] - response += string[:length] + '&' + self.html_special_characters[characters[i]] + ';' + response += string[:length] + '&' + WMarkDown.html_special_characters[characters[i]] + ';' string = string[length + 1:] for j in range(l): @@ -472,7 +474,7 @@ class WMarkDown: @classmethod def module_code_block(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: _type:str content:str @@ -491,26 +493,26 @@ class WMarkDown: if _type: - lines:list[str] = self.re_new_line.split(content)[2:] + lines:list[str] = WMarkDown.re_new_line.split(content)[2:] _:str return ('
    ' '
      ' + '
    • ' + - self.code_block_data("type", _type, language) + - self.code_block_data("characters", len(content), language) + - self.code_block_data("lines", len(lines), language) + + WMarkDown.code_block_data("type", _type, language) + + WMarkDown.code_block_data("characters", len(content), language) + + WMarkDown.code_block_data("lines", len(lines), language) + '
    ' + '
    ' + '
      ' + ''.join(['
    1. ' for _ in lines]) + '
    ' + - '
    ' + self.filter_html_special_characters(content) + '
    ' + + '
    ' + WMarkDown.filter_html_special_characters(content) + '
    ' + '
    ' + '
    ') return 'UNKNOWN_BLOCK' return None def module_special_characters(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: return matches.group(1) return None @@ -525,21 +527,21 @@ class WMarkDown: return None def module_include(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: relative_path:str = matches.group(1) new_path:str = path + relative_path - extension:str = self.re_extension.search(new_path).groups()[1:] - content:str|None = self.load_file(new_path) + extension:str = WMarkDown.re_extension.search(new_path).groups()[1:] + content:str|None = WMarkDown.load_file(new_path) directory:str = directory_name(new_path) + "/" results:str|None = ( None if content == None else self.process(content, language, directory)[0] if ".".join(extension) == "w.md" else - self.analyse(content, language, self.RAW, directory) if extension[-1] == "md" else + self.analyse(content, language, WMarkDown.RAW, directory) if extension[-1] == "md" else content) return ('
    ' + - '' + + '' + (results or "") + '
    ') return None @@ -559,14 +561,14 @@ class WMarkDown: '') def module_media(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: _type:str = matches.group(1).lower() - links:list[str] = self.re_white_spaces.split(matches.group(3) or matches.group(5) or matches.group(7)) + links:list[str] = WMarkDown.re_white_spaces.split(matches.group(3) or matches.group(5) or matches.group(7)) text:str = (matches.group(10) or matches.group(12) or matches.group(14) or '').strip() if _type in ("image", "picture", "icon"): - return self.build_html_image(links, _type, text) + return WMarkDown.build_html_image(links, _type, text) if _type in ("video",): @@ -609,7 +611,7 @@ class WMarkDown: start, end = matches.span() - string = string[:start] + self.item_mark[0] + str(len(fragments)) + self.item_mark[1] + string[end:] + string = string[:start] + WMarkDown.item_mark[0] + str(len(fragments)) + WMarkDown.item_mark[1] + string[end:] fragments += [matches.group(0)] return string @@ -619,7 +621,7 @@ class WMarkDown: while True: - matches:REMatch = self.item_mark[2].search(string) + matches:REMatch = WMarkDown.item_mark[2].search(string) if not matches: break @@ -636,16 +638,16 @@ class WMarkDown: @classmethod def __doc_typed_format(self, typed:str) -> str: - return self.filter_html_special_characters(typed.replace(' ', "").replace(',', ", ")) + return WMarkDown.filter_html_special_characters(typed.replace(' ', "").replace(',', ", ")) def module_code_doc(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: # print(matches.groups()) data:str = matches.group(1).strip() - base:REMatch = self.re_code_doc.search(data) - return_type:str = self.__doc_typed_format(base.group(2) or "void") + base:REMatch = WMarkDown.re_code_doc.search(data) + return_type:str = WMarkDown.__doc_typed_format(base.group(2) or "void") access:str = base.group(3) or "public" name_space:str|None = base.group(5) environment:str = base.group(6) or "global" @@ -680,10 +682,10 @@ class WMarkDown: if parameters: while True: - matches = self.re_code_doc_subarguments.search(parameters) + matches = WMarkDown.re_code_doc_subarguments.search(parameters) if matches: - parameters = self.mark_replace(parameters, matches, fragments) + parameters = WMarkDown.mark_replace(parameters, matches, fragments) else: break else: @@ -691,16 +693,16 @@ class WMarkDown: for parameter in parameters.split(","): - matches = self.re_code_doc_arguments.search(parameter.strip()) + matches = WMarkDown.re_code_doc_arguments.search(parameter.strip()) if matches: scopes:str = matches.group(1) or "" required:bool = "!" in scopes nullish:bool = "?" in scopes - typed:str = self.__doc_typed_format(self.restore_marks(matches.group(2), fragments)) + typed:str = WMarkDown.__doc_typed_format(WMarkDown.restore_marks(matches.group(2), fragments)) name:str = matches.group(3).strip() - default_value:str = self.filter_html_special_characters(self.restore_marks((matches.group(5) or "").strip(), fragments)) + default_value:str = WMarkDown.filter_html_special_characters(WMarkDown.restore_marks((matches.group(5) or "").strip(), fragments)) arguments += ('' + ('Required' if required else '') + @@ -739,7 +741,7 @@ class WMarkDown: return None def module_color_sample(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: color:str = matches.group(2) or matches.group(3) @@ -750,7 +752,7 @@ class WMarkDown: return None def module_presentation_links(self, matches:REMatch, language:Optional[int] = HTML, path:Optional[str] = None) -> str|None: - if language & self.HTML: + if language & WMarkDown.HTML: items:list = [] i:int = -1 @@ -760,9 +762,9 @@ class WMarkDown: html_avatars:str = '' html_list:str = '' - for line in self.re_new_lines.split(matches.group(1)): + for line in WMarkDown.re_new_lines.split(matches.group(1)): - has_spaces:bool = self.re_start_with_white_spaces.search(line) != None + has_spaces:bool = WMarkDown.re_start_with_white_spaces.search(line) != None data:str = line.strip() if not data: @@ -780,7 +782,6 @@ class WMarkDown: else: i += 1 items += [[line.strip(), [], []]] - continue for i, (title, avatars, links) in enumerate(items): @@ -789,11 +790,11 @@ class WMarkDown: html_avatars += ('
  • ' + ('' + - self.build_html_image(avatars) + - '' if len(links) else self.build_html_image(avatars)) + + WMarkDown.build_html_image(avatars) + + '' if len(links) else WMarkDown.build_html_image(avatars)) + ''.join(['' for link in links]) + '
  • ') html_list += ('
  • ' + @@ -813,7 +814,7 @@ class WMarkDown: def remove_default_tabulations(self, data:str) -> str: line:str - lines:list[str] = self.re_new_lines.split(data) + lines:list[str] = WMarkDown.re_new_lines.split(data) spaces:int = len(data) def callback(matches:REMatch): @@ -823,16 +824,16 @@ class WMarkDown: if not line: continue - white_spaces:int = len(self.re_started_white_spaces.search(line).group(0)) + white_spaces:int = len(WMarkDown.re_started_white_spaces.search(line).group(0)) if white_spaces < spaces: spaces = white_spaces - return self.re_lines.sub(callback, data) + return WMarkDown.re_lines.sub(callback, data) def __build(self, data:str, language:int, path:str|None) -> str: return ('
    ' + - self.analyse(self.remove_default_tabulations(data), language, self.RAW, path) + + self.analyse(WMarkDown.remove_default_tabulations(data), language, WMarkDown.RAW, path) + '
    ' + '
    ') @@ -840,7 +841,7 @@ class WMarkDown: results:str = "" variables:dict[str, str] = {} - options:REMatch = self.re_options.search(data) + options:REMatch = WMarkDown.re_options.search(data) if options: @@ -852,7 +853,7 @@ class WMarkDown: while True: - option:REMatch = self.re_option.search(options_data) + option:REMatch = WMarkDown.re_option.search(options_data) if not option: break @@ -864,7 +865,7 @@ class WMarkDown: while True: - matches:REMatch = self.re_block_mark.search(data) + matches:REMatch = WMarkDown.re_block_mark.search(data) if not matches: results += data @@ -873,7 +874,7 @@ class WMarkDown: open_from:int open_to:int mark:str = matches.group(1) - re_close:REPattern = RECompile(r'^\s*' + mark, RE_MULTILINE) if mark else self.re_block_html + re_close:REPattern = RECompile(r'^\s*' + mark, RE_MULTILINE) if mark else WMarkDown.re_block_html open_from, open_to = matches.span() results += data[:open_from] @@ -900,9 +901,8 @@ class WMarkDown: def analyse(self, data:str, language:Optional[int] = HTML, mode:Optional[int] = RAW, path:Optional[str] = None) -> str: response:str = "" - pattern:REPattern item_mode:int - items:dict[str, list[bool, int, int, REMatch]] = {key : [True, -1, -1, None] for key, (item_mode, pattern) in self.modules.items() if mode == self.RAW or mode | item_mode == item_mode} + items:dict[str, list[bool, int, int, REMatch]] = {key : [True, -1, -1, None] for key, (item_mode, pattern) in self.modules.items() if mode == WMarkDown.RAW or mode | item_mode == item_mode} # j:int = 0 # m:int = 10 @@ -920,7 +920,7 @@ class WMarkDown: if not exists: continue - pattern = self.modules[key][1] + pattern:REPattern = self.modules[key][1] if _from < 0: items[key][3] = matches = pattern.search(data) @@ -955,4 +955,4 @@ class WMarkDown: return response def to_html(self, data:str, path:Optional[str] = None) -> str: - return self.analyse(data, self.HTML, self.RAW, path) \ No newline at end of file + return self.analyse(data, WMarkDown.HTML, WMarkDown.RAW, path) \ No newline at end of file diff --git a/version b/version index 86d4946..340ff46 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.0.2.0 \ No newline at end of file +0.0.2.1 \ No newline at end of file