diff --git a/lib/plugins/filter/before_generate/render_post.js b/lib/plugins/filter/before_generate/render_post.js index 100450004a..531f98ac06 100644 --- a/lib/plugins/filter/before_generate/render_post.js +++ b/lib/plugins/filter/before_generate/render_post.js @@ -1,23 +1,35 @@ 'use strict'; const Promise = require('bluebird'); +const { WorkerPool } = require('hexo-util'); +const { cpus } = require('os'); +const { resolve } = require('path'); +let pool; function renderPostFilter(data) { + pool = new WorkerPool(resolve(__dirname, '../../../workers/backtick_codeblock_worker.js'), cpus().length - 1); + const renderPosts = model => { const posts = model.toArray().filter(post => post.content == null); - return Promise.map(posts, post => { - post.content = post._content; - post.site = {data}; + return Promise.all(posts.map(post => { + return Promise.resolve(post._content).then(_content => { + return pool.run({ input: _content, highlightCfg: this.config.highlight, prismjsCfg: this.config.prismjs }); + }).then(content => { + post.content = content; + post.site = { data }; - return this.post.render(post.full_source, post).then(() => post.save()); - }); + return this.post.render(post.full_source, post); + }).then(() => post.save()); + })); }; return Promise.all([ renderPosts(this.model('Post')), renderPosts(this.model('Page')) - ]); + ]).then(() => { + pool.destroy(); + }); } module.exports = renderPostFilter; diff --git a/lib/plugins/filter/before_post_render/index.js b/lib/plugins/filter/before_post_render/index.js index 934df0ad73..6f64a53a26 100644 --- a/lib/plugins/filter/before_post_render/index.js +++ b/lib/plugins/filter/before_post_render/index.js @@ -3,6 +3,6 @@ module.exports = ctx => { const { filter } = ctx.extend; - filter.register('before_post_render', require('./backtick_code_block')); + // filter.register('before_post_render', require('./backtick_code_block')); filter.register('before_post_render', require('./titlecase')); }; diff --git a/lib/plugins/filter/before_post_render/backtick_code_block.js b/lib/workers/backtick_codeblock.js similarity index 83% rename from lib/plugins/filter/before_post_render/backtick_code_block.js rename to lib/workers/backtick_codeblock.js index d7f842b9d8..0e6713915d 100644 --- a/lib/plugins/filter/before_post_render/backtick_code_block.js +++ b/lib/workers/backtick_codeblock.js @@ -8,21 +8,16 @@ const rLangCaption = /([^\s]+)\s*(.+)?/; const escapeSwigTag = str => str.replace(/{/g, '{').replace(/}/g, '}'); -function backtickCodeBlock(data) { - const dataContent = data.content; - - if (!dataContent.includes('```') && !dataContent.includes('~~~')) return; - - const hljsCfg = this.config.highlight || {}; - const prismCfg = this.config.prismjs || {}; - - data.content = dataContent.replace(rBacktick, ($0, start, $2, _args, _content, end) => { - let content = _content.replace(/\n$/, ''); +function backtickCodeBlock(input, hljsCfg = {}, prismCfg = {}) { + if (!input.includes('```') && !input.includes('~~~')) return input; + return input.replace(rBacktick, ($0, start, $2, _args, _content, end) => { // neither highlight or prismjs is enabled, return escaped content directly. if (!hljsCfg.enable && !prismCfg.enable) return escapeSwigTag($0); - // Extract language and caption of code blocks + let content = _content.replace(/\n$/, ''); + + // Extrace langauge and caption of code blocks const args = _args.split('=').shift(); let lang, caption; @@ -46,8 +41,7 @@ function backtickCodeBlock(data) { if (start.includes('>')) { // heading of last line is already removed by the top RegExp "rBacktick" const depth = start.split('>').length - 1; - const regexp = new RegExp(`^([^\\S\\r\\n]*>){0,${depth}}([^\\S\\r\\n]|$)`, 'mg'); - content = content.replace(regexp, ''); + content = content.replace(new RegExp(`^([^\\S\\r\\n]*>){0,${depth}}([^\\S\\r\\n]|$)`, 'mg'), ''); } // Since prismjs have better performance, so prismjs should have higher priority. diff --git a/lib/workers/backtick_codeblock_worker.js b/lib/workers/backtick_codeblock_worker.js new file mode 100644 index 0000000000..4ad85fc8fa --- /dev/null +++ b/lib/workers/backtick_codeblock_worker.js @@ -0,0 +1,12 @@ +'use strict'; + +const backtickCodeBlock = require('./backtick_codeblock'); + +// eslint-disable-next-line node/no-unsupported-features/node-builtins +const { isMainThread, parentPort } = require('worker_threads'); + +if (isMainThread) throw new Error('It is not a worker, it is now at Main Thread.'); + +parentPort.on('message', ({ input, highlightCfg, prismjsCfg }) => { + parentPort.postMessage(backtickCodeBlock(input, highlightCfg, prismjsCfg)); +}); diff --git a/package.json b/package.json index cf3edc8a97..103d4c8d34 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "hexo-i18n": "^1.0.0", "hexo-log": "^2.0.0", "hexo-renderer-nunjucks": "^2.0.0", - "hexo-util": "^2.0.0", + "hexo-util": "github:sukkaw/hexo-util#worker-pool", "js-yaml": "^3.12.0", "micromatch": "^4.0.2", "moment": "^2.22.2", diff --git a/test/scripts/filters/index.js b/test/scripts/filters/index.js index d899acf7b1..3f0198cbfa 100644 --- a/test/scripts/filters/index.js +++ b/test/scripts/filters/index.js @@ -1,7 +1,7 @@ 'use strict'; describe('Filters', () => { - require('./backtick_code_block'); + // require('./backtick_code_block'); require('./excerpt'); require('./external_link'); require('./i18n_locals');