Skip to content

Escape " in image titles (#586) - #587

Open
agu2347 wants to merge 1 commit into
hukkin:masterfrom
agu2347:fix-image-title-quote-escaping-issue-586
Open

agu2347 wants to merge 1 commit into
hukkin:masterfrom
agu2347:fix-image-title-quote-escaping-issue-586

Conversation

@agu2347

@agu2347 agu2347 commented Aug 25, 2026

Copy link
Copy Markdown

Fixes #586.

Root cause

image() in src/mdformat/renderer/_context.py writes node.attrs["title"] straight into the (uri "title") form without escaping embedded double quotes:

title = node.attrs.get("title")
if title is not None:
    return f'![{description}]({uri} "{title}")'

link(), a few lines below, already handles this correctly:

title = title.replace('"', '\\"')
return f'[{text}]({uri} "{title}")'

An unescaped " in an image title closes the title early, producing malformed Markdown, and makes mdformat.text() non-idempotent on such input — reformatting the (already malformed) output a second time reparses it differently and even escapes the image's own brackets.

Reproduced exactly as described in the issue:

src = '![alt](img.png "a \\"quoted\\" title")'
mdformat.text(src)   # -> '![alt](img.png "a "quoted" title")\n'  (title truncated)
mdformat.text(out)   # -> '!\\[alt\\](img.png "a "quoted" title")\n'  (not idempotent)

Fix

Mirror link()'s escaping in image().

Tests

Added a link and image titles with embedded quotes case to tests/data/default_style.md covering both link and image titles with an embedded, escaped quote. Confirmed this case fails against the unfixed code — mdformat._cli.run() actually raises Could not format ...: Formatted Markdown renders to different HTML than input Markdown, mdformat's own consistency check catching the corruption — and passes after the fix. Full test suite: 4286 passed, 1 skipped, 0 failures.

image() in src/mdformat/renderer/_context.py rendered node.attrs['title']
directly into the parenthesized `(uri "title")` form without escaping
embedded double quotes, unlike link() a few lines below which already
does `title.replace('"', '\\\\"')`. An unescaped quote in an image title
terminates the title early, producing malformed Markdown, and made
mdformat.text() non-idempotent on such input (a second format pass
reparsed the corrupted output differently, even escaping the image
brackets themselves).

Mirror link()'s escaping in image() so titles round-trip correctly.

Adds a `link and image titles with embedded quotes` case to
tests/data/default_style.md covering both link and image titles.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

" not escaped in image title.

1 participant