0

I am trying to use pydoc to generate documentation for my code. Basically everything goes smoothly - I input my docstrings and run python -m pydoc on the module and an html file is written.

But the output html file is "plain vanilla" with no nice formatting: white background, no colors to highlite, ugly serif font etc.:

Ugly output

What I am looking for is output formatted like this:

Nice output

I couldn't find help on how to format the output.

EDIT: After a while, I believe some other tool than PyDoc might offer more flexibility in terms of formatting the output. No really helpful and simple answers to my original question have come.

2 Answers 2

1

I have exactly the same problem. It was particularly frustrating because apparently everybody else is getting the nicely formatted html page according to some YouTube video.

Then I did a little digging in pydoc.py. I realize pydoc is indeed writing a html page without any style sheets when you call pydoc.writedoc(), which is what you get when you type

pydoc -w myModule

in the terminal. However, when you use

pydoc -b myModule or pydoc -p myModule

the style sheet seems to be available. This means the your local server generates the html using a different function. Then I tracked down the html.page() function and realize there're 2 versions:

The original HTMLDoc(Doc) version and the overridden version in a locally defined class _HTMLDoc(HTMLDoc) inside _url_handler(). The overridden version is really what we want. So here's my hack:

  1. Find your pydoc.py, mine (Windows 11) is in C:/Users/MyUserName/AppData/Local/Programs/Python/Python312/Lib/pydoc.py
  2. Find class HTMLDoc(Doc) and class _HTMLDoc(HTMLDoc). They both have a function page()
  3. Replace page() in class HTMLDoc(Doc) with the one in class _HTMLDoc(HTMLDoc). Now because the one in class _HTMLDoc(HTMLDoc) also calls another function html_navbar(), you'll have to copy html_navbar() over as well. In particular this means replacing original HTMLDoc.page() code: HTMLDoc.page() without using _pydoc.css

with:

 def page(self, title, contents):
    """Format an HTML page."""
    css_path = "file://C|/Users/MyUserName/AppData/Local/Programs/Python/Python312/Lib/pydoc_data/_pydoc.css"
    css_link = (
            '<link rel="stylesheet" type="text/css" href="%s">' %
            css_path)
    return """\
<!DOCTYPE>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Pydoc: %s</title>
%s</head><body>%s<div style="clear:both;padding-top:.5em;">%s</div>
</body></html>""" % (title, css_link, self.html_navbar(), contents)


def html_navbar(self):
    version = html.escape("%s [%s, %s]" % (platform.python_version(),
                                           platform.python_build()[0],
                                           platform.python_compiler()))
    return """
            <div style='float:left'>
                Python %s<br>%s
            </div>
            <div style='float:right'>
                <div style='text-align:center'>
                  <a href="index.html">Module Index</a>
                  : <a href="topics.html">Topics</a>
                  : <a href="keywords.html">Keywords</a>
                </div>
                <div>
                    <form action="get" style='display:inline;'>
                      <input type=text name=key size=15>
                      <input type=submit value="Get">
                    </form>&nbsp;
                    <form action="search" style='display:inline;'>
                      <input type=text name=key size=15>
                      <input type=submit value="Search">
                    </form>
                </div>
            </div>
            """ % (version, html.escape(platform.platform(terse=True)))
  1. Be aware I also changed the css_path variable in the new page() function to be an absolute path to my file.

This worked for me perfectly! Now I have to figure out why it originally works for some people and not me... Hope this helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent! Thank you. I will try this.
0

There is an issue on that https://github.com/python/cpython/issues/127276

The solution proposed there can also be adapted in your own code:

import pydoc
import importlib.resources
css_data = importlib.resources.files('pydoc_data').joinpath('_pydoc.css').read_text()

pydoc.writedoc(module)  # this is the equivalent to pydoc -w
with open(module.__name__ + ".html") as inp:
    html = inp.read()
with open(module.__name__ + ".html", "w") as out:
    out.write(html.replace("</head>", "<style>%s</style></head>" % css_data))

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.