diff --git a/lib/hexo/default_config.js b/lib/hexo/default_config.js
index daaf6b4a89..8c529ac7bf 100644
--- a/lib/hexo/default_config.js
+++ b/lib/hexo/default_config.js
@@ -48,6 +48,12 @@ module.exports = {
wrap: true,
hljs: false
},
+ prismjs: {
+ enable: false,
+ preprocess: true,
+ line_number: true,
+ tab_replace: ''
+ },
// Category & Tag
default_category: 'uncategorized',
category_map: {},
diff --git a/lib/plugins/filter/before_post_render/backtick_code_block.js b/lib/plugins/filter/before_post_render/backtick_code_block.js
index ca608692ad..36f609117c 100644
--- a/lib/plugins/filter/before_post_render/backtick_code_block.js
+++ b/lib/plugins/filter/before_post_render/backtick_code_block.js
@@ -1,51 +1,38 @@
'use strict';
-const { highlight } = require('hexo-util');
+let highlight, prismHighlight;
const rBacktick = /^((?:[^\S\r\n]*>){0,3}[^\S\r\n]*)(`{3,}|~{3,})[^\S\r\n]*((?:.*?[^`\s])?)[^\S\r\n]*\n((?:[\s\S]*?\n)?)(?:(?:[^\S\r\n]*>){0,3}[^\S\r\n]*)\2(\n+|$)/gm;
const rAllOptions = /([^\s]+)\s+(.+?)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/;
const rLangCaption = /([^\s]+)\s*(.+)?/;
+const escapeSwigTag = str => str.replace(/{/g, '{').replace(/}/g, '}');
+
function backtickCodeBlock(data) {
- const config = this.config.highlight || {};
- if (!config.enable) return;
+ const hljsCfg = this.config.highlight || {};
+ const prismCfg = this.config.prismjs || {};
+
data.content = data.content.replace(rBacktick, ($0, start, $2, _args, _content, end) => {
let content = _content.replace(/\n$/, '');
- const args = _args.split('=').shift();
-
- const options = {
- hljs: config.hljs,
- autoDetect: config.auto_detect,
- gutter: config.line_number,
- tab: config.tab_replace,
- wrap: config.wrap
- };
- if (options.gutter) {
- config.first_line_number = config.first_line_number || 'always1';
- if (config.first_line_number === 'inline') {
+ // neither highlight or prismjs is enabled, return escaped content directly.
+ if (!hljsCfg.enable && !prismCfg.enable) return escapeSwigTag($0);
- // setup line number by inline
- _args = _args.replace('=+', '=');
- options.gutter = _args.includes('=');
-
- // setup fiestLineNumber;
- options.firstLine = options.gutter ? _args.split('=')[1] || 1 : 0;
- }
- }
+ // Extrace langauge and caption of code blocks
+ const args = _args.split('=').shift();
+ let lang, caption;
if (args) {
const match = rAllOptions.exec(args) || rLangCaption.exec(args);
-
if (match) {
- options.lang = match[1];
+ lang = match[1];
if (match[2]) {
- options.caption = `${match[2]}`;
+ caption = `${match[2]}`;
if (match[3]) {
- options.caption += `${match[4] ? match[4] : 'link'}`;
+ caption += `${match[4] ? match[4] : 'link'}`;
}
}
}
@@ -59,11 +46,52 @@ function backtickCodeBlock(data) {
content = content.replace(regexp, '');
}
- content = highlight(content, options)
- .replace(/{/g, '{')
- .replace(/}/g, '}');
+ // Since prismjs have better performance, so prismjs should have higher priority.
+ if (prismCfg.enable) {
+ if (!prismHighlight) prismHighlight = require('hexo-util').prismHighlight;
+
+ const options = {
+ lineNumber: prismCfg.line_number,
+ tab: prismCfg.tab_replace,
+ isPreprocess: prismCfg.preprocess,
+ lang
+ };
+
+ content = prismHighlight(content, options);
+ } else if (hljsCfg.enable) {
+ if (!highlight) highlight = require('hexo-util').highlight;
+
+ const options = {
+ hljs: hljsCfg.hljs,
+ autoDetect: hljsCfg.auto_detect,
+ gutter: hljsCfg.line_number,
+ tab: hljsCfg.tab_replace,
+ wrap: hljsCfg.wrap,
+ lang,
+ caption
+ };
+
+ if (options.gutter) {
+ hljsCfg.first_line_number = hljsCfg.first_line_number || 'always1';
+ if (hljsCfg.first_line_number === 'inline') {
+
+ // setup line number by inline
+ _args = _args.replace('=+', '=');
+ options.gutter = _args.includes('=');
+
+ // setup firstLineNumber;
+ options.firstLine = options.gutter ? _args.split('=')[1] || 1 : 0;
+ }
+ }
+
+ content = highlight(content, options);
+ }
- return `${start}${end}`;
+ return start
+ + ''
+ + end;
});
}
diff --git a/lib/plugins/tag/code.js b/lib/plugins/tag/code.js
index a831db6fb0..d668a3cb7d 100644
--- a/lib/plugins/tag/code.js
+++ b/lib/plugins/tag/code.js
@@ -2,7 +2,7 @@
// Based on: https://raw.github.com/imathis/octopress/master/plugins/code_block.rb
-const { escapeHTML, highlight } = require('hexo-util');
+const { escapeHTML, highlight, prismHighlight } = require('hexo-util');
const rCaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/\S+)\s+(.+)/i;
const rCaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/\S+)/i;
@@ -25,13 +25,13 @@ const rCaption = /\S[\S\s]*/;
* Example: `mark:1,4-7,10` will mark line 1, 4 to 7 and 10.
* @param {Object} wrap Wrap the code block in
, value must be a boolean
* @returns {String} Code snippet with code highlighting
- */
+*/
-function getHighlightOptions(config, args) {
+function parseArgs(args) {
const _else = [];
const len = args.length;
- let lang = '';
- let { line_number, wrap } = config;
+ let lang,
+ line_number, wrap;
let firstLine = 1;
const mark = [];
for (let i = 0; i < len; i++) {
@@ -86,8 +86,9 @@ function getHighlightOptions(config, args) {
}
const arg = _else.join(' ');
- let caption = '';
- let match;
+ // eslint-disable-next-line one-var
+ let match, caption = '';
+
if ((match = arg.match(rCaptionUrlTitle)) != null) {
caption = `${match[1]}${match[3]}`;
} else if ((match = arg.match(rCaptionUrl)) != null) {
@@ -100,37 +101,60 @@ function getHighlightOptions(config, args) {
lang,
firstLine,
caption,
- gutter: line_number,
- hljs: config.hljs,
+ line_number,
mark,
- tab: config.tab_replace,
- autoDetect: config.auto_detect,
wrap
};
}
module.exports = ctx => function codeTag(args, content) {
- const config = ctx.config.highlight || {};
- let { enable } = config;
+ const hljsCfg = ctx.config.highlight || {};
+ const prismjsCfg = ctx.config.prismjs || {};
let index;
+ let enableHighlight = true;
if ((index = args.findIndex(item => item.startsWith('highlight:'))) !== -1) {
const arg = args[index];
- const _enable = arg.slice(10);
- enable = _enable === 'true';
+ const highlightStr = arg.slice(10);
+ enableHighlight = highlightStr === 'true';
args.splice(index, 1);
}
- if (!enable) {
- content = escapeHTML(content);
- return `${content}
`;
+ // If 'hilight: false' is given, return escaped code directly
+ // If neither highlight.js nor prism.js is enabled, return escaped code directly
+ if (!enableHighlight || (!hljsCfg.enable && !prismjsCfg.enable)) {
+ return `${escapeHTML(content)}
`;
}
- content = highlight(content, getHighlightOptions(config, args));
-
- content = content.replace(/{/g, '{')
- .replace(/}/g, '}');
+ const { lang, firstLine, caption, line_number, mark, wrap } = parseArgs(args);
+
+ if (prismjsCfg.enable) {
+ const prismjsOption = {
+ lang,
+ firstLine,
+ lineNumber: typeof line_number !== 'undefined' ? line_number : prismjsCfg.line_number,
+ mark,
+ tab: prismjsCfg.tab_replace,
+ isPreprocess: prismjsCfg.preprocess
+ };
+
+ content = prismHighlight(content, prismjsOption);
+ } else {
+ const hljsOption = {
+ lang: typeof lang !== 'undefined' ? lang : '',
+ firstLine,
+ caption,
+ gutter: typeof line_number !== 'undefined' ? line_number : hljsCfg.line_number,
+ hljs: hljsCfg.hljs,
+ mark,
+ tab: hljsCfg.tab_replace,
+ autoDetect: hljsCfg.auto_detect,
+ wrap: typeof wrap === 'undefined' ? wrap : hljsCfg.wrap
+ };
+
+ content = highlight(content, hljsOption);
+ }
- return content;
+ return content.replace(/{/g, '{').replace(/}/g, '}');
};
diff --git a/lib/plugins/tag/include_code.js b/lib/plugins/tag/include_code.js
index 96823c5332..a4bab70037 100644
--- a/lib/plugins/tag/include_code.js
+++ b/lib/plugins/tag/include_code.js
@@ -2,7 +2,7 @@
const fs = require('hexo-fs');
const { basename, extname, join } = require('path');
-const { highlight } = require('hexo-util');
+const { highlight, prismHighlight } = require('hexo-util');
const rCaptionTitleFile = /(.*)?(?:\s+|^)(\/*\S+)/;
const rLang = /\s*lang:(\w+)/i;
@@ -17,7 +17,6 @@ const rTo = /\s*to:(\d+)/i;
*/
module.exports = ctx => function includeCodeTag(args) {
- const config = ctx.config.highlight || {};
let codeDir = ctx.config.code_dir;
let arg = args.join(' ');
@@ -47,22 +46,31 @@ module.exports = ctx => function includeCodeTag(args) {
const path = match[2];
- // If the title is not defined, use file name instead
- const title = match[1] || basename(path);
-
// If the language is not defined, use file extension instead
lang = lang || extname(path).substring(1);
const src = join(ctx.source_dir, codeDir, path);
+ // If the title is not defined, use file name instead
+ const title = match[1] || basename(path);
const caption = `${title}view raw`;
- const options = {
+ const hljsCfg = ctx.config.highlight || {};
+ const prismjsCfg = ctx.config.prismjs || {};
+
+ const hljsOptions = {
lang,
caption,
- gutter: config.line_number,
- hljs: config.hljs,
- tab: config.tab_replace
+ gutter: hljsCfg.line_number,
+ hljs: hljsCfg.hljs,
+ tab: hljsCfg.tab_replace
+ };
+
+ const prismjsOptions = {
+ lang,
+ lineNumber: prismjsCfg.line_number,
+ tab: prismjsCfg.tab_replace,
+ isPreprocess: prismjsCfg.preprocess
};
return fs.exists(src).then(exist => {
@@ -73,10 +81,12 @@ module.exports = ctx => function includeCodeTag(args) {
const lines = code.split('\n');
code = lines.slice(from, to).join('\n').trim();
- if (!config.enable) {
- return `${code}
`;
+ if (prismjsCfg.enable) {
+ return prismHighlight(code, prismjsOptions);
+ } else if (hljsCfg.enable) {
+ return highlight(code, hljsOptions);
}
- return highlight(code, options);
+ return `${code}
`;
});
};
diff --git a/test/scripts/filters/backtick_code_block.js b/test/scripts/filters/backtick_code_block.js
index 278c22b48c..dd3aec048c 100644
--- a/test/scripts/filters/backtick_code_block.js
+++ b/test/scripts/filters/backtick_code_block.js
@@ -9,7 +9,7 @@ describe('Backtick code block', () => {
const codeBlock = require('../../../lib/plugins/filter/before_post_render/backtick_code_block').bind(hexo);
const code = [
- 'if (tired && night){',
+ 'if (tired && night) {',
' sleep();',
'}'
].join('\n');
@@ -20,9 +20,28 @@ describe('Backtick code block', () => {
.replace(/}/g, '}');
}
+ function prism(code, options) {
+ return util.prismHighlight(code, options || {})
+ .replace(/{/g, '{')
+ .replace(/}/g, '}');
+ }
+
+ // Used for prismjs related test cases
+ function enablePrismjs() {
+ hexo.config.highlight.enable = false;
+ hexo.config.prismjs.enable = true;
+ }
+
beforeEach(() => {
// Reset config
hexo.config.highlight = Object.assign({}, defaultConfig.highlight);
+ hexo.config.prismjs = Object.assign({}, defaultConfig.prismjs);
+ });
+
+ after(() => {
+ // Reset config for further test
+ hexo.config.highlight = defaultConfig.highlight;
+ hexo.config.prismjs = defaultConfig.prismjs;
});
it('disabled', () => {
@@ -35,8 +54,9 @@ describe('Backtick code block', () => {
const data = {content};
hexo.config.highlight.enable = false;
+ hexo.config.prismjs.enable = false;
codeBlock(data);
- data.content.should.eql(content);
+ data.content.should.eql(content.replace(/{/g, '{').replace(/}/g, '}'));
});
it('with no config (disabled)', () => {
@@ -48,16 +68,19 @@ describe('Backtick code block', () => {
const data = {content};
- const oldConfig = hexo.config.highlight;
+ const oldHljsCfg = hexo.config.highlight;
+ const oldPrismCfg = hexo.config.prismjs;
delete hexo.config.highlight;
+ delete hexo.config.prismjs;
codeBlock(data);
- data.content.should.eql(content);
+ data.content.should.eql(content.replace(/{/g, '{').replace(/}/g, '}'));
- hexo.config.highlight = oldConfig;
+ hexo.config.highlight = oldHljsCfg;
+ hexo.config.prismjs = oldPrismCfg;
});
- it('default', () => {
+ it('highlightjs - default', () => {
const data = {
content: [
'``` js',
@@ -70,7 +93,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('without language name', () => {
+ it('highlightjs - without language name', () => {
const data = {
content: [
'```',
@@ -85,7 +108,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('without language name - ignore tab character', () => {
+ it('highlightjs - without language name - ignore tab character', () => {
const data = {
content: [
'``` \t',
@@ -100,7 +123,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('title', () => {
+ it('highlightjs - title', () => {
const data = {
content: [
'``` js Hello world',
@@ -118,7 +141,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('url', () => {
+ it('highlightjs - url', () => {
const data = {
content: [
'``` js Hello world https://hexo.io/',
@@ -136,7 +159,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('link text', () => {
+ it('highlightjs - link text', () => {
const data = {
content: [
'``` js Hello world https://hexo.io/ Hexo',
@@ -154,7 +177,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('indent', () => {
+ it('highlightjs - indent', () => {
const indentCode = code.split('\n').map(line => ' ' + line).join('\n');
const data = {
@@ -174,7 +197,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('line number false', () => {
+ it('highlightjs - line number false', () => {
hexo.config.highlight.line_number = false;
const data = {
@@ -194,7 +217,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('line number false, don`t first_line_number always1', () => {
+ it('highlightjs - line number false, don`t first_line_number always1', () => {
hexo.config.highlight.line_number = false;
hexo.config.highlight.first_line_number = 'always1';
@@ -215,7 +238,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('line number false, don`t care first_line_number inilne', () => {
+ it('highlightjs - line number false, don`t care first_line_number inilne', () => {
hexo.config.highlight.line_number = false;
hexo.config.highlight.first_line_number = 'inilne';
@@ -236,7 +259,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('line number true', () => {
+ it('highlightjs - line number true', () => {
hexo.config.highlight.line_number = true;
const data = {
@@ -256,7 +279,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('line number, first_line_number always1, js=', () => {
+ it('highlightjs - line number, first_line_number always1, js=', () => {
hexo.config.highlight.line_number = true;
hexo.config.highlight.first_line_number = 'always1';
@@ -278,7 +301,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('line number, first_line_number inline, js', () => {
+ it('highlightjs - line number, first_line_number inline, js', () => {
hexo.config.highlight.line_number = true;
hexo.config.highlight.first_line_number = 'inline';
@@ -300,7 +323,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('line number, first_line_number inline, js=1', () => {
+ it('highlightjs - line number, first_line_number inline, js=1', () => {
hexo.config.highlight.line_number = true;
hexo.config.highlight.first_line_number = 'inline';
@@ -322,7 +345,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('line number, first_line_number inline, js=2', () => {
+ it('highlightjs - line number, first_line_number inline, js=2', () => {
hexo.config.highlight.line_number = true;
hexo.config.highlight.first_line_number = 'inline';
@@ -344,7 +367,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('tab replace', () => {
+ it('highlightjs - tab replace', () => {
hexo.config.highlight.tab_replace = ' ';
const code = [
@@ -370,7 +393,7 @@ describe('Backtick code block', () => {
data.content.should.eql('');
});
- it('wrap', () => {
+ it('highlightjs - wrap', () => {
hexo.config.highlight.wrap = false;
const data = {
@@ -398,8 +421,8 @@ describe('Backtick code block', () => {
'```'
].join('\n')
};
-
codeBlock(data);
+
data.content.should.eql('```foo```\n\n');
});
@@ -419,5 +442,126 @@ describe('Backtick code block', () => {
codeBlock(data);
data.content.should.eql('');
+
+ });
+
+ it('prismjs - default', () => {
+ enablePrismjs();
+
+ const data = {
+ content: [
+ '``` js',
+ code,
+ '```'
+ ].join('\n')
+ };
+
+ codeBlock(data);
+
+ data.content.should.eql('');
+ });
+
+ it('prismjs - without language name', () => {
+ enablePrismjs();
+
+ const data = {
+ content: [
+ '```',
+ code,
+ '```'
+ ].join('\n')
+ };
+
+ const expected = prism(code);
+
+ codeBlock(data);
+ data.content.should.eql('');
+ });
+
+
+ it('prismjs - without language name - ignore tab character', () => {
+ enablePrismjs();
+
+ const data = {
+ content: [
+ '``` \t',
+ code,
+ '```'
+ ].join('\n')
+ };
+
+ const expected = prism(code);
+
+ codeBlock(data);
+ data.content.should.eql('');
+ });
+
+ it('prismjs - indent', () => {
+ enablePrismjs();
+
+ const indentCode = code.split('\n').map(line => ' ' + line).join('\n');
+
+ const data = {
+ content: [
+ '``` js',
+ indentCode,
+ '```'
+ ].join('\n')
+ };
+
+ const expected = prism(code, { lang: 'js' });
+
+ codeBlock(data);
+ data.content.should.eql('');
+ });
+
+ it('prismjs - line number false', () => {
+ enablePrismjs();
+
+ hexo.config.prismjs.line_number = false;
+
+ const data = {
+ content: [
+ '``` js',
+ code,
+ '```'
+ ].join('\n')
+ };
+
+ const expected = prism(code, {
+ lang: 'js',
+ lineNumber: false
+ });
+
+ codeBlock(data);
+ data.content.should.eql('');
+ });
+
+ it('prismjs - tab replace', () => {
+ enablePrismjs();
+
+ hexo.config.prismjs.tab_replace = ' ';
+
+ const code = [
+ 'if (tired && night){',
+ '\tsleep();',
+ '}'
+ ].join('\n');
+
+ const data = {
+ content: [
+ '``` js',
+ code,
+ '```'
+ ].join('\n')
+ };
+
+ const expected = prism(code, {
+ lang: 'js',
+ tab: ' '
+ });
+
+ codeBlock(data);
+ data.content.should.eql('');
});
});
diff --git a/test/scripts/tags/code.js b/test/scripts/tags/code.js
index 5ab15a80a0..c9c3cf5039 100644
--- a/test/scripts/tags/code.js
+++ b/test/scripts/tags/code.js
@@ -7,7 +7,7 @@ describe('code', () => {
const Hexo = require('../../../lib/hexo');
const hexo = new Hexo();
const codeTag = require('../../../lib/plugins/tag/code')(hexo);
- const escapeHTML = util.escapeHTML;
+ const { escapeHTML } = util;
const fixture = [
'if (tired && night){',
@@ -19,18 +19,30 @@ describe('code', () => {
return codeTag(args.split(' '), content);
}
+ // Used for prismjs related test cases
+ function enablePrismjs() {
+ hexo.config.highlight.enable = false;
+ hexo.config.prismjs.enable = true;
+ }
+
function highlight(code, options) {
return util.highlight(code, options || {})
.replace(/{/g, '{')
.replace(/}/g, '}');
}
- it('default', () => {
+ function prism(code, options) {
+ return util.prismHighlight(code, options || {})
+ .replace(/{/g, '{')
+ .replace(/}/g, '}');
+ }
+
+ it('highlightjs - default', () => {
const result = code('', fixture);
result.should.eql(highlight(fixture));
});
- it('non standard indent', () => {
+ it('highlightjs - non standard indent', () => {
const nonStandardIndent = [
' ',
' return x;',
@@ -43,14 +55,14 @@ describe('code', () => {
result.should.eql(highlight(nonStandardIndent));
});
- it('lang', () => {
+ it('highlightjs - lang', () => {
const result = code('lang:js', fixture);
result.should.eql(highlight(fixture, {
lang: 'js'
}));
});
- it('line_number', () => {
+ it('highlightjs - line_number', () => {
let result = code('line_number:false', fixture);
result.should.eql(highlight(fixture, {
gutter: false
@@ -61,19 +73,19 @@ describe('code', () => {
}));
});
- it('highlight disable', () => {
+ it('highlightjs - highlight disable', () => {
const result = code('highlight:false', fixture);
result.should.eql('' + escapeHTML(fixture) + '
');
});
- it('title', () => {
+ it('highlightjs - title', () => {
const result = code('Hello world', fixture);
result.should.eql(highlight(fixture, {
caption: 'Hello world'
}));
});
- it('link', () => {
+ it('highlightjs - link', () => {
const result = code('Hello world https://hexo.io/', fixture);
const expected = highlight(fixture, {
caption: 'Hello worldlink'
@@ -82,7 +94,7 @@ describe('code', () => {
result.should.eql(expected);
});
- it('link text', () => {
+ it('highlightjs - link text', () => {
const result = code('Hello world https://hexo.io/ Hexo', fixture);
const expected = highlight(fixture, {
caption: 'Hello worldHexo'
@@ -91,7 +103,7 @@ describe('code', () => {
result.should.eql(expected);
});
- it('disabled', () => {
+ it('highlightjs - disabled', () => {
hexo.config.highlight.enable = false;
const result = code('', fixture);
@@ -100,7 +112,7 @@ describe('code', () => {
hexo.config.highlight.enable = true;
});
- it('first_line', () => {
+ it('highlightjs - first_line', () => {
let result = code('first_line:1234', fixture);
result.should.eql(highlight(fixture, {
firstLine: 1234
@@ -111,7 +123,7 @@ describe('code', () => {
}));
});
- it('mark', () => {
+ it('highlightjs - mark', () => {
const source = [
'const http = require(\'http\');',
'',
@@ -135,13 +147,13 @@ describe('code', () => {
}));
});
- it('# lines', () => {
+ it('highlightjs - # lines', () => {
const result = code('', fixture);
const $ = cheerio.load(result);
$('.gutter .line').should.have.lengthOf(3);
});
- it('wrap', () => {
+ it('highlightjs - wrap', () => {
let result = code('wrap:false', fixture);
result.should.eql(highlight(fixture, {
wrap: false
@@ -151,4 +163,104 @@ describe('code', () => {
wrap: true
}));
});
+
+ it('prismjs - default', () => {
+ enablePrismjs();
+
+ const result = code('', fixture);
+ result.should.eql(prism(fixture));
+ });
+
+ it('prismjs - non standard indent', () => {
+ enablePrismjs();
+
+ const nonStandardIndent = [
+ ' ',
+ ' return x;',
+ '}',
+ '',
+ fixture,
+ ' '
+ ].join('/n');
+ const result = code('', nonStandardIndent);
+ result.should.eql(prism(nonStandardIndent));
+ });
+
+ it('prismjs - lang', () => {
+ enablePrismjs();
+
+ const result = code('lang:js', fixture);
+ result.should.eql(prism(fixture, {
+ lang: 'js'
+ }));
+ });
+
+ it('prismjs - line_number', () => {
+ enablePrismjs();
+
+ let result = code('line_number:false', fixture);
+ result.should.eql(prism(fixture, {
+ lineNumber: false
+ }));
+ result = code('line_number:true', fixture);
+ result.should.eql(prism(fixture, {
+ lineNumber: true
+ }));
+ });
+
+ it('prismjs - highlight disable', () => {
+ enablePrismjs();
+
+ const result = code('highlight:false', fixture);
+ result.should.eql('' + escapeHTML(fixture) + '
');
+ });
+
+ it('prismjs - disabled', () => {
+ hexo.config.highlight.enable = false;
+ hexo.config.prismjs.enable = false;
+
+ const result = code('', fixture);
+ result.should.eql('' + escapeHTML(fixture) + '
');
+
+ hexo.config.highlight.enable = true;
+ });
+
+ it('prismjs - first_line', () => {
+ enablePrismjs();
+
+ let result = code('first_line:1234', fixture);
+ result.should.eql(prism(fixture, {
+ firstLine: 1234
+ }));
+ result = code('', fixture);
+ result.should.eql(prism(fixture, {
+ firstLine: 1
+ }));
+ });
+
+ it('prismjs - mark', () => {
+ enablePrismjs();
+
+ const source = [
+ 'const http = require(\'http\');',
+ '',
+ 'const hostname = \'127.0.0.1\';',
+ 'const port = 1337;',
+ '',
+ 'http.createServer((req, res) => {',
+ ' res.writeHead(200, { \'Content-Type\': \'text/plain\' });',
+ ' res.end(\'Hello World\n\');',
+ '}).listen(port, hostname, () => {',
+ ' console.log(`Server running at http://${hostname}:${port}/`);',
+ '});'
+ ].join('\n');
+
+ code('mark:1,7-9,11', source).should.eql(prism(source, {
+ mark: [1, 7, 8, 9, 11]
+ }));
+
+ code('mark:11,9-7,1', source).should.eql(prism(source, {
+ mark: [1, 7, 8, 9, 11]
+ }));
+ });
});
diff --git a/test/scripts/tags/include_code.js b/test/scripts/tags/include_code.js
index a9902ca63c..844c82ede2 100644
--- a/test/scripts/tags/include_code.js
+++ b/test/scripts/tags/include_code.js
@@ -2,7 +2,7 @@
const pathFn = require('path');
const fs = require('hexo-fs');
-const { highlight } = require('hexo-util');
+const { highlight, prismHighlight } = require('hexo-util');
const Promise = require('bluebird');
describe('include_code', () => {
@@ -17,15 +17,16 @@ describe('include_code', () => {
'}'
].join('\n');
- function code(args) {
- return includeCode(args.split(' '));
- }
+ const code = args => includeCode(args.split(' '));
before(() => fs.writeFile(path, fixture));
after(() => fs.rmdir(hexo.base_dir));
- it('default', () => {
+ it('highlightjs - default', () => {
+ hexo.config.highlight.enable = true;
+ hexo.config.prismjs.enable = false;
+
const expected = highlight(fixture, {
lang: 'js',
caption: 'test.jsview raw'
@@ -36,7 +37,7 @@ describe('include_code', () => {
});
});
- it('title', () => {
+ it('highlightjs - title', () => {
const expected = highlight(fixture, {
lang: 'js',
caption: 'Hello worldview raw'
@@ -47,7 +48,7 @@ describe('include_code', () => {
});
});
- it('lang', () => {
+ it('highlightjs - lang', () => {
const expected = highlight(fixture, {
lang: 'js',
caption: 'Hello worldview raw'
@@ -58,7 +59,7 @@ describe('include_code', () => {
});
});
- it('from', () => {
+ it('highlightjs - from', () => {
const fixture = [
'}'
].join('\n');
@@ -72,7 +73,7 @@ describe('include_code', () => {
});
});
- it('to', () => {
+ it('highlightjs - to', () => {
const fixture = [
'if (tired && night){',
' sleep();'
@@ -87,7 +88,7 @@ describe('include_code', () => {
});
});
- it('from and to', () => {
+ it('highlightjs - from and to', () => {
const fixture = [
'sleep();'
].join('\n');
@@ -101,11 +102,11 @@ describe('include_code', () => {
});
});
- it('file not found', () => code('nothing').then(result => {
+ it('highlightjs - file not found', () => code('nothing').then(result => {
should.not.exist(result);
}));
- it('disabled', () => {
+ it('highlightjs - disabled', () => {
hexo.config.highlight.enable = false;
return code('test.js').then(result => {
@@ -113,4 +114,81 @@ describe('include_code', () => {
hexo.config.highlight.enable = true;
});
});
+
+ it('prismjs - default', () => {
+ hexo.config.highlight.enable = false;
+ hexo.config.prismjs.enable = true;
+
+ const expected = prismHighlight(fixture, {
+ lang: 'js'
+ });
+
+ return code('test.js').then(result => {
+ result.should.eql(expected);
+ });
+ });
+
+ it('prismjs - lang', () => {
+ const expected = prismHighlight(fixture, {
+ lang: 'js',
+ caption: 'Hello worldview raw'
+ });
+
+ return code('Hello world lang:js test.js').then(result => {
+ result.should.eql(expected);
+ });
+ });
+
+ it('prismjs - from', () => {
+ const fixture = [
+ '}'
+ ].join('\n');
+ const expected = prismHighlight(fixture, {
+ lang: 'js'
+ });
+
+ return code('Hello world lang:js from:3 test.js').then(result => {
+ result.should.eql(expected);
+ });
+ });
+
+ it('prismjs - to', () => {
+ const fixture = [
+ 'if (tired && night){',
+ ' sleep();'
+ ].join('\n');
+ const expected = prismHighlight(fixture, {
+ lang: 'js'
+ });
+
+ return code('Hello world lang:js to:2 test.js').then(result => {
+ result.should.eql(expected);
+ });
+ });
+
+ it('prismjs - from and to', () => {
+ const fixture = [
+ 'sleep();'
+ ].join('\n');
+ const expected = prismHighlight(fixture, {
+ lang: 'js'
+ });
+
+ return code('Hello world lang:js from:2 to:2 test.js').then(result => {
+ result.should.eql(expected);
+ });
+ });
+
+ it('prismjs - file not found', () => code('nothing').then(result => {
+ should.not.exist(result);
+ }));
+
+ it('prismjs - disabled', () => {
+ hexo.config.highlight.enable = false;
+ hexo.config.prismjs.enable = false;
+
+ return code('test.js').then(result => {
+ result.should.eql('' + fixture + '
');
+ });
+ });
});