From 5f11975699ab5bf6a7b179e216016b27e58fc453 Mon Sep 17 00:00:00 2001 From: pdmurray Date: Mon, 6 Jan 2025 12:08:59 -0800 Subject: [PATCH] [BUG] Fix handling of leading whitespaces in code blocks --- nbconvert/filters/highlight.py | 2 +- nbconvert/filters/markdown_mistune.py | 2 +- pyproject.toml | 2 +- tests/exporters/test_html.py | 35 +++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/nbconvert/filters/highlight.py b/nbconvert/filters/highlight.py index d29a4759a..7aface2dd 100644 --- a/nbconvert/filters/highlight.py +++ b/nbconvert/filters/highlight.py @@ -179,7 +179,7 @@ def _pygments_highlight(source, output_formatter, language="ipython", metadata=N if lexer is None: try: - lexer = get_lexer_by_name(language, stripall=True) + lexer = get_lexer_by_name(language, stripall=False) except ClassNotFound: warn("No lexer found for language %r. Treating as plain text." % language, stacklevel=2) from pygments.lexers.special import TextLexer diff --git a/nbconvert/filters/markdown_mistune.py b/nbconvert/filters/markdown_mistune.py index fb8828167..407aa240c 100644 --- a/nbconvert/filters/markdown_mistune.py +++ b/nbconvert/filters/markdown_mistune.py @@ -317,7 +317,7 @@ def block_code(self, code: str, info: Optional[str] = None) -> str: try: if info.strip().split(None, 1): lang = info.strip().split(maxsplit=1)[0] - lexer = get_lexer_by_name(lang, stripall=True) + lexer = get_lexer_by_name(lang, stripall=False) except ClassNotFound: code = f"{lang}\n{code}" lang = None diff --git a/pyproject.toml b/pyproject.toml index 9d8768138..06fd056f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -224,7 +224,6 @@ ignore = [ "T201", # `print` found "RUF012", # Mutable class attributes should be annotated "UP031", # Use format specifiers instead of percent format - ] unfixable = [ "T201", # Don't touch print statements @@ -253,6 +252,7 @@ unfixable = [ "nbconvert/__init__.py" = ["F401", "F403"] # PLR2004 Magic value used in comparison "nbconvert/filters/ansi.py" = ["PLR2004"] +"tests/exporters/test_html.py" = ["RUF001"] [tool.interrogate] ignore-init-module=true diff --git a/tests/exporters/test_html.py b/tests/exporters/test_html.py index 810de47ec..5d1310702 100644 --- a/tests/exporters/test_html.py +++ b/tests/exporters/test_html.py @@ -262,3 +262,38 @@ def test_language_code_error(self): (output, resources) = exporter.from_filename(self._get_notebook()) assert '' in output + + +def test_syntax_highlight_leading_whitespace(): + """Test that syntax highlight doesn't strip leading spaces.""" + nb = v4.reads(r""" +{ + "cells": [ + { + "cell_type": "markdown", + "id": "29da71a9-ae40-4098-8c3b-31a98e79fc12", + "metadata": {}, + "source": [ + "```APL\n", + " 1+2×⍳3\n", + "3 5 7\n", + "```\n", + "\n", + "```\n", + " 1+2×⍳3\n", + "3 5 7\n", + "```" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} + """) + output, _ = HTMLExporter().from_notebook_node(nb) + # Check that the second code block has the leading spaces + assert "
      1+2×⍳3\n3 5 7\n
" in output + + # Check that the APL-formatted code block has the leading spaces + assert ' ' in output