diff options
author | Matthew Woehlke <matthew.woehlke@kitware.com> | 2023-03-09 16:32:07 (GMT) |
---|---|---|
committer | Matthew Woehlke <matthew.woehlke@kitware.com> | 2023-03-09 16:32:07 (GMT) |
commit | cc21d0e47802fb1d054eb56b8bb4bd8ee66f9caa (patch) | |
tree | 0a63ab5ce52622dae91def59212c39ffb942eb4f /Utilities | |
parent | 37e015d4a65566386266a99c70226b4082defce2 (diff) | |
download | CMake-cc21d0e47802fb1d054eb56b8bb4bd8ee66f9caa.zip CMake-cc21d0e47802fb1d054eb56b8bb4bd8ee66f9caa.tar.gz CMake-cc21d0e47802fb1d054eb56b8bb4bd8ee66f9caa.tar.bz2 |
Utilities/Sphinx: Make signatures linkable
Add signatures to the collection of observed objects (which can be
referenced elsewhere). Don't automatically strip parameters from a
:command: reference, as these may now link signatures. (Do, however,
munge them into 'text <ref>' form if they aren't already, as not doing
so adds an extra '()' for some reason.) Correspondingly, change xref
resolution to try to match 'command' when a ref like 'command(args)' is
not matched, so that existing links to commands that have not been
converted to use the new signature directive don't immediately break.
Diffstat (limited to 'Utilities')
-rw-r--r-- | Utilities/Sphinx/cmake.py | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index fb22767..a07b6e9 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py @@ -360,7 +360,7 @@ class CMakeSignatureObject(CMakeObject): def add_target_and_index(self, name, sig, signode): if name in self.targetnames: - targetname = self.targetnames[name].lower() + sigargs = self.targetnames[name] else: def extract_keywords(params): for p in params: @@ -370,7 +370,8 @@ class CMakeSignatureObject(CMakeObject): return keywords = extract_keywords(name.split('(')[1].split()) - targetname = ' '.join(keywords).lower() + sigargs = ' '.join(keywords) + targetname = sigargs.lower() targetid = nodes.make_id(targetname) if targetid not in self.state.document.ids: @@ -379,6 +380,15 @@ class CMakeSignatureObject(CMakeObject): signode['first'] = (not self.names) self.state.document.note_explicit_target(signode) + # Register the signature as a command object. + command = name.split('(')[0].lower() + refname = f'{command}({sigargs})' + refid = f'command:{command}({targetname})' + + domain = cast(CMakeDomain, self.env.get_domain('cmake')) + domain.note_object('command', name=refname, target_id=refid, + node_id=targetid, location=signode) + def run(self): targets = self.options.get('target') if targets is not None: @@ -393,19 +403,15 @@ class CMakeXRefRole(XRefRole): # See sphinx.util.nodes.explicit_title_re; \x00 escapes '<'. _re = re.compile(r'^(.+?)(\s*)(?<!\x00)<(.*?)>$', re.DOTALL) - _re_sub = re.compile(r'^([^()\s]+)\s*\(([^()]*)\)$', re.DOTALL) + _re_ref = re.compile(r'^.*\s<\w+([(][\w\s]+[)])?>$', re.DOTALL) _re_genex = re.compile(r'^\$<([^<>:]+)(:[^<>]+)?>$', re.DOTALL) _re_guide = re.compile(r'^([^<>/]+)/([^<>]*)$', re.DOTALL) def __call__(self, typ, rawtext, text, *args, **keys): - # Translate CMake command cross-references of the form: - # `command_name(SUB_COMMAND)` - # to have an explicit target: - # `command_name(SUB_COMMAND) <command_name>` if typ == 'cmake:command': - m = CMakeXRefRole._re_sub.match(text) - if m: - text = '%s <%s>' % (text, m.group(1)) + m = CMakeXRefRole._re_ref.match(text) + if m is None: + text = f'{text} <{text}>' elif typ == 'cmake:genex': m = CMakeXRefRole._re_genex.match(text) if m: @@ -461,6 +467,10 @@ class CMakeXRefTransform(Transform): # Do not index cross-references to guide sections. continue + if objtype == 'command': + # Index signature references to their parent command. + objname = objname.split('(')[0].lower() + targetnum = env.new_serialno('index-%s:%s' % (objtype, objname)) targetid = 'index-%s-%s:%s' % (targetnum, objtype, objname) @@ -537,6 +547,15 @@ class CMakeDomain(Domain): typ, target, node, contnode): targetid = f'{typ}:{target}' obj = self.data['objects'].get(targetid) + + if obj is None and typ == 'command': + # If 'command(args)' wasn't found, try just 'command'. + # TODO: remove this fallback? warn? + # logger.warning(f'no match for {targetid}') + command = target.split('(')[0] + targetid = f'{typ}:{command}' + obj = self.data['objects'].get(targetid) + if obj is None: # TODO: warn somehow? return None |