Skip to content

Commit f5d8454

Browse files
authored
👌 IMPROVE: Add ensure_index_file on build completion (#21)
Ensures that an index.html exists for HTML builds.
1 parent 58ba771 commit f5d8454

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

sphinx_external_toc/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def setup(app: "Sphinx") -> dict:
1515
InsertToctrees,
1616
TableofContents,
1717
add_changed_toctrees,
18+
ensure_index_file,
1819
parse_toc_to_env,
1920
)
2021

@@ -29,5 +30,6 @@ def setup(app: "Sphinx") -> dict:
2930
app.connect("env-get-outdated", add_changed_toctrees)
3031
app.add_directive("tableofcontents", TableofContents)
3132
app.add_transform(InsertToctrees)
33+
app.connect("build-finished", ensure_index_file)
3234

3335
return {"version": __version__, "parallel_read_safe": True}

sphinx_external_toc/events.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ def create_warning(
4646
return None
4747

4848

49+
def remove_suffix(docname: str, suffixes: List[str]) -> str:
50+
"""Remove any suffixes."""
51+
for suffix in suffixes:
52+
if docname.endswith(suffix):
53+
return docname[: -len(suffix)]
54+
return docname
55+
56+
4957
def parse_toc_to_env(app: Sphinx, config: Config) -> None:
5058
"""Parse the external toc file and store it in the Sphinx environment.
5159
@@ -192,7 +200,6 @@ def insert_toctrees(app: Sphinx, doctree: nodes.document) -> None:
192200
node.replace_self([])
193201

194202
# initial variables
195-
suffixes = app.config.source_suffix
196203
all_docnames = app.env.found_docs.copy()
197204
all_docnames.remove(app.env.docname) # remove current document
198205
excluded = Matcher(app.config.exclude_patterns)
@@ -235,11 +242,7 @@ def insert_toctrees(app: Sphinx, doctree: nodes.document) -> None:
235242
docname = str(entry)
236243
title = child_doc_item.title
237244

238-
# remove any suffixes
239-
for suffix in suffixes:
240-
if docname.endswith(suffix):
241-
docname = docname[: -len(suffix)]
242-
break
245+
docname = remove_suffix(docname, app.config.source_suffix)
243246

244247
if docname not in app.env.found_docs:
245248
if excluded(app.env.doc2path(docname, None)):
@@ -293,3 +296,26 @@ class InsertToctrees(SphinxTransform):
293296

294297
def apply(self, **kwargs: Any) -> None:
295298
insert_toctrees(self.app, self.document)
299+
300+
301+
def ensure_index_file(app: Sphinx, exception: Optional[Exception]) -> None:
302+
"""Ensure that an index.html exists for HTML builds.
303+
304+
This is required when navigating to the site, without specifying a page,
305+
which will then route to index.html by default.
306+
"""
307+
index_path = Path(app.outdir).joinpath("index.html")
308+
if (
309+
exception is not None
310+
or "html" not in app.builder.format
311+
or app.config.master_doc == "index"
312+
# TODO rewrite the redirect if master_doc has changed since last build
313+
or index_path.exists()
314+
):
315+
return
316+
root_name = remove_suffix(app.config.master_doc, app.config.source_suffix)
317+
# TODO the other way to do this would be to
318+
# simply copy the contents of the root file? (this method was taken from jupyter-book)
319+
redirect_text = f'<meta http-equiv="Refresh" content="0; url={root_name}.html" />\n'
320+
index_path.write_text(redirect_text, encoding="utf8")
321+
logger.info("[etoc] missing index.html written as redirect to '%s.html'", root_name)

0 commit comments

Comments
 (0)