pdoc.render
1from __future__ import annotations 2 3import os 4import types 5import warnings 6from pathlib import Path 7from typing import cast 8from typing import Mapping 9 10import jinja2 11from jinja2 import Environment 12from jinja2 import FileSystemLoader 13 14import pdoc.doc 15import pdoc.docstrings 16from pdoc.render_helpers import DefaultMacroExtension 17from pdoc.render_helpers import defuse_unsafe_reprs 18from pdoc.render_helpers import edit_url 19from pdoc.render_helpers import format_signature 20from pdoc.render_helpers import highlight 21from pdoc.render_helpers import link 22from pdoc.render_helpers import linkify 23from pdoc.render_helpers import minify_css 24from pdoc.render_helpers import root_module_name 25from pdoc.render_helpers import to_html 26from pdoc.render_helpers import to_markdown_with_context 27from pdoc.search import make_index 28from pdoc.search import precompile_index 29 30try: 31 from typing import Literal 32except ImportError: # pragma: no cover 33 # Python < 3.8 - we cannot use pdoc._compat because ruff does not like it. 34 class Literal: # type: ignore 35 pass 36 37 38def configure( 39 *, 40 docformat: Literal[ 41 "markdown", "google", "numpy", "restructuredtext" 42 ] = "restructuredtext", 43 edit_url_map: Mapping[str, str] | None = None, 44 favicon: str | None = None, 45 footer_text: str = "", 46 logo: str | None = None, 47 logo_link: str | None = None, 48 math: bool = False, 49 search: bool = True, 50 show_source: bool = True, 51 template_directory: Path | None = None, 52): 53 """ 54 Configure the rendering output. 55 56 - `docformat` is the docstring flavor in use. 57 pdoc prefers plain Markdown (the default), but also supports other formats. 58 - `edit_url_map` is a mapping from module names to URL prefixes. For example, 59 60 ```json 61 {"pdoc": "https://github.com/mitmproxy/pdoc/blob/main/pdoc/"} 62 ``` 63 64 renders the "Edit on GitHub" button on this page. The URL prefix can be modified to pin a particular version. 65 - `favicon` is an optional path/URL for a favicon image 66 - `footer_text` is additional text that should appear in the navigation footer. 67 - `logo` is an optional URL to the project's logo image 68 - `logo_link` is an optional URL the logo should point to 69 - `math` enables math rendering by including MathJax into the rendered documentation. 70 - `search` controls whether search functionality is enabled and a search index is built. 71 - `show_source` controls whether a "View Source" button should be included in the output. 72 - `template_directory` can be used to set an additional (preferred) directory 73 for templates. You can find an example in the main documentation of `pdoc` 74 or in `examples/custom-template`. 75 """ 76 searchpath = _default_searchpath 77 if template_directory: 78 searchpath = [template_directory] + searchpath 79 env.loader = FileSystemLoader(searchpath) 80 81 env.globals["edit_url_map"] = edit_url_map or {} 82 env.globals["docformat"] = docformat 83 env.globals["math"] = math 84 env.globals["show_source"] = show_source 85 env.globals["favicon"] = favicon 86 env.globals["logo"] = logo 87 env.globals["logo_link"] = logo_link 88 env.globals["footer_text"] = footer_text 89 env.globals["search"] = search 90 91 92@defuse_unsafe_reprs() 93def html_module( 94 module: pdoc.doc.Module, 95 all_modules: Mapping[str, pdoc.doc.Module], 96 mtime: str | None = None, 97) -> str: 98 """ 99 Renders the documentation for a `pdoc.doc.Module`. 100 101 - `all_modules` contains all modules that are rendered in this invocation. 102 This is used to determine which identifiers should be linked and which should not. 103 - If `mtime` is given, include additional JavaScript on the page for live-reloading. 104 This is only passed by `pdoc.web`. 105 """ 106 return env.get_template("module.html.jinja2").render( 107 module=module, 108 all_modules=all_modules, 109 root_module_name=root_module_name(all_modules), 110 edit_url=edit_url( 111 module.modulename, 112 module.is_package, 113 cast(Mapping[str, str], env.globals["edit_url_map"]), 114 ), 115 mtime=mtime, 116 ) 117 118 119@defuse_unsafe_reprs() 120def html_index(all_modules: Mapping[str, pdoc.doc.Module]) -> str: 121 """Renders the module index.""" 122 return env.get_template("index.html.jinja2").render( 123 all_modules=all_modules, 124 root_module_name=root_module_name(all_modules), 125 ) 126 127 128@defuse_unsafe_reprs() 129def html_error(error: str, details: str = "") -> str: 130 """Renders an error message.""" 131 return env.get_template("error.html.jinja2").render( 132 error=error, 133 details=details, 134 ) 135 136 137@defuse_unsafe_reprs() 138def search_index(all_modules: Mapping[str, pdoc.doc.Module]) -> str: 139 """Renders the Elasticlunr.js search index.""" 140 if not env.globals["search"]: 141 return "" 142 # This is a rather terrible hack to determine if a given object is public and should be included in the index. 143 module_template: jinja2.Template = env.get_template("module.html.jinja2") 144 ctx: jinja2.runtime.Context = module_template.new_context( 145 {"module": pdoc.doc.Module(types.ModuleType("")), "all_modules": all_modules} 146 ) 147 for _ in module_template.root_render_func(ctx): # type: ignore 148 pass 149 150 def is_public(x: pdoc.doc.Doc) -> bool: 151 return bool(ctx["is_public"](x).strip()) 152 153 index = make_index( 154 all_modules, 155 is_public, 156 cast(str, env.globals["docformat"]), 157 ) 158 159 compile_js = Path(env.get_template("build-search-index.js").filename) # type: ignore 160 return env.get_template("search.js.jinja2").render( 161 search_index=precompile_index(index, compile_js) 162 ) 163 164 165@defuse_unsafe_reprs() 166def repr_module(module: pdoc.doc.Module) -> str: 167 """Renders `repr(pdoc.doc.Module)`, primarily used for tests and debugging.""" 168 return repr(module) 169 170 171_default_searchpath = [ 172 Path(os.environ.get("XDG_CONFIG_HOME", "~/.config")).expanduser() / "pdoc", 173 Path(__file__).parent / "templates", 174 Path(__file__).parent / "templates" / "default", 175 Path(__file__).parent / "templates" / "deprecated", 176] 177 178env = Environment( 179 loader=FileSystemLoader(_default_searchpath), 180 extensions=[DefaultMacroExtension], 181 autoescape=True, 182 trim_blocks=True, 183 lstrip_blocks=True, 184) 185""" 186The Jinja2 environment used to render all templates. 187You can modify this object to add custom filters and globals. 188""" 189env.filters["to_markdown"] = to_markdown_with_context 190env.filters["to_html"] = to_html 191env.filters["highlight"] = highlight 192env.filters["format_signature"] = format_signature 193env.filters["linkify"] = linkify 194env.filters["link"] = link 195env.filters["minify_css"] = minify_css 196env.globals["__version__"] = pdoc.__version__ 197env.globals["env"] = os.environ 198env.globals["warn"] = warnings.warn 199configure() # add default globals
def
configure( *, docformat: Literal['markdown', 'google', 'numpy', 'restructuredtext'] = 'restructuredtext', edit_url_map: Optional[Mapping[str, str]] = None, favicon: str | None = None, footer_text: str = '', logo: str | None = None, logo_link: str | None = None, math: bool = False, search: bool = True, show_source: bool = True, template_directory: pathlib.Path | None = None):
39def configure( 40 *, 41 docformat: Literal[ 42 "markdown", "google", "numpy", "restructuredtext" 43 ] = "restructuredtext", 44 edit_url_map: Mapping[str, str] | None = None, 45 favicon: str | None = None, 46 footer_text: str = "", 47 logo: str | None = None, 48 logo_link: str | None = None, 49 math: bool = False, 50 search: bool = True, 51 show_source: bool = True, 52 template_directory: Path | None = None, 53): 54 """ 55 Configure the rendering output. 56 57 - `docformat` is the docstring flavor in use. 58 pdoc prefers plain Markdown (the default), but also supports other formats. 59 - `edit_url_map` is a mapping from module names to URL prefixes. For example, 60 61 ```json 62 {"pdoc": "https://github.com/mitmproxy/pdoc/blob/main/pdoc/"} 63 ``` 64 65 renders the "Edit on GitHub" button on this page. The URL prefix can be modified to pin a particular version. 66 - `favicon` is an optional path/URL for a favicon image 67 - `footer_text` is additional text that should appear in the navigation footer. 68 - `logo` is an optional URL to the project's logo image 69 - `logo_link` is an optional URL the logo should point to 70 - `math` enables math rendering by including MathJax into the rendered documentation. 71 - `search` controls whether search functionality is enabled and a search index is built. 72 - `show_source` controls whether a "View Source" button should be included in the output. 73 - `template_directory` can be used to set an additional (preferred) directory 74 for templates. You can find an example in the main documentation of `pdoc` 75 or in `examples/custom-template`. 76 """ 77 searchpath = _default_searchpath 78 if template_directory: 79 searchpath = [template_directory] + searchpath 80 env.loader = FileSystemLoader(searchpath) 81 82 env.globals["edit_url_map"] = edit_url_map or {} 83 env.globals["docformat"] = docformat 84 env.globals["math"] = math 85 env.globals["show_source"] = show_source 86 env.globals["favicon"] = favicon 87 env.globals["logo"] = logo 88 env.globals["logo_link"] = logo_link 89 env.globals["footer_text"] = footer_text 90 env.globals["search"] = search
Configure the rendering output.
docformat
is the docstring flavor in use. pdoc prefers plain Markdown (the default), but also supports other formats.edit_url_map
is a mapping from module names to URL prefixes. For example,{"pdoc": "https://github.com/mitmproxy/pdoc/blob/main/pdoc/"}
renders the "Edit on GitHub" button on this page. The URL prefix can be modified to pin a particular version.
favicon
is an optional path/URL for a favicon imagefooter_text
is additional text that should appear in the navigation footer.logo
is an optional URL to the project's logo imagelogo_link
is an optional URL the logo should point tomath
enables math rendering by including MathJax into the rendered documentation.search
controls whether search functionality is enabled and a search index is built.show_source
controls whether a "View Source" button should be included in the output.template_directory
can be used to set an additional (preferred) directory for templates. You can find an example in the main documentation ofpdoc
or inexamples/custom-template
.
@defuse_unsafe_reprs()
def
html_module( module: pdoc.doc.Module, all_modules: Mapping[str, pdoc.doc.Module], mtime: str | None = None) -> str:
93@defuse_unsafe_reprs() 94def html_module( 95 module: pdoc.doc.Module, 96 all_modules: Mapping[str, pdoc.doc.Module], 97 mtime: str | None = None, 98) -> str: 99 """ 100 Renders the documentation for a `pdoc.doc.Module`. 101 102 - `all_modules` contains all modules that are rendered in this invocation. 103 This is used to determine which identifiers should be linked and which should not. 104 - If `mtime` is given, include additional JavaScript on the page for live-reloading. 105 This is only passed by `pdoc.web`. 106 """ 107 return env.get_template("module.html.jinja2").render( 108 module=module, 109 all_modules=all_modules, 110 root_module_name=root_module_name(all_modules), 111 edit_url=edit_url( 112 module.modulename, 113 module.is_package, 114 cast(Mapping[str, str], env.globals["edit_url_map"]), 115 ), 116 mtime=mtime, 117 )
Renders the documentation for a pdoc.doc.Module
.
all_modules
contains all modules that are rendered in this invocation. This is used to determine which identifiers should be linked and which should not.- If
mtime
is given, include additional JavaScript on the page for live-reloading. This is only passed bypdoc.web
.
120@defuse_unsafe_reprs() 121def html_index(all_modules: Mapping[str, pdoc.doc.Module]) -> str: 122 """Renders the module index.""" 123 return env.get_template("index.html.jinja2").render( 124 all_modules=all_modules, 125 root_module_name=root_module_name(all_modules), 126 )
Renders the module index.
@defuse_unsafe_reprs()
def
html_error(error: str, details: str = '') -> str:
129@defuse_unsafe_reprs() 130def html_error(error: str, details: str = "") -> str: 131 """Renders an error message.""" 132 return env.get_template("error.html.jinja2").render( 133 error=error, 134 details=details, 135 )
Renders an error message.
138@defuse_unsafe_reprs() 139def search_index(all_modules: Mapping[str, pdoc.doc.Module]) -> str: 140 """Renders the Elasticlunr.js search index.""" 141 if not env.globals["search"]: 142 return "" 143 # This is a rather terrible hack to determine if a given object is public and should be included in the index. 144 module_template: jinja2.Template = env.get_template("module.html.jinja2") 145 ctx: jinja2.runtime.Context = module_template.new_context( 146 {"module": pdoc.doc.Module(types.ModuleType("")), "all_modules": all_modules} 147 ) 148 for _ in module_template.root_render_func(ctx): # type: ignore 149 pass 150 151 def is_public(x: pdoc.doc.Doc) -> bool: 152 return bool(ctx["is_public"](x).strip()) 153 154 index = make_index( 155 all_modules, 156 is_public, 157 cast(str, env.globals["docformat"]), 158 ) 159 160 compile_js = Path(env.get_template("build-search-index.js").filename) # type: ignore 161 return env.get_template("search.js.jinja2").render( 162 search_index=precompile_index(index, compile_js) 163 )
Renders the Elasticlunr.js search index.
166@defuse_unsafe_reprs() 167def repr_module(module: pdoc.doc.Module) -> str: 168 """Renders `repr(pdoc.doc.Module)`, primarily used for tests and debugging.""" 169 return repr(module)
Renders repr(pdoc.doc.Module)
, primarily used for tests and debugging.
env = <jinja2.environment.Environment object>
The Jinja2 environment used to render all templates. You can modify this object to add custom filters and globals.