diff --git a/libs/highlight.js b/libs/highlight.js
index 43a8760..0239a35 100644
--- a/libs/highlight.js
+++ b/libs/highlight.js
@@ -1,44 +1,5 @@
-/*
- * This file is part of moemark-renderer.
- *
- * Copyright (c) 2016 Menci
- *
- * moemark-renderer is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * moemark-renderer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with moemark-renderer. If not, see .
- */
-
-const pygmentize = require('pygmentize-bundled-cached');
-
-function escapeHTML(s) {
- // Code from http://stackoverflow.com/questions/5251520/how-do-i-escape-some-html-in-javascript/5251551
- return s.replace(/[^0-9A-Za-z ]/g, (c) => {
- return "" + c.charCodeAt(0) + ";";
- });
-}
+const { highlight } = require('syzoj-renderer');
module.exports = (code, lang, cb) => {
- pygmentize({
- lang: lang,
- format: 'html',
- options: {
- nowrap: true,
- classprefix: 'pl-'
- }
- }, code, (err, res) => {
- if (err || res.toString() === 'undefined') {
- cb(escapeHTML(code));
- } else {
- cb(res);
- }
- });
+ highlight(code, lang).then(cb);
}
diff --git a/libs/markdown.js b/libs/markdown.js
index 9527145..3618d76 100644
--- a/libs/markdown.js
+++ b/libs/markdown.js
@@ -1,27 +1,26 @@
-/*
- * This file is part of moemark-renderer.
- *
- * Copyright (c) 2016 Menci
- *
- * moemark-renderer is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * moemark-renderer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with moemark-renderer. If not, see .
- */
-
-const MoeMark = require('moemark');
-const katex = require('katex');
-const mj = require('mathjax-node');
+const { markdown } = require('syzoj-renderer');
+const XSS = require('xss');
+const CSSFilter = require('cssfilter');
+const xssWhiteList = Object.assign({}, require('xss/lib/default').whiteList);
+
+delete xssWhiteList.audio;
+delete xssWhiteList.video;
+
+for (const tag in xssWhiteList) {
+ xssWhiteList[tag] = xssWhiteList[tag].concat(['style', 'class']);
+}
+
+const xss = new XSS.FilterXSS({
+ whiteList: xssWhiteList,
+ stripIgnoreTag: true,
+ onTagAttr: (tag, name, value, isWhiteAttr) => {
+ if (tag.toLowerCase() === 'img' && name.toLowerCase() === 'src' && value.startsWith('data:image/')) {
+ return name + '="' + XSS.escapeAttrValue(value) + '"';
+ }
+ }
+});
-let defaultCache = {
+const defaultCache = {
data: {},
get(key) {
return this.data[key];
@@ -31,124 +30,14 @@ let defaultCache = {
}
};
-let config = {
- highlight: require('./highlight')
-};
-
-let uuid = require('uuid');
-
-function render(s, cb) {
- if (!s.trim()) return cb('');
-
- let mathCnt = 0, mathPending = 0, maths = new Array(), mathID = new Array(), hlCnt = 0, hlPending = 0, hls = new Array(), hlID = new Array(), res, callback, ss, cache = render.cache, cacheOption = render.cacheOption, finished = false;
- if (cacheOption.result) {
- let x = cache.get('RES_' + s);
- if (x !== undefined) return cb(x);
- }
-
- MoeMark.setOptions({
- lineNumber: false,
- math: true,
- highlight: function(code, lang) {
- if (cacheOption.highlight) {
- let x = cache.get('H_' + lang + '_' + code);
- if (x !== undefined) return x;
- }
- let id = hlCnt;
- hlCnt++, hlPending++;
- config.highlight(code, lang, res => {
- hls[id] = res;
- if (cacheOption.highlight) cache.set('H_' + lang + '_' + code, res);
- if (!--hlPending) finish();
- });
- return hlID[id] = uuid();
- },
- mathRenderer: function(str, display) {
- let mathFinish = (error, result) => {
- if (error) maths[id] = '' + error.toString() + '
';
- else if (display) maths[id] = '' + result + '
';
- else maths[id] = result;
- if (cacheOption.math) cache.set('M_' + display + '_' + str, maths[id]);
- if (!--mathPending) finish();
- }
-
- const id = mathCnt;
- mathCnt++, mathPending++;
-
- try {
- let x = cache.get('M_' + display + '_' + str);
- if (x !== undefined) process.nextTick(() => mathFinish(null, x));
- else {
- let res = katex.renderToString(str, { displayMode: display });
- process.nextTick(() => mathFinish(null, '' + res + ''));
- }
- } catch (e) {
- mj.typeset({
- math: str,
- format: display ? 'TeX' : 'inline-TeX',
- svg: true,
- width: 0
- }, data => {
- mathFinish(data.errors, data.svg);
- });
- }
- return mathID[id] = uuid();
- }
- });
-
- function finish() {
- if (finished || !res || mathPending || hlPending) return;
- finished = true;
- if (maths.length || hls.length) {
- for (let i = 0; i < maths.length; i++) {
- res = res.replace(mathID[i], maths[i]);
- }
- for (let i = 0; i < hls.length; i++) {
- res = res.replace(hlID[i], hls[i]);
- }
- }
- if (cacheOption.result) cache.set('RES_' + s, res);
- cb(res);
- }
-
- try {
- let XSS = require('xss');
- let CSSFilter = require('cssfilter');
- let whiteList = Object.assign({}, require('xss/lib/default').whiteList);
- delete whiteList.audio;
- delete whiteList.video;
- for (let tag in whiteList) whiteList[tag] = whiteList[tag].concat(['style', 'class']);
- let xss = new XSS.FilterXSS({
- whiteList: whiteList,
- stripIgnoreTag: true,
- onTagAttr: (tag, name, value, isWhiteAttr) => {
- if (tag.toLowerCase() === 'img' && name.toLowerCase() === 'src' && value.startsWith('data:image/')) return name + '="' + XSS.escapeAttrValue(value) + '"';
- }
- });
- let replaceXSS = s => {
- s = xss.process(s);
- if (s) {
- s = `${s}
`;
- }
- return s;
- };
-
- res = replaceXSS(MoeMark(s));
- if (mathPending == 0 && hlPending == 0) {
- finish();
- }
- } catch(e) {
- cb(e);
- }
+function filter(html) {
+ html = xss.process(html);
+ if (html) {
+ html = `${html}
`;
+ }
+ return html;
};
-render.moemark = MoeMark;
-render.cache = defaultCache;
-render.cacheOption = {
- highlight: true,
- math: true,
- result: false
+module.exports = (markdownCode, callback) => {
+ markdown(markdownCode, defaultCache, filter).then(callback);
};
-render.config = config;
-
-module.exports = render;
diff --git a/package.json b/package.json
index b8ed0a3..b9fce8f 100644
--- a/package.json
+++ b/package.json
@@ -42,17 +42,13 @@
"js-yaml": "^3.9.0",
"jsondiffpatch": "0.2.5",
"jsonwebtoken": "^8.4.0",
- "katex": "^0.10.1",
"mariadb": "^2.0.2-rc",
- "mathjax-node": "^2.1.1",
- "moemark": "^0.3.10",
"moment": "^2.24.0",
"msgpack-lite": "^0.1.26",
"multer": "^1.2.0",
"node-7z": "^0.4.0",
"nodemailer": "^4.7.0",
"object-assign-deep": "^0.4.0",
- "pygmentize-bundled-cached": "^1.1.0",
"randomstring": "^1.1.5",
"request": "^2.74.0",
"request-promise": "^4.1.1",
@@ -63,6 +59,7 @@
"socket.io": "^2.2.0",
"stream-to-string": "^1.1.0",
"syzoj-divine": "^1.0.2",
+ "syzoj-renderer": "syzoj/syzoj-renderer",
"tempfile": "^2.0.0",
"tmp-promise": "^1.0.3",
"waliyun": "^3.1.1",