"""Plain-text Sphinx builder.""" from os import path from typing import Any, Dict, Iterator, Set, Tuple from docutils.io import StringOutput from docutils.nodes import Node from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.locale import __ from sphinx.util import logging from sphinx.util.osutil import ensuredir, os_path from sphinx.writers.text import TextTranslator, TextWriter logger = logging.getLogger(__name__) class TextBuilder(Builder): name = 'text' format = 'text' epilog = __('The text files are in %(outdir)s.') out_suffix = '.txt' allow_parallel = True default_translator_class = TextTranslator current_docname: str = None def init(self) -> None: # section numbers for headings in the currently visited document self.secnumbers: Dict[str, Tuple[int, ...]] = {} def get_outdated_docs(self) -> Iterator[str]: for docname in self.env.found_docs: if docname not in self.env.all_docs: yield docname continue targetname = path.join(self.outdir, docname + self.out_suffix) try: targetmtime = path.getmtime(targetname) except Exception: targetmtime = 0 try: srcmtime = path.getmtime(self.env.doc2path(docname)) if srcmtime > targetmtime: yield docname except OSError: # source doesn't exist anymore pass def get_target_uri(self, docname: str, typ: str = None) -> str: return '' def prepare_writing(self, docnames: Set[str]) -> None: self.writer = TextWriter(self) def write_doc(self, docname: str, doctree: Node) -> None: self.current_docname = docname self.secnumbers = self.env.toc_secnumbers.get(docname, {}) destination = StringOutput(encoding='utf-8') self.writer.write(doctree, destination) outfilename = path.join(self.outdir, os_path(docname) + self.out_suffix) ensuredir(path.dirname(outfilename)) try: with open(outfilename, 'w', encoding='utf-8') as f: f.write(self.writer.output) except OSError as err: logger.warning(__("error writing file %s: %s"), outfilename, err) def finish(self) -> None: pass def setup(app: Sphinx) -> Dict[str, Any]: app.add_builder(TextBuilder) app.add_config_value('text_sectionchars', '*=-~"+`', 'env') app.add_config_value('text_newlines', 'unix', 'env') app.add_config_value('text_add_secnumbers', True, 'env') app.add_config_value('text_secnumber_suffix', '. ', 'env') return { 'version': 'builtin', 'parallel_read_safe': True, 'parallel_write_safe': True, }