mirror of
https://github.com/showdownjs/showdown.git
synced 2024-03-22 13:30:55 +08:00
fix(HTMLParser): fix ghCodeBlocks being parsed inside code tags
When using html pre/code tags to wrap github's fenced code block syntax, showdown would parsed them instead of treating them like plain code. Closes #229
This commit is contained in:
parent
e8852a83bb
commit
7d0436d210
BIN
dist/showdown.js
vendored
BIN
dist/showdown.js
vendored
Binary file not shown.
BIN
dist/showdown.js.map
vendored
BIN
dist/showdown.js.map
vendored
Binary file not shown.
BIN
dist/showdown.min.js
vendored
BIN
dist/showdown.min.js
vendored
Binary file not shown.
BIN
dist/showdown.min.js.map
vendored
BIN
dist/showdown.min.js.map
vendored
Binary file not shown.
|
@ -242,7 +242,8 @@ showdown.Converter = function (converterOptions) {
|
||||||
hashLinkCounts: {},
|
hashLinkCounts: {},
|
||||||
langExtensions: langExtensions,
|
langExtensions: langExtensions,
|
||||||
outputModifiers: outputModifiers,
|
outputModifiers: outputModifiers,
|
||||||
converter: this
|
converter: this,
|
||||||
|
ghCodeBlocks: []
|
||||||
};
|
};
|
||||||
|
|
||||||
// attacklab: Replace ~ with ~T
|
// attacklab: Replace ~ with ~T
|
||||||
|
|
|
@ -23,6 +23,7 @@ showdown.subParser('githubCodeBlocks', function (text, options, globals) {
|
||||||
text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g, function (wholeMatch, language, codeblock) {
|
text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g, function (wholeMatch, language, codeblock) {
|
||||||
var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n';
|
var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n';
|
||||||
|
|
||||||
|
// First parse the github code block
|
||||||
codeblock = showdown.subParser('encodeCode')(codeblock);
|
codeblock = showdown.subParser('encodeCode')(codeblock);
|
||||||
codeblock = showdown.subParser('detab')(codeblock);
|
codeblock = showdown.subParser('detab')(codeblock);
|
||||||
codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
|
codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
|
||||||
|
@ -30,13 +31,16 @@ showdown.subParser('githubCodeBlocks', function (text, options, globals) {
|
||||||
|
|
||||||
codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>';
|
codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>';
|
||||||
|
|
||||||
return showdown.subParser('hashBlock')(codeblock, options, globals);
|
codeblock = showdown.subParser('hashBlock')(codeblock, options, globals);
|
||||||
|
|
||||||
|
// Since GHCodeblocks can be false positives, we need to
|
||||||
|
// store the primitive text and the parsed text in a global var,
|
||||||
|
// and then return a token
|
||||||
|
return '\n\n~G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
|
||||||
});
|
});
|
||||||
|
|
||||||
// attacklab: strip sentinel
|
// attacklab: strip sentinel
|
||||||
text = text.replace(/~0/, '');
|
text = text.replace(/~0/, '');
|
||||||
|
|
||||||
text = globals.converter._dispatch('githubCodeBlocks.after', text, options);
|
return globals.converter._dispatch('githubCodeBlocks.after', text, options);
|
||||||
|
|
||||||
return text;
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,11 +15,10 @@ showdown.subParser('paragraphs', function (text, options, globals) {
|
||||||
|
|
||||||
for (var i = 0; i < end; i++) {
|
for (var i = 0; i < end; i++) {
|
||||||
var str = grafs[i];
|
var str = grafs[i];
|
||||||
|
|
||||||
// if this is an HTML marker, copy it
|
// if this is an HTML marker, copy it
|
||||||
if (str.search(/~K(\d+)K/g) >= 0) {
|
if (str.search(/~(K|G)(\d+)\1/g) >= 0) {
|
||||||
grafsOut.push(str);
|
grafsOut.push(str);
|
||||||
} else if (str.search(/\S/) >= 0) {
|
} else {
|
||||||
str = showdown.subParser('spanGamut')(str, options, globals);
|
str = showdown.subParser('spanGamut')(str, options, globals);
|
||||||
str = str.replace(/^([ \t]*)/g, '<p>');
|
str = str.replace(/^([ \t]*)/g, '<p>');
|
||||||
str += '</p>';
|
str += '</p>';
|
||||||
|
@ -29,16 +28,37 @@ showdown.subParser('paragraphs', function (text, options, globals) {
|
||||||
|
|
||||||
/** Unhashify HTML blocks */
|
/** Unhashify HTML blocks */
|
||||||
end = grafsOut.length;
|
end = grafsOut.length;
|
||||||
|
console.log(text);
|
||||||
for (i = 0; i < end; i++) {
|
for (i = 0; i < end; i++) {
|
||||||
var blockText = '';
|
var blockText = '',
|
||||||
|
grafsOutIt = grafsOut[i],
|
||||||
|
child = false,
|
||||||
|
codeFlag = false;
|
||||||
// if this is a marker for an html block...
|
// if this is a marker for an html block...
|
||||||
while (grafsOut[i].search(/~K(\d+)K/) >= 0) {
|
while (grafsOutIt.search(/~(K|G)(\d+)\1/) >= 0) {
|
||||||
blockText = globals.gHtmlBlocks[RegExp.$1];
|
var delim = RegExp.$1,
|
||||||
blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs
|
num = RegExp.$2;
|
||||||
grafsOut[i] = grafsOut[i].replace(/~K\d+K/, blockText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
text = globals.converter._dispatch('paragraphs.after', text, options);
|
if (delim === 'K') {
|
||||||
return grafsOut.join('\n\n');
|
blockText = globals.gHtmlBlocks[num];
|
||||||
|
} else {
|
||||||
|
// we need to check if ghBlock is a false positive
|
||||||
|
blockText = (codeFlag) ? globals.ghCodeBlocks[num].text : globals.ghCodeBlocks[num].codeblock;
|
||||||
|
}
|
||||||
|
blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs
|
||||||
|
|
||||||
|
grafsOutIt = grafsOutIt.replace(/(\n\n)?~(K|G)\d+\2(\n\n)?/, blockText);
|
||||||
|
// Check if grafsOutIt is a pre->code
|
||||||
|
if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) {
|
||||||
|
codeFlag = true;
|
||||||
|
}
|
||||||
|
child = true;
|
||||||
|
}
|
||||||
|
grafsOut[i] = grafsOutIt;
|
||||||
|
}
|
||||||
|
text = grafsOut.join('\n\n');
|
||||||
|
// Strip leading and trailing lines:
|
||||||
|
text = text.replace(/^\n+/g, '');
|
||||||
|
text = text.replace(/\n+$/g, '');
|
||||||
|
return globals.converter._dispatch('paragraphs.after', text, options);
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,6 +2,5 @@
|
||||||
<li><p>A list item with code:</p>
|
<li><p>A list item with code:</p>
|
||||||
|
|
||||||
<pre><code>alert('Hello world!');
|
<pre><code>alert('Hello world!');
|
||||||
</code></pre>
|
</code></pre></li>
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -5,14 +5,12 @@
|
||||||
<pre><code class="sh language-sh">$ git clone thing.git
|
<pre><code class="sh language-sh">$ git clone thing.git
|
||||||
|
|
||||||
dfgdfg
|
dfgdfg
|
||||||
</code></pre>
|
</code></pre></li>
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<p>I am another thing!</p>
|
<p>I am another thing!</p>
|
||||||
|
|
||||||
<pre><code class="sh language-sh">$ git clone other-thing.git
|
<pre><code class="sh language-sh">$ git clone other-thing.git
|
||||||
|
|
||||||
foobar
|
foobar
|
||||||
</code></pre>
|
</code></pre></li>
|
||||||
</li>
|
|
||||||
</ol>
|
</ol>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<pre lang="no-highlight"><code>
|
||||||
|
foo
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var s = "JavaScript syntax highlighting";
|
||||||
|
alert(s);
|
||||||
|
```
|
||||||
|
|
||||||
|
bar
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>this is a long paragraph</p>
|
||||||
|
|
||||||
|
<p>this is another long paragraph</p>
|
||||||
|
|
||||||
|
<pre lang="no-highlight"><code>```javascript
|
||||||
|
var s = "JavaScript syntax highlighting";
|
||||||
|
alert(s);
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
s = "Python syntax highlighting"
|
||||||
|
print s
|
||||||
|
```
|
||||||
|
</code></pre>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<pre lang="no-highlight"><code>
|
||||||
|
foo
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var s = "JavaScript syntax highlighting";
|
||||||
|
alert(s);
|
||||||
|
```
|
||||||
|
|
||||||
|
bar
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
this is a long paragraph
|
||||||
|
|
||||||
|
this is another long paragraph
|
||||||
|
|
||||||
|
<pre lang="no-highlight"><code>```javascript
|
||||||
|
var s = "JavaScript syntax highlighting";
|
||||||
|
alert(s);
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
s = "Python syntax highlighting"
|
||||||
|
print s
|
||||||
|
```
|
||||||
|
</code></pre>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<pre lang="no-highlight"><code>
|
||||||
|
```javascript
|
||||||
|
var s = "JavaScript syntax highlighting";
|
||||||
|
alert(s);
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
s = "Python syntax highlighting"
|
||||||
|
print s
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
No language indicated, so no syntax highlighting.
|
||||||
|
But let's throw in a <b>tag</b>.
|
||||||
|
```
|
||||||
|
</code></pre>
|
16
test/issues/#229.code-being-parsed-inside-HTML-code-tags.md
Normal file
16
test/issues/#229.code-being-parsed-inside-HTML-code-tags.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<pre lang="no-highlight"><code>
|
||||||
|
```javascript
|
||||||
|
var s = "JavaScript syntax highlighting";
|
||||||
|
alert(s);
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
s = "Python syntax highlighting"
|
||||||
|
print s
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
No language indicated, so no syntax highlighting.
|
||||||
|
But let's throw in a <b>tag</b>.
|
||||||
|
```
|
||||||
|
</code></pre>
|
|
@ -1,8 +1,8 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><p>a list containing a block of code</p>
|
<li>
|
||||||
|
<p>a list containing a block of code</p>
|
||||||
|
|
||||||
<pre><code>10 PRINT HELLO INFINITE
|
<pre><code>10 PRINT HELLO INFINITE
|
||||||
20 GOTO 10
|
20 GOTO 10
|
||||||
</code></pre>
|
</code></pre></li>
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
Loading…
Reference in New Issue
Block a user