diff --git a/README.md b/README.md
index 8ad7a36..bb8f5b3 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@ marked:
autolink: true
sanitizeUrl: false
headerIds: true
+ prependRoot: false
```
- **gfm** - Enables [GitHub flavored markdown](https://help.github.com/articles/github-flavored-markdown)
@@ -42,6 +43,13 @@ marked:
- **autolink** - Enable autolink for URLs. E.g. `https://hexo.io` will become `https://hexo.io`.
- **sanitizeUrl** - Remove URLs that start with `javascript:`, `vbscript:` and `data:`.
- **headerIds** - Insert header id, e.g. `
text
`. Useful for inserting anchor link to each paragraph with a heading.
+- **headerIds** - Insert header id, e.g. `text
`. Useful for inserting anchor link to each paragraph with a heading.
+- **prependRoot** - Prepend root value to (internal) image path.
+ * Example `_config.yml`:
+ ``` yml
+ root: /blog/
+ ```
+ * `![text](/path/to/image.jpg)` becomes `
`
## Extras
diff --git a/index.js b/index.js
index aa1605c..6c75006 100644
--- a/index.js
+++ b/index.js
@@ -13,7 +13,9 @@ hexo.config.marked = Object.assign({
modifyAnchors: '',
autolink: true,
sanitizeUrl: false,
- headerIds: true
+ headerIds: true,
+ // TODO: enable prependRoot by default in v3
+ prependRoot: false
}, hexo.config.marked);
hexo.extend.renderer.register('md', 'html', renderer, true);
diff --git a/lib/renderer.js b/lib/renderer.js
index 61f9fb3..c67103c 100644
--- a/lib/renderer.js
+++ b/lib/renderer.js
@@ -2,8 +2,9 @@
const marked = require('marked');
const stripIndent = require('strip-indent');
-const { stripHTML, highlight, slugize } = require('hexo-util');
+const { stripHTML, highlight, slugize, encodeURL, url_for } = require('hexo-util');
const MarkedRenderer = marked.Renderer;
+const { parse } = require('url');
function Renderer() {
MarkedRenderer.apply(this);
@@ -82,6 +83,16 @@ Renderer.prototype.paragraph = text => {
return `${text}
\n`;
};
+// Prepend root to image path
+Renderer.prototype.image = function(href, title, text) {
+ if (!parse(href).hostname && !this.options.config.relative_link
+ && this.options.prependRoot) {
+ href = url_for.call(this.options, href);
+ }
+
+ return `
`;
+};
+
marked.setOptions({
langPrefix: '',
highlight(code, lang) {
@@ -94,7 +105,14 @@ marked.setOptions({
});
module.exports = function(data, options) {
+ const url_forCfg = Object.assign({}, {
+ config: {
+ root: this.config.root,
+ relative_link: this.config.relative_link
+ }
+ });
+
return marked(data.text, Object.assign({
renderer: new Renderer()
- }, this.config.marked, options));
+ }, this.config.marked, options, url_forCfg));
};
diff --git a/package.json b/package.json
index 5f1f25b..2c9bba4 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,8 @@
],
"license": "MIT",
"dependencies": {
- "hexo-util": "^1.0.1",
+ "hexo": "^3.9.0",
+ "hexo-util": "^1.3.0",
"marked": "^0.7.0",
"strip-indent": "^3.0.0"
},
diff --git a/test/index.js b/test/index.js
index 169b9b9..a3b99ad 100644
--- a/test/index.js
+++ b/test/index.js
@@ -191,4 +191,75 @@ describe('Marked renderer', () => {
].join('\n'));
});
});
+
+ describe('prependRoot option tests', () => {
+ const body = [
+ '![](/bar/baz.jpg)',
+ '![foo](/aaa/bbb.jpg)'
+ ].join('\n');
+
+ const renderer = require('../lib/renderer');
+
+ const ctx = {
+ config: {
+ marked: {
+ prependRoot: false
+ },
+ root: '/blog/',
+ relative_link: false
+ }
+ };
+
+ it('should not modify image path with default option', () => {
+ const r = renderer.bind(ctx);
+ const result = r({text: body});
+
+ result.should.eql([
+ '
',
+ '![foo](/aaa/bbb.jpg)
\n'
+ ].join('\n'));
+ });
+
+ it('should not modify image path when enable relative_link', () => {
+ ctx.config.relative_link = true;
+ const r = renderer.bind(ctx);
+ const result = r({text: body});
+
+ result.should.eql([
+ '
',
+ '![foo](/aaa/bbb.jpg)
\n'
+ ].join('\n'));
+
+ ctx.config.relative_link = false;
+ });
+
+ it('should prepend image path with root', () => {
+ ctx.config.marked.prependRoot = true;
+ const r = renderer.bind(ctx);
+ const result = r({text: body});
+
+ result.should.eql([
+ '
',
+ '![foo](/blog/aaa/bbb.jpg)
\n'
+ ].join('\n'));
+ ctx.config.marked.prependRoot = false;
+ });
+ });
+
+ it('should encode image url', () => {
+ const body = [
+ '![](/foo/bár.jpg)',
+ '![](http://fóo.com/bar.jpg)'
+ ].join('\n');
+
+ const renderer = require('../lib/renderer');
+ const r = renderer.bind(ctx);
+
+ const result = r({text: body});
+
+ result.should.eql([
+ '
',
+ '![](http://xn--fo-5ja.com/bar.jpg)
\n'
+ ].join('\n'));
+ });
});