1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Docs: Restore Doxygen macro descriptions

This commit is contained in:
Tom Poole 2025-09-23 22:26:43 +01:00
parent 84e180b82c
commit f226d2e038
3 changed files with 250 additions and 188 deletions

View file

@ -819,7 +819,7 @@ SHOW_USED_FILES = NO
# (if specified). # (if specified).
# The default value is: YES. # The default value is: YES.
SHOW_FILES = NO SHOW_FILES = YES
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
# page. This will remove the Namespaces entry from the Quick Index and from the # page. This will remove the Namespaces entry from the Quick Index and from the

View file

@ -1,19 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<doxygenlayout version="1.0"> <doxygenlayout version="2.0">
<!-- Generated by doxygen 1.9.8 --> <!-- Generated by doxygen 1.14.0 -->
<!-- Navigation index tabs for HTML output --> <!-- Navigation index tabs for HTML output -->
<navindex> <navindex>
<tab type="mainpage" visible="yes" title="Modules"/> <tab type="mainpage" visible="yes" title="Modules"/>
<tab type="pages" visible="no" title="" intro=""/>
<tab type="topics" visible="no" title="" intro=""/> <tab type="topics" visible="no" title="" intro=""/>
<tab type="modules" visible="no" title="" intro=""> <tab type="modules" visible="no" title="" intro="">
<tab type="modulelist" visible="no" title="" intro=""/> <tab type="modulelist" visible="yes" title="" intro=""/>
<tab type="modulemembers" visible="no" title="" intro=""/> <tab type="modulemembers" visible="yes" title="" intro=""/>
</tab> </tab>
<tab type="namespaces" visible="no" title="Namespaces"> <tab type="namespaces" visible="no" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/> <tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/> <tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab> </tab>
<tab type="concepts" visible="yes" title="Concepts"> <tab type="concepts" visible="no" title="">
</tab> </tab>
<tab type="interfaces" visible="no" title=""> <tab type="interfaces" visible="no" title="">
<tab type="interfacelist" visible="yes" title="" intro=""/> <tab type="interfacelist" visible="yes" title="" intro=""/>
@ -26,7 +27,7 @@
<tab type="hierarchy" visible="yes" title="" intro=""/> <tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/> <tab type="classmembers" visible="yes" title="" intro=""/>
</tab> </tab>
<tab type="classindex" visible="yes" title="Alphabetical"/> <tab type="classindex" visible="$ALPHABETICAL_INDEX" title="All Classes"/>
<tab type="structs" visible="no" title=""> <tab type="structs" visible="no" title="">
<tab type="structlist" visible="yes" title="" intro=""/> <tab type="structlist" visible="yes" title="" intro=""/>
<tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/> <tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
@ -46,56 +47,57 @@
<!-- Layout definition for a class page --> <!-- Layout definition for a class page -->
<class> <class>
<detaileddescription title=""/> <briefdescription visible="no"/>
<detaileddescription visible="yes" title=""/>
<includes visible="$SHOW_HEADERFILE"/> <includes visible="$SHOW_HEADERFILE"/>
<inheritancegraph visible="$CLASS_GRAPH"/> <inheritancegraph visible="yes"/>
<collaborationgraph visible="yes"/> <collaborationgraph visible="yes"/>
<memberdecl> <memberdecl>
<nestedclasses visible="yes" title=""/> <nestedclasses visible="yes" title=""/>
<publictypes title=""/> <publictypes visible="yes" title=""/>
<services title=""/> <services visible="yes" title=""/>
<interfaces title=""/> <interfaces visible="yes" title=""/>
<publicslots title=""/> <publicslots visible="yes" title=""/>
<signals title=""/> <signals visible="yes" title=""/>
<publicmethods title=""/> <publicmethods visible="yes" title=""/>
<publicstaticmethods title=""/> <publicstaticmethods visible="yes" title=""/>
<publicattributes title=""/> <publicattributes visible="yes" title=""/>
<publicstaticattributes title=""/> <publicstaticattributes visible="yes" title=""/>
<protectedtypes title=""/> <protectedtypes visible="yes" title=""/>
<protectedslots title=""/> <protectedslots visible="yes" title=""/>
<protectedmethods title=""/> <protectedmethods visible="yes" title=""/>
<protectedstaticmethods title=""/> <protectedstaticmethods visible="yes" title=""/>
<protectedattributes title=""/> <protectedattributes visible="yes" title=""/>
<protectedstaticattributes title=""/> <protectedstaticattributes visible="yes" title=""/>
<packagetypes title=""/> <packagetypes visible="yes" title=""/>
<packagemethods title=""/> <packagemethods visible="yes" title=""/>
<packagestaticmethods title=""/> <packagestaticmethods visible="yes" title=""/>
<packageattributes title=""/> <packageattributes visible="yes" title=""/>
<packagestaticattributes title=""/> <packagestaticattributes visible="yes" title=""/>
<properties title=""/> <properties visible="yes" title=""/>
<events title=""/> <events visible="yes" title=""/>
<privatetypes title=""/> <privatetypes visible="yes" title=""/>
<privateslots title=""/> <privateslots visible="yes" title=""/>
<privatemethods title=""/> <privatemethods visible="yes" title=""/>
<privatestaticmethods title=""/> <privatestaticmethods visible="yes" title=""/>
<privateattributes title=""/> <privateattributes visible="yes" title=""/>
<privatestaticattributes title=""/> <privatestaticattributes visible="yes" title=""/>
<friends title=""/> <friends visible="yes" title=""/>
<related title="" subtitle=""/> <related visible="yes" title="" subtitle=""/>
<membergroups visible="yes"/> <membergroups visible="yes"/>
</memberdecl> </memberdecl>
<memberdef> <memberdef>
<inlineclasses title=""/> <inlineclasses visible="yes" title=""/>
<typedefs title=""/> <typedefs visible="yes" title=""/>
<enums title="Member Enums"/> <enums visible="yes" title="Member Enums"/>
<services title=""/> <services visible="yes" title=""/>
<interfaces title=""/> <interfaces visible="yes" title=""/>
<constructors title="Constructors and Destructors"/> <constructors visible="yes" title="Constructors and Destructors"/>
<functions title="Member Functions"/> <functions visible="yes" title="Member Functions"/>
<related title=""/> <related visible="yes" title=""/>
<variables title=""/> <variables visible="yes" title=""/>
<properties title=""/> <properties visible="yes" title=""/>
<events title=""/> <events visible="yes" title=""/>
</memberdef> </memberdef>
<allmemberslink visible="yes"/> <allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/> <usedfiles visible="$SHOW_USED_FILES"/>
@ -113,23 +115,25 @@
<concepts visible="yes" title=""/> <concepts visible="yes" title=""/>
<structs visible="yes" title=""/> <structs visible="yes" title=""/>
<exceptions visible="yes" title=""/> <exceptions visible="yes" title=""/>
<typedefs title=""/> <typedefs visible="yes" title=""/>
<sequences title=""/> <sequences visible="yes" title=""/>
<dictionaries title=""/> <dictionaries visible="yes" title=""/>
<enums title=""/> <enums visible="yes" title=""/>
<functions title=""/> <functions visible="yes" title=""/>
<variables title=""/> <variables visible="yes" title=""/>
<properties visible="yes" title=""/>
<membergroups visible="yes"/> <membergroups visible="yes"/>
</memberdecl> </memberdecl>
<detaileddescription title=""/> <detaileddescription visible="yes" title=""/>
<memberdef> <memberdef>
<inlineclasses title=""/> <inlineclasses visible="yes" title=""/>
<typedefs title=""/> <typedefs visible="yes" title=""/>
<sequences title=""/> <sequences visible="yes" title=""/>
<dictionaries title=""/> <dictionaries visible="yes" title=""/>
<enums title=""/> <enums visible="yes" title=""/>
<functions title=""/> <functions visible="yes" title=""/>
<variables title=""/> <variables visible="yes" title=""/>
<properties visible="yes" title=""/>
</memberdef> </memberdef>
<authorsection visible="yes"/> <authorsection visible="yes"/>
</namespace> </namespace>
@ -139,7 +143,7 @@
<briefdescription visible="yes"/> <briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/> <includes visible="$SHOW_HEADERFILE"/>
<definition visible="yes" title=""/> <definition visible="yes" title=""/>
<detaileddescription title=""/> <detaileddescription visible="yes" title=""/>
<authorsection visible="yes"/> <authorsection visible="yes"/>
</concept> </concept>
@ -158,25 +162,27 @@
<namespaces visible="yes" title=""/> <namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/> <concepts visible="yes" title=""/>
<constantgroups visible="yes" title=""/> <constantgroups visible="yes" title=""/>
<defines title=""/> <defines visible="yes" title=""/>
<typedefs title=""/> <typedefs visible="yes" title=""/>
<sequences title=""/> <sequences visible="yes" title=""/>
<dictionaries title=""/> <dictionaries visible="yes" title=""/>
<enums title=""/> <enums visible="yes" title=""/>
<functions title=""/> <functions visible="yes" title=""/>
<variables title=""/> <variables visible="yes" title=""/>
<properties visible="yes" title=""/>
<membergroups visible="yes"/> <membergroups visible="yes"/>
</memberdecl> </memberdecl>
<detaileddescription title=""/> <detaileddescription visible="yes" title=""/>
<memberdef> <memberdef>
<inlineclasses title=""/> <inlineclasses visible="yes" title=""/>
<defines title=""/> <defines visible="yes" title=""/>
<typedefs title=""/> <typedefs visible="yes" title=""/>
<sequences title=""/> <sequences visible="yes" title=""/>
<dictionaries title=""/> <dictionaries visible="yes" title=""/>
<enums title=""/> <enums visible="yes" title=""/>
<functions title=""/> <functions visible="yes" title=""/>
<variables title=""/> <variables visible="yes" title=""/>
<properties visible="yes" title=""/>
</memberdef> </memberdef>
<authorsection/> <authorsection/>
</file> </file>
@ -193,42 +199,42 @@
<namespaces visible="yes" title=""/> <namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/> <concepts visible="yes" title=""/>
<classes visible="yes" title=""/> <classes visible="yes" title=""/>
<defines title=""/> <defines visible="yes" title=""/>
<typedefs title=""/> <typedefs visible="yes" title=""/>
<sequences title=""/> <sequences visible="yes" title=""/>
<dictionaries title=""/> <dictionaries visible="yes" title=""/>
<enums title=""/> <enums visible="yes" title=""/>
<enumvalues title=""/> <enumvalues visible="yes" title=""/>
<functions title=""/> <functions visible="yes" title=""/>
<variables title=""/> <variables visible="yes" title=""/>
<signals title=""/> <signals visible="yes" title=""/>
<publicslots title=""/> <publicslots visible="yes" title=""/>
<protectedslots title=""/> <protectedslots visible="yes" title=""/>
<privateslots title=""/> <privateslots visible="yes" title=""/>
<events title=""/> <events visible="yes" title=""/>
<properties title=""/> <properties visible="yes" title=""/>
<friends title=""/> <friends visible="yes" title=""/>
<membergroups visible="yes"/> <membergroups visible="yes"/>
</memberdecl> </memberdecl>
<detaileddescription title=""/> <detaileddescription visible="yes" title=""/>
<memberdef> <memberdef>
<pagedocs/> <pagedocs/>
<inlineclasses title=""/> <inlineclasses visible="yes" title=""/>
<defines title=""/> <defines visible="yes" title=""/>
<typedefs title=""/> <typedefs visible="yes" title=""/>
<sequences title=""/> <sequences visible="yes" title=""/>
<dictionaries title=""/> <dictionaries visible="yes" title=""/>
<enums title=""/> <enums visible="yes" title=""/>
<enumvalues title=""/> <enumvalues visible="yes" title=""/>
<functions title=""/> <functions visible="yes" title=""/>
<variables title=""/> <variables visible="yes" title=""/>
<signals title=""/> <signals visible="yes" title=""/>
<publicslots title=""/> <publicslots visible="yes" title=""/>
<protectedslots title=""/> <protectedslots visible="yes" title=""/>
<privateslots title=""/> <privateslots visible="yes" title=""/>
<events title=""/> <events visible="yes" title=""/>
<properties title=""/> <properties visible="yes" title=""/>
<friends title=""/> <friends visible="yes" title=""/>
</memberdef> </memberdef>
<authorsection visible="yes"/> <authorsection visible="yes"/>
</group> </group>
@ -240,13 +246,13 @@
<memberdecl> <memberdecl>
<concepts visible="yes" title=""/> <concepts visible="yes" title=""/>
<classes visible="yes" title=""/> <classes visible="yes" title=""/>
<enums title=""/> <enums visible="yes" title=""/>
<typedefs title=""/> <typedefs visible="yes" title=""/>
<functions title=""/> <functions visible="yes" title=""/>
<variables title=""/> <variables visible="yes" title=""/>
<membergroups title=""/> <membergroups visible="yes" title=""/>
</memberdecl> </memberdecl>
<detaileddescription title=""/> <detaileddescription visible="yes" title=""/>
<memberdecl> <memberdecl>
<files visible="yes"/> <files visible="yes"/>
</memberdecl> </memberdecl>
@ -260,6 +266,6 @@
<dirs visible="yes"/> <dirs visible="yes"/>
<files visible="yes"/> <files visible="yes"/>
</memberdecl> </memberdecl>
<detaileddescription title=""/> <detaileddescription visible="yes" title=""/>
</directory> </directory>
</doxygenlayout> </doxygenlayout>

