@@ -139,22 +139,23 @@ def source_read_handler(app, docname, source):
139139 source [0 ] = source [0 ].replace (placeholder , replacement )
140140
141141
142- # -- Markdown builder: register missing admonition handlers ----------------
142+ # -- Markdown builder: register missing node handlers ------- ----------------
143143
144144def _patch_markdown_translator (app ):
145- """Add handlers for admonition types not supported by sphinx-markdown-builder."""
145+ """Add handlers for node types not supported by sphinx-markdown-builder."""
146146 try :
147147 from sphinx_markdown_builder .translator import MarkdownTranslator
148148 except ImportError :
149149 return
150+ from docutils import nodes as _nodes
150151
151- def _make_visit (label ):
152+ def _make_admonition_visit (label ):
152153 def visit (self , node ):
153154 self ._push_box (label )
154155 return visit
155156
156- def _make_depart (self , node ):
157- pass
157+ def _admonition_depart (self , node ):
158+ self . _pop_context ( node )
158159
159160 for node_type , label in [
160161 ("tip" , "TIP" ),
@@ -165,8 +166,66 @@ def _make_depart(self, node):
165166 visit_name = f"visit_{ node_type } "
166167 depart_name = f"depart_{ node_type } "
167168 if not hasattr (MarkdownTranslator , visit_name ):
168- setattr (MarkdownTranslator , visit_name , _make_visit (label ))
169- setattr (MarkdownTranslator , depart_name , _make_depart )
169+ setattr (MarkdownTranslator , visit_name , _make_admonition_visit (label ))
170+ setattr (MarkdownTranslator , depart_name , _admonition_depart )
171+
172+ # productionlist: render grammar rules as a code block
173+ def visit_productionlist (self , node ):
174+ self ._push_status (escape_text = False )
175+ self .add ("```" , prefix_eol = 2 , suffix_eol = 1 )
176+ for production in node .children :
177+ token_name = production .get ("tokenname" , "" )
178+ rule_text = production .astext ()
179+ if token_name :
180+ self .add (f"{ token_name } ::= { rule_text } " , prefix_eol = 1 )
181+ else :
182+ self .add (f" { rule_text } " , prefix_eol = 1 )
183+ self .add ("```" , prefix_eol = 1 , suffix_eol = 2 )
184+ self ._pop_status ()
185+ raise _nodes .SkipNode
186+
187+ if not hasattr (MarkdownTranslator , "visit_productionlist" ):
188+ MarkdownTranslator .visit_productionlist = visit_productionlist
189+ MarkdownTranslator .depart_productionlist = lambda self , node : None
190+
191+ # caption: render as bold text
192+ def visit_caption (self , node ):
193+ self .add ("**" , prefix_eol = 2 )
194+
195+ def depart_caption (self , node ):
196+ self .add ("**" , suffix_eol = 2 )
197+
198+ if not hasattr (MarkdownTranslator , "visit_caption" ):
199+ MarkdownTranslator .visit_caption = visit_caption
200+ MarkdownTranslator .depart_caption = depart_caption
201+
202+ # hlist / hlistcol: pass through to children (they contain bullet_lists)
203+ def _pass (self , node ):
204+ pass
205+
206+ if not hasattr (MarkdownTranslator , "visit_hlist" ):
207+ MarkdownTranslator .visit_hlist = _pass
208+ MarkdownTranslator .depart_hlist = _pass
209+
210+ if not hasattr (MarkdownTranslator , "visit_hlistcol" ):
211+ MarkdownTranslator .visit_hlistcol = _pass
212+ MarkdownTranslator .depart_hlistcol = _pass
213+
214+ # label (non-footnote, e.g. tab labels from sphinx_inline_tabs): skip
215+ from sphinx_markdown_builder .contexts import FootNoteContext as _FootNoteContext
216+
217+ def visit_label (self , node ):
218+ if isinstance (self .ctx , _FootNoteContext ):
219+ self .footnote_ctx .visit_label ()
220+ else :
221+ raise _nodes .SkipNode
222+
223+ def depart_label (self , node ):
224+ if isinstance (self .ctx , _FootNoteContext ):
225+ self .footnote_ctx .depart_label ()
226+
227+ MarkdownTranslator .visit_label = visit_label
228+ MarkdownTranslator .depart_label = depart_label
170229
171230
172231def _builder_inited_handler (app ):
0 commit comments