client/misc: add formatMarkdown()
This commit is contained in:
parent
1a6ea4f58a
commit
6d6cce20dd
|
@ -1,5 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const marked = require('marked');
|
||||||
|
|
||||||
function* range(start=0, end=null, step=1) {
|
function* range(start=0, end=null, step=1) {
|
||||||
if (end == null) {
|
if (end == null) {
|
||||||
end = start;
|
end = start;
|
||||||
|
@ -81,6 +83,72 @@ function formatRelativeTime(timeString) {
|
||||||
return future ? 'in ' + text : text + ' ago';
|
return future ? 'in ' + text : text + ' ago';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatMarkdown(text) {
|
||||||
|
const renderer = new marked.Renderer();
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
renderer: renderer,
|
||||||
|
breaks: true,
|
||||||
|
sanitize: true,
|
||||||
|
smartypants: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const sjis = [];
|
||||||
|
|
||||||
|
const preDecorator = text => {
|
||||||
|
text = text.replace(
|
||||||
|
/\[sjis\]((?:[^\[]|\[(?!\/?sjis\]))+)\[\/sjis\]/ig,
|
||||||
|
(match, capture) => {
|
||||||
|
var ret = '%%%SJIS' + sjis.length;
|
||||||
|
sjis.push(capture);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
//prevent ^#... from being treated as headers, due to tag permalinks
|
||||||
|
text = text.replace(/^#/g, '%%%#');
|
||||||
|
//fix \ before ~ being stripped away
|
||||||
|
text = text.replace(/\\~/g, '%%%T');
|
||||||
|
//post, user and tags premalinks
|
||||||
|
text = text.replace(
|
||||||
|
/(^|^\(|(?:[^\]])\(|[\s<>\[\]\)])([+#@][a-zA-Z0-9_-]+)/g,
|
||||||
|
'$1[$2]($2)');
|
||||||
|
text = text.replace(/\]\(@(\d+)\)/g, '](#/post/$1)');
|
||||||
|
text = text.replace(/\]\(\+([a-zA-Z0-9_-]+)\)/g, '](#/user/$1)');
|
||||||
|
text = text.replace(/\]\(#([a-zA-Z0-9_-]+)\)/g, '](#/posts/query=$1)');
|
||||||
|
return text;
|
||||||
|
};
|
||||||
|
|
||||||
|
const postDecorator = text => {
|
||||||
|
//restore fixes
|
||||||
|
text = text.replace(/%%%T/g, '\\~');
|
||||||
|
text = text.replace(/%%%#/g, '#');
|
||||||
|
|
||||||
|
text = text.replace(
|
||||||
|
/%%%SJIS(\d+)/,
|
||||||
|
(match, capture) => {
|
||||||
|
return '<div class="sjis">' + sjis[capture] + '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
//search permalinks
|
||||||
|
text = text.replace(
|
||||||
|
/\[search\]((?:[^\[]|\[(?!\/?search\]))+)\[\/search\]/ig,
|
||||||
|
'<a href="#/posts/query=$1"><code>$1</code></a>');
|
||||||
|
//spoilers
|
||||||
|
text = text.replace(
|
||||||
|
/\[spoiler\]((?:[^\[]|\[(?!\/?spoiler\]))+)\[\/spoiler\]/ig,
|
||||||
|
'<span class="spoiler">$1</span>');
|
||||||
|
//[small]
|
||||||
|
text = text.replace(
|
||||||
|
/\[small\]((?:[^\[]|\[(?!\/?small\]))+)\[\/small\]/ig,
|
||||||
|
'<small>$1</small>');
|
||||||
|
//strike-through
|
||||||
|
text = text.replace(/(^|[^\\])(~~|~)([^~]+)\2/g, '$1<del>$3</del>');
|
||||||
|
text = text.replace(/\\~/g, '~');
|
||||||
|
return text;
|
||||||
|
};
|
||||||
|
|
||||||
|
return postDecorator(marked(preDecorator(text), options));
|
||||||
|
}
|
||||||
|
|
||||||
function formatSearchQuery(dict) {
|
function formatSearchQuery(dict) {
|
||||||
let result = [];
|
let result = [];
|
||||||
for (let key of Object.keys(dict)) {
|
for (let key of Object.keys(dict)) {
|
||||||
|
@ -138,5 +206,6 @@ module.exports = {
|
||||||
parseSearchQueryRoute: parseSearchQueryRoute,
|
parseSearchQueryRoute: parseSearchQueryRoute,
|
||||||
formatRelativeTime: formatRelativeTime,
|
formatRelativeTime: formatRelativeTime,
|
||||||
formatFileSize: formatFileSize,
|
formatFileSize: formatFileSize,
|
||||||
|
formatMarkdown: formatMarkdown,
|
||||||
unindent: unindent,
|
unindent: unindent,
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
"html-minifier": "^1.3.1",
|
"html-minifier": "^1.3.1",
|
||||||
"js-cookie": "^2.1.0",
|
"js-cookie": "^2.1.0",
|
||||||
"js-yaml": "^3.5.5",
|
"js-yaml": "^3.5.5",
|
||||||
|
"marked": "~0.3.2",
|
||||||
"merge": "^1.2.0",
|
"merge": "^1.2.0",
|
||||||
"mousetrap": "^1.5.3",
|
"mousetrap": "^1.5.3",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
|
|
Loading…
Reference in New Issue