View file

@ -1,20 +1,14 @@
from pathlib import Path
import argparse import argparse
import os import os
import subprocess import subprocess
from pathlib import Path, PurePath
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element from xml.etree.ElementTree import Element
import re
def get_modules_directory_xml_element(xml_dir: Path) -> Element: MODULES_DIR = Path('../../modules')
for entry in os.listdir('xml'): assert MODULES_DIR.is_dir()
if not entry.startswith('dir_'): ABS_MODULES_DIR = MODULES_DIR.resolve()
continue
root = ET.parse(xml_dir / entry).getroot()
location = root.find('.//location')
path = PurePath(location.attrib['file'])
referenced_dir_path_parts = path.parts
if referenced_dir_path_parts[-1] == 'modules':
return root, path
def get_module_description(module_header: Path) -> str: def get_module_description(module_header: Path) -> str:
with open(module_header, 'r') as f: with open(module_header, 'r') as f:
@ -24,52 +18,107 @@ def get_module_description(module_header: Path) -> str:
if line.startswith('description:'): if line.startswith('description:'):
return line.removeprefix('description:').strip() return line.removeprefix('description:').strip()
def get_doxygen_items_recursive(xml_file_ref: str, items: list): def createContentDict() -> dict:
element = ET.parse(f'{Path('xml') / xml_file_ref}.xml').getroot() return {
item_type = element.find('compounddef').attrib['kind'] 'classes/structs': {},
if item_type == 'dir': 'functions': {},
name = element.find('.//compoundname').text 'typedefs': {},
new_item = { 'macros': {},
'name': name, 'enums': {},
'classes': [], 'dirs': {}
'dirs': []
} }
items.append(new_item)
items = new_item['classes']
for class_reference in element.findall('.//innerclass'):
html_filename = f'{class_reference.attrib['refid']}.html'
if (Path('doc') / html_filename).exists():
items.append({
'name': class_reference.text.removeprefix('juce::'),
'url': f'./{html_filename}',
})
for file_reference in element.findall('.//innerfile'):
get_doxygen_items_recursive(file_reference.attrib['refid'], items)
for dir_reference in element.findall('.//innerdir'):
get_doxygen_items_recursive(dir_reference.attrib['refid'], new_item['dirs'])
def remove_empty_doxygen_items_recursive(parent: dict): def getContentObjectFromPath(root_object: dict, location: str) -> dict:
parent['dirs'] = list(filter(lambda x: x['classes'] or x['dirs'], parent['dirs'])) path_in_modules = Path(location).relative_to(ABS_MODULES_DIR)
for d in parent['dirs']: path_components = path_in_modules.parts
remove_empty_doxygen_items_recursive(d) contents = root_object[path_components[0]]
for path_component in path_components[1:-1]:
if not (path_component in contents['dirs']):
contents['dirs'][path_component] = createContentDict()
contents = contents['dirs'][path_component]
return contents
def parseNamespaceXml(root_object, filename):
element = ET.parse(f'xml/{filename}').getroot()
for class_reference in element.findall('.//innerclass'):
refid = class_reference.attrib['refid']
html_filename = f'{refid}.html'
if not Path(f'doc/{html_filename}').is_file():
continue
xml_path = Path(f'xml/{refid}.xml')
if not xml_path.is_file():
continue
class_element = ET.parse(xml_path).getroot()
location = class_element.find('.//location').attrib['file']
contents = getContentObjectFromPath(root_object, location)
contents['classes/structs'][class_reference.text.removeprefix('juce::')] = {
'url': f'./{html_filename}'
}
namespace_def_id = element.find('.//compounddef').attrib['id']
namespace_id_prefix = f'{namespace_def_id}_1'
for kind, contents_key in (('function', 'functions'), ('typedef', 'typedefs'), ('enum', 'enums')):
for reference in element.findall(f".//memberdef[@kind='{kind}']"):
desc = reference.find('briefdescription')
if (len(desc) == 0) and (not desc.text.strip()):
continue
ref_id = reference.attrib['id']
if not ref_id.startswith(namespace_id_prefix):
continue
name = reference.find('.//qualifiedname').text.removeprefix('juce::')
if re.search(r'operator[+\-*/=!<>]*$', name):
continue
anchor = ref_id.removeprefix(namespace_id_prefix)
location = reference.find('.//location').attrib['file']
contents = getContentObjectFromPath(modules, location)
contents[contents_key][name] = {
'url': f'./{namespace_def_id}.html#{anchor}'
}
def parseFileXml(root_object, filename):
element = ET.parse(f'xml/{filename}').getroot()
compounddef_id = element.find('compounddef').attrib['id']
def_reference_link_prefix = compounddef_id + '_1'
for def_reference in element.findall(".//memberdef[@kind='define']"):
def_id = def_reference.attrib['id']
if not def_id.startswith(def_reference_link_prefix):
continue
def_desc = def_reference.find('briefdescription')
if (len(def_desc) == 0) and (not def_desc.text.strip()):
continue
html_filename = f'{compounddef_id}.html'
if not (Path('doc') / html_filename).exists():
continue
location = def_reference.find('.//location').attrib['file']
contents = getContentObjectFromPath(root_object, location)
anchor = def_id.removeprefix(def_reference_link_prefix)
contents['macros'][def_reference.find('name').text] = {
'url': f'./{html_filename}#{anchor}',
}
def write_module_html_recursive(parent: Element, data: dict): def write_module_html_recursive(parent: Element, data: dict):
if data['classes']: for section_key, section_contents in data.items():
class_list = ET.SubElement(parent, 'ul', {'class': 'juce-module-class-list'}) if section_key in ('dirs', 'description'):
for c in data['classes']: continue
item = ET.SubElement(class_list, 'li', {'class': 'juce-module-class-item'}) if not section_contents:
ET.SubElement(item, 'a', {'href': c['url'], 'class': 'juce-module-class-link'}).text = c['name'] continue
#ET.SubElement(parent, 'span', {'class': 'juce-module-contents-title'}).text = section_key
section_list = ET.SubElement(parent, 'ul', {'class': 'juce-module-class-list'})
for section_item_key, section_item_contents in sorted(section_contents.items()):
item = ET.SubElement(section_list, 'li', {'class': 'juce-module-class-item'})
ET.SubElement(item, 'a', {'href': section_item_contents['url'], 'class': 'juce-module-class-link'}).text = section_item_key
if data['dirs']: if data['dirs']:
dir_table = ET.SubElement(parent, 'table', {'class': 'juce-module-dir-table'}) dir_table = ET.SubElement(parent, 'table', {'class': 'juce-module-dir-table'})
for d in data['dirs']: for dir_key, dir_contents in sorted(data['dirs'].items()):
row = ET.SubElement(dir_table, 'tr', {'class': 'juce-module-dir-row'}) row = ET.SubElement(dir_table, 'tr', {'class': 'juce-module-dir-row'})
ET.SubElement(row, 'td', {'class': 'juce-module-dir-name'}).text = d['name'] ET.SubElement(row, 'td', {'class': 'juce-module-dir-name'}).text = dir_key
content = ET.SubElement(row, 'td', {'class': 'juce-module-dir-contents'}) content = ET.SubElement(row, 'td', {'class': 'juce-module-dir-contents'})
write_module_html_recursive(content, d) write_module_html_recursive(content, dir_contents)
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--sitemap-url', help='a sitemap URL for Doxygen') parser.add_argument('--sitemap-url', help='The Doxygen sitemap configuration variable')
args = parser.parse_args() args = parser.parse_args()
if args.sitemap_url: if args.sitemap_url:
@ -78,18 +127,25 @@ if args.sitemap_url:
print('--- Running Doxygen') print('--- Running Doxygen')
subprocess.run("doxygen", shell=True, check=True) subprocess.run("doxygen", shell=True, check=True)
print('--- Parsing module headers')
modules = {}
for module_name in os.listdir(MODULES_DIR):
module_dir = MODULES_DIR / module_name
if not module_dir.is_dir():
continue
module_header = module_dir / f'{module_name}.h'
if not module_header.is_file():
continue
modules[module_name] = createContentDict()
modules[module_name]['description'] = get_module_description(module_header)
print('--- Parsing Doxygen XML') print('--- Parsing Doxygen XML')
xml_dir = Path('xml') for xml_filename in os.listdir('xml'):
root, root_path = get_modules_directory_xml_element(xml_dir) if xml_filename.startswith('namespacejuce'):
modules = [] parseNamespaceXml(modules, xml_filename)
module_descriptions = {} elif xml_filename.startswith('juce__'):
for dir_reference in root.findall('.//innerdir'): # There are no macros in the namespace XML so we need to get them separately
module_name = dir_reference.text parseFileXml(modules, xml_filename)
module_path = root_path / module_name
module_header_path = module_path / f'{module_name}.h'
module_descriptions[module_name] = get_module_description(module_header_path)
get_doxygen_items_recursive(dir_reference.attrib['refid'], modules)
remove_empty_doxygen_items_recursive(modules[-1])
print('--- Creating JUCE Module HTML') print('--- Creating JUCE Module HTML')
@ -99,24 +155,24 @@ ET.SubElement(module_icon, 'path', {'d': 'M 28.0000 26.6406 L 50.0783 14.1016 C
main_div = ET.Element('div', {'class': 'juce-modules-continer'}) main_div = ET.Element('div', {'class': 'juce-modules-continer'})
toc_div = ET.SubElement(main_div, 'div', {'class': 'juce-module-toc-container'}) toc_div = ET.SubElement(main_div, 'div', {'class': 'juce-module-toc-container'})
ET.SubElement(toc_div, 'p', {'class': 'juce-module-toc-desc'}).text = "Here are the JUCE modules with some brief descriptions:" ET.SubElement(toc_div, 'p', {'class': 'juce-module-toc-desc'}).text = "Here is a summary of the JUCE modules. To search absolutely everything please use the search bar."
toc_table = ET.SubElement(toc_div, 'table', {'class': 'juce-module-toc-table'}) toc_table = ET.SubElement(toc_div, 'table', {'class': 'juce-module-toc-table'})
for module in modules: for key, contents in sorted(modules.items()):
toc_row = ET.SubElement(toc_table, 'tr', {'class': 'juce-module-toc-row'}) toc_row = ET.SubElement(toc_table, 'tr', {'class': 'juce-module-toc-row'})
module_toc_name = ET.SubElement(toc_row, 'td', {'class': 'juce-module-toc-module-name'}) module_toc_name = ET.SubElement(toc_row, 'td', {'class': 'juce-module-toc-module-name'})
ET.SubElement(module_toc_name, 'a', {'href': f'#{module['name']}', 'class': 'juce-module-toc-module-name-link'}).text = module['name'] ET.SubElement(module_toc_name, 'a', {'href': f'#{key}', 'class': 'juce-module-toc-module-name-link'}).text = key
ET.SubElement(toc_row, 'td', {'class': 'juce-module-toc-module-decs'}).text = module_descriptions[module['name']] ET.SubElement(toc_row, 'td', {'class': 'juce-module-toc-module-decs'}).text = contents['description']
ET.SubElement(main_div, 'div', {'class': 'juce-module-toc-divider'}) ET.SubElement(main_div, 'div', {'class': 'juce-module-toc-divider'})
for module in modules: for key, contents in sorted(modules.items()):
module_div = ET.SubElement(main_div, 'div', {'class': 'juce-module'}) module_div = ET.SubElement(main_div, 'div', {'class': 'juce-module'})
module_header_div = ET.SubElement(module_div, 'div', {'class': 'juce-module-header'}) module_header_div = ET.SubElement(module_div, 'div', {'class': 'juce-module-header'})
module_title_div = ET.SubElement(module_header_div, 'div', {'class': 'juce-module-title'}) module_title_div = ET.SubElement(module_header_div, 'div', {'class': 'juce-module-title'})
module_title_div.append(module_icon) module_title_div.append(module_icon)
ET.SubElement(module_title_div, 'span', {'id': module['name'], 'class': 'juce-module-name'}).text = module['name'] ET.SubElement(module_title_div, 'span', {'id': key, 'class': 'juce-module-name'}).text = key
ET.SubElement(module_header_div, 'span', {'class': 'juce-module-desc'}).text = module_descriptions[module['name']] ET.SubElement(module_header_div, 'span', {'class': 'juce-module-desc'}).text = contents['description']
module_contents_div = ET.SubElement(module_div, 'div', {'class': 'juce-module-contents'}) module_contents_div = ET.SubElement(module_div, 'div', {'class': 'juce-module-contents'})
write_module_html_recursive(module_contents_div, module) write_module_html_recursive(module_contents_div, contents)
print('--- Updating Doxygen HTML') print('--- Updating Doxygen HTML')
html = ET.tostring(main_div, encoding='utf-8', method='html').decode('utf-8') html = ET.tostring(main_div, encoding='utf-8', method='html').decode('utf-8')