|
17 | 17 | import sphinx |
18 | 18 | import subprocess |
19 | 19 | import os |
| 20 | +import docutils |
20 | 21 | import xml.etree.ElementTree as ET |
21 | 22 |
|
22 | 23 | ## Project information ################################################################################################# |
|
98 | 99 | html_logo = None |
99 | 100 | # Path to the HTML fav icon. |
100 | 101 | html_favicon = None |
| 102 | +# Paths to static files and folders, will be stored in '_static' folder. |
| 103 | +html_static_path = [ |
| 104 | + "../other/commonapi_docs/FrancaUserGuide-0.12.0.1.pdf", |
| 105 | + "../other/commonapi_docs/CommonAPICppSpecification.pdf", |
| 106 | + "../other/commonapi_docs/CommonAPICppUserGuide.pdf", |
| 107 | + "../other/commonapi_docs/CommonAPI-4_deployment_spec.fdepl", |
| 108 | + "../other/commonapi_docs/dbus/CommonAPI-4-DBus_deployment_spec.fdepl", |
| 109 | + "../other/commonapi_docs/dbus/CommonAPIDBusCppUserGuide.pdf", |
| 110 | + "../other/commonapi_docs/someip/CommonAPI-4-SOMEIP_deployment_spec.fdepl", |
| 111 | + "../other/commonapi_docs/someip/CommonAPISomeIPCppUserGuide.pdf", |
| 112 | + "../other/commonapi_docs/someip/vsomeipUserGuide.html" |
| 113 | +] |
101 | 114 | # Add permalinks to every section. |
102 | 115 | html_permalinks = True |
103 | 116 | # Do not include the original sources in the final documentation. |
@@ -174,43 +187,55 @@ def breathe_load_tags_on_doxyfile() -> None: |
174 | 187 | if len(elems) == 1: |
175 | 188 | _ = [tags.add(tag.text) for tag in elems[0] if tag.text.isidentifier()] |
176 | 189 |
|
177 | | -def on_missing_reference(_app: sphinx.application.Sphinx, |
178 | | - _env: sphinx.app.builder.env, |
| 190 | +def on_missing_reference(app: sphinx.application.Sphinx, |
| 191 | + env: sphinx.environment.BuildEnvironment, |
179 | 192 | node: sphinx.addnodes.pending_xref, |
180 | | - contnode: sphinx.addnodes.pending_xref): |
181 | | - """Handler for 'on_missing_reference' warning. Lots of false positives can be raised by Sphinx from this, for |
| 193 | + contnode: docutils.nodes.TextElement) -> docutils.nodes.reference | None: |
| 194 | + """Handler for 'missing-reference' warning. Lots of false positives can be raised by Sphinx from this, for |
182 | 195 | example from missing references to standard library types or missing references to third-party types that are not |
183 | 196 | documented by Sphinx or which are not processed by Doxygen. |
184 | 197 |
|
185 | | - One solution is to disable errors as warnings, but this is not convenient as it could hide real errors. |
| 198 | + One solution is to disable errors as warnings, but this is not convenient as it could hide real errors. Another |
| 199 | + solution implies the use of 'c_extra_keywords' and 'c_id_attributes', however, this also causes other kind of |
| 200 | + errors. Thus the solution to handle the event directly. |
186 | 201 |
|
187 | | - The implementation of this handler here allows to ignore warnings for the types specified.""" |
| 202 | + The implementation of this handler allows to ignore this kind of warnings and also to look for substitue |
| 203 | + nodes when a reference has not been found.""" |
188 | 204 | # Print missing reference in color in the terminal to differentiate it. |
189 | | - # print(f"\033[93m mon_missing_reference: {node}.\033[00m") |
190 | | - |
191 | | - # Missing references handler, lots of false positives can occur in the C/C++ domain. |
192 | | - # Trying to handle them with 'c_extra_keywords' or 'c_id_attributes' generates other kind of errors. |
193 | | - # Allowed reference domains, reference targets and reference types that can be missing are described below. |
194 | | - refdomains = ["c", "cpp"] |
195 | | - reftypes = ["identifier"] |
196 | | - |
197 | | - # C Standard library identifiers to ignore. |
198 | | - c_std_reftargets = [] |
199 | | - |
200 | | - # C++ Standard library identifiers to ignore. |
201 | | - cpp_std_reftargets = ["size_t"] |
202 | | - |
203 | | - # Build total reftargets. |
204 | | - reftargets = [ |
205 | | - *c_std_reftargets, |
206 | | - *cpp_std_reftargets |
207 | | - ] |
208 | | - |
209 | | - # Check if the reference is of C/C++ type and it can be allowed to be missing. |
210 | | - if all((node["refdomain"] in refdomains, node["reftarget"] in reftargets, node["reftype"] in reftypes)): |
211 | | - # Return OK in Sphinx. |
212 | | - return contnode |
213 | | - # Raise error in Sphinx. |
| 205 | + print(f"\033[93m on_missing_reference: {node}.\033[00m") |
| 206 | + |
| 207 | + # The lookup dictionary with missing targets and replacements. |
| 208 | + reftargets = { |
| 209 | + "c": { |
| 210 | + |
| 211 | + }, |
| 212 | + "cpp": { |
| 213 | + "*": { |
| 214 | + "size_t": None, "uint32_t": None, |
| 215 | + "v0_1": None, "v0_1::commonapi": None, "v0_1::commonapi::app": None, "v0_1::commonapi::app::AppStubDefault": None |
| 216 | + } |
| 217 | + } |
| 218 | + } |
| 219 | + |
| 220 | + # Obtain the reference target replacement, if any, note that refdoc replacements take priority over global ones. |
| 221 | + domain_dict = reftargets.get(node["refdomain"], {}) |
| 222 | + reftarget = {**domain_dict.get("*", {}), **domain_dict.get(node["refdoc"], {})}.get(node["reftarget"], False) |
| 223 | + |
| 224 | + # Check if the replacement target has been found and the node refers to an identifier. |
| 225 | + if all([node["reftype"] == "identifier", reftarget is not False]): |
| 226 | + # No explicit replacement for target, thus acknowledge warning and continue with node as is. |
| 227 | + if reftarget is None: |
| 228 | + return contnode |
| 229 | + |
| 230 | + # Find explicit replacement for target, and ensure there is no ambiguity. |
| 231 | + reftarget_cand = env.domains[node["refdomain"]].resolve_any_xref( |
| 232 | + env, './index', app.builder, reftarget, node, contnode |
| 233 | + ) |
| 234 | + if len(reftarget_cand) != 1: |
| 235 | + raise sphinx.errors.ExtensionError(f"Found {len(reftarget_cand)} '{reftarget}' replacements for '{node['reftarget']}'.") |
| 236 | + return reftarget_cand[0][1] |
| 237 | + |
| 238 | + # Could not resolve identifier, let other handlers resolve it if they can. |
214 | 239 | return None |
215 | 240 |
|
216 | 241 | def setup(app: sphinx.application.Sphinx): |
|
0 commit comments