1414import posixpath
1515
1616from docutils import nodes
17- from docutils .parsers .rst import directives , Directive
17+ from docutils .parsers .rst import directives
18+ from sphinx .util .docutils import SphinxDirective
19+ from sphinx .writers .html5 import HTML5Translator
1820
1921if TYPE_CHECKING :
2022 from sphinx .application import Sphinx
@@ -51,24 +53,38 @@ def ext_config_to_isso_config(key:str, value:Any) -> Tuple[str,str]:
5153 return (key , value )
5254
5355
54- class IssoNode (nodes .General , nodes .Element ):
56+ class IssoNode (nodes .General , nodes .Element ): pass
5557
56- @staticmethod
57- def visit (self , node ):
58- kwargs = {
59- 'data-isso-id' : node ['thread-id' ],
60- }
61- if node .get ('thread-title' ):
62- kwargs ['data-title' ] = node ['thread-title' ]
63- self .body .append (self .starttag (node , 'section' , '' , ** kwargs ))
58+ def html_visit_isso_node (self : HTML5Translator , node ):
59+ docname = node ['docname' ]
60+ metadata = self .builder .env .metadata [docname ]
61+
62+ # If docinfo :nocomments: is set, won’t display a comment form for a page
63+ # generated from this source file.
64+ #
65+ # See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html
66+ if 'nocomments' in metadata :
67+ raise nodes .SkipNode
6468
69+ thread_id = node .get ('thread-id' ) or \
70+ metadata .get ('isso-id' ) or \
71+ '/' + docname
72+ if not thread_id .startswith ('/' ):
73+ logger .warning (f'isso thread-id { thread_id } doesn\' t start with slash' , location = node )
74+
75+ kwargs = {
76+ 'data-isso-id' : thread_id ,
77+ }
78+ if node .get ('thread-title' ):
79+ kwargs ['data-title' ] = node ['thread-title' ]
80+ self .body .append (self .starttag (node , 'section' , '' , ** kwargs ))
6581
66- @staticmethod
67- def depart (self , _ ):
68- self .body .append ('</section>' )
6982
83+ def html_depart_isso_oode (self : HTML5Translator , _ ):
84+ self .body .append ('</section>' )
7085
71- class IssoDirective (Directive ):
86+
87+ class IssoDirective (SphinxDirective ):
7288 """Isso ".. isso::" rst directive."""
7389
7490 option_spec = {
@@ -84,16 +100,17 @@ def run(self):
84100
85101 node = IssoNode ()
86102 node ['ids' ] = ['isso-thread' ]
103+ # Save docname for later looking up :attr:`self.env.metadata`,
104+ # which is not yet available now.
105+ node ['docname' ] = self .env .docname
106+
87107 if self .options .get ('id' ):
88- thread_id = self .options .get ('id' )
89- if not thread_id .startswith ('/' ):
90- logger .warning ('isso thread-id should starts with slash' , location = node )
91- node ['thread-id' ] = thread_id
92- else :
93- node ['thread-id' ] = '/' + self .state .document .settings .env .docname
108+ node ['thread-id' ] = self .options .get ('id' )
109+
94110 if self .options .get ('title' ):
95111 node ['thread-title' ] = self .options .get ('title' )
96112 else :
113+ # TODO: support section title?
97114 title = self .state .document .next_node (nodes .title )
98115 if title :
99116 node ['thread-title' ] = title .astext ()
@@ -135,7 +152,7 @@ def setup(app:Sphinx):
135152 for cfg in CONFIG_ITEMS :
136153 app .add_config_value (cfg , None , '' )
137154 app .add_directive ('isso' , IssoDirective )
138- app .add_node (IssoNode , html = (IssoNode . visit , IssoNode . depart ))
155+ app .add_node (IssoNode , html = (html_visit_isso_node , html_depart_isso_oode ))
139156 app .connect ('html-page-context' , on_html_page_context )
140157
141158 return {'version' : __version__ }
0 commit comments