diff pygments_lexer_pseudocode2/utils.py @ 288:298841bc4dee

Allow "normal" Pygments token names in "\ttX" ("Error", "Text.Whitespace", ...)
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 22 May 2026 12:32:38 +0200
parents ae5e741d2a9b
children
line wrap: on
line diff
--- a/pygments_lexer_pseudocode2/utils.py	Fri May 22 12:31:09 2026 +0200
+++ b/pygments_lexer_pseudocode2/utils.py	Fri May 22 12:32:38 2026 +0200
@@ -7,7 +7,10 @@
 
 """
 
-__all__ = ["REVERSED_STANDARD_TYPES"]
+__all__ = [
+    "REVERSED_STANDARD_TYPES",
+    "string_to_defined_tokentype",
+]
 
 
 import pygments.token
@@ -19,3 +22,39 @@
 for _toktype, _cssstyle in pygments.token.STANDARD_TYPES.items():
     REVERSED_STANDARD_TYPES[_cssstyle] = _toktype
 del _toktype, _cssstyle
+
+
+def string_to_defined_tokentype(s):
+    """Determine whether the token type `s` given as string is defined.
+
+    :param str s: A token type string as in
+                 :py:func:`pygments.token.string_to_tokentype`.
+    :returns: An **existing** token if
+              :py:func:`pygments.token.string_to_tokentype`
+              would return an already existing token type,
+              :py:obj:`None` otherwise.
+    :rtype: :py:class:`pygments.token._TokenType` or :py:obj:`None`
+
+    This implementation is needed because
+    :py:func:`pygments.token.string_to_tokentype` synthesizes a new token
+    on not yet existing token types.
+    And :py:func:`is_token_subtype` works only on token instances.
+
+    """
+    ttype = pygments.token.Token
+    ttype_prefix = "Token."
+    if not s:
+        return ttype
+    for part in s.split("."):
+        for subtype in ttype.subtypes:
+            subtypename = str(subtype)
+            # Remove prefix
+            assert subtypename.startswith(ttype_prefix)
+            subtypename = subtypename[len(ttype_prefix):]
+            if subtypename == part:
+                ttype = subtype
+                ttype_prefix += "%s." % (part,)
+                break
+        else:
+            return None
+    return ttype