Как заставить пробелы в блоке кода в reStructuredText

во-первых, мы используем некоторые пробелы перед блоком, чтобы сказать, что это блок кода. Поскольку Python также использует пробелы для отступа блока кода, я хотел бы, чтобы мой первый блок кода сохранил эти пробелы, если бы я писал код Python. Как я могу это сделать?

Допустим у нас есть класс:

class Test(object):

и мы хотим написать метод, называемый __init__ это член этого класса. Этот метод принадлежит другому блоку кода, но мы хотим иметь визуальную подсказку, поэтому что читатели знают, что этот второй блок является продолжением предыдущей. На данный момент я использую # чтобы отметить вертикальную направляющую линии блока кода, как это:

    def __init__(self):
        pass
#

без #, def __init__(self) будет напечатан на том же уровне отступа, как class Test(object). Должен быть более элегантный способ.

3 ответов


Ах... Я сталкивался с этим раньше ;). Увы, трюк # - это то, что я обычно использую. Если Вы читаете спецификацию, похоже, что она всегда будет отнимать ведущий отступ. [1]

вы также можете использовать альтернативный синтаксис:

::

>     def foo(x):
>         pass

с ведущим ">", который сохранит ведущее пространство.

[1] : http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#indented-literal-blocks

редактировать

просто прокопал код docutils (это тоже меня очень беспокоит) и может подтвердить, что он всегда будет удалять общий отступ, без вопросов. Было бы легко изменить это поведение, но это сделало бы полученный реструктурированный текст нестандартным.


вы также можете попробовать Линия Блоков которые выглядят так:

|     def foo(x):
|         pass

хотя они не специфичны для примеров кода.


вам нужно определить свою собственную директиву (это правда, что стандарт .. code:: директива проглатывает пробелы, но вы можете сделать свою собственную директиву, которая этого не делает):

import re
from docutils.parsers.rst import directives

INDENTATION_RE = re.compile("^ *")

def measure_indentation(line):
    return INDENTATION_RE.match(line).end()

class MyCodeBlock(directives.body.CodeBlock):
    EXPECTED_INDENTATION = 3

    def run(self):
        block_lines = self.block_text.splitlines()
        block_header_len = self.content_offset - self.lineno + 1
        block_indentation = measure_indentation(self.block_text)
        code_indentation = block_indentation + MyCodeBlock.EXPECTED_INDENTATION
        self.content = [ln[code_indentation:] for ln in block_lines[block_header_len:]]
        return super(MyCodeBlock, self).run()

directives.register_directive("my-code", MyCodeBlock)

вы могли бы, конечно, перезаписать стандарт .. code:: директива с этим тоже.