333 lines
10 KiB
PHP
333 lines
10 KiB
PHP
|
|
// Please do not edit this file. It has been generated automatically
|
||
|
|
// from `src/module/markdown.wren` using `util/wren_to_c_string.py`
|
||
|
|
|
||
|
|
static const char* markdownModuleSource =
|
||
|
|
"// retoor <retoor@molodetz.nl>\n"
|
||
|
|
"\n"
|
||
|
|
"import \"html\" for Html\n"
|
||
|
|
"\n"
|
||
|
|
"class Markdown {\n"
|
||
|
|
" static toHtml(text) { toHtml(text, {}) }\n"
|
||
|
|
"\n"
|
||
|
|
" static toHtml(text, options) {\n"
|
||
|
|
" var safeMode = options.containsKey(\"safeMode\") ? options[\"safeMode\"] : false\n"
|
||
|
|
" var lines = text.split(\"\\n\")\n"
|
||
|
|
" var result = []\n"
|
||
|
|
" var inCodeBlock = false\n"
|
||
|
|
" var codeBlockContent = []\n"
|
||
|
|
" var inList = false\n"
|
||
|
|
" var listType = null\n"
|
||
|
|
" var inBlockquote = false\n"
|
||
|
|
"\n"
|
||
|
|
" for (i in 0...lines.count) {\n"
|
||
|
|
" var line = lines[i]\n"
|
||
|
|
"\n"
|
||
|
|
" if (line.startsWith(\"```\")) {\n"
|
||
|
|
" if (inCodeBlock) {\n"
|
||
|
|
" result.add(\"<pre><code>\" + (safeMode ? Html.quote(codeBlockContent.join(\"\\n\")) : codeBlockContent.join(\"\\n\")) + \"</code></pre>\")\n"
|
||
|
|
" codeBlockContent = []\n"
|
||
|
|
" inCodeBlock = false\n"
|
||
|
|
" } else {\n"
|
||
|
|
" closeList_(result, inList, listType)\n"
|
||
|
|
" inList = false\n"
|
||
|
|
" inCodeBlock = true\n"
|
||
|
|
" }\n"
|
||
|
|
" continue\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" if (inCodeBlock) {\n"
|
||
|
|
" codeBlockContent.add(line)\n"
|
||
|
|
" continue\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" if (line.count == 0) {\n"
|
||
|
|
" closeList_(result, inList, listType)\n"
|
||
|
|
" inList = false\n"
|
||
|
|
" if (inBlockquote) {\n"
|
||
|
|
" result.add(\"</blockquote>\")\n"
|
||
|
|
" inBlockquote = false\n"
|
||
|
|
" }\n"
|
||
|
|
" continue\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" if (line.startsWith(\"> \")) {\n"
|
||
|
|
" closeList_(result, inList, listType)\n"
|
||
|
|
" inList = false\n"
|
||
|
|
" if (!inBlockquote) {\n"
|
||
|
|
" result.add(\"<blockquote>\")\n"
|
||
|
|
" inBlockquote = true\n"
|
||
|
|
" }\n"
|
||
|
|
" result.add(\"<p>\" + processInline_(line[2..-1], safeMode) + \"</p>\")\n"
|
||
|
|
" continue\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" if (line.startsWith(\"---\") || line.startsWith(\"***\") || line.startsWith(\"___\")) {\n"
|
||
|
|
" var isHr = true\n"
|
||
|
|
" for (c in line) {\n"
|
||
|
|
" if (c != \"-\" && c != \"*\" && c != \"_\" && c != \" \") {\n"
|
||
|
|
" isHr = false\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
" if (isHr && line.count >= 3) {\n"
|
||
|
|
" closeList_(result, inList, listType)\n"
|
||
|
|
" inList = false\n"
|
||
|
|
" result.add(\"<hr>\")\n"
|
||
|
|
" continue\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" var heading = parseHeading_(line)\n"
|
||
|
|
" if (heading) {\n"
|
||
|
|
" closeList_(result, inList, listType)\n"
|
||
|
|
" inList = false\n"
|
||
|
|
" result.add(\"<h%(heading[\"level\"])>\" + processInline_(heading[\"text\"], safeMode) + \"</h%(heading[\"level\"])>\")\n"
|
||
|
|
" continue\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" var listItem = parseListItem_(line)\n"
|
||
|
|
" if (listItem) {\n"
|
||
|
|
" var newType = listItem[\"type\"]\n"
|
||
|
|
" if (!inList || listType != newType) {\n"
|
||
|
|
" closeList_(result, inList, listType)\n"
|
||
|
|
" result.add(newType == \"ul\" ? \"<ul>\" : \"<ol>\")\n"
|
||
|
|
" inList = true\n"
|
||
|
|
" listType = newType\n"
|
||
|
|
" }\n"
|
||
|
|
" result.add(\"<li>\" + processInline_(listItem[\"text\"], safeMode) + \"</li>\")\n"
|
||
|
|
" continue\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" closeList_(result, inList, listType)\n"
|
||
|
|
" inList = false\n"
|
||
|
|
" result.add(\"<p>\" + processInline_(line, safeMode) + \"</p>\")\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" closeList_(result, inList, listType)\n"
|
||
|
|
" if (inBlockquote) {\n"
|
||
|
|
" result.add(\"</blockquote>\")\n"
|
||
|
|
" }\n"
|
||
|
|
" if (inCodeBlock) {\n"
|
||
|
|
" result.add(\"<pre><code>\" + (safeMode ? Html.quote(codeBlockContent.join(\"\\n\")) : codeBlockContent.join(\"\\n\")) + \"</code></pre>\")\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" return result.join(\"\\n\")\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" static closeList_(result, inList, listType) {\n"
|
||
|
|
" if (inList) {\n"
|
||
|
|
" result.add(listType == \"ul\" ? \"</ul>\" : \"</ol>\")\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" static parseHeading_(line) {\n"
|
||
|
|
" var level = 0\n"
|
||
|
|
" for (c in line) {\n"
|
||
|
|
" if (c == \"#\") {\n"
|
||
|
|
" level = level + 1\n"
|
||
|
|
" } else {\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
" if (level > 0 && level <= 6 && line.count > level && line[level] == \" \") {\n"
|
||
|
|
" return {\"level\": level, \"text\": line[level + 1..-1]}\n"
|
||
|
|
" }\n"
|
||
|
|
" return null\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" static parseListItem_(line) {\n"
|
||
|
|
" var trimmed = line\n"
|
||
|
|
" var indent = 0\n"
|
||
|
|
" while (trimmed.count > 0 && trimmed[0] == \" \") {\n"
|
||
|
|
" trimmed = trimmed[1..-1]\n"
|
||
|
|
" indent = indent + 1\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" if (trimmed.count >= 2 && (trimmed[0] == \"-\" || trimmed[0] == \"*\" || trimmed[0] == \"+\") && trimmed[1] == \" \") {\n"
|
||
|
|
" return {\"type\": \"ul\", \"text\": trimmed[2..-1]}\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" var i = 0\n"
|
||
|
|
" while (i < trimmed.count) {\n"
|
||
|
|
" var c = trimmed[i].codePoints.toList[0]\n"
|
||
|
|
" if (c < 48 || c > 57) break\n"
|
||
|
|
" i = i + 1\n"
|
||
|
|
" }\n"
|
||
|
|
" if (i > 0 && i < trimmed.count - 1 && trimmed[i] == \".\" && trimmed[i + 1] == \" \") {\n"
|
||
|
|
" return {\"type\": \"ol\", \"text\": trimmed[i + 2..-1]}\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" return null\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" static processInline_(text, safeMode) {\n"
|
||
|
|
" if (safeMode) text = Html.quote(text)\n"
|
||
|
|
" text = processCode_(text)\n"
|
||
|
|
" text = processBold_(text)\n"
|
||
|
|
" text = processItalic_(text)\n"
|
||
|
|
" text = processStrikethrough_(text)\n"
|
||
|
|
" text = processImages_(text)\n"
|
||
|
|
" text = processLinks_(text)\n"
|
||
|
|
" return text\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" static processCode_(text) {\n"
|
||
|
|
" var result = \"\"\n"
|
||
|
|
" var i = 0\n"
|
||
|
|
" var chars = text.toList\n"
|
||
|
|
" while (i < chars.count) {\n"
|
||
|
|
" if (chars[i] == \"`\") {\n"
|
||
|
|
" var end = i + 1\n"
|
||
|
|
" while (end < chars.count && chars[end] != \"`\") {\n"
|
||
|
|
" end = end + 1\n"
|
||
|
|
" }\n"
|
||
|
|
" if (end < chars.count) {\n"
|
||
|
|
" var code = \"\"\n"
|
||
|
|
" for (j in (i + 1)...end) {\n"
|
||
|
|
" code = code + chars[j]\n"
|
||
|
|
" }\n"
|
||
|
|
" result = result + \"<code>\" + code + \"</code>\"\n"
|
||
|
|
" i = end + 1\n"
|
||
|
|
" } else {\n"
|
||
|
|
" result = result + chars[i]\n"
|
||
|
|
" i = i + 1\n"
|
||
|
|
" }\n"
|
||
|
|
" } else {\n"
|
||
|
|
" result = result + chars[i]\n"
|
||
|
|
" i = i + 1\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
" return result\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" static processBold_(text) {\n"
|
||
|
|
" var result = text\n"
|
||
|
|
" while (result.contains(\"**\")) {\n"
|
||
|
|
" var start = result.indexOf(\"**\")\n"
|
||
|
|
" var rest = result[start + 2..-1]\n"
|
||
|
|
" var end = rest.indexOf(\"**\")\n"
|
||
|
|
" if (end >= 0) {\n"
|
||
|
|
" var before = result[0...start]\n"
|
||
|
|
" var content = rest[0...end]\n"
|
||
|
|
" var after = rest[end + 2..-1]\n"
|
||
|
|
" result = before + \"<strong>\" + content + \"</strong>\" + after\n"
|
||
|
|
" } else {\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
" while (result.contains(\"__\")) {\n"
|
||
|
|
" var start = result.indexOf(\"__\")\n"
|
||
|
|
" var rest = result[start + 2..-1]\n"
|
||
|
|
" var end = rest.indexOf(\"__\")\n"
|
||
|
|
" if (end >= 0) {\n"
|
||
|
|
" var before = result[0...start]\n"
|
||
|
|
" var content = rest[0...end]\n"
|
||
|
|
" var after = rest[end + 2..-1]\n"
|
||
|
|
" result = before + \"<strong>\" + content + \"</strong>\" + after\n"
|
||
|
|
" } else {\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
" return result\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" static processItalic_(text) {\n"
|
||
|
|
" var result = text\n"
|
||
|
|
" while (result.contains(\"*\")) {\n"
|
||
|
|
" var start = result.indexOf(\"*\")\n"
|
||
|
|
" if (start > 0 && result[start - 1] == \"<\") {\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" var rest = result[start + 1..-1]\n"
|
||
|
|
" var end = rest.indexOf(\"*\")\n"
|
||
|
|
" if (end >= 0 && end > 0) {\n"
|
||
|
|
" var before = result[0...start]\n"
|
||
|
|
" var content = rest[0...end]\n"
|
||
|
|
" var after = rest[end + 1..-1]\n"
|
||
|
|
" result = before + \"<em>\" + content + \"</em>\" + after\n"
|
||
|
|
" } else {\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
" return result\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" static processStrikethrough_(text) {\n"
|
||
|
|
" var result = text\n"
|
||
|
|
" while (result.contains(\"~~\")) {\n"
|
||
|
|
" var start = result.indexOf(\"~~\")\n"
|
||
|
|
" var rest = result[start + 2..-1]\n"
|
||
|
|
" var end = rest.indexOf(\"~~\")\n"
|
||
|
|
" if (end >= 0) {\n"
|
||
|
|
" var before = result[0...start]\n"
|
||
|
|
" var content = rest[0...end]\n"
|
||
|
|
" var after = rest[end + 2..-1]\n"
|
||
|
|
" result = before + \"<del>\" + content + \"</del>\" + after\n"
|
||
|
|
" } else {\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
" return result\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" static processLinks_(text) {\n"
|
||
|
|
" var result = text\n"
|
||
|
|
" while (result.contains(\"](\")) {\n"
|
||
|
|
" var linkEnd = result.indexOf(\"](\")\n"
|
||
|
|
" var textStart = linkEnd\n"
|
||
|
|
" while (textStart > 0 && result[textStart - 1] != \"[\") {\n"
|
||
|
|
" textStart = textStart - 1\n"
|
||
|
|
" }\n"
|
||
|
|
" if (textStart > 0 && result[textStart - 1] == \"[\") {\n"
|
||
|
|
" var urlStart = linkEnd + 2\n"
|
||
|
|
" var urlEnd = urlStart\n"
|
||
|
|
" while (urlEnd < result.count && result[urlEnd] != \")\") {\n"
|
||
|
|
" urlEnd = urlEnd + 1\n"
|
||
|
|
" }\n"
|
||
|
|
" if (urlEnd < result.count) {\n"
|
||
|
|
" var before = result[0...textStart - 1]\n"
|
||
|
|
" var linkText = result[textStart...linkEnd]\n"
|
||
|
|
" var url = result[urlStart...urlEnd]\n"
|
||
|
|
" var after = result[urlEnd + 1..-1]\n"
|
||
|
|
" result = before + \"<a href=\\\"\" + url + \"\\\">\" + linkText + \"</a>\" + after\n"
|
||
|
|
" } else {\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" } else {\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
" return result\n"
|
||
|
|
" }\n"
|
||
|
|
"\n"
|
||
|
|
" static processImages_(text) {\n"
|
||
|
|
" var result = text\n"
|
||
|
|
" while (result.contains(\"![\")) {\n"
|
||
|
|
" var start = result.indexOf(\"![\")\n"
|
||
|
|
" var altEnd = start + 2\n"
|
||
|
|
" while (altEnd < result.count && result[altEnd] != \"]\") {\n"
|
||
|
|
" altEnd = altEnd + 1\n"
|
||
|
|
" }\n"
|
||
|
|
" if (altEnd < result.count && altEnd + 1 < result.count && result[altEnd + 1] == \"(\") {\n"
|
||
|
|
" var urlStart = altEnd + 2\n"
|
||
|
|
" var urlEnd = urlStart\n"
|
||
|
|
" while (urlEnd < result.count && result[urlEnd] != \")\") {\n"
|
||
|
|
" urlEnd = urlEnd + 1\n"
|
||
|
|
" }\n"
|
||
|
|
" if (urlEnd < result.count) {\n"
|
||
|
|
" var before = result[0...start]\n"
|
||
|
|
" var alt = result[start + 2...altEnd]\n"
|
||
|
|
" var url = result[urlStart...urlEnd]\n"
|
||
|
|
" var after = result[urlEnd + 1..-1]\n"
|
||
|
|
" result = before + \"<img src=\\\"\" + url + \"\\\" alt=\\\"\" + alt + \"\\\">\" + after\n"
|
||
|
|
" } else {\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" } else {\n"
|
||
|
|
" break\n"
|
||
|
|
" }\n"
|
||
|
|
" }\n"
|
||
|
|
" return result\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n";
|