diff options
author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2022-01-16 02:00:40 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-16 02:00:40 +0900 |
commit | a55a765e797197cfdf8a3e5033efe8ed72191a62 (patch) | |
tree | 2b6317ca8377ffbdce0eeb7745c82a3a3fd2fd26 | |
parent | 0938c193ea6f56dbb930bfb323602bc4e2b7b9c6 (diff) | |
parent | ff54f97aba881f31359d983d1e82c63199886768 (diff) | |
download | sphinx-git-a55a765e797197cfdf8a3e5033efe8ed72191a62.tar.gz |
Merge pull request #9661 from latosha-maltba/dedent
code-block: Fix handling of :dedent: and add unit tests
-rw-r--r-- | CHANGES | 2 | ||||
-rw-r--r-- | doc/usage/restructuredtext/directives.rst | 1 | ||||
-rw-r--r-- | sphinx/directives/code.py | 6 | ||||
-rw-r--r-- | tests/roots/test-directive-code/dedent.rst | 64 | ||||
-rw-r--r-- | tests/test_directive_code.py | 27 |
5 files changed, 96 insertions, 4 deletions
@@ -78,7 +78,7 @@ Bugs fixed * #9979: Error level messages were displayed as warning messages * #10057: Failed to scan documents if the project is placed onto the root directory - +* #9636: code-block: ``:dedent:`` without argument did strip newlines Testing -------- diff --git a/doc/usage/restructuredtext/directives.rst b/doc/usage/restructuredtext/directives.rst index bd1b1a3c6..d1877bca0 100644 --- a/doc/usage/restructuredtext/directives.rst +++ b/doc/usage/restructuredtext/directives.rst @@ -598,6 +598,7 @@ __ https://pygments.org/docs/lexers are removed via :func:`textwrap.dedent()`. For example:: .. code-block:: ruby + :linenos: :dedent: 4 some ruby code diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index 8bead7163..ddd47e1f8 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -57,7 +57,7 @@ class Highlight(SphinxDirective): def dedent_lines(lines: List[str], dedent: int, location: Tuple[str, int] = None) -> List[str]: - if not dedent: + if dedent is None: return textwrap.dedent(''.join(lines)).splitlines(True) if any(s[:dedent].strip() for s in lines): @@ -138,9 +138,9 @@ class CodeBlock(SphinxDirective): if 'dedent' in self.options: location = self.state_machine.get_source_and_line(self.lineno) - lines = code.split('\n') + lines = code.splitlines(True) lines = dedent_lines(lines, self.options['dedent'], location=location) - code = '\n'.join(lines) + code = ''.join(lines) literal: Element = nodes.literal_block(code, code) if 'linenos' in self.options or 'lineno-start' in self.options: diff --git a/tests/roots/test-directive-code/dedent.rst b/tests/roots/test-directive-code/dedent.rst new file mode 100644 index 000000000..f36e3e3ba --- /dev/null +++ b/tests/roots/test-directive-code/dedent.rst @@ -0,0 +1,64 @@ +dedent option +------------- + +.. code-block:: + + First line + Second line + Third line + Fourth line + +ReST has no fixed indent and only a change in indention is significant not the amount [1]_. +Thus, the following code inside the code block is not indent even it looks so with respect to the previous block. + +.. code-block:: + + First line + Second line + Third line + Fourth line + +Having an option "fixates" the indent to be 3 spaces, thus the code inside the code block is indented by 4 spaces. + +.. code-block:: + :class: dummy + + First line + Second line + Third line + Fourth line + +The code has 6 spaces indent, minus 4 spaces dedent should yield a 2 space indented code in the output. + +.. code-block:: + :dedent: 4 + + First line + Second line + Third line + Fourth line + +Dedenting by zero, should not strip any spaces and be a no-op. + +.. note:: + This can be used as an alternative to ``:class: dummy`` above, to fixate the ReST indention of the block. + +.. code-block:: + :dedent: 0 + + First line + Second line + Third line + Fourth line + +Dedent without argument should autostrip common whitespace at the beginning. + +.. code-block:: + :dedent: + + First line + Second line + Third line + Fourth line + +.. [1] https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#indentation diff --git a/tests/test_directive_code.py b/tests/test_directive_code.py index d8244db6a..5f519d3b9 100644 --- a/tests/test_directive_code.py +++ b/tests/test_directive_code.py @@ -580,3 +580,30 @@ def test_linenothreshold(app, status, warning): # literal include not using linenothreshold (no line numbers) assert ('<span></span><span class="c1"># Very small literal include ' '(linenothreshold check)</span>' in html) + + +@pytest.mark.sphinx('dummy', testroot='directive-code') +def test_code_block_dedent(app, status, warning): + app.builder.build(['dedent']) + doctree = app.env.get_doctree('dedent') + codeblocks = list(doctree.traverse(nodes.literal_block)) + # Note: comparison string should not have newlines at the beginning or end + text_0_indent = '''First line +Second line + Third line +Fourth line''' + text_2_indent = ''' First line + Second line + Third line + Fourth line''' + text_4_indent = ''' First line + Second line + Third line + Fourth line''' + + assert codeblocks[0].astext() == text_0_indent + assert codeblocks[1].astext() == text_0_indent + assert codeblocks[2].astext() == text_4_indent + assert codeblocks[3].astext() == text_2_indent + assert codeblocks[4].astext() == text_4_indent + assert codeblocks[5].astext() == text_0_indent |