summaryrefslogtreecommitdiff
path: root/Utilities
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-03-14 13:39:44 +0000
committerKitware Robot <kwrobot@kitware.com>2023-03-14 09:39:52 -0400
commit08d31c227b3245155ee9bfbd93119a2c2c860478 (patch)
treeccd8154db0ea6a0b96434279c293aad296a813ca /Utilities
parent17587c19f767cf713ac3338e83697037b1869ac4 (diff)
parent39ecaa5da1f1e42cb62d4ce3d6870409cdefec07 (diff)
downloadcmake-08d31c227b3245155ee9bfbd93119a2c2c860478.tar.gz
Merge topic 'smart-wrap-signatures'
39ecaa5da1 Utilities/Sphinx: Improve word wrap of signatures Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !8317
Diffstat (limited to 'Utilities')
-rw-r--r--Utilities/Sphinx/cmake.py83
-rw-r--r--Utilities/Sphinx/static/cmake.css5
2 files changed, 76 insertions, 12 deletions
diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py
index edfbc7b0b5..38fd98a73b 100644
--- a/Utilities/Sphinx/cmake.py
+++ b/Utilities/Sphinx/cmake.py
@@ -5,7 +5,7 @@ import os
import re
from dataclasses import dataclass
-from typing import Any, cast
+from typing import Any, List, cast
# Override much of pygments' CMakeLexer.
# We need to parse CMake syntax definitions, not CMake code.
@@ -343,14 +343,69 @@ class CMakeGenexObject(CMakeObject):
class CMakeSignatureObject(CMakeObject):
object_type = 'signature'
+ BREAK_ALL = 'all'
+ BREAK_SMART = 'smart'
+ BREAK_VERBATIM = 'verbatim'
+
+ BREAK_CHOICES = {BREAK_ALL, BREAK_SMART, BREAK_VERBATIM}
+
+ def break_option(argument):
+ return directives.choice(argument, CMakeSignatureObject.BREAK_CHOICES)
+
option_spec = {
'target': directives.unchanged,
+ 'break': break_option,
}
- def get_signatures(self):
+ def _break_signature_all(sig: str) -> str:
+ return ws_re.sub(' ', sig)
+
+ def _break_signature_verbatim(sig: str) -> str:
+ lines = [ws_re.sub('\xa0', line.strip()) for line in sig.split('\n')]
+ return ' '.join(lines)
+
+ def _break_signature_smart(sig: str) -> str:
+ tokens = []
+ for line in sig.split('\n'):
+ token = ''
+ delim = ''
+
+ for c in line.strip():
+ if len(delim) == 0 and ws_re.match(c):
+ if len(token):
+ tokens.append(ws_re.sub('\xa0', token))
+ token = ''
+ else:
+ if c == '[':
+ delim += ']'
+ elif c == '<':
+ delim += '>'
+ elif len(delim) and c == delim[-1]:
+ delim = delim[:-1]
+ token += c
+
+ if len(token):
+ tokens.append(ws_re.sub('\xa0', token))
+
+ return ' '.join(tokens)
+
+ def __init__(self, *args, **kwargs):
+ self.targetnames = {}
+ self.break_style = CMakeSignatureObject.BREAK_SMART
+ super().__init__(*args, **kwargs)
+
+ def get_signatures(self) -> List[str]:
content = nl_escape_re.sub('', self.arguments[0])
lines = sig_end_re.split(content)
- return [ws_re.sub(' ', line.strip()) for line in lines]
+
+ if self.break_style == CMakeSignatureObject.BREAK_VERBATIM:
+ fixup = CMakeSignatureObject._break_signature_verbatim
+ elif self.break_style == CMakeSignatureObject.BREAK_SMART:
+ fixup = CMakeSignatureObject._break_signature_smart
+ else:
+ fixup = CMakeSignatureObject._break_signature_all
+
+ return [fixup(line.strip()) for line in lines]
def handle_signature(self, sig, signode):
language = 'cmake'
@@ -368,7 +423,9 @@ class CMakeSignatureObject(CMakeObject):
raise self.warning(error)
for classes, value in tokens:
- if classes:
+ if value == '\xa0':
+ node += nodes.inline(value, value, classes=['nbsp'])
+ elif classes:
node += nodes.inline(value, value, classes=classes)
else:
node += nodes.Text(value)
@@ -378,13 +435,10 @@ class CMakeSignatureObject(CMakeObject):
return sig
- def __init__(self, *args, **kwargs):
- self.targetnames = {}
- super().__init__(*args, **kwargs)
-
def add_target_and_index(self, name, sig, signode):
- if name in self.targetnames:
- sigargs = self.targetnames[name]
+ sig = sig.replace('\xa0', ' ')
+ if sig in self.targetnames:
+ sigargs = self.targetnames[sig]
else:
def extract_keywords(params):
for p in params:
@@ -393,7 +447,7 @@ class CMakeSignatureObject(CMakeObject):
else:
return
- keywords = extract_keywords(name.split('(')[1].split())
+ keywords = extract_keywords(sig.split('(')[1].split())
sigargs = ' '.join(keywords)
targetname = sigargs.lower()
targetid = nodes.make_id(targetname)
@@ -405,7 +459,7 @@ class CMakeSignatureObject(CMakeObject):
self.state.document.note_explicit_target(signode)
# Register the signature as a command object.
- command = name.split('(')[0].lower()
+ command = sig.split('(')[0].lower()
refname = f'{command}({sigargs})'
refid = f'command:{command}({targetname})'
@@ -414,6 +468,8 @@ class CMakeSignatureObject(CMakeObject):
node_id=targetid, location=signode)
def run(self):
+ self.break_style = CMakeSignatureObject.BREAK_ALL
+
targets = self.options.get('target')
if targets is not None:
signatures = self.get_signatures()
@@ -421,6 +477,9 @@ class CMakeSignatureObject(CMakeObject):
for signature, target in zip(signatures, targets):
self.targetnames[signature] = target
+ self.break_style = (
+ self.options.get('break', CMakeSignatureObject.BREAK_SMART))
+
return super().run()
class CMakeXRefRole(XRefRole):
diff --git a/Utilities/Sphinx/static/cmake.css b/Utilities/Sphinx/static/cmake.css
index dd0dd0272d..41a74f5ac5 100644
--- a/Utilities/Sphinx/static/cmake.css
+++ b/Utilities/Sphinx/static/cmake.css
@@ -40,6 +40,11 @@ div.sphinxsidebarwrapper {
font-weight: normal;
}
+/* Implement non-breaking spaces in signatures. */
+.nbsp {
+ white-space: nowrap;
+}
+
/* Remove unwanted margin in case list item contains a div-wrapping
directive like `.. versionadded` or `.. deprecated`. */
dd > :first-child > p {