Skip to content

Commit

Permalink
chore(deps): adapt to marked@12
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenjoezhang committed Apr 3, 2024
1 parent 680f3ae commit dbc195b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 34 deletions.
81 changes: 49 additions & 32 deletions lib/renderer.js
Expand Up @@ -6,8 +6,6 @@ let JSDOM,
createDOMPurify;

const { encodeURL, slugize, stripHTML, url_for, isExternalLink, escapeHTML: escape, unescapeHTML: unescape } = require('hexo-util');
const MarkedRenderer = marked.Renderer;
const MarkedTokenizer = marked.Tokenizer;
const { basename, dirname, extname, join } = require('path').posix;
const rATag = /<a(?:\s+?|\s+?[^<>]+\s+?)?href=["'](?:#)([^<>"']+)["'][^<>]*>/i;
const rDlSyntax = /(?:^|\s)(\S.+)<br>:\s+(\S.+)/;
Expand All @@ -16,17 +14,27 @@ const anchorId = (str, transformOption) => {
return slugize(stripHTML(unescape(str)).trim(), { transform: transformOption });
};

class Renderer extends MarkedRenderer {
constructor(hexo) {
super();
this._headingId = {};
this.hexo = hexo;
function mangleEmail(text) {
let out = '';
let i,
ch;

const l = text.length;
for (i = 0; i < l; i++) {
ch = text.charCodeAt(i);
if (Math.random() > 0.5) {
ch = 'x' + ch.toString(16);
}
out += '&#' + ch + ';';
}

return out;
}

const renderer = {
// Add id attribute to headings
heading(text, level) {
const { anchorAlias, headerIds, modifyAnchors } = this.options;
const { _headingId } = this;
const { anchorAlias, headerIds, modifyAnchors, _headingId } = this.options;

if (!headerIds) {
return `<h${level}>${text}</h${level}>`;
Expand Down Expand Up @@ -57,17 +65,25 @@ class Renderer extends MarkedRenderer {

// add headerlink
return `<h${level} id="${id}"><a href="#${id}" class="headerlink" title="${stripHTML(text)}"></a>${text}</h${level}>`;
}
},

link(href, title, text) {
const { external_link, sanitizeUrl } = this.options;
const { url: urlCfg } = this.hexo.config;
const { external_link, sanitizeUrl, hexo, mangle } = this.options;
const { url: urlCfg } = hexo.config;

if (sanitizeUrl) {
if (href.startsWith('javascript:') || href.startsWith('vbscript:') || href.startsWith('data:')) {
href = '';
}
}
if (mangle) {
if (href.startsWith('mailto:')) {
const email = href.substring(7);
const mangledEmail = mangleEmail(email);

href = `mailto:${mangledEmail}`;
}
}

let out = '<a href="';

Expand Down Expand Up @@ -99,7 +115,7 @@ class Renderer extends MarkedRenderer {

out += `>${text}</a>`;
return out;
}
},

// Support Basic Description Lists
paragraph(text) {
Expand All @@ -112,11 +128,12 @@ class Renderer extends MarkedRenderer {
}

return `<p>${text}</p>\n`;
}
},

// Prepend root to image path
image(href, title, text) {
const { hexo, options } = this;
const { options } = this;
const { hexo } = options;
const { relative_link } = hexo.config;
const { lazyload, figcaption, prependRoot, postPath } = options;

Expand All @@ -142,11 +159,7 @@ class Renderer extends MarkedRenderer {
}
return out;
}
}

marked.setOptions({
langPrefix: ''
});
};

// https://github.com/markedjs/marked/blob/b6773fca412c339e0cedd56b63f9fa1583cfd372/src/Lexer.js#L8-L24
const smartypants = (str, quotes) => {
Expand All @@ -171,15 +184,15 @@ const smartypants = (str, quotes) => {
.replace(/\.{3}/g, '\u2026');
};

class Tokenizer extends MarkedTokenizer {
const tokenizer = {
// Support AutoLink option
url(src, mangle) {
const { options } = this;
const { autolink } = options;
url(src) {
const { autolink } = this.options;

if (!autolink) return;
return super.url(src, mangle);
}
// return false to use original url tokenizer
return false;
},

// Override smartypants
inlineText(src) {
Expand All @@ -202,21 +215,20 @@ class Tokenizer extends MarkedTokenizer {
};
}
}
}
};

module.exports = function(data, options) {
const { post_asset_folder, marked: markedCfg, source_dir } = this.config;
const { prependRoot, postAsset, dompurify } = markedCfg;
const { prependRoot, postAsset, dompurify, mangle } = markedCfg;

Check failure on line 222 in lib/renderer.js

View workflow job for this annotation

GitHub Actions / linter

'mangle' is assigned a value but never used

Check failure on line 222 in lib/renderer.js

View workflow job for this annotation

GitHub Actions / linter

'mangle' is assigned a value but never used
const { path, text } = data;

// exec filter to extend marked
this.execFilterSync('marked:use', marked.use, { context: this });

// exec filter to extend renderer.
const renderer = new Renderer(this);
this.execFilterSync('marked:renderer', renderer, { context: this });

const tokenizer = new Tokenizer();
// exec filter to extend tokenizer
this.execFilterSync('marked:tokenizer', tokenizer, { context: this });

const extensions = [];
Expand Down Expand Up @@ -250,8 +262,13 @@ module.exports = function(data, options) {
}
sanitizer = function(html) { return DOMPurify.sanitize(html, param); };
}
return sanitizer(marked(text, Object.assign({

marked.use({
renderer,
tokenizer
}, markedCfg, options, { postPath })));
});
return sanitizer(marked.parse(text, Object.assign({
// headerIds was removed in marked v8.0.0, but we still need it
headerIds: true
}, markedCfg, options, { postPath, hexo: this, _headingId: {} })));
};
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -34,7 +34,7 @@
"dompurify": "^3.0.3",
"hexo-util": "^3.1.0",
"jsdom": "^20.0.1",
"marked": "^4.3.0"
"marked": "^12.0.1"
},
"devDependencies": {
"c8": "^8.0.0",
Expand Down
5 changes: 4 additions & 1 deletion test/index.js
Expand Up @@ -9,7 +9,10 @@ const { sep } = require('path');
describe('Marked renderer', () => {
const hexo = new Hexo(__dirname, {silent: true});
const defaultCfg = JSON.parse(JSON.stringify(Object.assign(hexo.config, {
marked: {}
marked: {
headerIds: true,
mangle: true
}
})));

before(async () => {
Expand Down

0 comments on commit dbc195b

Please sign in to comment.