6

このスケルトンを持つ reStructuredText ドキュメントを考えてみましょう:

Main Title
==========

text text text text text

Subsection
----------

text text text text text

.. my-import-from:: file1
.. my-import-from:: file2

このmy-import-fromディレクティブは、ドキュメント固有の Sphinx 拡張によって提供されます。これは、引数として提供されたファイルを読み取り、それに埋め込まれた reST を解析し、結果を現在の入力ファイルのセクションとして挿入することになっています。(autodoc に似ていますが、ファイル形式が異なります。) 現在、私が持っているコードは次のようになります。

class MyImportFromDirective(Directive):
    required_arguments = 1
    def run(self):
        src, srcline = self.state_machine.get_source_and_line()
        doc_file = os.path.normpath(os.path.join(os.path.dirname(src),
                                                 self.arguments[0]))
        self.state.document.settings.record_dependencies.add(doc_file)
        doc_text  = ViewList()

        try:
            doc_text = extract_doc_from_file(doc_file)
        except EnvironmentError as e:
            raise self.error(e.filename + ": " + e.strerror) from e

        doc_section = nodes.section()
        doc_section.document = self.state.document

        # report line numbers within the nested parse correctly
        old_reporter = self.state.memo.reporter
        self.state.memo.reporter = AutodocReporter(doc_text,
                                                   self.state.memo.reporter)
        nested_parse_with_titles(self.state, doc_text, doc_section)
        self.state.memo.reporter = old_reporter

        if len(doc_section) == 1 and isinstance(doc_section[0], nodes.section):
            doc_section = doc_section[0]

        # If there was no title, synthesize one from the name of the file.
        if len(doc_section) == 0 or not isinstance(doc_section[0], nodes.title):
            doc_title = nodes.title()
            doc_title.append(make_title_text(doc_file))
            doc_section.insert(0, doc_title)

        return [doc_section]

これは機能しますが、新しいセクションが兄弟ではなく、現在のセクションのとして挿入されることを除きます。つまり、上記のサンプル ドキュメントは、次のような TOC ツリーを生成します。

  • メインタイトル
    • サブセクション
      • ファイル1
      • ファイル2

希望の代わりに

  • メインタイトル
    • サブセクション
    • ファイル1
    • ファイル2

これを修正するにはどうすればよいですか? Docutils のドキュメントは ... 特にセクションの深さの制御に関して不十分です。私が試した明らかなことの1つは、doc_section.childrenの代わりに戻ることです[doc_section]。TOC ツリーから完全に削除File1File2れます (ただし、ドキュメントの本文のセクション ヘッダーが適切なネスト レベルにあるように見えます)。

4

2 に答える 2

4

「現在の」セクションに追加されるため、ディレクティブからセクションを返すことによってこれを行うことはできないと思います(フロリアンが提案したことに沿って何かをすることなく)。ただし、次のようにセクションを追加できself.state.sectionます(簡潔にするために削除されたオプションの処理)

class FauxHeading(object):
    """
    A heading level that is not defined by a string. We need this to work with
    the mechanics of
    :py:meth:`docutils.parsers.rst.states.RSTState.check_subsection`.

    The important thing is that the length can vary, but it must be equal to
    any other instance of FauxHeading.
    """

    def __init__(self, length):
        self.length = length

    def __len__(self):
        return self.length

    def __eq__(self, other):
        return isinstance(other, FauxHeading)


class ParmDirective(Directive):

    required_arguments = 1
    optional_arguments = 0
    has_content = True
    option_spec = {
        'type':          directives.unchanged,
        'precision':     directives.nonnegative_int,
        'scale':         directives.nonnegative_int,
        'length':        directives.nonnegative_int}

    def run(self):
        variableName = self.arguments[0]
        lineno = self.state_machine.abs_line_number()
        secBody = None
        block_length = 0

        # added for some space
        lineBlock = nodes.line('', '', nodes.line_block())

        # parse the body of the directive
        if self.has_content and len(self.content):
            secBody = nodes.container()
            block_length += nested_parse_with_titles(
                self.state, self.content, secBody)

        # keeping track of the level seems to be required if we want to allow
        # nested content. Not sure why, but fits with the pattern in
        # :py:meth:`docutils.parsers.rst.states.RSTState.new_subsection`
        myLevel = self.state.memo.section_level
        self.state.section(
            variableName,
            '',
            FauxHeading(2 + len(self.options) + block_length),
            lineno,
            [lineBlock] if secBody is None else [lineBlock, secBody])
        self.state.memo.section_level = myLevel

        return []
于 2015-04-22T10:39:13.163 に答える
1

カスタム ディレクティブ内で直接行う方法がわかりません。ただし、カスタム変換を使用して、解析後にツリー内のノードFile1とノードを上げることができます。File2たとえば、docutils.transforms.frontmatterモジュール内の変換を参照してください。

Sphinx 拡張機能で、Sphinx.add_transformメソッドを使用してカスタム変換を登録します。

更新:docutils.nodes.pendingノード リストでクラスの 1 つ以上のインスタンスを返すことにより、ディレクティブに変換を直接登録することもできます。その場合は、必ずドキュメントのメソッドを呼び出してnote_pendingください (ディレクティブでは、 を介してドキュメントを取得できますself.state_machine.document)。

于 2014-04-10T11:49:04.237 に答える