mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
allow users to specify a highlighter for Markdown code blocks (#1412)
This commit is contained in:
parent
f3a31e9a4c
commit
2c47d4b306
@ -9,6 +9,7 @@ var logger = require('jsdoc/util/logger');
|
|||||||
var MarkdownIt = require('markdown-it');
|
var MarkdownIt = require('markdown-it');
|
||||||
var marked = require('marked');
|
var marked = require('marked');
|
||||||
var mdnh = require('markdown-it-named-headers');
|
var mdnh = require('markdown-it-named-headers');
|
||||||
|
var path = require('jsdoc/path');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,6 +138,51 @@ function unencodeQuotes(source) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the appropriate function for applying syntax highlighting to text, based on the user's
|
||||||
|
* Markdown configuration settings.
|
||||||
|
*
|
||||||
|
* @param {Object} conf - The user's Markdown configuration settings.
|
||||||
|
* @return {function} The highlighter function.
|
||||||
|
*/
|
||||||
|
function getHighlighter(conf) {
|
||||||
|
var highlighter;
|
||||||
|
var highlighterPath;
|
||||||
|
|
||||||
|
switch (typeof conf.highlight) {
|
||||||
|
case 'string':
|
||||||
|
highlighterPath = path.getResourcePath(conf.highlight);
|
||||||
|
|
||||||
|
if (highlighterPath) {
|
||||||
|
highlighter = require(highlighterPath).highlight;
|
||||||
|
|
||||||
|
if (typeof highlighter !== 'function') {
|
||||||
|
logger.error('The syntax highlighting module "%s" does not assign a method ' +
|
||||||
|
'to exports.highlight. Using the default syntax highlighter.',
|
||||||
|
conf.highlight);
|
||||||
|
highlighter = highlight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger.error('Unable to find the syntax highlighting module "%s". Using the ' +
|
||||||
|
'default syntax highlighter.', conf.highlight);
|
||||||
|
highlighter = highlight;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'function':
|
||||||
|
highlighter = conf.highlight;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
highlighter = highlight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return highlighter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a function that accepts a single parameter containing Markdown source. The function uses
|
* Retrieve a function that accepts a single parameter containing Markdown source. The function uses
|
||||||
* the specified parser to transform the Markdown source to HTML, then returns the HTML as a string.
|
* the specified parser to transform the Markdown source to HTML, then returns the HTML as a string.
|
||||||
@ -148,10 +194,12 @@ function unencodeQuotes(source) {
|
|||||||
* returns the resulting HTML.
|
* returns the resulting HTML.
|
||||||
*/
|
*/
|
||||||
function getParseFunction(parserName, conf) {
|
function getParseFunction(parserName, conf) {
|
||||||
|
var highlighter;
|
||||||
var parserFunction;
|
var parserFunction;
|
||||||
var renderer;
|
var renderer;
|
||||||
|
|
||||||
conf = conf || {};
|
conf = conf || {};
|
||||||
|
highlighter = getHighlighter(conf);
|
||||||
|
|
||||||
switch (parserName) {
|
switch (parserName) {
|
||||||
case parserNames.marked:
|
case parserNames.marked:
|
||||||
@ -168,7 +216,7 @@ function getParseFunction(parserName, conf) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.code = highlight;
|
renderer.code = highlighter;
|
||||||
|
|
||||||
parserFunction = function(source) {
|
parserFunction = function(source) {
|
||||||
var result;
|
var result;
|
||||||
@ -192,7 +240,7 @@ function getParseFunction(parserName, conf) {
|
|||||||
case parserNames.markdownit:
|
case parserNames.markdownit:
|
||||||
renderer = new MarkdownIt({
|
renderer = new MarkdownIt({
|
||||||
breaks: Boolean(conf.hardwrap),
|
breaks: Boolean(conf.hardwrap),
|
||||||
highlight: highlight,
|
highlight: highlighter,
|
||||||
html: true
|
html: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
3
test/fixtures/markdown/badhighlighter.js
vendored
Normal file
3
test/fixtures/markdown/badhighlighter.js
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
exports.highlight = 'Not a real highlighter';
|
||||||
5
test/fixtures/markdown/highlighter.js
vendored
Normal file
5
test/fixtures/markdown/highlighter.js
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
exports.highlight = function(code, language) {
|
||||||
|
return '<pre><code>' + code + ' in this language: ' + language + '</code></pre>';
|
||||||
|
};
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
describe('jsdoc/util/markdown', function() {
|
describe('jsdoc/util/markdown', function() {
|
||||||
var env = require('jsdoc/env');
|
var env = require('jsdoc/env');
|
||||||
|
var logger = require('jsdoc/util/logger');
|
||||||
var markdown = require('jsdoc/util/markdown');
|
var markdown = require('jsdoc/util/markdown');
|
||||||
|
|
||||||
it('should exist', function() {
|
it('should exist', function() {
|
||||||
@ -66,11 +67,10 @@ describe('jsdoc/util/markdown', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should log an error if an unrecognized Markdown parser is requested', function() {
|
it('should log an error if an unrecognized Markdown parser is requested', function() {
|
||||||
var logger = require('jsdoc/util/logger');
|
|
||||||
|
|
||||||
setMarkdownConf({parser: 'not-a-real-markdown-parser'});
|
setMarkdownConf({parser: 'not-a-real-markdown-parser'});
|
||||||
spyOn(logger, 'error');
|
spyOn(logger, 'error');
|
||||||
markdown.getParser();
|
markdown.getParser();
|
||||||
|
|
||||||
expect(logger.error).toHaveBeenCalled();
|
expect(logger.error).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -131,5 +131,53 @@ describe('jsdoc/util/markdown', function() {
|
|||||||
|
|
||||||
expect(parser(markdownText)).toBe(convertedText);
|
expect(parser(markdownText)).toBe(convertedText);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('syntax highlighter', function() {
|
||||||
|
it('should support a `highlight` function defined in the config file', function() {
|
||||||
|
var parser;
|
||||||
|
|
||||||
|
setMarkdownConf({
|
||||||
|
highlight: function(code, language) {
|
||||||
|
return '<pre><code>' + code + ' highlighted as ' + language +
|
||||||
|
'</code></pre>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
parser = markdown.getParser();
|
||||||
|
|
||||||
|
expect(parser('```js\nhello\n```')).toBe(
|
||||||
|
'<pre><code>hello\n highlighted as js</code></pre>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support `highlight` as the path to a highlighter module', function() {
|
||||||
|
var parser;
|
||||||
|
|
||||||
|
setMarkdownConf({ highlight: 'test/fixtures/markdown/highlighter' });
|
||||||
|
parser = markdown.getParser();
|
||||||
|
|
||||||
|
expect(parser('```js\nhello\n```')).toBe(
|
||||||
|
'<pre><code>hello\n in this language: js</code></pre>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log an error if the `highlight` module cannot be found', function() {
|
||||||
|
spyOn(logger, 'error');
|
||||||
|
|
||||||
|
setMarkdownConf({ highlight: 'foo/bar/baz' });
|
||||||
|
markdown.getParser();
|
||||||
|
|
||||||
|
expect(logger.error).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log an error if the `highlight` module does not assign a method to ' +
|
||||||
|
'`exports.highlight`', function() {
|
||||||
|
spyOn(logger, 'error');
|
||||||
|
|
||||||
|
setMarkdownConf({ highlight: 'test/fixtures/markdown/badhighlighter' });
|
||||||
|
markdown.getParser();
|
||||||
|
|
||||||
|
expect(logger.error).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user