Skip to content

Commit

Permalink
Support msg and srv entries
Browse files Browse the repository at this point in the history
  • Loading branch information
rkent committed Mar 27, 2024
1 parent c833d93 commit 5dc0885
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 5 deletions.
27 changes: 22 additions & 5 deletions rosdoc2/verbs/build/builders/sphinx_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from ..builder import Builder
from ..collect_inventory_files import collect_inventory_files
from ..create_format_map_from_package import create_format_map_from_package
from ..generate_interface_docs import generate_interface_docs

logger = logging.getLogger('rosdoc2')

Expand All @@ -32,7 +33,7 @@ def esc_backslash(path):
return path.replace('\\', '\\\\') if path else path


def generate_package_toc_entry(*, build_context) -> str:
def generate_package_toc_entry(*, build_context, interface_counts) -> str:
"""Construct a table of content (toc) entry for the package being processed."""
build_type = build_context.build_type
always_run_doxygen = build_context.always_run_doxygen
Expand All @@ -48,7 +49,10 @@ def generate_package_toc_entry(*, build_context) -> str:
toc_entry += toc_entry_py
if build_type in ['ament_cmake', 'cmake'] or always_run_doxygen:
toc_entry += toc_entry_cpp

if interface_counts['msg'] > 0:
toc_entry += toc_entry_msg
if interface_counts['srv'] > 0:
toc_entry += toc_entry_srv
return toc_entry


Expand Down Expand Up @@ -451,7 +455,17 @@ def build(self, *, doc_build_folder, output_staging_directory):
'Note: no sourcedir provided by the user and no Sphinx sourcedir was found '
'in the standard locations, therefore using a default Sphinx configuration.')
sourcedir = os.path.join(doc_build_folder, 'default_sphinx_project')
self.generate_default_project_into_directory(sourcedir, package_src_directory)

# Generate rst documents for interfaces
interface_counts = generate_interface_docs(
package_xml_directory,
self.build_context.package.name,
os.path.join(sourcedir, 'generated')
)
logger.info(f'interface_counts: {interface_counts}')

self.generate_default_project_into_directory(
sourcedir, package_src_directory, interface_counts)

# Collect intersphinx mapping extensions from discovered inventory files.
inventory_files = \
Expand Down Expand Up @@ -568,7 +582,8 @@ def locate_sphinx_sourcedir_from_standard_locations(self):
return option
return None

def generate_default_project_into_directory(self, directory, package_src_directory):
def generate_default_project_into_directory(
self, directory, package_src_directory, interface_counts):
"""Generate the default project configuration files."""
os.makedirs(directory, exist_ok=True)

Expand All @@ -590,7 +605,9 @@ def generate_default_project_into_directory(self, directory, package_src_directo
template_variables.update({
'root_title': root_title,
'root_title_underline': '=' * len(root_title),
'package_toc_entry': generate_package_toc_entry(build_context=self.build_context)
'package_toc_entry': generate_package_toc_entry(
build_context=self.build_context,
interface_counts=interface_counts)
})

with open(os.path.join(directory, 'index.rst'), 'w+') as f:
Expand Down
102 changes: 102 additions & 0 deletions rosdoc2/verbs/build/generate_interface_docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Copyright 2022 Open Source Robotics Foundation, Inc.
#
# 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.


"""Generate rst files for messages and services."""

import fnmatch
import os

# from jinja2 import Template

iface_fm_rst = """\
{iface_name}
{name_underline}
This is a ROS {type_name} definition.
**Source**
.. literalinclude:: {relative_path}
"""

toc_fm_rst = """\
{title}
{title_underline}
.. toctree::
:maxdepth: 1
:glob:
{type_ext}/*
"""


def _find_files_with_extension(path, ext):
# Partly adapted from https://github.com/ros-infrastructure/rosdoc_lite
matches = []
for root, _, filenames in os.walk(path):
for filename in fnmatch.filter(filenames, f'*.{ext}'):
matches.append((os.path.splitext(filename)[0], os.path.join(root, filename)))
return matches


def generate_interface_docs(path: str, package: str, output_dir: str):
"""
Generate rst files from messages and services.
:param str path: Directory path to start search for files
:param str package: Name of containing package
:param str output_dir: Directory path to write output
:return: {'msg':msg_count, 'srv':srv_count} count of files written
:rtype: dict(str, int)
"""
counts = {}
for type_info in (('msg', 'message'), ('srv', 'service')):
count = 0
(type_ext, type_name) = type_info
interfaces = _find_files_with_extension(path, type_ext)
output_dir_ex = os.path.join(output_dir, type_ext)
title = type_name.capitalize() + ' Definitions'
for interface in interfaces:
(iface_name, iface_path) = interface
relative_path = os.path.relpath(iface_path, start=output_dir_ex)
template_vars = {
'iface_name': iface_name,
'name_underline': '=' * len(iface_name),
'type_name': type_name,
'package': package,
'type_ext': type_ext,
'relative_path': relative_path,
'title': title,
'title_underline': '=' * len(title)
}
iface_rst = iface_fm_rst.format_map(template_vars)

if not os.path.exists(output_dir_ex):
os.makedirs(output_dir_ex)
output_path = os.path.join(output_dir_ex, f'{iface_name}.rst')
with open(output_path, 'w') as f:
f.write(iface_rst)
count += 1
if count > 0:
# generate a toc entry rst file for this type
toc_rst = toc_fm_rst.format_map(template_vars)
toc_name = type_name + '_definitions.rst'
toc_path = os.path.join(output_dir, toc_name)
with open(toc_path, 'w') as f:
f.write(toc_rst)
counts[type_ext] = count
return counts

0 comments on commit 5dc0885

Please sign in to comment.