cardinal_pythonlib.sphinxtools
Original code copyright (C) 2009-2022 Rudolf Cardinal (rudolf@pobox.com).
This file is part of cardinal_pythonlib.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Functions to help with Sphinx, in particular the generation of autodoc files.
Rationale: if you want Sphinx autodoc
code to appear as “one module per
Sphinx page” (which I normally do), you need one .rst
file per module.
- class cardinal_pythonlib.sphinxtools.AutodocIndex(index_filename: str, project_root_dir: str, autodoc_rst_root_dir: str, highest_code_dir: str, python_package_root_dir: str | None = None, source_filenames_or_globs: str | Iterable[str] | None = None, index_heading_underline_char: str = '-', source_rst_heading_underline_char: str = '~', title: str = 'Automatic documentation of source code', introductory_rst: str = '', recursive: bool = True, skip_globs: List[str] | None = None, toctree_maxdepth: int = 1, method: AutodocMethod = AutodocMethod.BEST, rst_prefix: str = '', rst_suffix: str = '', source_rst_title_style_python: bool = True, pygments_language_override: Dict[str, str] | None = None)[source]
Class to make an RST file that indexes others.
Example:
import logging from cardinal_pythonlib.logs import * from cardinal_pythonlib.sphinxtools import * main_only_quicksetup_rootlogger(level=logging.INFO) # Example where one index contains another: subidx = AutodocIndex( index_filename="~/Documents/code/cardinal_pythonlib/docs/source/autodoc/_index2.rst", highest_code_dir="~/Documents/code/cardinal_pythonlib", project_root_dir="~/Documents/code/cardinal_pythonlib", autodoc_rst_root_dir="~/Documents/code/cardinal_pythonlib/docs/source/autodoc", source_filenames_or_globs="~/Documents/code/cardinal_pythonlib/docs/*.py", ) idx = AutodocIndex( index_filename="~/Documents/code/cardinal_pythonlib/docs/source/autodoc/_index.rst", highest_code_dir="~/Documents/code/cardinal_pythonlib", project_root_dir="~/Documents/code/cardinal_pythonlib", autodoc_rst_root_dir="~/Documents/code/cardinal_pythonlib/docs/source/autodoc", source_filenames_or_globs="~/Documents/code/cardinal_pythonlib/cardinal_pythonlib/*.py", ) idx.add_index(subidx) print(idx.index_content()) idx.write_index_and_rst_files(overwrite=True, mock=True) # Example with a flat index: flatidx = AutodocIndex( index_filename="~/Documents/code/cardinal_pythonlib/docs/source/autodoc/_index.rst", highest_code_dir="~/Documents/code/cardinal_pythonlib/cardinal_pythonlib", project_root_dir="~/Documents/code/cardinal_pythonlib", autodoc_rst_root_dir="~/Documents/code/cardinal_pythonlib/docs/source/autodoc", source_filenames_or_globs="~/Documents/code/cardinal_pythonlib/cardinal_pythonlib/*.py", ) print(flatidx.index_content()) flatidx.write_index_and_rst_files(overwrite=True, mock=True)
- Parameters:
index_filename¶ – filename of the index
.RST
(ReStructured Text) file to createproject_root_dir¶ – top-level directory for the whole project
autodoc_rst_root_dir¶ – directory within which all automatically generated
.RST
files (each to document a specific source file) will be placed. A directory hierarchy within this directory will be created, reflecting the structure of the code relative tohighest_code_dir
(q.v.).highest_code_dir¶ – the “lowest” directory such that all code is found within it; the directory structure within
autodoc_rst_root_dir
is to.RST
files what the directory structure is of the source files, relative tohighest_code_dir
.python_package_root_dir¶ – if your Python modules live in a directory other than
project_root_dir
, specify it heresource_filenames_or_globs¶ – optional string, or list of strings, each describing a file or glob-style file specification; these are the source filenames to create automatic RST` for. If you don’t specify them here, you can use
add_source_files()
. To add sub-indexes, useadd_index()
andadd_indexes()
.index_heading_underline_char¶ – the character used to underline the title in the index file
source_rst_heading_underline_char¶ – the character used to underline the heading in each of the source files
title¶ – title for the index
introductory_rst¶ – extra RST for the index, which goes between the title and the table of contents
recursive¶ – use
glob.glob()
in recursive mode?skip_globs¶ – list of file names or file specifications to skip; e.g.
['__init__.py']
toctree_maxdepth¶ –
maxdepth
parameter for thetoctree
command generated in the index filemethod¶ – see
FileToAutodocument
rst_prefix¶ – optional RST content (e.g. copyright comment) to put early on in each of the RST files
rst_suffix¶ – optional RST content to put late on in each of the RST files
source_rst_title_style_python¶ – make the individual RST files use titles in the style of Python modules,
x.y.z
, rather than path style (x/y/z
); path style will be used for non-Python files in any case.pygments_language_override¶ – if specified, a dictionary mapping file specifications to Pygments languages (for example: a
.pro
file will be autodetected as Prolog, but you might want to map that tonone
for Qt project files).
- add_index(index: AutodocIndex) None [source]
Add a sub-index file to this index.
- Parameters:
index¶ – index file to add, as an instance of
AutodocIndex
- add_indexes(indexes: List[AutodocIndex]) None [source]
Adds multiple sub-indexes to this index.
- Parameters:
indexes¶ – list of sub-indexes
- add_source_files(source_filenames_or_globs: str | List[str], method: AutodocMethod | None = None, recursive: bool | None = None, source_rst_title_style_python: bool | None = None, pygments_language_override: Dict[str, str] | None = None) None [source]
Adds source files to the index.
- Parameters:
source_filenames_or_globs¶ – string containing a filename or a glob, describing the file(s) to be added, or a list of such strings
method¶ – optional method to override
self.method
recursive¶ – use
glob.glob()
in recursive mode? (IfNone
, the default, uses the version from the constructor.)source_rst_title_style_python¶ – optional to override
self.source_rst_title_style_python
pygments_language_override¶ – optional to override
self.pygments_language_override
- get_sorted_source_files(source_filenames_or_globs: str | List[str], recursive: bool = True) List[str] [source]
Returns a sorted list of filenames to process, from a filename, a glob string, or a list of filenames/globs.
- index_filename_rel_other_index(other: str) str [source]
Returns the filename of this index, relative to the director of another index. (For inserting a reference to this index into
other
.)- Parameters:
other¶ – the other index
- Returns:
relative filename of our index
- property index_filename_rel_project_root: str
Returns the name of the index filename, relative to the project root. Used for labelling the index file.
- specific_file_rst_filename(source_filename: str) str [source]
Gets the RST filename corresponding to a source filename. See the help for the constructor for more details.
- Parameters:
source_filename¶ – source filename within current project
- Returns:
RST filename
Note in particular: the way we structure the directories means that we won’t get clashes between files with idential names in two different directories. However, we must also incorporate the original source filename, in particular for C++ where
thing.h
andthing.cpp
must not generate the same RST filename. So we just add.rst
.
- class cardinal_pythonlib.sphinxtools.AutodocMethod(value)[source]
Enum to specify the method of autodocumenting a file.
- class cardinal_pythonlib.sphinxtools.FileToAutodocument(source_filename: str, project_root_dir: str, target_rst_filename: str, method: AutodocMethod = AutodocMethod.BEST, python_package_root_dir: str | None = None, source_rst_title_style_python: bool = True, pygments_language_override: Dict[str, str] | None = None)[source]
Class representing a file to document automatically via Sphinx autodoc.
Example:
import logging from cardinal_pythonlib.logs import * from cardinal_pythonlib.sphinxtools import * main_only_quicksetup_rootlogger(level=logging.DEBUG) f = FileToAutodocument( source_filename="~/Documents/code/cardinal_pythonlib/cardinal_pythonlib/sphinxtools.py", project_root_dir="~/Documents/code/cardinal_pythonlib", target_rst_filename="~/Documents/code/cardinal_pythonlib/docs/source/autodoc/sphinxtools.rst", ) print(f) f.source_extension f.is_python f.source_filename_rel_project_root f.rst_dir f.source_filename_rel_rst_file f.rst_filename_rel_project_root f.rst_filename_rel_autodoc_index( "~/Documents/code/cardinal_pythonlib/docs/source/autodoc/_index.rst") f.python_module_name f.pygments_code_type print(f.rst_content(prefix=".. Hello!")) print(f.rst_content(prefix=".. Hello!", method=AutodocMethod.CONTENTS)) f.write_rst(prefix=".. Hello!")
- Parameters:
source_filename¶ – source file (e.g. Python, C++, XML file) to document
project_root_dir¶ – root directory of the whole project
target_rst_filename¶ – filenamd of an RST file to write that will document the source file
method¶ – instance of
AutodocMethod
; for example, should we ask Sphinx’sautodoc
to read docstrings and build us a pretty page, or just include the contents with syntax highlighting?python_package_root_dir¶ – if your Python modules live in a directory other than
project_root_dir
, specify it heresource_rst_title_style_python¶ – if
True
and the file is a Python file andmethod == AutodocMethod.AUTOMODULE
, the heading used will be in the style of a Python module,x.y.z
. Otherwise, it will be a path (x/y/z
).pygments_language_override¶ – if specified, a dictionary mapping file specifications to Pygments languages (for example: a
.pro
file will be autodetected as Prolog, but you might want to map that tonone
for Qt project files).
- property is_python: bool
Is the source file a Python file?
- property pygments_language: str
Returns the code type annotation for Pygments; e.g.
python
for Python,cpp
for C++, etc.
- property python_module_name: str
Returns the name of the Python module that this instance refers to, in dotted Python module notation, or a blank string if it doesn’t.
- rst_content(prefix: str = '', suffix: str = '', heading_underline_char: str = '=', method: AutodocMethod | None = None) str [source]
Returns the text contents of an RST file that will automatically document our source file.
- property rst_dir: str
Returns the directory of the target RST file.
- rst_filename_rel_autodoc_index(index_filename: str) str [source]
Returns the filename of the target RST file, relative to a specified index file. Used to make the index refer to the RST.
- property rst_filename_rel_project_root: str
Returns the filename of the target RST file, relative to the project root directory. Used for labelling the RST file itself.
- property source_extension: str
Returns the extension of the source filename.
- property source_filename_rel_project_root: str
Returns the name of the source filename, relative to the project root. Used to calculate file titles.
- property source_filename_rel_python_root: str
Returns the name of the source filename, relative to the Python package root. Used to calculate the name of Python modules.
- property source_filename_rel_rst_file: str
Returns the source filename as seen from the RST filename that we will generate. Used for
.. include::
commands.
- write_rst(prefix: str = '', suffix: str = '', heading_underline_char: str = '=', method: AutodocMethod | None = None, overwrite: bool = False, mock: bool = False) None [source]
Writes the RST file to our destination RST filename, making any necessary directories.
- Parameters:
prefix¶ – as for
rst_content()
suffix¶ – as for
rst_content()
heading_underline_char¶ – as for
rst_content()
method¶ – as for
rst_content()
overwrite¶ – overwrite the file if it exists already?
mock¶ – pretend to write, but don’t
- cardinal_pythonlib.sphinxtools.filename_matches_glob(filename: str, globtext: str) bool [source]
The
glob.glob
function doesn’t do exclusion very well. We don’t want to have to specify root directories for exclusion patterns. We don’t want to have to trawl a massive set of files to find exclusion files. So let’s implement a glob match.See also:
- cardinal_pythonlib.sphinxtools.rst_underline(heading: str, underline_char: str) str [source]
Underlines a heading for RST files.