55import html
66import os
77from os import path
8- from typing import Any
9-
10- from docutils import nodes
11- from docutils .nodes import Element , Node , document
8+ from pathlib import Path
9+ from typing import TYPE_CHECKING , Any
1210
1311import sphinx
12+ from docutils import nodes
1413from sphinx import addnodes
15- from sphinx .application import Sphinx
1614from sphinx .builders .html import StandaloneHTMLBuilder
17- from sphinx .config import Config
1815from sphinx .environment .adapters .indexentries import IndexEntries
1916from sphinx .locale import get_translation
2017from sphinx .util import logging
2320from sphinx .util .osutil import make_filename_from_project , relpath
2421from sphinx .util .template import SphinxRenderer
2522
23+ if TYPE_CHECKING :
24+ from docutils .nodes import Element , Node , document
25+ from sphinx .application import Sphinx
26+ from sphinx .config import Config
27+
2628if sphinx .version_info [:2 ] >= (6 , 1 ):
2729 from sphinx .util .display import progress_message
2830else :
29- from sphinx .util import progress_message # type: ignore[attr-defined, no-redef]
31+ from sphinx .util import progress_message # type: ignore[no-redef]
3032
3133__version__ = '2.0.6'
3234__version_info__ = (2 , 0 , 6 )
@@ -126,8 +128,8 @@ def depart_list_item(self, node: Element) -> None:
126128
127129 def visit_reference (self , node : Element ) -> None :
128130 title = chm_htmlescape (node .astext (), True )
129- self .append (' <param name="Name" value="%s ">' % title )
130- self .append (' <param name="Local" value="%s">' % node [' refuri' ] )
131+ self .append (f ' <param name="Name" value="{ title } ">' )
132+ self .append (f ' <param name="Local" value="{ node [" refuri" ] } ">' )
131133 self .append ('</OBJECT>' )
132134 raise nodes .SkipNode
133135
@@ -170,7 +172,13 @@ def prepare_writing(self, docnames: set[str]) -> None:
170172 super ().prepare_writing (docnames )
171173 self .globalcontext ['html5_doctype' ] = False
172174
173- def update_page_context (self , pagename : str , templatename : str , ctx : dict , event_arg : str ) -> None : # NOQA
175+ def update_page_context (
176+ self ,
177+ pagename : str ,
178+ templatename : str ,
179+ ctx : dict [str , Any ],
180+ event_arg : str ,
181+ ) -> None :
174182 ctx ['encoding' ] = self .encoding
175183
176184 def handle_finish (self ) -> None :
@@ -180,14 +188,14 @@ def handle_finish(self) -> None:
180188 self .build_hhx (self .outdir , self .config .htmlhelp_basename )
181189
182190 def write_doc (self , docname : str , doctree : document ) -> None :
183- for node in doctree .traverse (nodes .reference ):
191+ for node in doctree .findall (nodes .reference ):
184192 # add ``target=_blank`` attributes to external links
185193 if node .get ('internal' ) is None and 'refuri' in node :
186194 node ['target' ] = '_blank'
187195
188196 super ().write_doc (docname , doctree )
189197
190- def render (self , name : str , context : dict ) -> str :
198+ def render (self , name : str , context : dict [ str , Any ] ) -> str :
191199 template = SphinxRenderer (template_dir )
192200 return template .render (name , context )
193201
@@ -220,40 +228,39 @@ def build_project_file(self) -> None:
220228 fn = relpath (path .join (root , fn ), self .outdir )
221229 project_files .append (fn .replace (os .sep , '\\ ' ))
222230
223- filename = path .join (self .outdir , self .config .htmlhelp_basename + '.hhp' )
224- with open (filename , 'w' , encoding = self .encoding , errors = 'xmlcharrefreplace' ) as f :
225- context = {
226- 'outname' : self .config .htmlhelp_basename ,
227- 'title' : self .config .html_title ,
228- 'version' : self .config .version ,
229- 'project' : self .config .project ,
230- 'lcid' : self .lcid ,
231- 'master_doc' : self .config .master_doc + self .out_suffix ,
232- 'files' : project_files ,
233- }
234- body = self .render ('project.hhp' , context )
235- f .write (body )
231+ context = {
232+ 'outname' : self .config .htmlhelp_basename ,
233+ 'title' : self .config .html_title ,
234+ 'version' : self .config .version ,
235+ 'project' : self .config .project ,
236+ 'lcid' : self .lcid ,
237+ 'master_doc' : self .config .master_doc + self .out_suffix ,
238+ 'files' : project_files ,
239+ }
240+ body = self .render ('project.hhp' , context )
241+ filename = Path (self .outdir , f'{ self .config .htmlhelp_basename } .hhp' )
242+ filename .write_text (body , encoding = self .encoding , errors = 'xmlcharrefreplace' )
236243
237244 @progress_message (__ ('writing TOC file' ))
238245 def build_toc_file (self ) -> None :
239246 """Create a ToC file (.hhp) on outdir."""
240- filename = path . join (self .outdir , self . config .htmlhelp_basename + '.hhc' )
241- with open ( filename , 'w' , encoding = self . encoding , errors = 'xmlcharrefreplace' ) as f :
242- toctree = self . env . get_and_resolve_doctree ( self . config . master_doc , self ,
243- prune_toctrees = False )
244- visitor = ToCTreeVisitor ( toctree )
245- matcher = NodeMatcher ( addnodes . compact_paragraph , toctree = True )
246- for node in toctree . traverse ( matcher ): # type: addnodes.compact_paragraph
247- node . walkabout ( visitor )
248-
249- context = {
250- 'body ' : visitor . astext () ,
251- 'suffix ' : self .out_suffix ,
252- 'short_title ' : self .config . html_short_title ,
253- 'master_doc' : self . config . master_doc ,
254- 'domain_indices' : self .domain_indices ,
255- }
256- f . write ( self .render ( 'project.hhc' , context ) )
247+ toctree = self . env . get_and_resolve_doctree (self .config .master_doc , self ,
248+ prune_toctrees = False )
249+ visitor = ToCTreeVisitor ( toctree )
250+ matcher = NodeMatcher ( addnodes . compact_paragraph , toctree = True )
251+ for node in toctree . findall ( matcher ):
252+ node . walkabout ( visitor )
253+
254+ context = {
255+ 'body' : visitor . astext (),
256+ 'suffix' : self . out_suffix ,
257+ 'short_title ' : self . config . html_short_title ,
258+ 'master_doc ' : self .config . master_doc ,
259+ 'domain_indices ' : self .domain_indices ,
260+ }
261+ body = self .render ( 'project.hhc' , context )
262+ filename = Path ( self . outdir , f' { self . config . htmlhelp_basename } .hhc' )
263+ filename . write_text ( body , encoding = self .encoding , errors = 'xmlcharrefreplace' )
257264
258265 def build_hhx (self , outdir : str | os .PathLike [str ], outname : str ) -> None :
259266 logger .info (__ ('writing index file...' ))
@@ -262,9 +269,13 @@ def build_hhx(self, outdir: str | os.PathLike[str], outname: str) -> None:
262269 with open (filename , 'w' , encoding = self .encoding , errors = 'xmlcharrefreplace' ) as f :
263270 f .write ('<UL>\n ' )
264271
265- def write_index (title : str , refs : list [tuple [str , str ]], subitems : list [tuple [str , list [tuple [str , str ]]]]) -> None : # NOQA
272+ def write_index (
273+ title : str ,
274+ refs : list [tuple [str , str ]],
275+ subitems : list [tuple [str , list [tuple [str , str ]]]],
276+ ) -> None :
266277 def write_param (name : str , value : str ) -> None :
267- item = ' <param name="%s " value="%s ">\n ' % ( name , value )
278+ item = f ' <param name="{ name } " value="{ value } ">\n '
268279 f .write (item )
269280 title = chm_htmlescape (title , True )
270281 f .write ('<LI> <OBJECT type="text/sitemap">\n ' )
@@ -284,9 +295,9 @@ def write_param(name: str, value: str) -> None:
284295 for subitem in subitems :
285296 write_index (subitem [0 ], subitem [1 ], [])
286297 f .write ('</UL>' )
287- for (key , group ) in index :
288- for title , (refs , subitems , key_ ) in group :
289- write_index (title , refs , subitems ) # type: ignore[arg-type]
298+ for (_group_key , group ) in index :
299+ for title , (refs , subitems , _category_key ) in group :
300+ write_index (title , refs , subitems )
290301 f .write ('</UL>\n ' )
291302
292303
0 commit comments