Sphinx: customize sidebar section titles - python

I am documenting my Python project with Sphinx. As some of my documentation pages are rather long, I would like to have both a local and a global table of contents in the sidebar. I achieve achieve this via
html_sidebars = { '**': ['localtoc.html', 'globaltoc.html', 'searchbox.html'] }
The result is almost as desired. However, both the local and the global table of contents have the same title ("Table of Contents"). That is, it looks like
Table of Contents
- Subheading 1
- Subheading 2
- Subheading 3
Table of Contents
- Subpage 1
- Subpage 2
- Subpage 3
This is confusing to the reader.
I have located the file localtoc.html in the sphinx package folder of my Python installation, and adjusting the html to my needs (replacing the title) is simple. However, I would not like to change a Sphinx source file, and building my own theme via a python package seems overkill to me.
Is there any way to replace localtoc.html locally, i.e. for the current project only?

You can override the behaviour of the localtoc.html template.
Create a _templates folder in your Sphinx root (the same place where your conf.py file is located), and copy localtoc.html from your Sphinx installation to this folder.
You can then modify this file as you wish. Remove this line:
<h3>{{ _('Table of Contents') }}</h3>
to get rid of the extra heading, or you could replace any of the text, as you wish (for example changing the content of the <a> to Local Contents or whatever you like.
Note that changing the localtoc.html removes the top of the two headings. If this is what you wanted, great! If not, you could replicate the process just using globaltoc.html in the same way.

Related

django-admin makemessages: how does it work with txt, xml and other files?

I am in the process of translating a Django app. I have translatable strings in files of a specific extensions (.vue files, but that's not very important for now).
I have to run the makemessages command to parse those strings and generate .po files.
The documentation says:
makemessages: Runs over the entire source tree of the current directory and pulls
out all strings marked for translation.
Also, the docs states that the default file extensions are: html, txt, py and gives an example with explicitly defined extentions:
django-admin makemessages --locale=de --extension=html,txt --extension xml
My question is: how is makemessages supposed to work with non-compiled files like txt and xml? How would I mark string for translation in files like that?
I know how to do this in a template or a .py file:
.html
{% trans "Text to be translated" %}
.py
gettext("Text to be translated")
# or
_("Text to be translated")
But what about other extensions? .txt, .xml? ... and eventually .vue?
The makemessages command searches for files to translate and invokes the (x)gettext utility to extract the strings marked for translation. It will behave differently depending on whether you tell it to use the django or djangojs --domain.
When using the django domain, it runs non-.py files through django.utils.translation.templatize to "Turn a Django template into something that is understood by xgettext"). It basically turns the whole file into XXXXX apart from the parts the lexer determines are relevant to gettext, which keeps the line numbers intact, etc.
>>> from django.utils.translation import templatize
>>> content = """This is a {% trans "test" %}!
... {# Translators: these comments remain intact for translators #}
... {% blocktrans %}Only applies to --domain=django and non-.py files {% endblocktrans %}
...
... Everything else is {# ignored #}
... {% trans "EOM" %}
... :)"""
>>> print(templatize(content))
XXXX XX X gettext(u'test') X
# Translators: these comments remain intact for translators
gettext(u'Only applies to --domain=django and non-.py files ') SSSS SSSSSSS SS SSSSSSSSSSSSSSS SSS SSSSSSS SSSSS
XXXXXXXXXX XXXX XX
gettext(u'EOM')
XX
>>>
So for most non-Python, non-Django-template files, this will obliterate your translatable content.
When using the djangojs domain, Django won't perform any such preprocessing on the files. (For versions of gettext older than 0.18.3, makemessages would call django.utils.jslex.prepare_js_for_gettext, which is somewhat less aggressive and just tweaks any escaping/regex syntax if necessary).
If you run makemessages -a -d djangojs -e "js,vue", Django will tell xgettext to parse your .js and .vue files with --language=JavaScript and a certain number of extra --keyword configurations to support gettext_noop, gettext_lazy, etc (gettext defaults to a keywordspec of _, gettext, dgettext:2, dcgettext:2, ngettext:1,2, dngettext:2,3, pgettext:1c,2, dpgettext:2c,3 for JavaScript). makemessages will also pass --from-code=UTF-8 and --add-comments=Translators arguments.
It's then over to gettext to do the parsing based on those specifications, and its own understanding of the files based on the --language specified.
Therefore your best bet for translating .txt, .xml, etc files with makemessages is to use the djangojs domain and see what gettext picks up based on --language=JavaScript, so you'd mark your strings as you would for JavaScript.
Or for Jinja2 templates, etc you could use an alternative solution such as Babel's Message Extraction
Or you could even customize makemessages to pass different parameters to gettext based on your requirements.
So for your Vue example...
If your .vue file contains calls to gettext in javascript code sections (default parsing doesn't seem to pick up on gettext calls within template attributes, etc) you should find that makemessages will extract these strings for translation (and compilemessages will generate the required binary files after the .po files are edited).
Then in order to see the translations when the code runs, you'll need to use the Django JavaScript Catalog, so ensure you include something like <script type="text/javascript" src="{% url 'javascript-catalog' %}"></script> in your code so that the gettext etc functions actually exist. (It sounds like you've already got this, but included for the sake of completeness.)
In your .vue files you could use something like:
<script> // trick to ensure xgettext doesn't omit the code below: </closetag>
data(){
const _ = gettext;
// gettext default JavaScript keywordspec includes "_" shortcut
// and should extract the strings below by default
// -- or you could just use gettext('my string') directly
return {
heading: _('This is my translatable heading'),
button_text: _('Click here'),
}
}
</script>
<template>
<h1>{{ heading }}</h1>
<button type="button">{{ button_text }}</button>
</template>
-- the strings should be translated based on the currently activated language courtesty of Django's translation mechanism.
If you want any of the content of those files to be dynamic, then you need to put them through some kind of parsing process.
There's absolutely no reason why you couldn't treat them as Django templates and render them through the normal Django template rending process; obviously without knowing what you are doing with those files it's impossible to give you specific advice, but you might want to use render_to_string. In itself, this doesn't have anything to do with translation or makemessages.

How to add the source code to a LaTeX document generated with sphinx

I'm generating the docs of my python library with Sphinx. I use the extension sphinx.ext.viewcode
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
"sphinx.ext.intersphinx",
"sphinx.ext.ifconfig",
"sphinx.ext.viewcode", # Add links to highlighted source code
"sphinx.ext.napoleon", # to render Google format docstrings
]
This generates a link to the source documentation, similarly to:
class MyClass(param1, param2)[source]
like in this image:
If I press source, I see the source code correctly in my HTML page.
I would like to do exactly the same when I generate a LaTeX file. I can't find in the documentation how to add the source code when you create a pdf from LaTeX. Any hint?
There is a way to add code to python through a package called listings. This package allows one to show code and even complete files.
For implementing this, in conf.py you can add:
latex_elements = {
"papersize": "letterpaper",
"pointsize": "10pt",
"figure_align": "htbp",
"preamble": r"""
\usepackage{listings}
\lstset{
language=Python, % the language of the code
title=\lstname % show the filename of files included with \lstinputlisting; also try caption instead of title
}
""",
}
there are more settings that can be added to lstset.
Then the code can be added in the .rst file as:
.. raw:: latex
\section{Code}
\lstinputlisting{../../../path/to/my/file.py}
According to the documentation for sphinx.ext.viewcode:
This extension works only on HTML related builders like html, applehelp, devhelp, htmlhelp, qthelp and so on except singlehtml.

