mirror of
https://github.com/showdownjs/showdown.git
synced 2024-03-22 13:30:55 +08:00
0c6f345c4c
fix italicsAndBold if literalMidwordUnderscores option is enabled it should end at the nearest closing underscores, not the furthest Closes #544
71 lines
2.8 KiB
JavaScript
71 lines
2.8 KiB
JavaScript
showdown.subParser('italicsAndBold', function (text, options, globals) {
|
|
'use strict';
|
|
|
|
text = globals.converter._dispatch('italicsAndBold.before', text, options, globals);
|
|
|
|
// it's faster to have 3 separate regexes for each case than have just one
|
|
// because of backtracing, in some cases, it could lead to an exponential effect
|
|
// called "catastrophic backtrace". Ominous!
|
|
|
|
function parseInside (txt, left, right) {
|
|
/*
|
|
if (options.simplifiedAutoLink) {
|
|
txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);
|
|
}
|
|
*/
|
|
return left + txt + right;
|
|
}
|
|
|
|
// Parse underscores
|
|
if (options.literalMidWordUnderscores) {
|
|
text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
|
|
return parseInside (txt, '<strong><em>', '</em></strong>');
|
|
});
|
|
text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
|
|
return parseInside (txt, '<strong>', '</strong>');
|
|
});
|
|
text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) {
|
|
return parseInside (txt, '<em>', '</em>');
|
|
});
|
|
} else {
|
|
text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
|
|
return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
|
|
});
|
|
text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
|
|
return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
|
|
});
|
|
text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) {
|
|
// !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it)
|
|
return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
|
|
});
|
|
}
|
|
|
|
// Now parse asterisks
|
|
if (options.literalMidWordAsterisks) {
|
|
text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) {
|
|
return parseInside (txt, lead + '<strong><em>', '</em></strong>');
|
|
});
|
|
text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) {
|
|
return parseInside (txt, lead + '<strong>', '</strong>');
|
|
});
|
|
text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) {
|
|
return parseInside (txt, lead + '<em>', '</em>');
|
|
});
|
|
} else {
|
|
text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) {
|
|
return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
|
|
});
|
|
text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) {
|
|
return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
|
|
});
|
|
text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) {
|
|
// !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it)
|
|
return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
|
|
});
|
|
}
|
|
|
|
|
|
text = globals.converter._dispatch('italicsAndBold.after', text, options, globals);
|
|
return text;
|
|
});
|