28

私は自分のプロジェクトのドキュメントを生成するためにSphinxを使用しています。

このプロジェクトでは、使用可能なコマンドのリストをyamlファイルに記述します。このファイルが読み込まれると、次のような形式の辞書が作成さ{command-name : command-description}れます。

commands = {"copy"  : "Copy the highlighted text in the clipboard",
            "paste" : "Paste the clipboard text to cursor location",
            ...}

私が知りたいのは、サイクル中にyamlファイルをロードし、python辞書をreStructuredText形式(定義リストなど)に変換し、html出力に含める方法がsphinxにある場合です。make html

私の.rstファイルは次のようになると思います:

Available commands
==================
The commands available in bla-bla-bla...

.. magic-directive-that-execute-python-code::
   :maybe python code or name of python file here:

内部で次のように変換されます。

Available commands
==================
The commands available in bla-bla-bla...

copy
  Copy the highlighted text in the clipboard

paste
  Paste the clipboard text to cursor location

HTMLに変換される前。

4

6 に答える 6

26

最後に、私は自分が望んでいたことを達成する方法を見つけます。方法は次のとおりです。

  1. reStructuredTextgenerate-includes.pyを生成し、ファイルに保存する Python スクリプト( と呼びましょう) を作成します。(私の例では、これは YAML を読み込んで解析するスクリプトになりますが、これは無関係です)。このファイルが実行可能であることを確認してください!!!myrst.inc
  2. include動的に生成されたドキュメントを挿入するポイントで、ドキュメントのメイン .rst ドキュメントでディレクティブを使用します。

    .. include:: myrst.inc
    
  3. ビルド時に必要な .inc ファイルを生成するために、sphinx Makefileを変更します。

    myrst.inc:
        ./generate-includes.py
    
    html: myrst.inc
        ...(other stuff here)
    
  4. を使用して、通常どおりドキュメントを作成make htmlます。

于 2011-08-31T15:17:44.243 に答える
18

Michael のコードと組み込みの include ディレクティブに基づく改善:

import sys
from os.path import basename

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

from docutils.parsers.rst import Directive    
from docutils import nodes, statemachine

class ExecDirective(Directive):
    """Execute the specified python code and insert the output into the document"""
    has_content = True

    def run(self):
        oldStdout, sys.stdout = sys.stdout, StringIO()

        tab_width = self.options.get('tab-width', self.state.document.settings.tab_width)
        source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1)

        try:
            exec('\n'.join(self.content))
            text = sys.stdout.getvalue()
            lines = statemachine.string2lines(text, tab_width, convert_whitespace=True)
            self.state_machine.insert_input(lines, source)
            return []
        except Exception:
            return [nodes.error(None, nodes.paragraph(text = "Unable to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text = str(sys.exc_info()[1])))]
        finally:
            sys.stdout = oldStdout

def setup(app):
    app.add_directive('exec', ExecDirective)

これは出力を先にインポートして、パーサーを直接通過するようにします。Python 3 でも動作します。

于 2013-08-09T09:14:48.847 に答える
9

同じものが必要だったので、機能しているように見える新しいディレクティブをまとめました(カスタムのSphinxディレクティブについては何も知りませんが、これまでのところ機能しています)。

import sys
from os.path import basename
from StringIO import StringIO

from sphinx.util.compat import Directive
from docutils import nodes

class ExecDirective(Directive):
    """Execute the specified python code and insert the output into the document"""
    has_content = True

    def run(self):
        oldStdout, sys.stdout = sys.stdout, StringIO()
        try:
            exec '\n'.join(self.content)
            return [nodes.paragraph(text = sys.stdout.getvalue())]
        except Exception, e:
            return [nodes.error(None, nodes.paragraph(text = "Unable to execute python code at %s:%d:" % (basename(self.src), self.srcline)), nodes.paragraph(text = str(e)))]
        finally:
            sys.stdout = oldStdout

def setup(app):
    app.add_directive('exec', ExecDirective)

次のように使用されます。

.. exec::
   print "Python code!"
   print "This text will show up in the document"
于 2012-04-13T18:34:19.283 に答える
4

Sphinxには、好きなことをするための機能が組み込まれていません。ファイルを処理するカスタムディレクティブを作成するか、別のステップでreStructuredTextを生成し、includeディレクティブを使用して結果のreStructuredTextファイルをインクルードすることができます。

于 2011-08-31T00:08:58.983 に答える
3

この質問が古いことは知っていますが、他の誰かも役に立つと思うかもしれません。

実際に Python コードを実行する必要はないように思えますが、ファイルの内容を再フォーマットするだけで済みます。その場合は、sphinx-jinja ( https://pypi.python.org/pypi/sphinx-jinja ) を参照してください。

YAML ファイルは次の場所にロードできますconf.py

jinja_contexts = yaml.load(yourFileHere)

次に、jinja テンプレートを使用してコンテンツを書き出し、reST 入力として扱うことができます。

于 2016-05-17T13:57:26.480 に答える
0

Sphinx は、おそらくこれを行うための最良の方法であるカスタム拡張機能をサポートしていますhttp://sphinx.pocoo.org/ext/tutorial.html

于 2011-10-08T06:17:22.873 に答える