Python Pdoc - how to export html with separate css file?

I am using pdoc function:
def html(module_name, docfilter=None, allsubmodules=False, external_links=False, link_prefix='', source=True)
But according to documentation on http://pdoc.burntsushi.net/pdoc#pdoc.html I am unable to find out how to export HTML separated from CSS.
Pdoc uses a html.mako template file that includes CSS stylesheets. To change CSS, one needs to either copy and modify the whole HTML template, or override just the included head.mako to include additional styles. In either case one then needs to run pdoc with --template-dir switch:
$ pdoc --html --template-dir=my_templates my_project

Sphinx apidoc section titles for Python module/package names

When I run sphinx-apidoc and then make html it produces doc pages that have "Subpackages" and "Submodules" sections and "module" and "package" at the end of each module/package name in the table of contents (TOC). How might I prevent these extra titles from being written without editing the Sphinx source?
here's an example doc pages I would like to make (notice TOC):
http://selenium.googlecode.com/svn/trunk/docs/api/py/index.html#documentation
I understand it is due to the apidoc.py file in the sphinx source (line 88):
https://bitbucket.org/birkenfeld/sphinx/src/ef3092d458cc00c4b74dd342ea05ba1059a5da70/sphinx/apidoc.py?at=default
I could manually edit each individual .rst file to delete these titles or just remove those lines of code from the script but then I'd have to compile the Sphinx source code. Is there an automatic way of doing this without manually editing the Sphinx source?
I was struggling with this myself when I found this question... The answers given didn't quite do what I wanted so I vowed to come back when I figured it out. :)
In order to remove 'package' and 'module' from the auto-generated headings and have docs that are truly automatic, you need to make changes in several places so bear with me.
First, you need to handle your sphinx-apidoc options. What I use is:
sphinx-apidoc -fMeET ../yourpackage -o api
Assuming you are running this from inside the docs directory, this will source yourpackage for documentation and put the resulting files at docs/api. The options I'm using here will overwrite existing files, put module docs before submodule docs, put documentation for each module on its own page, abstain from creating module/package headings if your docstrings already have them, and it won't create a table of contents file.
That's a lot of options to remember, so I just add this to the end of my Makefile:
buildapi:
sphinx-apidoc -fMeET ../yourpackage -o api
#echo "Auto-generation of API documentation finished. " \
"The generated files are in 'api/'"
With this in place, you can just run make buildapi to build your docs.
Next, create an api.rst file at the root of your docs with the following contents:
API Documentation
=================
Information on specific functions, classes, and methods.
.. toctree::
:glob:
api/*
This will create a table of contents with everything in the api folder.
Unfortunately, sphinx-apidoc will still generate a yourpackage.rst file with an ugly 'yourpackage package' heading, so we need one final piece of configuration. In your conf.py file, find the exclude_patterns option and add this file to the list. It should look something like this:
exclude_patterns = ['_build', 'api/yourpackage.rst']
Now your documentation should look exactly like you designed it in the module docstrings, and you never have to worry about your Sphinx docs and your in-code documentation being out of sync!
It's probably late, but the options maxdepth or titlesonly should do the trick.
More details :
http://sphinx-doc.org/latest/markup/toctree.html
The answer by Jen Garcia helped a lot but it requires to put repeat package names in docstrings. I used a Perl one-liner to remove the "module" or "package" suffix in my Makefile:
docs:
rm -rf docs/api docs/_build
sphinx-apidoc -MeT -o docs/api wdmapper
for f in docs/api/*.rst; do\
perl -pi -e 's/(module|package)$$// if $$. == 1' $$f ;\
done
$(MAKE) -C docs html
I didn't want to use the titles within my docstrings as I was following numpy style guidelines. So I first generate the rst files and then run the following python script as a post-processing step.
from pathlib import Path
src_dir = Path("source/api")
for file in src_dir.iterdir():
print("Processed RST file:", file)
with open(file, "r") as f:
lines = f.read()
junk_strs = ["Submodules\n----------", "Subpackages\n-----------"]
for junk in junk_strs:
lines = lines.replace(junk, "")
lines = lines.replace(" module\n=", "\n")
with open(file, "w") as f:
f.write(lines)
This script is kept in the same directory as the makefile. I also add the following lines to the makefile.
html:
# rm -r "$(BUILDDIR)"
python rst_process.py
#$(SPHINXBUILD) -M $# "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
Now running make html builds the documentation in the way I want.
I'm not sure I'm 100% answering your question, but I had a similar experience and I realized I was running sphinx-apidoc with the -f flag each time, which created the .rst files fresh each time.
Now I'm allowing sphinx-apidoc to generate the .rst files once, but not overwriting them, so I can modify them to change titles/etc. and then run make html to propagate the changes. If I want to freshly generate .rst files I can just remove the files I want to regenerate or pass the -f flag in.
So you do have to change the rst files but only once.
In newer versions of Apidoc, you can use a custom Jinja template to control the generated output.
The default templates are here: https://github.com/sphinx-doc/sphinx/tree/5.x/sphinx/templates/apidoc
You can make a local copy of each template using the same names (e.g. source/_templates/toc.rst_t) and invoke sphinx-apidoc with the --templatedir option (e.g. sphinx-apidoc --templatedir source/_templates).
Once you are using your own template file, you can customize it however you want. For example, you can remove the ugly "package" and "module" suffix, which is added at this stage.

Can you rename "table of contents" in the Sphinx sidebar?

More generally how do you rename Sphinx default elements (e.g. Quick Search to Search)? Can you?
Here is how you could change "Quick search" to something else by overriding a template:
Create a folder called templates in the Sphinx project directory.
Copy <Sphinx install dir>/themes/basic/searchbox.html to templates.
In conf.py, add
templates_path = ["templates"]
Rename 'Quick search' to whatever you want in the copy of searchbox.html.
But I would not do it this way.
A more flexible approach is to create a gettext MO file and set up the configuration as described in the documentation for locale_dirs. Like this:
The template file <Sphinx install dir>/locale/sphinx.pot contains all the strings that can be translated. Copy that file to a local sphinx.po file.
Add your changes to sphinx.po.
Use msgfmt.py to compile sphinx.po into sphinx.mo.
Put sphinx.mo in the proper directory (<your_locale_dir>/en/LC_MESSAGES for English).
See also http://docs.python.org/library/gettext.html#internationalizing-your-programs-and-modules.
According to Sphinx config documentation, you should be able to amend the html templates or perhaps point Sphinx to new templates to achieve what you trying to do by working on the templates' html.
Current templates have search title provided in the context, I am not sure though what populates context value for _('search'). I wander if you could try customizing it by amending the locale file in /sphinx/sphinx/locale/sphinx.pot:
#: sphinx/themes/agogo/layout.html:49 sphinx/themes/basic/layout.html:137
#: sphinx/themes/basic/search.html:11 sphinx/themes/basic/search.html:20
msgid "Search"
msgstr ""
and say msgstr "My alternative search" instead of msgstr "".

Categories

Resources