簡體   English   中英

如何使用 Python 以編程方式生成 Sphinx 文檔的一部分?

[英]How to use Python to programmatically generate part of Sphinx documentation?

我正在使用Sphinx為我的一個項目生成文檔。

在這個項目中,我在一個yaml文件中描述了一個可用命令列表,一旦加載,就會生成一個{command-name : command-description}形式的字典,例如:

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

我想知道的是,sphinx 中是否有一種方法可以在make html循環期間加載 yaml 文件,以某種reStructuredText格式(例如定義列表)翻譯 python 字典並包含在我的 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 之前。

最后我找到了一種方法來實現我想要的。 這是操作方法:

  1. 創建一個 python 腳本(我們稱之為generate-includes.py ),它將生成reStructuredText並將其保存在myrst.inc文件中。 (在我的示例中,這將是加載和解析 YAML 的腳本,但這無關緊要)。 確保這個文件是可執行的!!!
  2. 在文檔的主 .rst 文檔中使用include指令,在您希望插入動態生成的文檔的位置:

     .. include:: myrst.inc
  3. 修改 sphinx Makefile以便在構建時生成所需的 .inc 文件:

     myrst.inc: ./generate-includes.py html: myrst.inc ...(other stuff here)
  4. 通常使用make html構建您的文檔

基於 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。

我需要同樣的東西,所以我拼湊了一個似乎有效的新指令(我對自定義 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"

Sphinx 沒有內置任何東西來做你喜歡做的事。 您可以創建自定義指令來處理您的文件,也可以在單獨的步驟中生成 reStructuredText 並使用 include 指令包含生成的 reStructuredText 文件。

我知道這個問題很舊,但也許其他人也會發現它很有用。

聽起來您實際上不需要執行任何 python 代碼,但您只需要重新格式化文件的內容。 在這種情況下,您可能想查看 sphinx-jinja ( https://pypi.python.org/pypi/sphinx-jinja )。

您可以在conf.py加載您的 YAML 文件:

jinja_contexts = yaml.load(yourFileHere)

然后您可以使用 jinja 模板來寫出內容並將它們視為 reST 輸入。

Sphinx 確實支持自定義擴展,這可能是執行此操作的最佳方式http://sphinx.pocoo.org/ext/tutorial.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM