44SPDX-License-Identifier: Apache-2.0
55"""
66
7- import os
8- from typing import Any , Dict
9-
107import concurrent .futures
8+ import os
9+ from typing import Any
1110
11+ import doxmlparser
1212from docutils import nodes
13-
13+ from docutils .parsers .rst import directives
14+ from doxmlparser .compound import DoxCompoundKind , DoxMemberKind
1415from sphinx import addnodes
1516from sphinx .application import Sphinx
17+ from sphinx .domains .c import CXRefRole
1618from sphinx .transforms .post_transforms import SphinxPostTransform
1719from sphinx .util import logging
1820from sphinx .util .docutils import SphinxDirective
19- from sphinx .domains .c import CXRefRole
20-
21- import doxmlparser
22- from doxmlparser .compound import DoxCompoundKind , DoxMemberKind
2321
2422logger = logging .getLogger (__name__ )
2523
@@ -37,6 +35,9 @@ class DoxygenGroupDirective(SphinxDirective):
3735 has_content = False
3836 required_arguments = 1
3937 optional_arguments = 0
38+ option_spec = {
39+ "project" : directives .unchanged ,
40+ }
4041
4142 def run (self ):
4243
@@ -51,6 +52,7 @@ def run(self):
5152 reftype = "group" ,
5253 reftarget = self .arguments [0 ],
5354 refwarn = True ,
55+ project = self .options .get ("project" )
5456 )
5557 group_xref += nodes .Text (self .arguments [0 ])
5658 title_signode += group_xref
@@ -76,28 +78,40 @@ def run(self, **kwargs: Any) -> None:
7678 if reftype in ("member" , "data" ):
7779 reftype = "var"
7880
79- entry = self .app .env .doxybridge_cache .get (reftype )
80- if not entry :
81- continue
81+ found_name = None
82+ found_id = None
83+ for name in self .app .config .doxybridge_projects :
84+ entry = self .app .env .doxybridge_cache [name ].get (reftype )
85+ if not entry :
86+ continue
8287
83- reftarget = node .get ("reftarget" ).replace ("." , "::" ).rstrip ("()" )
84- id = entry .get (reftarget )
85- if not id :
86- if reftype == "func" :
87- # macros are sometimes referenced as functions, so try that
88- id = self .app .env .doxybridge_cache .get ("macro" ).get (reftarget )
89- if not id :
88+ reftarget = node .get ("reftarget" ).replace ("." , "::" ).rstrip ("()" )
89+ id = entry .get (reftarget )
90+ if not id :
91+ if reftype == "func" :
92+ # macros are sometimes referenced as functions, so try that
93+ id = self .app .env .doxybridge_cache [name ].get ("macro" ).get (reftarget )
94+ if not id :
95+ continue
96+ else :
9097 continue
91- else :
92- continue
98+
99+ found_name = name
100+ found_id = id
101+ break
102+
103+ if not found_name or not found_id :
104+ continue
93105
94106 if reftype in ("struct" , "union" , "group" ):
95107 doxygen_target = f"{ id } .html"
96108 else :
97- split = id .split ("_" )
109+ split = found_id .split ("_" )
98110 doxygen_target = f"{ '_' .join (split [:- 1 ])} .html#{ split [- 1 ][1 :]} "
99111
100- doxygen_target = str (self .app .config .doxybridge_dir ) + "/html/" + doxygen_target
112+ doxygen_target = (
113+ str (self .app .config .doxybridge_projects [found_name ]) + "/html/" + doxygen_target
114+ )
101115
102116 doc_dir = os .path .dirname (self .document .get ("source" ))
103117 doc_dest = os .path .join (
@@ -112,7 +126,7 @@ def run(self, **kwargs: Any) -> None:
112126
113127 if reftype == "group" :
114128 refnode ["classes" ].append ("doxygroup" )
115- title = self .app .env .doxybridge_group_titles .get (reftarget , "group" )
129+ title = self .app .env .doxybridge_group_titles [ found_name ] .get (reftarget , "group" )
116130 refnode [0 ] = nodes .Text (title )
117131
118132 node .replace_self ([refnode ])
@@ -154,7 +168,7 @@ def parse_sections(compounddef):
154168 return cache
155169
156170
157- def parse_compound (inDirName , baseName ) -> Dict :
171+ def parse_compound (inDirName , baseName ) -> dict :
158172 rootObj = doxmlparser .compound .parse (inDirName + "/" + baseName + ".xml" , True )
159173 cache = {}
160174 group_titles = {}
@@ -181,7 +195,7 @@ def parse_compound(inDirName, baseName) -> Dict:
181195 return cache , group_titles
182196
183197
184- def parse_index (app : Sphinx , inDirName ):
198+ def parse_index (app : Sphinx , name , inDirName ):
185199 rootObj = doxmlparser .index .parse (inDirName + "/index.xml" , True )
186200 compounds = rootObj .get_compound ()
187201
@@ -193,33 +207,40 @@ def parse_index(app: Sphinx, inDirName):
193207 for future in concurrent .futures .as_completed (futures ):
194208 cache , group_titles = future .result ()
195209 for kind , data in cache .items ():
196- app .env .doxybridge_cache .setdefault (kind , {}).update (data )
197- app .env .doxybridge_group_titles .update (group_titles )
210+ app .env .doxybridge_cache [ name ] .setdefault (kind , {}).update (data )
211+ app .env .doxybridge_group_titles [ name ] .update (group_titles )
198212
199213
200214def doxygen_parse (app : Sphinx ) -> None :
201- if not app .env .doxygen_input_changed :
202- return
203-
204- app .env .doxybridge_cache = {
205- "macro" : {},
206- "var" : {},
207- "type" : {},
208- "enum" : {},
209- "enumerator" : {},
210- "func" : {},
211- "union" : {},
212- "struct" : {},
213- "group" : {},
214- }
215+ if not hasattr (app .env , "doxybridge_cache" ):
216+ app .env .doxybridge_cache = dict ()
217+
218+ if not hasattr (app .env , "doxybridge_group_titles" ):
219+ app .env .doxybridge_group_titles = dict ()
220+
221+ for name , path in app .config .doxybridge_projects .items ():
222+ if name in app .env .doxygen_input_changed and not app .env .doxygen_input_changed [name ]:
223+ return
224+
225+ app .env .doxybridge_cache [name ] = {
226+ "macro" : {},
227+ "var" : {},
228+ "type" : {},
229+ "enum" : {},
230+ "enumerator" : {},
231+ "func" : {},
232+ "union" : {},
233+ "struct" : {},
234+ "group" : {},
235+ }
215236
216- app .env .doxybridge_group_titles = {}
237+ app .env .doxybridge_group_titles [ name ] = dict ()
217238
218- parse_index (app , str (app . config . doxybridge_dir / "xml" ))
239+ parse_index (app , name , str (path / "xml" ))
219240
220241
221- def setup (app : Sphinx ) -> Dict [str , Any ]:
222- app .add_config_value ("doxybridge_dir " , None , "env" )
242+ def setup (app : Sphinx ) -> dict [str , Any ]:
243+ app .add_config_value ("doxybridge_projects " , None , "env" )
223244
224245 app .add_directive ("doxygengroup" , DoxygenGroupDirective )
225246
0 commit comments