Как использовать Python для программной генерации части документации Sphinx
Я использую Sphinx для создания документации для моего проекта.
В этом проекте я описываю список доступных команд в файле yaml, который после загрузки приводит к появлению словаря в форма {command-name : command-description}
, например:
commands = {"copy" : "Copy the highlighted text in the clipboard",
"paste" : "Paste the clipboard text to cursor location",
...}
То, что я хотел бы знать, , если в sphinx есть метод для загрузки файла yaml во время цикла make html
, переведите словарь python в некоторый формат reStructuredText (например, список определения) и включить в мой вывод 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 script (позвоните ему
generate-includes.py
), который сгенерирует reStructuredText и сохранит его в файле myrst.inc
. (В моем примере это будет script загрузка и анализ YAML, но это не имеет значения). Убедитесь, что этот файл является исполняемым.
-
Используйте директиву include
в основном документе .rst вашей документации в том месте, где вы хотите вставить вашу динамически создаваемую документацию:
.. include:: myrst.inc
-
Измените файл makefile sphinx, чтобы сгенерировать требуемые файлы .inc во время сборки:
myrst.inc:
./generate-includes.py
html: myrst.inc
...(other stuff here)
-
Создайте свою документацию обычно с помощью make html
.
Ответ 2
Улучшение, основанное на коде Михаэля и встроенной директиве include:
import sys
from os.path import basename
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
from sphinx.util.compat 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.
Ответ 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"
Ответ 4
Sphinx не имеет ничего встроенного, чтобы делать то, что вам нравится. Вы можете создать пользовательскую директиву для обработки ваших файлов или сгенерировать reStructuredText на отдельном шаге и включить результирующий файл reStructuredText с помощью директивы include.
Ответ 5
Я знаю, что этот вопрос старый, но, возможно, кто-то еще найдет его полезным.
Похоже, вам действительно не нужно выполнять какой-либо код на Python, но вам просто нужно переформатировать содержимое вашего файла. В этом случае вы можете посмотреть на sphinx-jinja (https://pypi.python.org/pypi/sphinx-jinja).
Вы можете загрузить свой файл YAML в conf.py
:
jinja_contexts = yaml.load(yourFileHere)
Затем вы можете использовать jinja templating для записи содержимого и обработать их как вкладку reST.
Ответ 6
Sphinx поддерживает пользовательские расширения, которые, вероятно, будут лучшим способом сделать это http://sphinx.pocoo.org/ext/tutorial.html.