@@ -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+
4957def 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