mdsmith
Esc
    v0.52.0 GitHub
    MDS047 prose ready

    MDS047: ambiguous-emphasis

    Forbid emphasis sequences whose meaning a human cannot predict at a glance.

    CommonMark pairs * and _ runs by counting flanking delimiters. The output is well-defined; the source is not. This rule names three shapes that read poorly and refuses them.

    The shapes are:

    • long runs of the same delimiter character
    • backslash escapes glued to a run
    • the same delimiter repeated three times across word boundaries

    The check runs on raw source bytes. It skips ranges covered by inline code spans, fenced code blocks, and indented code blocks.

    # Settings

    SettingTypeDefaultDescription
    max-runint0Maximum allowed length of a contiguous * or _ run; 0 disables the check
    forbid-escaped-in-runboolfalseFlag *\* or _\_ where a backslash-escaped delimiter butts against a run
    forbid-adjacent-same-delimboolfalseFlag three same-delimiter runs glued by non-whitespace (*a*b*, __a__b__)

    The defaults make the rule a no-op even when enabled, so it ships safe. The portable and plain conventions enable this rule and set max-run: 2. User overrides on top still win via deep-merge.

    # Config

    Enable all three detectors:

    rules:
      ambiguous-emphasis:
        max-run: 2
        forbid-escaped-in-run: true
        forbid-adjacent-same-delim: true

    Disable:

    rules:
      ambiguous-emphasis: false

    Long-run only (skip the other two detectors):

    rules:
      ambiguous-emphasis:
        max-run: 2

    # Examples

    # Bad – long delimiter run

    # Title
    
    ***bold-italic*** at the start of a paragraph.

    # Bad – escaped delimiter inside a run

    # Title
    
    *****\*a* in the rant string.

    # Bad – adjacent same-delimiter runs

    # Title
    
    __a__b__ ambiguous between bold(a) literal-b and literal-a bold(b).

    # Bad – the rant’s Peter Piper example

    # Title
    
    ***Peter* Piper** is the rant's other Exhibit-A example.

    # Good

    # Title
    
    This sentence has **bold** and *italic* and even `*****\*literal*` in a
    code span without flagging.
    
    Multiple separate emphases like *one* and *two* and *three* read
    naturally because spaces split the runs.

    # Good – patterns inside code spans

    # In code span
    
    The string `*****\*a*` inside an inline code span must not flag, and
    neither must `__a__b__` nor `***Peter* Piper**` when wrapped this way.

    # Good – patterns inside fenced code blocks

    # In fenced block
    
    The patterns below sit inside a fenced code block and must not flag.
    
    ```text
    *****\*a*
    ***bold-italic***
    __a__b__
    ***Peter* Piper**
    ```

    # Diagnostics

    • emphasis run of {n} delimiters; max is {max-run}
    • escaped delimiter inside emphasis run
    • adjacent same-delimiter emphasis is ambiguous

    # Edge Cases

    • No auto-fix. The right rewrite depends on author intent: add a space, swap to an HTML entity, or split the run. The rule reports and lets the author choose.
    • Symmetric openers and closers collapse. ***x*** has two three-star runs but emits a single long-run diagnostic, anchored at the first occurrence on the line.
    • Whitespace clears the gap. *a* *b* *c* does not flag adjacent same-delimiter because each gap contains a space; CommonMark resolves the runs unambiguously.
    • Interaction with MDS042. MDS042 (emphasis-style) pins which delimiter is used. MDS047 catches the ambiguous combinations that survive a delimiter pin. Both can fire on the same line.

    # Meta-Information

    • ID: MDS047
    • Name: ambiguous-emphasis
    • Status: ready
    • Default: disabled
    • Fixable: no
    • Implementation: source
    • Category: prose
    • markdownlint: MD037 (no-space-in-emphasis)
    • rumdl: MD037 (spaces-around-emphasis)
    • mado: MD037 (no-space-in-emphasis)