sphinx_docs_conf.py
Go to the documentation of this file.
1 # SPDX-License-Identifier: BSD-3-Clause
2 # SPDX-FileCopyrightText: Czech Technical University in Prague
3 
4 """A default conf.py file for rosdoc_lite/sphinx documentation builder.
5 
6 It provides some useful shortcuts and automatically links to ROS message definitions on docs.ros.org.
7 
8 You can try e.g. :roswiki:`cras_py_common`, :rosdep:`rosdep2_api.html`, :tf2_msgs:`TFMessage`, :class:`genpy.Message` or
9 :class:`tf2_msgs.msg.TFMessage`.
10 
11 To use this file in you project, create file `doc/conf.py` with the following content::
12 
13  import os
14  os.environ['CRAS_DOCS_COMMON_SPHINX_PACKAGE_PATH'] = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
15  from cras_docs_common.sphinx_docs_conf import *
16 
17  # Here you can customize all the variables, but leaving the rest empty is usually enough.
18 
19 """
20 
21 import os
22 import sys
23 import time
24 import catkin_pkg.package
25 
26 from os.path import abspath, dirname, join
27 
28 from docutils import nodes
29 from sphinx.ext import intersphinx
30 
31 # Set this variable to pass the path to the package root (i.e. the folder containing package.xml).
32 catkin_dir = os.getenv('CRAS_DOCS_COMMON_SPHINX_PACKAGE_PATH', dirname(dirname(abspath(__file__))))
33 catkin_package = catkin_pkg.package.parse_package(join(catkin_dir, catkin_pkg.package.PACKAGE_MANIFEST_FILENAME))
34 
35 project = catkin_package.name
36 copyright = time.strftime("%Y") + ', Czech Technical University in Prague'
37 author = ", ".join([a.name for a in catkin_package.authors])
38 version = catkin_package.version
39 release = catkin_package.version
40 
41 import catkin_sphinx
42 
43 extensions = [
44  'sphinx.ext.autodoc',
45  'sphinx.ext.intersphinx',
46  'sphinx.ext.extlinks',
47  'catkin_sphinx.ShLexer',
48  'catkin_sphinx.cmake',
49 ]
50 
51 try:
52  import m2r
53  extensions.append('m2r')
54 except ImportError:
55  pass
56 
57 master_doc = 'index'
58 autoclass_content = 'both'
59 # Allow specifying inline code only as `code` and not as ``code``
60 default_role = 'code'
61 
62 this_dir = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
63 theme_path = os.path.join(this_dir, 'sphinx-themes')
64 
65 html_theme_path = [theme_path, catkin_sphinx.get_theme_path()]
66 
67 custom_theme_path = os.getenv('CRAS_DOCS_COMMON_SPHINX_THEME_PATH', None)
68 if custom_theme_path is not None:
69  html_theme_path.insert(0, custom_theme_path)
70 
71 # Use ROS theme
72 html_theme = os.getenv('CRAS_DOCS_COMMON_SPHINX_HTML_THEME', 'cras-theme')
73 
74 ros_distro = os.getenv('ROS_DISTRO', 'latest')
75 ros_api_base = 'https://docs.ros.org/en/%s/api/'
76 ros_wiki_base = 'https://wiki.ros.org/'
77 
78 # Dynamic project title
79 rst_epilog = """
80 .. |project| replace:: {}
81 .. |description| replace:: {}
82 .. role:: raw-html(raw)
83  :format: html
84 
85 .. |wiki| replace:: :raw-html:`<a href="{}{}?distro={}">ROS wiki entry</a>`
86 """.format(project, catkin_package.description, ros_wiki_base, project, ros_distro)
87 
88 ros_api = ros_api_base % ros_distro
89 melodic_api = ros_api_base % "melodic"
90 independent_api = ros_api_base % "independent"
91 
92 extlinks = {
93  'ros': (ros_api + '%s', None),
94  'roswiki': (ros_wiki_base + '%s?distro=' + ros_distro, ''),
95  'rospy:class': (melodic_api + 'rospy/html/rospy.%s-class.html', "rospy."),
96  'rospy:fn': (melodic_api + 'rospy/html/rospy-module.html#%s', "rospy."),
97  'catkin_pkg': (independent_api + 'catkin_pkg/html/%s', None),
98  'rosdep': (independent_api + 'rosdep/html/%s', None),
99  'rospkg': (independent_api + 'rospkg/html/%s', None),
100  'dynamic_reconfigure': (ros_api + 'dynamic_reconfigure/html/msg/%s.html', "dynamic_reconfigure/"),
101 }
102 for dep in catkin_package.exec_depends:
103  if dep.name.endswith("_msgs"):
104  extlinks[dep.name] = (ros_api + dep.name + '/html/msg/%s.html', dep.name + "/")
105  elif dep.name.endswith("_srvs"):
106  extlinks[dep.name] = (ros_api + dep.name + '/html/srv/%s.html', dep.name + "/")
107  elif dep.name not in extlinks:
108  extlinks[dep.name] = (ros_api + dep.name + '/html/%s.html', dep.name + "/")
109 
110 intersphinx_mapping = {
111  "numpy": ("https://numpy.org/doc/stable/", None),
112  "genpy": (ros_api + "genpy/html", None),
113 }
114 if sys.version_info.major == 2:
115  intersphinx_mapping['python'] = ('https://docs.python.org/2.7/', None)
116 else:
117  python_version = '{}.{}'.format(sys.version_info.major, sys.version_info.minor)
118  intersphinx_mapping['python'] = ('https://docs.python.org/{}/'.format(python_version), None)
119 
120 
121 def ros_msg_reference(app, env, node, contnode):
122  text_node = next(iter(contnode.traverse(lambda n: n.tagname == '#text')))
123  parts = text_node.astext().split('.')
124  if len(parts) != 3:
125  return intersphinx.missing_reference(app, env, node, contnode)
126  pkg, obj_type, obj = parts
127  if obj_type not in ("msg", "srv"):
128  return intersphinx.missing_reference(app, env, node, contnode)
129  target = ros_api + '{}/html/{}/{}.html'.format(pkg, obj_type, obj)
130  ref_node = nodes.reference()
131  ref_node['refuri'] = target
132  title = '{}/{}'.format(pkg, obj)
133  text_node = nodes.literal(title, title)
134  text_node['classes'] = ['xref', 'ros', 'ros-' + obj_type]
135  ref_node += text_node
136  return ref_node
137 
138 # Backport of fix for issue https://github.com/sphinx-doc/sphinx/issues/2549. Without it, :ivar: fields wrongly resolve cross-references.
139 from sphinx.domains.python import PyObject
140 PyObject.doc_field_types[list(map(lambda f: f.name == 'variable', PyObject.doc_field_types)).index(True)].rolename = None
141 
142 def setup(app):
143  app.connect("missing-reference", ros_msg_reference)
cras_docs_common.sphinx_docs_conf.setup
def setup(app)
Definition: sphinx_docs_conf.py:142
cras_docs_common.sphinx_docs_conf.ros_msg_reference
def ros_msg_reference(app, env, node, contnode)
Definition: sphinx_docs_conf.py:121


cras_docs_common
Author(s): Martin Pecka
autogenerated on Wed Apr 23 2025 02:48:51