Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle bold/strong nested inside italics/em #307

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion inline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,18 @@ func TestEmphasisMix(t *testing.T) {
"***triple emphasis___\n",
"<p>***triple emphasis___</p>\n",

"*italics **and bold** end*\n",
"<p><em>italics <strong>and bold</strong> end</em></p>\n",

"*italics **and bold***\n",
"<p><em>italics <strong>and bold</strong></em></p>\n",

"***bold** and italics*\n",
"<p><em><strong>bold</strong> and italics</em></p>\n",

"*start **bold** and italics*\n",
"<p><em>start <strong>bold</strong> and italics</em></p>\n",

"*__triple emphasis__*\n",
"<p><em><strong>triple emphasis</strong></em></p>\n",

Expand All @@ -183,7 +195,7 @@ func TestEmphasisMix(t *testing.T) {
"<p><strong>improper *nesting</strong> is* bad</p>\n",

"*improper **nesting* is** bad\n",
"<p>*improper <strong>nesting* is</strong> bad</p>\n",
"<p><em>improper **nesting</em> is** bad</p>\n",
}
doTestsInline(t, tests)
}
Expand Down
14 changes: 8 additions & 6 deletions parser/inline.go
Original file line number Diff line number Diff line change
Expand Up @@ -1185,23 +1185,20 @@ func helperFindEmphChar(data []byte, c byte) int {
func helperEmphasis(p *Parser, data []byte, c byte) (int, ast.Node) {
i := 0

// skip one symbol if coming from emph3
// skip two symbols if coming from emph3, as it detected a double emphasis case
if len(data) > 1 && data[0] == c && data[1] == c {
i = 1
i += 2
}

for i < len(data) {
length := helperFindEmphChar(data[i:], c)
if length == 0 {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building on last commit, in the triple c case, we'd still have short-circuited here - but we actually want to claim this c as our own. So we do the rest of the validity checks first, and then do this check at the end to exit the loop

return 0, nil
}
i += length
if i >= len(data) {
return 0, nil
}

if i+1 < len(data) && data[i+1] == c {
i++
i += 2
Copy link
Author

@cddude229 cddude229 May 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i++ guarantees the next character checked is c. This means helperFindEmphChar above returns a guaranteed 0 for length, which then short-circuits to the return 0, nil case. We choose to skip the next c character here by incrementing by 2 instead. (This will expose a separate bug if we're actually in the triple c case, which is what the next commit fixes.)

continue
}

Expand All @@ -1218,6 +1215,11 @@ func helperEmphasis(p *Parser, data []byte, c byte) (int, ast.Node) {
p.Inline(emph, data[:i])
return i + 1, emph
}

// We have to check this at the end, otherwise the scenario where we find repeated c's will get skipped
if length == 0 {
return 0, nil
}
}

return 0, nil
Expand Down
2 changes: 1 addition & 1 deletion parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ func IsPunctuation2(d []byte) bool {
return unicode.IsPunct(r)
}

// IsSpace returns true if c is a white-space charactr
// IsSpace returns true if c is a white-space character
func IsSpace(c byte) bool {
return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v'
}
Expand Down
Loading