diff --git a/CHANGELOG.md b/CHANGELOG.md index 040ff138..39733e46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* šŸ› Fix code span padding to strip one surrounding space when the content consists of tabs or other non-space whitespace. * ✨ Add `--enable-tables` to the CLI for file, standard input and interactive parsing in [#422](https://github.com/executablebooks/markdown-it-py/pull/422) * šŸ› Fix CLI interactive mode joining input lines with an extra newline, which split every line into its own paragraph and broke hard line breaks, in [#172](https://github.com/executablebooks/markdown-it-py/issues/172) * šŸ› Fix trimming and splitting with the Python whitespace set instead of the CommonMark one, which dropped U+001C–U+001F and U+0085 from paragraphs, headings, table cells and fence info strings and let distinct reference labels resolve each other, in [#418](https://github.com/executablebooks/markdown-it-py/pull/418), thanks to [@Nexory](https://github.com/Nexory) diff --git a/markdown_it/rules_inline/backticks.py b/markdown_it/rules_inline/backticks.py index 67b5b5af..d1b6023b 100644 --- a/markdown_it/rules_inline/backticks.py +++ b/markdown_it/rules_inline/backticks.py @@ -54,7 +54,7 @@ def backtick(state: StateInline, silent: bool) -> bool: if ( token.content.startswith(" ") and token.content.endswith(" ") - and len(token.content.strip()) > 0 + and len(token.content.strip(" ")) > 0 ): token.content = token.content[1:-1] state.pos = matchEnd diff --git a/tests/test_port/test_backticks.py b/tests/test_port/test_backticks.py new file mode 100644 index 00000000..38edf814 --- /dev/null +++ b/tests/test_port/test_backticks.py @@ -0,0 +1,51 @@ +"""Code span padding uses U+0020 spaces, not Python's whitespace set.""" + +import pytest + +from markdown_it import MarkdownIt + + +@pytest.mark.parametrize("marker", ["`", "``"]) +@pytest.mark.parametrize( + "content,expected", + [ + pytest.param(" \t ", "\t", id="tab"), + pytest.param(" \v ", "\v", id="vertical-tab"), + pytest.param(" \f ", "\f", id="form-feed"), + pytest.param(" \x1c ", "\x1c", id="file-separator"), + pytest.param(" \x85 ", "\x85", id="next-line"), + pytest.param(" \xa0 ", "\xa0", id="no-break-space"), + pytest.param(" \u2003 ", "\u2003", id="em-space"), + pytest.param(" \u2028 ", "\u2028", id="line-separator"), + pytest.param(" \u3000 ", "\u3000", id="ideographic-space"), + pytest.param(" \t\xa0 ", "\t\xa0", id="mixed-whitespace"), + pytest.param(" \t ", " \t ", id="one-space-per-side"), + pytest.param(" ", " ", id="one-space"), + pytest.param(" ", " ", id="two-spaces"), + pytest.param(" ", " ", id="three-spaces"), + pytest.param("\t", "\t", id="bare-tab"), + pytest.param("\xa0", "\xa0", id="bare-no-break-space"), + pytest.param(" \t", " \t", id="leading-space-only"), + pytest.param("\t ", "\t ", id="trailing-space-only"), + pytest.param("\t text \t", "\t text \t", id="non-space-edges"), + pytest.param(" text ", "text", id="text-padding"), + pytest.param("a \t b", "a \t b", id="internal-whitespace"), + pytest.param("\n", " ", id="newline-only"), + pytest.param(" \n ", " ", id="spaces-and-newline"), + pytest.param("\n\t\n", "\t", id="newline-padding"), + pytest.param("\r\t\r", "\t", id="carriage-return-padding"), + pytest.param("\r\n\t\r\n", "\t", id="crlf-padding"), + ], +) +def test_code_span_space_padding(marker, content, expected): + """Strip one surrounding space unless the normalized content is all spaces.""" + md = MarkdownIt("commonmark") + source = f"{marker}{content}{marker}" + + assert md.renderInline(source) == f"{expected}" + children = md.parseInline(source)[0].children + assert children is not None + assert len(children) == 1 + assert children[0].type == "code_inline" + assert children[0].markup == marker + assert children[0].content == expected