Module pdoc.cli
pdoc's CLI interface and helper functions.
Functions
def main()
-
Expand source code Browse git
def main(_args=None): """ Command-line entry point """ global args args = _args or parser.parse_args() # If warnings not externally managed, show deprecation warnings if not sys.warnoptions: warnings.simplefilter("once", DeprecationWarning) if args.close_stdin: sys.stdin.close() if (args.html or args.http) and not args.output_dir: args.output_dir = 'html' if args.html_dir: _warn_deprecated('--html-dir', '--output-dir') args.output_dir = args.html_dir if args.overwrite: _warn_deprecated('--overwrite', '--force') args.force = args.overwrite template_config = {} for config_str in args.config: try: key, value = config_str.split('=', 1) value = ast.literal_eval(value) template_config[key] = value except Exception: raise ValueError( f'Error evaluating --config statement "{config_str}". ' 'Make sure string values are quoted?' ) if args.html_no_source: _warn_deprecated('--html-no-source', '-c show_source_code=False', True) template_config['show_source_code'] = False if args.link_prefix: _warn_deprecated('--link-prefix', '-c link_prefix="foo"', True) template_config['link_prefix'] = args.link_prefix if args.external_links: _warn_deprecated('--external-links') template_config['external_links'] = True if args.template_dir is not None: if not path.isdir(args.template_dir): print(f'Error: Template dir {args.template_dir!r} is not a directory', file=sys.stderr) sys.exit(1) pdoc.tpl_lookup.directories.insert(0, args.template_dir) # Support loading modules specified as python paths relative to cwd sys.path.append(os.getcwd()) # Virtual environment handling for pdoc script run from system site try: os.environ['VIRTUAL_ENV'] except KeyError: pass # pdoc was not invoked while in a virtual environment else: from glob import glob from sysconfig import get_path libdir = get_path("platlib") sys.path.append(libdir) # Resolve egg-links from `setup.py develop` or `pip install -e` # XXX: Welcome a more canonical approach for pth in glob(path.join(libdir, '*.egg-link')): try: with open(pth) as f: sys.path.append(path.join(libdir, f.readline().rstrip())) except IOError: warn(f'Invalid egg-link in venv: {pth!r}') if args.http: template_config['link_prefix'] = "/" # Run the HTTP server. _WebDoc.args = args # Pass params to HTTPServer xP _WebDoc.template_config = template_config host, _, port = args.http.partition(':') host = host or DEFAULT_HOST port = int(port or DEFAULT_PORT) print(f'Starting pdoc server on {host}:{port}', file=sys.stderr) httpd = HTTPServer((host, port), _WebDoc) print(f"pdoc server ready at http://{host}:{port}", file=sys.stderr) # Allow tests to perform `pdoc.cli._httpd.shutdown()` global _httpd _httpd = httpd try: httpd.serve_forever() finally: httpd.server_close() sys.exit(0) if args.filter and args.filter.strip(): def docfilter(obj, _filters=args.filter.strip().split(',')): return any(f in obj.refname or isinstance(obj, pdoc.Class) and f in obj.doc for f in _filters) else: docfilter = None modules = [pdoc.Module(module, docfilter=docfilter, skip_errors=args.skip_errors) for module in args.modules] pdoc.link_inheritance() # Loading is done. Output stage ... config = pdoc._get_config(**template_config) # Load configured global markdown extensions # XXX: This is hereby enabled only for CLI usage as for # API use I couldn't figure out where reliably to put it. if config.get('md_extensions'): from .html_helpers import _md _kwargs = {'extensions': [], 'configs': {}} _kwargs.update(config.get('md_extensions', {})) _md.registerExtensions(**_kwargs) if args.pdf: _print_pdf(modules, **template_config) import textwrap PANDOC_CMD = textwrap.indent(_PANDOC_COMMAND, ' ') print(f""" PDF-ready markdown written to standard output. ^^^^^^^^^^^^^^^ Convert this file to PDF using e.g. Pandoc: {PANDOC_CMD} or using Python-Markdown and Chrome/Chromium/WkHtmlToPDF: markdown_py --extension=meta \\ --extension=abbr \\ --extension=attr_list \\ --extension=def_list \\ --extension=fenced_code \\ --extension=footnotes \\ --extension=tables \\ --extension=admonition \\ --extension=smarty \\ --extension=toc \\ pdf.md > pdf.html chromium --headless --disable-gpu --print-to-pdf=pdf.pdf pdf.html wkhtmltopdf --encoding utf8 -s A4 --print-media-type pdf.html pdf.pdf or similar, at your own discretion.""", file=sys.stderr) sys.exit(0) for module in modules: if args.html: _quit_if_exists(module, ext='.html') recursive_write_files(module, ext='.html', **template_config) elif args.output_dir: # Generate text files _quit_if_exists(module, ext='.md') recursive_write_files(module, ext='.md', **template_config) else: sys.stdout.write(module.text(**template_config)) # Two blank lines between two modules' texts sys.stdout.write(os.linesep * (1 + 2 * int(module != modules[-1]))) if args.html: lunr_config = config.get('lunr_search') if lunr_config is not None: _generate_lunr_search( modules, lunr_config.get("index_docstrings", True), template_config)
Command-line entry point
def module_path(m: Module, ext: str)
-
Expand source code Browse git
def module_path(m: pdoc.Module, ext: str): return path.join(args.output_dir, *re.sub(r'\.html$', ext, m.url()).split('/'))
def recursive_write_files(m: Module,
ext: str,
**kwargs)-
Expand source code Browse git
def recursive_write_files(m: pdoc.Module, ext: str, **kwargs): assert ext in ('.html', '.md') filepath = module_path(m, ext=ext) dirpath = path.dirname(filepath) if not os.access(dirpath, os.R_OK): os.makedirs(dirpath) with _open_write_file(filepath) as f: if ext == '.html': f.write(m.html(**kwargs)) elif ext == '.md': f.write(m.text(**kwargs)) for submodule in m.submodules(): recursive_write_files(submodule, ext=ext, **kwargs)