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.

asked Dec 11, 2024 at 15:48

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.

answered Feb 27, 2025 at 1:33
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))
answered Oct 17, 2025 at 13:18

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.