Add support for Markdown. This plugin uses marked as its render engine.
$ npm install hexo-renderer-marked --save
You can configure this plugin in _config.yml
.
marked:
gfm: true
pedantic: false
breaks: true
smartLists: true
smartypants: true
quotes: '“”‘’'
modifyAnchors: 0
anchorAlias: false
autolink: true
mangle: true
sanitizeUrl: false
dompurify: false,
headerIds: true
lazyload: false
prependRoot: false
postAsset: false
external_link:
enable: false
exclude: []
nofollow: false
disableNunjucks: false
descriptionLists: true
markdown.pl
as much as possible. Don't fix any of the original markdown bugs or poor behavior.gfm
option to be true.1
) or upper case (2
).https://hexo.io
will become <a href="https://hexo.io">https://hexo.io</a>
.javascript:
, vbscript:
and data:
.<h1 id="value">text</h1>
. Useful for inserting anchor link to each paragraph with a heading.## [foo](#bar)
, id will be set as "bar".loading="lazy"
attribute.prependRoot - Prepend root value to (internal) image path.
Example _config.yml
:
root: /blog/

becomes <img src="/blog/path/to/image.jpg" alt="text">
post_asset_folder
is enabled.
becomes <img src="/2020/01/02/foo/image.jpg">
www
.[foo](http://bar.com)
becomes <a href="http://bar.com" target="_blank" rel="noopener">foo</a>
rel="noopener external nofollow noreferrer"
to all external links for security, privacy and SEO. Read more. This can be enabled regardless of external_link.enable
[foo](http://bar.com)
becomes <a href="http://bar.com" rel="noopener external nofollow noreferrer">foo</a>
{{ }}
or {% %}
(usually used by tag plugins) will not be rendered.hexo-renderer-marked
only provides the option for backward compatibility.descriptionLists
, markdown rendering performance will be improved by a lot.For more options, see Marked. Due to the customizations implemented by this plugin, some of the Marked's options may not work as expected. Feel free to raise an issue to us for clarification.
DOMPurify can be enabled to sanitize the rendered HTML.
To enable it, pass an object containing the DOMPurify options:
dompurify: true
Or you can enable specific DOMPurify options (but according to DOMPurify authors, the default options are safe):
dompurify:
FORBID_TAGS:
- "style"
See https://github.com/cure53/DOMPurify#can-i-configure-dompurify for a full reference of available options
hexo-renderer-marked
also implements description/definition lists using the same syntax as PHP Markdown Extra.
This Markdown:
Definition Term
: This is the definition for the term
will generate this HTML:
<dl>
<dt>Definition Term</dt>
<dd>This is the definition for the term</dd>
</dl>
Note: There is currently a limitation in this implementation. If multiple definitions are provided, the rendered HTML will be incorrect.
For example, this Markdown:
Definition Term
: Definition 1
: Definition 2
will generate this HTML:
<dl>
<dt>Definition Term<br>: Definition 1</dt>
<dd>Definition 2</dd>
</dl>
If you've got ideas on how to support multiple definitions, please provide a pull request. We'd love to support it.
This plugin overrides some default behaviours of how marked plugin renders the markdown into html, to integrate with the Hexo ecosystem. It is possible to override this plugin too, without resorting to forking the whole thing.
For example, to override how heading like # heading text
is rendered:
hexo.extend.filter.register('marked:renderer', function(renderer) {
const { config } = this; // Skip this line if you don't need user config from _config.yml
renderer.heading = function(text, level) {
// Default behaviour
// return `<h${level}>${text}</h${level}>`;
// outputs <h1>heading text</h1>
// If you want to insert custom class name
return `<h${level} class="headerlink">${text}</h${level}>`;
// outputs <h1 class="headerlink">heading text</h1>
}
})
Save the file in "scripts/" folder and run Hexo as usual.
Notice renderer.heading = function (text, level) {
corresponds to this line. Refer to renderer.js on how this plugin overrides the default methods. For other methods not covered by this plugin, refer to marked's documentation.
It is also possible to customize the tokenizer.
const { escape } = require('marked/src/helpers');
// https://github.com/markedjs/marked/blob/b6773fca412c339e0cedd56b63f9fa1583cfd372/src/Lexer.js#L8-L24
// Replace dashes only
const smartypants = (str) => {
return str
// em-dashes
.replace(/---/g, '\u2014')
// en-dashes
.replace(/--/g, '\u2013')
};
hexo.extend.filter.register('marked:tokenizer', function(tokenizer) {
const { smartypants: isSmarty } = this.config.marked;
tokenizer.inlineText = function(src, inRawBlock) {
const { rules } = this;
// https://github.com/markedjs/marked/blob/b6773fca412c339e0cedd56b63f9fa1583cfd372/src/Tokenizer.js#L643-L658
const cap = rules.inline.text.exec(src);
if (cap) {
let text;
if (inRawBlock) {
text = cap[0];
} else {
text = escape(isSmarty ? smartypants(cap[0]) : cap[0]);
}
return {
// `type` value is a corresponding renderer method
// https://marked.js.org/using_pro#inline-level-renderer-methods
type: 'text',
raw: cap[0],
text
};
}
}
});