4141from sphinx import roles # NoQA: F401 isort:skip
4242
4343if TYPE_CHECKING :
44- from collections .abc import Iterable , Sequence
44+ from collections .abc import Iterable , Sequence , Set
4545
4646 from docutils .nodes import Node
4747
@@ -664,6 +664,7 @@ def write_doctree(
664664 if _cache :
665665 self .env ._write_doc_doctree_cache [docname ] = doctree
666666
667+ @final
667668 def write (
668669 self ,
669670 build_docnames : Iterable [str ] | None ,
@@ -685,11 +686,12 @@ def write(
685686 logger .debug (__ ('docnames to write: %s' ), ', ' .join (sorted (docnames )))
686687
687688 # add all toctree-containing files that may have changed
688- for docname in list (docnames ):
689+ extra = {self .config .root_doc }
690+ for docname in docnames :
689691 for tocdocname in self .env .files_to_rebuild .get (docname , set ()):
690692 if tocdocname in self .env .found_docs :
691- docnames .add (tocdocname )
692- docnames . add ( self . config . root_doc )
693+ extra .add (tocdocname )
694+ docnames |= extra
693695
694696 # sort to ensure deterministic toctree generation
695697 self .env .toctree_includes = dict (sorted (self .env .toctree_includes .items ()))
@@ -700,12 +702,21 @@ def write(
700702 with progress_message (__ ('copying assets' ), nonl = False ):
701703 self .copy_assets ()
702704
705+ self .write_documents (docnames )
706+
707+ def write_documents (self , docnames : Set [str ]) -> None :
708+ """Write all documents in *docnames*.
709+
710+ This method can be overridden if a builder does not create
711+ output files for each document.
712+ """
713+ sorted_docnames = sorted (docnames )
703714 if self .parallel_ok :
704715 # number of subprocesses is parallel-1 because the main process
705716 # is busy loading doctrees and doing write_doc_serialized()
706- self ._write_parallel (sorted ( docnames ) , nproc = self .app .parallel - 1 )
717+ self ._write_parallel (sorted_docnames , nproc = self .app .parallel - 1 )
707718 else :
708- self ._write_serial (sorted ( docnames ) )
719+ self ._write_serial (sorted_docnames )
709720
710721 def _write_serial (self , docnames : Sequence [str ]) -> None :
711722 with (
@@ -769,9 +780,9 @@ def on_chunk_done(args: list[tuple[str, nodes.document]], result: None) -> None:
769780 tasks .join ()
770781 logger .info ('' )
771782
772- def prepare_writing (self , docnames : set [str ]) -> None :
783+ def prepare_writing (self , docnames : Set [str ]) -> None :
773784 """A place where you can add logic before :meth:`write_doc` is run"""
774- raise NotImplementedError
785+ pass
775786
776787 def copy_assets (self ) -> None :
777788 """Where assets (images, static files, etc) are copied before writing"""
0 commit comments