from __future__ import annotations import re CODE_SPAN_RE = re.compile(r"`[^`]*`") FILE_PATH_RE = re.compile( r"(? str: text = raw or "" protected = _ProtectedText() text = self._protect(text, protected) text = self._collapse_whitespace(text) text = text.translate(QUOTE_TRANSLATION) text = SPACE_BEFORE_PUNCT_RE.sub(r"\1", text) text = SPACE_AFTER_PUNCT_RE.sub(r"\1 ", text) text = self._collapse_whitespace(text) return protected.restore(text) def _protect(self, text: str, protected: "_ProtectedText") -> str: for pattern in (CODE_SPAN_RE, FILE_PATH_RE, DOTTED_IDENT_RE, CAMEL_RE, SNAKE_RE): text = pattern.sub(protected.replace, text) return text def _collapse_whitespace(self, text: str) -> str: return WS_RE.sub(" ", text).strip() class _ProtectedText: def __init__(self) -> None: self._items: dict[str, str] = {} self._index = 0 def replace(self, match: re.Match[str]) -> str: placeholder = f"@@P{self._index}@@" self._items[placeholder] = match.group(0) self._index += 1 return placeholder def restore(self, text: str) -> str: restored = text for placeholder, value in self._items.items(): restored = restored.replace(placeholder, value) return restored