# Emphasis inside Strong broken in JS implementation when parenthesis involved

**URL:** <https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903>\
**Category:** Spec\
**Created:** [November 12, 2014, 7:19pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903 "2014-11-12T19:19:43Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nicolas\_Cadilhac](https://talk.commonmark.org/user_avatar/talk.commonmark.org/nicolas_cadilhac/32/516_2.png) [@Nicolas\_Cadilhac](https://talk.commonmark.org/u/Nicolas_Cadilhac)\
**Post date:** [November 12, 2014, 7:19pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/1 "2014-11-12T19:19:44Z")

</div>

Why does the following markdown string:

```
**Gomphocarpus (*Gomphocarpus physocarpus*, syn. *Asclepias physocarpa*)**

```

produces:

_Gomphocarpus (Gomphocarpus physocarpus_, syn. _Asclepias physocarpa_)\*\*

i.e.

```
<p><em><em>Gomphocarpus (</em>Gomphocarpus physocarpus</em>, syn. <em>Asclepias physocarpa</em>)**</p>

```

I experience this in the [Try page](http://spec.commonmark.org/dingus.html) of this site and on my own web site where I installed the prebuilt JS parser. Strangely, it is well formatted in the Preview pane at the right of the box where I typed this message… (same on stackoverflow, so I guess that a different parser is used here for the preview of WMD).

---

<div class="post-metadata">

**Author:** ![Knagis](https://talk.commonmark.org/letter_avatar_proxy/v2/letter/k/ba9def/32.png) [@Knagis](https://talk.commonmark.org/u/Knagis)\
**Post date:** [November 12, 2014, 7:22pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/2 "2014-11-12T19:22:43Z")

</div>

It is because of rule 3 for the emphasis parsing:

```
3. A single * character can close emphasis iff it is not preceded by whitespace.

```

This rule probably should be extended to consider opening parenthesis - if there isn’t a good example not to?

---

<div class="post-metadata">

**Author:** ![Nicolas\_Cadilhac](https://talk.commonmark.org/user_avatar/talk.commonmark.org/nicolas_cadilhac/32/516_2.png) [@Nicolas\_Cadilhac](https://talk.commonmark.org/u/Nicolas_Cadilhac)\
**Post date:** [November 12, 2014, 7:28pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/3 "2014-11-12T19:28:41Z")

</div>

You’re right. Thanks.  
It would be great to include parenthesis. Writing my sentence as I did seemed so natural (and this is the right way to write in botany).

May I add a non related question?.. Is the source of this WMD editor available somewhere? Like here and on StackOverflow, I’m looking to be able to plug my image upload service.

---

<div class="post-metadata">

**Author:** ![jgm](https://talk.commonmark.org/user_avatar/talk.commonmark.org/jgm/32/1360_2.png) [@jgm](https://talk.commonmark.org/u/jgm)\
**Post date:** [November 12, 2014, 8:06pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/4 "2014-11-12T20:06:31Z")

</div>

Yes, it’s probably a good idea to extend the rules so that closers can’t be preceded by `(` (or `[` or `{`?) and openers can’t be followed by `)` (or `]` or `}`?). Does anyone see problems with this?

Of course, it would mean you’d need to write

```
 *`)`*

```

if you wanted an italicized parenthesis.

---

<div class="post-metadata">

**Author:** ![jgm](https://talk.commonmark.org/user_avatar/talk.commonmark.org/jgm/32/1360_2.png) [@jgm](https://talk.commonmark.org/u/jgm)\
**Post date:** [November 12, 2014, 8:11pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/5 "2014-11-12T20:11:38Z")

</div>

By the way, you can work around this for now by using `_` for the inner emphasis markers.

---

<div class="post-metadata">

**Author:** ![Nicolas\_Cadilhac](https://talk.commonmark.org/user_avatar/talk.commonmark.org/nicolas_cadilhac/32/516_2.png) [@Nicolas\_Cadilhac](https://talk.commonmark.org/u/Nicolas_Cadilhac)\
**Post date:** [November 12, 2014, 8:17pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/6 "2014-11-12T20:17:17Z")

</div>

> [@jgm](#):
>
> By the way, you can work around this for now by using \_ for the inner emphasis markers.

😄 but I’m still in dev process right now so this is not a hurry…

---

<div class="post-metadata">

**Author:** ![Knagis](https://talk.commonmark.org/letter_avatar_proxy/v2/letter/k/ba9def/32.png) [@Knagis](https://talk.commonmark.org/u/Knagis)\
**Post date:** [November 18, 2014, 3:32pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/7 "2014-11-18T15:32:39Z")

</div>

@jgm - There could be a better approach for handling cases such as this - skip all symbols and punctuation before checking for whitespace before or after the emphasis char.

This would also handle cases like:

```
foo*. bar -- only closer because followed by space (skipping the dot)
**foo "*bar*" foo** -- skips quotes

```

---

<div class="post-metadata">

**Author:** ![jgm](https://talk.commonmark.org/user_avatar/talk.commonmark.org/jgm/32/1360_2.png) [@jgm](https://talk.commonmark.org/u/jgm)\
**Post date:** [November 18, 2014, 8:29pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/8 "2014-11-18T20:29:33Z")

</div>

There are some good ideas [here](http://www.vfmd.org/vfmd-spec/specification/#procedure-for-identifying-emphasis-tags). It looks hairy, but if I understand correctly, basic idea is fairly simple:

1. Strings of `*` or `_` are divided into “left flanking” and “right flanking,” based on two things: the character immediately before them and the character immediately after.
2. Left-flanking delimiters can open emphasis, right flanking can close, and non-flanking delimiters are just regular text.
3. A delimiter is left-flanking if the character to the left has a lower rank than the character to the right, according to the following ranking: spaces and newlines are 0, punctuation (unicode categories Pc, Pd, Ps, Pe, Pi, Pf, Po, Sc, Sk, Sm or So) is 1, the rest 2. And similarly a delimiter is right-flanking if the character to the left has a higher rank than the character to the right.

---

<div class="post-metadata">

**Author:** ![jgm](https://talk.commonmark.org/user_avatar/talk.commonmark.org/jgm/32/1360_2.png) [@jgm](https://talk.commonmark.org/u/jgm)\
**Post date:** [November 18, 2014, 9:46pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/9 "2014-11-18T21:46:42Z")

</div>

@Knagis, your idea is also a good one, I just wanted to mention another alternative that might be worth looking into. Both require recognizing unicode punctuation, which adds another level of complexity to the C parser. And your suggestion might require indefinite lookbehind or lookahead in cases where you have a whole pile of punctuation characters before or after the delimiter.

---

<div class="post-metadata">

**Author:** ![jgm](https://talk.commonmark.org/user_avatar/talk.commonmark.org/jgm/32/1360_2.png) [@jgm](https://talk.commonmark.org/u/jgm)\
**Post date:** [December 15, 2014, 2:31am UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/10 "2014-12-15T02:31:37Z")

</div>

I’ve implemented a solution on the `newemph` branch – still need to update the spec and the JS parser. But the examples in this thread are now handled well. If anyone is intersted, the commit is here:  
[https://github.com/jgm/CommonMark/commit/f716b37838f42f93e197d4ac3c90286108e28328](https://github.com/jgm/CommonMark/commit/f716b37838f42f93e197d4ac3c90286108e28328)

---

<div class="post-metadata">

**Author:** ![jgm](https://talk.commonmark.org/user_avatar/talk.commonmark.org/jgm/32/1360_2.png) [@jgm](https://talk.commonmark.org/u/jgm)\
**Post date:** [December 25, 2014, 6:51pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/11 "2014-12-25T18:51:39Z")

</div>

I’ve polished this change and merged it into master. Spec, C, and JS implementations have all been updated.

```auto
% ./cmark
**Gomphocarpus (*Gomphocarpus physocarpus*, syn. *Asclepias physocarpa*)**
^D
<p><strong>Gomphocarpus (<em>Gomphocarpus physocarpus</em>, syn. <em>Asclepias physocarpa</em>)</strong></p>

```

---

<div class="post-metadata">

**Author:** ![lu\_zero](https://talk.commonmark.org/user_avatar/talk.commonmark.org/lu_zero/32/557_2.png) [@lu\_zero](https://talk.commonmark.org/u/lu_zero)\
**Post date:** [December 25, 2014, 10:44pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/12 "2014-12-25T22:44:01Z")

</div>

do you have the commit line handy? I’d sync up the python implementation later.

---

<div class="post-metadata">

**Author:** ![Crissov](https://talk.commonmark.org/user_avatar/talk.commonmark.org/crissov/32/1455_2.png) [@Crissov](https://talk.commonmark.org/u/Crissov)\
**Post date:** [November 26, 2023, 10:05pm UTC](https://talk.commonmark.org/t/emphasis-inside-strong-broken-in-js-implementation-when-parenthesis-involved/903/13 "2023-11-26T22:05:33Z")

</div>

Nine years ago, @jgm concluded:

> 1. Strings of `*` or `_` are divided into “left flanking” and “right flanking,” based on two things:  
> the character immediately before them  
> and the character immediately after.
> 2. Left-flanking delimiters can open emphasis,  
> right flanking can close,  
> and non-flanking delimiters are just regular text.
> 3. A delimiter is left-flanking if the character to the left has a lower rank than the character to the right, according to the following ranking:  
> spaces and newlines are 0,  
> punctuation (unicode categories Pc, Pd, Ps, Pe, Pi, Pf, Po, Sc, Sk, Sm or So) is 1,  
> the rest 2.  
> And similarly a delimiter is right-flanking if the character to the left has a higher rank than the character to the right.

With minor subsequent changes, this led to the following [text in the specification](https://spec.commonmark.org/0.30/#left-flanking-delimiter-run):

> A [left-flanking delimiter run](https://spec.commonmark.org/0.30/#left-flanking-delimiter-run) is a [delimiter run](https://spec.commonmark.org/0.30/#delimiter-run) that is  
> (1) not followed by [Unicode whitespace](https://spec.commonmark.org/0.30/#unicode-whitespace), and  
> either (2a) not followed by a [Unicode punctuation character](https://spec.commonmark.org/0.30/#unicode-punctuation-character),  
> or (2b) followed by a [Unicode punctuation character](https://spec.commonmark.org/0.30/#unicode-punctuation-character) and preceded by [Unicode whitespace](https://spec.commonmark.org/0.30/#unicode-whitespace) or a [Unicode punctuation character](https://spec.commonmark.org/0.30/#unicode-punctuation-character). (…)
> 
> A [right-flanking delimiter run](https://spec.commonmark.org/0.30/#right-flanking-delimiter-run) is a [delimiter run](https://spec.commonmark.org/0.30/#delimiter-run) that is  
> (1) not preceded by [Unicode whitespace](https://spec.commonmark.org/0.30/#unicode-whitespace), and  
> either (2a) not preceded by a [Unicode punctuation character](https://spec.commonmark.org/0.30/#unicode-punctuation-character),  
> or (2b) preceded by a [Unicode punctuation character](https://spec.commonmark.org/0.30/#unicode-punctuation-character) and followed by [Unicode whitespace](https://spec.commonmark.org/0.30/#unicode-whitespace) or a [Unicode punctuation character](https://spec.commonmark.org/0.30/#unicode-punctuation-character).

> 1. A single `*` character [can open emphasis](https://spec.commonmark.org/0.30/#can-open-emphasis)  
> iff (if and only if) it is part of a [left-flanking delimiter run](https://spec.commonmark.org/0.30/#left-flanking-delimiter-run).
> 2. A single `_` character [can open emphasis](https://spec.commonmark.org/0.30/#can-open-emphasis)  
> iff it is part of a [left-flanking delimiter run](https://spec.commonmark.org/0.30/#left-flanking-delimiter-run) and  
> either (a) not part of a [right-flanking delimiter run](https://spec.commonmark.org/0.30/#right-flanking-delimiter-run)  
> or (b) part of a [right-flanking delimiter run](https://spec.commonmark.org/0.30/#right-flanking-delimiter-run) preceded by a [Unicode punctuation character](https://spec.commonmark.org/0.30/#unicode-punctuation-character).
> 3. A single `*` character [can close emphasis](https://spec.commonmark.org/0.30/#can-close-emphasis)  
> iff it is part of a [right-flanking delimiter run](https://spec.commonmark.org/0.30/#right-flanking-delimiter-run).
> 4. A single `_` character [can close emphasis](https://spec.commonmark.org/0.30/#can-close-emphasis)  
> iff it is part of a [right-flanking delimiter run](https://spec.commonmark.org/0.30/#right-flanking-delimiter-run) and  
> either (a) not part of a [left-flanking delimiter run](https://spec.commonmark.org/0.30/#left-flanking-delimiter-run)  
> or (b) part of a [left-flanking delimiter run](https://spec.commonmark.org/0.30/#left-flanking-delimiter-run) followed by a [Unicode punctuation character](https://spec.commonmark.org/0.30/#unicode-punctuation-character).

In an [issue comment on GitHub](https://github.com/commonmark/commonmark-spec/issues/650), I suggested that it may be useful – especially for East Asian languages and others written without inter-word spacing –, to treat the different Unicode punctuation classes differently for flanking (or _can open/close emphasis_) behavior.

- Open/Start `Ps`, e.g. `(`
- Initial `Pi`, e.g. `“`
- Close/End `Pe`, e.g. `)`
- Final `Pf`, e.g. `”`
- Connector `Pc`, e.g. `_`
- Dash `Pd`, e.g. `-`
- Other `Po`, e.g. `,`

## Current classification of delimiter runs

- `␠`: any (Unicode) whitespace, including line start and end
- `.`: any (Unicode) punctuation
- `a`: neither punctuation nor whitespace

| Before | After | Flanking | Open | Close |
| --- | --- | --- | --- | --- |
| ␠ | ␠ | none | | |
| a | a | both (2a) | `*` | `*` |
| . | . | both (2b2) | `*`, `_` (b) | `*`, `_` (b) |
| . | a | left (2a) | `*`, `_` (a) | |
| ␠ | a | left (2a) | `*`, `_` (a) | |
| ␠ | . | left (2b1) | `*`, `_` (a) | |
| a | . | right (2a) | | `*`, `_` (a) |
| a | ␠ | right (2a) | | `*`, `_` (a) |
| . | ␠ | right (2b1) | | `*`, `_` (a) |

## Proposed differentiation of punctuation classes

- `(`: `Ps` or `Pi`
- `)`: `Pe` or `Pf`
- `,`: `Pc`, `Pd` or `Po`

| Before | After | Flanking | Open | Close |
| --- | --- | --- | --- | --- |
| , | , | both | `*`, `_` | `*`, `_` |
| ( | ( | left ( ~~both~~ ) | `*`, `_` | `*`, `_` |
| ) | ) | right ( ~~both~~ ) | `*`, `_` | `*`, `_` |
| ( | ) | both | `*`, `_`? | `*`, `_`? |
| ) | ( | both (none?) | `*`, `_` | `*`, `_` |
| ( | , | both (left?) | `*`, `_` | `*`, `_` |
| ) | , | right ( ~~both~~ ) | `*`, `_` | `*`, `_` |
| , | ( | left ( ~~both~~ ) | `*`, `_` | `*`, `_` |
| , | ) | both (right?) | `*`, `_` | `*`, `_` |
| ( | a | left | `*`, `_` | |
| ␠ | ( | left | `*`, `_` | |
| a | ( | **both** ~~right~~ | **`*`, `_`** | `*`, `_` |
| ( | ␠ | right | | `*`, `_` |
| ) | a | **both** ~~left~~ | `*`, `_` | **`*`, `_`** |
| ␠ | ) | left | `*`, `_` | |
| a | ) | right | | `*`, `_` |
| ) | ␠ | right | | `*`, `_` |
| , | a | left | `*`, `_` | |
| ␠ | , | left | `*`, `_` | |
| a | , | right | | `*`, `_` |
| , | ␠ | right | | `*`, `_` |

> A **left-flanking delimiter run** is a _delimiter run_ that is  
> (1) not followed by _whitespace_, and  
> either (2a) not followed by _punctuation_,  
> or (2b) followed by _ **non-starting** punctuation_ and preceded by _whitespace_ or _ **non-ending** punctuation_,  
> or **(2c)** followed by _starting punctuation_.  
> A **strongly left-flanking delimiter run** is a _left-flanking delimiter run_ that is  
> either (a) not part of a _right-flanking delimiter run_  
> or (b) part of a _right-flanking delimiter run_ preceded by _punctuation_  
> (…)

> 1. A single `*` character _can open emphasis_  
> iff (if and only if) it is part of a _left-flanking delimiter run_.
> 2. A single `_` character _can open emphasis_  
> iff it is part of a _strongly left-flanking delimiter run_
> 3. (…)
