Skip to content

bug(MD049/MD037): rumdl fmt replaces inline code inside emphasis with X placeholders #651

@thegeorgeliu

Description

@thegeorgeliu

rumdl version

0.2.5 (also reproduces on main)

Installation method

mise

Bug description

When rumdl fmt auto-fixes an emphasis span that contains an inline-code span, the inline code, including its surrounding backticks, is replaced in the written file by a run of literal X characters of equal length. The original code content is permanently lost, so this corrupts the document.

Internally, rumdl masks inline code with equal-length X runs so that backtick contents are not mistaken for emphasis markers during detection. That masked copy is meant to be used only for detection, but for these two rules the masked text leaks into the fix replacement instead of the original text being restored.

Affected rules:

  • MD049 (emphasis style, _ to * or * to _)
  • MD037 (spaces inside emphasis)

MD050 (strong style) is not affected.

Steps to reproduce

  1. Create test.md:

    - _An item with `inline code` inside._
  2. Create .rumdl.toml:

    [MD049]
    style = "asterisk"
  3. Run:

    rumdl fmt test.md

Expected behavior

The inline code is preserved verbatim and only the emphasis markers change:

- *An item with `inline code` inside.*

Actual behavior

The inline code is replaced by X placeholders (here `inline code` is 13 characters, so 13 Xs):

- *An item with XXXXXXXXXXXXX inside.*

The same corruption occurs for MD037. Given the input A paragraph with * spaced inline code emphasis * here., rumdl fmt produces A paragraph with *spaced XXXXXXXXXXXXX emphasis* here.

Configuration

[MD049]
style = "asterisk"

Operating system

macOS

Additional context

  • This is fmt-only. rumdl check does not modify files, so it does not corrupt content (it only reports the warning).
  • Independent of line length/MD013 reflow, list vs. paragraph context, and the emphasis direction; the only requirement is that an inline-code span sits inside an emphasis span being fixed.
  • Root cause: the fix replacement is built from the code-masked copy of the line (replace_inline_code) rather than the original text.
  • Likely origin: For MD049, commit 1d38d7d1 (first released in v0.0.90) replaced the earlier AST-based emphasis fix, which read the replacement text straight from the original document, with the current approach that detects emphasis on the X-masked copy of the line and then reuses that masked text in the fix. For MD037, commit bac52d8a (first released in v0.0.72) made the equivalent change, switching from a regex over the original line to detection on the masked copy whose content then feeds the fix. In both, masking was added for detection but the fix was never switched back to the original text.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions