fix(underline): Make underline lazy

fix underline if literalMidwordUnderscores option is enabled
it should end at the nearest closing underscores, not the furthest
pull/607/head
Vladimir Vuksanovic 2018-10-21 15:20:39 +02:00
parent 4da93e8e13
commit 81edc70da7
7 changed files with 85 additions and 70 deletions

132
dist/showdown.js vendored
View File

@ -1,5 +1,5 @@
;/*! showdown v 2.0.0-alpha1 - 25-09-2018 */
(function(){
;/*! showdown v 2.0.0-alpha1 - 21-10-2018 */
(function(){
/**
* Created by Tivie on 13-07-2015.
*/
@ -187,7 +187,7 @@ function allOptionsOn () {
}
return ret;
}
/**
* Created by Tivie on 06-01-2015.
*/
@ -567,7 +567,7 @@ showdown.validateExtension = function (ext) {
}
return true;
};
/**
* showdownjs helper functions
*/
@ -2255,7 +2255,7 @@ showdown.helper.emojis = {
'octocat': '<img width="20" height="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">',
'showdown': '<img width="20" height="20" align="absmiddle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAS1BMVEX///8jJS0jJS0jJS0jJS0jJS0jJS0jJS0jJS0jJS0jJS0jJS0jJS0jJS0jJS0jJS0jJS3b1q3b1q3b1q3b1q3b1q3b1q3b1q3b1q0565CIAAAAGXRSTlMAQHCAYCCw/+DQwPCQUBAwoHCAEP+wwFBgS2fvBgAAAUZJREFUeAHs1cGy7BAUheFFsEDw/k97VTq3T6ge2EmdM+pvrP6Iwd74XV9Kb52xuMU4/uc1YNgZLFOeV8FGdhGrNk5SEgUyPxAEdj4LlMRDyhVAMVEa2M7TBSeVZAFPdqHgzSZJwPKgcLFLAooHDJo4EDCw4gAtBoJA5UFj4Ng5LOGLwVXZuoIlji/jeQHFk7+baHxrCjeUwB9+s88KndvlhcyBN5BSkYNQIVVb4pV+Npm7hhuKDs/uMP5KxT3WzSNNLIuuoDpMmuAVMruMSeDyQBi24DTr43LAY7ILA1QYaWkgfHzFthYYzg67SQsCbB8GhJUEGCtO9n0rSaCLxgJQjS/JSgMTg2eBDEHAJ+H350AsjYNYscrErgI2e/l+mdR967TCX/v6N0EhPECYCP0i+IAoYQOE8BogNhQMEMdrgAQWHaMAAGi5I5euoY9NAAAAAElFTkSuQmCC">'
};
/**
* These are all the transformations that form block-level
* tags like paragraphs, headers, and list items.
@ -2288,7 +2288,7 @@ showdown.subParser('makehtml.blockGamut', function (text, options, globals) {
return text;
});
showdown.subParser('makehtml.blockQuotes', function (text, options, globals) {
'use strict';
@ -2331,7 +2331,7 @@ showdown.subParser('makehtml.blockQuotes', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.blockQuotes.after', text, options, globals).getText();
return text;
});
/**
* Process Markdown `<pre><code>` blocks.
*/
@ -2370,7 +2370,7 @@ showdown.subParser('makehtml.codeBlocks', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.codeBlocks.after', text, options, globals).getText();
return text;
});
/**
*
* * Backtick quotes are used for <code></code> spans.
@ -2419,7 +2419,7 @@ showdown.subParser('makehtml.codeSpans', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.codeSpans.after', text, options, globals).getText();
return text;
});
/**
* Turn Markdown link shortcuts into XHTML <a> tags.
*/
@ -2482,7 +2482,7 @@ showdown.subParser('makehtml.completeHTMLDocument', function (text, options, glo
text = globals.converter._dispatch('makehtml.completeHTMLDocument.after', text, options, globals).getText();
return text;
});
/**
* Convert all tabs to spaces
*/
@ -2516,7 +2516,7 @@ showdown.subParser('makehtml.detab', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.detab.after', text, options, globals).getText();
return text;
});
showdown.subParser('makehtml.ellipsis', function (text, options, globals) {
'use strict';
@ -2528,7 +2528,7 @@ showdown.subParser('makehtml.ellipsis', function (text, options, globals) {
return text;
});
/**
* These are all the transformations that occur *within* block-level
* tags like paragraphs, headers, and list items.
@ -2555,7 +2555,7 @@ showdown.subParser('makehtml.emoji', function (text, options, globals) {
return text;
});
/**
* Smart processing for ampersands and angle brackets that need to be encoded.
*/
@ -2579,7 +2579,7 @@ showdown.subParser('makehtml.encodeAmpsAndAngles', function (text, options, glob
text = globals.converter._dispatch('makehtml.encodeAmpsAndAngles.after', text, options, globals).getText();
return text;
});
/**
* Returns the string, with after processing the following backslash escape sequences.
*
@ -2601,7 +2601,7 @@ showdown.subParser('makehtml.encodeBackslashEscapes', function (text, options, g
text = globals.converter._dispatch('makehtml.encodeBackslashEscapes.after', text, options, globals).getText();
return text;
});
/**
* Encode/escape certain characters inside Markdown code runs.
* The point is that in code, these characters are literals,
@ -2625,7 +2625,7 @@ showdown.subParser('makehtml.encodeCode', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.encodeCode.after', text, options, globals).getText();
return text;
});
/**
* Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they
* don't conflict with their use in Markdown for code, italics and strong.
@ -2652,7 +2652,7 @@ showdown.subParser('makehtml.escapeSpecialCharsWithinTagAttributes', function (t
text = globals.converter._dispatch('makehtml.escapeSpecialCharsWithinTagAttributes.after', text, options, globals).getText();
return text;
});
/**
* Handle github codeblocks prior to running HashHTML so that
* HTML contained within the codeblock gets escaped properly
@ -2699,7 +2699,7 @@ showdown.subParser('makehtml.githubCodeBlocks', function (text, options, globals
return globals.converter._dispatch('makehtml.githubCodeBlocks.after', text, options, globals).getText();
});
showdown.subParser('makehtml.hashBlock', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('makehtml.hashBlock.before', text, options, globals).getText();
@ -2708,7 +2708,7 @@ showdown.subParser('makehtml.hashBlock', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.hashBlock.after', text, options, globals).getText();
return text;
});
/**
* Hash and escape <code> elements that should not be parsed as markdown
*/
@ -2727,7 +2727,7 @@ showdown.subParser('makehtml.hashCodeTags', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.hashCodeTags.after', text, options, globals).getText();
return text;
});
showdown.subParser('makehtml.hashElement', function (text, options, globals) {
'use strict';
@ -2747,7 +2747,7 @@ showdown.subParser('makehtml.hashElement', function (text, options, globals) {
return blockText;
};
});
showdown.subParser('makehtml.hashHTMLBlocks', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('makehtml.hashHTMLBlocks.before', text, options, globals).getText();
@ -2846,7 +2846,7 @@ showdown.subParser('makehtml.hashHTMLBlocks', function (text, options, globals)
text = globals.converter._dispatch('makehtml.hashHTMLBlocks.after', text, options, globals).getText();
return text;
});
/**
* Hash span elements that should not be parsed as markdown
*/
@ -2905,7 +2905,7 @@ showdown.subParser('makehtml.unhashHTMLSpans', function (text, options, globals)
text = globals.converter._dispatch('makehtml.unhashHTMLSpans.after', text, options, globals).getText();
return text;
});
/**
* Hash and escape <pre><code> elements that should not be parsed as markdown
*/
@ -2925,7 +2925,7 @@ showdown.subParser('makehtml.hashPreCodeTags', function (text, options, globals)
text = globals.converter._dispatch('makehtml.hashPreCodeTags.after', text, options, globals).getText();
return text;
});
showdown.subParser('makehtml.headers', function (text, options, globals) {
'use strict';
@ -3052,7 +3052,7 @@ showdown.subParser('makehtml.headers', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.headers.after', text, options, globals).getText();
return text;
});
/**
* Turn Markdown link shortcuts into XHTML <a> tags.
*/
@ -3068,7 +3068,7 @@ showdown.subParser('makehtml.horizontalRule', function (text, options, globals)
text = globals.converter._dispatch('makehtml.horizontalRule.after', text, options, globals).getText();
return text;
});
/**
* Turn Markdown image shortcuts into <img> tags.
*/
@ -3173,7 +3173,7 @@ showdown.subParser('makehtml.images', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.images.after', text, options, globals).getText();
return text;
});
showdown.subParser('makehtml.italicsAndBold', function (text, options, globals) {
'use strict';
@ -3240,7 +3240,7 @@ showdown.subParser('makehtml.italicsAndBold', function (text, options, globals)
text = globals.converter._dispatch('makehtml.italicsAndBold.after', text, options, globals).getText();
return text;
});
////
// makehtml/links.js
// Copyright (c) 2018 ShowdownJS
@ -3660,7 +3660,7 @@ showdown.subParser('makehtml.italicsAndBold', function (text, options, globals)
return text;
});
})();
/**
* Form HTML ordered (numbered) and unordered (bulleted) lists.
*/
@ -3877,7 +3877,7 @@ showdown.subParser('makehtml.lists', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.lists.after', text, options, globals).getText();
return text;
});
/**
* Parse metadata at the top of the document
*/
@ -3927,7 +3927,7 @@ showdown.subParser('makehtml.metadata', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.metadata.after', text, options, globals).getText();
return text;
});
/**
* Remove one level of line-leading tabs or spaces
*/
@ -3945,7 +3945,7 @@ showdown.subParser('makehtml.outdent', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.outdent.after', text, options, globals).getText();
return text;
});
/**
*
*/
@ -4016,7 +4016,7 @@ showdown.subParser('makehtml.paragraphs', function (text, options, globals) {
text = text.replace(/\n+$/g, '');
return globals.converter._dispatch('makehtml.paragraphs.after', text, options, globals).getText();
});
/**
* Run extension
*/
@ -4037,7 +4037,7 @@ showdown.subParser('makehtml.runExtension', function (ext, text, options, global
return text;
});
/**
* These are all the transformations that occur *within* block-level
* tags like paragraphs, headers, and list items.
@ -4088,7 +4088,7 @@ showdown.subParser('makehtml.spanGamut', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.spanGamut.after', text, options, globals).getText();
return text;
});
showdown.subParser('makehtml.strikethrough', function (text, options, globals) {
'use strict';
@ -4100,7 +4100,7 @@ showdown.subParser('makehtml.strikethrough', function (text, options, globals) {
return text;
});
/**
* Strips link definitions from text, stores the URLs and titles in
* hash references.
@ -4154,7 +4154,7 @@ showdown.subParser('makehtml.stripLinkDefinitions', function (text, options, glo
return text;
});
showdown.subParser('makehtml.tables', function (text, options, globals) {
'use strict';
@ -4298,7 +4298,7 @@ showdown.subParser('makehtml.tables', function (text, options, globals) {
return text;
});
showdown.subParser('makehtml.underline', function (text, options, globals) {
'use strict';
@ -4309,11 +4309,17 @@ showdown.subParser('makehtml.underline', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.underline.before', text, options, globals).getText();
if (options.literalMidWordUnderscores) {
text = text.replace(/\b_?__(\S[\s\S]*)___?\b/g, function (wm, txt) {
text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
return '<u>' + txt + '</u>';
});
text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
return '<u>' + txt + '</u>';
});
} else {
text = text.replace(/_?__(\S[\s\S]*?)___?/g, function (wm, m) {
text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
});
text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
});
}
@ -4325,7 +4331,7 @@ showdown.subParser('makehtml.underline', function (text, options, globals) {
return text;
});
/**
* Swap back in all the special characters we've hidden.
*/
@ -4341,7 +4347,7 @@ showdown.subParser('makehtml.unescapeSpecialChars', function (text, options, glo
text = globals.converter._dispatch('makehtml.unescapeSpecialChars.after', text, options, globals).getText();
return text;
});
showdown.subParser('makeMarkdown.blockquote', function (node, globals) {
'use strict';
@ -4364,7 +4370,7 @@ showdown.subParser('makeMarkdown.blockquote', function (node, globals) {
txt = '> ' + txt.split('\n').join('\n> ');
return txt;
});
showdown.subParser('makeMarkdown.codeBlock', function (node, globals) {
'use strict';
@ -4372,13 +4378,13 @@ showdown.subParser('makeMarkdown.codeBlock', function (node, globals) {
num = node.getAttribute('precodenum');
return '```' + lang + '\n' + globals.preList[num] + '\n```';
});
showdown.subParser('makeMarkdown.codeSpan', function (node) {
'use strict';
return '`' + node.innerHTML + '`';
});
showdown.subParser('makeMarkdown.emphasis', function (node, globals) {
'use strict';
@ -4394,7 +4400,7 @@ showdown.subParser('makeMarkdown.emphasis', function (node, globals) {
}
return txt;
});
showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) {
'use strict';
@ -4412,13 +4418,13 @@ showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel)
}
return txt;
});
showdown.subParser('makeMarkdown.hr', function () {
'use strict';
return '---';
});
showdown.subParser('makeMarkdown.image', function (node) {
'use strict';
@ -4437,7 +4443,7 @@ showdown.subParser('makeMarkdown.image', function (node) {
}
return txt;
});
showdown.subParser('makeMarkdown.links', function (node, globals) {
'use strict';
@ -4458,7 +4464,7 @@ showdown.subParser('makeMarkdown.links', function (node, globals) {
}
return txt;
});
showdown.subParser('makeMarkdown.list', function (node, globals, type) {
'use strict';
@ -4490,7 +4496,7 @@ showdown.subParser('makeMarkdown.list', function (node, globals, type) {
return txt.trim();
});
showdown.subParser('makeMarkdown.listItem', function (node, globals) {
'use strict';
@ -4516,7 +4522,7 @@ showdown.subParser('makeMarkdown.listItem', function (node, globals) {
return listItemTxt;
});
showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) {
@ -4637,7 +4643,7 @@ showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) {
return txt;
});
showdown.subParser('makeMarkdown.paragraph', function (node, globals) {
'use strict';
@ -4655,14 +4661,14 @@ showdown.subParser('makeMarkdown.paragraph', function (node, globals) {
return txt;
});
showdown.subParser('makeMarkdown.pre', function (node, globals) {
'use strict';
var num = node.getAttribute('prenum');
return '<pre>' + globals.preList[num] + '</pre>';
});
showdown.subParser('makeMarkdown.strikethrough', function (node, globals) {
'use strict';
@ -4678,7 +4684,7 @@ showdown.subParser('makeMarkdown.strikethrough', function (node, globals) {
}
return txt;
});
showdown.subParser('makeMarkdown.strong', function (node, globals) {
'use strict';
@ -4694,7 +4700,7 @@ showdown.subParser('makeMarkdown.strong', function (node, globals) {
}
return txt;
});
showdown.subParser('makeMarkdown.table', function (node, globals) {
'use strict';
@ -4765,7 +4771,7 @@ showdown.subParser('makeMarkdown.table', function (node, globals) {
return txt.trim();
});
showdown.subParser('makeMarkdown.tableCell', function (node, globals) {
'use strict';
@ -4781,7 +4787,7 @@ showdown.subParser('makeMarkdown.tableCell', function (node, globals) {
}
return txt.trim();
});
showdown.subParser('makeMarkdown.txt', function (node) {
'use strict';
@ -4825,7 +4831,7 @@ showdown.subParser('makeMarkdown.txt', function (node) {
return txt;
});
/**
* Created by Estevao on 31-05-2015.
*/
@ -5428,7 +5434,7 @@ showdown.Converter = function (converterOptions) {
metadata.raw = raw;
};
};
var root = this;
// AMD Loader
@ -5446,6 +5452,6 @@ if (typeof define === 'function' && define.amd) {
} else {
root.showdown = showdown;
}
}).call(this);
}).call(this);
//# sourceMappingURL=showdown.js.map
//# sourceMappingURL=showdown.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,11 +8,17 @@ showdown.subParser('makehtml.underline', function (text, options, globals) {
text = globals.converter._dispatch('makehtml.underline.before', text, options, globals).getText();
if (options.literalMidWordUnderscores) {
text = text.replace(/\b_?__(\S[\s\S]*)___?\b/g, function (wm, txt) {
text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
return '<u>' + txt + '</u>';
});
text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
return '<u>' + txt + '</u>';
});
} else {
text = text.replace(/_?__(\S[\s\S]*?)___?/g, function (wm, m) {
text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
});
text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
});
}

View File

@ -2,3 +2,4 @@
<p><u>an underlined sentence</u></p>
<p><u>three underscores are fine</u></p>
<p>_single_ underscores are left alone</p>
<p><u>multiple</u> underlines in a <u>paragraph</u></p>

View File

@ -5,3 +5,5 @@ __an underlined sentence__
___three underscores are fine___
_single_ underscores are left alone
__multiple__ underlines in a __paragraph__