Merge pull request #6492 from tk0miya/5602_apidoc_templating

Close #5602: apidoc: Add ``--templatedir`` option
This commit is contained in:
Takeshi KOMIYA 2019-06-18 22:01:59 +09:00 committed by GitHub
commit c78018cda7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 61 additions and 20 deletions

View File

@ -7,6 +7,8 @@ Dependencies
Incompatible changes
--------------------
* apidoc: template files are renamed to ``.rst_t``
Deprecated
----------
@ -27,6 +29,7 @@ Features added
* #5124: graphviz: ``:graphviz_dot:`` option is renamed to ``:layout:``
* #1464: html: emit a warning if :confval:`html_static_path` and
:confval:`html_extra_path` directories are inside output directory
* #5602: apidoc: Add ``--templatedir`` option
Bugs fixed
----------

View File

@ -126,6 +126,30 @@ These options are used when :option:`--full` is specified:
Sets the project release to put in generated files (see :confval:`release`).
.. rubric:: Project templating
.. versionadded:: 2.2
Project templating options for sphinx-apidoc
.. option:: -t, --templatedir=TEMPLATEDIR
Template directory for template files. You can modify the templates of
sphinx project files generated by apidoc. Following Jinja2 template
files are allowed:
* ``module.rst_t``
* ``package.rst_t``
* ``toc.rst_t``
* ``master_doc.rst_t``
* ``conf.py_t``
* ``Makefile_t``
* ``Makefile.new_t``
* ``make.bat_t``
* ``make.bat.new_t``
In detail, please refer the system template files Sphinx provides.
(``sphinx/templates/apidoc`` and ``sphinx/templates/quickstart``)
Environment
-----------

View File

