127 lines
4.6 KiB
JavaScript
127 lines
4.6 KiB
JavaScript
"use strict";
|
|
|
|
export const MarkDown = (function(){
|
|
|
|
const MarkDown = function(anp){};
|
|
|
|
MarkDown.Item = function(pattern, replace, block = false){
|
|
this.pattern = pattern;
|
|
this.replace = replace;
|
|
this.block = block;
|
|
this.match = null;
|
|
this.length = 0;
|
|
this.more = true;
|
|
this.index = -1;
|
|
};
|
|
|
|
MarkDown.Header = () => new MarkDown.Item(/^(#{1,6})\s*(.+)$/m, (match, hashes, content) => `<h${hashes.length}>${MarkDown.to_html(content, false)}</h${hashes.length}>`, true);
|
|
|
|
MarkDown.Block = () => new MarkDown.Item(/^```([a-z]*)\r?\n([\s\S]*?)\r?\n```/, (match, lang, content) => `<fieldset><legend>${lang}</legend><pre><code class="${lang}">${content}</code></pre></fieldset>`, true);
|
|
|
|
MarkDown.BlockQuote = () => new MarkDown.Item(/^>\s?(.+)$/m, (match, content) => `<blockquote>${MarkDown.to_html(content, false)}</blockquote>`, true);
|
|
|
|
MarkDown.Paragraph = () => new MarkDown.Item(/^((?:[^\r\n]+(?:\r\n|[\r\n])?)+)/m, (match, content) => `<p>${MarkDown.to_html(content, false)}</p>\n\n`, true);
|
|
|
|
MarkDown.Link = () => new MarkDown.Item(/\[([^\]]+)\]\(([^)]+)\)|([a-z]{2,12}:\/{2}[^ "']+)/, (match, text, url, link) => `<a href="${url || link}" target="_blank" title="${text || link}">${text || link}</a>`);
|
|
|
|
MarkDown.Bold = () => new MarkDown.Item(/\*{2}((?:(?!(?:\*{2})).)+)\*{2}/, (match, content) => `<b>${MarkDown.to_html(content, false)}</b>`);
|
|
|
|
MarkDown.Italic = () => new MarkDown.Item(/\*((?:(?!(?:\*)).|\*{2})+)\*(?!\*)/, (match, content) => `<i>${MarkDown.to_html(content, false)}</i>`);
|
|
|
|
// MarkDown.UnorderedList = () => new MarkDown.Item(/^\s*[-+*]\s+(.+)$/m, (match, content) => `<ul><li>${MarkDown.to_html(content, false)}</li></ul>`, true);
|
|
|
|
// MarkDown.OrderedList = () => new MarkDown.Item(/^(\s*\d+\.\s+.+(?:\r\n|[\r\n])?)$/m, (match, content) => `<ol><li>${MarkDown.to_html(content, false)}</li></ol>`, true);
|
|
|
|
// MarkDown.Table = () => new MarkDown.Item(/^\s*\|(.+)\|\s*$/m, (match, content) => {
|
|
|
|
// const rows = content.split(/\r?\n/).map(row => row.trim().split("|").map(cell => cell.trim()));
|
|
|
|
// if(rows.length < 2)
|
|
// return content;
|
|
// const header = rows[0],
|
|
// alignments = rows[1].map(cell => {
|
|
// if(/^:-+:$/.test(cell))
|
|
// return "center";
|
|
// else if(/^-+:$/.test(cell))
|
|
// return "right";
|
|
// else if(/^:-+$/.test(cell))
|
|
// return "left";
|
|
// return null;
|
|
// }),
|
|
// body = rows.slice(2);
|
|
|
|
// return `<table><thead><tr>${header.map((cell, i) => `<th${alignments[i] ? ` style="text-align:${alignments[i]}"` : ""}>${MarkDown.to_html(cell, false)}</th>`).join("")}</tr></thead><tbody>${body.map(row => `<tr>${row.map((cell, i) => `<td${alignments[i] ? ` style="text-align:${alignments[i]}"` : ""}>${MarkDown.to_html(cell, false)}</td>`).join("")}</tr>`).join("")}</tbody></table>`;
|
|
|
|
// }, true);
|
|
|
|
MarkDown.to_html = (string, blocks = true) => {
|
|
|
|
let html = ``;
|
|
const matches = [
|
|
MarkDown.Header(),
|
|
MarkDown.Block(),
|
|
MarkDown.BlockQuote(),
|
|
MarkDown.Paragraph(),
|
|
MarkDown.Link(),
|
|
MarkDown.Bold(),
|
|
MarkDown.Italic()
|
|
];
|
|
|
|
do{
|
|
|
|
let index = 1 << 28,
|
|
i = null;
|
|
|
|
[...matches].forEach((item, j) => {
|
|
if(!item.more)
|
|
return;
|
|
|
|
if(item.block && !blocks){
|
|
item.more = false;
|
|
return;
|
|
};
|
|
|
|
if(item.index < 0){
|
|
|
|
const submatches = string.match(item.pattern);
|
|
|
|
if(!submatches){
|
|
item.more = false;
|
|
return;
|
|
};
|
|
|
|
item.match = submatches;
|
|
item.length = submatches[0].length;
|
|
item.index = submatches.index;
|
|
|
|
};
|
|
|
|
if(index > item.index){
|
|
index = item.index;
|
|
i = j;
|
|
};
|
|
|
|
});
|
|
|
|
if(i === null)
|
|
break;
|
|
|
|
const item = matches[i],
|
|
total = index + item.length;
|
|
|
|
html += string.substring(0, index) + item.replace(...item.match);
|
|
string = string.substring(total);
|
|
|
|
matches.forEach(item => {
|
|
item.index -= total;
|
|
});
|
|
|
|
}while(matches.length)
|
|
|
|
html += string;
|
|
|
|
return html;
|
|
}
|
|
|
|
return MarkDown;
|
|
})(); |