Skip to content

Commit 12cd797

Browse files
authored
[feat]: add marked extensions support (#227)
* feat: add marked:extensions support * test: fix typo * test(extensions): add marked:extensions test * docs(extensions): add extensions example
1 parent 4b5b702 commit 12cd797

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

README.md

+33
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,39 @@ hexo.extend.filter.register('marked:tokenizer', function(tokenizer) {
233233
});
234234
```
235235

236+
#### Extensions
237+
238+
It is also possible to customize the [extensions](https://marked.js.org/using_pro#extensions).
239+
For example, use [KaTeX](https://katex.org/) to render block-level math:
240+
241+
```js
242+
const katex = require('katex');
243+
244+
hexo.extend.filter.register('marked:extensions', function(extensions) {
245+
// Info: `extensions` is an array.
246+
extensions.push({
247+
name: 'blockMath',
248+
level: 'block',
249+
tokenizer(src) {
250+
const cap = /^\s{0,3}\$\$((?:[^\n]|\n[^\n])+?)\n{0,1}\$\$/.exec(src);
251+
252+
if (cap !== null) {
253+
return {
254+
type: 'blockMath',
255+
raw: cap[0],
256+
math: cap[1]
257+
};
258+
}
259+
260+
return undefined;
261+
},
262+
renderer(token) {
263+
return `<p>${katex.renderToString(token.math, {displayMode: true})}</p>\n`;
264+
}
265+
});
266+
});
267+
```
268+
236269
[Markdown]: https://daringfireball.net/projects/markdown/
237270
[marked]: https://github.com/chjj/marked
238271
[PHP Markdown Extra]: https://michelf.ca/projects/php-markdown/extra/#def-list

lib/renderer.js

+4
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,10 @@ module.exports = function(data, options) {
213213
const tokenizer = new Tokenizer();
214214
this.execFilterSync('marked:tokenizer', tokenizer, {context: this});
215215

216+
const extensions = [];
217+
this.execFilterSync('marked:extensions', extensions, {context: this});
218+
marked.use({extensions});
219+
216220
let postPath = '';
217221
if (path && post_asset_folder && prependRoot && postAsset) {
218222
const Post = this.model('Post');

test/index.js

+33-1
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ describe('Marked renderer', () => {
899899
].join('\n'));
900900
});
901901

902-
it('should execute filter registered to marked:renderer', () => {
902+
it('should execute filter registered to marked:tokenizer', () => {
903903
const smartypants = str => {
904904
return str.replace(/---/g, '\u2014');
905905
};
@@ -921,6 +921,38 @@ describe('Marked renderer', () => {
921921
const result = r({text: body});
922922
result.should.eql(`<p>${smartypants(body)}</p>\n`);
923923
});
924+
925+
it('should execute filter registered to marked:extensions', () => {
926+
hexo.extend.filter.register('marked:extensions', extensions => {
927+
extensions.push({
928+
name: 'blockMath',
929+
level: 'block',
930+
tokenizer(src) {
931+
const cap = /^\s{0,3}\$\$((?:[^\n]|\n[^\n])+?)\n{0,1}\$\$/.exec(src);
932+
933+
if (cap !== null) {
934+
return {
935+
type: 'blockMath',
936+
raw: cap[0],
937+
math: cap[1]
938+
};
939+
}
940+
941+
return undefined;
942+
},
943+
renderer(token) {
944+
return `<p class="math block">${escapeHTML(token.math)}</p>\n`;
945+
}
946+
});
947+
});
948+
949+
const body = '$$E=mc^2$$';
950+
951+
const r = require('../lib/renderer').bind(hexo);
952+
953+
const result = r({text: body});
954+
result.should.eql(`<p class="math block">${escapeHTML('E=mc^2')}</p>\n`);
955+
});
924956
});
925957

926958
describe('nunjucks', () => {

0 commit comments

Comments
 (0)