-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(jsdoc): do not parse for tags within HTML blocks
In markdown you can provide inline HTML blocks which are not parsed for further markdown syntax. In the same way that the parseTagsProcessor ignored potential tags inside backtick code blocks, it now also ignores potential tags inside inline HTML blocks. These blocks are identified with the same semantic as inline HTML in markdown. This fix is implemented by making the parser more generic and the modifying its behaviour by specifying "parser adapters". Currently parse adapters must expose the following interface: ``` interface ParseAdapter { init(lines, tags); nextLine(line, lineNumber) parseForTags() } ``` BREAKING CHANGE: Tags inside HTML blocks are no longer parsed by default. If you wish this to enable this then you can modify the `parseTagsProcessor.parserAdapters` array from a config block: ``` somePackage.config(function(parseTagsProcessor, backtickParserAdapter) { parseTagsProcessor.parserAdapters = [backtickParserAdapter]; }); ```
- Loading branch information
1 parent
5297e93
commit 451d84a
Showing
7 changed files
with
305 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/** | ||
* A ParserAdapter adapter that ignores tags between triple backtick blocks | ||
*/ | ||
module.exports = function backTickParserAdapter() { | ||
return { | ||
init: function() {}, | ||
nextLine: function(line, lineNumber) { | ||
const CODE_FENCE = /^\s*```(?!.*```)/; | ||
if ( CODE_FENCE.test(line) ) { | ||
this.inCode = !this.inCode; | ||
} | ||
}, | ||
parseForTags: function() { | ||
return !this.inCode; | ||
} | ||
}; | ||
}; |
79 changes: 79 additions & 0 deletions
79
jsdoc/services/parser-adapters/backtick-parser-adapter.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
const backTickParserAdapterFactory = require('./backtick-parser-adapter'); | ||
const TagCollection = require('../../lib/TagCollection'); | ||
|
||
describe('backTickParserAdapter', function() { | ||
it("should ignore @tags inside back-ticked code blocks", function() { | ||
const adapter = backTickParserAdapterFactory(); | ||
const lines = [ | ||
'@a some text', | ||
'', | ||
'', | ||
'```', | ||
' some code', | ||
' @b not a tag', | ||
'```', | ||
'', | ||
'more text', | ||
'@b is a tag' | ||
]; | ||
adapter.init && adapter.init(lines, new TagCollection()); | ||
|
||
adapter.nextLine(lines[0], 0); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[1], 1); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[2], 2); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[3], 3); | ||
expect(adapter.parseForTags()).toBeFalsy(); | ||
adapter.nextLine(lines[4], 4); | ||
expect(adapter.parseForTags()).toBeFalsy(); | ||
adapter.nextLine(lines[5], 5); | ||
expect(adapter.parseForTags()).toBeFalsy(); | ||
adapter.nextLine(lines[6], 6); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[7], 7); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[8], 8); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[9], 9); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
}); | ||
|
||
|
||
it("should cope with single line back-ticked code blocks", function() { | ||
const adapter = backTickParserAdapterFactory(); | ||
const lines = [ | ||
'@a some text', | ||
'', | ||
'```some single line of code @b not a tag```', | ||
'', | ||
'some text outside a code block', | ||
'```', | ||
' some code', | ||
' @b not a tag', | ||
'```' | ||
]; | ||
|
||
adapter.init(lines, new TagCollection()); | ||
|
||
adapter.nextLine(lines[0], 0); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[1], 1); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[2], 2); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[3], 3); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[4], 4); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
adapter.nextLine(lines[5], 5); | ||
expect(adapter.parseForTags()).toBeFalsy(); | ||
adapter.nextLine(lines[6], 6); | ||
expect(adapter.parseForTags()).toBeFalsy(); | ||
adapter.nextLine(lines[7], 7); | ||
expect(adapter.parseForTags()).toBeFalsy(); | ||
adapter.nextLine(lines[8], 8); | ||
expect(adapter.parseForTags()).toBeTruthy(); | ||
}); | ||
}); |
42 changes: 42 additions & 0 deletions
42
jsdoc/services/parser-adapters/html-block-parser-adapter.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
const TAG_REGEXP = /^<([a-zA-Z]+)\b[\s\S]*?>/; | ||
/** | ||
* A ParserAdapter adapter that ignores tags between HTML blocks that would be ignored by markdown | ||
* See https://daringfireball.net/projects/markdown/syntax#html | ||
*/ | ||
module.exports = function htmlBlockParserAdapter() { | ||
return { | ||
init: function(lines) { | ||
this.lines = lines; | ||
this.tagDepth = 0; | ||
this.currentTag = null; | ||
}, | ||
nextLine: function(line, lineNumber) { | ||
if (this.tagDepth === 0 && this.lines[lineNumber - 1] === '') { | ||
const m = TAG_REGEXP.exec(line); | ||
if (m) { | ||
this.currentTag = m[1]; | ||
} | ||
} | ||
if (this.currentTag) { | ||
this.tagDepth = this.tagDepth + countTags(line, '<' + this.currentTag) - countTags(line, '</' + this.currentTag); | ||
} | ||
if (this.tagDepth === 0) { | ||
this.currentTag = null; | ||
} | ||
}, | ||
parseForTags: function() { | ||
return !this.currentTag; | ||
} | ||
}; | ||
}; | ||
|
||
|
||
function countTags(line, marker) { | ||
const regexp = new RegExp(marker + '\\b[\\s\\S]*?(/)?>', 'g'); | ||
let count = 0; | ||
let match; | ||
while(match = regexp.exec(line)) { | ||
count += 1; | ||
} | ||
return count; | ||
} |
Oops, something went wrong.