From 48495b7d98bbff9b678ee905ad61a1ce1cafbc8e Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 30 Jun 2024 11:33:26 +0100 Subject: [PATCH] Support tabbed indentation --- src/blacken_docs/__init__.py | 18 +++---- tests/test_blacken_docs.py | 98 ++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 9 deletions(-) diff --git a/src/blacken_docs/__init__.py b/src/blacken_docs/__init__.py index 298fb99..534b5fe 100644 --- a/src/blacken_docs/__init__.py +++ b/src/blacken_docs/__init__.py @@ -16,7 +16,7 @@ PYGMENTS_PY_LANGS = frozenset(("python", "py", "sage", "python3", "py3", "numpy")) PYGMENTS_PY_LANGS_RE_FRAGMENT = f"({'|'.join(PYGMENTS_PY_LANGS)})" MD_RE = re.compile( - r"(?P^(?P *)```[^\S\r\n]*" + r"(?P^(?P[ \t]*)```[^\S\r\n]*" + PYGMENTS_PY_LANGS_RE_FRAGMENT + r"( .*?)?\n)" r"(?P.*?)" @@ -24,7 +24,7 @@ re.DOTALL | re.MULTILINE, ) MD_PYCON_RE = re.compile( - r"(?P^(?P *)```[^\S\r\n]*pycon( .*?)?\n)" + r"(?P^(?P[ \t]*)```[^\S\r\n]*pycon( .*?)?\n)" r"(?P.*?)" r"(?P^(?P=indent)```[^\S\r\n]*$)", re.DOTALL | re.MULTILINE, @@ -33,20 +33,20 @@ DOCTEST_TYPES = "(testsetup|testcleanup|testcode)" RST_RE = re.compile( rf"(?P" - rf"^(?P *)\.\. (" + rf"^(?P[ \t]*)\.\. (" rf"jupyter-execute::|" rf"{BLOCK_TYPES}:: (?P\w+)|" rf"{DOCTEST_TYPES}::.*" rf")\n" rf"((?P=indent) +:.*\n)*" - rf"( *\n)*" + rf"([ \t]*\n)*" rf")" rf"(?P(^((?P=indent) +.*)?\n)+)", re.MULTILINE, ) RST_LITERAL_BLOCKS_RE = re.compile( r"(?P" - r"^(?! *\.\. )(?P *).*::\n" + r"^(?! *\.\. )(?P[ \t]*).*::\n" r"((?P=indent) +:.*\n)*" r"\n*" r")" @@ -55,7 +55,7 @@ ) RST_PYCON_RE = re.compile( r"(?P" - r"(?P *)\.\. ((code|code-block):: pycon|doctest::.*)\n" + r"(?P[ \t]*)\.\. ((code|code-block):: pycon|doctest::.*)\n" r"((?P=indent) +:.*\n)*" r"\n*" r")" @@ -68,20 +68,20 @@ rf"^{re.escape(PYCON_CONTINUATION_PREFIX)}( |$)", ) LATEX_RE = re.compile( - r"(?P^(?P *)\\begin{minted}(\[.*?\])?{python}\n)" + r"(?P^(?P[ \t]*)\\begin{minted}(\[.*?\])?{python}\n)" r"(?P.*?)" r"(?P^(?P=indent)\\end{minted}\s*$)", re.DOTALL | re.MULTILINE, ) LATEX_PYCON_RE = re.compile( - r"(?P^(?P *)\\begin{minted}(\[.*?\])?{pycon}\n)" + r"(?P^(?P[ \t]*)\\begin{minted}(\[.*?\])?{pycon}\n)" r"(?P.*?)" r"(?P^(?P=indent)\\end{minted}\s*$)", re.DOTALL | re.MULTILINE, ) PYTHONTEX_LANG = r"(?Ppyblock|pycode|pyconsole|pyverbatim)" PYTHONTEX_RE = re.compile( - rf"(?P^(?P *)\\begin{{{PYTHONTEX_LANG}}}\n)" + rf"(?P^(?P[ \t]*)\\begin{{{PYTHONTEX_LANG}}}\n)" rf"(?P.*?)" rf"(?P^(?P=indent)\\end{{(?P=lang)}}\s*$)", re.DOTALL | re.MULTILINE, diff --git a/tests/test_blacken_docs.py b/tests/test_blacken_docs.py index 9df0838..367d80d 100644 --- a/tests/test_blacken_docs.py +++ b/tests/test_blacken_docs.py @@ -140,6 +140,26 @@ def test_format_src_indented_markdown(): ) +def test_format_src_markdown_indented_tabs(): + before = dedent( + """\ + Example: + \t```python + \tf(1,2,3) + \t``` + """ + ) + after, _ = blacken_docs.format_str(before, BLACK_MODE) + assert after == dedent( + """\ + Example: + \t```python + \tf(1, 2, 3) + \t``` + """ + ) + + def test_format_src_markdown_pycon(): before = ( "hello\n" @@ -426,6 +446,30 @@ def test_format_src_latex_minted_indented(): ) +def test_format_src_latex_minted_indented_tabs(): + before = dedent( + """\ + hello + \t\\begin{minted}{python} + \t if True: + \t f(1,2,3) + \t\\end{minted} + world! + """ + ) + after, _ = blacken_docs.format_str(before, BLACK_MODE) + assert after == dedent( + """\ + hello + \t\\begin{minted}{python} + \t if True: + \t f(1, 2, 3) + \t\\end{minted} + world! + """ + ) + + def test_format_src_latex_minted_pycon(): before = ( "Preceeding text\n" @@ -579,6 +623,28 @@ def test_format_src_rst_literal_blocks_nested(): assert errors == [] +def test_format_src_rst_literal_blocks_indented_tabs(): + before = dedent( + """\ + \thello:: + + \t f(1,2,3) + """, + ) + after, _ = blacken_docs.format_str( + before, + BLACK_MODE, + rst_literal_blocks=True, + ) + assert after == dedent( + """\ + hello:: + + \t f(1, 2, 3) + """, + ) + + def test_format_src_rst_literal_blocks_empty(): before = dedent( """ @@ -688,6 +754,38 @@ def hi(): ) +def test_format_src_rst_indented_tabs(): + before = dedent( + """\ + .. versionadded:: 3.1 + + \thello + + \t.. code-block:: python + + \t\tdef hi(): + \t\tf(1,2,3) + + \tworld + """ + ) + after, _ = blacken_docs.format_str(before, BLACK_MODE) + assert after == dedent( + """\ + .. versionadded:: 3.1 + + \thello + + \t.. code-block:: python + + \t def hi(): + \t f(1, 2, 3) + + \tworld + """ + ) + + def test_format_src_rst_code_block_indent(): before = "\n".join( [