예제 #1
0
    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)
예제 #2
0
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)
예제 #3
0
파일: cli.py 프로젝트: linconvidal/pdoc
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)
예제 #4
0
def _print_pdf(modules, **kwargs):
    modules = list(_flatten_submodules(modules))
    print(pdoc._render_template('/pdf.mako', modules=modules, **kwargs))
예제 #5
0
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)
예제 #6
0
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)
예제 #7
0
    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)
예제 #8
0
def pdf(modules):
    pdf = pdoc._render_template('pdf.mako', modules=modules)
    return pdf