escape HTML characters in code blocks (#635)

This commit is contained in:
Jeff Williams 2014-06-15 14:12:17 -07:00
parent 92c8f101e4
commit 722241dd51
2 changed files with 44 additions and 13 deletions

View File

@ -1,4 +1,4 @@
/*global env: true */
/*global env */
/**
* Provides access to Markdown-related functions.
@ -8,6 +8,8 @@
*/
'use strict';
var util = require('util');
/**
* Enumeration of Markdown parsers that are available.
* @enum {String}
@ -64,6 +66,18 @@ function unescapeUrls(source) {
return source.replace(/(https?)\:\\\/\\\//g, '$1://');
}
/**
* Escape characters in text within a code block.
*
* @param {string} source - The source text to escape.
* @return {string} The escaped source text.
*/
function escapeCode(source) {
return source.replace(/</g, '&lt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
/**
* 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.
@ -86,14 +100,17 @@ function getParseFunction(parserName, conf) {
if (parserName === parserNames.marked) {
// Marked generates an "id" attribute for headers; this custom renderer suppresses it
markedRenderer = new marked.Renderer();
markedRenderer.heading = function(text, level) {
var util = require('util');
markedRenderer.heading = function(text, level) {
return util.format('<h%s>%s</h%s>', level, text, level);
};
// Allow prettyprint to work on inline code samples
markedRenderer.code = function(code, language) {
return '<pre class="prettyprint source"><code>' + code + '</code></pre>';
var langClass = language ? ' lang-' + language : '';
return util.format( '<pre class="prettyprint source%s"><code>%s</code></pre>',
langClass, escapeCode(code) );
};
parserFunction = function(source) {

View File

@ -54,6 +54,18 @@ describe('jsdoc/util/markdown', function() {
expect(parser._parser).toEqual('marked');
});
it('should log an error if an unrecognized Markdown parser is requested', function() {
var logger = require('jsdoc/util/logger');
var parser;
var storage = setMarkdownConf({parser: 'not-a-real-markdown-parser'});
spyOn(logger, 'error');
parser = markdown.getParser();
expect(logger.error).toHaveBeenCalled();
});
it('should not apply formatting to inline tags when the marked parser is enabled', function() {
var storage = setMarkdownConf({parser: 'marked'});
var parser = markdown.getParser();
@ -72,16 +84,18 @@ describe('jsdoc/util/markdown', function() {
.toBe('<p>Visit {@link https://google.com}.</p>');
});
it('should log an error if an unrecognized Markdown parser is requested', function() {
var logger = require('jsdoc/util/logger');
var parser;
var storage = setMarkdownConf({parser: 'not-a-real-markdown-parser'});
it('should escape characters in code blocks as needed', function() {
var parser = markdown.getParser();
var markdownText = '' +
'```html\n' +
'<p><a href="#">Sample \'HTML.\'</a></p>\n' +
'```';
var convertedText = '' +
'<pre class="prettyprint source lang-html"><code>' +
'&lt;p>&lt;a href=&quot;#&quot;>Sample \'HTML.\'&lt;/a>&lt;/p>' +
'</code></pre>';
spyOn(logger, 'error');
parser = markdown.getParser();
expect(logger.error).toHaveBeenCalled();
expect(parser(markdownText)).toBe(convertedText);
});
});
});