mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 03:44:29 +03:00
No autolinking inside of code blocks
closes #865 - rejigged markdown to have some functionality before showdown runs, and other functionality before. - autolinking now happens last, so it can be smarter
This commit is contained in:
parent
8c6519fde7
commit
e411ed6889
54
core/shared/vendor/showdown/extensions/github.js
vendored
54
core/shared/vendor/showdown/extensions/github.js
vendored
@ -16,11 +16,10 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
// GFM newline and underscore modifications
|
||||
// GFM newline and underscore modifications, happen BEFORE showdown
|
||||
type : 'lang',
|
||||
filter : function (text) {
|
||||
var extractions = {},
|
||||
imageMarkdownRegex = /^(?:\{(.*?)\})?!(?:\[([^\n\]]*)\])(?:\(([^\n\]]*)\))?$/gim,
|
||||
var preExtractions = {},
|
||||
hashID = 0;
|
||||
|
||||
function hashId() {
|
||||
@ -30,19 +29,10 @@
|
||||
// Extract pre blocks
|
||||
text = text.replace(/<pre>[\s\S]*?<\/pre>/gim, function (x) {
|
||||
var hash = hashId();
|
||||
extractions[hash] = x;
|
||||
preExtractions[hash] = x;
|
||||
return "{gfm-js-extract-pre-" + hash + "}";
|
||||
}, 'm');
|
||||
|
||||
// better URL support, but no title support
|
||||
text = text.replace(imageMarkdownRegex, function (match, key, alt, src) {
|
||||
if (src) {
|
||||
return '<img src="' + src + '" alt="' + alt + '" />';
|
||||
}
|
||||
|
||||
return '';
|
||||
});
|
||||
|
||||
//prevent foo_bar and foo_bar_baz from ending up with an italic word in the middle
|
||||
text = text.replace(/(^(?! {4}|\t)\w+_\w+_\w[\w_]*)/gm, function (x) {
|
||||
return x.replace(/_/gm, '\\_');
|
||||
@ -53,8 +43,9 @@
|
||||
return x.match(/\n{2}/) ? x : x.trim() + " \n";
|
||||
});
|
||||
|
||||
|
||||
text = text.replace(/\{gfm-js-extract-pre-([0-9]+)\}/gm, function (x, y) {
|
||||
return "\n\n" + extractions[y];
|
||||
return "\n\n" + preExtractions[y];
|
||||
});
|
||||
|
||||
|
||||
@ -62,25 +53,43 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
// Auto-link URLs and emails
|
||||
type : 'lang',
|
||||
// GFM autolinking & custom image handling, happens AFTER showdown
|
||||
type : 'html',
|
||||
filter : function (text) {
|
||||
var extractions = {},
|
||||
var refExtractions = {},
|
||||
preExtractions = {},
|
||||
imageMarkdownRegex = /^(?:\{(.*?)\})?!(?:\[([^\n\]]*)\])(?:\(([^\n\]]*)\))?$/gim,
|
||||
hashID = 0;
|
||||
|
||||
function hashId() {
|
||||
return hashID++;
|
||||
}
|
||||
|
||||
// Extract pre blocks
|
||||
text = text.replace(/<(pre|code)>[\s\S]*?<\/(\1)>/gim, function (x) {
|
||||
var hash = hashId();
|
||||
preExtractions[hash] = x;
|
||||
return "{gfm-js-extract-pre-" + hash + "}";
|
||||
}, 'm');
|
||||
|
||||
// filter out def urls
|
||||
// from Marked https://github.com/chjj/marked/blob/master/lib/marked.js#L24
|
||||
text = text.replace(/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/gmi,
|
||||
function (x) {
|
||||
var hash = hashId();
|
||||
extractions[hash] = x;
|
||||
refExtractions[hash] = x;
|
||||
return "{gfm-js-extract-ref-url-" + hash + "}";
|
||||
});
|
||||
|
||||
// better URL support, but no title support
|
||||
text = text.replace(imageMarkdownRegex, function (match, key, alt, src) {
|
||||
if (src) {
|
||||
return '<img src="' + src + '" alt="' + alt + '" />';
|
||||
}
|
||||
|
||||
return '';
|
||||
});
|
||||
|
||||
// match a URL
|
||||
// adapted from https://gist.github.com/jorilallo/1283095#L158
|
||||
// and http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript
|
||||
@ -95,13 +104,18 @@
|
||||
return lookBehind ? wholeMatch : "<a href='" + wholeMatch + "'>" + wholeMatch + "</a>";
|
||||
});
|
||||
|
||||
// match emil
|
||||
// match email
|
||||
text = text.replace(/[a-z0-9_\-+=.]+@[a-z0-9\-]+(\.[a-z0-9-]+)+/gmi, function (wholeMatch) {
|
||||
return "<a href='mailto:" + wholeMatch + "'>" + wholeMatch + "</a>";
|
||||
});
|
||||
|
||||
// replace extractions
|
||||
text = text.replace(/\{gfm-js-extract-pre-([0-9]+)\}/gm, function (x, y) {
|
||||
return preExtractions[y];
|
||||
});
|
||||
|
||||
text = text.replace(/\{gfm-js-extract-ref-url-([0-9]+)\}/gi, function (x, y) {
|
||||
return "\n\n" + extractions[y];
|
||||
return "\n\n" + refExtractions[y];
|
||||
});
|
||||
|
||||
return text;
|
||||
|
@ -178,7 +178,7 @@ describe("Showdown client side converter", function () {
|
||||
},
|
||||
{
|
||||
input: "# http://google.co.uk",
|
||||
output: /^<h1 id="ahrefhttpgooglecoukhttpgooglecouka"><a href=\'http:\/\/google.co.uk\'>http:\/\/google.co.uk<\/a><\/h1>$/
|
||||
output: /^<h1 id="httpgooglecouk"><a href=\'http:\/\/google.co.uk\'>http:\/\/google.co.uk<\/a><\/h1>$/
|
||||
},
|
||||
{
|
||||
input: "* http://google.co.uk",
|
||||
@ -279,6 +279,30 @@ describe("Showdown client side converter", function () {
|
||||
});
|
||||
});
|
||||
|
||||
it("should NOT auto-link URLS inside of code/pre blocks", function () {
|
||||
var testPhrases = [
|
||||
{
|
||||
input: "```\nurl: http://google.co.uk\n```",
|
||||
output: /^<pre><code>url: http:\/\/google.co.uk \n<\/code><\/pre>$/
|
||||
},
|
||||
{
|
||||
input: "`url: http://google.co.uk`",
|
||||
output: /^<p><code>url: http:\/\/google.co.uk<\/code><\/p>$/
|
||||
},
|
||||
{
|
||||
input: "Hello type some `url: http://google.co.uk` stuff",
|
||||
output: /^<p>Hello type some <code>url: http:\/\/google.co.uk<\/code> stuff<\/p>$/
|
||||
}
|
||||
|
||||
],
|
||||
processedMarkup;
|
||||
|
||||
testPhrases.forEach(function (testPhrase) {
|
||||
processedMarkup = converter.makeHtml(testPhrase.input);
|
||||
processedMarkup.should.match(testPhrase.output);
|
||||
});
|
||||
});
|
||||
|
||||
it("should not display anything for reference URL", function () {
|
||||
var testPhrases = [
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user