【问题标题】:Customize templates for `sphinx-apidoc`自定义 `sphinx-apidoc` 的模板
【发布时间】:2015-06-05 18:59:44
【问题描述】:

我最近尝试使用来自Sphinxsphinx-apidoc 来帮助从 Python 项目的 API 生成 Sphinx 特定的 reStructuredText。

但是,我得到的结果是:

有人知道我是否可以自定义模板sphinx-api 用于其输出?具体来说,我想:

  • 去掉所有“子模块”、“子包”和“模块内容”标题,并且
  • 将我的__init__.py 文件中的文档字符串的结果直接显示在包下,这样如果我单击包名称,我首先看到的是包文档。目前,该文档位于每个包部分末尾略微奇怪的“模块内容”标题下。

我认为“子模块”和“子包”标题是多余的,因为包/模块的正常标题是“xxx.yyy 包”和“xxx.yyy.zzz 模块”。

上面的小例子我想要的结构是

  • orexplore.components 包
    • orexplore.components.mbg120 模块
  • orexplore.simulators 包
    • orexplore.simulators.test 包
      • orexplore.simulators.test.mbg120 模块
    • orexplore.simulators.mbg120 模块

点击包,我在页面上看到的第一件事就是包文档。

或者甚至只是

  • orexplore.components
    • orexplore.components.mbg120
  • orexplore.simulators
    • 或explore.simulators.test
      • orexplore.simulators.test.mbg120
  • orexplore.simulators.mbg120

如果有某种方法可以在视觉上区分包/模块(颜色?标志?)而不是冗长的“包”和“模块”。

【问题讨论】:

    标签: python python-sphinx


    【解决方案1】:

    sphinx-apidoc 脚本使用apidoc.py 模块。我无法提供详细说明,但为了删除标题或以其他方式自定义输出,您必须编写自己的此模块版本。没有其他“模板”。

    请注意,如果 API 和模块结构稳定,则无需重复运行 sphinx-apidoc。您可以根据自己的喜好对生成的 rst 文件进行后处理一次,然后将它们置于版本控制之下。另见https://stackoverflow.com/a/28481785/407651

    更新

    从 Sphinx 2.2.0 开始,sphinx-apidoc 支持模板。见https://stackoverflow.com/a/57520238/407651

    【讨论】:

    • 谢谢@mzjn。我有点怀疑没有办法自定义它。 sphinx-apidoc 的一个缺点是我认为它没有模板化。你说得对,一旦包结构稳定,我可以安全地编辑生成的.rst。目前它有点不稳定,但我会忍受这种奇怪的表情,直到它稳定下来。在那之后,我或许可以避免将来必须运行 sphinx-apidoc 并手动进行任何更新。
    • 从 Sphinx 2.2 开始,apidoc 脚本现在支持模板
    【解决方案2】:

    我实现了better-apidoc,这是sphinx-apidoc 脚本的补丁版本,增加了对模板的全面支持。

    它添加了一个-t/--template 选项,允许传递一个模板目录 必须包含模板文件package.rstmodule.rst。 看 package.rstmodule.rst 例如。这些渲染到例如 http://qnet.readthedocs.io/en/latest/API/qnet.algebra.operator_algebra.html.

    【讨论】:

    • 你的工具在 sphinx 中非常需要,它非常适合平淡无奇的文档​​,但非常缺乏 api 参考。我想知道是否有可能实现this 之类的结果。 Pyside 使用 sphinx 作为其文档,但如您所见,它已经过大量定制。输出有点类似于 Doxygen:首先是类名,然后是其继承图,然后是简要或完整描述,然后是成员和方法列表,最后是详细部分。更容易阅读
    • 您是否知道better-apidoc 模板根据原始问题将子包和子模块列表合并为一个?
    【解决方案3】:

    FWIW,这是一个完整的脚本,用于在每个“filename.rst”旁边的“filename.rst.new”文件中进行您想要的更改,这也是我想要的更改:

    #!/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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多