For basic directives, or if you want maximum portability, you can base your directive on
Directive class from
If your directive mimics the
.. include:: directive in some way it’s easy enough to
insert some reStructuredText into the final document.
def run(self): ... filename = pathlib.Path(...) with filename.open() as f: content = f.read().splitlines() self.state_machine.insert_input(content, str(readme))
.. include:: directive does a lot more work to handle edge cases particuarly
when it comes to whitespace, so the above approach may not be sufficient in all cases.
If the directive is only for use within Sphinx projects, it’s a good idea to base it
SphinxDirective as it exposes more of Sphinx’s
internals potentially leading into better integration.
If you are referencing files from a directive, chances are you want to reference that
file either relative to the document’s source or the root of the documentation project.
Thankfully, there is the
method that implements that logic for you
def run(self): ... relpath, abspath = self.env.relfn2(filename)
The path of the file relative to the project’s
The absolute path of the file.
If the result of your directive depends on more than just the source file that contains
it you can use the
method to indicate the document should be rebuild if one of these external files change.
def run(self): ... self.env.note_dependency(filename)
During a build, Sphinx will look and issue warnings for any document not included in some
toctree. If however, an rst file is included by your directive and not directly included
note_included method can be used to suppress the warning.
def run(self): ... self.env.note_included(filename)