Настроить шаблоны для `sphinx-apidoc`
Недавно я попробовал использовать sphinx-apidoc из Sphinx, чтобы помочь сгенерировать специфический для Sphinx reStructuredText из API проекта Python.
Однако я получаю результат:
![Default look of <code>sphinx-api</code> result]()
Кто-нибудь знает, могу ли я настроить шаблон sphinx-api
для его вывода? В частности, я хотел бы:
- Избавьтесь от всех заголовков "Submodules", "Subpackages" и "Module contents" и
- Получают ли результаты из docstring в моих файлах
__init__.py
непосредственно под пакетами, поэтому, если я нажму имя пакета, первое, что я вижу, это документация пакета. На данный момент эта документация помещается под слегка странным заголовком "Module contents" в самом конце каждого раздела пакета.
Заголовки "Submodules" и "Subpackages" являются избыточными, я думаю, поскольку обычные заголовки для пакетов/модулей "xxx.yyy package" и "xxx.yyy.zzz module".
Структура, которая мне нужна для приведенного выше небольшого примера, -
- orexplore.components package
- orexplore.components.mbg120
- пакет orexplore.simulators
- пакет orexplore.simulators.test
-
Модуль
- orexplore.simulators.test.mbg120
Модуль - orexplore.simulators.mbg120
Если щелкнуть пакеты, первым, что я увижу на странице, будет документация пакета.
Или, может быть, даже просто
- orexplore.components
- orexplore.components.mbg120
- orexplore.simulators
- orexplore.simulators.test
- orexplore.simulators.test.mbg120
- orexplore.simulators.mbg120
если есть какой-то способ визуально различать пакеты/модули (цвет? emblem?) вместо довольно многословного "пакета" и "модуля".
Ответы
Ответ 1
sphinx-apidoc script использует модуль apidoc.py. Я не могу предоставить подробные инструкции, но чтобы удалить заголовки или иным образом настроить выход, вам придется написать собственную версию этого модуля. Нет другого "шаблона".
Обратите внимание, что если структура API и модуля стабильна, нет необходимости повторно запускать sphinx-apidoc. Вы можете постовать обработанные первые файлы по своему вкусу один раз, а затем поместить их под контроль версий. См. Также fooobar.com/questions/544914/....
Ответ 2
Я реализовал better-apidoc, исправленную версию скрипта sphinx-apidoc
, которая добавляет полную поддержку шаблонов.
Он добавляет опцию -t/--template
, позволяющую передать каталог шаблона, который
должен содержать файлы шаблонов package.rst
и module.rst
.
Видеть
package.rst
а также
module.rst
для примера. Это рендеринг, например,
http://qnet.readthedocs.io/en/latest/API/qnet.algebra.operator_algebra.html.
Ответ 3
FWIW, здесь полный взлом script, чтобы внести нужные изменения, которые также были моими желаемыми изменениями, в файле "filename.rst.new" рядом с каждым "filename.rst":
#!/usr/bin/env python
'''
Rearrange content in sphinx-apidoc generated .rst files.
* Move "Module Contents" section to the top.
* Remove headers for "Module Contents", "Submodules" and "Subpackages",
including their underlines and the following blank line.
'''
import argparse
import glob
import os
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def argument_parser():
'''
Define command line arguments.
'''
parser = argparse.ArgumentParser(
description='''
Rearrange content in sphinx-apidoc generated .rst files.
'''
)
parser.add_argument(
'-v', '--verbose',
dest='verbose',
default=False,
action='store_true',
help="""
show more output.
"""
)
parser.add_argument(
'input_file',
metavar="INPUT_FILE",
nargs='+',
help="""
file.
"""
)
return parser
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def main():
'''
Main program entry point.
'''
global args
parser = argument_parser()
args = parser.parse_args()
filenames = [glob.glob(x) for x in args.input_file]
if len(filenames) > 0:
filenames = reduce(lambda x, y: x + y, filenames)
for filename in set(filenames):
# line_num was going to be for some consistency checks, never
# implemented but left in place.
found = {
'Subpackages': {'contents': False, 'line_num': None},
'Submodules': {'contents': False, 'line_num': None},
'Module contents': {'contents': True, 'line_num': None},
}
in_module_contents = False
line_num = 0
reordered = []
module_contents = []
new_filename = '.'.join([filename, 'new'])
with open(filename, 'r') as fptr:
for line in fptr:
line = line.rstrip()
discard = False
line_num += 1
if (
in_module_contents
and len(line) > 0
and line[0] not in ['.', '-', ' ']
): # pylint: disable=bad-continuation
in_module_contents = False
for sought in found:
if line.find(sought) == 0:
found[sought]['line_num'] = line_num
if found[sought]['contents']:
in_module_contents = True
discard = True
# discard the underlines and a blank line too
_ = fptr.next()
_ = fptr.next()
if in_module_contents and not discard:
module_contents.append(line)
elif not discard:
reordered.append(line)
# print '{:<6}|{}'.format(len(line), line)
with open(new_filename, 'w') as fptr:
fptr.write('\n'.join(reordered[:3]))
fptr.write('\n')
if module_contents:
fptr.write('\n'.join(module_contents))
fptr.write('\n')
if len(module_contents[-1]) > 0:
fptr.write('\n')
if reordered[3:]:
fptr.write('\n'.join(reordered[3:]))
fptr.write('\n')
if __name__ == "__main__":
main()