diff --git a/src/docc/cli.py b/src/docc/cli.py index cd43489..6526f72 100644 --- a/src/docc/cli.py +++ b/src/docc/cli.py @@ -30,6 +30,7 @@ from .context import Context from .document import Document, Node, OutputNode, Visit, Visitor from .performance import measure +from .plugins.listing import ListingSource from .settings import Settings from .source import Source @@ -157,6 +158,9 @@ def main(command_line: Sequence[str] | None = None) -> None: rmtree(output_root, ignore_errors=True) with measure("Wrote outputs (%.4f s)", level=logging.INFO): + non_listing_outputs: Set[Path] = set() + resolved: Dict[Source, Path] = {} + for source, context_ in contexts.items(): document = context_[Document] extension = document.extension() @@ -172,8 +176,24 @@ def main(command_line: Sequence[str] | None = None) -> None: output_path = Path( output_path.with_suffix(output_path.suffix + extension) ) + resolved[source] = output_path + if not isinstance(source, ListingSource): + non_listing_outputs.add(output_path) + + for source, context_ in contexts.items(): + output_path = resolved.get(source) + if output_path is None: + continue + if ( + isinstance(source, ListingSource) + and output_path in non_listing_outputs + ): + # Another source already writes here (e.g. an + # ``__init__.py`` rendered as the package's index page). + continue output_path.parent.mkdir(parents=True, exist_ok=True) + document = context_[Document] with open(output_path, "w", encoding="utf-8") as destination: document.root.visit(_OutputVisitor(context_, destination)) diff --git a/src/docc/plugins/python/cst.py b/src/docc/plugins/python/cst.py index 7f7ee20..d44c722 100644 --- a/src/docc/plugins/python/cst.py +++ b/src/docc/plugins/python/cst.py @@ -156,11 +156,21 @@ def relative_path(self) -> Optional[PurePath]: """ return self._relative_path + @property + def is_package_init(self) -> bool: + """ + Whether this source is an ``__init__.py`` rendered as the package + directory's index page. + """ + return self.absolute_path.name == "__init__.py" + @property def output_path(self) -> PurePath: """ Where to put the output derived from this source. """ + if self.is_package_init: + return self._relative_path.parent / "index" return self._relative_path def open(self) -> TextIO: