Skip to content

Commit fc15c87

Browse files
authored
Merge pull request #458 from greymoth-jp/fix/emphasis-mod3-original-length
Fix emphasis multiple-of-3 rule mis-rendering (e.g. *foo***bar*)
2 parents 90b1a73 + 2d26bc8 commit fc15c87

2 files changed

Lines changed: 25 additions & 2 deletions

File tree

src/mistune/inline_parser.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,9 @@ class _Delimiter:
529529
length: int
530530
can_open: bool
531531
can_close: bool
532+
#: original run length, used by the CommonMark multiple-of-3 rule even
533+
#: after the run has been partially consumed
534+
orig_length: int = 0
532535

533536

534537
def _finalize_emphasis_tokens(tokens: List[Dict[str, Any]], enabled: bool) -> List[Dict[str, Any]]:
@@ -618,7 +621,7 @@ def _split_text_token(
618621
index = len(parts)
619622
parts.append({"type": "text", "raw": text[pos:end]})
620623
if can_open or can_close:
621-
delimiters.append(_Delimiter(index, marker, length, can_open, can_close))
624+
delimiters.append(_Delimiter(index, marker, length, can_open, can_close, length))
622625
pos = end
623626

624627

@@ -733,7 +736,12 @@ def _has_emphasis_content(parts: List[Dict[str, Any]], start: int, end: int) ->
733736

734737
def _can_match_emphasis_delimiters(opener: _Delimiter, closer: _Delimiter) -> bool:
735738
if opener.can_close or closer.can_open:
736-
return (opener.length + closer.length) % 3 != 0 or opener.length % 3 == 0 and closer.length % 3 == 0
739+
# CommonMark rules 9 and 10: the multiple-of-3 test uses the lengths of
740+
# the original delimiter runs, not the lengths remaining after the runs
741+
# have been partially consumed.
742+
open_len = opener.orig_length
743+
close_len = closer.orig_length
744+
return (open_len + close_len) % 3 != 0 or open_len % 3 == 0 and close_len % 3 == 0
737745
return True
738746

739747

tests/fixtures/fix-commonmark.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@ CommonMark delimiter handling is the default.
5454
<p>*a *<em>b c</em> d</p>
5555
````````````````````````````````
5656

57+
The multiple-of-3 rule uses the original delimiter run length, so the
58+
remainder of a partially consumed run can still match a later delimiter.
59+
60+
```````````````````````````````` example
61+
*a***a*
62+
.
63+
<p><em>a</em>*<em>a</em></p>
64+
````````````````````````````````
65+
66+
```````````````````````````````` example
67+
*foo***bar*
68+
.
69+
<p><em>foo</em>*<em>bar</em></p>
70+
````````````````````````````````
71+
5772

5873
## Max depth
5974

0 commit comments

Comments
 (0)