diff --git a/pdoc/__init__.py b/pdoc/__init__.py index eb1ecaf2..9dc515f7 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -105,7 +105,8 @@ def _render_template(template_name, **kwargs): config.update((var, getattr(config_module, var, None)) for var in config_module.__dict__ if var not in MAKO_INTERNALS) - known_keys = set(config) | {'module', 'modules', 'http_server', 'external_links'} # deprecated + known_keys = set(config) | {'module', 'modules', 'http_server', + 'html_index', 'external_links'} # deprecated invalid_keys = {k: v for k, v in kwargs.items() if k not in known_keys} if invalid_keys: warn('Unknown configuration variables (not in config.mako): {}'.format(invalid_keys)) diff --git a/pdoc/cli.py b/pdoc/cli.py index 149d1117..3c26bb73 100755 --- a/pdoc/cli.py +++ b/pdoc/cli.py @@ -82,6 +82,11 @@ help="The directory to output generated HTML/markdown files to " "(default: ./html for --html).", ) +aa( + "--html-index", + action="store_true", + help="Make a top-level index.html listing all the documented packages." +) aa( "--html-no-source", action="store_true", @@ -288,19 +293,22 @@ def module_path(m: pdoc.Module, ext: str): return path.join(args.output_dir, *re.sub(r'\.html$', ext, m.url()).split('/')) -def _quit_if_exists(m: pdoc.Module, ext: str): +def _quit_if_file_exists(pth): if args.force: return + if path.lexists(pth): + print("File '%s' already exists. Delete it, or run with --force" % pth, + file=sys.stderr) + sys.exit(1) + +def _quit_if_module_exists(m: pdoc.Module, ext: str): paths = [module_path(m, ext)] if m.is_package: # If package, make sure the dir doesn't exist either paths.append(path.dirname(paths[0])) for pth in paths: - if path.lexists(pth): - print("File '%s' already exists. Delete it, or run with --force" % pth, - file=sys.stderr) - sys.exit(1) + _quit_if_file_exists(pth) def write_files(m: pdoc.Module, ext: str, **kwargs): @@ -477,16 +485,36 @@ def docfilter(obj, _filters=args.filter.strip().split(',')): for module in modules: if args.html: - _quit_if_exists(module, ext='.html') - write_files(module, ext='.html', **template_config) + _quit_if_module_exists(module, ext='.html') + write_files(module, ext='.html', html_index=args.html_index, **template_config) elif args.output_dir: # Generate text files - _quit_if_exists(module, ext='.md') + _quit_if_module_exists(module, ext='.md') 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 and args.html_index: + # Add the root index.html at the top level. + index_file = path.join(args.output_dir, 'index.html') + _quit_if_file_exists(index_file) + # The template expects `modules` to be Tuples of (name, docstring). + module_tuples = sorted((module.name, module.docstring) + for module in modules) + index_text = pdoc._render_template('/html.mako', + modules=module_tuples, + **template_config) + try: + with open(index_file, 'w+', encoding='utf-8') as w: + w.write(index_text) + except Exception: + try: + os.unlink(index_file) + except Exception: + pass + raise + if __name__ == "__main__": main(parser.parse_args()) diff --git a/pdoc/templates/html.mako b/pdoc/templates/html.mako index ef0ce266..95591694 100644 --- a/pdoc/templates/html.mako +++ b/pdoc/templates/html.mako @@ -100,7 +100,7 @@
- % if http_server: + % if http_server or html_index: