Skip to content

Commit 7293251

Browse files
authoredFeb 7, 2021
fix: Total rework of Emphasis/Strong (#1864)
BREAKING CHANGE: `em` and `strong` tokenizers have been merged into one `emStrong` tokenizer
1 parent f848e77 commit 7293251

14 files changed

+280
-372
lines changed
 

‎lib/marked.esm.js

+73-91
Original file line numberDiff line numberDiff line change
@@ -839,46 +839,61 @@ var Tokenizer_1 = class Tokenizer {
839839
}
840840
}
841841

842-
strong(src, maskedSrc, prevChar = '') {
843-
let match = this.rules.inline.strong.start.exec(src);
842+
emStrong(src, maskedSrc, prevChar = '') {
843+
let match = this.rules.inline.emStrong.lDelim.exec(src);
844+
if (!match) return;
844845

845-
if (match && (!match[1] || (match[1] && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))))) {
846-
maskedSrc = maskedSrc.slice(-1 * src.length);
847-
const endReg = match[0] === '**' ? this.rules.inline.strong.endAst : this.rules.inline.strong.endUnd;
846+
if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) return; // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
848847

848+
const nextChar = match[1] || match[2] || '';
849+
850+
if (!nextChar || (nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) {
851+
const lLength = match[0].length - 1;
852+
let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
853+
854+
const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
849855
endReg.lastIndex = 0;
850856

851-
let cap;
857+
maskedSrc = maskedSrc.slice(-1 * src.length + lLength); // Bump maskedSrc to same section of string as src (move to lexer?)
858+
852859
while ((match = endReg.exec(maskedSrc)) != null) {
853-
cap = this.rules.inline.strong.middle.exec(maskedSrc.slice(0, match.index + 3));
854-
if (cap) {
855-
return {
856-
type: 'strong',
857-
raw: src.slice(0, cap[0].length),
858-
text: src.slice(2, cap[0].length - 2)
859-
};
860+
rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
861+
862+
if (!rDelim) continue; // matched the first alternative in rules.js (skip the * in __abc*abc__)
863+
864+
rLength = rDelim.length;
865+
866+
if (match[3] || match[4]) { // found another Left Delim
867+
delimTotal += rLength;
868+
continue;
869+
} else if (match[5] || match[6]) { // either Left or Right Delim
870+
if (lLength % 3 && !((lLength + rLength) % 3)) {
871+
midDelimTotal += rLength;
872+
continue; // CommonMark Emphasis Rules 9-10
873+
}
860874
}
861-
}
862-
}
863-
}
864875

865-
em(src, maskedSrc, prevChar = '') {
866-
let match = this.rules.inline.em.start.exec(src);
876+
delimTotal -= rLength;
867877

868-
if (match && (!match[1] || (match[1] && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))))) {
869-
maskedSrc = maskedSrc.slice(-1 * src.length);
870-
const endReg = match[0] === '*' ? this.rules.inline.em.endAst : this.rules.inline.em.endUnd;
878+
if (delimTotal > 0) continue; // Haven't found enough closing delimiters
871879

872-
endReg.lastIndex = 0;
880+
// If this is the last rDelimiter, remove extra characters. *a*** -> *a*
881+
if (delimTotal + midDelimTotal - rLength <= 0 && !maskedSrc.slice(endReg.lastIndex).match(endReg)) {
882+
rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
883+
}
873884

874-
let cap;
875-
while ((match = endReg.exec(maskedSrc)) != null) {
876-
cap = this.rules.inline.em.middle.exec(maskedSrc.slice(0, match.index + 2));
877-
if (cap) {
885+
if (Math.min(lLength, rLength) % 2) {
878886
return {
879887
type: 'em',
880-
raw: src.slice(0, cap[0].length),
881-
text: src.slice(1, cap[0].length - 1)
888+
raw: src.slice(0, lLength + match.index + rLength + 1),
889+
text: src.slice(1, lLength + match.index + rLength)
890+
};
891+
}
892+
if (Math.min(lLength, rLength) % 2 === 0) {
893+
return {
894+
type: 'strong',
895+
raw: src.slice(0, lLength + match.index + rLength + 1),
896+
text: src.slice(2, lLength + match.index + rLength - 1)
882897
};
883898
}
884899
}
@@ -1182,74 +1197,41 @@ const inline = {
11821197
reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
11831198
nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
11841199
reflinkSearch: 'reflink|nolink(?!\\()',
1185-
strong: {
1186-
start: /^(?:(\*\*(?=[*punctuation]))|\*\*)(?![\s])|__/, // (1) returns if starts w/ punctuation
1187-
middle: /^\*\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*\*$|^__(?![\s])((?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?)__$/,
1188-
endAst: /[^punctuation\s]\*\*(?!\*)|[punctuation]\*\*(?!\*)(?:(?=[punctuation_\s]|$))/, // last char can't be punct, or final * must also be followed by punct (or endline)
1189-
endUnd: /[^\s]__(?!_)(?:(?=[punctuation*\s])|$)/ // last char can't be a space, and final _ must preceed punct or \s (or endline)
1190-
},
1191-
em: {
1192-
start: /^(?:(\*(?=[punctuation]))|\*)(?![*\s])|_/, // (1) returns if starts w/ punctuation
1193-
middle: /^\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*$|^_(?![_\s])(?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?_$/,
1194-
endAst: /[^punctuation\s]\*(?!\*)|[punctuation]\*(?!\*)(?:(?=[punctuation_\s]|$))/, // last char can't be punct, or final * must also be followed by punct (or endline)
1195-
endUnd: /[^\s]_(?!_)(?:(?=[punctuation*\s])|$)/ // last char can't be a space, and final _ must preceed punct or \s (or endline)
1200+
emStrong: {
1201+
lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
1202+
// (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.
1203+
// () Skip other delimiter (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
1204+
rDelimAst: /\_\_[^_]*?\*[^_]*?\_\_|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,
1205+
rDelimUnd: /\*\*[^*]*?\_[^*]*?\*\*|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
11961206
},
11971207
code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
11981208
br: /^( {2,}|\\)\n(?!\s*$)/,
11991209
del: noopTest$1,
1200-
text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*]|\b_|$)|[^ ](?= {2,}\n)))/,
1201-
punctuation: /^([\s*punctuation])/
1210+
text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
1211+
punctuation: /^([\spunctuation])/
12021212
};
12031213

1204-
// list of punctuation marks from common mark spec
1205-
// without * and _ to workaround cases with double emphasis
1214+
// list of punctuation marks from CommonMark spec
1215+
// without * and _ to handle the different emphasis markers * and _
12061216
inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~';
12071217
inline.punctuation = edit$1(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
12081218

12091219
// sequences em should skip over [title](link), `code`, <html>
1210-
inline._blockSkip = '\\[[^\\]]*?\\]\\([^\\)]*?\\)|`[^`]*?`|<[^>]*?>';
1211-
inline._overlapSkip = '__[^_]*?__|\\*\\*\\[^\\*\\]*?\\*\\*';
1220+
inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
1221+
inline.escapedEmSt = /\\\*|\\_/g;
12121222

12131223
inline._comment = edit$1(block._comment).replace('(?:-->|$)', '-->').getRegex();
12141224

1215-
inline.em.start = edit$1(inline.em.start)
1216-
.replace(/punctuation/g, inline._punctuation)
1225+
inline.emStrong.lDelim = edit$1(inline.emStrong.lDelim)
1226+
.replace(/punct/g, inline._punctuation)
12171227
.getRegex();
12181228

1219-
inline.em.middle = edit$1(inline.em.middle)
1220-
.replace(/punctuation/g, inline._punctuation)
1221-
.replace(/overlapSkip/g, inline._overlapSkip)
1229+
inline.emStrong.rDelimAst = edit$1(inline.emStrong.rDelimAst, 'g')
1230+
.replace(/punct/g, inline._punctuation)
12221231
.getRegex();
12231232

1224-
inline.em.endAst = edit$1(inline.em.endAst, 'g')
1225-
.replace(/punctuation/g, inline._punctuation)
1226-
.getRegex();
1227-
1228-
inline.em.endUnd = edit$1(inline.em.endUnd, 'g')
1229-
.replace(/punctuation/g, inline._punctuation)
1230-
.getRegex();
1231-
1232-
inline.strong.start = edit$1(inline.strong.start)
1233-
.replace(/punctuation/g, inline._punctuation)
1234-
.getRegex();
1235-
1236-
inline.strong.middle = edit$1(inline.strong.middle)
1237-
.replace(/punctuation/g, inline._punctuation)
1238-
.replace(/overlapSkip/g, inline._overlapSkip)
1239-
.getRegex();
1240-
1241-
inline.strong.endAst = edit$1(inline.strong.endAst, 'g')
1242-
.replace(/punctuation/g, inline._punctuation)
1243-
.getRegex();
1244-
1245-
inline.strong.endUnd = edit$1(inline.strong.endUnd, 'g')
1246-
.replace(/punctuation/g, inline._punctuation)
1247-
.getRegex();
1248-
1249-
inline.blockSkip = edit$1(inline._blockSkip, 'g')
1250-
.getRegex();
1251-
1252-
inline.overlapSkip = edit$1(inline._overlapSkip, 'g')
1233+
inline.emStrong.rDelimUnd = edit$1(inline.emStrong.rDelimUnd, 'g')
1234+
.replace(/punct/g, inline._punctuation)
12531235
.getRegex();
12541236

12551237
inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
@@ -1328,7 +1310,7 @@ inline.gfm = merge$1({}, inline.normal, {
13281310
url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
13291311
_backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
13301312
del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
1331-
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*~]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/
1313+
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/
13321314
});
13331315

13341316
inline.gfm.url = edit$1(inline.gfm.url, 'i')
@@ -1704,11 +1686,17 @@ var Lexer_1 = class Lexer {
17041686
maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString$1('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
17051687
}
17061688

1689+
// Mask out escaped em & strong delimiters
1690+
while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
1691+
maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
1692+
}
1693+
17071694
while (src) {
17081695
if (!keepPrevChar) {
17091696
prevChar = '';
17101697
}
17111698
keepPrevChar = false;
1699+
17121700
// escape
17131701
if (token = this.tokenizer.escape(src)) {
17141702
src = src.substring(token.raw.length);
@@ -1757,16 +1745,8 @@ var Lexer_1 = class Lexer {
17571745
continue;
17581746
}
17591747

1760-
// strong
1761-
if (token = this.tokenizer.strong(src, maskedSrc, prevChar)) {
1762-
src = src.substring(token.raw.length);
1763-
token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
1764-
tokens.push(token);
1765-
continue;
1766-
}
1767-
1768-
// em
1769-
if (token = this.tokenizer.em(src, maskedSrc, prevChar)) {
1748+
// em & strong
1749+
if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
17701750
src = src.substring(token.raw.length);
17711751
token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
17721752
tokens.push(token);
@@ -1812,7 +1792,9 @@ var Lexer_1 = class Lexer {
18121792
// text
18131793
if (token = this.tokenizer.inlineText(src, inRawBlock, smartypants)) {
18141794
src = src.substring(token.raw.length);
1815-
prevChar = token.raw.slice(-1);
1795+
if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
1796+
prevChar = token.raw.slice(-1);
1797+
}
18161798
keepPrevChar = true;
18171799
lastToken = tokens[tokens.length - 1];
18181800
if (lastToken && lastToken.type === 'text') {

‎lib/marked.js

+75-78
Large diffs are not rendered by default.

‎marked.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/Lexer.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -355,11 +355,17 @@ module.exports = class Lexer {
355355
maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
356356
}
357357

358+
// Mask out escaped em & strong delimiters
359+
while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
360+
maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
361+
}
362+
358363
while (src) {
359364
if (!keepPrevChar) {
360365
prevChar = '';
361366
}
362367
keepPrevChar = false;
368+
363369
// escape
364370
if (token = this.tokenizer.escape(src)) {
365371
src = src.substring(token.raw.length);
@@ -408,16 +414,8 @@ module.exports = class Lexer {
408414
continue;
409415
}
410416

411-
// strong
412-
if (token = this.tokenizer.strong(src, maskedSrc, prevChar)) {
413-
src = src.substring(token.raw.length);
414-
token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
415-
tokens.push(token);
416-
continue;
417-
}
418-
419-
// em
420-
if (token = this.tokenizer.em(src, maskedSrc, prevChar)) {
417+
// em & strong
418+
if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
421419
src = src.substring(token.raw.length);
422420
token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
423421
tokens.push(token);
@@ -463,7 +461,9 @@ module.exports = class Lexer {
463461
// text
464462
if (token = this.tokenizer.inlineText(src, inRawBlock, smartypants)) {
465463
src = src.substring(token.raw.length);
466-
prevChar = token.raw.slice(-1);
464+
if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
465+
prevChar = token.raw.slice(-1);
466+
}
467467
keepPrevChar = true;
468468
lastToken = tokens[tokens.length - 1];
469469
if (lastToken && lastToken.type === 'text') {

‎src/Tokenizer.js

+43-28
Original file line numberDiff line numberDiff line change
@@ -527,46 +527,61 @@ module.exports = class Tokenizer {
527527
}
528528
}
529529

530-
strong(src, maskedSrc, prevChar = '') {
531-
let match = this.rules.inline.strong.start.exec(src);
530+
emStrong(src, maskedSrc, prevChar = '') {
531+
let match = this.rules.inline.emStrong.lDelim.exec(src);
532+
if (!match) return;
532533

533-
if (match && (!match[1] || (match[1] && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))))) {
534-
maskedSrc = maskedSrc.slice(-1 * src.length);
535-
const endReg = match[0] === '**' ? this.rules.inline.strong.endAst : this.rules.inline.strong.endUnd;
534+
if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) return; // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
536535

536+
const nextChar = match[1] || match[2] || '';
537+
538+
if (!nextChar || (nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) {
539+
const lLength = match[0].length - 1;
540+
let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
541+
542+
const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
537543
endReg.lastIndex = 0;
538544

539-
let cap;
545+
maskedSrc = maskedSrc.slice(-1 * src.length + lLength); // Bump maskedSrc to same section of string as src (move to lexer?)
546+
540547
while ((match = endReg.exec(maskedSrc)) != null) {
541-
cap = this.rules.inline.strong.middle.exec(maskedSrc.slice(0, match.index + 3));
542-
if (cap) {
543-
return {
544-
type: 'strong',
545-
raw: src.slice(0, cap[0].length),
546-
text: src.slice(2, cap[0].length - 2)
547-
};
548+
rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
549+
550+
if (!rDelim) continue; // matched the first alternative in rules.js (skip the * in __abc*abc__)
551+
552+
rLength = rDelim.length;
553+
554+
if (match[3] || match[4]) { // found another Left Delim
555+
delimTotal += rLength;
556+
continue;
557+
} else if (match[5] || match[6]) { // either Left or Right Delim
558+
if (lLength % 3 && !((lLength + rLength) % 3)) {
559+
midDelimTotal += rLength;
560+
continue; // CommonMark Emphasis Rules 9-10
561+
}
548562
}
549-
}
550-
}
551-
}
552563

553-
em(src, maskedSrc, prevChar = '') {
554-
let match = this.rules.inline.em.start.exec(src);
564+
delimTotal -= rLength;
555565

556-
if (match && (!match[1] || (match[1] && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))))) {
557-
maskedSrc = maskedSrc.slice(-1 * src.length);
558-
const endReg = match[0] === '*' ? this.rules.inline.em.endAst : this.rules.inline.em.endUnd;
566+
if (delimTotal > 0) continue; // Haven't found enough closing delimiters
559567

560-
endReg.lastIndex = 0;
568+
// If this is the last rDelimiter, remove extra characters. *a*** -> *a*
569+
if (delimTotal + midDelimTotal - rLength <= 0 && !maskedSrc.slice(endReg.lastIndex).match(endReg)) {
570+
rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
571+
}
561572

562-
let cap;
563-
while ((match = endReg.exec(maskedSrc)) != null) {
564-
cap = this.rules.inline.em.middle.exec(maskedSrc.slice(0, match.index + 2));
565-
if (cap) {
573+
if (Math.min(lLength, rLength) % 2) {
566574
return {
567575
type: 'em',
568-
raw: src.slice(0, cap[0].length),
569-
text: src.slice(1, cap[0].length - 1)
576+
raw: src.slice(0, lLength + match.index + rLength + 1),
577+
text: src.slice(1, lLength + match.index + rLength)
578+
};
579+
}
580+
if (Math.min(lLength, rLength) % 2 === 0) {
581+
return {
582+
type: 'strong',
583+
raw: src.slice(0, lLength + match.index + rLength + 1),
584+
text: src.slice(2, lLength + match.index + rLength - 1)
570585
};
571586
}
572587
}

‎src/rules.js

+19-52
Original file line numberDiff line numberDiff line change
@@ -173,74 +173,41 @@ const inline = {
173173
reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
174174
nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
175175
reflinkSearch: 'reflink|nolink(?!\\()',
176-
strong: {
177-
start: /^(?:(\*\*(?=[*punctuation]))|\*\*)(?![\s])|__/, // (1) returns if starts w/ punctuation
178-
middle: /^\*\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*\*$|^__(?![\s])((?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?)__$/,
179-
endAst: /[^punctuation\s]\*\*(?!\*)|[punctuation]\*\*(?!\*)(?:(?=[punctuation_\s]|$))/, // last char can't be punct, or final * must also be followed by punct (or endline)
180-
endUnd: /[^\s]__(?!_)(?:(?=[punctuation*\s])|$)/ // last char can't be a space, and final _ must preceed punct or \s (or endline)
181-
},
182-
em: {
183-
start: /^(?:(\*(?=[punctuation]))|\*)(?![*\s])|_/, // (1) returns if starts w/ punctuation
184-
middle: /^\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*$|^_(?![_\s])(?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?_$/,
185-
endAst: /[^punctuation\s]\*(?!\*)|[punctuation]\*(?!\*)(?:(?=[punctuation_\s]|$))/, // last char can't be punct, or final * must also be followed by punct (or endline)
186-
endUnd: /[^\s]_(?!_)(?:(?=[punctuation*\s])|$)/ // last char can't be a space, and final _ must preceed punct or \s (or endline)
176+
emStrong: {
177+
lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
178+
// (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.
179+
// () Skip other delimiter (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
180+
rDelimAst: /\_\_[^_]*?\*[^_]*?\_\_|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,
181+
rDelimUnd: /\*\*[^*]*?\_[^*]*?\*\*|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
187182
},
188183
code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
189184
br: /^( {2,}|\\)\n(?!\s*$)/,
190185
del: noopTest,
191-
text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*]|\b_|$)|[^ ](?= {2,}\n)))/,
192-
punctuation: /^([\s*punctuation])/
186+
text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
187+
punctuation: /^([\spunctuation])/
193188
};
194189

195-
// list of punctuation marks from common mark spec
196-
// without * and _ to workaround cases with double emphasis
190+
// list of punctuation marks from CommonMark spec
191+
// without * and _ to handle the different emphasis markers * and _
197192
inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~';
198193
inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
199194

200195
// sequences em should skip over [title](link), `code`, <html>
201-
inline._blockSkip = '\\[[^\\]]*?\\]\\([^\\)]*?\\)|`[^`]*?`|<[^>]*?>';
202-
inline._overlapSkip = '__[^_]*?__|\\*\\*\\[^\\*\\]*?\\*\\*';
196+
inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
197+
inline.escapedEmSt = /\\\*|\\_/g;
203198

204199
inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
205200

206-
inline.em.start = edit(inline.em.start)
207-
.replace(/punctuation/g, inline._punctuation)
208-
.getRegex();
209-
210-
inline.em.middle = edit(inline.em.middle)
211-
.replace(/punctuation/g, inline._punctuation)
212-
.replace(/overlapSkip/g, inline._overlapSkip)
213-
.getRegex();
214-
215-
inline.em.endAst = edit(inline.em.endAst, 'g')
216-
.replace(/punctuation/g, inline._punctuation)
217-
.getRegex();
218-
219-
inline.em.endUnd = edit(inline.em.endUnd, 'g')
220-
.replace(/punctuation/g, inline._punctuation)
221-
.getRegex();
222-
223-
inline.strong.start = edit(inline.strong.start)
224-
.replace(/punctuation/g, inline._punctuation)
225-
.getRegex();
226-
227-
inline.strong.middle = edit(inline.strong.middle)
228-
.replace(/punctuation/g, inline._punctuation)
229-
.replace(/overlapSkip/g, inline._overlapSkip)
230-
.getRegex();
231-
232-
inline.strong.endAst = edit(inline.strong.endAst, 'g')
233-
.replace(/punctuation/g, inline._punctuation)
234-
.getRegex();
235-
236-
inline.strong.endUnd = edit(inline.strong.endUnd, 'g')
237-
.replace(/punctuation/g, inline._punctuation)
201+
inline.emStrong.lDelim = edit(inline.emStrong.lDelim)
202+
.replace(/punct/g, inline._punctuation)
238203
.getRegex();
239204

240-
inline.blockSkip = edit(inline._blockSkip, 'g')
205+
inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g')
206+
.replace(/punct/g, inline._punctuation)
241207
.getRegex();
242208

243-
inline.overlapSkip = edit(inline._overlapSkip, 'g')
209+
inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g')
210+
.replace(/punct/g, inline._punctuation)
244211
.getRegex();
245212

246213
inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
@@ -319,7 +286,7 @@ inline.gfm = merge({}, inline.normal, {
319286
url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
320287
_backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
321288
del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
322-
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*~]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/
289+
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/
323290
});
324291

325292
inline.gfm.url = edit(inline.gfm.url, 'i')

‎test/specs/bug/adjacent_lists.html

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p><em>foo <strong>bar *baz bim</strong> bam</em></p>

‎test/specs/bug/adjacent_lists.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*foo __bar *baz bim__ bam*

‎test/specs/commonmark/commonmark.0.29.json

+22-44
Original file line numberDiff line numberDiff line change
@@ -2916,8 +2916,7 @@
29162916
"example": 361,
29172917
"start_line": 6390,
29182918
"end_line": 6394,
2919-
"section": "Emphasis and strong emphasis",
2920-
"shouldFail": true
2919+
"section": "Emphasis and strong emphasis"
29212920
},
29222921
{
29232922
"markdown": "aa_\"bb\"_cc\n",
@@ -3125,17 +3124,15 @@
31253124
"example": 387,
31263125
"start_line": 6641,
31273126
"end_line": 6645,
3128-
"section": "Emphasis and strong emphasis",
3129-
"shouldFail": true
3127+
"section": "Emphasis and strong emphasis"
31303128
},
31313129
{
31323130
"markdown": "__foo, __bar__, baz__\n",
31333131
"html": "<p><strong>foo, <strong>bar</strong>, baz</strong></p>\n",
31343132
"example": 388,
31353133
"start_line": 6648,
31363134
"end_line": 6652,
3137-
"section": "Emphasis and strong emphasis",
3138-
"shouldFail": true
3135+
"section": "Emphasis and strong emphasis"
31393136
},
31403137
{
31413138
"markdown": "foo-__(bar)__\n",
@@ -3287,8 +3284,7 @@
32873284
"example": 407,
32883285
"start_line": 6831,
32893286
"end_line": 6835,
3290-
"section": "Emphasis and strong emphasis",
3291-
"shouldFail": true
3287+
"section": "Emphasis and strong emphasis"
32923288
},
32933289
{
32943290
"markdown": "*foo *bar**\n",
@@ -3328,8 +3324,7 @@
33283324
"example": 412,
33293325
"start_line": 6888,
33303326
"end_line": 6892,
3331-
"section": "Emphasis and strong emphasis",
3332-
"shouldFail": true
3327+
"section": "Emphasis and strong emphasis"
33333328
},
33343329
{
33353330
"markdown": "*foo **bar***\n",
@@ -3353,17 +3348,15 @@
33533348
"example": 415,
33543349
"start_line": 6913,
33553350
"end_line": 6917,
3356-
"section": "Emphasis and strong emphasis",
3357-
"shouldFail": true
3351+
"section": "Emphasis and strong emphasis"
33583352
},
33593353
{
33603354
"markdown": "foo******bar*********baz\n",
33613355
"html": "<p>foo<strong><strong><strong>bar</strong></strong></strong>***baz</p>\n",
33623356
"example": 416,
33633357
"start_line": 6919,
33643358
"end_line": 6923,
3365-
"section": "Emphasis and strong emphasis",
3366-
"shouldFail": true
3359+
"section": "Emphasis and strong emphasis"
33673360
},
33683361
{
33693362
"markdown": "*foo **bar *baz* bim** bop*\n",
@@ -3427,17 +3420,15 @@
34273420
"example": 424,
34283421
"start_line": 6990,
34293422
"end_line": 6994,
3430-
"section": "Emphasis and strong emphasis",
3431-
"shouldFail": true
3423+
"section": "Emphasis and strong emphasis"
34323424
},
34333425
{
34343426
"markdown": "____foo__ bar__\n",
34353427
"html": "<p><strong><strong>foo</strong> bar</strong></p>\n",
34363428
"example": 425,
34373429
"start_line": 6997,
34383430
"end_line": 7001,
3439-
"section": "Emphasis and strong emphasis",
3440-
"shouldFail": true
3431+
"section": "Emphasis and strong emphasis"
34413432
},
34423433
{
34433434
"markdown": "**foo **bar****\n",
@@ -3573,8 +3564,7 @@
35733564
"example": 442,
35743565
"start_line": 7129,
35753566
"end_line": 7133,
3576-
"section": "Emphasis and strong emphasis",
3577-
"shouldFail": true
3567+
"section": "Emphasis and strong emphasis"
35783568
},
35793569
{
35803570
"markdown": "***foo**\n",
@@ -3598,17 +3588,15 @@
35983588
"example": 445,
35993589
"start_line": 7150,
36003590
"end_line": 7154,
3601-
"section": "Emphasis and strong emphasis",
3602-
"shouldFail": true
3591+
"section": "Emphasis and strong emphasis"
36033592
},
36043593
{
36053594
"markdown": "*foo****\n",
36063595
"html": "<p><em>foo</em>***</p>\n",
36073596
"example": 446,
36083597
"start_line": 7157,
36093598
"end_line": 7161,
3610-
"section": "Emphasis and strong emphasis",
3611-
"shouldFail": true
3599+
"section": "Emphasis and strong emphasis"
36123600
},
36133601
{
36143602
"markdown": "foo ___\n",
@@ -3664,53 +3652,47 @@
36643652
"example": 453,
36653653
"start_line": 7209,
36663654
"end_line": 7213,
3667-
"section": "Emphasis and strong emphasis",
3668-
"shouldFail": true
3655+
"section": "Emphasis and strong emphasis"
36693656
},
36703657
{
36713658
"markdown": "_foo__\n",
36723659
"html": "<p><em>foo</em>_</p>\n",
36733660
"example": 454,
36743661
"start_line": 7220,
36753662
"end_line": 7224,
3676-
"section": "Emphasis and strong emphasis",
3677-
"shouldFail": true
3663+
"section": "Emphasis and strong emphasis"
36783664
},
36793665
{
36803666
"markdown": "___foo__\n",
36813667
"html": "<p>_<strong>foo</strong></p>\n",
36823668
"example": 455,
36833669
"start_line": 7227,
36843670
"end_line": 7231,
3685-
"section": "Emphasis and strong emphasis",
3686-
"shouldFail": true
3671+
"section": "Emphasis and strong emphasis"
36873672
},
36883673
{
36893674
"markdown": "____foo_\n",
36903675
"html": "<p>___<em>foo</em></p>\n",
36913676
"example": 456,
36923677
"start_line": 7234,
36933678
"end_line": 7238,
3694-
"section": "Emphasis and strong emphasis",
3695-
"shouldFail": true
3679+
"section": "Emphasis and strong emphasis"
36963680
},
36973681
{
36983682
"markdown": "__foo___\n",
36993683
"html": "<p><strong>foo</strong>_</p>\n",
37003684
"example": 457,
37013685
"start_line": 7241,
37023686
"end_line": 7245,
3703-
"section": "Emphasis and strong emphasis",
3704-
"shouldFail": true
3687+
"section": "Emphasis and strong emphasis"
37053688
},
37063689
{
37073690
"markdown": "_foo____\n",
37083691
"html": "<p><em>foo</em>___</p>\n",
37093692
"example": 458,
37103693
"start_line": 7248,
37113694
"end_line": 7252,
3712-
"section": "Emphasis and strong emphasis",
3713-
"shouldFail": true
3695+
"section": "Emphasis and strong emphasis"
37143696
},
37153697
{
37163698
"markdown": "**foo**\n",
@@ -3766,26 +3748,23 @@
37663748
"example": 465,
37673749
"start_line": 7307,
37683750
"end_line": 7311,
3769-
"section": "Emphasis and strong emphasis",
3770-
"shouldFail": true
3751+
"section": "Emphasis and strong emphasis"
37713752
},
37723753
{
37733754
"markdown": "***foo***\n",
37743755
"html": "<p><em><strong>foo</strong></em></p>\n",
37753756
"example": 466,
37763757
"start_line": 7316,
37773758
"end_line": 7320,
3778-
"section": "Emphasis and strong emphasis",
3779-
"shouldFail": true
3759+
"section": "Emphasis and strong emphasis"
37803760
},
37813761
{
37823762
"markdown": "_____foo_____\n",
37833763
"html": "<p><em><strong><strong>foo</strong></strong></em></p>\n",
37843764
"example": 467,
37853765
"start_line": 7323,
37863766
"end_line": 7327,
3787-
"section": "Emphasis and strong emphasis",
3788-
"shouldFail": true
3767+
"section": "Emphasis and strong emphasis"
37893768
},
37903769
{
37913770
"markdown": "*foo _bar* baz_\n",
@@ -3809,8 +3788,7 @@
38093788
"example": 470,
38103789
"start_line": 7348,
38113790
"end_line": 7352,
3812-
"section": "Emphasis and strong emphasis",
3813-
"shouldFail": true
3791+
"section": "Emphasis and strong emphasis"
38143792
},
38153793
{
38163794
"markdown": "*foo *bar baz*\n",

‎test/specs/gfm/commonmark.0.29.json

+22-44
Original file line numberDiff line numberDiff line change
@@ -2916,8 +2916,7 @@
29162916
"example": 361,
29172917
"start_line": 6390,
29182918
"end_line": 6394,
2919-
"section": "Emphasis and strong emphasis",
2920-
"shouldFail": true
2919+
"section": "Emphasis and strong emphasis"
29212920
},
29222921
{
29232922
"markdown": "aa_\"bb\"_cc\n",
@@ -3125,17 +3124,15 @@
31253124
"example": 387,
31263125
"start_line": 6641,
31273126
"end_line": 6645,
3128-
"section": "Emphasis and strong emphasis",
3129-
"shouldFail": true
3127+
"section": "Emphasis and strong emphasis"
31303128
},
31313129
{
31323130
"markdown": "__foo, __bar__, baz__\n",
31333131
"html": "<p><strong>foo, <strong>bar</strong>, baz</strong></p>\n",
31343132
"example": 388,
31353133
"start_line": 6648,
31363134
"end_line": 6652,
3137-
"section": "Emphasis and strong emphasis",
3138-
"shouldFail": true
3135+
"section": "Emphasis and strong emphasis"
31393136
},
31403137
{
31413138
"markdown": "foo-__(bar)__\n",
@@ -3287,8 +3284,7 @@
32873284
"example": 407,
32883285
"start_line": 6831,
32893286
"end_line": 6835,
3290-
"section": "Emphasis and strong emphasis",
3291-
"shouldFail": true
3287+
"section": "Emphasis and strong emphasis"
32923288
},
32933289
{
32943290
"markdown": "*foo *bar**\n",
@@ -3328,8 +3324,7 @@
33283324
"example": 412,
33293325
"start_line": 6888,
33303326
"end_line": 6892,
3331-
"section": "Emphasis and strong emphasis",
3332-
"shouldFail": true
3327+
"section": "Emphasis and strong emphasis"
33333328
},
33343329
{
33353330
"markdown": "*foo **bar***\n",
@@ -3353,17 +3348,15 @@
33533348
"example": 415,
33543349
"start_line": 6913,
33553350
"end_line": 6917,
3356-
"section": "Emphasis and strong emphasis",
3357-
"shouldFail": true
3351+
"section": "Emphasis and strong emphasis"
33583352
},
33593353
{
33603354
"markdown": "foo******bar*********baz\n",
33613355
"html": "<p>foo<strong><strong><strong>bar</strong></strong></strong>***baz</p>\n",
33623356
"example": 416,
33633357
"start_line": 6919,
33643358
"end_line": 6923,
3365-
"section": "Emphasis and strong emphasis",
3366-
"shouldFail": true
3359+
"section": "Emphasis and strong emphasis"
33673360
},
33683361
{
33693362
"markdown": "*foo **bar *baz* bim** bop*\n",
@@ -3427,17 +3420,15 @@
34273420
"example": 424,
34283421
"start_line": 6990,
34293422
"end_line": 6994,
3430-
"section": "Emphasis and strong emphasis",
3431-
"shouldFail": true
3423+
"section": "Emphasis and strong emphasis"
34323424
},
34333425
{
34343426
"markdown": "____foo__ bar__\n",
34353427
"html": "<p><strong><strong>foo</strong> bar</strong></p>\n",
34363428
"example": 425,
34373429
"start_line": 6997,
34383430
"end_line": 7001,
3439-
"section": "Emphasis and strong emphasis",
3440-
"shouldFail": true
3431+
"section": "Emphasis and strong emphasis"
34413432
},
34423433
{
34433434
"markdown": "**foo **bar****\n",
@@ -3573,8 +3564,7 @@
35733564
"example": 442,
35743565
"start_line": 7129,
35753566
"end_line": 7133,
3576-
"section": "Emphasis and strong emphasis",
3577-
"shouldFail": true
3567+
"section": "Emphasis and strong emphasis"
35783568
},
35793569
{
35803570
"markdown": "***foo**\n",
@@ -3598,17 +3588,15 @@
35983588
"example": 445,
35993589
"start_line": 7150,
36003590
"end_line": 7154,
3601-
"section": "Emphasis and strong emphasis",
3602-
"shouldFail": true
3591+
"section": "Emphasis and strong emphasis"
36033592
},
36043593
{
36053594
"markdown": "*foo****\n",
36063595
"html": "<p><em>foo</em>***</p>\n",
36073596
"example": 446,
36083597
"start_line": 7157,
36093598
"end_line": 7161,
3610-
"section": "Emphasis and strong emphasis",
3611-
"shouldFail": true
3599+
"section": "Emphasis and strong emphasis"
36123600
},
36133601
{
36143602
"markdown": "foo ___\n",
@@ -3664,53 +3652,47 @@
36643652
"example": 453,
36653653
"start_line": 7209,
36663654
"end_line": 7213,
3667-
"section": "Emphasis and strong emphasis",
3668-
"shouldFail": true
3655+
"section": "Emphasis and strong emphasis"
36693656
},
36703657
{
36713658
"markdown": "_foo__\n",
36723659
"html": "<p><em>foo</em>_</p>\n",
36733660
"example": 454,
36743661
"start_line": 7220,
36753662
"end_line": 7224,
3676-
"section": "Emphasis and strong emphasis",
3677-
"shouldFail": true
3663+
"section": "Emphasis and strong emphasis"
36783664
},
36793665
{
36803666
"markdown": "___foo__\n",
36813667
"html": "<p>_<strong>foo</strong></p>\n",
36823668
"example": 455,
36833669
"start_line": 7227,
36843670
"end_line": 7231,
3685-
"section": "Emphasis and strong emphasis",
3686-
"shouldFail": true
3671+
"section": "Emphasis and strong emphasis"
36873672
},
36883673
{
36893674
"markdown": "____foo_\n",
36903675
"html": "<p>___<em>foo</em></p>\n",
36913676
"example": 456,
36923677
"start_line": 7234,
36933678
"end_line": 7238,
3694-
"section": "Emphasis and strong emphasis",
3695-
"shouldFail": true
3679+
"section": "Emphasis and strong emphasis"
36963680
},
36973681
{
36983682
"markdown": "__foo___\n",
36993683
"html": "<p><strong>foo</strong>_</p>\n",
37003684
"example": 457,
37013685
"start_line": 7241,
37023686
"end_line": 7245,
3703-
"section": "Emphasis and strong emphasis",
3704-
"shouldFail": true
3687+
"section": "Emphasis and strong emphasis"
37053688
},
37063689
{
37073690
"markdown": "_foo____\n",
37083691
"html": "<p><em>foo</em>___</p>\n",
37093692
"example": 458,
37103693
"start_line": 7248,
37113694
"end_line": 7252,
3712-
"section": "Emphasis and strong emphasis",
3713-
"shouldFail": true
3695+
"section": "Emphasis and strong emphasis"
37143696
},
37153697
{
37163698
"markdown": "**foo**\n",
@@ -3766,26 +3748,23 @@
37663748
"example": 465,
37673749
"start_line": 7307,
37683750
"end_line": 7311,
3769-
"section": "Emphasis and strong emphasis",
3770-
"shouldFail": true
3751+
"section": "Emphasis and strong emphasis"
37713752
},
37723753
{
37733754
"markdown": "***foo***\n",
37743755
"html": "<p><em><strong>foo</strong></em></p>\n",
37753756
"example": 466,
37763757
"start_line": 7316,
37773758
"end_line": 7320,
3778-
"section": "Emphasis and strong emphasis",
3779-
"shouldFail": true
3759+
"section": "Emphasis and strong emphasis"
37803760
},
37813761
{
37823762
"markdown": "_____foo_____\n",
37833763
"html": "<p><em><strong><strong>foo</strong></strong></em></p>\n",
37843764
"example": 467,
37853765
"start_line": 7323,
37863766
"end_line": 7327,
3787-
"section": "Emphasis and strong emphasis",
3788-
"shouldFail": true
3767+
"section": "Emphasis and strong emphasis"
37893768
},
37903769
{
37913770
"markdown": "*foo _bar* baz_\n",
@@ -3809,8 +3788,7 @@
38093788
"example": 470,
38103789
"start_line": 7348,
38113790
"end_line": 7352,
3812-
"section": "Emphasis and strong emphasis",
3813-
"shouldFail": true
3791+
"section": "Emphasis and strong emphasis"
38143792
},
38153793
{
38163794
"markdown": "*foo *bar baz*\n",

‎test/specs/new/em_list_links.html

+8-9
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
</ul>
1515
</li>
1616
<li>bold italic<ul>
17-
<li><a href="https://www.google.com"><strong><em>named link</em></strong></a></li>
18-
<li><strong><em><a href="https://www.google.com">named link</a></em></strong></li>
19-
<li><a href="https://www.google.com"><strong><em>named link</em></strong></a></li>
20-
<li><strong><em><a href="https://www.google.com">named link</a></em></strong></li>
17+
<li><a href="https://www.google.com"><em><strong>named link</strong></em></a></li>
18+
<li><em><strong><a href="https://www.google.com">named link</a></strong></em></li>
19+
<li><a href="https://www.google.com"><em><strong>named link</strong></em></a></li>
20+
<li><em><strong><a href="https://www.google.com">named link</a></strong></em></li>
2121
<li><a href="https://www.google.com"><em><strong>named link</strong></em></a></li>
2222
<li><a href="https://www.google.com"><strong><em>named link</em></strong></a></li>
2323
<li><strong><em><a href="https://www.google.com">named link</a></em></strong></li>
@@ -42,14 +42,13 @@
4242
</ul>
4343
</li>
4444
<li>code bold italic<ul>
45-
<li><a href="https://www.google.com"><strong><em><code>named link</code></em></strong></a></li>
46-
<li><strong><em><a href="https://www.google.com"><code>named link</code></a></em></strong></li>
47-
<li><a href="https://www.google.com"><strong><em><code>named link</code></em></strong></a></li>
48-
<li><strong><em><a href="https://www.google.com"><code>named link</code></a></em></strong></li>
45+
<li><a href="https://www.google.com"><em><strong><code>named link</code></strong></em></a></li>
46+
<li><em><strong><a href="https://www.google.com"><code>named link</code></a></strong></em></li>
47+
<li><a href="https://www.google.com"><em><strong><code>named link</code></strong></em></a></li>
48+
<li><em><strong><a href="https://www.google.com"><code>named link</code></a></strong></em></li>
4949
<li><a href="https://www.google.com"><em><strong><code>named link</code></strong></em></a></li>
5050
<li><a href="https://www.google.com"><strong><em><code>named link</code></em></strong></a></li>
5151
<li><strong><em><a href="https://www.google.com"><code>named link</code></a></em></strong></li>
5252
</ul>
5353
</li>
5454
</ul>
55-

‎test/specs/original/strong_and_em_together.html

-7
This file was deleted.

‎test/specs/original/strong_and_em_together.md

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
markdown: `${'_'.repeat(101)} a`,
3+
html: `<p>${'_'.repeat(101)} a</p>`
4+
};

1 commit comments

Comments
 (1)
Please sign in to comment.