@ -1,16 +1,38 @@
@@ -1,16 +1,38 @@
# Copyright (c) 2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
from pathlib import Path
from typing import Any
import doxmlparser
from docutils import nodes
from doxmlparser . compound import DoxCompoundKind
from sphinx . application import Sphinx
from sphinx . util . docutils import SphinxDirective
def get_group ( innergroup , all_groups ) :
try :
return [
g
for g in all_groups
if g . get_compounddef ( ) [ 0 ] . get_id ( ) == innergroup . get_refid ( )
] [ 0 ]
except IndexError as e :
raise Exception ( f " Unexpected group { innergroup . get_refid ( ) } " ) from e
def parse_xml_dir ( dir_name ) :
groups = [ ]
root = doxmlparser . index . parse ( Path ( dir_name ) / " index.xml " , True )
for compound in root . get_compound ( ) :
if compound . get_kind ( ) == DoxCompoundKind . GROUP :
file_name = Path ( dir_name ) / f " { compound . get_refid ( ) } .xml "
groups . append ( doxmlparser . compound . parse ( file_name , True ) )
return groups
class ApiOverview ( SphinxDirective ) :
"""
This is a Zephyr directive to generate a table containing an overview
@ -21,156 +43,121 @@ class ApiOverview(SphinxDirective):
@@ -21,156 +43,121 @@ class ApiOverview(SphinxDirective):
Configuration options :
api_overview_doxygen_xml_dir : Doxygen xml output directory
api_overview_doxygen_base_url : Doxygen base html directory
api_overview_doxygen_out_dir : Doxygen output directory
"""
def run ( self ) :
return [ self . env . api_overview_table ]
groups = parse_xml_dir ( self . config . api_overview_doxygen_out_dir + " /xml " )
def get_group ( innergroup , all_groups ) :
try :
return [
toplevel = [
g
for g in all_groups
if g . get_compounddef ( ) [ 0 ] . get_id ( ) == innergroup . get_refid ( )
] [ 0 ]
except IndexError as e :
raise Exception ( f " Unexpected group { innergroup . get_refid ( ) } " ) from e
for g in groups
if g . get_compounddef ( ) [ 0 ] . get_id ( )
not in [
i . get_refid ( )
for h in [ j . get_compounddef ( ) [ 0 ] . get_innergroup ( ) for j in groups ]
for i in h
]
]
return [ self . generate_table ( toplevel , groups ) ]
def visit_group ( app , group , all_groups , rows , indent = 0 ) :
version = since = " "
github_uri = " https://github.com/zephyrproject-rtos/zephyr/releases/tag/ "
cdef = group . get_compounddef ( ) [ 0 ]
ssects = [
s for p in cdef . get_detaileddescription ( ) . get_para ( ) for s in p . get_simplesect ( )
]
for sect in ssects :
if sect . get_kind ( ) == " since " :
since = sect . get_para ( ) [ 0 ] . get_valueOf_ ( )
elif sect . get_kind ( ) == " version " :
version = sect . get_para ( ) [ 0 ] . get_valueOf_ ( )
if since :
since_url = nodes . inline ( )
reference = nodes . reference (
text = f " v { since . strip ( ) } .0 " , refuri = f " { github_uri } /v { since . strip ( ) } .0 "
)
reference . attributes [ " internal " ] = True
since_url + = reference
else :
since_url = nodes . Text ( " " )
def generate_table ( self , toplevel , groups ) :
table = nodes . table ( )
tgroup = nodes . tgroup ( )
url_base = Path ( app . config . api_overview_doxygen_base_url )
url = url_base / f " { cdef . get_id ( ) } .html "
thead = nodes . thead ( )
thead_row = nodes . row ( )
for header_name in [ " API " , " Version " , " Available in Zephyr Since " ] :
colspec = nodes . colspec ( )
tgroup + = colspec
title = cdef . get_title ( )
entry = nodes . entry ( )
entry + = nodes . Text ( header_name )
thead_row + = entry
thead + = thead_row
tgroup + = thead
row_node = nodes . row ( )
rows = [ ]
tbody = nodes . tbody ( )
for t in toplevel :
self . visit_group ( t , groups , rows )
tbody . extend ( rows )
tgroup + = tbody
# Next entry will contain the spacer and the link with API name
entry = nodes . entry ( )
span = nodes . Text ( " " . join ( [ " \U000000A0 " ] * indent ) )
entry + = span
table + = tgroup
# API name with link
inline = nodes . inline ( )
reference = nodes . reference ( text = title , refuri = str ( url ) )
reference . attributes [ " internal " ] = True
inline + = reference
entry + = inline
row_node + = entry
return table
version_node = nodes . Text ( version )
# Finally, add version and since
for cell in [ version_node , since_url ] :
entry = nodes . entry ( )
entry + = cell
row_node + = entry
rows . append ( row_node )
def visit_group ( self , group , all_groups , rows , indent = 0 ) :
version = since = " "
github_uri = " https://github.com/zephyrproject-rtos/zephyr/releases/tag/ "
cdef = group . get_compounddef ( ) [ 0 ]
for innergroup in cdef . get_innergroup ( ) :
visit_group (
app , get_group ( innergroup , all_groups ) , all_groups , rows , indent + 6
ssects = [
s for p in cdef . get_detaileddescription ( ) . get_para ( ) for s in p . get_simplesect ( )
]
for sect in ssects :
if sect . get_kind ( ) == " since " :
since = sect . get_para ( ) [ 0 ] . get_valueOf_ ( )
elif sect . get_kind ( ) == " version " :
version = sect . get_para ( ) [ 0 ] . get_valueOf_ ( )
if since :
since_url = nodes . inline ( )
reference = nodes . reference (
text = f " v { since . strip ( ) } .0 " , refuri = f " { github_uri } /v { since . strip ( ) } .0 "
)
reference . attributes [ " internal " ] = True
since_url + = reference
else :
since_url = nodes . Text ( " " )
url_base = Path ( self . config . api_overview_doxygen_out_dir + " /html " )
abs_url = url_base / f " { cdef . get_id ( ) } .html "
doc_dir = os . path . dirname ( self . get_source_info ( ) [ 0 ] )
doc_dest = os . path . join (
self . env . app . outdir ,
os . path . relpath ( doc_dir , self . env . app . srcdir ) ,
)
url = os . path . relpath ( abs_url , doc_dest )
title = cdef . get_title ( )
def parse_xml_dir ( dir_name ) :
groups = [ ]
root = doxmlparser . index . parse ( Path ( dir_name ) / " index.xml " , True )
for compound in root . get_compound ( ) :
if compound . get_kind ( ) == DoxCompoundKind . GROUP :
file_name = Path ( dir_name ) / f " { compound . get_refid ( ) } .xml "
groups . append ( doxmlparser . compound . parse ( file_name , True ) )
return groups
row_node = nodes . row ( )
def generate_table ( app , toplevel , groups ) :
table = nodes . table ( )
tgroup = nodes . tgroup ( )
# Next entry will contain the spacer and the link with API name
entry = nodes . entry ( )
span = nodes . Text ( " " . join ( [ " \U000000A0 " ] * indent ) )
entry + = span
thead = nodes . thead ( )
thead_row = nodes . row ( )
for header_name in [ " API " , " Version " , " Available in Zephyr Since " ] :
colspec = nodes . colspec ( )
tgroup + = colspec
# API name with link
inline = nodes . inline ( )
reference = nodes . reference ( text = title , refuri = str ( url ) )
reference . attributes [ " internal " ] = True
inline + = reference
entry + = inline
row_node + = entry
entry = nodes . entry ( )
entry + = nodes . Text ( header_name )
thead_row + = entry
thead + = thead_row
tgroup + = thead
rows = [ ]
tbody = nodes . tbody ( )
for t in toplevel :
visit_group ( app , t , groups , rows )
tbody . extend ( rows )
tgroup + = tbody
table + = tgroup
return table
def sync_contents ( app : Sphinx ) - > None :
if app . config . doxyrunner_outdir :
doxygen_out_dir = Path ( app . config . doxyrunner_outdir )
else :
doxygen_out_dir = Path ( app . outdir ) / " _doxygen "
if not app . env . doxygen_input_changed :
return
doxygen_xml_dir = doxygen_out_dir / " xml "
groups = parse_xml_dir ( doxygen_xml_dir )
toplevel = [
g
for g in groups
if g . get_compounddef ( ) [ 0 ] . get_id ( )
not in [
i . get_refid ( )
for h in [ j . get_compounddef ( ) [ 0 ] . get_innergroup ( ) for j in groups ]
for i in h
]
]
version_node = nodes . Text ( version )
# Finally, add version and since
for cell in [ version_node , since_url ] :
entry = nodes . entry ( )
entry + = cell
row_node + = entry
rows . append ( row_node )
app . builder . env . api_overview_table = generate_table ( app , toplevel , groups )
for innergroup in cdef . get_innergroup ( ) :
self . visit_group (
get_group ( innergroup , all_groups ) , all_groups , rows , indent + 6
)
def setup ( app ) - > dict [ str , Any ] :
app . add_config_value ( " api_overview_doxygen_xml_dir " , " html/doxygen/xml " , " env " )
app . add_config_value ( " api_overview_doxygen_base_url " , " ../../doxygen/html " , " env " )
app . add_config_value ( " api_overview_doxygen_out_dir " , " " , " env " )
app . add_directive ( " api-overview-table " , ApiOverview )
app . connect ( " builder-inited " , sync_contents )
return {
" version " : " 0.1 " ,
" parallel_read_safe " : True ,