[英]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 之前。
最后我找到了一種方法來實現我想要的。 這是操作方法:
generate-includes.py
),它將生成reStructuredText並將其保存在myrst.inc
文件中。 (在我的示例中,這將是加載和解析 YAML 的腳本,但這無關緊要)。 確保這個文件是可執行的!!! 在文檔的主 .rst 文檔中使用include
指令,在您希望插入動態生成的文檔的位置:
.. include:: myrst.inc
修改 sphinx Makefile以便在構建時生成所需的 .inc 文件:
myrst.inc: ./generate-includes.py html: myrst.inc ...(other stuff here)
通常使用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.