@ -111,8 +111,8 @@ def format_directive(module, package=None):
return directive
def create_module_file(package, basename, opts):
# type: (str, str, Any) -> None
def create_module_file(package, basename, opts, user_template_dir=None):
# type: (str, str, Any, str) -> None
"""Build the text of the file and write the file."""
qualname = module_join(package, basename)
context = {
@ -121,12 +121,13 @@ def create_module_file(package, basename, opts):
'qualname': qualname,
'automodule_options': OPTIONS,
}
text = ReSTRenderer(template_dir).render('module.rst', context)
text = ReSTRenderer([user_template_dir, template_dir]).render('module.rst_t', context)
write_file(qualname, text, opts)
def create_package_file(root, master_package, subroot, py_files, opts, subs, is_namespace, excludes=[]): # NOQA
# type: (str, str, str, List[str], Any, List[str], bool, List[str]) -> None
def create_package_file(root, master_package, subroot, py_files, opts, subs,
is_namespace, excludes=[], user_template_dir=None):
# type: (str, str, str, List[str], Any, List[str], bool, List[str], str) -> None
"""Build the text of the file and write the file."""
# build a list of sub packages (directories containing an INITPY file)
subpackages = [sub for sub in subs if not
@ -151,7 +152,7 @@ def create_package_file(root, master_package, subroot, py_files, opts, subs, is_
'automodule_options': OPTIONS,
'show_headings': not opts.noheadings,
}
text = ReSTRenderer(template_dir).render('package.rst', context)
text = ReSTRenderer([user_template_dir, template_dir]).render('package.rst_t', context)
write_file(pkgname, text, opts)
if submodules and opts.separatemodules:
@ -159,8 +160,8 @@ def create_package_file(root, master_package, subroot, py_files, opts, subs, is_
create_module_file(None, submodule, opts)
def create_modules_toc_file(modules, opts, name='modules'):
# type: (List[str], Any, str) -> None
def create_modules_toc_file(modules, opts, name='modules', user_template_dir=None):
# type: (List[str], Any, str, str) -> None
"""Create the module's index."""
modules.sort()
prev_module = ''
@ -176,7 +177,7 @@ def create_modules_toc_file(modules, opts, name='modules'):
'maxdepth': opts.maxdepth,
'docnames': modules,
}
text = ReSTRenderer(template_dir).render('toc.rst', context)
text = ReSTRenderer([user_template_dir, template_dir]).render('toc.rst_t', context)
write_file(name, text, opts)
@ -220,8 +221,8 @@ def is_skipped_module(filename, opts, excludes):
return False
def recurse_tree(rootpath, excludes, opts):
# type: (str, List[str], Any) -> List[str]
def recurse_tree(rootpath, excludes, opts, user_template_dir=None):
# type: (str, List[str], Any, str) -> List[str]
"""
Look for every file in the directory tree and create the corresponding
ReST files.
@ -271,7 +272,8 @@ def recurse_tree(rootpath, excludes, opts):
# a namespace and there is something there to document
if not is_namespace or len(py_files) > 0:
create_package_file(root, root_package, subpackage,
py_files, opts, subs, is_namespace, excludes)
py_files, opts, subs, is_namespace, excludes,
user_template_dir)
toplevels.append(module_join(root_package, subpackage))
else:
# if we are at the root level, we don't require it to be a package
@ -279,7 +281,7 @@ def recurse_tree(rootpath, excludes, opts):
for py_file in py_files:
if not is_skipped_module(path.join(rootpath, py_file), opts, excludes):
module = path.splitext(py_file)[0]
create_module_file(root_package, module, opts)
create_module_file(root_package, module, opts, user_template_dir)
toplevels.append(module)
return toplevels
@ -386,6 +388,11 @@ Note: By default this script will not overwrite already created files."""))
const='sphinx.ext.%s' % ext, dest='extensions',
help=__('enable %s extension') % ext)
group = parser.add_argument_group(__('Project templating'))
group.add_argument('-t', '--templatedir', metavar='TEMPLATEDIR',
dest='templatedir',
help=__('template directory for template files'))
return parser
@ -412,7 +419,7 @@ def main(argv=sys.argv[1:]):
if not args.dryrun:
ensuredir(args.destdir)
excludes = [path.abspath(exclude) for exclude in args.exclude_pattern]
modules = recurse_tree(rootpath, excludes, args)
modules = recurse_tree(rootpath, excludes, args, args.templatedir)
if args.full:
from sphinx.cmd import quickstart as qs
@ -455,9 +462,10 @@ def main(argv=sys.argv[1:]):
d['extensions'].extend(ext.split(','))
if not args.dryrun:
qs.generate(d, silent=True, overwrite=args.force)
qs.generate(d, silent=True, overwrite=args.force,
templatedir=args.templatedir)
elif args.tocfile:
create_modules_toc_file(modules, args, args.tocfile)
create_modules_toc_file(modules, args, args.tocfile, args.templatedir)
return 0

View File

@ -9,7 +9,7 @@
"""
import os
from typing import Dict
from typing import Dict, List, Union
from jinja2.loaders import BaseLoader
from jinja2.sandbox import SandboxedEnvironment
@ -34,7 +34,13 @@ class BaseRenderer:
class FileRenderer(BaseRenderer):
def __init__(self, search_path: str) -> None:
def __init__(self, search_path: Union[str, List[str]]) -> None:
if isinstance(search_path, str):
search_path = [search_path]
else:
# filter "None" paths
search_path = list(filter(None, search_path))
loader = SphinxFileSystemLoader(search_path)
super().__init__(loader)
@ -46,7 +52,7 @@ class FileRenderer(BaseRenderer):
class SphinxRenderer(FileRenderer):
def __init__(self, template_path: str = None) -> None:
def __init__(self, template_path: Union[str, List[str]] = None) -> None:
if template_path is None:
template_path = os.path.join(package_dir, 'templates')
super().__init__(template_path)
@ -76,7 +82,7 @@ class LaTeXRenderer(SphinxRenderer):
class ReSTRenderer(SphinxRenderer):
def __init__(self, template_path: str = None, language: str = None) -> None:
def __init__(self, template_path: Union[str, List[str]] = None, language: str = None) -> None: # NOQA
super().__init__(template_path)
# add language to environment