101 lines
3.2 KiB
JavaScript
101 lines
3.2 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.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;
|
|
})(); |