11# Copyright (c) 2023 Intel Corporation
22# SPDX-License-Identifier: Apache-2.0
33
4- import doxmlparser
4+ import os
5+ from pathlib import Path
6+ from typing import Any
57
8+ import doxmlparser
69from docutils import nodes
710from doxmlparser .compound import DoxCompoundKind
8- from pathlib import Path
9- from sphinx .application import Sphinx
1011from sphinx .util .docutils import SphinxDirective
11- from typing import Any , Dict
12+
13+
14+ def get_group (innergroup , all_groups ):
15+ try :
16+ return [
17+ g
18+ for g in all_groups
19+ if g .get_compounddef ()[0 ].get_id () == innergroup .get_refid ()
20+ ][0 ]
21+ except IndexError as e :
22+ raise Exception (f"Unexpected group { innergroup .get_refid ()} " ) from e
23+
24+
25+ def parse_xml_dir (dir_name ):
26+ groups = []
27+ root = doxmlparser .index .parse (Path (dir_name ) / "index.xml" , True )
28+ for compound in root .get_compound ():
29+ if compound .get_kind () == DoxCompoundKind .GROUP :
30+ file_name = Path (dir_name ) / f"{ compound .get_refid ()} .xml"
31+ groups .append (doxmlparser .compound .parse (file_name , True ))
32+
33+ return groups
1234
1335
1436class ApiOverview (SphinxDirective ):
@@ -21,154 +43,121 @@ class ApiOverview(SphinxDirective):
2143
2244 Configuration options:
2345
24- api_overview_doxygen_xml_dir: Doxygen xml output directory
25- api_overview_doxygen_base_url: Doxygen base html directory
46+ api_overview_doxygen_out_dir: Doxygen output directory
2647 """
2748
2849 def run (self ):
29- return [ self .env . api_overview_table ]
50+ groups = parse_xml_dir ( self .config . api_overview_doxygen_out_dir + "/xml" )
3051
31-
32- def get_group (innergroup , all_groups ):
33- try :
34- return [
52+ toplevel = [
3553 g
36- for g in all_groups
37- if g .get_compounddef ()[0 ].get_id () == innergroup .get_refid ()
38- ][0 ]
39- except IndexError as e :
40- raise Exception (f"Unexpected group { innergroup .get_refid ()} " ) from e
41-
42-
43- def visit_group (app , group , all_groups , rows , indent = 0 ):
44- version = since = ""
45- github_uri = "https://github.com/zephyrproject-rtos/zephyr/releases/tag/"
46- cdef = group .get_compounddef ()[0 ]
54+ for g in groups
55+ if g .get_compounddef ()[0 ].get_id ()
56+ not in [
57+ i .get_refid ()
58+ for h in [j .get_compounddef ()[0 ].get_innergroup () for j in groups ]
59+ for i in h
60+ ]
61+ ]
4762
48- ssects = [
49- s for p in cdef .get_detaileddescription ().get_para () for s in p .get_simplesect ()
50- ]
51- for sect in ssects :
52- if sect .get_kind () == "since" :
53- since = sect .get_para ()[0 ].get_valueOf_ ()
54- elif sect .get_kind () == "version" :
55- version = sect .get_para ()[0 ].get_valueOf_ ()
63+ return [self .generate_table (toplevel , groups )]
5664
57- if since :
58- since_url = nodes .inline ()
59- reference = nodes .reference (text = f"v{ since .strip ()} .0" , refuri = f"{ github_uri } /v{ since .strip ()} .0" )
60- reference .attributes ["internal" ] = True
61- since_url += reference
62- else :
63- since_url = nodes .Text ("" )
65+ def generate_table (self , toplevel , groups ):
66+ table = nodes .table ()
67+ tgroup = nodes .tgroup ()
6468
65- url_base = Path (app .config .api_overview_doxygen_base_url )
66- url = url_base / f"{ cdef .get_id ()} .html"
69+ thead = nodes .thead ()
70+ thead_row = nodes .row ()
71+ for header_name in ["API" , "Version" , "Available in Zephyr Since" ]:
72+ colspec = nodes .colspec ()
73+ tgroup += colspec
6774
68- title = cdef .get_title ()
75+ entry = nodes .entry ()
76+ entry += nodes .Text (header_name )
77+ thead_row += entry
78+ thead += thead_row
79+ tgroup += thead
6980
70- row_node = nodes .row ()
81+ rows = []
82+ tbody = nodes .tbody ()
83+ for t in toplevel :
84+ self .visit_group (t , groups , rows )
85+ tbody .extend (rows )
86+ tgroup += tbody
7187
72- # Next entry will contain the spacer and the link with API name
73- entry = nodes .entry ()
74- span = nodes .Text ("" .join (["\U000000A0 " ] * indent ))
75- entry += span
88+ table += tgroup
7689
77- # API name with link
78- inline = nodes .inline ()
79- reference = nodes .reference (text = title , refuri = str (url ))
80- reference .attributes ["internal" ] = True
81- inline += reference
82- entry += inline
83- row_node += entry
90+ return table
8491
85- version_node = nodes .Text (version )
86- # Finally, add version and since
87- for cell in [version_node , since_url ]:
88- entry = nodes .entry ()
89- entry += cell
90- row_node += entry
91- rows .append (row_node )
92+ def visit_group (self , group , all_groups , rows , indent = 0 ):
93+ version = since = ""
94+ github_uri = "https://github.com/zephyrproject-rtos/zephyr/releases/tag/"
95+ cdef = group .get_compounddef ()[0 ]
9296
93- for innergroup in cdef .get_innergroup ():
94- visit_group (
95- app , get_group (innergroup , all_groups ), all_groups , rows , indent + 6
97+ ssects = [
98+ s for p in cdef .get_detaileddescription ().get_para () for s in p .get_simplesect ()
99+ ]
100+ for sect in ssects :
101+ if sect .get_kind () == "since" :
102+ since = sect .get_para ()[0 ].get_valueOf_ ()
103+ elif sect .get_kind () == "version" :
104+ version = sect .get_para ()[0 ].get_valueOf_ ()
105+
106+ if since :
107+ since_url = nodes .inline ()
108+ reference = nodes .reference (
109+ text = f"v{ since .strip ()} .0" , refuri = f"{ github_uri } /v{ since .strip ()} .0"
110+ )
111+ reference .attributes ["internal" ] = True
112+ since_url += reference
113+ else :
114+ since_url = nodes .Text ("" )
115+
116+ url_base = Path (self .config .api_overview_doxygen_out_dir + "/html" )
117+ abs_url = url_base / f"{ cdef .get_id ()} .html"
118+ doc_dir = os .path .dirname (self .get_source_info ()[0 ])
119+ doc_dest = os .path .join (
120+ self .env .app .outdir ,
121+ os .path .relpath (doc_dir , self .env .app .srcdir ),
96122 )
123+ url = os .path .relpath (abs_url , doc_dest )
97124
125+ title = cdef .get_title ()
98126
99- def parse_xml_dir (dir_name ):
100- groups = []
101- root = doxmlparser .index .parse (Path (dir_name ) / "index.xml" , True )
102- for compound in root .get_compound ():
103- if compound .get_kind () == DoxCompoundKind .GROUP :
104- file_name = Path (dir_name ) / f"{ compound .get_refid ()} .xml"
105- groups .append (doxmlparser .compound .parse (file_name , True ))
106-
107- return groups
127+ row_node = nodes .row ()
108128
129+ # Next entry will contain the spacer and the link with API name
130+ entry = nodes .entry ()
131+ span = nodes .Text ("" .join (["\U000000A0 " ] * indent ))
132+ entry += span
109133
110- def generate_table (app , toplevel , groups ):
111- table = nodes .table ()
112- tgroup = nodes .tgroup ()
134+ # API name with link
135+ inline = nodes .inline ()
136+ reference = nodes .reference (text = title , refuri = str (url ))
137+ reference .attributes ["internal" ] = True
138+ inline += reference
139+ entry += inline
140+ row_node += entry
113141
114- thead = nodes .thead ()
115- thead_row = nodes .row ()
116- for header_name in ["API" , "Version" , "Available in Zephyr Since" ]:
117- colspec = nodes .colspec ()
118- tgroup += colspec
142+ version_node = nodes .Text (version )
143+ # Finally, add version and since
144+ for cell in [version_node , since_url ]:
145+ entry = nodes .entry ()
146+ entry += cell
147+ row_node += entry
148+ rows .append (row_node )
119149
120- entry = nodes .entry ()
121- entry += nodes .Text (header_name )
122- thead_row += entry
123- thead += thead_row
124- tgroup += thead
125-
126- rows = []
127- tbody = nodes .tbody ()
128- for t in toplevel :
129- visit_group (app , t , groups , rows )
130- tbody .extend (rows )
131- tgroup += tbody
132-
133- table += tgroup
134-
135- return table
136-
137-
138- def sync_contents (app : Sphinx ) -> None :
139- if app .config .doxyrunner_outdir :
140- doxygen_out_dir = Path (app .config .doxyrunner_outdir )
141- else :
142- doxygen_out_dir = Path (app .outdir ) / "_doxygen"
143-
144- if not app .env .doxygen_input_changed :
145- return
146-
147- doxygen_xml_dir = doxygen_out_dir / "xml"
148- groups = parse_xml_dir (doxygen_xml_dir )
149-
150- toplevel = [
151- g
152- for g in groups
153- if g .get_compounddef ()[0 ].get_id ()
154- not in [
155- i .get_refid ()
156- for h in [j .get_compounddef ()[0 ].get_innergroup () for j in groups ]
157- for i in h
158- ]
159- ]
160-
161- app .builder .env .api_overview_table = generate_table (app , toplevel , groups )
150+ for innergroup in cdef .get_innergroup ():
151+ self .visit_group (
152+ get_group (innergroup , all_groups ), all_groups , rows , indent + 6
153+ )
162154
163155
164- def setup (app ) -> Dict [str , Any ]:
165- app .add_config_value ("api_overview_doxygen_xml_dir" , "html/doxygen/xml" , "env" )
166- app .add_config_value ("api_overview_doxygen_base_url" , "../../doxygen/html" , "env" )
156+ def setup (app ) -> dict [str , Any ]:
157+ app .add_config_value ("api_overview_doxygen_out_dir" , "" , "env" )
167158
168159 app .add_directive ("api-overview-table" , ApiOverview )
169160
170- app .connect ("builder-inited" , sync_contents )
171-
172161 return {
173162 "version" : "0.1" ,
174163 "parallel_read_safe" : True ,
0 commit comments