1a33ca4ae5
PiperOrigin-RevId: 950744854 Change-Id: Ibcd9d6bd3e6ec50d5d6753b8c9516f7d31f19e5b
171 lines
5.3 KiB
Python
171 lines
5.3 KiB
Python
# Copyright 2026 DeepMind Technologies Limited
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
# ==============================================================================
|
|
"""Generates functions API for APIreference.rst."""
|
|
|
|
import re
|
|
import sys
|
|
|
|
import os
|
|
import sys
|
|
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
_REPO_ROOT = os.path.dirname(os.path.dirname(_SCRIPT_DIR))
|
|
sys.path.insert(0, _SCRIPT_DIR)
|
|
import generate_api_header
|
|
_FUNCTIONS_OVERRIDE = 'doc/APIreference/functions_override.rst'
|
|
|
|
_RST_SECTION_REGEX = re.compile(r'^\.\. (?P<section>_[A-Z].+):')
|
|
_RST_FUNCTION_REGEX = re.compile(r'^\.\. _(?P<function>mj.+):')
|
|
|
|
rst_to_section = {
|
|
'_Parseandcompile': ['Parse and compile', ''],
|
|
'_Mainsimulation': ['Main simulation', ''],
|
|
'_Support': ['Support', ''],
|
|
'_Components': ['Components', ''],
|
|
'_Subcomponents': ['Sub components', ''],
|
|
'_Raycollisions': ['Ray casting', ''],
|
|
'_Printing': ['Printing', ''],
|
|
'_Virtualfilesystem': ['Virtual file system', ''],
|
|
'_Assetcache': ['Asset cache', ''],
|
|
'_Resources': ['Resources', ''],
|
|
'_Initialization': ['Initialization', ''],
|
|
'_Errorandmemory': ['Error and memory', ''],
|
|
'_Miscellaneous': ['Miscellaneous', ''],
|
|
'_Interaction': ['Interaction', ''],
|
|
'_Visualization-api': ['Visualization', ''],
|
|
'_OpenGLrendering': ['OpenGL rendering', ''],
|
|
'_FilamentRenderingApi': ['Filament rendering', ''],
|
|
'_UIframework': ['UI framework', ''],
|
|
'_Derivatives-api': ['Derivatives', ''],
|
|
'_Signeddistancefunction': ['Signed Distance Functions', ''],
|
|
'_Plugins-api': ['Plugins', ''],
|
|
'_Thread': ['Threads', ''],
|
|
'_Standardmath': ['Standard math', ''],
|
|
'_Vectormath': ['Vector math', ''],
|
|
'_Sparsemath': ['Sparse math', ''],
|
|
'_Quaternions': ['Quaternions', ''],
|
|
'_Poses': ['Poses', ''],
|
|
'_Decompositions': ['Decompositions / Solvers', ''],
|
|
'_Attachment': ['Attachment', ''],
|
|
'_AddTreeElements': ['Tree elements', ''],
|
|
'_AddNonTreeElements': ['Non-tree elements', ''],
|
|
'_Setactuatorparameters': ['Set actuator parameters', ''],
|
|
'_AddAssets': ['Assets', ''],
|
|
'_FindAndGetUtilities': ['Find and get utilities', ''],
|
|
'_AttributeSetters': ['Attribute setters', ''],
|
|
'_AttributeGetters': ['Attribute getters', ''],
|
|
'_SpecUtilities': ['Spec utilities', ''],
|
|
'_ElementInitialization': ['Element initialization', ''],
|
|
'_ElementCasting': ['Element casting', ''],
|
|
}
|
|
|
|
|
|
def generate() -> str:
|
|
"""Generates functions.rst."""
|
|
rst_str = ''
|
|
api = generate_api_header.read_headers()
|
|
|
|
filepath = os.path.join(_REPO_ROOT, _FUNCTIONS_OVERRIDE)
|
|
with open(filepath, 'r', encoding='utf-8') as file:
|
|
current_section = None
|
|
current_function = None
|
|
for line in file:
|
|
|
|
# Try matching a section.
|
|
match = _RST_SECTION_REGEX.search(line)
|
|
if match is not None:
|
|
current_section = match.group('section')
|
|
if current_section in rst_to_section:
|
|
current_function = None
|
|
else:
|
|
current_section = None
|
|
continue
|
|
|
|
# Try matching a function
|
|
match = _RST_FUNCTION_REGEX.search(line)
|
|
if match is not None:
|
|
current_function = match.group('function')
|
|
if current_function in api:
|
|
api[current_function].doc = ''
|
|
current_section = None
|
|
else:
|
|
current_function = None
|
|
continue
|
|
|
|
# Update section doc.
|
|
if current_section is not None:
|
|
rst_to_section[current_section][1] += line
|
|
|
|
# Override doc.
|
|
if current_function is not None:
|
|
api[current_function].doc += line
|
|
|
|
# Check that all function sections from the headers are mapped.
|
|
mapped_sections = {v[0] for v in rst_to_section.values()}
|
|
for token, defn in api.items():
|
|
if defn.c_type == 'FUNCTION' and defn.section not in mapped_sections:
|
|
raise ValueError(
|
|
f'Function {token!r} is in unmapped section {defn.section!r}. '
|
|
f'Add an entry to rst_to_section in generate_functions.py.'
|
|
)
|
|
|
|
# Write out RST file.
|
|
rst_str += ("""
|
|
..
|
|
AUTOGENERATED: DO NOT EDIT MANUALLY
|
|
|
|
|
|
""".lstrip())
|
|
|
|
for section in rst_to_section:
|
|
section_title = rst_to_section[section][0]
|
|
rst_str += (
|
|
f"""
|
|
.. {section}:
|
|
|
|
{section_title}
|
|
{'^'*len(section_title)}
|
|
{rst_to_section[section][1]}""".lstrip())
|
|
|
|
for token in api:
|
|
if api[token].c_type != 'FUNCTION' or api[token].section != section_title:
|
|
continue
|
|
|
|
doc = api[token].doc.strip()
|
|
doc = doc.replace(' ', '`` ``')
|
|
|
|
rst_str += (f"""
|
|
.. _{token}:
|
|
|
|
`{token} <#{token}>`__
|
|
{'~'*(2*len(token)+8)}
|
|
|
|
.. mujoco-include:: {token}
|
|
|
|
{doc}
|
|
|
|
""".lstrip())
|
|
return rst_str
|
|
|
|
|
|
def main() -> None:
|
|
if len(sys.argv) > 1:
|
|
sys.exit('Too many command-line arguments.')
|
|
|
|
sys.stdout.buffer.write(generate().encode('utf-8'))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|