Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

:dedent: 0 not respected and :dedent: without argument seems broken #9636

Closed
latosha-maltba opened this issue Sep 15, 2021 · 3 comments
Closed

Comments

@latosha-maltba
Copy link
Contributor

Describe the bug

:dedent: 0 not respected

The .. code-block:: (and probably related directives, too) does not respect the :dedent: 0 option.
Instead of doing nothing, it does the same as :dedent: (without argument).
I believe :dedent: 0 should be a noop to be in line with the expectation of dedenting by 0 characters.

Use case:

First part

.. code-block::

   class PythonClass:

Second part

.. code-block::
   :dedent: 0

       def __init__():
           pass

third part

Without the :dedent: the code block would (by I think the ReST parser, not the renderer) be read with ONE 7 space indent (instead of ONE 3 space indent and a 4 space indent inside the code block). Thus, messing up the code layout. The :dedent: 0 would help in such cases as it indicates ONE 3 space indent for the directive.
As a workaround :class: dummy can also be used, however, this pollutes the class attribute of the node.

Proposed solution:

Instead of if not dedent: use if dedent is None: in sphinx/directives/code.py line 60

:dedent: (without argument)

Also, I noticed that :dedent: (without any argument) seemingly produces garbage, namely it removes all newlines and only the indent of the first line, producing a single long line.

Proposed solution

The reason seems to be that the function dedent_lines() (sphinx/directives/code.py line 59) uses

        return textwrap.dedent(''.join(lines)).splitlines(True)

instead of the line preserving

        return textwrap.dedent('\n'.join(lines)).split('\n')

Closing words

If the above analysis is correct and you agree with the proposed solutions, I'm happy to provide a PR if that reduces the workload for you.

How to Reproduce

MWE is given above in the use case.

Expected behavior

No response

Your project

Sorry that's a private one, the MWE above should do.

Screenshots

No response

OS

Linux

Python version

3.9

Sphinx version

4

Sphinx extensions

No response

Extra tools

No response

Additional context

No response

@tk0miya
Copy link
Member

tk0miya commented Sep 18, 2021

I don't think this is a bug because your goal is not "dedenting" the content by 0. I think you'd like to use the :dedent: 0 option as a workaround to keep indentation, right? To fix this properly, we need to add a new syntax or parsing rules to reStructuredText.

But, at this moment, supporting 0 value is a good workaround for your case. And it is low cost to implement it and it does not harm anybody. So I can agree to add the change as a "secret" feature.

If the above analysis is correct and you agree with the proposed solutions, I'm happy to provide a PR if that reduces the workload for you.

It must be help us. Could you make a PR?

@tk0miya tk0miya added this to the 4.3.0 milestone Sep 18, 2021
@latosha-maltba
Copy link
Contributor Author

I don't think this is a bug because your goal is not "dedenting" the content by 0.

I agree that I use the feature in a hacky way, however, – nitpick – I don't agree that it is not a bug as the implementation does not follow the documentation, which states:

When number given, leading N characters are removed.

and (to me) N = 0 is a perfectly fine number. But lets not talk about distinctions without difference and instead focus on a more important issue:

Could you have a look at the second part of this report: :dedent: without argument. I noticed I did not provide a MWE as it is so obvious:

.. code-block::
   :dedent:

   first line
   second line

The above produces first linesecond line as output (no newline between the lines), which, I guess, is not intended.
As suggested in the initial report: I propose to change line 59 in sphinx/directives/code.py line 59 from

    return textwrap.dedent(''.join(lines)).splitlines(True)

to the newline preserving:

    return textwrap.dedent('\n'.join(lines)).split('\n')

@tk0miya
Copy link
Member

tk0miya commented Sep 20, 2021

Could you have a look at the second part of this report: :dedent: without argument. I noticed I did not provide a MWE as it is so obvious:

Oops... it must be a bug!

latosha-maltba added a commit to latosha-maltba/sphinx that referenced this issue Sep 21, 2021
Due to how Python converts ints to bool the numeric argument ``0`` to
the :dedent: option of the code-block directive was handled like if no
argument was given to :dedent:.

Check properly for None in the options argument processing, so ``0`` is
treated as numeric argument to :dedent:.

Bug: sphinx-doc#9636
@tk0miya tk0miya modified the milestones: 4.3.0, 4.4.0 Nov 9, 2021
@tk0miya tk0miya closed this as completed Jan 15, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants