Skip to content

Fix non-idempotent setext heading whose line ends in a tab#579

Open
sarathfrancis90 wants to merge 1 commit into
hukkin:masterfrom
sarathfrancis90:fix-setext-heading-tab-idempotency
Open

Fix non-idempotent setext heading whose line ends in a tab#579
sarathfrancis90 wants to merge 1 commit into
hukkin:masterfrom
sarathfrancis90:fix-setext-heading-tab-idempotency

Conversation

@sarathfrancis90

Copy link
Copy Markdown

I noticed mdformat isn't idempotent for a setext heading whose line ends in a tab. Formatting it once gives a heading with two spaces, and formatting that output again collapses them to one:

import mdformat
mdformat.text("first\tsecond\n---")      # -> "## first  second\n"  (two spaces)
mdformat.text("## first  second\n")        # -> "## first second\n"   (one space)

A line of a setext heading can end in a tab, which the parser keeps in the inline text token. When the heading is rewritten as a single-line ATX heading, that tab turns into a space right next to the space produced for the line break, so two spaces sneak in. A trailing space (rather than a tab) doesn't hit this because the parser strips trailing spaces.

The fix collapses the spaces around the converted line break so the heading renders the same way on a second pass. Added a fixture case to default_style.md; full test suite, flake8, black, isort and mypy are green.

A setext heading whose line ends in a tab kept that tab in the inline
text token. When the heading was rewritten as a single-line ATX heading,
the tab became a space next to the space produced for the line break,
yielding two consecutive spaces. Reformatting then collapsed them to one,
so formatting was not idempotent.

Collapse the spaces around the converted line break so the heading is
stable on a second format pass.
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.

1 participant