1
1
# Copyright (c) 2023 Intel Corporation
2
2
# SPDX-License-Identifier: Apache-2.0
3
3
4
+ import os
4
5
from pathlib import Path
5
6
from typing import Any
6
7
7
8
import doxmlparser
8
9
from docutils import nodes
9
10
from doxmlparser .compound import DoxCompoundKind
10
- from sphinx .application import Sphinx
11
11
from sphinx .util .docutils import SphinxDirective
12
12
13
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
34
+
35
+
14
36
class ApiOverview (SphinxDirective ):
15
37
"""
16
38
This is a Zephyr directive to generate a table containing an overview
@@ -21,156 +43,121 @@ class ApiOverview(SphinxDirective):
21
43
22
44
Configuration options:
23
45
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
26
47
"""
27
48
28
49
def run (self ):
29
- return [self .env .api_overview_table ]
30
-
50
+ groups = parse_xml_dir (self .config .api_overview_doxygen_out_dir + "/xml" )
31
51
32
- def get_group (innergroup , all_groups ):
33
- try :
34
- return [
52
+ toplevel = [
35
53
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
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
+ ]
41
62
63
+ return [self .generate_table (toplevel , groups )]
42
64
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 ]
47
-
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_ ()
56
-
57
- if since :
58
- since_url = nodes .inline ()
59
- reference = nodes .reference (
60
- text = f"v{ since .strip ()} .0" , refuri = f"{ github_uri } /v{ since .strip ()} .0"
61
- )
62
- reference .attributes ["internal" ] = True
63
- since_url += reference
64
- else :
65
- since_url = nodes .Text ("" )
65
+ def generate_table (self , toplevel , groups ):
66
+ table = nodes .table ()
67
+ tgroup = nodes .tgroup ()
66
68
67
- url_base = Path (app .config .api_overview_doxygen_base_url )
68
- 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
69
74
70
- 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
71
80
72
- 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
73
87
74
- # Next entry will contain the spacer and the link with API name
75
- entry = nodes .entry ()
76
- span = nodes .Text ("" .join (["\U000000A0 " ] * indent ))
77
- entry += span
88
+ table += tgroup
78
89
79
- # API name with link
80
- inline = nodes .inline ()
81
- reference = nodes .reference (text = title , refuri = str (url ))
82
- reference .attributes ["internal" ] = True
83
- inline += reference
84
- entry += inline
85
- row_node += entry
90
+ return table
86
91
87
- version_node = nodes .Text (version )
88
- # Finally, add version and since
89
- for cell in [version_node , since_url ]:
90
- entry = nodes .entry ()
91
- entry += cell
92
- row_node += entry
93
- 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 ]
94
96
95
- for innergroup in cdef .get_innergroup ():
96
- visit_group (
97
- 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 ),
98
122
)
123
+ url = os .path .relpath (abs_url , doc_dest )
99
124
125
+ title = cdef .get_title ()
100
126
101
- def parse_xml_dir (dir_name ):
102
- groups = []
103
- root = doxmlparser .index .parse (Path (dir_name ) / "index.xml" , True )
104
- for compound in root .get_compound ():
105
- if compound .get_kind () == DoxCompoundKind .GROUP :
106
- file_name = Path (dir_name ) / f"{ compound .get_refid ()} .xml"
107
- groups .append (doxmlparser .compound .parse (file_name , True ))
108
-
109
- return groups
110
-
127
+ row_node = nodes .row ()
111
128
112
- def generate_table (app , toplevel , groups ):
113
- table = nodes .table ()
114
- tgroup = nodes .tgroup ()
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
115
133
116
- thead = nodes .thead ()
117
- thead_row = nodes .row ()
118
- for header_name in ["API" , "Version" , "Available in Zephyr Since" ]:
119
- colspec = nodes .colspec ()
120
- tgroup += colspec
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
121
141
122
- entry = nodes .entry ()
123
- entry += nodes .Text (header_name )
124
- thead_row += entry
125
- thead += thead_row
126
- tgroup += thead
127
-
128
- rows = []
129
- tbody = nodes .tbody ()
130
- for t in toplevel :
131
- visit_group (app , t , groups , rows )
132
- tbody .extend (rows )
133
- tgroup += tbody
134
-
135
- table += tgroup
136
-
137
- return table
138
-
139
-
140
- def sync_contents (app : Sphinx ) -> None :
141
- if app .config .doxyrunner_outdir :
142
- doxygen_out_dir = Path (app .config .doxyrunner_outdir )
143
- else :
144
- doxygen_out_dir = Path (app .outdir ) / "_doxygen"
145
-
146
- if not app .env .doxygen_input_changed :
147
- return
148
-
149
- doxygen_xml_dir = doxygen_out_dir / "xml"
150
- groups = parse_xml_dir (doxygen_xml_dir )
151
-
152
- toplevel = [
153
- g
154
- for g in groups
155
- if g .get_compounddef ()[0 ].get_id ()
156
- not in [
157
- i .get_refid ()
158
- for h in [j .get_compounddef ()[0 ].get_innergroup () for j in groups ]
159
- for i in h
160
- ]
161
- ]
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 )
162
149
163
- 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
+ )
164
154
165
155
166
156
def setup (app ) -> dict [str , Any ]:
167
- app .add_config_value ("api_overview_doxygen_xml_dir" , "html/doxygen/xml" , "env" )
168
- app .add_config_value ("api_overview_doxygen_base_url" , "../../doxygen/html" , "env" )
157
+ app .add_config_value ("api_overview_doxygen_out_dir" , "" , "env" )
169
158
170
159
app .add_directive ("api-overview-table" , ApiOverview )
171
160
172
- app .connect ("builder-inited" , sync_contents )
173
-
174
161
return {
175
162
"version" : "0.1" ,
176
163
"parallel_read_safe" : True ,
0 commit comments