Как использовать Python для программного генерирования части документации Sphinx - PullRequest
23 голосов
/ 31 августа 2011

Я использую 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.

Ответы [ 6 ]

21 голосов
/ 31 августа 2011

В конце я нахожу способ достичь того, чего я хотел.Вот инструкции:

  1. Создайте скрипт Python (назовем его generate-includes.py), который сгенерирует reStructuredText и сохранит его в myrst.inc файл.(В моем примере это будет сценарий загрузки и анализа YAML, но это не имеет значения). Убедитесь, что этот файл исполняемый !!!
  2. Используйте директиву include в своем основном .rst документе вашей документации, в точке, гдеВы хотите, чтобы ваша динамически сгенерированная документация была вставлена:

    .. include:: myrst.inc
    
  3. Измените Makefile sphinx , чтобы генерировать необходимые файлы .inc во время сборки:

    myrst.inc:
        ./generate-includes.py
    
    html: myrst.inc
        ...(other stuff here)
    
  4. Создайте свою документацию нормально с make html.

14 голосов
/ 09 августа 2013

Улучшение на основе кода Майкла и встроенной директивы 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.

8 голосов
/ 13 апреля 2012

Мне нужно было то же самое, поэтому я собрал новую директиву, которая, кажется, работает (я ничего не знаю о пользовательских директивах 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 голосов
/ 31 августа 2011

Сфинкс не имеет ничего встроенного, чтобы делать то, что вам нравится.Вы можете создать пользовательскую директиву для обработки ваших файлов или сгенерировать reStructuredText на отдельном шаге и включить полученный файл reStructuredText с помощью директивы include.

2 голосов
/ 17 мая 2016

Я знаю, что этот вопрос старый, но, возможно, кто-то найдет его полезным.

Звучит так, будто вам не нужно выполнять какой-либо код на Python, но вам просто нужно переформатировать содержимоевашего файла.В этом случае вы можете захотеть взглянуть на sphinx-jinja (https://pypi.python.org/pypi/sphinx-jinja).

. Вы можете загрузить свой YAML-файл в conf.py:

jinja_contexts = yaml.load(yourFileHere)

. Затем вы можете использовать jinja-шаблонызапишите содержимое и сделайте так, чтобы они обрабатывались как вводные данные.

0 голосов
/ 08 октября 2011

Sphinx поддерживает пользовательские расширения, которые, вероятно, будут лучшим способом сделать это http://sphinx.pocoo.org/ext/tutorial.html.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...