def do_GET(self): # Deny favicon shortcut early. if self.path == "/favicon.ico": return None importlib.invalidate_caches() code = 200 if self.path == "/": modules = [pdoc.import_module(module, reload=True) for module in self.args.modules] modules = sorted((module.__name__, inspect.getdoc(module)) for module in modules) out = pdoc._render_template('/html.mako', modules=modules, **self.template_config) elif self.path.endswith(".ext"): # External links are a bit weird. You should view them as a giant # hack. Basically, the idea is to "guess" where something lives # when documenting another module and hope that guess can actually # track something down in a more global context. # # The idea here is to start specific by looking for HTML that # exists that matches the full external path given. Then trim off # one component at the end and try again. # # If no HTML is found, then we ask `pdoc` to do its thang on the # parent module in the external path. If all goes well, that # module will then be able to find the external identifier. import_path = self.path[:-4].lstrip("/") resolved = self.resolve_ext(import_path) if resolved is None: # Try to generate the HTML... print("Generating HTML for %s on the fly..." % import_path, file=sys.stderr) try: out = pdoc.html(import_path.split(".")[0], **self.template_config) except Exception as e: print('Error generating docs: {}'.format(e), file=sys.stderr) # All hope is lost. code = 404 out = "External identifier <code>%s</code> not found." % import_path else: return self.redirect(resolved) # Redirect '/pdoc' to '/pdoc/' so that relative links work # (results in '/pdoc/cli.html' instead of 'cli.html') elif not self.path.endswith(('/', '.html')): return self.redirect(self.path + '/') # Redirect '/pdoc/index.html' to '/pdoc/' so it's more pretty elif self.path.endswith(pdoc._URL_PACKAGE_SUFFIX): return self.redirect(self.path[:-len(pdoc._URL_PACKAGE_SUFFIX)] + '/') else: try: out = self.html() except ImportError: code = 404 out = "Module <code>%s</code> not found." % self.import_path_from_req_url self.send_response(code) self.send_header("Content-type", "text/html; charset=utf-8") self.end_headers() self.echo(out)
def _generate_lunr_search(top_module: pdoc.Module, index_docstrings: bool, template_config: dict): """Generate index.js for search""" def trim_docstring(docstring): return re.sub(r''' \s+| # whitespace sequences \s+[-=~]{3,}\s+| # title underlines ^[ \t]*[`~]{3,}\w*$| # code blocks \s*[`#*]+\s*| # common markdown chars \s*([^\w\d_>])\1\s*| # sequences of punct of the same kind \s*</?\w*[^>]*>\s* # simple HTML tags ''', ' ', docstring, flags=re.VERBOSE | re.MULTILINE) def recursive_add_to_index(dobj): info = { 'ref': dobj.refname, 'url': to_url_id(dobj.module), } if index_docstrings: info['doc'] = trim_docstring(dobj.docstring) if isinstance(dobj, pdoc.Function): info['func'] = 1 index.append(info) for member_dobj in getattr(dobj, 'doc', {}).values(): recursive_add_to_index(member_dobj) @lru_cache() def to_url_id(module): url = module.url() if top_module.is_package: # Reference from subfolder if its a package _, url = url.split('/', maxsplit=1) if url not in url_cache: url_cache[url] = len(url_cache) return url_cache[url] index = [] # type: List[Dict] url_cache = {} # type: Dict[str, int] recursive_add_to_index(top_module) urls = [i[0] for i in sorted(url_cache.items(), key=lambda i: i[1])] # If top module is a package, output the index in its subfolder, else, in the output dir main_path = path.join( args.output_dir, *top_module.name.split('.') if top_module.is_package else '') with _open_write_file(path.join(main_path, 'index.js')) as f: f.write("URLS=") json.dump(urls, f, indent=0, separators=(',', ':')) f.write(";\nINDEX=") json.dump(index, f, indent=0, separators=(',', ':')) # Generate search.html with _open_write_file(path.join(main_path, 'search.html')) as f: rendered_template = pdoc._render_template('/search.mako', module=top_module, **template_config) f.write(rendered_template)
def _generate_lunr_search(modules: List[pdoc.Module], index_docstrings: bool, template_config: dict): """Generate index.js for search""" def trim_docstring(docstring): return re.sub(r''' \s+| # whitespace sequences \s+[-=~]{3,}\s+| # title underlines ^[ \t]*[`~]{3,}\w*$| # code blocks \s*[`#*]+\s*| # common markdown chars \s*([^\w\d_>])\1\s*| # sequences of punct of the same kind \s*</?\w*[^>]*>\s* # simple HTML tags ''', ' ', docstring, flags=re.VERBOSE | re.MULTILINE) def recursive_add_to_index(dobj): info = { 'ref': dobj.refname, 'url': to_url_id(dobj.module), } if index_docstrings: info['doc'] = trim_docstring(dobj.docstring) if isinstance(dobj, pdoc.Function): info['func'] = 1 index.append(info) for member_dobj in getattr(dobj, 'doc', {}).values(): recursive_add_to_index(member_dobj) @lru_cache() def to_url_id(module): url = module.url() if url not in url_cache: url_cache[url] = len(url_cache) return url_cache[url] index: List[Dict] = [] url_cache: Dict[str, int] = {} for top_module in modules: recursive_add_to_index(top_module) urls = sorted(url_cache.keys(), key=url_cache.__getitem__) main_path = args.output_dir with _open_write_file(path.join(main_path, 'index.js')) as f: f.write("URLS=") json.dump(urls, f, indent=0, separators=(',', ':')) f.write(";\nINDEX=") json.dump(index, f, indent=0, separators=(',', ':')) # Generate search.html with _open_write_file(path.join(main_path, 'doc-search.html')) as f: rendered_template = pdoc._render_template('/search.mako', **template_config) f.write(rendered_template)
def _print_pdf(modules, **kwargs): modules = list(_flatten_submodules(modules)) print(pdoc._render_template('/pdf.mako', modules=modules, **kwargs))
def recursive_mds(module): # noqa """Recursively render mkdocs friendly markdown/html""" yield module.name, _render_template("/mkdocs_markdown.mako", module=module) for submod in module.submodules(): yield from recursive_mds(submod)
def _patched_generate_lunr_search(modules, index_docstrings, template_config): # This will only be called once due to how we generate the documentation, so we can ignore the rest assert len( modules) == 1, "expected only 1 module to be generated, got more" top_module = modules[0] def trim_docstring(docstring): return re.sub( r""" \s+[-=~]{3,}\s+| # title underlines ^[ \t]*[`~]{3,}\w*$| # code blocks \s*[`#*]+\s*| # common markdown chars \s*([^\w\d_>])\1\s*| # sequences of punct of the same kind \s*</?\w*[^>]*>\s* # simple HTML tags \s+ # whitespace sequences """, " ", docstring, flags=re.VERBOSE | re.MULTILINE, ) def recursive_add_to_index(dobj): if dobj.module.name != "hikari": # Do not index root url = to_url_id(dobj) # r: ref # u: url # d: docstring # f: function info = {"r": dobj.refname, "u": url} if index_docstrings: info["d"] = trim_docstring(dobj.docstring) if isinstance(dobj, pdoc.Function): info["f"] = 1 index.append(info) for member_dobj in getattr(dobj, "doc", {}).values(): if dobj.module.name == "hikari" and not isinstance( member_dobj, pdoc.Module): continue recursive_add_to_index(member_dobj) def to_url_id(dobj): # pdocs' .url() doesn't take in account that some attributes are inherited, # which generates an invalid url. Because of this, we need to take matter # into our own hands. url = dobj.refname.replace(".", "/") if not isinstance(dobj, pdoc.Module): depth = 1 obj = getattr(dobj, "cls", None) while obj: depth += 1 obj = getattr(obj, "cls", None) url = "/".join(url.split("/")[:-depth]) if top_module.is_package: # Reference from subfolder if its a package _, url = url.split("/", maxsplit=1) if url not in url_cache: url_cache[url] = len(url_cache) return url_cache[url] index = [] url_cache = {} recursive_add_to_index(top_module) urls = sorted(url_cache.keys(), key=url_cache.__getitem__) # If top module is a package, output the index in its subfolder, else, in the output dir main_path = path.join( cli.args.output_dir, *top_module.name.split(".") if top_module.is_package else "") with cli._open_write_file(path.join(main_path, "index.json")) as f: json.dump({"urls": urls, "index": index}, f) # Generate search.html with cli._open_write_file(path.join(main_path, "search.html")) as f: rendered_template = pdoc._render_template("/search.mako", module=top_module, **template_config) f.write(rendered_template)
def _patched_generate_lunr_search(modules, index_docstrings, template_config): # This will only be called once due to how we generate the documentation, so we can ignore the rest assert len(modules) == 1, "expected only 1 module to be generated, got more" top_module = modules[0] def trim_docstring(docstring): return re.sub( r""" \s+| # whitespace sequences \s+[-=~]{3,}\s+| # title underlines ^[ \t]*[`~]{3,}\w*$| # code blocks \s*[`#*]+\s*| # common markdown chars \s*([^\w\d_>])\1\s*| # sequences of punct of the same kind \s*</?\w*[^>]*>\s* # simple HTML tags """, " ", docstring, flags=re.VERBOSE | re.MULTILINE, ) def recursive_add_to_index(dobj): url = to_url_id(dobj.module) if url != 0: # 0 is index.html # r: ref # u: url # d: doc # f: function info = {"r": dobj.refname, "u": url} if index_docstrings: info["d"] = trim_docstring(dobj.docstring) if isinstance(dobj, pdoc.Function): info["f"] = 1 index.append(info) for member_dobj in getattr(dobj, "doc", {}).values(): if url == 0 and not isinstance(dobj, pdoc.Module): # Don't document anything that is not a submodule in root package continue recursive_add_to_index(member_dobj) @lru_cache() def to_url_id(module): url = module.url() if top_module.is_package: # Reference from subfolder if its a package _, url = url.split("/", maxsplit=1) if url not in url_cache: url_cache[url] = len(url_cache) return url_cache[url] index = [] url_cache = {} recursive_add_to_index(top_module) urls = sorted(url_cache.keys(), key=url_cache.__getitem__) # If top module is a package, output the index in its subfolder, else, in the output dir main_path = path.join(cli.args.output_dir, *top_module.name.split(".") if top_module.is_package else "") with cli._open_write_file(path.join(main_path, "index.json")) as f: json.dump({"index": index, "urls": urls}, f) # Generate search.html with cli._open_write_file(path.join(main_path, "search.html")) as f: rendered_template = pdoc._render_template("/search.mako", module=top_module, **template_config) f.write(rendered_template)
def pdf(modules): pdf = pdoc._render_template('pdf.mako', modules=modules) return pdf