Skip to content

Commit

Permalink
feat: postAsset to prepend post's relative path
Browse files Browse the repository at this point in the history
  • Loading branch information
curbengh committed Aug 13, 2020
1 parent 0000e3a commit acae1cb
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 12 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ marked:
headerIds: true
lazyload: false
prependRoot: false
postAsset: false
external_link:
enable: false
exclude: []
Expand All @@ -55,6 +56,10 @@ marked:
root: /blog/
```
* `![text](/path/to/image.jpg)` becomes `<img src="/blog/path/to/image.jpg" alt="text">`
- **postAsset** - Resolve post asset's image path to relative path and prepend root valuewhen [`post_asset_folder`](https://hexo.io/docs/asset-folders) is enabled.
* "image.jpg" is located at "/2020/01/02/foo/image.jpg", which is a post asset of "/2020/01/02/foo/".
* `![](image.jpg)` becomes `<img src="/2020/01/02/foo/image.jpg">`
* Requires `prependRoot:` to be enabled.
- **external_link**
* **enable** - Open external links in a new tab.
* **exclude** - Exclude hostname. Specify subdomain when applicable, including `www`.
Expand Down
15 changes: 13 additions & 2 deletions lib/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const marked = require('marked');
const { encodeURL, slugize, stripHTML, url_for, isExternalLink } = require('hexo-util');
const MarkedRenderer = marked.Renderer;
const { parse } = require('url');
const { join, relative } = require('path').posix;

const anchorId = (str, transformOption) => {
return slugize(str.trim(), {transform: transformOption});
Expand Down Expand Up @@ -87,6 +88,7 @@ class Renderer extends MarkedRenderer {

if (!parse(href).hostname && !options.config.relative_link
&& options.prependRoot) {
if (options.path) href = join(options.path, href);
href = url_for.call(options, href);
}

Expand All @@ -109,15 +111,24 @@ module.exports = function(data, options) {
config: {
url: this.config.url,
root: this.config.root,
relative_link: this.config.relative_link
relative_link: this.config.relative_link,
post_asset_folder: this.config.post_asset_folder
}
});

let path = '';
if (this.config.post_asset_folder && this.config.marked.prependRoot && this.config.marked.postAsset) {
const Post = this.model('Post');
const source = relative(this.source_dir, data.path);
const post = Post.findOne({ source });
path = post ? post.path : '';
}

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

return marked(data.text, Object.assign({
renderer
}, this.config.marked, options, siteCfg));
}, this.config.marked, options, siteCfg, { path }));
};
94 changes: 84 additions & 10 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
'use strict';

require('chai').should();
const { encodeURL, escapeHTML } = require('hexo-util');
const { encodeURL, escapeHTML, url_for } = require('hexo-util');
const Hexo = require('hexo');
const { join } = require('path').posix;

describe('Marked renderer', () => {
const hexo = new Hexo(__dirname, {silent: true});
const ctx = Object.assign(hexo, {
config: {
marked: {}
}
const defaultCfg = JSON.parse(JSON.stringify(Object.assign(hexo.config, {
marked: {}
})));

before(async () => {
hexo.config.permalink = ':title';
await hexo.init();
});

beforeEach(() => {
hexo.config = JSON.parse(JSON.stringify(defaultCfg));
});

const r = require('../lib/renderer').bind(hexo);
Expand Down Expand Up @@ -88,7 +96,7 @@ describe('Marked renderer', () => {

it('should render headings without headerIds when disabled', () => {
const body = '## hexo-server';
ctx.config.marked.headerIds = false;
hexo.config.marked.headerIds = false;

const result = r({text: body});

Expand Down Expand Up @@ -545,7 +553,7 @@ describe('Marked renderer', () => {
`![](${urlB})`
].join('\n');

const r = require('../lib/renderer').bind(ctx);
const r = require('../lib/renderer').bind(hexo);

const result = r({text: body});

Expand All @@ -562,7 +570,7 @@ describe('Marked renderer', () => {
'![a"b](http://bar.com/b.jpg "c>d")'
].join('\n');

const r = require('../lib/renderer').bind(ctx);
const r = require('../lib/renderer').bind(hexo);

const result = r({text: body});

Expand All @@ -579,9 +587,9 @@ describe('Marked renderer', () => {
'![foo](/aaa/bbb.jpg)'
].join('\n');

ctx.config.marked.lazyload = true;
hexo.config.marked.lazyload = true;

const r = require('../lib/renderer').bind(ctx);
const r = require('../lib/renderer').bind(hexo);

const result = r({ text: body });

Expand All @@ -591,6 +599,72 @@ describe('Marked renderer', () => {
].join('\n'));
});

it('postAsset', async () => {
hexo.config.post_asset_folder = true;
hexo.config.marked = {
prependRoot: true,
postAsset: true
};
const content = '![](foo.svg)';
const path = join(__dirname, '_posts', 'foo.md');
const post = {
title: 'foo',
slug: 'foo',
content
};
await hexo.post.create(post);

const result = r({ text: content, path });

console.log(result);
});

describe('postAsset', () => {
const Post = hexo.model('Post');

it('should prepend post path', async () => {
hexo.config.post_asset_folder = true;
hexo.config.marked = {
prependRoot: true,
postAsset: true
};

const asset = 'bar.svg';
const content = `![](${asset})`;
const post = {
source: '_posts/foo.md',
slug: 'foo'
};
const data = await Post.insert(post);

const result = r({ text: content, path: data.full_source });
result.should.eql(`<p><img src="${url_for.call(hexo, join(data.path, asset))}"></p>\n`);

await Post.removeById(data._id);
});

it('should handle slash prefix', async () => {
hexo.config.post_asset_folder = true;
hexo.config.marked = {
prependRoot: true,
postAsset: true
};

const asset = '/bar.svg';
const content = `![](${asset})`;
const post = {
source: '_posts/foo.md',
slug: 'foo'
};
const data = await Post.insert(post);

const result = r({ text: content, path: data.full_source });
result.should.eql(`<p><img src="${url_for.call(hexo, join(data.path, asset))}"></p>\n`);

await Post.removeById(data._id);
});
});

describe('exec filter to extend', () => {
it('should execute filter registered to marked:renderer', () => {
const hexo = new Hexo(__dirname, {silent: true});
Expand Down

0 comments on commit acae1cb

Please sign in to comment.