ZhengyangZhang commited on
Commit
4b213e1
·
verified ·
1 Parent(s): e03c8b2

Add files using upload-large-folder tool

Browse files
Files changed (50) hide show
  1. lib/python3.12/site-packages/omegaconf/__pycache__/__init__.cpython-312.pyc +0 -0
  2. lib/python3.12/site-packages/omegaconf/__pycache__/_impl.cpython-312.pyc +0 -0
  3. lib/python3.12/site-packages/omegaconf/__pycache__/_utils.cpython-312.pyc +0 -0
  4. lib/python3.12/site-packages/omegaconf/__pycache__/base.cpython-312.pyc +0 -0
  5. lib/python3.12/site-packages/omegaconf/__pycache__/basecontainer.cpython-312.pyc +0 -0
  6. lib/python3.12/site-packages/omegaconf/__pycache__/dictconfig.cpython-312.pyc +0 -0
  7. lib/python3.12/site-packages/omegaconf/__pycache__/errors.cpython-312.pyc +0 -0
  8. lib/python3.12/site-packages/omegaconf/__pycache__/grammar_parser.cpython-312.pyc +0 -0
  9. lib/python3.12/site-packages/omegaconf/__pycache__/grammar_visitor.cpython-312.pyc +0 -0
  10. lib/python3.12/site-packages/omegaconf/__pycache__/listconfig.cpython-312.pyc +0 -0
  11. lib/python3.12/site-packages/omegaconf/__pycache__/nodes.cpython-312.pyc +0 -0
  12. lib/python3.12/site-packages/omegaconf/__pycache__/omegaconf.cpython-312.pyc +0 -0
  13. lib/python3.12/site-packages/omegaconf/__pycache__/version.cpython-312.pyc +0 -0
  14. lib/python3.12/site-packages/omegaconf/grammar/__pycache__/__init__.cpython-312.pyc +0 -0
  15. lib/python3.12/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarLexer.cpython-312.pyc +0 -0
  16. lib/python3.12/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarParser.cpython-312.pyc +0 -0
  17. lib/python3.12/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarParserListener.cpython-312.pyc +0 -0
  18. lib/python3.12/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarParserVisitor.cpython-312.pyc +0 -0
  19. lib/python3.12/site-packages/omegaconf/grammar/gen/__pycache__/__init__.cpython-312.pyc +0 -0
  20. lib/python3.12/site-packages/omegaconf/resolvers/__init__.py +5 -0
  21. lib/python3.12/site-packages/omegaconf/resolvers/__pycache__/__init__.cpython-312.pyc +0 -0
  22. lib/python3.12/site-packages/omegaconf/resolvers/oc/__init__.py +113 -0
  23. lib/python3.12/site-packages/omegaconf/resolvers/oc/__pycache__/__init__.cpython-312.pyc +0 -0
  24. lib/python3.12/site-packages/omegaconf/resolvers/oc/__pycache__/dict.cpython-312.pyc +0 -0
  25. lib/python3.12/site-packages/omegaconf/resolvers/oc/dict.py +83 -0
  26. lib/python3.12/site-packages/pygments/__init__.py +82 -0
  27. lib/python3.12/site-packages/pygments/__main__.py +17 -0
  28. lib/python3.12/site-packages/pygments/cmdline.py +668 -0
  29. lib/python3.12/site-packages/pygments/console.py +70 -0
  30. lib/python3.12/site-packages/pygments/filter.py +70 -0
  31. lib/python3.12/site-packages/pygments/filters/__init__.py +940 -0
  32. lib/python3.12/site-packages/pygments/filters/__pycache__/__init__.cpython-312.pyc +0 -0
  33. lib/python3.12/site-packages/pygments/formatter.py +129 -0
  34. lib/python3.12/site-packages/pygments/lexer.py +961 -0
  35. lib/python3.12/site-packages/pygments/modeline.py +43 -0
  36. lib/python3.12/site-packages/pygments/plugin.py +72 -0
  37. lib/python3.12/site-packages/pygments/regexopt.py +91 -0
  38. lib/python3.12/site-packages/pygments/scanner.py +104 -0
  39. lib/python3.12/site-packages/pygments/sphinxext.py +247 -0
  40. lib/python3.12/site-packages/pygments/style.py +203 -0
  41. lib/python3.12/site-packages/pygments/styles/colorful.py +83 -0
  42. lib/python3.12/site-packages/pygments/styles/dracula.py +90 -0
  43. lib/python3.12/site-packages/pygments/styles/friendly.py +76 -0
  44. lib/python3.12/site-packages/pygments/styles/igor.py +32 -0
  45. lib/python3.12/site-packages/pygments/styles/inkpot.py +72 -0
  46. lib/python3.12/site-packages/pygments/styles/lilypond.py +62 -0
  47. lib/python3.12/site-packages/pygments/styles/murphy.py +82 -0
  48. lib/python3.12/site-packages/pygments/token.py +214 -0
  49. lib/python3.12/site-packages/pygments/unistring.py +153 -0
  50. lib/python3.12/site-packages/pygments/util.py +324 -0
lib/python3.12/site-packages/omegaconf/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (1.2 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/_impl.cpython-312.pyc ADDED
Binary file (3.59 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/_utils.cpython-312.pyc ADDED
Binary file (39.7 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/base.cpython-312.pyc ADDED
Binary file (39.2 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/basecontainer.cpython-312.pyc ADDED
Binary file (36.6 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/dictconfig.cpython-312.pyc ADDED
Binary file (32.8 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/errors.cpython-312.pyc ADDED
Binary file (6.1 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/grammar_parser.cpython-312.pyc ADDED
Binary file (4.84 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/grammar_visitor.cpython-312.pyc ADDED
Binary file (19 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/listconfig.cpython-312.pyc ADDED
Binary file (30.7 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/nodes.cpython-312.pyc ADDED
Binary file (23.8 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/omegaconf.cpython-312.pyc ADDED
Binary file (45.9 kB). View file
 
lib/python3.12/site-packages/omegaconf/__pycache__/version.cpython-312.pyc ADDED
Binary file (669 Bytes). View file
 
lib/python3.12/site-packages/omegaconf/grammar/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (196 Bytes). View file
 
lib/python3.12/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarLexer.cpython-312.pyc ADDED
Binary file (21.7 kB). View file
 
lib/python3.12/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarParser.cpython-312.pyc ADDED
Binary file (94.5 kB). View file
 
lib/python3.12/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarParserListener.cpython-312.pyc ADDED
Binary file (7.13 kB). View file
 
lib/python3.12/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarParserVisitor.cpython-312.pyc ADDED
Binary file (4.56 kB). View file
 
lib/python3.12/site-packages/omegaconf/grammar/gen/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (200 Bytes). View file
 
lib/python3.12/site-packages/omegaconf/resolvers/__init__.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from omegaconf.resolvers import oc
2
+
3
+ __all__ = [
4
+ "oc",
5
+ ]
lib/python3.12/site-packages/omegaconf/resolvers/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (279 Bytes). View file
 
lib/python3.12/site-packages/omegaconf/resolvers/oc/__init__.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import string
3
+ import warnings
4
+ from typing import Any, Optional
5
+
6
+ from omegaconf import Container, Node
7
+ from omegaconf._utils import _DEFAULT_MARKER_, _get_value
8
+ from omegaconf.basecontainer import BaseContainer
9
+ from omegaconf.errors import ConfigKeyError
10
+ from omegaconf.grammar_parser import parse
11
+ from omegaconf.resolvers.oc import dict
12
+
13
+
14
+ def create(obj: Any, _parent_: Container) -> Any:
15
+ """Create a config object from `obj`, similar to `OmegaConf.create`"""
16
+ from omegaconf import OmegaConf
17
+
18
+ assert isinstance(_parent_, BaseContainer)
19
+ return OmegaConf.create(obj, parent=_parent_)
20
+
21
+
22
+ def env(key: str, default: Any = _DEFAULT_MARKER_) -> Optional[str]:
23
+ """
24
+ :param key: Environment variable key
25
+ :param default: Optional default value to use in case the key environment variable is not set.
26
+ If default is not a string, it is converted with str(default).
27
+ None default is returned as is.
28
+ :return: The environment variable 'key'. If the environment variable is not set and a default is
29
+ provided, the default is used. If used, the default is converted to a string with str(default).
30
+ If the default is None, None is returned (without a string conversion).
31
+ """
32
+ try:
33
+ return os.environ[key]
34
+ except KeyError:
35
+ if default is not _DEFAULT_MARKER_:
36
+ return str(default) if default is not None else None
37
+ else:
38
+ raise KeyError(f"Environment variable '{key}' not found")
39
+
40
+
41
+ def decode(expr: Optional[str], _parent_: Container, _node_: Node) -> Any:
42
+ """
43
+ Parse and evaluate `expr` according to the `singleElement` rule of the grammar.
44
+
45
+ If `expr` is `None`, then return `None`.
46
+ """
47
+ if expr is None:
48
+ return None
49
+
50
+ if not isinstance(expr, str):
51
+ raise TypeError(
52
+ f"`oc.decode` can only take strings or None as input, "
53
+ f"but `{expr}` is of type {type(expr).__name__}"
54
+ )
55
+
56
+ parse_tree = parse(expr, parser_rule="singleElement", lexer_mode="VALUE_MODE")
57
+ val = _parent_.resolve_parse_tree(parse_tree, node=_node_)
58
+ return _get_value(val)
59
+
60
+
61
+ def deprecated(
62
+ key: str,
63
+ message: str = "'$OLD_KEY' is deprecated. Change your code and config to use '$NEW_KEY'",
64
+ *,
65
+ _parent_: Container,
66
+ _node_: Node,
67
+ ) -> Any:
68
+ from omegaconf._impl import select_node
69
+
70
+ if not isinstance(key, str):
71
+ raise TypeError(
72
+ f"oc.deprecated: interpolation key type is not a string ({type(key).__name__})"
73
+ )
74
+
75
+ if not isinstance(message, str):
76
+ raise TypeError(
77
+ f"oc.deprecated: interpolation message type is not a string ({type(message).__name__})"
78
+ )
79
+
80
+ full_key = _node_._get_full_key(key=None)
81
+ target_node = select_node(_parent_, key, absolute_key=True)
82
+ if target_node is None:
83
+ raise ConfigKeyError(
84
+ f"In oc.deprecated resolver at '{full_key}': Key not found: '{key}'"
85
+ )
86
+ new_key = target_node._get_full_key(key=None)
87
+ msg = string.Template(message).safe_substitute(
88
+ OLD_KEY=full_key,
89
+ NEW_KEY=new_key,
90
+ )
91
+ warnings.warn(category=UserWarning, message=msg)
92
+ return target_node
93
+
94
+
95
+ def select(
96
+ key: str,
97
+ default: Any = _DEFAULT_MARKER_,
98
+ *,
99
+ _parent_: Container,
100
+ ) -> Any:
101
+ from omegaconf._impl import select_value
102
+
103
+ return select_value(cfg=_parent_, key=key, absolute_key=True, default=default)
104
+
105
+
106
+ __all__ = [
107
+ "create",
108
+ "decode",
109
+ "deprecated",
110
+ "dict",
111
+ "env",
112
+ "select",
113
+ ]
lib/python3.12/site-packages/omegaconf/resolvers/oc/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (4.81 kB). View file
 
lib/python3.12/site-packages/omegaconf/resolvers/oc/__pycache__/dict.cpython-312.pyc ADDED
Binary file (3.19 kB). View file
 
lib/python3.12/site-packages/omegaconf/resolvers/oc/dict.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, List
2
+
3
+ from omegaconf import AnyNode, Container, DictConfig, ListConfig
4
+ from omegaconf._utils import Marker
5
+ from omegaconf.basecontainer import BaseContainer
6
+ from omegaconf.errors import ConfigKeyError
7
+
8
+ _DEFAULT_SELECT_MARKER_: Any = Marker("_DEFAULT_SELECT_MARKER_")
9
+
10
+
11
+ def keys(
12
+ key: str,
13
+ _parent_: Container,
14
+ ) -> ListConfig:
15
+ from omegaconf import OmegaConf
16
+
17
+ assert isinstance(_parent_, BaseContainer)
18
+
19
+ in_dict = _get_and_validate_dict_input(
20
+ key, parent=_parent_, resolver_name="oc.dict.keys"
21
+ )
22
+
23
+ ret = OmegaConf.create(list(in_dict.keys()), parent=_parent_)
24
+ assert isinstance(ret, ListConfig)
25
+ return ret
26
+
27
+
28
+ def values(key: str, _root_: BaseContainer, _parent_: Container) -> ListConfig:
29
+ assert isinstance(_parent_, BaseContainer)
30
+ in_dict = _get_and_validate_dict_input(
31
+ key, parent=_parent_, resolver_name="oc.dict.values"
32
+ )
33
+
34
+ content = in_dict._content
35
+ assert isinstance(content, dict)
36
+
37
+ ret = ListConfig([])
38
+ if key.startswith("."):
39
+ key = f".{key}" # extra dot to compensate for extra level of nesting within ret ListConfig
40
+ for k in content:
41
+ ref_node = AnyNode(f"${{{key}.{k!s}}}")
42
+ ret.append(ref_node)
43
+
44
+ # Finalize result by setting proper type and parent.
45
+ element_type: Any = in_dict._metadata.element_type
46
+ ret._metadata.element_type = element_type
47
+ ret._metadata.ref_type = List[element_type]
48
+ ret._set_parent(_parent_)
49
+
50
+ return ret
51
+
52
+
53
+ def _get_and_validate_dict_input(
54
+ key: str,
55
+ parent: BaseContainer,
56
+ resolver_name: str,
57
+ ) -> DictConfig:
58
+ from omegaconf._impl import select_value
59
+
60
+ if not isinstance(key, str):
61
+ raise TypeError(
62
+ f"`{resolver_name}` requires a string as input, but obtained `{key}` "
63
+ f"of type: {type(key).__name__}"
64
+ )
65
+
66
+ in_dict = select_value(
67
+ parent,
68
+ key,
69
+ throw_on_missing=True,
70
+ absolute_key=True,
71
+ default=_DEFAULT_SELECT_MARKER_,
72
+ )
73
+
74
+ if in_dict is _DEFAULT_SELECT_MARKER_:
75
+ raise ConfigKeyError(f"Key not found: '{key}'")
76
+
77
+ if not isinstance(in_dict, DictConfig):
78
+ raise TypeError(
79
+ f"`{resolver_name}` cannot be applied to objects of type: "
80
+ f"{type(in_dict).__name__}"
81
+ )
82
+
83
+ return in_dict
lib/python3.12/site-packages/pygments/__init__.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Pygments
3
+ ~~~~~~~~
4
+
5
+ Pygments is a syntax highlighting package written in Python.
6
+
7
+ It is a generic syntax highlighter for general use in all kinds of software
8
+ such as forum systems, wikis or other applications that need to prettify
9
+ source code. Highlights are:
10
+
11
+ * a wide range of common languages and markup formats is supported
12
+ * special attention is paid to details, increasing quality by a fair amount
13
+ * support for new languages and formats are added easily
14
+ * a number of output formats, presently HTML, LaTeX, RTF, SVG, all image
15
+ formats that PIL supports, and ANSI sequences
16
+ * it is usable as a command-line tool and as a library
17
+ * ... and it highlights even Brainfuck!
18
+
19
+ The `Pygments master branch`_ is installable with ``easy_install Pygments==dev``.
20
+
21
+ .. _Pygments master branch:
22
+ https://github.com/pygments/pygments/archive/master.zip#egg=Pygments-dev
23
+
24
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
25
+ :license: BSD, see LICENSE for details.
26
+ """
27
+ from io import StringIO, BytesIO
28
+
29
+ __version__ = '2.19.2'
30
+ __docformat__ = 'restructuredtext'
31
+
32
+ __all__ = ['lex', 'format', 'highlight']
33
+
34
+
35
+ def lex(code, lexer):
36
+ """
37
+ Lex `code` with the `lexer` (must be a `Lexer` instance)
38
+ and return an iterable of tokens. Currently, this only calls
39
+ `lexer.get_tokens()`.
40
+ """
41
+ try:
42
+ return lexer.get_tokens(code)
43
+ except TypeError:
44
+ # Heuristic to catch a common mistake.
45
+ from pygments.lexer import RegexLexer
46
+ if isinstance(lexer, type) and issubclass(lexer, RegexLexer):
47
+ raise TypeError('lex() argument must be a lexer instance, '
48
+ 'not a class')
49
+ raise
50
+
51
+
52
+ def format(tokens, formatter, outfile=None): # pylint: disable=redefined-builtin
53
+ """
54
+ Format ``tokens`` (an iterable of tokens) with the formatter ``formatter``
55
+ (a `Formatter` instance).
56
+
57
+ If ``outfile`` is given and a valid file object (an object with a
58
+ ``write`` method), the result will be written to it, otherwise it
59
+ is returned as a string.
60
+ """
61
+ try:
62
+ if not outfile:
63
+ realoutfile = getattr(formatter, 'encoding', None) and BytesIO() or StringIO()
64
+ formatter.format(tokens, realoutfile)
65
+ return realoutfile.getvalue()
66
+ else:
67
+ formatter.format(tokens, outfile)
68
+ except TypeError:
69
+ # Heuristic to catch a common mistake.
70
+ from pygments.formatter import Formatter
71
+ if isinstance(formatter, type) and issubclass(formatter, Formatter):
72
+ raise TypeError('format() argument must be a formatter instance, '
73
+ 'not a class')
74
+ raise
75
+
76
+
77
+ def highlight(code, lexer, formatter, outfile=None):
78
+ """
79
+ This is the most high-level highlighting function. It combines `lex` and
80
+ `format` in one function.
81
+ """
82
+ return format(lex(code, lexer), formatter, outfile)
lib/python3.12/site-packages/pygments/__main__.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.__main__
3
+ ~~~~~~~~~~~~~~~~~
4
+
5
+ Main entry point for ``python -m pygments``.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ import sys
12
+ import pygments.cmdline
13
+
14
+ try:
15
+ sys.exit(pygments.cmdline.main(sys.argv))
16
+ except KeyboardInterrupt:
17
+ sys.exit(1)
lib/python3.12/site-packages/pygments/cmdline.py ADDED
@@ -0,0 +1,668 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.cmdline
3
+ ~~~~~~~~~~~~~~~~
4
+
5
+ Command line interface.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ import os
12
+ import sys
13
+ import shutil
14
+ import argparse
15
+ from textwrap import dedent
16
+
17
+ from pygments import __version__, highlight
18
+ from pygments.util import ClassNotFound, OptionError, docstring_headline, \
19
+ guess_decode, guess_decode_from_terminal, terminal_encoding, \
20
+ UnclosingTextIOWrapper
21
+ from pygments.lexers import get_all_lexers, get_lexer_by_name, guess_lexer, \
22
+ load_lexer_from_file, get_lexer_for_filename, find_lexer_class_for_filename
23
+ from pygments.lexers.special import TextLexer
24
+ from pygments.formatters.latex import LatexEmbeddedLexer, LatexFormatter
25
+ from pygments.formatters import get_all_formatters, get_formatter_by_name, \
26
+ load_formatter_from_file, get_formatter_for_filename, find_formatter_class
27
+ from pygments.formatters.terminal import TerminalFormatter
28
+ from pygments.formatters.terminal256 import Terminal256Formatter, TerminalTrueColorFormatter
29
+ from pygments.filters import get_all_filters, find_filter_class
30
+ from pygments.styles import get_all_styles, get_style_by_name
31
+
32
+
33
+ def _parse_options(o_strs):
34
+ opts = {}
35
+ if not o_strs:
36
+ return opts
37
+ for o_str in o_strs:
38
+ if not o_str.strip():
39
+ continue
40
+ o_args = o_str.split(',')
41
+ for o_arg in o_args:
42
+ o_arg = o_arg.strip()
43
+ try:
44
+ o_key, o_val = o_arg.split('=', 1)
45
+ o_key = o_key.strip()
46
+ o_val = o_val.strip()
47
+ except ValueError:
48
+ opts[o_arg] = True
49
+ else:
50
+ opts[o_key] = o_val
51
+ return opts
52
+
53
+
54
+ def _parse_filters(f_strs):
55
+ filters = []
56
+ if not f_strs:
57
+ return filters
58
+ for f_str in f_strs:
59
+ if ':' in f_str:
60
+ fname, fopts = f_str.split(':', 1)
61
+ filters.append((fname, _parse_options([fopts])))
62
+ else:
63
+ filters.append((f_str, {}))
64
+ return filters
65
+
66
+
67
+ def _print_help(what, name):
68
+ try:
69
+ if what == 'lexer':
70
+ cls = get_lexer_by_name(name)
71
+ print(f"Help on the {cls.name} lexer:")
72
+ print(dedent(cls.__doc__))
73
+ elif what == 'formatter':
74
+ cls = find_formatter_class(name)
75
+ print(f"Help on the {cls.name} formatter:")
76
+ print(dedent(cls.__doc__))
77
+ elif what == 'filter':
78
+ cls = find_filter_class(name)
79
+ print(f"Help on the {name} filter:")
80
+ print(dedent(cls.__doc__))
81
+ return 0
82
+ except (AttributeError, ValueError):
83
+ print(f"{what} not found!", file=sys.stderr)
84
+ return 1
85
+
86
+
87
+ def _print_list(what):
88
+ if what == 'lexer':
89
+ print()
90
+ print("Lexers:")
91
+ print("~~~~~~~")
92
+
93
+ info = []
94
+ for fullname, names, exts, _ in get_all_lexers():
95
+ tup = (', '.join(names)+':', fullname,
96
+ exts and '(filenames ' + ', '.join(exts) + ')' or '')
97
+ info.append(tup)
98
+ info.sort()
99
+ for i in info:
100
+ print(('* {}\n {} {}').format(*i))
101
+
102
+ elif what == 'formatter':
103
+ print()
104
+ print("Formatters:")
105
+ print("~~~~~~~~~~~")
106
+
107
+ info = []
108
+ for cls in get_all_formatters():
109
+ doc = docstring_headline(cls)
110
+ tup = (', '.join(cls.aliases) + ':', doc, cls.filenames and
111
+ '(filenames ' + ', '.join(cls.filenames) + ')' or '')
112
+ info.append(tup)
113
+ info.sort()
114
+ for i in info:
115
+ print(('* {}\n {} {}').format(*i))
116
+
117
+ elif what == 'filter':
118
+ print()
119
+ print("Filters:")
120
+ print("~~~~~~~~")
121
+
122
+ for name in get_all_filters():
123
+ cls = find_filter_class(name)
124
+ print("* " + name + ':')
125
+ print(f" {docstring_headline(cls)}")
126
+
127
+ elif what == 'style':
128
+ print()
129
+ print("Styles:")
130
+ print("~~~~~~~")
131
+
132
+ for name in get_all_styles():
133
+ cls = get_style_by_name(name)
134
+ print("* " + name + ':')
135
+ print(f" {docstring_headline(cls)}")
136
+
137
+
138
+ def _print_list_as_json(requested_items):
139
+ import json
140
+ result = {}
141
+ if 'lexer' in requested_items:
142
+ info = {}
143
+ for fullname, names, filenames, mimetypes in get_all_lexers():
144
+ info[fullname] = {
145
+ 'aliases': names,
146
+ 'filenames': filenames,
147
+ 'mimetypes': mimetypes
148
+ }
149
+ result['lexers'] = info
150
+
151
+ if 'formatter' in requested_items:
152
+ info = {}
153
+ for cls in get_all_formatters():
154
+ doc = docstring_headline(cls)
155
+ info[cls.name] = {
156
+ 'aliases': cls.aliases,
157
+ 'filenames': cls.filenames,
158
+ 'doc': doc
159
+ }
160
+ result['formatters'] = info
161
+
162
+ if 'filter' in requested_items:
163
+ info = {}
164
+ for name in get_all_filters():
165
+ cls = find_filter_class(name)
166
+ info[name] = {
167
+ 'doc': docstring_headline(cls)
168
+ }
169
+ result['filters'] = info
170
+
171
+ if 'style' in requested_items:
172
+ info = {}
173
+ for name in get_all_styles():
174
+ cls = get_style_by_name(name)
175
+ info[name] = {
176
+ 'doc': docstring_headline(cls)
177
+ }
178
+ result['styles'] = info
179
+
180
+ json.dump(result, sys.stdout)
181
+
182
+ def main_inner(parser, argns):
183
+ if argns.help:
184
+ parser.print_help()
185
+ return 0
186
+
187
+ if argns.V:
188
+ print(f'Pygments version {__version__}, (c) 2006-2024 by Georg Brandl, Matthäus '
189
+ 'Chajdas and contributors.')
190
+ return 0
191
+
192
+ def is_only_option(opt):
193
+ return not any(v for (k, v) in vars(argns).items() if k != opt)
194
+
195
+ # handle ``pygmentize -L``
196
+ if argns.L is not None:
197
+ arg_set = set()
198
+ for k, v in vars(argns).items():
199
+ if v:
200
+ arg_set.add(k)
201
+
202
+ arg_set.discard('L')
203
+ arg_set.discard('json')
204
+
205
+ if arg_set:
206
+ parser.print_help(sys.stderr)
207
+ return 2
208
+
209
+ # print version
210
+ if not argns.json:
211
+ main(['', '-V'])
212
+ allowed_types = {'lexer', 'formatter', 'filter', 'style'}
213
+ largs = [arg.rstrip('s') for arg in argns.L]
214
+ if any(arg not in allowed_types for arg in largs):
215
+ parser.print_help(sys.stderr)
216
+ return 0
217
+ if not largs:
218
+ largs = allowed_types
219
+ if not argns.json:
220
+ for arg in largs:
221
+ _print_list(arg)
222
+ else:
223
+ _print_list_as_json(largs)
224
+ return 0
225
+
226
+ # handle ``pygmentize -H``
227
+ if argns.H:
228
+ if not is_only_option('H'):
229
+ parser.print_help(sys.stderr)
230
+ return 2
231
+ what, name = argns.H
232
+ if what not in ('lexer', 'formatter', 'filter'):
233
+ parser.print_help(sys.stderr)
234
+ return 2
235
+ return _print_help(what, name)
236
+
237
+ # parse -O options
238
+ parsed_opts = _parse_options(argns.O or [])
239
+
240
+ # parse -P options
241
+ for p_opt in argns.P or []:
242
+ try:
243
+ name, value = p_opt.split('=', 1)
244
+ except ValueError:
245
+ parsed_opts[p_opt] = True
246
+ else:
247
+ parsed_opts[name] = value
248
+
249
+ # encodings
250
+ inencoding = parsed_opts.get('inencoding', parsed_opts.get('encoding'))
251
+ outencoding = parsed_opts.get('outencoding', parsed_opts.get('encoding'))
252
+
253
+ # handle ``pygmentize -N``
254
+ if argns.N:
255
+ lexer = find_lexer_class_for_filename(argns.N)
256
+ if lexer is None:
257
+ lexer = TextLexer
258
+
259
+ print(lexer.aliases[0])
260
+ return 0
261
+
262
+ # handle ``pygmentize -C``
263
+ if argns.C:
264
+ inp = sys.stdin.buffer.read()
265
+ try:
266
+ lexer = guess_lexer(inp, inencoding=inencoding)
267
+ except ClassNotFound:
268
+ lexer = TextLexer
269
+
270
+ print(lexer.aliases[0])
271
+ return 0
272
+
273
+ # handle ``pygmentize -S``
274
+ S_opt = argns.S
275
+ a_opt = argns.a
276
+ if S_opt is not None:
277
+ f_opt = argns.f
278
+ if not f_opt:
279
+ parser.print_help(sys.stderr)
280
+ return 2
281
+ if argns.l or argns.INPUTFILE:
282
+ parser.print_help(sys.stderr)
283
+ return 2
284
+
285
+ try:
286
+ parsed_opts['style'] = S_opt
287
+ fmter = get_formatter_by_name(f_opt, **parsed_opts)
288
+ except ClassNotFound as err:
289
+ print(err, file=sys.stderr)
290
+ return 1
291
+
292
+ print(fmter.get_style_defs(a_opt or ''))
293
+ return 0
294
+
295
+ # if no -S is given, -a is not allowed
296
+ if argns.a is not None:
297
+ parser.print_help(sys.stderr)
298
+ return 2
299
+
300
+ # parse -F options
301
+ F_opts = _parse_filters(argns.F or [])
302
+
303
+ # -x: allow custom (eXternal) lexers and formatters
304
+ allow_custom_lexer_formatter = bool(argns.x)
305
+
306
+ # select lexer
307
+ lexer = None
308
+
309
+ # given by name?
310
+ lexername = argns.l
311
+ if lexername:
312
+ # custom lexer, located relative to user's cwd
313
+ if allow_custom_lexer_formatter and '.py' in lexername:
314
+ try:
315
+ filename = None
316
+ name = None
317
+ if ':' in lexername:
318
+ filename, name = lexername.rsplit(':', 1)
319
+
320
+ if '.py' in name:
321
+ # This can happen on Windows: If the lexername is
322
+ # C:\lexer.py -- return to normal load path in that case
323
+ name = None
324
+
325
+ if filename and name:
326
+ lexer = load_lexer_from_file(filename, name,
327
+ **parsed_opts)
328
+ else:
329
+ lexer = load_lexer_from_file(lexername, **parsed_opts)
330
+ except ClassNotFound as err:
331
+ print('Error:', err, file=sys.stderr)
332
+ return 1
333
+ else:
334
+ try:
335
+ lexer = get_lexer_by_name(lexername, **parsed_opts)
336
+ except (OptionError, ClassNotFound) as err:
337
+ print('Error:', err, file=sys.stderr)
338
+ return 1
339
+
340
+ # read input code
341
+ code = None
342
+
343
+ if argns.INPUTFILE:
344
+ if argns.s:
345
+ print('Error: -s option not usable when input file specified',
346
+ file=sys.stderr)
347
+ return 2
348
+
349
+ infn = argns.INPUTFILE
350
+ try:
351
+ with open(infn, 'rb') as infp:
352
+ code = infp.read()
353
+ except Exception as err:
354
+ print('Error: cannot read infile:', err, file=sys.stderr)
355
+ return 1
356
+ if not inencoding:
357
+ code, inencoding = guess_decode(code)
358
+
359
+ # do we have to guess the lexer?
360
+ if not lexer:
361
+ try:
362
+ lexer = get_lexer_for_filename(infn, code, **parsed_opts)
363
+ except ClassNotFound as err:
364
+ if argns.g:
365
+ try:
366
+ lexer = guess_lexer(code, **parsed_opts)
367
+ except ClassNotFound:
368
+ lexer = TextLexer(**parsed_opts)
369
+ else:
370
+ print('Error:', err, file=sys.stderr)
371
+ return 1
372
+ except OptionError as err:
373
+ print('Error:', err, file=sys.stderr)
374
+ return 1
375
+
376
+ elif not argns.s: # treat stdin as full file (-s support is later)
377
+ # read code from terminal, always in binary mode since we want to
378
+ # decode ourselves and be tolerant with it
379
+ code = sys.stdin.buffer.read() # use .buffer to get a binary stream
380
+ if not inencoding:
381
+ code, inencoding = guess_decode_from_terminal(code, sys.stdin)
382
+ # else the lexer will do the decoding
383
+ if not lexer:
384
+ try:
385
+ lexer = guess_lexer(code, **parsed_opts)
386
+ except ClassNotFound:
387
+ lexer = TextLexer(**parsed_opts)
388
+
389
+ else: # -s option needs a lexer with -l
390
+ if not lexer:
391
+ print('Error: when using -s a lexer has to be selected with -l',
392
+ file=sys.stderr)
393
+ return 2
394
+
395
+ # process filters
396
+ for fname, fopts in F_opts:
397
+ try:
398
+ lexer.add_filter(fname, **fopts)
399
+ except ClassNotFound as err:
400
+ print('Error:', err, file=sys.stderr)
401
+ return 1
402
+
403
+ # select formatter
404
+ outfn = argns.o
405
+ fmter = argns.f
406
+ if fmter:
407
+ # custom formatter, located relative to user's cwd
408
+ if allow_custom_lexer_formatter and '.py' in fmter:
409
+ try:
410
+ filename = None
411
+ name = None
412
+ if ':' in fmter:
413
+ # Same logic as above for custom lexer
414
+ filename, name = fmter.rsplit(':', 1)
415
+
416
+ if '.py' in name:
417
+ name = None
418
+
419
+ if filename and name:
420
+ fmter = load_formatter_from_file(filename, name,
421
+ **parsed_opts)
422
+ else:
423
+ fmter = load_formatter_from_file(fmter, **parsed_opts)
424
+ except ClassNotFound as err:
425
+ print('Error:', err, file=sys.stderr)
426
+ return 1
427
+ else:
428
+ try:
429
+ fmter = get_formatter_by_name(fmter, **parsed_opts)
430
+ except (OptionError, ClassNotFound) as err:
431
+ print('Error:', err, file=sys.stderr)
432
+ return 1
433
+
434
+ if outfn:
435
+ if not fmter:
436
+ try:
437
+ fmter = get_formatter_for_filename(outfn, **parsed_opts)
438
+ except (OptionError, ClassNotFound) as err:
439
+ print('Error:', err, file=sys.stderr)
440
+ return 1
441
+ try:
442
+ outfile = open(outfn, 'wb')
443
+ except Exception as err:
444
+ print('Error: cannot open outfile:', err, file=sys.stderr)
445
+ return 1
446
+ else:
447
+ if not fmter:
448
+ if os.environ.get('COLORTERM','') in ('truecolor', '24bit'):
449
+ fmter = TerminalTrueColorFormatter(**parsed_opts)
450
+ elif '256' in os.environ.get('TERM', ''):
451
+ fmter = Terminal256Formatter(**parsed_opts)
452
+ else:
453
+ fmter = TerminalFormatter(**parsed_opts)
454
+ outfile = sys.stdout.buffer
455
+
456
+ # determine output encoding if not explicitly selected
457
+ if not outencoding:
458
+ if outfn:
459
+ # output file? use lexer encoding for now (can still be None)
460
+ fmter.encoding = inencoding
461
+ else:
462
+ # else use terminal encoding
463
+ fmter.encoding = terminal_encoding(sys.stdout)
464
+
465
+ # provide coloring under Windows, if possible
466
+ if not outfn and sys.platform in ('win32', 'cygwin') and \
467
+ fmter.name in ('Terminal', 'Terminal256'): # pragma: no cover
468
+ # unfortunately colorama doesn't support binary streams on Py3
469
+ outfile = UnclosingTextIOWrapper(outfile, encoding=fmter.encoding)
470
+ fmter.encoding = None
471
+ try:
472
+ import colorama.initialise
473
+ except ImportError:
474
+ pass
475
+ else:
476
+ outfile = colorama.initialise.wrap_stream(
477
+ outfile, convert=None, strip=None, autoreset=False, wrap=True)
478
+
479
+ # When using the LaTeX formatter and the option `escapeinside` is
480
+ # specified, we need a special lexer which collects escaped text
481
+ # before running the chosen language lexer.
482
+ escapeinside = parsed_opts.get('escapeinside', '')
483
+ if len(escapeinside) == 2 and isinstance(fmter, LatexFormatter):
484
+ left = escapeinside[0]
485
+ right = escapeinside[1]
486
+ lexer = LatexEmbeddedLexer(left, right, lexer)
487
+
488
+ # ... and do it!
489
+ if not argns.s:
490
+ # process whole input as per normal...
491
+ try:
492
+ highlight(code, lexer, fmter, outfile)
493
+ finally:
494
+ if outfn:
495
+ outfile.close()
496
+ return 0
497
+ else:
498
+ # line by line processing of stdin (eg: for 'tail -f')...
499
+ try:
500
+ while 1:
501
+ line = sys.stdin.buffer.readline()
502
+ if not line:
503
+ break
504
+ if not inencoding:
505
+ line = guess_decode_from_terminal(line, sys.stdin)[0]
506
+ highlight(line, lexer, fmter, outfile)
507
+ if hasattr(outfile, 'flush'):
508
+ outfile.flush()
509
+ return 0
510
+ except KeyboardInterrupt: # pragma: no cover
511
+ return 0
512
+ finally:
513
+ if outfn:
514
+ outfile.close()
515
+
516
+
517
+ class HelpFormatter(argparse.HelpFormatter):
518
+ def __init__(self, prog, indent_increment=2, max_help_position=16, width=None):
519
+ if width is None:
520
+ try:
521
+ width = shutil.get_terminal_size().columns - 2
522
+ except Exception:
523
+ pass
524
+ argparse.HelpFormatter.__init__(self, prog, indent_increment,
525
+ max_help_position, width)
526
+
527
+
528
+ def main(args=sys.argv):
529
+ """
530
+ Main command line entry point.
531
+ """
532
+ desc = "Highlight an input file and write the result to an output file."
533
+ parser = argparse.ArgumentParser(description=desc, add_help=False,
534
+ formatter_class=HelpFormatter)
535
+
536
+ operation = parser.add_argument_group('Main operation')
537
+ lexersel = operation.add_mutually_exclusive_group()
538
+ lexersel.add_argument(
539
+ '-l', metavar='LEXER',
540
+ help='Specify the lexer to use. (Query names with -L.) If not '
541
+ 'given and -g is not present, the lexer is guessed from the filename.')
542
+ lexersel.add_argument(
543
+ '-g', action='store_true',
544
+ help='Guess the lexer from the file contents, or pass through '
545
+ 'as plain text if nothing can be guessed.')
546
+ operation.add_argument(
547
+ '-F', metavar='FILTER[:options]', action='append',
548
+ help='Add a filter to the token stream. (Query names with -L.) '
549
+ 'Filter options are given after a colon if necessary.')
550
+ operation.add_argument(
551
+ '-f', metavar='FORMATTER',
552
+ help='Specify the formatter to use. (Query names with -L.) '
553
+ 'If not given, the formatter is guessed from the output filename, '
554
+ 'and defaults to the terminal formatter if the output is to the '
555
+ 'terminal or an unknown file extension.')
556
+ operation.add_argument(
557
+ '-O', metavar='OPTION=value[,OPTION=value,...]', action='append',
558
+ help='Give options to the lexer and formatter as a comma-separated '
559
+ 'list of key-value pairs. '
560
+ 'Example: `-O bg=light,python=cool`.')
561
+ operation.add_argument(
562
+ '-P', metavar='OPTION=value', action='append',
563
+ help='Give a single option to the lexer and formatter - with this '
564
+ 'you can pass options whose value contains commas and equal signs. '
565
+ 'Example: `-P "heading=Pygments, the Python highlighter"`.')
566
+ operation.add_argument(
567
+ '-o', metavar='OUTPUTFILE',
568
+ help='Where to write the output. Defaults to standard output.')
569
+
570
+ operation.add_argument(
571
+ 'INPUTFILE', nargs='?',
572
+ help='Where to read the input. Defaults to standard input.')
573
+
574
+ flags = parser.add_argument_group('Operation flags')
575
+ flags.add_argument(
576
+ '-v', action='store_true',
577
+ help='Print a detailed traceback on unhandled exceptions, which '
578
+ 'is useful for debugging and bug reports.')
579
+ flags.add_argument(
580
+ '-s', action='store_true',
581
+ help='Process lines one at a time until EOF, rather than waiting to '
582
+ 'process the entire file. This only works for stdin, only for lexers '
583
+ 'with no line-spanning constructs, and is intended for streaming '
584
+ 'input such as you get from `tail -f`. '
585
+ 'Example usage: `tail -f sql.log | pygmentize -s -l sql`.')
586
+ flags.add_argument(
587
+ '-x', action='store_true',
588
+ help='Allow custom lexers and formatters to be loaded from a .py file '
589
+ 'relative to the current working directory. For example, '
590
+ '`-l ./customlexer.py -x`. By default, this option expects a file '
591
+ 'with a class named CustomLexer or CustomFormatter; you can also '
592
+ 'specify your own class name with a colon (`-l ./lexer.py:MyLexer`). '
593
+ 'Users should be very careful not to use this option with untrusted '
594
+ 'files, because it will import and run them.')
595
+ flags.add_argument('--json', help='Output as JSON. This can '
596
+ 'be only used in conjunction with -L.',
597
+ default=False,
598
+ action='store_true')
599
+
600
+ special_modes_group = parser.add_argument_group(
601
+ 'Special modes - do not do any highlighting')
602
+ special_modes = special_modes_group.add_mutually_exclusive_group()
603
+ special_modes.add_argument(
604
+ '-S', metavar='STYLE -f formatter',
605
+ help='Print style definitions for STYLE for a formatter '
606
+ 'given with -f. The argument given by -a is formatter '
607
+ 'dependent.')
608
+ special_modes.add_argument(
609
+ '-L', nargs='*', metavar='WHAT',
610
+ help='List lexers, formatters, styles or filters -- '
611
+ 'give additional arguments for the thing(s) you want to list '
612
+ '(e.g. "styles"), or omit them to list everything.')
613
+ special_modes.add_argument(
614
+ '-N', metavar='FILENAME',
615
+ help='Guess and print out a lexer name based solely on the given '
616
+ 'filename. Does not take input or highlight anything. If no specific '
617
+ 'lexer can be determined, "text" is printed.')
618
+ special_modes.add_argument(
619
+ '-C', action='store_true',
620
+ help='Like -N, but print out a lexer name based solely on '
621
+ 'a given content from standard input.')
622
+ special_modes.add_argument(
623
+ '-H', action='store', nargs=2, metavar=('NAME', 'TYPE'),
624
+ help='Print detailed help for the object <name> of type <type>, '
625
+ 'where <type> is one of "lexer", "formatter" or "filter".')
626
+ special_modes.add_argument(
627
+ '-V', action='store_true',
628
+ help='Print the package version.')
629
+ special_modes.add_argument(
630
+ '-h', '--help', action='store_true',
631
+ help='Print this help.')
632
+ special_modes_group.add_argument(
633
+ '-a', metavar='ARG',
634
+ help='Formatter-specific additional argument for the -S (print '
635
+ 'style sheet) mode.')
636
+
637
+ argns = parser.parse_args(args[1:])
638
+
639
+ try:
640
+ return main_inner(parser, argns)
641
+ except BrokenPipeError:
642
+ # someone closed our stdout, e.g. by quitting a pager.
643
+ return 0
644
+ except Exception:
645
+ if argns.v:
646
+ print(file=sys.stderr)
647
+ print('*' * 65, file=sys.stderr)
648
+ print('An unhandled exception occurred while highlighting.',
649
+ file=sys.stderr)
650
+ print('Please report the whole traceback to the issue tracker at',
651
+ file=sys.stderr)
652
+ print('<https://github.com/pygments/pygments/issues>.',
653
+ file=sys.stderr)
654
+ print('*' * 65, file=sys.stderr)
655
+ print(file=sys.stderr)
656
+ raise
657
+ import traceback
658
+ info = traceback.format_exception(*sys.exc_info())
659
+ msg = info[-1].strip()
660
+ if len(info) >= 3:
661
+ # extract relevant file and position info
662
+ msg += '\n (f{})'.format(info[-2].split('\n')[0].strip()[1:])
663
+ print(file=sys.stderr)
664
+ print('*** Error while highlighting:', file=sys.stderr)
665
+ print(msg, file=sys.stderr)
666
+ print('*** If this is a bug you want to report, please rerun with -v.',
667
+ file=sys.stderr)
668
+ return 1
lib/python3.12/site-packages/pygments/console.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.console
3
+ ~~~~~~~~~~~~~~~~
4
+
5
+ Format colored console output.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ esc = "\x1b["
12
+
13
+ codes = {}
14
+ codes[""] = ""
15
+ codes["reset"] = esc + "39;49;00m"
16
+
17
+ codes["bold"] = esc + "01m"
18
+ codes["faint"] = esc + "02m"
19
+ codes["standout"] = esc + "03m"
20
+ codes["underline"] = esc + "04m"
21
+ codes["blink"] = esc + "05m"
22
+ codes["overline"] = esc + "06m"
23
+
24
+ dark_colors = ["black", "red", "green", "yellow", "blue",
25
+ "magenta", "cyan", "gray"]
26
+ light_colors = ["brightblack", "brightred", "brightgreen", "brightyellow", "brightblue",
27
+ "brightmagenta", "brightcyan", "white"]
28
+
29
+ x = 30
30
+ for dark, light in zip(dark_colors, light_colors):
31
+ codes[dark] = esc + "%im" % x
32
+ codes[light] = esc + "%im" % (60 + x)
33
+ x += 1
34
+
35
+ del dark, light, x
36
+
37
+ codes["white"] = codes["bold"]
38
+
39
+
40
+ def reset_color():
41
+ return codes["reset"]
42
+
43
+
44
+ def colorize(color_key, text):
45
+ return codes[color_key] + text + codes["reset"]
46
+
47
+
48
+ def ansiformat(attr, text):
49
+ """
50
+ Format ``text`` with a color and/or some attributes::
51
+
52
+ color normal color
53
+ *color* bold color
54
+ _color_ underlined color
55
+ +color+ blinking color
56
+ """
57
+ result = []
58
+ if attr[:1] == attr[-1:] == '+':
59
+ result.append(codes['blink'])
60
+ attr = attr[1:-1]
61
+ if attr[:1] == attr[-1:] == '*':
62
+ result.append(codes['bold'])
63
+ attr = attr[1:-1]
64
+ if attr[:1] == attr[-1:] == '_':
65
+ result.append(codes['underline'])
66
+ attr = attr[1:-1]
67
+ result.append(codes[attr])
68
+ result.append(text)
69
+ result.append(codes['reset'])
70
+ return ''.join(result)
lib/python3.12/site-packages/pygments/filter.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.filter
3
+ ~~~~~~~~~~~~~~~
4
+
5
+ Module that implements the default filter.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+
12
+ def apply_filters(stream, filters, lexer=None):
13
+ """
14
+ Use this method to apply an iterable of filters to
15
+ a stream. If lexer is given it's forwarded to the
16
+ filter, otherwise the filter receives `None`.
17
+ """
18
+ def _apply(filter_, stream):
19
+ yield from filter_.filter(lexer, stream)
20
+ for filter_ in filters:
21
+ stream = _apply(filter_, stream)
22
+ return stream
23
+
24
+
25
+ def simplefilter(f):
26
+ """
27
+ Decorator that converts a function into a filter::
28
+
29
+ @simplefilter
30
+ def lowercase(self, lexer, stream, options):
31
+ for ttype, value in stream:
32
+ yield ttype, value.lower()
33
+ """
34
+ return type(f.__name__, (FunctionFilter,), {
35
+ '__module__': getattr(f, '__module__'),
36
+ '__doc__': f.__doc__,
37
+ 'function': f,
38
+ })
39
+
40
+
41
+ class Filter:
42
+ """
43
+ Default filter. Subclass this class or use the `simplefilter`
44
+ decorator to create own filters.
45
+ """
46
+
47
+ def __init__(self, **options):
48
+ self.options = options
49
+
50
+ def filter(self, lexer, stream):
51
+ raise NotImplementedError()
52
+
53
+
54
+ class FunctionFilter(Filter):
55
+ """
56
+ Abstract class used by `simplefilter` to create simple
57
+ function filters on the fly. The `simplefilter` decorator
58
+ automatically creates subclasses of this class for
59
+ functions passed to it.
60
+ """
61
+ function = None
62
+
63
+ def __init__(self, **options):
64
+ if not hasattr(self, 'function'):
65
+ raise TypeError(f'{self.__class__.__name__!r} used without bound function')
66
+ Filter.__init__(self, **options)
67
+
68
+ def filter(self, lexer, stream):
69
+ # pylint: disable=not-callable
70
+ yield from self.function(lexer, stream, self.options)
lib/python3.12/site-packages/pygments/filters/__init__.py ADDED
@@ -0,0 +1,940 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.filters
3
+ ~~~~~~~~~~~~~~~~
4
+
5
+ Module containing filter lookup functions and default
6
+ filters.
7
+
8
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
9
+ :license: BSD, see LICENSE for details.
10
+ """
11
+
12
+ import re
13
+
14
+ from pygments.token import String, Comment, Keyword, Name, Error, Whitespace, \
15
+ string_to_tokentype
16
+ from pygments.filter import Filter
17
+ from pygments.util import get_list_opt, get_int_opt, get_bool_opt, \
18
+ get_choice_opt, ClassNotFound, OptionError
19
+ from pygments.plugin import find_plugin_filters
20
+
21
+
22
+ def find_filter_class(filtername):
23
+ """Lookup a filter by name. Return None if not found."""
24
+ if filtername in FILTERS:
25
+ return FILTERS[filtername]
26
+ for name, cls in find_plugin_filters():
27
+ if name == filtername:
28
+ return cls
29
+ return None
30
+
31
+
32
+ def get_filter_by_name(filtername, **options):
33
+ """Return an instantiated filter.
34
+
35
+ Options are passed to the filter initializer if wanted.
36
+ Raise a ClassNotFound if not found.
37
+ """
38
+ cls = find_filter_class(filtername)
39
+ if cls:
40
+ return cls(**options)
41
+ else:
42
+ raise ClassNotFound(f'filter {filtername!r} not found')
43
+
44
+
45
+ def get_all_filters():
46
+ """Return a generator of all filter names."""
47
+ yield from FILTERS
48
+ for name, _ in find_plugin_filters():
49
+ yield name
50
+
51
+
52
+ def _replace_special(ttype, value, regex, specialttype,
53
+ replacefunc=lambda x: x):
54
+ last = 0
55
+ for match in regex.finditer(value):
56
+ start, end = match.start(), match.end()
57
+ if start != last:
58
+ yield ttype, value[last:start]
59
+ yield specialttype, replacefunc(value[start:end])
60
+ last = end
61
+ if last != len(value):
62
+ yield ttype, value[last:]
63
+
64
+
65
+ class CodeTagFilter(Filter):
66
+ """Highlight special code tags in comments and docstrings.
67
+
68
+ Options accepted:
69
+
70
+ `codetags` : list of strings
71
+ A list of strings that are flagged as code tags. The default is to
72
+ highlight ``XXX``, ``TODO``, ``FIXME``, ``BUG`` and ``NOTE``.
73
+
74
+ .. versionchanged:: 2.13
75
+ Now recognizes ``FIXME`` by default.
76
+ """
77
+
78
+ def __init__(self, **options):
79
+ Filter.__init__(self, **options)
80
+ tags = get_list_opt(options, 'codetags',
81
+ ['XXX', 'TODO', 'FIXME', 'BUG', 'NOTE'])
82
+ self.tag_re = re.compile(r'\b({})\b'.format('|'.join([
83
+ re.escape(tag) for tag in tags if tag
84
+ ])))
85
+
86
+ def filter(self, lexer, stream):
87
+ regex = self.tag_re
88
+ for ttype, value in stream:
89
+ if ttype in String.Doc or \
90
+ ttype in Comment and \
91
+ ttype not in Comment.Preproc:
92
+ yield from _replace_special(ttype, value, regex, Comment.Special)
93
+ else:
94
+ yield ttype, value
95
+
96
+
97
+ class SymbolFilter(Filter):
98
+ """Convert mathematical symbols such as \\<longrightarrow> in Isabelle
99
+ or \\longrightarrow in LaTeX into Unicode characters.
100
+
101
+ This is mostly useful for HTML or console output when you want to
102
+ approximate the source rendering you'd see in an IDE.
103
+
104
+ Options accepted:
105
+
106
+ `lang` : string
107
+ The symbol language. Must be one of ``'isabelle'`` or
108
+ ``'latex'``. The default is ``'isabelle'``.
109
+ """
110
+
111
+ latex_symbols = {
112
+ '\\alpha' : '\U000003b1',
113
+ '\\beta' : '\U000003b2',
114
+ '\\gamma' : '\U000003b3',
115
+ '\\delta' : '\U000003b4',
116
+ '\\varepsilon' : '\U000003b5',
117
+ '\\zeta' : '\U000003b6',
118
+ '\\eta' : '\U000003b7',
119
+ '\\vartheta' : '\U000003b8',
120
+ '\\iota' : '\U000003b9',
121
+ '\\kappa' : '\U000003ba',
122
+ '\\lambda' : '\U000003bb',
123
+ '\\mu' : '\U000003bc',
124
+ '\\nu' : '\U000003bd',
125
+ '\\xi' : '\U000003be',
126
+ '\\pi' : '\U000003c0',
127
+ '\\varrho' : '\U000003c1',
128
+ '\\sigma' : '\U000003c3',
129
+ '\\tau' : '\U000003c4',
130
+ '\\upsilon' : '\U000003c5',
131
+ '\\varphi' : '\U000003c6',
132
+ '\\chi' : '\U000003c7',
133
+ '\\psi' : '\U000003c8',
134
+ '\\omega' : '\U000003c9',
135
+ '\\Gamma' : '\U00000393',
136
+ '\\Delta' : '\U00000394',
137
+ '\\Theta' : '\U00000398',
138
+ '\\Lambda' : '\U0000039b',
139
+ '\\Xi' : '\U0000039e',
140
+ '\\Pi' : '\U000003a0',
141
+ '\\Sigma' : '\U000003a3',
142
+ '\\Upsilon' : '\U000003a5',
143
+ '\\Phi' : '\U000003a6',
144
+ '\\Psi' : '\U000003a8',
145
+ '\\Omega' : '\U000003a9',
146
+ '\\leftarrow' : '\U00002190',
147
+ '\\longleftarrow' : '\U000027f5',
148
+ '\\rightarrow' : '\U00002192',
149
+ '\\longrightarrow' : '\U000027f6',
150
+ '\\Leftarrow' : '\U000021d0',
151
+ '\\Longleftarrow' : '\U000027f8',
152
+ '\\Rightarrow' : '\U000021d2',
153
+ '\\Longrightarrow' : '\U000027f9',
154
+ '\\leftrightarrow' : '\U00002194',
155
+ '\\longleftrightarrow' : '\U000027f7',
156
+ '\\Leftrightarrow' : '\U000021d4',
157
+ '\\Longleftrightarrow' : '\U000027fa',
158
+ '\\mapsto' : '\U000021a6',
159
+ '\\longmapsto' : '\U000027fc',
160
+ '\\relbar' : '\U00002500',
161
+ '\\Relbar' : '\U00002550',
162
+ '\\hookleftarrow' : '\U000021a9',
163
+ '\\hookrightarrow' : '\U000021aa',
164
+ '\\leftharpoondown' : '\U000021bd',
165
+ '\\rightharpoondown' : '\U000021c1',
166
+ '\\leftharpoonup' : '\U000021bc',
167
+ '\\rightharpoonup' : '\U000021c0',
168
+ '\\rightleftharpoons' : '\U000021cc',
169
+ '\\leadsto' : '\U0000219d',
170
+ '\\downharpoonleft' : '\U000021c3',
171
+ '\\downharpoonright' : '\U000021c2',
172
+ '\\upharpoonleft' : '\U000021bf',
173
+ '\\upharpoonright' : '\U000021be',
174
+ '\\restriction' : '\U000021be',
175
+ '\\uparrow' : '\U00002191',
176
+ '\\Uparrow' : '\U000021d1',
177
+ '\\downarrow' : '\U00002193',
178
+ '\\Downarrow' : '\U000021d3',
179
+ '\\updownarrow' : '\U00002195',
180
+ '\\Updownarrow' : '\U000021d5',
181
+ '\\langle' : '\U000027e8',
182
+ '\\rangle' : '\U000027e9',
183
+ '\\lceil' : '\U00002308',
184
+ '\\rceil' : '\U00002309',
185
+ '\\lfloor' : '\U0000230a',
186
+ '\\rfloor' : '\U0000230b',
187
+ '\\flqq' : '\U000000ab',
188
+ '\\frqq' : '\U000000bb',
189
+ '\\bot' : '\U000022a5',
190
+ '\\top' : '\U000022a4',
191
+ '\\wedge' : '\U00002227',
192
+ '\\bigwedge' : '\U000022c0',
193
+ '\\vee' : '\U00002228',
194
+ '\\bigvee' : '\U000022c1',
195
+ '\\forall' : '\U00002200',
196
+ '\\exists' : '\U00002203',
197
+ '\\nexists' : '\U00002204',
198
+ '\\neg' : '\U000000ac',
199
+ '\\Box' : '\U000025a1',
200
+ '\\Diamond' : '\U000025c7',
201
+ '\\vdash' : '\U000022a2',
202
+ '\\models' : '\U000022a8',
203
+ '\\dashv' : '\U000022a3',
204
+ '\\surd' : '\U0000221a',
205
+ '\\le' : '\U00002264',
206
+ '\\ge' : '\U00002265',
207
+ '\\ll' : '\U0000226a',
208
+ '\\gg' : '\U0000226b',
209
+ '\\lesssim' : '\U00002272',
210
+ '\\gtrsim' : '\U00002273',
211
+ '\\lessapprox' : '\U00002a85',
212
+ '\\gtrapprox' : '\U00002a86',
213
+ '\\in' : '\U00002208',
214
+ '\\notin' : '\U00002209',
215
+ '\\subset' : '\U00002282',
216
+ '\\supset' : '\U00002283',
217
+ '\\subseteq' : '\U00002286',
218
+ '\\supseteq' : '\U00002287',
219
+ '\\sqsubset' : '\U0000228f',
220
+ '\\sqsupset' : '\U00002290',
221
+ '\\sqsubseteq' : '\U00002291',
222
+ '\\sqsupseteq' : '\U00002292',
223
+ '\\cap' : '\U00002229',
224
+ '\\bigcap' : '\U000022c2',
225
+ '\\cup' : '\U0000222a',
226
+ '\\bigcup' : '\U000022c3',
227
+ '\\sqcup' : '\U00002294',
228
+ '\\bigsqcup' : '\U00002a06',
229
+ '\\sqcap' : '\U00002293',
230
+ '\\Bigsqcap' : '\U00002a05',
231
+ '\\setminus' : '\U00002216',
232
+ '\\propto' : '\U0000221d',
233
+ '\\uplus' : '\U0000228e',
234
+ '\\bigplus' : '\U00002a04',
235
+ '\\sim' : '\U0000223c',
236
+ '\\doteq' : '\U00002250',
237
+ '\\simeq' : '\U00002243',
238
+ '\\approx' : '\U00002248',
239
+ '\\asymp' : '\U0000224d',
240
+ '\\cong' : '\U00002245',
241
+ '\\equiv' : '\U00002261',
242
+ '\\Join' : '\U000022c8',
243
+ '\\bowtie' : '\U00002a1d',
244
+ '\\prec' : '\U0000227a',
245
+ '\\succ' : '\U0000227b',
246
+ '\\preceq' : '\U0000227c',
247
+ '\\succeq' : '\U0000227d',
248
+ '\\parallel' : '\U00002225',
249
+ '\\mid' : '\U000000a6',
250
+ '\\pm' : '\U000000b1',
251
+ '\\mp' : '\U00002213',
252
+ '\\times' : '\U000000d7',
253
+ '\\div' : '\U000000f7',
254
+ '\\cdot' : '\U000022c5',
255
+ '\\star' : '\U000022c6',
256
+ '\\circ' : '\U00002218',
257
+ '\\dagger' : '\U00002020',
258
+ '\\ddagger' : '\U00002021',
259
+ '\\lhd' : '\U000022b2',
260
+ '\\rhd' : '\U000022b3',
261
+ '\\unlhd' : '\U000022b4',
262
+ '\\unrhd' : '\U000022b5',
263
+ '\\triangleleft' : '\U000025c3',
264
+ '\\triangleright' : '\U000025b9',
265
+ '\\triangle' : '\U000025b3',
266
+ '\\triangleq' : '\U0000225c',
267
+ '\\oplus' : '\U00002295',
268
+ '\\bigoplus' : '\U00002a01',
269
+ '\\otimes' : '\U00002297',
270
+ '\\bigotimes' : '\U00002a02',
271
+ '\\odot' : '\U00002299',
272
+ '\\bigodot' : '\U00002a00',
273
+ '\\ominus' : '\U00002296',
274
+ '\\oslash' : '\U00002298',
275
+ '\\dots' : '\U00002026',
276
+ '\\cdots' : '\U000022ef',
277
+ '\\sum' : '\U00002211',
278
+ '\\prod' : '\U0000220f',
279
+ '\\coprod' : '\U00002210',
280
+ '\\infty' : '\U0000221e',
281
+ '\\int' : '\U0000222b',
282
+ '\\oint' : '\U0000222e',
283
+ '\\clubsuit' : '\U00002663',
284
+ '\\diamondsuit' : '\U00002662',
285
+ '\\heartsuit' : '\U00002661',
286
+ '\\spadesuit' : '\U00002660',
287
+ '\\aleph' : '\U00002135',
288
+ '\\emptyset' : '\U00002205',
289
+ '\\nabla' : '\U00002207',
290
+ '\\partial' : '\U00002202',
291
+ '\\flat' : '\U0000266d',
292
+ '\\natural' : '\U0000266e',
293
+ '\\sharp' : '\U0000266f',
294
+ '\\angle' : '\U00002220',
295
+ '\\copyright' : '\U000000a9',
296
+ '\\textregistered' : '\U000000ae',
297
+ '\\textonequarter' : '\U000000bc',
298
+ '\\textonehalf' : '\U000000bd',
299
+ '\\textthreequarters' : '\U000000be',
300
+ '\\textordfeminine' : '\U000000aa',
301
+ '\\textordmasculine' : '\U000000ba',
302
+ '\\euro' : '\U000020ac',
303
+ '\\pounds' : '\U000000a3',
304
+ '\\yen' : '\U000000a5',
305
+ '\\textcent' : '\U000000a2',
306
+ '\\textcurrency' : '\U000000a4',
307
+ '\\textdegree' : '\U000000b0',
308
+ }
309
+
310
+ isabelle_symbols = {
311
+ '\\<zero>' : '\U0001d7ec',
312
+ '\\<one>' : '\U0001d7ed',
313
+ '\\<two>' : '\U0001d7ee',
314
+ '\\<three>' : '\U0001d7ef',
315
+ '\\<four>' : '\U0001d7f0',
316
+ '\\<five>' : '\U0001d7f1',
317
+ '\\<six>' : '\U0001d7f2',
318
+ '\\<seven>' : '\U0001d7f3',
319
+ '\\<eight>' : '\U0001d7f4',
320
+ '\\<nine>' : '\U0001d7f5',
321
+ '\\<A>' : '\U0001d49c',
322
+ '\\<B>' : '\U0000212c',
323
+ '\\<C>' : '\U0001d49e',
324
+ '\\<D>' : '\U0001d49f',
325
+ '\\<E>' : '\U00002130',
326
+ '\\<F>' : '\U00002131',
327
+ '\\<G>' : '\U0001d4a2',
328
+ '\\<H>' : '\U0000210b',
329
+ '\\<I>' : '\U00002110',
330
+ '\\<J>' : '\U0001d4a5',
331
+ '\\<K>' : '\U0001d4a6',
332
+ '\\<L>' : '\U00002112',
333
+ '\\<M>' : '\U00002133',
334
+ '\\<N>' : '\U0001d4a9',
335
+ '\\<O>' : '\U0001d4aa',
336
+ '\\<P>' : '\U0001d4ab',
337
+ '\\<Q>' : '\U0001d4ac',
338
+ '\\<R>' : '\U0000211b',
339
+ '\\<S>' : '\U0001d4ae',
340
+ '\\<T>' : '\U0001d4af',
341
+ '\\<U>' : '\U0001d4b0',
342
+ '\\<V>' : '\U0001d4b1',
343
+ '\\<W>' : '\U0001d4b2',
344
+ '\\<X>' : '\U0001d4b3',
345
+ '\\<Y>' : '\U0001d4b4',
346
+ '\\<Z>' : '\U0001d4b5',
347
+ '\\<a>' : '\U0001d5ba',
348
+ '\\<b>' : '\U0001d5bb',
349
+ '\\<c>' : '\U0001d5bc',
350
+ '\\<d>' : '\U0001d5bd',
351
+ '\\<e>' : '\U0001d5be',
352
+ '\\<f>' : '\U0001d5bf',
353
+ '\\<g>' : '\U0001d5c0',
354
+ '\\<h>' : '\U0001d5c1',
355
+ '\\<i>' : '\U0001d5c2',
356
+ '\\<j>' : '\U0001d5c3',
357
+ '\\<k>' : '\U0001d5c4',
358
+ '\\<l>' : '\U0001d5c5',
359
+ '\\<m>' : '\U0001d5c6',
360
+ '\\<n>' : '\U0001d5c7',
361
+ '\\<o>' : '\U0001d5c8',
362
+ '\\<p>' : '\U0001d5c9',
363
+ '\\<q>' : '\U0001d5ca',
364
+ '\\<r>' : '\U0001d5cb',
365
+ '\\<s>' : '\U0001d5cc',
366
+ '\\<t>' : '\U0001d5cd',
367
+ '\\<u>' : '\U0001d5ce',
368
+ '\\<v>' : '\U0001d5cf',
369
+ '\\<w>' : '\U0001d5d0',
370
+ '\\<x>' : '\U0001d5d1',
371
+ '\\<y>' : '\U0001d5d2',
372
+ '\\<z>' : '\U0001d5d3',
373
+ '\\<AA>' : '\U0001d504',
374
+ '\\<BB>' : '\U0001d505',
375
+ '\\<CC>' : '\U0000212d',
376
+ '\\<DD>' : '\U0001d507',
377
+ '\\<EE>' : '\U0001d508',
378
+ '\\<FF>' : '\U0001d509',
379
+ '\\<GG>' : '\U0001d50a',
380
+ '\\<HH>' : '\U0000210c',
381
+ '\\<II>' : '\U00002111',
382
+ '\\<JJ>' : '\U0001d50d',
383
+ '\\<KK>' : '\U0001d50e',
384
+ '\\<LL>' : '\U0001d50f',
385
+ '\\<MM>' : '\U0001d510',
386
+ '\\<NN>' : '\U0001d511',
387
+ '\\<OO>' : '\U0001d512',
388
+ '\\<PP>' : '\U0001d513',
389
+ '\\<QQ>' : '\U0001d514',
390
+ '\\<RR>' : '\U0000211c',
391
+ '\\<SS>' : '\U0001d516',
392
+ '\\<TT>' : '\U0001d517',
393
+ '\\<UU>' : '\U0001d518',
394
+ '\\<VV>' : '\U0001d519',
395
+ '\\<WW>' : '\U0001d51a',
396
+ '\\<XX>' : '\U0001d51b',
397
+ '\\<YY>' : '\U0001d51c',
398
+ '\\<ZZ>' : '\U00002128',
399
+ '\\<aa>' : '\U0001d51e',
400
+ '\\<bb>' : '\U0001d51f',
401
+ '\\<cc>' : '\U0001d520',
402
+ '\\<dd>' : '\U0001d521',
403
+ '\\<ee>' : '\U0001d522',
404
+ '\\<ff>' : '\U0001d523',
405
+ '\\<gg>' : '\U0001d524',
406
+ '\\<hh>' : '\U0001d525',
407
+ '\\<ii>' : '\U0001d526',
408
+ '\\<jj>' : '\U0001d527',
409
+ '\\<kk>' : '\U0001d528',
410
+ '\\<ll>' : '\U0001d529',
411
+ '\\<mm>' : '\U0001d52a',
412
+ '\\<nn>' : '\U0001d52b',
413
+ '\\<oo>' : '\U0001d52c',
414
+ '\\<pp>' : '\U0001d52d',
415
+ '\\<qq>' : '\U0001d52e',
416
+ '\\<rr>' : '\U0001d52f',
417
+ '\\<ss>' : '\U0001d530',
418
+ '\\<tt>' : '\U0001d531',
419
+ '\\<uu>' : '\U0001d532',
420
+ '\\<vv>' : '\U0001d533',
421
+ '\\<ww>' : '\U0001d534',
422
+ '\\<xx>' : '\U0001d535',
423
+ '\\<yy>' : '\U0001d536',
424
+ '\\<zz>' : '\U0001d537',
425
+ '\\<alpha>' : '\U000003b1',
426
+ '\\<beta>' : '\U000003b2',
427
+ '\\<gamma>' : '\U000003b3',
428
+ '\\<delta>' : '\U000003b4',
429
+ '\\<epsilon>' : '\U000003b5',
430
+ '\\<zeta>' : '\U000003b6',
431
+ '\\<eta>' : '\U000003b7',
432
+ '\\<theta>' : '\U000003b8',
433
+ '\\<iota>' : '\U000003b9',
434
+ '\\<kappa>' : '\U000003ba',
435
+ '\\<lambda>' : '\U000003bb',
436
+ '\\<mu>' : '\U000003bc',
437
+ '\\<nu>' : '\U000003bd',
438
+ '\\<xi>' : '\U000003be',
439
+ '\\<pi>' : '\U000003c0',
440
+ '\\<rho>' : '\U000003c1',
441
+ '\\<sigma>' : '\U000003c3',
442
+ '\\<tau>' : '\U000003c4',
443
+ '\\<upsilon>' : '\U000003c5',
444
+ '\\<phi>' : '\U000003c6',
445
+ '\\<chi>' : '\U000003c7',
446
+ '\\<psi>' : '\U000003c8',
447
+ '\\<omega>' : '\U000003c9',
448
+ '\\<Gamma>' : '\U00000393',
449
+ '\\<Delta>' : '\U00000394',
450
+ '\\<Theta>' : '\U00000398',
451
+ '\\<Lambda>' : '\U0000039b',
452
+ '\\<Xi>' : '\U0000039e',
453
+ '\\<Pi>' : '\U000003a0',
454
+ '\\<Sigma>' : '\U000003a3',
455
+ '\\<Upsilon>' : '\U000003a5',
456
+ '\\<Phi>' : '\U000003a6',
457
+ '\\<Psi>' : '\U000003a8',
458
+ '\\<Omega>' : '\U000003a9',
459
+ '\\<bool>' : '\U0001d539',
460
+ '\\<complex>' : '\U00002102',
461
+ '\\<nat>' : '\U00002115',
462
+ '\\<rat>' : '\U0000211a',
463
+ '\\<real>' : '\U0000211d',
464
+ '\\<int>' : '\U00002124',
465
+ '\\<leftarrow>' : '\U00002190',
466
+ '\\<longleftarrow>' : '\U000027f5',
467
+ '\\<rightarrow>' : '\U00002192',
468
+ '\\<longrightarrow>' : '\U000027f6',
469
+ '\\<Leftarrow>' : '\U000021d0',
470
+ '\\<Longleftarrow>' : '\U000027f8',
471
+ '\\<Rightarrow>' : '\U000021d2',
472
+ '\\<Longrightarrow>' : '\U000027f9',
473
+ '\\<leftrightarrow>' : '\U00002194',
474
+ '\\<longleftrightarrow>' : '\U000027f7',
475
+ '\\<Leftrightarrow>' : '\U000021d4',
476
+ '\\<Longleftrightarrow>' : '\U000027fa',
477
+ '\\<mapsto>' : '\U000021a6',
478
+ '\\<longmapsto>' : '\U000027fc',
479
+ '\\<midarrow>' : '\U00002500',
480
+ '\\<Midarrow>' : '\U00002550',
481
+ '\\<hookleftarrow>' : '\U000021a9',
482
+ '\\<hookrightarrow>' : '\U000021aa',
483
+ '\\<leftharpoondown>' : '\U000021bd',
484
+ '\\<rightharpoondown>' : '\U000021c1',
485
+ '\\<leftharpoonup>' : '\U000021bc',
486
+ '\\<rightharpoonup>' : '\U000021c0',
487
+ '\\<rightleftharpoons>' : '\U000021cc',
488
+ '\\<leadsto>' : '\U0000219d',
489
+ '\\<downharpoonleft>' : '\U000021c3',
490
+ '\\<downharpoonright>' : '\U000021c2',
491
+ '\\<upharpoonleft>' : '\U000021bf',
492
+ '\\<upharpoonright>' : '\U000021be',
493
+ '\\<restriction>' : '\U000021be',
494
+ '\\<Colon>' : '\U00002237',
495
+ '\\<up>' : '\U00002191',
496
+ '\\<Up>' : '\U000021d1',
497
+ '\\<down>' : '\U00002193',
498
+ '\\<Down>' : '\U000021d3',
499
+ '\\<updown>' : '\U00002195',
500
+ '\\<Updown>' : '\U000021d5',
501
+ '\\<langle>' : '\U000027e8',
502
+ '\\<rangle>' : '\U000027e9',
503
+ '\\<lceil>' : '\U00002308',
504
+ '\\<rceil>' : '\U00002309',
505
+ '\\<lfloor>' : '\U0000230a',
506
+ '\\<rfloor>' : '\U0000230b',
507
+ '\\<lparr>' : '\U00002987',
508
+ '\\<rparr>' : '\U00002988',
509
+ '\\<lbrakk>' : '\U000027e6',
510
+ '\\<rbrakk>' : '\U000027e7',
511
+ '\\<lbrace>' : '\U00002983',
512
+ '\\<rbrace>' : '\U00002984',
513
+ '\\<guillemotleft>' : '\U000000ab',
514
+ '\\<guillemotright>' : '\U000000bb',
515
+ '\\<bottom>' : '\U000022a5',
516
+ '\\<top>' : '\U000022a4',
517
+ '\\<and>' : '\U00002227',
518
+ '\\<And>' : '\U000022c0',
519
+ '\\<or>' : '\U00002228',
520
+ '\\<Or>' : '\U000022c1',
521
+ '\\<forall>' : '\U00002200',
522
+ '\\<exists>' : '\U00002203',
523
+ '\\<nexists>' : '\U00002204',
524
+ '\\<not>' : '\U000000ac',
525
+ '\\<box>' : '\U000025a1',
526
+ '\\<diamond>' : '\U000025c7',
527
+ '\\<turnstile>' : '\U000022a2',
528
+ '\\<Turnstile>' : '\U000022a8',
529
+ '\\<tturnstile>' : '\U000022a9',
530
+ '\\<TTurnstile>' : '\U000022ab',
531
+ '\\<stileturn>' : '\U000022a3',
532
+ '\\<surd>' : '\U0000221a',
533
+ '\\<le>' : '\U00002264',
534
+ '\\<ge>' : '\U00002265',
535
+ '\\<lless>' : '\U0000226a',
536
+ '\\<ggreater>' : '\U0000226b',
537
+ '\\<lesssim>' : '\U00002272',
538
+ '\\<greatersim>' : '\U00002273',
539
+ '\\<lessapprox>' : '\U00002a85',
540
+ '\\<greaterapprox>' : '\U00002a86',
541
+ '\\<in>' : '\U00002208',
542
+ '\\<notin>' : '\U00002209',
543
+ '\\<subset>' : '\U00002282',
544
+ '\\<supset>' : '\U00002283',
545
+ '\\<subseteq>' : '\U00002286',
546
+ '\\<supseteq>' : '\U00002287',
547
+ '\\<sqsubset>' : '\U0000228f',
548
+ '\\<sqsupset>' : '\U00002290',
549
+ '\\<sqsubseteq>' : '\U00002291',
550
+ '\\<sqsupseteq>' : '\U00002292',
551
+ '\\<inter>' : '\U00002229',
552
+ '\\<Inter>' : '\U000022c2',
553
+ '\\<union>' : '\U0000222a',
554
+ '\\<Union>' : '\U000022c3',
555
+ '\\<squnion>' : '\U00002294',
556
+ '\\<Squnion>' : '\U00002a06',
557
+ '\\<sqinter>' : '\U00002293',
558
+ '\\<Sqinter>' : '\U00002a05',
559
+ '\\<setminus>' : '\U00002216',
560
+ '\\<propto>' : '\U0000221d',
561
+ '\\<uplus>' : '\U0000228e',
562
+ '\\<Uplus>' : '\U00002a04',
563
+ '\\<noteq>' : '\U00002260',
564
+ '\\<sim>' : '\U0000223c',
565
+ '\\<doteq>' : '\U00002250',
566
+ '\\<simeq>' : '\U00002243',
567
+ '\\<approx>' : '\U00002248',
568
+ '\\<asymp>' : '\U0000224d',
569
+ '\\<cong>' : '\U00002245',
570
+ '\\<smile>' : '\U00002323',
571
+ '\\<equiv>' : '\U00002261',
572
+ '\\<frown>' : '\U00002322',
573
+ '\\<Join>' : '\U000022c8',
574
+ '\\<bowtie>' : '\U00002a1d',
575
+ '\\<prec>' : '\U0000227a',
576
+ '\\<succ>' : '\U0000227b',
577
+ '\\<preceq>' : '\U0000227c',
578
+ '\\<succeq>' : '\U0000227d',
579
+ '\\<parallel>' : '\U00002225',
580
+ '\\<bar>' : '\U000000a6',
581
+ '\\<plusminus>' : '\U000000b1',
582
+ '\\<minusplus>' : '\U00002213',
583
+ '\\<times>' : '\U000000d7',
584
+ '\\<div>' : '\U000000f7',
585
+ '\\<cdot>' : '\U000022c5',
586
+ '\\<star>' : '\U000022c6',
587
+ '\\<bullet>' : '\U00002219',
588
+ '\\<circ>' : '\U00002218',
589
+ '\\<dagger>' : '\U00002020',
590
+ '\\<ddagger>' : '\U00002021',
591
+ '\\<lhd>' : '\U000022b2',
592
+ '\\<rhd>' : '\U000022b3',
593
+ '\\<unlhd>' : '\U000022b4',
594
+ '\\<unrhd>' : '\U000022b5',
595
+ '\\<triangleleft>' : '\U000025c3',
596
+ '\\<triangleright>' : '\U000025b9',
597
+ '\\<triangle>' : '\U000025b3',
598
+ '\\<triangleq>' : '\U0000225c',
599
+ '\\<oplus>' : '\U00002295',
600
+ '\\<Oplus>' : '\U00002a01',
601
+ '\\<otimes>' : '\U00002297',
602
+ '\\<Otimes>' : '\U00002a02',
603
+ '\\<odot>' : '\U00002299',
604
+ '\\<Odot>' : '\U00002a00',
605
+ '\\<ominus>' : '\U00002296',
606
+ '\\<oslash>' : '\U00002298',
607
+ '\\<dots>' : '\U00002026',
608
+ '\\<cdots>' : '\U000022ef',
609
+ '\\<Sum>' : '\U00002211',
610
+ '\\<Prod>' : '\U0000220f',
611
+ '\\<Coprod>' : '\U00002210',
612
+ '\\<infinity>' : '\U0000221e',
613
+ '\\<integral>' : '\U0000222b',
614
+ '\\<ointegral>' : '\U0000222e',
615
+ '\\<clubsuit>' : '\U00002663',
616
+ '\\<diamondsuit>' : '\U00002662',
617
+ '\\<heartsuit>' : '\U00002661',
618
+ '\\<spadesuit>' : '\U00002660',
619
+ '\\<aleph>' : '\U00002135',
620
+ '\\<emptyset>' : '\U00002205',
621
+ '\\<nabla>' : '\U00002207',
622
+ '\\<partial>' : '\U00002202',
623
+ '\\<flat>' : '\U0000266d',
624
+ '\\<natural>' : '\U0000266e',
625
+ '\\<sharp>' : '\U0000266f',
626
+ '\\<angle>' : '\U00002220',
627
+ '\\<copyright>' : '\U000000a9',
628
+ '\\<registered>' : '\U000000ae',
629
+ '\\<hyphen>' : '\U000000ad',
630
+ '\\<inverse>' : '\U000000af',
631
+ '\\<onequarter>' : '\U000000bc',
632
+ '\\<onehalf>' : '\U000000bd',
633
+ '\\<threequarters>' : '\U000000be',
634
+ '\\<ordfeminine>' : '\U000000aa',
635
+ '\\<ordmasculine>' : '\U000000ba',
636
+ '\\<section>' : '\U000000a7',
637
+ '\\<paragraph>' : '\U000000b6',
638
+ '\\<exclamdown>' : '\U000000a1',
639
+ '\\<questiondown>' : '\U000000bf',
640
+ '\\<euro>' : '\U000020ac',
641
+ '\\<pounds>' : '\U000000a3',
642
+ '\\<yen>' : '\U000000a5',
643
+ '\\<cent>' : '\U000000a2',
644
+ '\\<currency>' : '\U000000a4',
645
+ '\\<degree>' : '\U000000b0',
646
+ '\\<amalg>' : '\U00002a3f',
647
+ '\\<mho>' : '\U00002127',
648
+ '\\<lozenge>' : '\U000025ca',
649
+ '\\<wp>' : '\U00002118',
650
+ '\\<wrong>' : '\U00002240',
651
+ '\\<struct>' : '\U000022c4',
652
+ '\\<acute>' : '\U000000b4',
653
+ '\\<index>' : '\U00000131',
654
+ '\\<dieresis>' : '\U000000a8',
655
+ '\\<cedilla>' : '\U000000b8',
656
+ '\\<hungarumlaut>' : '\U000002dd',
657
+ '\\<some>' : '\U000003f5',
658
+ '\\<newline>' : '\U000023ce',
659
+ '\\<open>' : '\U00002039',
660
+ '\\<close>' : '\U0000203a',
661
+ '\\<here>' : '\U00002302',
662
+ '\\<^sub>' : '\U000021e9',
663
+ '\\<^sup>' : '\U000021e7',
664
+ '\\<^bold>' : '\U00002759',
665
+ '\\<^bsub>' : '\U000021d8',
666
+ '\\<^esub>' : '\U000021d9',
667
+ '\\<^bsup>' : '\U000021d7',
668
+ '\\<^esup>' : '\U000021d6',
669
+ }
670
+
671
+ lang_map = {'isabelle' : isabelle_symbols, 'latex' : latex_symbols}
672
+
673
+ def __init__(self, **options):
674
+ Filter.__init__(self, **options)
675
+ lang = get_choice_opt(options, 'lang',
676
+ ['isabelle', 'latex'], 'isabelle')
677
+ self.symbols = self.lang_map[lang]
678
+
679
+ def filter(self, lexer, stream):
680
+ for ttype, value in stream:
681
+ if value in self.symbols:
682
+ yield ttype, self.symbols[value]
683
+ else:
684
+ yield ttype, value
685
+
686
+
687
+ class KeywordCaseFilter(Filter):
688
+ """Convert keywords to lowercase or uppercase or capitalize them, which
689
+ means first letter uppercase, rest lowercase.
690
+
691
+ This can be useful e.g. if you highlight Pascal code and want to adapt the
692
+ code to your styleguide.
693
+
694
+ Options accepted:
695
+
696
+ `case` : string
697
+ The casing to convert keywords to. Must be one of ``'lower'``,
698
+ ``'upper'`` or ``'capitalize'``. The default is ``'lower'``.
699
+ """
700
+
701
+ def __init__(self, **options):
702
+ Filter.__init__(self, **options)
703
+ case = get_choice_opt(options, 'case',
704
+ ['lower', 'upper', 'capitalize'], 'lower')
705
+ self.convert = getattr(str, case)
706
+
707
+ def filter(self, lexer, stream):
708
+ for ttype, value in stream:
709
+ if ttype in Keyword:
710
+ yield ttype, self.convert(value)
711
+ else:
712
+ yield ttype, value
713
+
714
+
715
+ class NameHighlightFilter(Filter):
716
+ """Highlight a normal Name (and Name.*) token with a different token type.
717
+
718
+ Example::
719
+
720
+ filter = NameHighlightFilter(
721
+ names=['foo', 'bar', 'baz'],
722
+ tokentype=Name.Function,
723
+ )
724
+
725
+ This would highlight the names "foo", "bar" and "baz"
726
+ as functions. `Name.Function` is the default token type.
727
+
728
+ Options accepted:
729
+
730
+ `names` : list of strings
731
+ A list of names that should be given the different token type.
732
+ There is no default.
733
+ `tokentype` : TokenType or string
734
+ A token type or a string containing a token type name that is
735
+ used for highlighting the strings in `names`. The default is
736
+ `Name.Function`.
737
+ """
738
+
739
+ def __init__(self, **options):
740
+ Filter.__init__(self, **options)
741
+ self.names = set(get_list_opt(options, 'names', []))
742
+ tokentype = options.get('tokentype')
743
+ if tokentype:
744
+ self.tokentype = string_to_tokentype(tokentype)
745
+ else:
746
+ self.tokentype = Name.Function
747
+
748
+ def filter(self, lexer, stream):
749
+ for ttype, value in stream:
750
+ if ttype in Name and value in self.names:
751
+ yield self.tokentype, value
752
+ else:
753
+ yield ttype, value
754
+
755
+
756
+ class ErrorToken(Exception):
757
+ pass
758
+
759
+
760
+ class RaiseOnErrorTokenFilter(Filter):
761
+ """Raise an exception when the lexer generates an error token.
762
+
763
+ Options accepted:
764
+
765
+ `excclass` : Exception class
766
+ The exception class to raise.
767
+ The default is `pygments.filters.ErrorToken`.
768
+
769
+ .. versionadded:: 0.8
770
+ """
771
+
772
+ def __init__(self, **options):
773
+ Filter.__init__(self, **options)
774
+ self.exception = options.get('excclass', ErrorToken)
775
+ try:
776
+ # issubclass() will raise TypeError if first argument is not a class
777
+ if not issubclass(self.exception, Exception):
778
+ raise TypeError
779
+ except TypeError:
780
+ raise OptionError('excclass option is not an exception class')
781
+
782
+ def filter(self, lexer, stream):
783
+ for ttype, value in stream:
784
+ if ttype is Error:
785
+ raise self.exception(value)
786
+ yield ttype, value
787
+
788
+
789
+ class VisibleWhitespaceFilter(Filter):
790
+ """Convert tabs, newlines and/or spaces to visible characters.
791
+
792
+ Options accepted:
793
+
794
+ `spaces` : string or bool
795
+ If this is a one-character string, spaces will be replaces by this string.
796
+ If it is another true value, spaces will be replaced by ``·`` (unicode
797
+ MIDDLE DOT). If it is a false value, spaces will not be replaced. The
798
+ default is ``False``.
799
+ `tabs` : string or bool
800
+ The same as for `spaces`, but the default replacement character is ``»``
801
+ (unicode RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK). The default value
802
+ is ``False``. Note: this will not work if the `tabsize` option for the
803
+ lexer is nonzero, as tabs will already have been expanded then.
804
+ `tabsize` : int
805
+ If tabs are to be replaced by this filter (see the `tabs` option), this
806
+ is the total number of characters that a tab should be expanded to.
807
+ The default is ``8``.
808
+ `newlines` : string or bool
809
+ The same as for `spaces`, but the default replacement character is ``¶``
810
+ (unicode PILCROW SIGN). The default value is ``False``.
811
+ `wstokentype` : bool
812
+ If true, give whitespace the special `Whitespace` token type. This allows
813
+ styling the visible whitespace differently (e.g. greyed out), but it can
814
+ disrupt background colors. The default is ``True``.
815
+
816
+ .. versionadded:: 0.8
817
+ """
818
+
819
+ def __init__(self, **options):
820
+ Filter.__init__(self, **options)
821
+ for name, default in [('spaces', '·'),
822
+ ('tabs', '»'),
823
+ ('newlines', '¶')]:
824
+ opt = options.get(name, False)
825
+ if isinstance(opt, str) and len(opt) == 1:
826
+ setattr(self, name, opt)
827
+ else:
828
+ setattr(self, name, (opt and default or ''))
829
+ tabsize = get_int_opt(options, 'tabsize', 8)
830
+ if self.tabs:
831
+ self.tabs += ' ' * (tabsize - 1)
832
+ if self.newlines:
833
+ self.newlines += '\n'
834
+ self.wstt = get_bool_opt(options, 'wstokentype', True)
835
+
836
+ def filter(self, lexer, stream):
837
+ if self.wstt:
838
+ spaces = self.spaces or ' '
839
+ tabs = self.tabs or '\t'
840
+ newlines = self.newlines or '\n'
841
+ regex = re.compile(r'\s')
842
+
843
+ def replacefunc(wschar):
844
+ if wschar == ' ':
845
+ return spaces
846
+ elif wschar == '\t':
847
+ return tabs
848
+ elif wschar == '\n':
849
+ return newlines
850
+ return wschar
851
+
852
+ for ttype, value in stream:
853
+ yield from _replace_special(ttype, value, regex, Whitespace,
854
+ replacefunc)
855
+ else:
856
+ spaces, tabs, newlines = self.spaces, self.tabs, self.newlines
857
+ # simpler processing
858
+ for ttype, value in stream:
859
+ if spaces:
860
+ value = value.replace(' ', spaces)
861
+ if tabs:
862
+ value = value.replace('\t', tabs)
863
+ if newlines:
864
+ value = value.replace('\n', newlines)
865
+ yield ttype, value
866
+
867
+
868
+ class GobbleFilter(Filter):
869
+ """Gobbles source code lines (eats initial characters).
870
+
871
+ This filter drops the first ``n`` characters off every line of code. This
872
+ may be useful when the source code fed to the lexer is indented by a fixed
873
+ amount of space that isn't desired in the output.
874
+
875
+ Options accepted:
876
+
877
+ `n` : int
878
+ The number of characters to gobble.
879
+
880
+ .. versionadded:: 1.2
881
+ """
882
+ def __init__(self, **options):
883
+ Filter.__init__(self, **options)
884
+ self.n = get_int_opt(options, 'n', 0)
885
+
886
+ def gobble(self, value, left):
887
+ if left < len(value):
888
+ return value[left:], 0
889
+ else:
890
+ return '', left - len(value)
891
+
892
+ def filter(self, lexer, stream):
893
+ n = self.n
894
+ left = n # How many characters left to gobble.
895
+ for ttype, value in stream:
896
+ # Remove ``left`` tokens from first line, ``n`` from all others.
897
+ parts = value.split('\n')
898
+ (parts[0], left) = self.gobble(parts[0], left)
899
+ for i in range(1, len(parts)):
900
+ (parts[i], left) = self.gobble(parts[i], n)
901
+ value = '\n'.join(parts)
902
+
903
+ if value != '':
904
+ yield ttype, value
905
+
906
+
907
+ class TokenMergeFilter(Filter):
908
+ """Merges consecutive tokens with the same token type in the output
909
+ stream of a lexer.
910
+
911
+ .. versionadded:: 1.2
912
+ """
913
+ def __init__(self, **options):
914
+ Filter.__init__(self, **options)
915
+
916
+ def filter(self, lexer, stream):
917
+ current_type = None
918
+ current_value = None
919
+ for ttype, value in stream:
920
+ if ttype is current_type:
921
+ current_value += value
922
+ else:
923
+ if current_type is not None:
924
+ yield current_type, current_value
925
+ current_type = ttype
926
+ current_value = value
927
+ if current_type is not None:
928
+ yield current_type, current_value
929
+
930
+
931
+ FILTERS = {
932
+ 'codetagify': CodeTagFilter,
933
+ 'keywordcase': KeywordCaseFilter,
934
+ 'highlight': NameHighlightFilter,
935
+ 'raiseonerror': RaiseOnErrorTokenFilter,
936
+ 'whitespace': VisibleWhitespaceFilter,
937
+ 'gobble': GobbleFilter,
938
+ 'tokenmerge': TokenMergeFilter,
939
+ 'symbols': SymbolFilter,
940
+ }
lib/python3.12/site-packages/pygments/filters/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (37.9 kB). View file
 
lib/python3.12/site-packages/pygments/formatter.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.formatter
3
+ ~~~~~~~~~~~~~~~~~~
4
+
5
+ Base formatter class.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ import codecs
12
+
13
+ from pygments.util import get_bool_opt
14
+ from pygments.styles import get_style_by_name
15
+
16
+ __all__ = ['Formatter']
17
+
18
+
19
+ def _lookup_style(style):
20
+ if isinstance(style, str):
21
+ return get_style_by_name(style)
22
+ return style
23
+
24
+
25
+ class Formatter:
26
+ """
27
+ Converts a token stream to text.
28
+
29
+ Formatters should have attributes to help selecting them. These
30
+ are similar to the corresponding :class:`~pygments.lexer.Lexer`
31
+ attributes.
32
+
33
+ .. autoattribute:: name
34
+ :no-value:
35
+
36
+ .. autoattribute:: aliases
37
+ :no-value:
38
+
39
+ .. autoattribute:: filenames
40
+ :no-value:
41
+
42
+ You can pass options as keyword arguments to the constructor.
43
+ All formatters accept these basic options:
44
+
45
+ ``style``
46
+ The style to use, can be a string or a Style subclass
47
+ (default: "default"). Not used by e.g. the
48
+ TerminalFormatter.
49
+ ``full``
50
+ Tells the formatter to output a "full" document, i.e.
51
+ a complete self-contained document. This doesn't have
52
+ any effect for some formatters (default: false).
53
+ ``title``
54
+ If ``full`` is true, the title that should be used to
55
+ caption the document (default: '').
56
+ ``encoding``
57
+ If given, must be an encoding name. This will be used to
58
+ convert the Unicode token strings to byte strings in the
59
+ output. If it is "" or None, Unicode strings will be written
60
+ to the output file, which most file-like objects do not
61
+ support (default: None).
62
+ ``outencoding``
63
+ Overrides ``encoding`` if given.
64
+
65
+ """
66
+
67
+ #: Full name for the formatter, in human-readable form.
68
+ name = None
69
+
70
+ #: A list of short, unique identifiers that can be used to lookup
71
+ #: the formatter from a list, e.g. using :func:`.get_formatter_by_name()`.
72
+ aliases = []
73
+
74
+ #: A list of fnmatch patterns that match filenames for which this
75
+ #: formatter can produce output. The patterns in this list should be unique
76
+ #: among all formatters.
77
+ filenames = []
78
+
79
+ #: If True, this formatter outputs Unicode strings when no encoding
80
+ #: option is given.
81
+ unicodeoutput = True
82
+
83
+ def __init__(self, **options):
84
+ """
85
+ As with lexers, this constructor takes arbitrary optional arguments,
86
+ and if you override it, you should first process your own options, then
87
+ call the base class implementation.
88
+ """
89
+ self.style = _lookup_style(options.get('style', 'default'))
90
+ self.full = get_bool_opt(options, 'full', False)
91
+ self.title = options.get('title', '')
92
+ self.encoding = options.get('encoding', None) or None
93
+ if self.encoding in ('guess', 'chardet'):
94
+ # can happen for e.g. pygmentize -O encoding=guess
95
+ self.encoding = 'utf-8'
96
+ self.encoding = options.get('outencoding') or self.encoding
97
+ self.options = options
98
+
99
+ def get_style_defs(self, arg=''):
100
+ """
101
+ This method must return statements or declarations suitable to define
102
+ the current style for subsequent highlighted text (e.g. CSS classes
103
+ in the `HTMLFormatter`).
104
+
105
+ The optional argument `arg` can be used to modify the generation and
106
+ is formatter dependent (it is standardized because it can be given on
107
+ the command line).
108
+
109
+ This method is called by the ``-S`` :doc:`command-line option <cmdline>`,
110
+ the `arg` is then given by the ``-a`` option.
111
+ """
112
+ return ''
113
+
114
+ def format(self, tokensource, outfile):
115
+ """
116
+ This method must format the tokens from the `tokensource` iterable and
117
+ write the formatted version to the file object `outfile`.
118
+
119
+ Formatter options can control how exactly the tokens are converted.
120
+ """
121
+ if self.encoding:
122
+ # wrap the outfile in a StreamWriter
123
+ outfile = codecs.lookup(self.encoding)[3](outfile)
124
+ return self.format_unencoded(tokensource, outfile)
125
+
126
+ # Allow writing Formatter[str] or Formatter[bytes]. That's equivalent to
127
+ # Formatter. This helps when using third-party type stubs from typeshed.
128
+ def __class_getitem__(cls, name):
129
+ return cls
lib/python3.12/site-packages/pygments/lexer.py ADDED
@@ -0,0 +1,961 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.lexer
3
+ ~~~~~~~~~~~~~~
4
+
5
+ Base lexer classes.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ import re
12
+ import sys
13
+ import time
14
+
15
+ from pygments.filter import apply_filters, Filter
16
+ from pygments.filters import get_filter_by_name
17
+ from pygments.token import Error, Text, Other, Whitespace, _TokenType
18
+ from pygments.util import get_bool_opt, get_int_opt, get_list_opt, \
19
+ make_analysator, Future, guess_decode
20
+ from pygments.regexopt import regex_opt
21
+
22
+ __all__ = ['Lexer', 'RegexLexer', 'ExtendedRegexLexer', 'DelegatingLexer',
23
+ 'LexerContext', 'include', 'inherit', 'bygroups', 'using', 'this',
24
+ 'default', 'words', 'line_re']
25
+
26
+ line_re = re.compile('.*?\n')
27
+
28
+ _encoding_map = [(b'\xef\xbb\xbf', 'utf-8'),
29
+ (b'\xff\xfe\0\0', 'utf-32'),
30
+ (b'\0\0\xfe\xff', 'utf-32be'),
31
+ (b'\xff\xfe', 'utf-16'),
32
+ (b'\xfe\xff', 'utf-16be')]
33
+
34
+ _default_analyse = staticmethod(lambda x: 0.0)
35
+
36
+
37
+ class LexerMeta(type):
38
+ """
39
+ This metaclass automagically converts ``analyse_text`` methods into
40
+ static methods which always return float values.
41
+ """
42
+
43
+ def __new__(mcs, name, bases, d):
44
+ if 'analyse_text' in d:
45
+ d['analyse_text'] = make_analysator(d['analyse_text'])
46
+ return type.__new__(mcs, name, bases, d)
47
+
48
+
49
+ class Lexer(metaclass=LexerMeta):
50
+ """
51
+ Lexer for a specific language.
52
+
53
+ See also :doc:`lexerdevelopment`, a high-level guide to writing
54
+ lexers.
55
+
56
+ Lexer classes have attributes used for choosing the most appropriate
57
+ lexer based on various criteria.
58
+
59
+ .. autoattribute:: name
60
+ :no-value:
61
+ .. autoattribute:: aliases
62
+ :no-value:
63
+ .. autoattribute:: filenames
64
+ :no-value:
65
+ .. autoattribute:: alias_filenames
66
+ .. autoattribute:: mimetypes
67
+ :no-value:
68
+ .. autoattribute:: priority
69
+
70
+ Lexers included in Pygments should have two additional attributes:
71
+
72
+ .. autoattribute:: url
73
+ :no-value:
74
+ .. autoattribute:: version_added
75
+ :no-value:
76
+
77
+ Lexers included in Pygments may have additional attributes:
78
+
79
+ .. autoattribute:: _example
80
+ :no-value:
81
+
82
+ You can pass options to the constructor. The basic options recognized
83
+ by all lexers and processed by the base `Lexer` class are:
84
+
85
+ ``stripnl``
86
+ Strip leading and trailing newlines from the input (default: True).
87
+ ``stripall``
88
+ Strip all leading and trailing whitespace from the input
89
+ (default: False).
90
+ ``ensurenl``
91
+ Make sure that the input ends with a newline (default: True). This
92
+ is required for some lexers that consume input linewise.
93
+
94
+ .. versionadded:: 1.3
95
+
96
+ ``tabsize``
97
+ If given and greater than 0, expand tabs in the input (default: 0).
98
+ ``encoding``
99
+ If given, must be an encoding name. This encoding will be used to
100
+ convert the input string to Unicode, if it is not already a Unicode
101
+ string (default: ``'guess'``, which uses a simple UTF-8 / Locale /
102
+ Latin1 detection. Can also be ``'chardet'`` to use the chardet
103
+ library, if it is installed.
104
+ ``inencoding``
105
+ Overrides the ``encoding`` if given.
106
+ """
107
+
108
+ #: Full name of the lexer, in human-readable form
109
+ name = None
110
+
111
+ #: A list of short, unique identifiers that can be used to look
112
+ #: up the lexer from a list, e.g., using `get_lexer_by_name()`.
113
+ aliases = []
114
+
115
+ #: A list of `fnmatch` patterns that match filenames which contain
116
+ #: content for this lexer. The patterns in this list should be unique among
117
+ #: all lexers.
118
+ filenames = []
119
+
120
+ #: A list of `fnmatch` patterns that match filenames which may or may not
121
+ #: contain content for this lexer. This list is used by the
122
+ #: :func:`.guess_lexer_for_filename()` function, to determine which lexers
123
+ #: are then included in guessing the correct one. That means that
124
+ #: e.g. every lexer for HTML and a template language should include
125
+ #: ``\*.html`` in this list.
126
+ alias_filenames = []
127
+
128
+ #: A list of MIME types for content that can be lexed with this lexer.
129
+ mimetypes = []
130
+
131
+ #: Priority, should multiple lexers match and no content is provided
132
+ priority = 0
133
+
134
+ #: URL of the language specification/definition. Used in the Pygments
135
+ #: documentation. Set to an empty string to disable.
136
+ url = None
137
+
138
+ #: Version of Pygments in which the lexer was added.
139
+ version_added = None
140
+
141
+ #: Example file name. Relative to the ``tests/examplefiles`` directory.
142
+ #: This is used by the documentation generator to show an example.
143
+ _example = None
144
+
145
+ def __init__(self, **options):
146
+ """
147
+ This constructor takes arbitrary options as keyword arguments.
148
+ Every subclass must first process its own options and then call
149
+ the `Lexer` constructor, since it processes the basic
150
+ options like `stripnl`.
151
+
152
+ An example looks like this:
153
+
154
+ .. sourcecode:: python
155
+
156
+ def __init__(self, **options):
157
+ self.compress = options.get('compress', '')
158
+ Lexer.__init__(self, **options)
159
+
160
+ As these options must all be specifiable as strings (due to the
161
+ command line usage), there are various utility functions
162
+ available to help with that, see `Utilities`_.
163
+ """
164
+ self.options = options
165
+ self.stripnl = get_bool_opt(options, 'stripnl', True)
166
+ self.stripall = get_bool_opt(options, 'stripall', False)
167
+ self.ensurenl = get_bool_opt(options, 'ensurenl', True)
168
+ self.tabsize = get_int_opt(options, 'tabsize', 0)
169
+ self.encoding = options.get('encoding', 'guess')
170
+ self.encoding = options.get('inencoding') or self.encoding
171
+ self.filters = []
172
+ for filter_ in get_list_opt(options, 'filters', ()):
173
+ self.add_filter(filter_)
174
+
175
+ def __repr__(self):
176
+ if self.options:
177
+ return f'<pygments.lexers.{self.__class__.__name__} with {self.options!r}>'
178
+ else:
179
+ return f'<pygments.lexers.{self.__class__.__name__}>'
180
+
181
+ def add_filter(self, filter_, **options):
182
+ """
183
+ Add a new stream filter to this lexer.
184
+ """
185
+ if not isinstance(filter_, Filter):
186
+ filter_ = get_filter_by_name(filter_, **options)
187
+ self.filters.append(filter_)
188
+
189
+ def analyse_text(text):
190
+ """
191
+ A static method which is called for lexer guessing.
192
+
193
+ It should analyse the text and return a float in the range
194
+ from ``0.0`` to ``1.0``. If it returns ``0.0``, the lexer
195
+ will not be selected as the most probable one, if it returns
196
+ ``1.0``, it will be selected immediately. This is used by
197
+ `guess_lexer`.
198
+
199
+ The `LexerMeta` metaclass automatically wraps this function so
200
+ that it works like a static method (no ``self`` or ``cls``
201
+ parameter) and the return value is automatically converted to
202
+ `float`. If the return value is an object that is boolean `False`
203
+ it's the same as if the return values was ``0.0``.
204
+ """
205
+
206
+ def _preprocess_lexer_input(self, text):
207
+ """Apply preprocessing such as decoding the input, removing BOM and normalizing newlines."""
208
+
209
+ if not isinstance(text, str):
210
+ if self.encoding == 'guess':
211
+ text, _ = guess_decode(text)
212
+ elif self.encoding == 'chardet':
213
+ try:
214
+ import chardet
215
+ except ImportError as e:
216
+ raise ImportError('To enable chardet encoding guessing, '
217
+ 'please install the chardet library '
218
+ 'from http://chardet.feedparser.org/') from e
219
+ # check for BOM first
220
+ decoded = None
221
+ for bom, encoding in _encoding_map:
222
+ if text.startswith(bom):
223
+ decoded = text[len(bom):].decode(encoding, 'replace')
224
+ break
225
+ # no BOM found, so use chardet
226
+ if decoded is None:
227
+ enc = chardet.detect(text[:1024]) # Guess using first 1KB
228
+ decoded = text.decode(enc.get('encoding') or 'utf-8',
229
+ 'replace')
230
+ text = decoded
231
+ else:
232
+ text = text.decode(self.encoding)
233
+ if text.startswith('\ufeff'):
234
+ text = text[len('\ufeff'):]
235
+ else:
236
+ if text.startswith('\ufeff'):
237
+ text = text[len('\ufeff'):]
238
+
239
+ # text now *is* a unicode string
240
+ text = text.replace('\r\n', '\n')
241
+ text = text.replace('\r', '\n')
242
+ if self.stripall:
243
+ text = text.strip()
244
+ elif self.stripnl:
245
+ text = text.strip('\n')
246
+ if self.tabsize > 0:
247
+ text = text.expandtabs(self.tabsize)
248
+ if self.ensurenl and not text.endswith('\n'):
249
+ text += '\n'
250
+
251
+ return text
252
+
253
+ def get_tokens(self, text, unfiltered=False):
254
+ """
255
+ This method is the basic interface of a lexer. It is called by
256
+ the `highlight()` function. It must process the text and return an
257
+ iterable of ``(tokentype, value)`` pairs from `text`.
258
+
259
+ Normally, you don't need to override this method. The default
260
+ implementation processes the options recognized by all lexers
261
+ (`stripnl`, `stripall` and so on), and then yields all tokens
262
+ from `get_tokens_unprocessed()`, with the ``index`` dropped.
263
+
264
+ If `unfiltered` is set to `True`, the filtering mechanism is
265
+ bypassed even if filters are defined.
266
+ """
267
+ text = self._preprocess_lexer_input(text)
268
+
269
+ def streamer():
270
+ for _, t, v in self.get_tokens_unprocessed(text):
271
+ yield t, v
272
+ stream = streamer()
273
+ if not unfiltered:
274
+ stream = apply_filters(stream, self.filters, self)
275
+ return stream
276
+
277
+ def get_tokens_unprocessed(self, text):
278
+ """
279
+ This method should process the text and return an iterable of
280
+ ``(index, tokentype, value)`` tuples where ``index`` is the starting
281
+ position of the token within the input text.
282
+
283
+ It must be overridden by subclasses. It is recommended to
284
+ implement it as a generator to maximize effectiveness.
285
+ """
286
+ raise NotImplementedError
287
+
288
+
289
+ class DelegatingLexer(Lexer):
290
+ """
291
+ This lexer takes two lexer as arguments. A root lexer and
292
+ a language lexer. First everything is scanned using the language
293
+ lexer, afterwards all ``Other`` tokens are lexed using the root
294
+ lexer.
295
+
296
+ The lexers from the ``template`` lexer package use this base lexer.
297
+ """
298
+
299
+ def __init__(self, _root_lexer, _language_lexer, _needle=Other, **options):
300
+ self.root_lexer = _root_lexer(**options)
301
+ self.language_lexer = _language_lexer(**options)
302
+ self.needle = _needle
303
+ Lexer.__init__(self, **options)
304
+
305
+ def get_tokens_unprocessed(self, text):
306
+ buffered = ''
307
+ insertions = []
308
+ lng_buffer = []
309
+ for i, t, v in self.language_lexer.get_tokens_unprocessed(text):
310
+ if t is self.needle:
311
+ if lng_buffer:
312
+ insertions.append((len(buffered), lng_buffer))
313
+ lng_buffer = []
314
+ buffered += v
315
+ else:
316
+ lng_buffer.append((i, t, v))
317
+ if lng_buffer:
318
+ insertions.append((len(buffered), lng_buffer))
319
+ return do_insertions(insertions,
320
+ self.root_lexer.get_tokens_unprocessed(buffered))
321
+
322
+
323
+ # ------------------------------------------------------------------------------
324
+ # RegexLexer and ExtendedRegexLexer
325
+ #
326
+
327
+
328
+ class include(str): # pylint: disable=invalid-name
329
+ """
330
+ Indicates that a state should include rules from another state.
331
+ """
332
+ pass
333
+
334
+
335
+ class _inherit:
336
+ """
337
+ Indicates the a state should inherit from its superclass.
338
+ """
339
+ def __repr__(self):
340
+ return 'inherit'
341
+
342
+ inherit = _inherit() # pylint: disable=invalid-name
343
+
344
+
345
+ class combined(tuple): # pylint: disable=invalid-name
346
+ """
347
+ Indicates a state combined from multiple states.
348
+ """
349
+
350
+ def __new__(cls, *args):
351
+ return tuple.__new__(cls, args)
352
+
353
+ def __init__(self, *args):
354
+ # tuple.__init__ doesn't do anything
355
+ pass
356
+
357
+
358
+ class _PseudoMatch:
359
+ """
360
+ A pseudo match object constructed from a string.
361
+ """
362
+
363
+ def __init__(self, start, text):
364
+ self._text = text
365
+ self._start = start
366
+
367
+ def start(self, arg=None):
368
+ return self._start
369
+
370
+ def end(self, arg=None):
371
+ return self._start + len(self._text)
372
+
373
+ def group(self, arg=None):
374
+ if arg:
375
+ raise IndexError('No such group')
376
+ return self._text
377
+
378
+ def groups(self):
379
+ return (self._text,)
380
+
381
+ def groupdict(self):
382
+ return {}
383
+
384
+
385
+ def bygroups(*args):
386
+ """
387
+ Callback that yields multiple actions for each group in the match.
388
+ """
389
+ def callback(lexer, match, ctx=None):
390
+ for i, action in enumerate(args):
391
+ if action is None:
392
+ continue
393
+ elif type(action) is _TokenType:
394
+ data = match.group(i + 1)
395
+ if data:
396
+ yield match.start(i + 1), action, data
397
+ else:
398
+ data = match.group(i + 1)
399
+ if data is not None:
400
+ if ctx:
401
+ ctx.pos = match.start(i + 1)
402
+ for item in action(lexer,
403
+ _PseudoMatch(match.start(i + 1), data), ctx):
404
+ if item:
405
+ yield item
406
+ if ctx:
407
+ ctx.pos = match.end()
408
+ return callback
409
+
410
+
411
+ class _This:
412
+ """
413
+ Special singleton used for indicating the caller class.
414
+ Used by ``using``.
415
+ """
416
+
417
+ this = _This()
418
+
419
+
420
+ def using(_other, **kwargs):
421
+ """
422
+ Callback that processes the match with a different lexer.
423
+
424
+ The keyword arguments are forwarded to the lexer, except `state` which
425
+ is handled separately.
426
+
427
+ `state` specifies the state that the new lexer will start in, and can
428
+ be an enumerable such as ('root', 'inline', 'string') or a simple
429
+ string which is assumed to be on top of the root state.
430
+
431
+ Note: For that to work, `_other` must not be an `ExtendedRegexLexer`.
432
+ """
433
+ gt_kwargs = {}
434
+ if 'state' in kwargs:
435
+ s = kwargs.pop('state')
436
+ if isinstance(s, (list, tuple)):
437
+ gt_kwargs['stack'] = s
438
+ else:
439
+ gt_kwargs['stack'] = ('root', s)
440
+
441
+ if _other is this:
442
+ def callback(lexer, match, ctx=None):
443
+ # if keyword arguments are given the callback
444
+ # function has to create a new lexer instance
445
+ if kwargs:
446
+ # XXX: cache that somehow
447
+ kwargs.update(lexer.options)
448
+ lx = lexer.__class__(**kwargs)
449
+ else:
450
+ lx = lexer
451
+ s = match.start()
452
+ for i, t, v in lx.get_tokens_unprocessed(match.group(), **gt_kwargs):
453
+ yield i + s, t, v
454
+ if ctx:
455
+ ctx.pos = match.end()
456
+ else:
457
+ def callback(lexer, match, ctx=None):
458
+ # XXX: cache that somehow
459
+ kwargs.update(lexer.options)
460
+ lx = _other(**kwargs)
461
+
462
+ s = match.start()
463
+ for i, t, v in lx.get_tokens_unprocessed(match.group(), **gt_kwargs):
464
+ yield i + s, t, v
465
+ if ctx:
466
+ ctx.pos = match.end()
467
+ return callback
468
+
469
+
470
+ class default:
471
+ """
472
+ Indicates a state or state action (e.g. #pop) to apply.
473
+ For example default('#pop') is equivalent to ('', Token, '#pop')
474
+ Note that state tuples may be used as well.
475
+
476
+ .. versionadded:: 2.0
477
+ """
478
+ def __init__(self, state):
479
+ self.state = state
480
+
481
+
482
+ class words(Future):
483
+ """
484
+ Indicates a list of literal words that is transformed into an optimized
485
+ regex that matches any of the words.
486
+
487
+ .. versionadded:: 2.0
488
+ """
489
+ def __init__(self, words, prefix='', suffix=''):
490
+ self.words = words
491
+ self.prefix = prefix
492
+ self.suffix = suffix
493
+
494
+ def get(self):
495
+ return regex_opt(self.words, prefix=self.prefix, suffix=self.suffix)
496
+
497
+
498
+ class RegexLexerMeta(LexerMeta):
499
+ """
500
+ Metaclass for RegexLexer, creates the self._tokens attribute from
501
+ self.tokens on the first instantiation.
502
+ """
503
+
504
+ def _process_regex(cls, regex, rflags, state):
505
+ """Preprocess the regular expression component of a token definition."""
506
+ if isinstance(regex, Future):
507
+ regex = regex.get()
508
+ return re.compile(regex, rflags).match
509
+
510
+ def _process_token(cls, token):
511
+ """Preprocess the token component of a token definition."""
512
+ assert type(token) is _TokenType or callable(token), \
513
+ f'token type must be simple type or callable, not {token!r}'
514
+ return token
515
+
516
+ def _process_new_state(cls, new_state, unprocessed, processed):
517
+ """Preprocess the state transition action of a token definition."""
518
+ if isinstance(new_state, str):
519
+ # an existing state
520
+ if new_state == '#pop':
521
+ return -1
522
+ elif new_state in unprocessed:
523
+ return (new_state,)
524
+ elif new_state == '#push':
525
+ return new_state
526
+ elif new_state[:5] == '#pop:':
527
+ return -int(new_state[5:])
528
+ else:
529
+ assert False, f'unknown new state {new_state!r}'
530
+ elif isinstance(new_state, combined):
531
+ # combine a new state from existing ones
532
+ tmp_state = '_tmp_%d' % cls._tmpname
533
+ cls._tmpname += 1
534
+ itokens = []
535
+ for istate in new_state:
536
+ assert istate != new_state, f'circular state ref {istate!r}'
537
+ itokens.extend(cls._process_state(unprocessed,
538
+ processed, istate))
539
+ processed[tmp_state] = itokens
540
+ return (tmp_state,)
541
+ elif isinstance(new_state, tuple):
542
+ # push more than one state
543
+ for istate in new_state:
544
+ assert (istate in unprocessed or
545
+ istate in ('#pop', '#push')), \
546
+ 'unknown new state ' + istate
547
+ return new_state
548
+ else:
549
+ assert False, f'unknown new state def {new_state!r}'
550
+
551
+ def _process_state(cls, unprocessed, processed, state):
552
+ """Preprocess a single state definition."""
553
+ assert isinstance(state, str), f"wrong state name {state!r}"
554
+ assert state[0] != '#', f"invalid state name {state!r}"
555
+ if state in processed:
556
+ return processed[state]
557
+ tokens = processed[state] = []
558
+ rflags = cls.flags
559
+ for tdef in unprocessed[state]:
560
+ if isinstance(tdef, include):
561
+ # it's a state reference
562
+ assert tdef != state, f"circular state reference {state!r}"
563
+ tokens.extend(cls._process_state(unprocessed, processed,
564
+ str(tdef)))
565
+ continue
566
+ if isinstance(tdef, _inherit):
567
+ # should be processed already, but may not in the case of:
568
+ # 1. the state has no counterpart in any parent
569
+ # 2. the state includes more than one 'inherit'
570
+ continue
571
+ if isinstance(tdef, default):
572
+ new_state = cls._process_new_state(tdef.state, unprocessed, processed)
573
+ tokens.append((re.compile('').match, None, new_state))
574
+ continue
575
+
576
+ assert type(tdef) is tuple, f"wrong rule def {tdef!r}"
577
+
578
+ try:
579
+ rex = cls._process_regex(tdef[0], rflags, state)
580
+ except Exception as err:
581
+ raise ValueError(f"uncompilable regex {tdef[0]!r} in state {state!r} of {cls!r}: {err}") from err
582
+
583
+ token = cls._process_token(tdef[1])
584
+
585
+ if len(tdef) == 2:
586
+ new_state = None
587
+ else:
588
+ new_state = cls._process_new_state(tdef[2],
589
+ unprocessed, processed)
590
+
591
+ tokens.append((rex, token, new_state))
592
+ return tokens
593
+
594
+ def process_tokendef(cls, name, tokendefs=None):
595
+ """Preprocess a dictionary of token definitions."""
596
+ processed = cls._all_tokens[name] = {}
597
+ tokendefs = tokendefs or cls.tokens[name]
598
+ for state in list(tokendefs):
599
+ cls._process_state(tokendefs, processed, state)
600
+ return processed
601
+
602
+ def get_tokendefs(cls):
603
+ """
604
+ Merge tokens from superclasses in MRO order, returning a single tokendef
605
+ dictionary.
606
+
607
+ Any state that is not defined by a subclass will be inherited
608
+ automatically. States that *are* defined by subclasses will, by
609
+ default, override that state in the superclass. If a subclass wishes to
610
+ inherit definitions from a superclass, it can use the special value
611
+ "inherit", which will cause the superclass' state definition to be
612
+ included at that point in the state.
613
+ """
614
+ tokens = {}
615
+ inheritable = {}
616
+ for c in cls.__mro__:
617
+ toks = c.__dict__.get('tokens', {})
618
+
619
+ for state, items in toks.items():
620
+ curitems = tokens.get(state)
621
+ if curitems is None:
622
+ # N.b. because this is assigned by reference, sufficiently
623
+ # deep hierarchies are processed incrementally (e.g. for
624
+ # A(B), B(C), C(RegexLexer), B will be premodified so X(B)
625
+ # will not see any inherits in B).
626
+ tokens[state] = items
627
+ try:
628
+ inherit_ndx = items.index(inherit)
629
+ except ValueError:
630
+ continue
631
+ inheritable[state] = inherit_ndx
632
+ continue
633
+
634
+ inherit_ndx = inheritable.pop(state, None)
635
+ if inherit_ndx is None:
636
+ continue
637
+
638
+ # Replace the "inherit" value with the items
639
+ curitems[inherit_ndx:inherit_ndx+1] = items
640
+ try:
641
+ # N.b. this is the index in items (that is, the superclass
642
+ # copy), so offset required when storing below.
643
+ new_inh_ndx = items.index(inherit)
644
+ except ValueError:
645
+ pass
646
+ else:
647
+ inheritable[state] = inherit_ndx + new_inh_ndx
648
+
649
+ return tokens
650
+
651
+ def __call__(cls, *args, **kwds):
652
+ """Instantiate cls after preprocessing its token definitions."""
653
+ if '_tokens' not in cls.__dict__:
654
+ cls._all_tokens = {}
655
+ cls._tmpname = 0
656
+ if hasattr(cls, 'token_variants') and cls.token_variants:
657
+ # don't process yet
658
+ pass
659
+ else:
660
+ cls._tokens = cls.process_tokendef('', cls.get_tokendefs())
661
+
662
+ return type.__call__(cls, *args, **kwds)
663
+
664
+
665
+ class RegexLexer(Lexer, metaclass=RegexLexerMeta):
666
+ """
667
+ Base for simple stateful regular expression-based lexers.
668
+ Simplifies the lexing process so that you need only
669
+ provide a list of states and regular expressions.
670
+ """
671
+
672
+ #: Flags for compiling the regular expressions.
673
+ #: Defaults to MULTILINE.
674
+ flags = re.MULTILINE
675
+
676
+ #: At all time there is a stack of states. Initially, the stack contains
677
+ #: a single state 'root'. The top of the stack is called "the current state".
678
+ #:
679
+ #: Dict of ``{'state': [(regex, tokentype, new_state), ...], ...}``
680
+ #:
681
+ #: ``new_state`` can be omitted to signify no state transition.
682
+ #: If ``new_state`` is a string, it is pushed on the stack. This ensure
683
+ #: the new current state is ``new_state``.
684
+ #: If ``new_state`` is a tuple of strings, all of those strings are pushed
685
+ #: on the stack and the current state will be the last element of the list.
686
+ #: ``new_state`` can also be ``combined('state1', 'state2', ...)``
687
+ #: to signify a new, anonymous state combined from the rules of two
688
+ #: or more existing ones.
689
+ #: Furthermore, it can be '#pop' to signify going back one step in
690
+ #: the state stack, or '#push' to push the current state on the stack
691
+ #: again. Note that if you push while in a combined state, the combined
692
+ #: state itself is pushed, and not only the state in which the rule is
693
+ #: defined.
694
+ #:
695
+ #: The tuple can also be replaced with ``include('state')``, in which
696
+ #: case the rules from the state named by the string are included in the
697
+ #: current one.
698
+ tokens = {}
699
+
700
+ def get_tokens_unprocessed(self, text, stack=('root',)):
701
+ """
702
+ Split ``text`` into (tokentype, text) pairs.
703
+
704
+ ``stack`` is the initial stack (default: ``['root']``)
705
+ """
706
+ pos = 0
707
+ tokendefs = self._tokens
708
+ statestack = list(stack)
709
+ statetokens = tokendefs[statestack[-1]]
710
+ while 1:
711
+ for rexmatch, action, new_state in statetokens:
712
+ m = rexmatch(text, pos)
713
+ if m:
714
+ if action is not None:
715
+ if type(action) is _TokenType:
716
+ yield pos, action, m.group()
717
+ else:
718
+ yield from action(self, m)
719
+ pos = m.end()
720
+ if new_state is not None:
721
+ # state transition
722
+ if isinstance(new_state, tuple):
723
+ for state in new_state:
724
+ if state == '#pop':
725
+ if len(statestack) > 1:
726
+ statestack.pop()
727
+ elif state == '#push':
728
+ statestack.append(statestack[-1])
729
+ else:
730
+ statestack.append(state)
731
+ elif isinstance(new_state, int):
732
+ # pop, but keep at least one state on the stack
733
+ # (random code leading to unexpected pops should
734
+ # not allow exceptions)
735
+ if abs(new_state) >= len(statestack):
736
+ del statestack[1:]
737
+ else:
738
+ del statestack[new_state:]
739
+ elif new_state == '#push':
740
+ statestack.append(statestack[-1])
741
+ else:
742
+ assert False, f"wrong state def: {new_state!r}"
743
+ statetokens = tokendefs[statestack[-1]]
744
+ break
745
+ else:
746
+ # We are here only if all state tokens have been considered
747
+ # and there was not a match on any of them.
748
+ try:
749
+ if text[pos] == '\n':
750
+ # at EOL, reset state to "root"
751
+ statestack = ['root']
752
+ statetokens = tokendefs['root']
753
+ yield pos, Whitespace, '\n'
754
+ pos += 1
755
+ continue
756
+ yield pos, Error, text[pos]
757
+ pos += 1
758
+ except IndexError:
759
+ break
760
+
761
+
762
+ class LexerContext:
763
+ """
764
+ A helper object that holds lexer position data.
765
+ """
766
+
767
+ def __init__(self, text, pos, stack=None, end=None):
768
+ self.text = text
769
+ self.pos = pos
770
+ self.end = end or len(text) # end=0 not supported ;-)
771
+ self.stack = stack or ['root']
772
+
773
+ def __repr__(self):
774
+ return f'LexerContext({self.text!r}, {self.pos!r}, {self.stack!r})'
775
+
776
+
777
+ class ExtendedRegexLexer(RegexLexer):
778
+ """
779
+ A RegexLexer that uses a context object to store its state.
780
+ """
781
+
782
+ def get_tokens_unprocessed(self, text=None, context=None):
783
+ """
784
+ Split ``text`` into (tokentype, text) pairs.
785
+ If ``context`` is given, use this lexer context instead.
786
+ """
787
+ tokendefs = self._tokens
788
+ if not context:
789
+ ctx = LexerContext(text, 0)
790
+ statetokens = tokendefs['root']
791
+ else:
792
+ ctx = context
793
+ statetokens = tokendefs[ctx.stack[-1]]
794
+ text = ctx.text
795
+ while 1:
796
+ for rexmatch, action, new_state in statetokens:
797
+ m = rexmatch(text, ctx.pos, ctx.end)
798
+ if m:
799
+ if action is not None:
800
+ if type(action) is _TokenType:
801
+ yield ctx.pos, action, m.group()
802
+ ctx.pos = m.end()
803
+ else:
804
+ yield from action(self, m, ctx)
805
+ if not new_state:
806
+ # altered the state stack?
807
+ statetokens = tokendefs[ctx.stack[-1]]
808
+ # CAUTION: callback must set ctx.pos!
809
+ if new_state is not None:
810
+ # state transition
811
+ if isinstance(new_state, tuple):
812
+ for state in new_state:
813
+ if state == '#pop':
814
+ if len(ctx.stack) > 1:
815
+ ctx.stack.pop()
816
+ elif state == '#push':
817
+ ctx.stack.append(ctx.stack[-1])
818
+ else:
819
+ ctx.stack.append(state)
820
+ elif isinstance(new_state, int):
821
+ # see RegexLexer for why this check is made
822
+ if abs(new_state) >= len(ctx.stack):
823
+ del ctx.stack[1:]
824
+ else:
825
+ del ctx.stack[new_state:]
826
+ elif new_state == '#push':
827
+ ctx.stack.append(ctx.stack[-1])
828
+ else:
829
+ assert False, f"wrong state def: {new_state!r}"
830
+ statetokens = tokendefs[ctx.stack[-1]]
831
+ break
832
+ else:
833
+ try:
834
+ if ctx.pos >= ctx.end:
835
+ break
836
+ if text[ctx.pos] == '\n':
837
+ # at EOL, reset state to "root"
838
+ ctx.stack = ['root']
839
+ statetokens = tokendefs['root']
840
+ yield ctx.pos, Text, '\n'
841
+ ctx.pos += 1
842
+ continue
843
+ yield ctx.pos, Error, text[ctx.pos]
844
+ ctx.pos += 1
845
+ except IndexError:
846
+ break
847
+
848
+
849
+ def do_insertions(insertions, tokens):
850
+ """
851
+ Helper for lexers which must combine the results of several
852
+ sublexers.
853
+
854
+ ``insertions`` is a list of ``(index, itokens)`` pairs.
855
+ Each ``itokens`` iterable should be inserted at position
856
+ ``index`` into the token stream given by the ``tokens``
857
+ argument.
858
+
859
+ The result is a combined token stream.
860
+
861
+ TODO: clean up the code here.
862
+ """
863
+ insertions = iter(insertions)
864
+ try:
865
+ index, itokens = next(insertions)
866
+ except StopIteration:
867
+ # no insertions
868
+ yield from tokens
869
+ return
870
+
871
+ realpos = None
872
+ insleft = True
873
+
874
+ # iterate over the token stream where we want to insert
875
+ # the tokens from the insertion list.
876
+ for i, t, v in tokens:
877
+ # first iteration. store the position of first item
878
+ if realpos is None:
879
+ realpos = i
880
+ oldi = 0
881
+ while insleft and i + len(v) >= index:
882
+ tmpval = v[oldi:index - i]
883
+ if tmpval:
884
+ yield realpos, t, tmpval
885
+ realpos += len(tmpval)
886
+ for it_index, it_token, it_value in itokens:
887
+ yield realpos, it_token, it_value
888
+ realpos += len(it_value)
889
+ oldi = index - i
890
+ try:
891
+ index, itokens = next(insertions)
892
+ except StopIteration:
893
+ insleft = False
894
+ break # not strictly necessary
895
+ if oldi < len(v):
896
+ yield realpos, t, v[oldi:]
897
+ realpos += len(v) - oldi
898
+
899
+ # leftover tokens
900
+ while insleft:
901
+ # no normal tokens, set realpos to zero
902
+ realpos = realpos or 0
903
+ for p, t, v in itokens:
904
+ yield realpos, t, v
905
+ realpos += len(v)
906
+ try:
907
+ index, itokens = next(insertions)
908
+ except StopIteration:
909
+ insleft = False
910
+ break # not strictly necessary
911
+
912
+
913
+ class ProfilingRegexLexerMeta(RegexLexerMeta):
914
+ """Metaclass for ProfilingRegexLexer, collects regex timing info."""
915
+
916
+ def _process_regex(cls, regex, rflags, state):
917
+ if isinstance(regex, words):
918
+ rex = regex_opt(regex.words, prefix=regex.prefix,
919
+ suffix=regex.suffix)
920
+ else:
921
+ rex = regex
922
+ compiled = re.compile(rex, rflags)
923
+
924
+ def match_func(text, pos, endpos=sys.maxsize):
925
+ info = cls._prof_data[-1].setdefault((state, rex), [0, 0.0])
926
+ t0 = time.time()
927
+ res = compiled.match(text, pos, endpos)
928
+ t1 = time.time()
929
+ info[0] += 1
930
+ info[1] += t1 - t0
931
+ return res
932
+ return match_func
933
+
934
+
935
+ class ProfilingRegexLexer(RegexLexer, metaclass=ProfilingRegexLexerMeta):
936
+ """Drop-in replacement for RegexLexer that does profiling of its regexes."""
937
+
938
+ _prof_data = []
939
+ _prof_sort_index = 4 # defaults to time per call
940
+
941
+ def get_tokens_unprocessed(self, text, stack=('root',)):
942
+ # this needs to be a stack, since using(this) will produce nested calls
943
+ self.__class__._prof_data.append({})
944
+ yield from RegexLexer.get_tokens_unprocessed(self, text, stack)
945
+ rawdata = self.__class__._prof_data.pop()
946
+ data = sorted(((s, repr(r).strip('u\'').replace('\\\\', '\\')[:65],
947
+ n, 1000 * t, 1000 * t / n)
948
+ for ((s, r), (n, t)) in rawdata.items()),
949
+ key=lambda x: x[self._prof_sort_index],
950
+ reverse=True)
951
+ sum_total = sum(x[3] for x in data)
952
+
953
+ print()
954
+ print('Profiling result for %s lexing %d chars in %.3f ms' %
955
+ (self.__class__.__name__, len(text), sum_total))
956
+ print('=' * 110)
957
+ print('%-20s %-64s ncalls tottime percall' % ('state', 'regex'))
958
+ print('-' * 110)
959
+ for d in data:
960
+ print('%-20s %-65s %5d %8.4f %8.4f' % d)
961
+ print('=' * 110)
lib/python3.12/site-packages/pygments/modeline.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.modeline
3
+ ~~~~~~~~~~~~~~~~~
4
+
5
+ A simple modeline parser (based on pymodeline).
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ import re
12
+
13
+ __all__ = ['get_filetype_from_buffer']
14
+
15
+
16
+ modeline_re = re.compile(r'''
17
+ (?: vi | vim | ex ) (?: [<=>]? \d* )? :
18
+ .* (?: ft | filetype | syn | syntax ) = ( [^:\s]+ )
19
+ ''', re.VERBOSE)
20
+
21
+
22
+ def get_filetype_from_line(l): # noqa: E741
23
+ m = modeline_re.search(l)
24
+ if m:
25
+ return m.group(1)
26
+
27
+
28
+ def get_filetype_from_buffer(buf, max_lines=5):
29
+ """
30
+ Scan the buffer for modelines and return filetype if one is found.
31
+ """
32
+ lines = buf.splitlines()
33
+ for line in lines[-1:-max_lines-1:-1]:
34
+ ret = get_filetype_from_line(line)
35
+ if ret:
36
+ return ret
37
+ for i in range(max_lines, -1, -1):
38
+ if i < len(lines):
39
+ ret = get_filetype_from_line(lines[i])
40
+ if ret:
41
+ return ret
42
+
43
+ return None
lib/python3.12/site-packages/pygments/plugin.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.plugin
3
+ ~~~~~~~~~~~~~~~
4
+
5
+ Pygments plugin interface.
6
+
7
+ lexer plugins::
8
+
9
+ [pygments.lexers]
10
+ yourlexer = yourmodule:YourLexer
11
+
12
+ formatter plugins::
13
+
14
+ [pygments.formatters]
15
+ yourformatter = yourformatter:YourFormatter
16
+ /.ext = yourformatter:YourFormatter
17
+
18
+ As you can see, you can define extensions for the formatter
19
+ with a leading slash.
20
+
21
+ syntax plugins::
22
+
23
+ [pygments.styles]
24
+ yourstyle = yourstyle:YourStyle
25
+
26
+ filter plugin::
27
+
28
+ [pygments.filter]
29
+ yourfilter = yourfilter:YourFilter
30
+
31
+
32
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
33
+ :license: BSD, see LICENSE for details.
34
+ """
35
+ from importlib.metadata import entry_points
36
+
37
+ LEXER_ENTRY_POINT = 'pygments.lexers'
38
+ FORMATTER_ENTRY_POINT = 'pygments.formatters'
39
+ STYLE_ENTRY_POINT = 'pygments.styles'
40
+ FILTER_ENTRY_POINT = 'pygments.filters'
41
+
42
+
43
+ def iter_entry_points(group_name):
44
+ groups = entry_points()
45
+ if hasattr(groups, 'select'):
46
+ # New interface in Python 3.10 and newer versions of the
47
+ # importlib_metadata backport.
48
+ return groups.select(group=group_name)
49
+ else:
50
+ # Older interface, deprecated in Python 3.10 and recent
51
+ # importlib_metadata, but we need it in Python 3.8 and 3.9.
52
+ return groups.get(group_name, [])
53
+
54
+
55
+ def find_plugin_lexers():
56
+ for entrypoint in iter_entry_points(LEXER_ENTRY_POINT):
57
+ yield entrypoint.load()
58
+
59
+
60
+ def find_plugin_formatters():
61
+ for entrypoint in iter_entry_points(FORMATTER_ENTRY_POINT):
62
+ yield entrypoint.name, entrypoint.load()
63
+
64
+
65
+ def find_plugin_styles():
66
+ for entrypoint in iter_entry_points(STYLE_ENTRY_POINT):
67
+ yield entrypoint.name, entrypoint.load()
68
+
69
+
70
+ def find_plugin_filters():
71
+ for entrypoint in iter_entry_points(FILTER_ENTRY_POINT):
72
+ yield entrypoint.name, entrypoint.load()
lib/python3.12/site-packages/pygments/regexopt.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.regexopt
3
+ ~~~~~~~~~~~~~~~~~
4
+
5
+ An algorithm that generates optimized regexes for matching long lists of
6
+ literal strings.
7
+
8
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
9
+ :license: BSD, see LICENSE for details.
10
+ """
11
+
12
+ import re
13
+ from re import escape
14
+ from os.path import commonprefix
15
+ from itertools import groupby
16
+ from operator import itemgetter
17
+
18
+ CS_ESCAPE = re.compile(r'[\[\^\\\-\]]')
19
+ FIRST_ELEMENT = itemgetter(0)
20
+
21
+
22
+ def make_charset(letters):
23
+ return '[' + CS_ESCAPE.sub(lambda m: '\\' + m.group(), ''.join(letters)) + ']'
24
+
25
+
26
+ def regex_opt_inner(strings, open_paren):
27
+ """Return a regex that matches any string in the sorted list of strings."""
28
+ close_paren = open_paren and ')' or ''
29
+ # print strings, repr(open_paren)
30
+ if not strings:
31
+ # print '-> nothing left'
32
+ return ''
33
+ first = strings[0]
34
+ if len(strings) == 1:
35
+ # print '-> only 1 string'
36
+ return open_paren + escape(first) + close_paren
37
+ if not first:
38
+ # print '-> first string empty'
39
+ return open_paren + regex_opt_inner(strings[1:], '(?:') \
40
+ + '?' + close_paren
41
+ if len(first) == 1:
42
+ # multiple one-char strings? make a charset
43
+ oneletter = []
44
+ rest = []
45
+ for s in strings:
46
+ if len(s) == 1:
47
+ oneletter.append(s)
48
+ else:
49
+ rest.append(s)
50
+ if len(oneletter) > 1: # do we have more than one oneletter string?
51
+ if rest:
52
+ # print '-> 1-character + rest'
53
+ return open_paren + regex_opt_inner(rest, '') + '|' \
54
+ + make_charset(oneletter) + close_paren
55
+ # print '-> only 1-character'
56
+ return open_paren + make_charset(oneletter) + close_paren
57
+ prefix = commonprefix(strings)
58
+ if prefix:
59
+ plen = len(prefix)
60
+ # we have a prefix for all strings
61
+ # print '-> prefix:', prefix
62
+ return open_paren + escape(prefix) \
63
+ + regex_opt_inner([s[plen:] for s in strings], '(?:') \
64
+ + close_paren
65
+ # is there a suffix?
66
+ strings_rev = [s[::-1] for s in strings]
67
+ suffix = commonprefix(strings_rev)
68
+ if suffix:
69
+ slen = len(suffix)
70
+ # print '-> suffix:', suffix[::-1]
71
+ return open_paren \
72
+ + regex_opt_inner(sorted(s[:-slen] for s in strings), '(?:') \
73
+ + escape(suffix[::-1]) + close_paren
74
+ # recurse on common 1-string prefixes
75
+ # print '-> last resort'
76
+ return open_paren + \
77
+ '|'.join(regex_opt_inner(list(group[1]), '')
78
+ for group in groupby(strings, lambda s: s[0] == first[0])) \
79
+ + close_paren
80
+
81
+
82
+ def regex_opt(strings, prefix='', suffix=''):
83
+ """Return a compiled regex that matches any string in the given list.
84
+
85
+ The strings to match must be literal strings, not regexes. They will be
86
+ regex-escaped.
87
+
88
+ *prefix* and *suffix* are pre- and appended to the final regex.
89
+ """
90
+ strings = sorted(strings)
91
+ return prefix + regex_opt_inner(strings, '(') + suffix
lib/python3.12/site-packages/pygments/scanner.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.scanner
3
+ ~~~~~~~~~~~~~~~~
4
+
5
+ This library implements a regex based scanner. Some languages
6
+ like Pascal are easy to parse but have some keywords that
7
+ depend on the context. Because of this it's impossible to lex
8
+ that just by using a regular expression lexer like the
9
+ `RegexLexer`.
10
+
11
+ Have a look at the `DelphiLexer` to get an idea of how to use
12
+ this scanner.
13
+
14
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
15
+ :license: BSD, see LICENSE for details.
16
+ """
17
+ import re
18
+
19
+
20
+ class EndOfText(RuntimeError):
21
+ """
22
+ Raise if end of text is reached and the user
23
+ tried to call a match function.
24
+ """
25
+
26
+
27
+ class Scanner:
28
+ """
29
+ Simple scanner
30
+
31
+ All method patterns are regular expression strings (not
32
+ compiled expressions!)
33
+ """
34
+
35
+ def __init__(self, text, flags=0):
36
+ """
37
+ :param text: The text which should be scanned
38
+ :param flags: default regular expression flags
39
+ """
40
+ self.data = text
41
+ self.data_length = len(text)
42
+ self.start_pos = 0
43
+ self.pos = 0
44
+ self.flags = flags
45
+ self.last = None
46
+ self.match = None
47
+ self._re_cache = {}
48
+
49
+ def eos(self):
50
+ """`True` if the scanner reached the end of text."""
51
+ return self.pos >= self.data_length
52
+ eos = property(eos, eos.__doc__)
53
+
54
+ def check(self, pattern):
55
+ """
56
+ Apply `pattern` on the current position and return
57
+ the match object. (Doesn't touch pos). Use this for
58
+ lookahead.
59
+ """
60
+ if self.eos:
61
+ raise EndOfText()
62
+ if pattern not in self._re_cache:
63
+ self._re_cache[pattern] = re.compile(pattern, self.flags)
64
+ return self._re_cache[pattern].match(self.data, self.pos)
65
+
66
+ def test(self, pattern):
67
+ """Apply a pattern on the current position and check
68
+ if it patches. Doesn't touch pos.
69
+ """
70
+ return self.check(pattern) is not None
71
+
72
+ def scan(self, pattern):
73
+ """
74
+ Scan the text for the given pattern and update pos/match
75
+ and related fields. The return value is a boolean that
76
+ indicates if the pattern matched. The matched value is
77
+ stored on the instance as ``match``, the last value is
78
+ stored as ``last``. ``start_pos`` is the position of the
79
+ pointer before the pattern was matched, ``pos`` is the
80
+ end position.
81
+ """
82
+ if self.eos:
83
+ raise EndOfText()
84
+ if pattern not in self._re_cache:
85
+ self._re_cache[pattern] = re.compile(pattern, self.flags)
86
+ self.last = self.match
87
+ m = self._re_cache[pattern].match(self.data, self.pos)
88
+ if m is None:
89
+ return False
90
+ self.start_pos = m.start()
91
+ self.pos = m.end()
92
+ self.match = m.group()
93
+ return True
94
+
95
+ def get_char(self):
96
+ """Scan exactly one char."""
97
+ self.scan('.')
98
+
99
+ def __repr__(self):
100
+ return '<%s %d/%d>' % (
101
+ self.__class__.__name__,
102
+ self.pos,
103
+ self.data_length
104
+ )
lib/python3.12/site-packages/pygments/sphinxext.py ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.sphinxext
3
+ ~~~~~~~~~~~~~~~~~~
4
+
5
+ Sphinx extension to generate automatic documentation of lexers,
6
+ formatters and filters.
7
+
8
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
9
+ :license: BSD, see LICENSE for details.
10
+ """
11
+
12
+ import sys
13
+
14
+ from docutils import nodes
15
+ from docutils.statemachine import ViewList
16
+ from docutils.parsers.rst import Directive
17
+ from sphinx.util.nodes import nested_parse_with_titles
18
+
19
+
20
+ MODULEDOC = '''
21
+ .. module:: %s
22
+
23
+ %s
24
+ %s
25
+ '''
26
+
27
+ LEXERDOC = '''
28
+ .. class:: %s
29
+
30
+ :Short names: %s
31
+ :Filenames: %s
32
+ :MIME types: %s
33
+
34
+ %s
35
+
36
+ %s
37
+
38
+ '''
39
+
40
+ FMTERDOC = '''
41
+ .. class:: %s
42
+
43
+ :Short names: %s
44
+ :Filenames: %s
45
+
46
+ %s
47
+
48
+ '''
49
+
50
+ FILTERDOC = '''
51
+ .. class:: %s
52
+
53
+ :Name: %s
54
+
55
+ %s
56
+
57
+ '''
58
+
59
+
60
+ class PygmentsDoc(Directive):
61
+ """
62
+ A directive to collect all lexers/formatters/filters and generate
63
+ autoclass directives for them.
64
+ """
65
+ has_content = False
66
+ required_arguments = 1
67
+ optional_arguments = 0
68
+ final_argument_whitespace = False
69
+ option_spec = {}
70
+
71
+ def run(self):
72
+ self.filenames = set()
73
+ if self.arguments[0] == 'lexers':
74
+ out = self.document_lexers()
75
+ elif self.arguments[0] == 'formatters':
76
+ out = self.document_formatters()
77
+ elif self.arguments[0] == 'filters':
78
+ out = self.document_filters()
79
+ elif self.arguments[0] == 'lexers_overview':
80
+ out = self.document_lexers_overview()
81
+ else:
82
+ raise Exception('invalid argument for "pygmentsdoc" directive')
83
+ node = nodes.compound()
84
+ vl = ViewList(out.split('\n'), source='')
85
+ nested_parse_with_titles(self.state, vl, node)
86
+ for fn in self.filenames:
87
+ self.state.document.settings.record_dependencies.add(fn)
88
+ return node.children
89
+
90
+ def document_lexers_overview(self):
91
+ """Generate a tabular overview of all lexers.
92
+
93
+ The columns are the lexer name, the extensions handled by this lexer
94
+ (or "None"), the aliases and a link to the lexer class."""
95
+ from pygments.lexers._mapping import LEXERS
96
+ import pygments.lexers
97
+ out = []
98
+
99
+ table = []
100
+
101
+ def format_link(name, url):
102
+ if url:
103
+ return f'`{name} <{url}>`_'
104
+ return name
105
+
106
+ for classname, data in sorted(LEXERS.items(), key=lambda x: x[1][1].lower()):
107
+ lexer_cls = pygments.lexers.find_lexer_class(data[1])
108
+ extensions = lexer_cls.filenames + lexer_cls.alias_filenames
109
+
110
+ table.append({
111
+ 'name': format_link(data[1], lexer_cls.url),
112
+ 'extensions': ', '.join(extensions).replace('*', '\\*').replace('_', '\\') or 'None',
113
+ 'aliases': ', '.join(data[2]),
114
+ 'class': f'{data[0]}.{classname}'
115
+ })
116
+
117
+ column_names = ['name', 'extensions', 'aliases', 'class']
118
+ column_lengths = [max([len(row[column]) for row in table if row[column]])
119
+ for column in column_names]
120
+
121
+ def write_row(*columns):
122
+ """Format a table row"""
123
+ out = []
124
+ for length, col in zip(column_lengths, columns):
125
+ if col:
126
+ out.append(col.ljust(length))
127
+ else:
128
+ out.append(' '*length)
129
+
130
+ return ' '.join(out)
131
+
132
+ def write_seperator():
133
+ """Write a table separator row"""
134
+ sep = ['='*c for c in column_lengths]
135
+ return write_row(*sep)
136
+
137
+ out.append(write_seperator())
138
+ out.append(write_row('Name', 'Extension(s)', 'Short name(s)', 'Lexer class'))
139
+ out.append(write_seperator())
140
+ for row in table:
141
+ out.append(write_row(
142
+ row['name'],
143
+ row['extensions'],
144
+ row['aliases'],
145
+ f':class:`~{row["class"]}`'))
146
+ out.append(write_seperator())
147
+
148
+ return '\n'.join(out)
149
+
150
+ def document_lexers(self):
151
+ from pygments.lexers._mapping import LEXERS
152
+ import pygments
153
+ import inspect
154
+ import pathlib
155
+
156
+ out = []
157
+ modules = {}
158
+ moduledocstrings = {}
159
+ for classname, data in sorted(LEXERS.items(), key=lambda x: x[0]):
160
+ module = data[0]
161
+ mod = __import__(module, None, None, [classname])
162
+ self.filenames.add(mod.__file__)
163
+ cls = getattr(mod, classname)
164
+ if not cls.__doc__:
165
+ print(f"Warning: {classname} does not have a docstring.")
166
+ docstring = cls.__doc__
167
+ if isinstance(docstring, bytes):
168
+ docstring = docstring.decode('utf8')
169
+
170
+ example_file = getattr(cls, '_example', None)
171
+ if example_file:
172
+ p = pathlib.Path(inspect.getabsfile(pygments)).parent.parent /\
173
+ 'tests' / 'examplefiles' / example_file
174
+ content = p.read_text(encoding='utf-8')
175
+ if not content:
176
+ raise Exception(
177
+ f"Empty example file '{example_file}' for lexer "
178
+ f"{classname}")
179
+
180
+ if data[2]:
181
+ lexer_name = data[2][0]
182
+ docstring += '\n\n .. admonition:: Example\n'
183
+ docstring += f'\n .. code-block:: {lexer_name}\n\n'
184
+ for line in content.splitlines():
185
+ docstring += f' {line}\n'
186
+
187
+ if cls.version_added:
188
+ version_line = f'.. versionadded:: {cls.version_added}'
189
+ else:
190
+ version_line = ''
191
+
192
+ modules.setdefault(module, []).append((
193
+ classname,
194
+ ', '.join(data[2]) or 'None',
195
+ ', '.join(data[3]).replace('*', '\\*').replace('_', '\\') or 'None',
196
+ ', '.join(data[4]) or 'None',
197
+ docstring,
198
+ version_line))
199
+ if module not in moduledocstrings:
200
+ moddoc = mod.__doc__
201
+ if isinstance(moddoc, bytes):
202
+ moddoc = moddoc.decode('utf8')
203
+ moduledocstrings[module] = moddoc
204
+
205
+ for module, lexers in sorted(modules.items(), key=lambda x: x[0]):
206
+ if moduledocstrings[module] is None:
207
+ raise Exception(f"Missing docstring for {module}")
208
+ heading = moduledocstrings[module].splitlines()[4].strip().rstrip('.')
209
+ out.append(MODULEDOC % (module, heading, '-'*len(heading)))
210
+ for data in lexers:
211
+ out.append(LEXERDOC % data)
212
+
213
+ return ''.join(out)
214
+
215
+ def document_formatters(self):
216
+ from pygments.formatters import FORMATTERS
217
+
218
+ out = []
219
+ for classname, data in sorted(FORMATTERS.items(), key=lambda x: x[0]):
220
+ module = data[0]
221
+ mod = __import__(module, None, None, [classname])
222
+ self.filenames.add(mod.__file__)
223
+ cls = getattr(mod, classname)
224
+ docstring = cls.__doc__
225
+ if isinstance(docstring, bytes):
226
+ docstring = docstring.decode('utf8')
227
+ heading = cls.__name__
228
+ out.append(FMTERDOC % (heading, ', '.join(data[2]) or 'None',
229
+ ', '.join(data[3]).replace('*', '\\*') or 'None',
230
+ docstring))
231
+ return ''.join(out)
232
+
233
+ def document_filters(self):
234
+ from pygments.filters import FILTERS
235
+
236
+ out = []
237
+ for name, cls in FILTERS.items():
238
+ self.filenames.add(sys.modules[cls.__module__].__file__)
239
+ docstring = cls.__doc__
240
+ if isinstance(docstring, bytes):
241
+ docstring = docstring.decode('utf8')
242
+ out.append(FILTERDOC % (cls.__name__, name, docstring))
243
+ return ''.join(out)
244
+
245
+
246
+ def setup(app):
247
+ app.add_directive('pygmentsdoc', PygmentsDoc)
lib/python3.12/site-packages/pygments/style.py ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.style
3
+ ~~~~~~~~~~~~~~
4
+
5
+ Basic style object.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ from pygments.token import Token, STANDARD_TYPES
12
+
13
+ # Default mapping of ansixxx to RGB colors.
14
+ _ansimap = {
15
+ # dark
16
+ 'ansiblack': '000000',
17
+ 'ansired': '7f0000',
18
+ 'ansigreen': '007f00',
19
+ 'ansiyellow': '7f7fe0',
20
+ 'ansiblue': '00007f',
21
+ 'ansimagenta': '7f007f',
22
+ 'ansicyan': '007f7f',
23
+ 'ansigray': 'e5e5e5',
24
+ # normal
25
+ 'ansibrightblack': '555555',
26
+ 'ansibrightred': 'ff0000',
27
+ 'ansibrightgreen': '00ff00',
28
+ 'ansibrightyellow': 'ffff00',
29
+ 'ansibrightblue': '0000ff',
30
+ 'ansibrightmagenta': 'ff00ff',
31
+ 'ansibrightcyan': '00ffff',
32
+ 'ansiwhite': 'ffffff',
33
+ }
34
+ # mapping of deprecated #ansixxx colors to new color names
35
+ _deprecated_ansicolors = {
36
+ # dark
37
+ '#ansiblack': 'ansiblack',
38
+ '#ansidarkred': 'ansired',
39
+ '#ansidarkgreen': 'ansigreen',
40
+ '#ansibrown': 'ansiyellow',
41
+ '#ansidarkblue': 'ansiblue',
42
+ '#ansipurple': 'ansimagenta',
43
+ '#ansiteal': 'ansicyan',
44
+ '#ansilightgray': 'ansigray',
45
+ # normal
46
+ '#ansidarkgray': 'ansibrightblack',
47
+ '#ansired': 'ansibrightred',
48
+ '#ansigreen': 'ansibrightgreen',
49
+ '#ansiyellow': 'ansibrightyellow',
50
+ '#ansiblue': 'ansibrightblue',
51
+ '#ansifuchsia': 'ansibrightmagenta',
52
+ '#ansiturquoise': 'ansibrightcyan',
53
+ '#ansiwhite': 'ansiwhite',
54
+ }
55
+ ansicolors = set(_ansimap)
56
+
57
+
58
+ class StyleMeta(type):
59
+
60
+ def __new__(mcs, name, bases, dct):
61
+ obj = type.__new__(mcs, name, bases, dct)
62
+ for token in STANDARD_TYPES:
63
+ if token not in obj.styles:
64
+ obj.styles[token] = ''
65
+
66
+ def colorformat(text):
67
+ if text in ansicolors:
68
+ return text
69
+ if text[0:1] == '#':
70
+ col = text[1:]
71
+ if len(col) == 6:
72
+ return col
73
+ elif len(col) == 3:
74
+ return col[0] * 2 + col[1] * 2 + col[2] * 2
75
+ elif text == '':
76
+ return ''
77
+ elif text.startswith('var') or text.startswith('calc'):
78
+ return text
79
+ assert False, f"wrong color format {text!r}"
80
+
81
+ _styles = obj._styles = {}
82
+
83
+ for ttype in obj.styles:
84
+ for token in ttype.split():
85
+ if token in _styles:
86
+ continue
87
+ ndef = _styles.get(token.parent, None)
88
+ styledefs = obj.styles.get(token, '').split()
89
+ if not ndef or token is None:
90
+ ndef = ['', 0, 0, 0, '', '', 0, 0, 0]
91
+ elif 'noinherit' in styledefs and token is not Token:
92
+ ndef = _styles[Token][:]
93
+ else:
94
+ ndef = ndef[:]
95
+ _styles[token] = ndef
96
+ for styledef in obj.styles.get(token, '').split():
97
+ if styledef == 'noinherit':
98
+ pass
99
+ elif styledef == 'bold':
100
+ ndef[1] = 1
101
+ elif styledef == 'nobold':
102
+ ndef[1] = 0
103
+ elif styledef == 'italic':
104
+ ndef[2] = 1
105
+ elif styledef == 'noitalic':
106
+ ndef[2] = 0
107
+ elif styledef == 'underline':
108
+ ndef[3] = 1
109
+ elif styledef == 'nounderline':
110
+ ndef[3] = 0
111
+ elif styledef[:3] == 'bg:':
112
+ ndef[4] = colorformat(styledef[3:])
113
+ elif styledef[:7] == 'border:':
114
+ ndef[5] = colorformat(styledef[7:])
115
+ elif styledef == 'roman':
116
+ ndef[6] = 1
117
+ elif styledef == 'sans':
118
+ ndef[7] = 1
119
+ elif styledef == 'mono':
120
+ ndef[8] = 1
121
+ else:
122
+ ndef[0] = colorformat(styledef)
123
+
124
+ return obj
125
+
126
+ def style_for_token(cls, token):
127
+ t = cls._styles[token]
128
+ ansicolor = bgansicolor = None
129
+ color = t[0]
130
+ if color in _deprecated_ansicolors:
131
+ color = _deprecated_ansicolors[color]
132
+ if color in ansicolors:
133
+ ansicolor = color
134
+ color = _ansimap[color]
135
+ bgcolor = t[4]
136
+ if bgcolor in _deprecated_ansicolors:
137
+ bgcolor = _deprecated_ansicolors[bgcolor]
138
+ if bgcolor in ansicolors:
139
+ bgansicolor = bgcolor
140
+ bgcolor = _ansimap[bgcolor]
141
+
142
+ return {
143
+ 'color': color or None,
144
+ 'bold': bool(t[1]),
145
+ 'italic': bool(t[2]),
146
+ 'underline': bool(t[3]),
147
+ 'bgcolor': bgcolor or None,
148
+ 'border': t[5] or None,
149
+ 'roman': bool(t[6]) or None,
150
+ 'sans': bool(t[7]) or None,
151
+ 'mono': bool(t[8]) or None,
152
+ 'ansicolor': ansicolor,
153
+ 'bgansicolor': bgansicolor,
154
+ }
155
+
156
+ def list_styles(cls):
157
+ return list(cls)
158
+
159
+ def styles_token(cls, ttype):
160
+ return ttype in cls._styles
161
+
162
+ def __iter__(cls):
163
+ for token in cls._styles:
164
+ yield token, cls.style_for_token(token)
165
+
166
+ def __len__(cls):
167
+ return len(cls._styles)
168
+
169
+
170
+ class Style(metaclass=StyleMeta):
171
+
172
+ #: overall background color (``None`` means transparent)
173
+ background_color = '#ffffff'
174
+
175
+ #: highlight background color
176
+ highlight_color = '#ffffcc'
177
+
178
+ #: line number font color
179
+ line_number_color = 'inherit'
180
+
181
+ #: line number background color
182
+ line_number_background_color = 'transparent'
183
+
184
+ #: special line number font color
185
+ line_number_special_color = '#000000'
186
+
187
+ #: special line number background color
188
+ line_number_special_background_color = '#ffffc0'
189
+
190
+ #: Style definitions for individual token types.
191
+ styles = {}
192
+
193
+ #: user-friendly style name (used when selecting the style, so this
194
+ # should be all-lowercase, no spaces, hyphens)
195
+ name = 'unnamed'
196
+
197
+ aliases = []
198
+
199
+ # Attribute for lexers defined within Pygments. If set
200
+ # to True, the style is not shown in the style gallery
201
+ # on the website. This is intended for language-specific
202
+ # styles.
203
+ web_style_gallery_exclude = False
lib/python3.12/site-packages/pygments/styles/colorful.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.styles.colorful
3
+ ~~~~~~~~~~~~~~~~~~~~~~~~
4
+
5
+ A colorful style, inspired by CodeRay.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ from pygments.style import Style
12
+ from pygments.token import Keyword, Name, Comment, String, Error, \
13
+ Number, Operator, Generic, Whitespace
14
+
15
+
16
+ __all__ = ['ColorfulStyle']
17
+
18
+
19
+ class ColorfulStyle(Style):
20
+ """
21
+ A colorful style, inspired by CodeRay.
22
+ """
23
+ name = 'colorful'
24
+
25
+ styles = {
26
+ Whitespace: "#bbbbbb",
27
+
28
+ Comment: "#888",
29
+ Comment.Preproc: "#579",
30
+ Comment.Special: "bold #cc0000",
31
+
32
+ Keyword: "bold #080",
33
+ Keyword.Pseudo: "#038",
34
+ Keyword.Type: "#339",
35
+
36
+ Operator: "#333",
37
+ Operator.Word: "bold #000",
38
+
39
+ Name.Builtin: "#007020",
40
+ Name.Function: "bold #06B",
41
+ Name.Class: "bold #B06",
42
+ Name.Namespace: "bold #0e84b5",
43
+ Name.Exception: "bold #F00",
44
+ Name.Variable: "#963",
45
+ Name.Variable.Instance: "#33B",
46
+ Name.Variable.Class: "#369",
47
+ Name.Variable.Global: "bold #d70",
48
+ Name.Constant: "bold #036",
49
+ Name.Label: "bold #970",
50
+ Name.Entity: "bold #800",
51
+ Name.Attribute: "#00C",
52
+ Name.Tag: "#070",
53
+ Name.Decorator: "bold #555",
54
+
55
+ String: "bg:#fff0f0",
56
+ String.Char: "#04D bg:",
57
+ String.Doc: "#D42 bg:",
58
+ String.Interpol: "bg:#eee",
59
+ String.Escape: "bold #666",
60
+ String.Regex: "bg:#fff0ff #000",
61
+ String.Symbol: "#A60 bg:",
62
+ String.Other: "#D20",
63
+
64
+ Number: "bold #60E",
65
+ Number.Integer: "bold #00D",
66
+ Number.Float: "bold #60E",
67
+ Number.Hex: "bold #058",
68
+ Number.Oct: "bold #40E",
69
+
70
+ Generic.Heading: "bold #000080",
71
+ Generic.Subheading: "bold #800080",
72
+ Generic.Deleted: "#A00000",
73
+ Generic.Inserted: "#00A000",
74
+ Generic.Error: "#FF0000",
75
+ Generic.Emph: "italic",
76
+ Generic.Strong: "bold",
77
+ Generic.EmphStrong: "bold italic",
78
+ Generic.Prompt: "bold #c65d09",
79
+ Generic.Output: "#888",
80
+ Generic.Traceback: "#04D",
81
+
82
+ Error: "#F00 bg:#FAA"
83
+ }
lib/python3.12/site-packages/pygments/styles/dracula.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.styles.dracula
3
+ ~~~~~~~~~~~~~~~~~~~~~~~
4
+
5
+ Pygments version of `Dracula` from https://github.com/dracula/dracula-theme.
6
+
7
+ Based on the Dracula Theme for pygments by Chris Bracco.
8
+ See https://github.com/dracula/pygments/tree/fee9ed5613d1086bc01b9d0a5a0e9867a009f571
9
+
10
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
11
+ :license: BSD, see LICENSE for details.
12
+ """
13
+
14
+ from pygments.style import Style
15
+ from pygments.token import Keyword, Name, Comment, String, Error, Literal, \
16
+ Number, Operator, Other, Punctuation, Text, Generic, Whitespace
17
+
18
+
19
+ __all__ = ['DraculaStyle']
20
+
21
+ background = "#282a36"
22
+ foreground = "#f8f8f2"
23
+ selection = "#44475a"
24
+ comment = "#6272a4"
25
+ cyan = "#8be9fd"
26
+ green = "#50fa7b"
27
+ orange = "#ffb86c"
28
+ pink = "#ff79c6"
29
+ purple = "#bd93f9"
30
+ red = "#ff5555"
31
+ yellow = "#f1fa8c"
32
+
33
+ deletion = "#8b080b"
34
+
35
+ class DraculaStyle(Style):
36
+ name = 'dracula'
37
+
38
+ background_color = background
39
+ highlight_color = selection
40
+ line_number_color = yellow
41
+ line_number_background_color = selection
42
+ line_number_special_color = green
43
+ line_number_special_background_color = comment
44
+
45
+ styles = {
46
+ Whitespace: foreground,
47
+
48
+ Comment: comment,
49
+ Comment.Preproc: pink,
50
+
51
+ Generic: foreground,
52
+ Generic.Deleted: deletion,
53
+ Generic.Emph: "underline",
54
+ Generic.Heading: "bold",
55
+ Generic.Inserted: "bold",
56
+ Generic.Output: selection,
57
+ Generic.EmphStrong: "underline",
58
+ Generic.Subheading: "bold",
59
+
60
+ Error: foreground,
61
+
62
+ Keyword: pink,
63
+ Keyword.Constant: pink,
64
+ Keyword.Declaration: cyan + " italic",
65
+ Keyword.Type: cyan,
66
+
67
+ Literal: foreground,
68
+
69
+ Name: foreground,
70
+ Name.Attribute: green,
71
+ Name.Builtin: cyan + " italic",
72
+ Name.Builtin.Pseudo: foreground,
73
+ Name.Class: green,
74
+ Name.Function: green,
75
+ Name.Label: cyan + " italic",
76
+ Name.Tag: pink,
77
+ Name.Variable: cyan + " italic",
78
+
79
+ Number: orange,
80
+
81
+ Operator: pink,
82
+
83
+ Other: foreground,
84
+
85
+ Punctuation: foreground,
86
+
87
+ String: purple,
88
+
89
+ Text: foreground,
90
+ }
lib/python3.12/site-packages/pygments/styles/friendly.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.styles.friendly
3
+ ~~~~~~~~~~~~~~~~~~~~~~~~
4
+
5
+ A modern style based on the VIM pyte theme.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ from pygments.style import Style
12
+ from pygments.token import Keyword, Name, Comment, String, Error, \
13
+ Number, Operator, Generic, Whitespace
14
+
15
+
16
+ __all__ = ['FriendlyStyle']
17
+
18
+
19
+ class FriendlyStyle(Style):
20
+ """
21
+ A modern style based on the VIM pyte theme.
22
+ """
23
+ name = 'friendly'
24
+
25
+ background_color = "#f0f0f0"
26
+ line_number_color = "#666666"
27
+
28
+ styles = {
29
+ Whitespace: "#bbbbbb",
30
+ Comment: "italic #60a0b0",
31
+ Comment.Preproc: "noitalic #007020",
32
+ Comment.Special: "noitalic bg:#fff0f0",
33
+
34
+ Keyword: "bold #007020",
35
+ Keyword.Pseudo: "nobold",
36
+ Keyword.Type: "nobold #902000",
37
+
38
+ Operator: "#666666",
39
+ Operator.Word: "bold #007020",
40
+
41
+ Name.Builtin: "#007020",
42
+ Name.Function: "#06287e",
43
+ Name.Class: "bold #0e84b5",
44
+ Name.Namespace: "bold #0e84b5",
45
+ Name.Exception: "#007020",
46
+ Name.Variable: "#bb60d5",
47
+ Name.Constant: "#60add5",
48
+ Name.Label: "bold #002070",
49
+ Name.Entity: "bold #d55537",
50
+ Name.Attribute: "#4070a0",
51
+ Name.Tag: "bold #062873",
52
+ Name.Decorator: "bold #555555",
53
+
54
+ String: "#4070a0",
55
+ String.Doc: "italic",
56
+ String.Interpol: "italic #70a0d0",
57
+ String.Escape: "bold #4070a0",
58
+ String.Regex: "#235388",
59
+ String.Symbol: "#517918",
60
+ String.Other: "#c65d09",
61
+ Number: "#40a070",
62
+
63
+ Generic.Heading: "bold #000080",
64
+ Generic.Subheading: "bold #800080",
65
+ Generic.Deleted: "#A00000",
66
+ Generic.Inserted: "#00A000",
67
+ Generic.Error: "#FF0000",
68
+ Generic.Emph: "italic",
69
+ Generic.Strong: "bold",
70
+ Generic.EmphStrong: "bold italic",
71
+ Generic.Prompt: "bold #c65d09",
72
+ Generic.Output: "#888",
73
+ Generic.Traceback: "#04D",
74
+
75
+ Error: "border:#FF0000"
76
+ }
lib/python3.12/site-packages/pygments/styles/igor.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.styles.igor
3
+ ~~~~~~~~~~~~~~~~~~~~
4
+
5
+ Igor Pro default style.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ from pygments.style import Style
12
+ from pygments.token import Keyword, Name, Comment, String
13
+
14
+
15
+ __all__ = ['IgorStyle']
16
+
17
+
18
+ class IgorStyle(Style):
19
+ """
20
+ Pygments version of the official colors for Igor Pro procedures.
21
+ """
22
+
23
+ name = 'igor'
24
+
25
+ styles = {
26
+ Comment: 'italic #FF0000',
27
+ Keyword: '#0000FF',
28
+ Name.Function: '#C34E00',
29
+ Name.Decorator: '#CC00A3',
30
+ Name.Class: '#007575',
31
+ String: '#009C00'
32
+ }
lib/python3.12/site-packages/pygments/styles/inkpot.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.styles.inkpot
3
+ ~~~~~~~~~~~~~~~~~~~~~~
4
+
5
+ A highlighting style for Pygments, inspired by the Inkpot theme for VIM.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ from pygments.style import Style
12
+ from pygments.token import Text, Other, Keyword, Name, Comment, String, \
13
+ Error, Number, Operator, Generic, Whitespace, Punctuation
14
+
15
+
16
+ __all__ = ['InkPotStyle']
17
+
18
+
19
+ class InkPotStyle(Style):
20
+ name = 'inkpot'
21
+
22
+ background_color = "#1e1e27"
23
+
24
+ styles = {
25
+ Text: "#cfbfad",
26
+ Other: "#cfbfad",
27
+ Whitespace: "#434357",
28
+ Comment: "#cd8b00",
29
+ Comment.Preproc: "#409090",
30
+ Comment.PreprocFile: "bg:#404040 #ffcd8b",
31
+ Comment.Special: "#808bed",
32
+
33
+ Keyword: "#808bed",
34
+ Keyword.Pseudo: "nobold",
35
+ Keyword.Type: "#ff8bff",
36
+
37
+ Operator: "#666666",
38
+
39
+ Punctuation: "#cfbfad",
40
+
41
+ Name: "#cfbfad",
42
+ Name.Attribute: "#cfbfad",
43
+ Name.Builtin.Pseudo: '#ffff00',
44
+ Name.Builtin: "#808bed",
45
+ Name.Class: "#ff8bff",
46
+ Name.Constant: "#409090",
47
+ Name.Decorator: "#409090",
48
+ Name.Exception: "#ff0000",
49
+ Name.Function: "#c080d0",
50
+ Name.Label: "#808bed",
51
+ Name.Namespace: "#ff0000",
52
+ Name.Variable: "#cfbfad",
53
+
54
+ String: "bg:#404040 #ffcd8b",
55
+ String.Doc: "#808bed",
56
+
57
+ Number: "#f0ad6d",
58
+
59
+ Generic.Heading: "bold #000080",
60
+ Generic.Subheading: "bold #800080",
61
+ Generic.Deleted: "#A00000",
62
+ Generic.Inserted: "#00A000",
63
+ Generic.Error: "#FF0000",
64
+ Generic.Emph: "italic",
65
+ Generic.Strong: "bold",
66
+ Generic.EmphStrong: "bold italic",
67
+ Generic.Prompt: "bold #000080",
68
+ Generic.Output: "#888",
69
+ Generic.Traceback: "#04D",
70
+
71
+ Error: "bg:#6e2e2e #ffffff"
72
+ }
lib/python3.12/site-packages/pygments/styles/lilypond.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.styles.lilypond
3
+ ~~~~~~~~~~~~~~~~~~~~~~~~
4
+
5
+ LilyPond-specific style.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ from pygments.style import Style
12
+ from pygments.token import Token
13
+
14
+
15
+ __all__ = ['LilyPondStyle']
16
+
17
+
18
+ class LilyPondStyle(Style):
19
+ """
20
+ Style for the LilyPond language.
21
+
22
+ .. versionadded:: 2.11
23
+ """
24
+
25
+ name = 'lilypond'
26
+
27
+ # Don't show it in the gallery, it's intended for LilyPond
28
+ # input only and doesn't show good output on Python code.
29
+ web_style_gallery_exclude = True
30
+
31
+ styles = {
32
+ Token.Text: "",
33
+ Token.Keyword: "bold",
34
+ Token.Comment: "italic #A3AAB2",
35
+ Token.String: "#AB0909",
36
+ Token.String.Escape: "#C46C6C",
37
+ Token.String.Symbol: "noinherit",
38
+ Token.Pitch: "", #"#911520",
39
+ Token.Number: "#976806", # includes durations
40
+ # A bare 11 is not distinguishable from a number, so we highlight
41
+ # the same.
42
+ Token.ChordModifier: "#976806",
43
+ Token.Name.Lvalue: "#08547A",
44
+ Token.Name.BackslashReference: "#08547A",
45
+ Token.Name.Builtin.MusicCommand: "bold #08547A",
46
+ Token.Name.Builtin.PaperVariable: "bold #6C5A05",
47
+ Token.Name.Builtin.HeaderVariable: "bold #6C5A05",
48
+ Token.Name.Builtin.MusicFunction: "bold #08547A",
49
+ Token.Name.Builtin.Clef: "bold #08547A",
50
+ Token.Name.Builtin.Scale: "bold #08547A",
51
+ Token.Name.Builtin.RepeatType: "#08547A",
52
+ Token.Name.Builtin.Dynamic: "#68175A",
53
+ Token.Name.Builtin.Articulation: "#68175A",
54
+ Token.Name.Builtin.SchemeFunction: "bold #A83401",
55
+ Token.Name.Builtin.SchemeBuiltin: "bold",
56
+ Token.Name.Builtin.MarkupCommand: "bold #831E71",
57
+ Token.Name.Builtin.Context: "bold #038B8B",
58
+ Token.Name.Builtin.ContextProperty: "#038B8B",
59
+ Token.Name.Builtin.Grob: "bold #0C7441",
60
+ Token.Name.Builtin.GrobProperty: "#0C7441",
61
+ Token.Name.Builtin.Translator: "bold #6200A4",
62
+ }
lib/python3.12/site-packages/pygments/styles/murphy.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.styles.murphy
3
+ ~~~~~~~~~~~~~~~~~~~~~~
4
+
5
+ Murphy's style from CodeRay.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ from pygments.style import Style
12
+ from pygments.token import Keyword, Name, Comment, String, Error, \
13
+ Number, Operator, Generic, Whitespace
14
+
15
+
16
+ __all__ = ['MurphyStyle']
17
+
18
+
19
+ class MurphyStyle(Style):
20
+ """
21
+ Murphy's style from CodeRay.
22
+ """
23
+ name = 'murphy'
24
+
25
+ styles = {
26
+ Whitespace: "#bbbbbb",
27
+ Comment: "#666 italic",
28
+ Comment.Preproc: "#579 noitalic",
29
+ Comment.Special: "#c00 bold",
30
+
31
+ Keyword: "bold #289",
32
+ Keyword.Pseudo: "#08f",
33
+ Keyword.Type: "#66f",
34
+
35
+ Operator: "#333",
36
+ Operator.Word: "bold #000",
37
+
38
+ Name.Builtin: "#072",
39
+ Name.Function: "bold #5ed",
40
+ Name.Class: "bold #e9e",
41
+ Name.Namespace: "bold #0e84b5",
42
+ Name.Exception: "bold #F00",
43
+ Name.Variable: "#036",
44
+ Name.Variable.Instance: "#aaf",
45
+ Name.Variable.Class: "#ccf",
46
+ Name.Variable.Global: "#f84",
47
+ Name.Constant: "bold #5ed",
48
+ Name.Label: "bold #970",
49
+ Name.Entity: "#800",
50
+ Name.Attribute: "#007",
51
+ Name.Tag: "#070",
52
+ Name.Decorator: "bold #555",
53
+
54
+ String: "bg:#e0e0ff",
55
+ String.Char: "#88F bg:",
56
+ String.Doc: "#D42 bg:",
57
+ String.Interpol: "bg:#eee",
58
+ String.Escape: "bold #666",
59
+ String.Regex: "bg:#e0e0ff #000",
60
+ String.Symbol: "#fc8 bg:",
61
+ String.Other: "#f88",
62
+
63
+ Number: "bold #60E",
64
+ Number.Integer: "bold #66f",
65
+ Number.Float: "bold #60E",
66
+ Number.Hex: "bold #058",
67
+ Number.Oct: "bold #40E",
68
+
69
+ Generic.Heading: "bold #000080",
70
+ Generic.Subheading: "bold #800080",
71
+ Generic.Deleted: "#A00000",
72
+ Generic.Inserted: "#00A000",
73
+ Generic.Error: "#FF0000",
74
+ Generic.Emph: "italic",
75
+ Generic.Strong: "bold",
76
+ Generic.EmphStrong: "bold italic",
77
+ Generic.Prompt: "bold #c65d09",
78
+ Generic.Output: "#888",
79
+ Generic.Traceback: "#04D",
80
+
81
+ Error: "#F00 bg:#FAA"
82
+ }
lib/python3.12/site-packages/pygments/token.py ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.token
3
+ ~~~~~~~~~~~~~~
4
+
5
+ Basic token types and the standard tokens.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+
12
+ class _TokenType(tuple):
13
+ parent = None
14
+
15
+ def split(self):
16
+ buf = []
17
+ node = self
18
+ while node is not None:
19
+ buf.append(node)
20
+ node = node.parent
21
+ buf.reverse()
22
+ return buf
23
+
24
+ def __init__(self, *args):
25
+ # no need to call super.__init__
26
+ self.subtypes = set()
27
+
28
+ def __contains__(self, val):
29
+ return self is val or (
30
+ type(val) is self.__class__ and
31
+ val[:len(self)] == self
32
+ )
33
+
34
+ def __getattr__(self, val):
35
+ if not val or not val[0].isupper():
36
+ return tuple.__getattribute__(self, val)
37
+ new = _TokenType(self + (val,))
38
+ setattr(self, val, new)
39
+ self.subtypes.add(new)
40
+ new.parent = self
41
+ return new
42
+
43
+ def __repr__(self):
44
+ return 'Token' + (self and '.' or '') + '.'.join(self)
45
+
46
+ def __copy__(self):
47
+ # These instances are supposed to be singletons
48
+ return self
49
+
50
+ def __deepcopy__(self, memo):
51
+ # These instances are supposed to be singletons
52
+ return self
53
+
54
+
55
+ Token = _TokenType()
56
+
57
+ # Special token types
58
+ Text = Token.Text
59
+ Whitespace = Text.Whitespace
60
+ Escape = Token.Escape
61
+ Error = Token.Error
62
+ # Text that doesn't belong to this lexer (e.g. HTML in PHP)
63
+ Other = Token.Other
64
+
65
+ # Common token types for source code
66
+ Keyword = Token.Keyword
67
+ Name = Token.Name
68
+ Literal = Token.Literal
69
+ String = Literal.String
70
+ Number = Literal.Number
71
+ Punctuation = Token.Punctuation
72
+ Operator = Token.Operator
73
+ Comment = Token.Comment
74
+
75
+ # Generic types for non-source code
76
+ Generic = Token.Generic
77
+
78
+ # String and some others are not direct children of Token.
79
+ # alias them:
80
+ Token.Token = Token
81
+ Token.String = String
82
+ Token.Number = Number
83
+
84
+
85
+ def is_token_subtype(ttype, other):
86
+ """
87
+ Return True if ``ttype`` is a subtype of ``other``.
88
+
89
+ exists for backwards compatibility. use ``ttype in other`` now.
90
+ """
91
+ return ttype in other
92
+
93
+
94
+ def string_to_tokentype(s):
95
+ """
96
+ Convert a string into a token type::
97
+
98
+ >>> string_to_token('String.Double')
99
+ Token.Literal.String.Double
100
+ >>> string_to_token('Token.Literal.Number')
101
+ Token.Literal.Number
102
+ >>> string_to_token('')
103
+ Token
104
+
105
+ Tokens that are already tokens are returned unchanged:
106
+
107
+ >>> string_to_token(String)
108
+ Token.Literal.String
109
+ """
110
+ if isinstance(s, _TokenType):
111
+ return s
112
+ if not s:
113
+ return Token
114
+ node = Token
115
+ for item in s.split('.'):
116
+ node = getattr(node, item)
117
+ return node
118
+
119
+
120
+ # Map standard token types to short names, used in CSS class naming.
121
+ # If you add a new item, please be sure to run this file to perform
122
+ # a consistency check for duplicate values.
123
+ STANDARD_TYPES = {
124
+ Token: '',
125
+
126
+ Text: '',
127
+ Whitespace: 'w',
128
+ Escape: 'esc',
129
+ Error: 'err',
130
+ Other: 'x',
131
+
132
+ Keyword: 'k',
133
+ Keyword.Constant: 'kc',
134
+ Keyword.Declaration: 'kd',
135
+ Keyword.Namespace: 'kn',
136
+ Keyword.Pseudo: 'kp',
137
+ Keyword.Reserved: 'kr',
138
+ Keyword.Type: 'kt',
139
+
140
+ Name: 'n',
141
+ Name.Attribute: 'na',
142
+ Name.Builtin: 'nb',
143
+ Name.Builtin.Pseudo: 'bp',
144
+ Name.Class: 'nc',
145
+ Name.Constant: 'no',
146
+ Name.Decorator: 'nd',
147
+ Name.Entity: 'ni',
148
+ Name.Exception: 'ne',
149
+ Name.Function: 'nf',
150
+ Name.Function.Magic: 'fm',
151
+ Name.Property: 'py',
152
+ Name.Label: 'nl',
153
+ Name.Namespace: 'nn',
154
+ Name.Other: 'nx',
155
+ Name.Tag: 'nt',
156
+ Name.Variable: 'nv',
157
+ Name.Variable.Class: 'vc',
158
+ Name.Variable.Global: 'vg',
159
+ Name.Variable.Instance: 'vi',
160
+ Name.Variable.Magic: 'vm',
161
+
162
+ Literal: 'l',
163
+ Literal.Date: 'ld',
164
+
165
+ String: 's',
166
+ String.Affix: 'sa',
167
+ String.Backtick: 'sb',
168
+ String.Char: 'sc',
169
+ String.Delimiter: 'dl',
170
+ String.Doc: 'sd',
171
+ String.Double: 's2',
172
+ String.Escape: 'se',
173
+ String.Heredoc: 'sh',
174
+ String.Interpol: 'si',
175
+ String.Other: 'sx',
176
+ String.Regex: 'sr',
177
+ String.Single: 's1',
178
+ String.Symbol: 'ss',
179
+
180
+ Number: 'm',
181
+ Number.Bin: 'mb',
182
+ Number.Float: 'mf',
183
+ Number.Hex: 'mh',
184
+ Number.Integer: 'mi',
185
+ Number.Integer.Long: 'il',
186
+ Number.Oct: 'mo',
187
+
188
+ Operator: 'o',
189
+ Operator.Word: 'ow',
190
+
191
+ Punctuation: 'p',
192
+ Punctuation.Marker: 'pm',
193
+
194
+ Comment: 'c',
195
+ Comment.Hashbang: 'ch',
196
+ Comment.Multiline: 'cm',
197
+ Comment.Preproc: 'cp',
198
+ Comment.PreprocFile: 'cpf',
199
+ Comment.Single: 'c1',
200
+ Comment.Special: 'cs',
201
+
202
+ Generic: 'g',
203
+ Generic.Deleted: 'gd',
204
+ Generic.Emph: 'ge',
205
+ Generic.Error: 'gr',
206
+ Generic.Heading: 'gh',
207
+ Generic.Inserted: 'gi',
208
+ Generic.Output: 'go',
209
+ Generic.Prompt: 'gp',
210
+ Generic.Strong: 'gs',
211
+ Generic.Subheading: 'gu',
212
+ Generic.EmphStrong: 'ges',
213
+ Generic.Traceback: 'gt',
214
+ }
lib/python3.12/site-packages/pygments/unistring.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.unistring
3
+ ~~~~~~~~~~~~~~~~~~
4
+
5
+ Strings of all Unicode characters of a certain category.
6
+ Used for matching in Unicode-aware languages. Run to regenerate.
7
+
8
+ Inspired by chartypes_create.py from the MoinMoin project.
9
+
10
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
11
+ :license: BSD, see LICENSE for details.
12
+ """
13
+
14
+ Cc = '\x00-\x1f\x7f-\x9f'
15
+
16
+ Cf = '\xad\u0600-\u0605\u061c\u06dd\u070f\u08e2\u180e\u200b-\u200f\u202a-\u202e\u2060-\u2064\u2066-\u206f\ufeff\ufff9-\ufffb\U000110bd\U000110cd\U0001bca0-\U0001bca3\U0001d173-\U0001d17a\U000e0001\U000e0020-\U000e007f'
17
+
18
+ Cn = '\u0378-\u0379\u0380-\u0383\u038b\u038d\u03a2\u0530\u0557-\u0558\u058b-\u058c\u0590\u05c8-\u05cf\u05eb-\u05ee\u05f5-\u05ff\u061d\u070e\u074b-\u074c\u07b2-\u07bf\u07fb-\u07fc\u082e-\u082f\u083f\u085c-\u085d\u085f\u086b-\u089f\u08b5\u08be-\u08d2\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09c5-\u09c6\u09c9-\u09ca\u09cf-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09ff-\u0a00\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a50\u0a52-\u0a58\u0a5d\u0a5f-\u0a65\u0a77-\u0a80\u0a84\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0acf\u0ad1-\u0adf\u0ae4-\u0ae5\u0af2-\u0af8\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34\u0b3a-\u0b3b\u0b45-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b64-\u0b65\u0b78-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bcf\u0bd1-\u0bd6\u0bd8-\u0be5\u0bfb-\u0bff\u0c0d\u0c11\u0c29\u0c3a-\u0c3c\u0c45\u0c49\u0c4e-\u0c54\u0c57\u0c5b-\u0c5f\u0c64-\u0c65\u0c70-\u0c77\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbb\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce4-\u0ce5\u0cf0\u0cf3-\u0cff\u0d04\u0d0d\u0d11\u0d45\u0d49\u0d50-\u0d53\u0d64-\u0d65\u0d80-\u0d81\u0d84\u0d97-\u0d99\u0db2\u0dbc\u0dbe-\u0dbf\u0dc7-\u0dc9\u0dcb-\u0dce\u0dd5\u0dd7\u0de0-\u0de5\u0df0-\u0df1\u0df5-\u0e00\u0e3b-\u0e3e\u0e5c-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0edb\u0ee0-\u0eff\u0f48\u0f6d-\u0f70\u0f98\u0fbd\u0fcd\u0fdb-\u0fff\u10c6\u10c8-\u10cc\u10ce-\u10cf\u1249\u124e-\u124f\u1257\u1259\u125e-\u125f\u1289\u128e-\u128f\u12b1\u12b6-\u12b7\u12bf\u12c1\u12c6-\u12c7\u12d7\u1311\u1316-\u1317\u135b-\u135c\u137d-\u137f\u139a-\u139f\u13f6-\u13f7\u13fe-\u13ff\u169d-\u169f\u16f9-\u16ff\u170d\u1715-\u171f\u1737-\u173f\u1754-\u175f\u176d\u1771\u1774-\u177f\u17de-\u17df\u17ea-\u17ef\u17fa-\u17ff\u180f\u181a-\u181f\u1879-\u187f\u18ab-\u18af\u18f6-\u18ff\u191f\u192c-\u192f\u193c-\u193f\u1941-\u1943\u196e-\u196f\u1975-\u197f\u19ac-\u19af\u19ca-\u19cf\u19db-\u19dd\u1a1c-\u1a1d\u1a5f\u1a7d-\u1a7e\u1a8a-\u1a8f\u1a9a-\u1a9f\u1aae-\u1aaf\u1abf-\u1aff\u1b4c-\u1b4f\u1b7d-\u1b7f\u1bf4-\u1bfb\u1c38-\u1c3a\u1c4a-\u1c4c\u1c89-\u1c8f\u1cbb-\u1cbc\u1cc8-\u1ccf\u1cfa-\u1cff\u1dfa\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fc5\u1fd4-\u1fd5\u1fdc\u1ff0-\u1ff1\u1ff5\u1fff\u2065\u2072-\u2073\u208f\u209d-\u209f\u20c0-\u20cf\u20f1-\u20ff\u218c-\u218f\u2427-\u243f\u244b-\u245f\u2b74-\u2b75\u2b96-\u2b97\u2bc9\u2bff\u2c2f\u2c5f\u2cf4-\u2cf8\u2d26\u2d28-\u2d2c\u2d2e-\u2d2f\u2d68-\u2d6e\u2d71-\u2d7e\u2d97-\u2d9f\u2da7\u2daf\u2db7\u2dbf\u2dc7\u2dcf\u2dd7\u2ddf\u2e4f-\u2e7f\u2e9a\u2ef4-\u2eff\u2fd6-\u2fef\u2ffc-\u2fff\u3040\u3097-\u3098\u3100-\u3104\u3130\u318f\u31bb-\u31bf\u31e4-\u31ef\u321f\u32ff\u4db6-\u4dbf\u9ff0-\u9fff\ua48d-\ua48f\ua4c7-\ua4cf\ua62c-\ua63f\ua6f8-\ua6ff\ua7ba-\ua7f6\ua82c-\ua82f\ua83a-\ua83f\ua878-\ua87f\ua8c6-\ua8cd\ua8da-\ua8df\ua954-\ua95e\ua97d-\ua97f\ua9ce\ua9da-\ua9dd\ua9ff\uaa37-\uaa3f\uaa4e-\uaa4f\uaa5a-\uaa5b\uaac3-\uaada\uaaf7-\uab00\uab07-\uab08\uab0f-\uab10\uab17-\uab1f\uab27\uab2f\uab66-\uab6f\uabee-\uabef\uabfa-\uabff\ud7a4-\ud7af\ud7c7-\ud7ca\ud7fc-\ud7ff\ufa6e-\ufa6f\ufada-\ufaff\ufb07-\ufb12\ufb18-\ufb1c\ufb37\ufb3d\ufb3f\ufb42\ufb45\ufbc2-\ufbd2\ufd40-\ufd4f\ufd90-\ufd91\ufdc8-\ufdef\ufdfe-\ufdff\ufe1a-\ufe1f\ufe53\ufe67\ufe6c-\ufe6f\ufe75\ufefd-\ufefe\uff00\uffbf-\uffc1\uffc8-\uffc9\uffd0-\uffd1\uffd8-\uffd9\uffdd-\uffdf\uffe7\uffef-\ufff8\ufffe-\uffff\U0001000c\U00010027\U0001003b\U0001003e\U0001004e-\U0001004f\U0001005e-\U0001007f\U000100fb-\U000100ff\U00010103-\U00010106\U00010134-\U00010136\U0001018f\U0001019c-\U0001019f\U000101a1-\U000101cf\U000101fe-\U0001027f\U0001029d-\U0001029f\U000102d1-\U000102df\U000102fc-\U000102ff\U00010324-\U0001032c\U0001034b-\U0001034f\U0001037b-\U0001037f\U0001039e\U000103c4-\U000103c7\U000103d6-\U000103ff\U0001049e-\U0001049f\U000104aa-\U000104af\U000104d4-\U000104d7\U000104fc-\U000104ff\U00010528-\U0001052f\U00010564-\U0001056e\U00010570-\U000105ff\U00010737-\U0001073f\U00010756-\U0001075f\U00010768-\U000107ff\U00010806-\U00010807\U00010809\U00010836\U00010839-\U0001083b\U0001083d-\U0001083e\U00010856\U0001089f-\U000108a6\U000108b0-\U000108df\U000108f3\U000108f6-\U000108fa\U0001091c-\U0001091e\U0001093a-\U0001093e\U00010940-\U0001097f\U000109b8-\U000109bb\U000109d0-\U000109d1\U00010a04\U00010a07-\U00010a0b\U00010a14\U00010a18\U00010a36-\U00010a37\U00010a3b-\U00010a3e\U00010a49-\U00010a4f\U00010a59-\U00010a5f\U00010aa0-\U00010abf\U00010ae7-\U00010aea\U00010af7-\U00010aff\U00010b36-\U00010b38\U00010b56-\U00010b57\U00010b73-\U00010b77\U00010b92-\U00010b98\U00010b9d-\U00010ba8\U00010bb0-\U00010bff\U00010c49-\U00010c7f\U00010cb3-\U00010cbf\U00010cf3-\U00010cf9\U00010d28-\U00010d2f\U00010d3a-\U00010e5f\U00010e7f-\U00010eff\U00010f28-\U00010f2f\U00010f5a-\U00010fff\U0001104e-\U00011051\U00011070-\U0001107e\U000110c2-\U000110cc\U000110ce-\U000110cf\U000110e9-\U000110ef\U000110fa-\U000110ff\U00011135\U00011147-\U0001114f\U00011177-\U0001117f\U000111ce-\U000111cf\U000111e0\U000111f5-\U000111ff\U00011212\U0001123f-\U0001127f\U00011287\U00011289\U0001128e\U0001129e\U000112aa-\U000112af\U000112eb-\U000112ef\U000112fa-\U000112ff\U00011304\U0001130d-\U0001130e\U00011311-\U00011312\U00011329\U00011331\U00011334\U0001133a\U00011345-\U00011346\U00011349-\U0001134a\U0001134e-\U0001134f\U00011351-\U00011356\U00011358-\U0001135c\U00011364-\U00011365\U0001136d-\U0001136f\U00011375-\U000113ff\U0001145a\U0001145c\U0001145f-\U0001147f\U000114c8-\U000114cf\U000114da-\U0001157f\U000115b6-\U000115b7\U000115de-\U000115ff\U00011645-\U0001164f\U0001165a-\U0001165f\U0001166d-\U0001167f\U000116b8-\U000116bf\U000116ca-\U000116ff\U0001171b-\U0001171c\U0001172c-\U0001172f\U00011740-\U000117ff\U0001183c-\U0001189f\U000118f3-\U000118fe\U00011900-\U000119ff\U00011a48-\U00011a4f\U00011a84-\U00011a85\U00011aa3-\U00011abf\U00011af9-\U00011bff\U00011c09\U00011c37\U00011c46-\U00011c4f\U00011c6d-\U00011c6f\U00011c90-\U00011c91\U00011ca8\U00011cb7-\U00011cff\U00011d07\U00011d0a\U00011d37-\U00011d39\U00011d3b\U00011d3e\U00011d48-\U00011d4f\U00011d5a-\U00011d5f\U00011d66\U00011d69\U00011d8f\U00011d92\U00011d99-\U00011d9f\U00011daa-\U00011edf\U00011ef9-\U00011fff\U0001239a-\U000123ff\U0001246f\U00012475-\U0001247f\U00012544-\U00012fff\U0001342f-\U000143ff\U00014647-\U000167ff\U00016a39-\U00016a3f\U00016a5f\U00016a6a-\U00016a6d\U00016a70-\U00016acf\U00016aee-\U00016aef\U00016af6-\U00016aff\U00016b46-\U00016b4f\U00016b5a\U00016b62\U00016b78-\U00016b7c\U00016b90-\U00016e3f\U00016e9b-\U00016eff\U00016f45-\U00016f4f\U00016f7f-\U00016f8e\U00016fa0-\U00016fdf\U00016fe2-\U00016fff\U000187f2-\U000187ff\U00018af3-\U0001afff\U0001b11f-\U0001b16f\U0001b2fc-\U0001bbff\U0001bc6b-\U0001bc6f\U0001bc7d-\U0001bc7f\U0001bc89-\U0001bc8f\U0001bc9a-\U0001bc9b\U0001bca4-\U0001cfff\U0001d0f6-\U0001d0ff\U0001d127-\U0001d128\U0001d1e9-\U0001d1ff\U0001d246-\U0001d2df\U0001d2f4-\U0001d2ff\U0001d357-\U0001d35f\U0001d379-\U0001d3ff\U0001d455\U0001d49d\U0001d4a0-\U0001d4a1\U0001d4a3-\U0001d4a4\U0001d4a7-\U0001d4a8\U0001d4ad\U0001d4ba\U0001d4bc\U0001d4c4\U0001d506\U0001d50b-\U0001d50c\U0001d515\U0001d51d\U0001d53a\U0001d53f\U0001d545\U0001d547-\U0001d549\U0001d551\U0001d6a6-\U0001d6a7\U0001d7cc-\U0001d7cd\U0001da8c-\U0001da9a\U0001daa0\U0001dab0-\U0001dfff\U0001e007\U0001e019-\U0001e01a\U0001e022\U0001e025\U0001e02b-\U0001e7ff\U0001e8c5-\U0001e8c6\U0001e8d7-\U0001e8ff\U0001e94b-\U0001e94f\U0001e95a-\U0001e95d\U0001e960-\U0001ec70\U0001ecb5-\U0001edff\U0001ee04\U0001ee20\U0001ee23\U0001ee25-\U0001ee26\U0001ee28\U0001ee33\U0001ee38\U0001ee3a\U0001ee3c-\U0001ee41\U0001ee43-\U0001ee46\U0001ee48\U0001ee4a\U0001ee4c\U0001ee50\U0001ee53\U0001ee55-\U0001ee56\U0001ee58\U0001ee5a\U0001ee5c\U0001ee5e\U0001ee60\U0001ee63\U0001ee65-\U0001ee66\U0001ee6b\U0001ee73\U0001ee78\U0001ee7d\U0001ee7f\U0001ee8a\U0001ee9c-\U0001eea0\U0001eea4\U0001eeaa\U0001eebc-\U0001eeef\U0001eef2-\U0001efff\U0001f02c-\U0001f02f\U0001f094-\U0001f09f\U0001f0af-\U0001f0b0\U0001f0c0\U0001f0d0\U0001f0f6-\U0001f0ff\U0001f10d-\U0001f10f\U0001f16c-\U0001f16f\U0001f1ad-\U0001f1e5\U0001f203-\U0001f20f\U0001f23c-\U0001f23f\U0001f249-\U0001f24f\U0001f252-\U0001f25f\U0001f266-\U0001f2ff\U0001f6d5-\U0001f6df\U0001f6ed-\U0001f6ef\U0001f6fa-\U0001f6ff\U0001f774-\U0001f77f\U0001f7d9-\U0001f7ff\U0001f80c-\U0001f80f\U0001f848-\U0001f84f\U0001f85a-\U0001f85f\U0001f888-\U0001f88f\U0001f8ae-\U0001f8ff\U0001f90c-\U0001f90f\U0001f93f\U0001f971-\U0001f972\U0001f977-\U0001f979\U0001f97b\U0001f9a3-\U0001f9af\U0001f9ba-\U0001f9bf\U0001f9c3-\U0001f9cf\U0001fa00-\U0001fa5f\U0001fa6e-\U0001ffff\U0002a6d7-\U0002a6ff\U0002b735-\U0002b73f\U0002b81e-\U0002b81f\U0002cea2-\U0002ceaf\U0002ebe1-\U0002f7ff\U0002fa1e-\U000e0000\U000e0002-\U000e001f\U000e0080-\U000e00ff\U000e01f0-\U000effff\U000ffffe-\U000fffff\U0010fffe-\U0010ffff'
19
+
20
+ Co = '\ue000-\uf8ff\U000f0000-\U000ffffd\U00100000-\U0010fffd'
21
+
22
+ Cs = '\ud800-\udbff\\\udc00\udc01-\udfff'
23
+
24
+ Ll = 'a-z\xb5\xdf-\xf6\xf8-\xff\u0101\u0103\u0105\u0107\u0109\u010b\u010d\u010f\u0111\u0113\u0115\u0117\u0119\u011b\u011d\u011f\u0121\u0123\u0125\u0127\u0129\u012b\u012d\u012f\u0131\u0133\u0135\u0137-\u0138\u013a\u013c\u013e\u0140\u0142\u0144\u0146\u0148-\u0149\u014b\u014d\u014f\u0151\u0153\u0155\u0157\u0159\u015b\u015d\u015f\u0161\u0163\u0165\u0167\u0169\u016b\u016d\u016f\u0171\u0173\u0175\u0177\u017a\u017c\u017e-\u0180\u0183\u0185\u0188\u018c-\u018d\u0192\u0195\u0199-\u019b\u019e\u01a1\u01a3\u01a5\u01a8\u01aa-\u01ab\u01ad\u01b0\u01b4\u01b6\u01b9-\u01ba\u01bd-\u01bf\u01c6\u01c9\u01cc\u01ce\u01d0\u01d2\u01d4\u01d6\u01d8\u01da\u01dc-\u01dd\u01df\u01e1\u01e3\u01e5\u01e7\u01e9\u01eb\u01ed\u01ef-\u01f0\u01f3\u01f5\u01f9\u01fb\u01fd\u01ff\u0201\u0203\u0205\u0207\u0209\u020b\u020d\u020f\u0211\u0213\u0215\u0217\u0219\u021b\u021d\u021f\u0221\u0223\u0225\u0227\u0229\u022b\u022d\u022f\u0231\u0233-\u0239\u023c\u023f-\u0240\u0242\u0247\u0249\u024b\u024d\u024f-\u0293\u0295-\u02af\u0371\u0373\u0377\u037b-\u037d\u0390\u03ac-\u03ce\u03d0-\u03d1\u03d5-\u03d7\u03d9\u03db\u03dd\u03df\u03e1\u03e3\u03e5\u03e7\u03e9\u03eb\u03ed\u03ef-\u03f3\u03f5\u03f8\u03fb-\u03fc\u0430-\u045f\u0461\u0463\u0465\u0467\u0469\u046b\u046d\u046f\u0471\u0473\u0475\u0477\u0479\u047b\u047d\u047f\u0481\u048b\u048d\u048f\u0491\u0493\u0495\u0497\u0499\u049b\u049d\u049f\u04a1\u04a3\u04a5\u04a7\u04a9\u04ab\u04ad\u04af\u04b1\u04b3\u04b5\u04b7\u04b9\u04bb\u04bd\u04bf\u04c2\u04c4\u04c6\u04c8\u04ca\u04cc\u04ce-\u04cf\u04d1\u04d3\u04d5\u04d7\u04d9\u04db\u04dd\u04df\u04e1\u04e3\u04e5\u04e7\u04e9\u04eb\u04ed\u04ef\u04f1\u04f3\u04f5\u04f7\u04f9\u04fb\u04fd\u04ff\u0501\u0503\u0505\u0507\u0509\u050b\u050d\u050f\u0511\u0513\u0515\u0517\u0519\u051b\u051d\u051f\u0521\u0523\u0525\u0527\u0529\u052b\u052d\u052f\u0560-\u0588\u10d0-\u10fa\u10fd-\u10ff\u13f8-\u13fd\u1c80-\u1c88\u1d00-\u1d2b\u1d6b-\u1d77\u1d79-\u1d9a\u1e01\u1e03\u1e05\u1e07\u1e09\u1e0b\u1e0d\u1e0f\u1e11\u1e13\u1e15\u1e17\u1e19\u1e1b\u1e1d\u1e1f\u1e21\u1e23\u1e25\u1e27\u1e29\u1e2b\u1e2d\u1e2f\u1e31\u1e33\u1e35\u1e37\u1e39\u1e3b\u1e3d\u1e3f\u1e41\u1e43\u1e45\u1e47\u1e49\u1e4b\u1e4d\u1e4f\u1e51\u1e53\u1e55\u1e57\u1e59\u1e5b\u1e5d\u1e5f\u1e61\u1e63\u1e65\u1e67\u1e69\u1e6b\u1e6d\u1e6f\u1e71\u1e73\u1e75\u1e77\u1e79\u1e7b\u1e7d\u1e7f\u1e81\u1e83\u1e85\u1e87\u1e89\u1e8b\u1e8d\u1e8f\u1e91\u1e93\u1e95-\u1e9d\u1e9f\u1ea1\u1ea3\u1ea5\u1ea7\u1ea9\u1eab\u1ead\u1eaf\u1eb1\u1eb3\u1eb5\u1eb7\u1eb9\u1ebb\u1ebd\u1ebf\u1ec1\u1ec3\u1ec5\u1ec7\u1ec9\u1ecb\u1ecd\u1ecf\u1ed1\u1ed3\u1ed5\u1ed7\u1ed9\u1edb\u1edd\u1edf\u1ee1\u1ee3\u1ee5\u1ee7\u1ee9\u1eeb\u1eed\u1eef\u1ef1\u1ef3\u1ef5\u1ef7\u1ef9\u1efb\u1efd\u1eff-\u1f07\u1f10-\u1f15\u1f20-\u1f27\u1f30-\u1f37\u1f40-\u1f45\u1f50-\u1f57\u1f60-\u1f67\u1f70-\u1f7d\u1f80-\u1f87\u1f90-\u1f97\u1fa0-\u1fa7\u1fb0-\u1fb4\u1fb6-\u1fb7\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fc7\u1fd0-\u1fd3\u1fd6-\u1fd7\u1fe0-\u1fe7\u1ff2-\u1ff4\u1ff6-\u1ff7\u210a\u210e-\u210f\u2113\u212f\u2134\u2139\u213c-\u213d\u2146-\u2149\u214e\u2184\u2c30-\u2c5e\u2c61\u2c65-\u2c66\u2c68\u2c6a\u2c6c\u2c71\u2c73-\u2c74\u2c76-\u2c7b\u2c81\u2c83\u2c85\u2c87\u2c89\u2c8b\u2c8d\u2c8f\u2c91\u2c93\u2c95\u2c97\u2c99\u2c9b\u2c9d\u2c9f\u2ca1\u2ca3\u2ca5\u2ca7\u2ca9\u2cab\u2cad\u2caf\u2cb1\u2cb3\u2cb5\u2cb7\u2cb9\u2cbb\u2cbd\u2cbf\u2cc1\u2cc3\u2cc5\u2cc7\u2cc9\u2ccb\u2ccd\u2ccf\u2cd1\u2cd3\u2cd5\u2cd7\u2cd9\u2cdb\u2cdd\u2cdf\u2ce1\u2ce3-\u2ce4\u2cec\u2cee\u2cf3\u2d00-\u2d25\u2d27\u2d2d\ua641\ua643\ua645\ua647\ua649\ua64b\ua64d\ua64f\ua651\ua653\ua655\ua657\ua659\ua65b\ua65d\ua65f\ua661\ua663\ua665\ua667\ua669\ua66b\ua66d\ua681\ua683\ua685\ua687\ua689\ua68b\ua68d\ua68f\ua691\ua693\ua695\ua697\ua699\ua69b\ua723\ua725\ua727\ua729\ua72b\ua72d\ua72f-\ua731\ua733\ua735\ua737\ua739\ua73b\ua73d\ua73f\ua741\ua743\ua745\ua747\ua749\ua74b\ua74d\ua74f\ua751\ua753\ua755\ua757\ua759\ua75b\ua75d\ua75f\ua761\ua763\ua765\ua767\ua769\ua76b\ua76d\ua76f\ua771-\ua778\ua77a\ua77c\ua77f\ua781\ua783\ua785\ua787\ua78c\ua78e\ua791\ua793-\ua795\ua797\ua799\ua79b\ua79d\ua79f\ua7a1\ua7a3\ua7a5\ua7a7\ua7a9\ua7af\ua7b5\ua7b7\ua7b9\ua7fa\uab30-\uab5a\uab60-\uab65\uab70-\uabbf\ufb00-\ufb06\ufb13-\ufb17\uff41-\uff5a\U00010428-\U0001044f\U000104d8-\U000104fb\U00010cc0-\U00010cf2\U000118c0-\U000118df\U00016e60-\U00016e7f\U0001d41a-\U0001d433\U0001d44e-\U0001d454\U0001d456-\U0001d467\U0001d482-\U0001d49b\U0001d4b6-\U0001d4b9\U0001d4bb\U0001d4bd-\U0001d4c3\U0001d4c5-\U0001d4cf\U0001d4ea-\U0001d503\U0001d51e-\U0001d537\U0001d552-\U0001d56b\U0001d586-\U0001d59f\U0001d5ba-\U0001d5d3\U0001d5ee-\U0001d607\U0001d622-\U0001d63b\U0001d656-\U0001d66f\U0001d68a-\U0001d6a5\U0001d6c2-\U0001d6da\U0001d6dc-\U0001d6e1\U0001d6fc-\U0001d714\U0001d716-\U0001d71b\U0001d736-\U0001d74e\U0001d750-\U0001d755\U0001d770-\U0001d788\U0001d78a-\U0001d78f\U0001d7aa-\U0001d7c2\U0001d7c4-\U0001d7c9\U0001d7cb\U0001e922-\U0001e943'
25
+
26
+ Lm = '\u02b0-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0374\u037a\u0559\u0640\u06e5-\u06e6\u07f4-\u07f5\u07fa\u081a\u0824\u0828\u0971\u0e46\u0ec6\u10fc\u17d7\u1843\u1aa7\u1c78-\u1c7d\u1d2c-\u1d6a\u1d78\u1d9b-\u1dbf\u2071\u207f\u2090-\u209c\u2c7c-\u2c7d\u2d6f\u2e2f\u3005\u3031-\u3035\u303b\u309d-\u309e\u30fc-\u30fe\ua015\ua4f8-\ua4fd\ua60c\ua67f\ua69c-\ua69d\ua717-\ua71f\ua770\ua788\ua7f8-\ua7f9\ua9cf\ua9e6\uaa70\uaadd\uaaf3-\uaaf4\uab5c-\uab5f\uff70\uff9e-\uff9f\U00016b40-\U00016b43\U00016f93-\U00016f9f\U00016fe0-\U00016fe1'
27
+
28
+ Lo = '\xaa\xba\u01bb\u01c0-\u01c3\u0294\u05d0-\u05ea\u05ef-\u05f2\u0620-\u063f\u0641-\u064a\u066e-\u066f\u0671-\u06d3\u06d5\u06ee-\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u0800-\u0815\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0972-\u0980\u0985-\u098c\u098f-\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc-\u09dd\u09df-\u09e1\u09f0-\u09f1\u09fc\u0a05-\u0a0a\u0a0f-\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32-\u0a33\u0a35-\u0a36\u0a38-\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2-\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0-\u0ae1\u0af9\u0b05-\u0b0c\u0b0f-\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32-\u0b33\u0b35-\u0b39\u0b3d\u0b5c-\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99-\u0b9a\u0b9c\u0b9e-\u0b9f\u0ba3-\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60-\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0-\u0ce1\u0cf1-\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32-\u0e33\u0e40-\u0e45\u0e81-\u0e82\u0e84\u0e87-\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa-\u0eab\u0ead-\u0eb0\u0eb2-\u0eb3\u0ebd\u0ec0-\u0ec4\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065-\u1066\u106e-\u1070\u1075-\u1081\u108e\u1100-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16f1-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17dc\u1820-\u1842\u1844-\u1878\u1880-\u1884\u1887-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae-\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c77\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5-\u1cf6\u2135-\u2138\u2d30-\u2d67\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3006\u303c\u3041-\u3096\u309f\u30a1-\u30fa\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua014\ua016-\ua48c\ua4d0-\ua4f7\ua500-\ua60b\ua610-\ua61f\ua62a-\ua62b\ua66e\ua6a0-\ua6e5\ua78f\ua7f7\ua7fb-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd-\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9e0-\ua9e4\ua9e7-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa6f\uaa71-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5-\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadc\uaae0-\uaaea\uaaf2\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff66-\uff6f\uff71-\uff9d\uffa0-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc\U00010000-\U0001000b\U0001000d-\U00010026\U00010028-\U0001003a\U0001003c-\U0001003d\U0001003f-\U0001004d\U00010050-\U0001005d\U00010080-\U000100fa\U00010280-\U0001029c\U000102a0-\U000102d0\U00010300-\U0001031f\U0001032d-\U00010340\U00010342-\U00010349\U00010350-\U00010375\U00010380-\U0001039d\U000103a0-\U000103c3\U000103c8-\U000103cf\U00010450-\U0001049d\U00010500-\U00010527\U00010530-\U00010563\U00010600-\U00010736\U00010740-\U00010755\U00010760-\U00010767\U00010800-\U00010805\U00010808\U0001080a-\U00010835\U00010837-\U00010838\U0001083c\U0001083f-\U00010855\U00010860-\U00010876\U00010880-\U0001089e\U000108e0-\U000108f2\U000108f4-\U000108f5\U00010900-\U00010915\U00010920-\U00010939\U00010980-\U000109b7\U000109be-\U000109bf\U00010a00\U00010a10-\U00010a13\U00010a15-\U00010a17\U00010a19-\U00010a35\U00010a60-\U00010a7c\U00010a80-\U00010a9c\U00010ac0-\U00010ac7\U00010ac9-\U00010ae4\U00010b00-\U00010b35\U00010b40-\U00010b55\U00010b60-\U00010b72\U00010b80-\U00010b91\U00010c00-\U00010c48\U00010d00-\U00010d23\U00010f00-\U00010f1c\U00010f27\U00010f30-\U00010f45\U00011003-\U00011037\U00011083-\U000110af\U000110d0-\U000110e8\U00011103-\U00011126\U00011144\U00011150-\U00011172\U00011176\U00011183-\U000111b2\U000111c1-\U000111c4\U000111da\U000111dc\U00011200-\U00011211\U00011213-\U0001122b\U00011280-\U00011286\U00011288\U0001128a-\U0001128d\U0001128f-\U0001129d\U0001129f-\U000112a8\U000112b0-\U000112de\U00011305-\U0001130c\U0001130f-\U00011310\U00011313-\U00011328\U0001132a-\U00011330\U00011332-\U00011333\U00011335-\U00011339\U0001133d\U00011350\U0001135d-\U00011361\U00011400-\U00011434\U00011447-\U0001144a\U00011480-\U000114af\U000114c4-\U000114c5\U000114c7\U00011580-\U000115ae\U000115d8-\U000115db\U00011600-\U0001162f\U00011644\U00011680-\U000116aa\U00011700-\U0001171a\U00011800-\U0001182b\U000118ff\U00011a00\U00011a0b-\U00011a32\U00011a3a\U00011a50\U00011a5c-\U00011a83\U00011a86-\U00011a89\U00011a9d\U00011ac0-\U00011af8\U00011c00-\U00011c08\U00011c0a-\U00011c2e\U00011c40\U00011c72-\U00011c8f\U00011d00-\U00011d06\U00011d08-\U00011d09\U00011d0b-\U00011d30\U00011d46\U00011d60-\U00011d65\U00011d67-\U00011d68\U00011d6a-\U00011d89\U00011d98\U00011ee0-\U00011ef2\U00012000-\U00012399\U00012480-\U00012543\U00013000-\U0001342e\U00014400-\U00014646\U00016800-\U00016a38\U00016a40-\U00016a5e\U00016ad0-\U00016aed\U00016b00-\U00016b2f\U00016b63-\U00016b77\U00016b7d-\U00016b8f\U00016f00-\U00016f44\U00016f50\U00017000-\U000187f1\U00018800-\U00018af2\U0001b000-\U0001b11e\U0001b170-\U0001b2fb\U0001bc00-\U0001bc6a\U0001bc70-\U0001bc7c\U0001bc80-\U0001bc88\U0001bc90-\U0001bc99\U0001e800-\U0001e8c4\U0001ee00-\U0001ee03\U0001ee05-\U0001ee1f\U0001ee21-\U0001ee22\U0001ee24\U0001ee27\U0001ee29-\U0001ee32\U0001ee34-\U0001ee37\U0001ee39\U0001ee3b\U0001ee42\U0001ee47\U0001ee49\U0001ee4b\U0001ee4d-\U0001ee4f\U0001ee51-\U0001ee52\U0001ee54\U0001ee57\U0001ee59\U0001ee5b\U0001ee5d\U0001ee5f\U0001ee61-\U0001ee62\U0001ee64\U0001ee67-\U0001ee6a\U0001ee6c-\U0001ee72\U0001ee74-\U0001ee77\U0001ee79-\U0001ee7c\U0001ee7e\U0001ee80-\U0001ee89\U0001ee8b-\U0001ee9b\U0001eea1-\U0001eea3\U0001eea5-\U0001eea9\U0001eeab-\U0001eebb\U00020000-\U0002a6d6\U0002a700-\U0002b734\U0002b740-\U0002b81d\U0002b820-\U0002cea1\U0002ceb0-\U0002ebe0\U0002f800-\U0002fa1d'
29
+
30
+ Lt = '\u01c5\u01c8\u01cb\u01f2\u1f88-\u1f8f\u1f98-\u1f9f\u1fa8-\u1faf\u1fbc\u1fcc\u1ffc'
31
+
32
+ Lu = 'A-Z\xc0-\xd6\xd8-\xde\u0100\u0102\u0104\u0106\u0108\u010a\u010c\u010e\u0110\u0112\u0114\u0116\u0118\u011a\u011c\u011e\u0120\u0122\u0124\u0126\u0128\u012a\u012c\u012e\u0130\u0132\u0134\u0136\u0139\u013b\u013d\u013f\u0141\u0143\u0145\u0147\u014a\u014c\u014e\u0150\u0152\u0154\u0156\u0158\u015a\u015c\u015e\u0160\u0162\u0164\u0166\u0168\u016a\u016c\u016e\u0170\u0172\u0174\u0176\u0178-\u0179\u017b\u017d\u0181-\u0182\u0184\u0186-\u0187\u0189-\u018b\u018e-\u0191\u0193-\u0194\u0196-\u0198\u019c-\u019d\u019f-\u01a0\u01a2\u01a4\u01a6-\u01a7\u01a9\u01ac\u01ae-\u01af\u01b1-\u01b3\u01b5\u01b7-\u01b8\u01bc\u01c4\u01c7\u01ca\u01cd\u01cf\u01d1\u01d3\u01d5\u01d7\u01d9\u01db\u01de\u01e0\u01e2\u01e4\u01e6\u01e8\u01ea\u01ec\u01ee\u01f1\u01f4\u01f6-\u01f8\u01fa\u01fc\u01fe\u0200\u0202\u0204\u0206\u0208\u020a\u020c\u020e\u0210\u0212\u0214\u0216\u0218\u021a\u021c\u021e\u0220\u0222\u0224\u0226\u0228\u022a\u022c\u022e\u0230\u0232\u023a-\u023b\u023d-\u023e\u0241\u0243-\u0246\u0248\u024a\u024c\u024e\u0370\u0372\u0376\u037f\u0386\u0388-\u038a\u038c\u038e-\u038f\u0391-\u03a1\u03a3-\u03ab\u03cf\u03d2-\u03d4\u03d8\u03da\u03dc\u03de\u03e0\u03e2\u03e4\u03e6\u03e8\u03ea\u03ec\u03ee\u03f4\u03f7\u03f9-\u03fa\u03fd-\u042f\u0460\u0462\u0464\u0466\u0468\u046a\u046c\u046e\u0470\u0472\u0474\u0476\u0478\u047a\u047c\u047e\u0480\u048a\u048c\u048e\u0490\u0492\u0494\u0496\u0498\u049a\u049c\u049e\u04a0\u04a2\u04a4\u04a6\u04a8\u04aa\u04ac\u04ae\u04b0\u04b2\u04b4\u04b6\u04b8\u04ba\u04bc\u04be\u04c0-\u04c1\u04c3\u04c5\u04c7\u04c9\u04cb\u04cd\u04d0\u04d2\u04d4\u04d6\u04d8\u04da\u04dc\u04de\u04e0\u04e2\u04e4\u04e6\u04e8\u04ea\u04ec\u04ee\u04f0\u04f2\u04f4\u04f6\u04f8\u04fa\u04fc\u04fe\u0500\u0502\u0504\u0506\u0508\u050a\u050c\u050e\u0510\u0512\u0514\u0516\u0518\u051a\u051c\u051e\u0520\u0522\u0524\u0526\u0528\u052a\u052c\u052e\u0531-\u0556\u10a0-\u10c5\u10c7\u10cd\u13a0-\u13f5\u1c90-\u1cba\u1cbd-\u1cbf\u1e00\u1e02\u1e04\u1e06\u1e08\u1e0a\u1e0c\u1e0e\u1e10\u1e12\u1e14\u1e16\u1e18\u1e1a\u1e1c\u1e1e\u1e20\u1e22\u1e24\u1e26\u1e28\u1e2a\u1e2c\u1e2e\u1e30\u1e32\u1e34\u1e36\u1e38\u1e3a\u1e3c\u1e3e\u1e40\u1e42\u1e44\u1e46\u1e48\u1e4a\u1e4c\u1e4e\u1e50\u1e52\u1e54\u1e56\u1e58\u1e5a\u1e5c\u1e5e\u1e60\u1e62\u1e64\u1e66\u1e68\u1e6a\u1e6c\u1e6e\u1e70\u1e72\u1e74\u1e76\u1e78\u1e7a\u1e7c\u1e7e\u1e80\u1e82\u1e84\u1e86\u1e88\u1e8a\u1e8c\u1e8e\u1e90\u1e92\u1e94\u1e9e\u1ea0\u1ea2\u1ea4\u1ea6\u1ea8\u1eaa\u1eac\u1eae\u1eb0\u1eb2\u1eb4\u1eb6\u1eb8\u1eba\u1ebc\u1ebe\u1ec0\u1ec2\u1ec4\u1ec6\u1ec8\u1eca\u1ecc\u1ece\u1ed0\u1ed2\u1ed4\u1ed6\u1ed8\u1eda\u1edc\u1ede\u1ee0\u1ee2\u1ee4\u1ee6\u1ee8\u1eea\u1eec\u1eee\u1ef0\u1ef2\u1ef4\u1ef6\u1ef8\u1efa\u1efc\u1efe\u1f08-\u1f0f\u1f18-\u1f1d\u1f28-\u1f2f\u1f38-\u1f3f\u1f48-\u1f4d\u1f59\u1f5b\u1f5d\u1f5f\u1f68-\u1f6f\u1fb8-\u1fbb\u1fc8-\u1fcb\u1fd8-\u1fdb\u1fe8-\u1fec\u1ff8-\u1ffb\u2102\u2107\u210b-\u210d\u2110-\u2112\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u2130-\u2133\u213e-\u213f\u2145\u2183\u2c00-\u2c2e\u2c60\u2c62-\u2c64\u2c67\u2c69\u2c6b\u2c6d-\u2c70\u2c72\u2c75\u2c7e-\u2c80\u2c82\u2c84\u2c86\u2c88\u2c8a\u2c8c\u2c8e\u2c90\u2c92\u2c94\u2c96\u2c98\u2c9a\u2c9c\u2c9e\u2ca0\u2ca2\u2ca4\u2ca6\u2ca8\u2caa\u2cac\u2cae\u2cb0\u2cb2\u2cb4\u2cb6\u2cb8\u2cba\u2cbc\u2cbe\u2cc0\u2cc2\u2cc4\u2cc6\u2cc8\u2cca\u2ccc\u2cce\u2cd0\u2cd2\u2cd4\u2cd6\u2cd8\u2cda\u2cdc\u2cde\u2ce0\u2ce2\u2ceb\u2ced\u2cf2\ua640\ua642\ua644\ua646\ua648\ua64a\ua64c\ua64e\ua650\ua652\ua654\ua656\ua658\ua65a\ua65c\ua65e\ua660\ua662\ua664\ua666\ua668\ua66a\ua66c\ua680\ua682\ua684\ua686\ua688\ua68a\ua68c\ua68e\ua690\ua692\ua694\ua696\ua698\ua69a\ua722\ua724\ua726\ua728\ua72a\ua72c\ua72e\ua732\ua734\ua736\ua738\ua73a\ua73c\ua73e\ua740\ua742\ua744\ua746\ua748\ua74a\ua74c\ua74e\ua750\ua752\ua754\ua756\ua758\ua75a\ua75c\ua75e\ua760\ua762\ua764\ua766\ua768\ua76a\ua76c\ua76e\ua779\ua77b\ua77d-\ua77e\ua780\ua782\ua784\ua786\ua78b\ua78d\ua790\ua792\ua796\ua798\ua79a\ua79c\ua79e\ua7a0\ua7a2\ua7a4\ua7a6\ua7a8\ua7aa-\ua7ae\ua7b0-\ua7b4\ua7b6\ua7b8\uff21-\uff3a\U00010400-\U00010427\U000104b0-\U000104d3\U00010c80-\U00010cb2\U000118a0-\U000118bf\U00016e40-\U00016e5f\U0001d400-\U0001d419\U0001d434-\U0001d44d\U0001d468-\U0001d481\U0001d49c\U0001d49e-\U0001d49f\U0001d4a2\U0001d4a5-\U0001d4a6\U0001d4a9-\U0001d4ac\U0001d4ae-\U0001d4b5\U0001d4d0-\U0001d4e9\U0001d504-\U0001d505\U0001d507-\U0001d50a\U0001d50d-\U0001d514\U0001d516-\U0001d51c\U0001d538-\U0001d539\U0001d53b-\U0001d53e\U0001d540-\U0001d544\U0001d546\U0001d54a-\U0001d550\U0001d56c-\U0001d585\U0001d5a0-\U0001d5b9\U0001d5d4-\U0001d5ed\U0001d608-\U0001d621\U0001d63c-\U0001d655\U0001d670-\U0001d689\U0001d6a8-\U0001d6c0\U0001d6e2-\U0001d6fa\U0001d71c-\U0001d734\U0001d756-\U0001d76e\U0001d790-\U0001d7a8\U0001d7ca\U0001e900-\U0001e921'
33
+
34
+ Mc = '\u0903\u093b\u093e-\u0940\u0949-\u094c\u094e-\u094f\u0982-\u0983\u09be-\u09c0\u09c7-\u09c8\u09cb-\u09cc\u09d7\u0a03\u0a3e-\u0a40\u0a83\u0abe-\u0ac0\u0ac9\u0acb-\u0acc\u0b02-\u0b03\u0b3e\u0b40\u0b47-\u0b48\u0b4b-\u0b4c\u0b57\u0bbe-\u0bbf\u0bc1-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcc\u0bd7\u0c01-\u0c03\u0c41-\u0c44\u0c82-\u0c83\u0cbe\u0cc0-\u0cc4\u0cc7-\u0cc8\u0cca-\u0ccb\u0cd5-\u0cd6\u0d02-\u0d03\u0d3e-\u0d40\u0d46-\u0d48\u0d4a-\u0d4c\u0d57\u0d82-\u0d83\u0dcf-\u0dd1\u0dd8-\u0ddf\u0df2-\u0df3\u0f3e-\u0f3f\u0f7f\u102b-\u102c\u1031\u1038\u103b-\u103c\u1056-\u1057\u1062-\u1064\u1067-\u106d\u1083-\u1084\u1087-\u108c\u108f\u109a-\u109c\u17b6\u17be-\u17c5\u17c7-\u17c8\u1923-\u1926\u1929-\u192b\u1930-\u1931\u1933-\u1938\u1a19-\u1a1a\u1a55\u1a57\u1a61\u1a63-\u1a64\u1a6d-\u1a72\u1b04\u1b35\u1b3b\u1b3d-\u1b41\u1b43-\u1b44\u1b82\u1ba1\u1ba6-\u1ba7\u1baa\u1be7\u1bea-\u1bec\u1bee\u1bf2-\u1bf3\u1c24-\u1c2b\u1c34-\u1c35\u1ce1\u1cf2-\u1cf3\u1cf7\u302e-\u302f\ua823-\ua824\ua827\ua880-\ua881\ua8b4-\ua8c3\ua952-\ua953\ua983\ua9b4-\ua9b5\ua9ba-\ua9bb\ua9bd-\ua9c0\uaa2f-\uaa30\uaa33-\uaa34\uaa4d\uaa7b\uaa7d\uaaeb\uaaee-\uaaef\uaaf5\uabe3-\uabe4\uabe6-\uabe7\uabe9-\uabea\uabec\U00011000\U00011002\U00011082\U000110b0-\U000110b2\U000110b7-\U000110b8\U0001112c\U00011145-\U00011146\U00011182\U000111b3-\U000111b5\U000111bf-\U000111c0\U0001122c-\U0001122e\U00011232-\U00011233\U00011235\U000112e0-\U000112e2\U00011302-\U00011303\U0001133e-\U0001133f\U00011341-\U00011344\U00011347-\U00011348\U0001134b-\U0001134d\U00011357\U00011362-\U00011363\U00011435-\U00011437\U00011440-\U00011441\U00011445\U000114b0-\U000114b2\U000114b9\U000114bb-\U000114be\U000114c1\U000115af-\U000115b1\U000115b8-\U000115bb\U000115be\U00011630-\U00011632\U0001163b-\U0001163c\U0001163e\U000116ac\U000116ae-\U000116af\U000116b6\U00011720-\U00011721\U00011726\U0001182c-\U0001182e\U00011838\U00011a39\U00011a57-\U00011a58\U00011a97\U00011c2f\U00011c3e\U00011ca9\U00011cb1\U00011cb4\U00011d8a-\U00011d8e\U00011d93-\U00011d94\U00011d96\U00011ef5-\U00011ef6\U00016f51-\U00016f7e\U0001d165-\U0001d166\U0001d16d-\U0001d172'
35
+
36
+ Me = '\u0488-\u0489\u1abe\u20dd-\u20e0\u20e2-\u20e4\ua670-\ua672'
37
+
38
+ Mn = '\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u0610-\u061a\u064b-\u065f\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7-\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0902\u093a\u093c\u0941-\u0948\u094d\u0951-\u0957\u0962-\u0963\u0981\u09bc\u09c1-\u09c4\u09cd\u09e2-\u09e3\u09fe\u0a01-\u0a02\u0a3c\u0a41-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a51\u0a70-\u0a71\u0a75\u0a81-\u0a82\u0abc\u0ac1-\u0ac5\u0ac7-\u0ac8\u0acd\u0ae2-\u0ae3\u0afa-\u0aff\u0b01\u0b3c\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b62-\u0b63\u0b82\u0bc0\u0bcd\u0c00\u0c04\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56\u0c62-\u0c63\u0c81\u0cbc\u0cbf\u0cc6\u0ccc-\u0ccd\u0ce2-\u0ce3\u0d00-\u0d01\u0d3b-\u0d3c\u0d41-\u0d44\u0d4d\u0d62-\u0d63\u0dca\u0dd2-\u0dd4\u0dd6\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb-\u0ebc\u0ec8-\u0ecd\u0f18-\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039-\u103a\u103d-\u103e\u1058-\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085-\u1086\u108d\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17b4-\u17b5\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u1885-\u1886\u18a9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193b\u1a17-\u1a18\u1a1b\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1ab0-\u1abd\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80-\u1b81\u1ba2-\u1ba5\u1ba8-\u1ba9\u1bab-\u1bad\u1be6\u1be8-\u1be9\u1bed\u1bef-\u1bf1\u1c2c-\u1c33\u1c36-\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1cf4\u1cf8-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302d\u3099-\u309a\ua66f\ua674-\ua67d\ua69e-\ua69f\ua6f0-\ua6f1\ua802\ua806\ua80b\ua825-\ua826\ua8c4-\ua8c5\ua8e0-\ua8f1\ua8ff\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\ua9e5\uaa29-\uaa2e\uaa31-\uaa32\uaa35-\uaa36\uaa43\uaa4c\uaa7c\uaab0\uaab2-\uaab4\uaab7-\uaab8\uaabe-\uaabf\uaac1\uaaec-\uaaed\uaaf6\uabe5\uabe8\uabed\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\U000101fd\U000102e0\U00010376-\U0001037a\U00010a01-\U00010a03\U00010a05-\U00010a06\U00010a0c-\U00010a0f\U00010a38-\U00010a3a\U00010a3f\U00010ae5-\U00010ae6\U00010d24-\U00010d27\U00010f46-\U00010f50\U00011001\U00011038-\U00011046\U0001107f-\U00011081\U000110b3-\U000110b6\U000110b9-\U000110ba\U00011100-\U00011102\U00011127-\U0001112b\U0001112d-\U00011134\U00011173\U00011180-\U00011181\U000111b6-\U000111be\U000111c9-\U000111cc\U0001122f-\U00011231\U00011234\U00011236-\U00011237\U0001123e\U000112df\U000112e3-\U000112ea\U00011300-\U00011301\U0001133b-\U0001133c\U00011340\U00011366-\U0001136c\U00011370-\U00011374\U00011438-\U0001143f\U00011442-\U00011444\U00011446\U0001145e\U000114b3-\U000114b8\U000114ba\U000114bf-\U000114c0\U000114c2-\U000114c3\U000115b2-\U000115b5\U000115bc-\U000115bd\U000115bf-\U000115c0\U000115dc-\U000115dd\U00011633-\U0001163a\U0001163d\U0001163f-\U00011640\U000116ab\U000116ad\U000116b0-\U000116b5\U000116b7\U0001171d-\U0001171f\U00011722-\U00011725\U00011727-\U0001172b\U0001182f-\U00011837\U00011839-\U0001183a\U00011a01-\U00011a0a\U00011a33-\U00011a38\U00011a3b-\U00011a3e\U00011a47\U00011a51-\U00011a56\U00011a59-\U00011a5b\U00011a8a-\U00011a96\U00011a98-\U00011a99\U00011c30-\U00011c36\U00011c38-\U00011c3d\U00011c3f\U00011c92-\U00011ca7\U00011caa-\U00011cb0\U00011cb2-\U00011cb3\U00011cb5-\U00011cb6\U00011d31-\U00011d36\U00011d3a\U00011d3c-\U00011d3d\U00011d3f-\U00011d45\U00011d47\U00011d90-\U00011d91\U00011d95\U00011d97\U00011ef3-\U00011ef4\U00016af0-\U00016af4\U00016b30-\U00016b36\U00016f8f-\U00016f92\U0001bc9d-\U0001bc9e\U0001d167-\U0001d169\U0001d17b-\U0001d182\U0001d185-\U0001d18b\U0001d1aa-\U0001d1ad\U0001d242-\U0001d244\U0001da00-\U0001da36\U0001da3b-\U0001da6c\U0001da75\U0001da84\U0001da9b-\U0001da9f\U0001daa1-\U0001daaf\U0001e000-\U0001e006\U0001e008-\U0001e018\U0001e01b-\U0001e021\U0001e023-\U0001e024\U0001e026-\U0001e02a\U0001e8d0-\U0001e8d6\U0001e944-\U0001e94a\U000e0100-\U000e01ef'
39
+
40
+ Nd = '0-9\u0660-\u0669\u06f0-\u06f9\u07c0-\u07c9\u0966-\u096f\u09e6-\u09ef\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be6-\u0bef\u0c66-\u0c6f\u0ce6-\u0cef\u0d66-\u0d6f\u0de6-\u0def\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29\u1040-\u1049\u1090-\u1099\u17e0-\u17e9\u1810-\u1819\u1946-\u194f\u19d0-\u19d9\u1a80-\u1a89\u1a90-\u1a99\u1b50-\u1b59\u1bb0-\u1bb9\u1c40-\u1c49\u1c50-\u1c59\ua620-\ua629\ua8d0-\ua8d9\ua900-\ua909\ua9d0-\ua9d9\ua9f0-\ua9f9\uaa50-\uaa59\uabf0-\uabf9\uff10-\uff19\U000104a0-\U000104a9\U00010d30-\U00010d39\U00011066-\U0001106f\U000110f0-\U000110f9\U00011136-\U0001113f\U000111d0-\U000111d9\U000112f0-\U000112f9\U00011450-\U00011459\U000114d0-\U000114d9\U00011650-\U00011659\U000116c0-\U000116c9\U00011730-\U00011739\U000118e0-\U000118e9\U00011c50-\U00011c59\U00011d50-\U00011d59\U00011da0-\U00011da9\U00016a60-\U00016a69\U00016b50-\U00016b59\U0001d7ce-\U0001d7ff\U0001e950-\U0001e959'
41
+
42
+ Nl = '\u16ee-\u16f0\u2160-\u2182\u2185-\u2188\u3007\u3021-\u3029\u3038-\u303a\ua6e6-\ua6ef\U00010140-\U00010174\U00010341\U0001034a\U000103d1-\U000103d5\U00012400-\U0001246e'
43
+
44
+ No = '\xb2-\xb3\xb9\xbc-\xbe\u09f4-\u09f9\u0b72-\u0b77\u0bf0-\u0bf2\u0c78-\u0c7e\u0d58-\u0d5e\u0d70-\u0d78\u0f2a-\u0f33\u1369-\u137c\u17f0-\u17f9\u19da\u2070\u2074-\u2079\u2080-\u2089\u2150-\u215f\u2189\u2460-\u249b\u24ea-\u24ff\u2776-\u2793\u2cfd\u3192-\u3195\u3220-\u3229\u3248-\u324f\u3251-\u325f\u3280-\u3289\u32b1-\u32bf\ua830-\ua835\U00010107-\U00010133\U00010175-\U00010178\U0001018a-\U0001018b\U000102e1-\U000102fb\U00010320-\U00010323\U00010858-\U0001085f\U00010879-\U0001087f\U000108a7-\U000108af\U000108fb-\U000108ff\U00010916-\U0001091b\U000109bc-\U000109bd\U000109c0-\U000109cf\U000109d2-\U000109ff\U00010a40-\U00010a48\U00010a7d-\U00010a7e\U00010a9d-\U00010a9f\U00010aeb-\U00010aef\U00010b58-\U00010b5f\U00010b78-\U00010b7f\U00010ba9-\U00010baf\U00010cfa-\U00010cff\U00010e60-\U00010e7e\U00010f1d-\U00010f26\U00010f51-\U00010f54\U00011052-\U00011065\U000111e1-\U000111f4\U0001173a-\U0001173b\U000118ea-\U000118f2\U00011c5a-\U00011c6c\U00016b5b-\U00016b61\U00016e80-\U00016e96\U0001d2e0-\U0001d2f3\U0001d360-\U0001d378\U0001e8c7-\U0001e8cf\U0001ec71-\U0001ecab\U0001ecad-\U0001ecaf\U0001ecb1-\U0001ecb4\U0001f100-\U0001f10c'
45
+
46
+ Pc = '_\u203f-\u2040\u2054\ufe33-\ufe34\ufe4d-\ufe4f\uff3f'
47
+
48
+ Pd = '\\-\u058a\u05be\u1400\u1806\u2010-\u2015\u2e17\u2e1a\u2e3a-\u2e3b\u2e40\u301c\u3030\u30a0\ufe31-\ufe32\ufe58\ufe63\uff0d'
49
+
50
+ Pe = ')\\]}\u0f3b\u0f3d\u169c\u2046\u207e\u208e\u2309\u230b\u232a\u2769\u276b\u276d\u276f\u2771\u2773\u2775\u27c6\u27e7\u27e9\u27eb\u27ed\u27ef\u2984\u2986\u2988\u298a\u298c\u298e\u2990\u2992\u2994\u2996\u2998\u29d9\u29db\u29fd\u2e23\u2e25\u2e27\u2e29\u3009\u300b\u300d\u300f\u3011\u3015\u3017\u3019\u301b\u301e-\u301f\ufd3e\ufe18\ufe36\ufe38\ufe3a\ufe3c\ufe3e\ufe40\ufe42\ufe44\ufe48\ufe5a\ufe5c\ufe5e\uff09\uff3d\uff5d\uff60\uff63'
51
+
52
+ Pf = '\xbb\u2019\u201d\u203a\u2e03\u2e05\u2e0a\u2e0d\u2e1d\u2e21'
53
+
54
+ Pi = '\xab\u2018\u201b-\u201c\u201f\u2039\u2e02\u2e04\u2e09\u2e0c\u2e1c\u2e20'
55
+
56
+ Po = "!-#%-'*,.-/:-;?-@\\\\\xa1\xa7\xb6-\xb7\xbf\u037e\u0387\u055a-\u055f\u0589\u05c0\u05c3\u05c6\u05f3-\u05f4\u0609-\u060a\u060c-\u060d\u061b\u061e-\u061f\u066a-\u066d\u06d4\u0700-\u070d\u07f7-\u07f9\u0830-\u083e\u085e\u0964-\u0965\u0970\u09fd\u0a76\u0af0\u0c84\u0df4\u0e4f\u0e5a-\u0e5b\u0f04-\u0f12\u0f14\u0f85\u0fd0-\u0fd4\u0fd9-\u0fda\u104a-\u104f\u10fb\u1360-\u1368\u166d-\u166e\u16eb-\u16ed\u1735-\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u1805\u1807-\u180a\u1944-\u1945\u1a1e-\u1a1f\u1aa0-\u1aa6\u1aa8-\u1aad\u1b5a-\u1b60\u1bfc-\u1bff\u1c3b-\u1c3f\u1c7e-\u1c7f\u1cc0-\u1cc7\u1cd3\u2016-\u2017\u2020-\u2027\u2030-\u2038\u203b-\u203e\u2041-\u2043\u2047-\u2051\u2053\u2055-\u205e\u2cf9-\u2cfc\u2cfe-\u2cff\u2d70\u2e00-\u2e01\u2e06-\u2e08\u2e0b\u2e0e-\u2e16\u2e18-\u2e19\u2e1b\u2e1e-\u2e1f\u2e2a-\u2e2e\u2e30-\u2e39\u2e3c-\u2e3f\u2e41\u2e43-\u2e4e\u3001-\u3003\u303d\u30fb\ua4fe-\ua4ff\ua60d-\ua60f\ua673\ua67e\ua6f2-\ua6f7\ua874-\ua877\ua8ce-\ua8cf\ua8f8-\ua8fa\ua8fc\ua92e-\ua92f\ua95f\ua9c1-\ua9cd\ua9de-\ua9df\uaa5c-\uaa5f\uaade-\uaadf\uaaf0-\uaaf1\uabeb\ufe10-\ufe16\ufe19\ufe30\ufe45-\ufe46\ufe49-\ufe4c\ufe50-\ufe52\ufe54-\ufe57\ufe5f-\ufe61\ufe68\ufe6a-\ufe6b\uff01-\uff03\uff05-\uff07\uff0a\uff0c\uff0e-\uff0f\uff1a-\uff1b\uff1f-\uff20\uff3c\uff61\uff64-\uff65\U00010100-\U00010102\U0001039f\U000103d0\U0001056f\U00010857\U0001091f\U0001093f\U00010a50-\U00010a58\U00010a7f\U00010af0-\U00010af6\U00010b39-\U00010b3f\U00010b99-\U00010b9c\U00010f55-\U00010f59\U00011047-\U0001104d\U000110bb-\U000110bc\U000110be-\U000110c1\U00011140-\U00011143\U00011174-\U00011175\U000111c5-\U000111c8\U000111cd\U000111db\U000111dd-\U000111df\U00011238-\U0001123d\U000112a9\U0001144b-\U0001144f\U0001145b\U0001145d\U000114c6\U000115c1-\U000115d7\U00011641-\U00011643\U00011660-\U0001166c\U0001173c-\U0001173e\U0001183b\U00011a3f-\U00011a46\U00011a9a-\U00011a9c\U00011a9e-\U00011aa2\U00011c41-\U00011c45\U00011c70-\U00011c71\U00011ef7-\U00011ef8\U00012470-\U00012474\U00016a6e-\U00016a6f\U00016af5\U00016b37-\U00016b3b\U00016b44\U00016e97-\U00016e9a\U0001bc9f\U0001da87-\U0001da8b\U0001e95e-\U0001e95f"
57
+
58
+ Ps = '(\\[{\u0f3a\u0f3c\u169b\u201a\u201e\u2045\u207d\u208d\u2308\u230a\u2329\u2768\u276a\u276c\u276e\u2770\u2772\u2774\u27c5\u27e6\u27e8\u27ea\u27ec\u27ee\u2983\u2985\u2987\u2989\u298b\u298d\u298f\u2991\u2993\u2995\u2997\u29d8\u29da\u29fc\u2e22\u2e24\u2e26\u2e28\u2e42\u3008\u300a\u300c\u300e\u3010\u3014\u3016\u3018\u301a\u301d\ufd3f\ufe17\ufe35\ufe37\ufe39\ufe3b\ufe3d\ufe3f\ufe41\ufe43\ufe47\ufe59\ufe5b\ufe5d\uff08\uff3b\uff5b\uff5f\uff62'
59
+
60
+ Sc = '$\xa2-\xa5\u058f\u060b\u07fe-\u07ff\u09f2-\u09f3\u09fb\u0af1\u0bf9\u0e3f\u17db\u20a0-\u20bf\ua838\ufdfc\ufe69\uff04\uffe0-\uffe1\uffe5-\uffe6\U0001ecb0'
61
+
62
+ Sk = '\\^`\xa8\xaf\xb4\xb8\u02c2-\u02c5\u02d2-\u02df\u02e5-\u02eb\u02ed\u02ef-\u02ff\u0375\u0384-\u0385\u1fbd\u1fbf-\u1fc1\u1fcd-\u1fcf\u1fdd-\u1fdf\u1fed-\u1fef\u1ffd-\u1ffe\u309b-\u309c\ua700-\ua716\ua720-\ua721\ua789-\ua78a\uab5b\ufbb2-\ufbc1\uff3e\uff40\uffe3\U0001f3fb-\U0001f3ff'
63
+
64
+ Sm = '+<->|~\xac\xb1\xd7\xf7\u03f6\u0606-\u0608\u2044\u2052\u207a-\u207c\u208a-\u208c\u2118\u2140-\u2144\u214b\u2190-\u2194\u219a-\u219b\u21a0\u21a3\u21a6\u21ae\u21ce-\u21cf\u21d2\u21d4\u21f4-\u22ff\u2320-\u2321\u237c\u239b-\u23b3\u23dc-\u23e1\u25b7\u25c1\u25f8-\u25ff\u266f\u27c0-\u27c4\u27c7-\u27e5\u27f0-\u27ff\u2900-\u2982\u2999-\u29d7\u29dc-\u29fb\u29fe-\u2aff\u2b30-\u2b44\u2b47-\u2b4c\ufb29\ufe62\ufe64-\ufe66\uff0b\uff1c-\uff1e\uff5c\uff5e\uffe2\uffe9-\uffec\U0001d6c1\U0001d6db\U0001d6fb\U0001d715\U0001d735\U0001d74f\U0001d76f\U0001d789\U0001d7a9\U0001d7c3\U0001eef0-\U0001eef1'
65
+
66
+ So = '\xa6\xa9\xae\xb0\u0482\u058d-\u058e\u060e-\u060f\u06de\u06e9\u06fd-\u06fe\u07f6\u09fa\u0b70\u0bf3-\u0bf8\u0bfa\u0c7f\u0d4f\u0d79\u0f01-\u0f03\u0f13\u0f15-\u0f17\u0f1a-\u0f1f\u0f34\u0f36\u0f38\u0fbe-\u0fc5\u0fc7-\u0fcc\u0fce-\u0fcf\u0fd5-\u0fd8\u109e-\u109f\u1390-\u1399\u1940\u19de-\u19ff\u1b61-\u1b6a\u1b74-\u1b7c\u2100-\u2101\u2103-\u2106\u2108-\u2109\u2114\u2116-\u2117\u211e-\u2123\u2125\u2127\u2129\u212e\u213a-\u213b\u214a\u214c-\u214d\u214f\u218a-\u218b\u2195-\u2199\u219c-\u219f\u21a1-\u21a2\u21a4-\u21a5\u21a7-\u21ad\u21af-\u21cd\u21d0-\u21d1\u21d3\u21d5-\u21f3\u2300-\u2307\u230c-\u231f\u2322-\u2328\u232b-\u237b\u237d-\u239a\u23b4-\u23db\u23e2-\u2426\u2440-\u244a\u249c-\u24e9\u2500-\u25b6\u25b8-\u25c0\u25c2-\u25f7\u2600-\u266e\u2670-\u2767\u2794-\u27bf\u2800-\u28ff\u2b00-\u2b2f\u2b45-\u2b46\u2b4d-\u2b73\u2b76-\u2b95\u2b98-\u2bc8\u2bca-\u2bfe\u2ce5-\u2cea\u2e80-\u2e99\u2e9b-\u2ef3\u2f00-\u2fd5\u2ff0-\u2ffb\u3004\u3012-\u3013\u3020\u3036-\u3037\u303e-\u303f\u3190-\u3191\u3196-\u319f\u31c0-\u31e3\u3200-\u321e\u322a-\u3247\u3250\u3260-\u327f\u328a-\u32b0\u32c0-\u32fe\u3300-\u33ff\u4dc0-\u4dff\ua490-\ua4c6\ua828-\ua82b\ua836-\ua837\ua839\uaa77-\uaa79\ufdfd\uffe4\uffe8\uffed-\uffee\ufffc-\ufffd\U00010137-\U0001013f\U00010179-\U00010189\U0001018c-\U0001018e\U00010190-\U0001019b\U000101a0\U000101d0-\U000101fc\U00010877-\U00010878\U00010ac8\U0001173f\U00016b3c-\U00016b3f\U00016b45\U0001bc9c\U0001d000-\U0001d0f5\U0001d100-\U0001d126\U0001d129-\U0001d164\U0001d16a-\U0001d16c\U0001d183-\U0001d184\U0001d18c-\U0001d1a9\U0001d1ae-\U0001d1e8\U0001d200-\U0001d241\U0001d245\U0001d300-\U0001d356\U0001d800-\U0001d9ff\U0001da37-\U0001da3a\U0001da6d-\U0001da74\U0001da76-\U0001da83\U0001da85-\U0001da86\U0001ecac\U0001f000-\U0001f02b\U0001f030-\U0001f093\U0001f0a0-\U0001f0ae\U0001f0b1-\U0001f0bf\U0001f0c1-\U0001f0cf\U0001f0d1-\U0001f0f5\U0001f110-\U0001f16b\U0001f170-\U0001f1ac\U0001f1e6-\U0001f202\U0001f210-\U0001f23b\U0001f240-\U0001f248\U0001f250-\U0001f251\U0001f260-\U0001f265\U0001f300-\U0001f3fa\U0001f400-\U0001f6d4\U0001f6e0-\U0001f6ec\U0001f6f0-\U0001f6f9\U0001f700-\U0001f773\U0001f780-\U0001f7d8\U0001f800-\U0001f80b\U0001f810-\U0001f847\U0001f850-\U0001f859\U0001f860-\U0001f887\U0001f890-\U0001f8ad\U0001f900-\U0001f90b\U0001f910-\U0001f93e\U0001f940-\U0001f970\U0001f973-\U0001f976\U0001f97a\U0001f97c-\U0001f9a2\U0001f9b0-\U0001f9b9\U0001f9c0-\U0001f9c2\U0001f9d0-\U0001f9ff\U0001fa60-\U0001fa6d'
67
+
68
+ Zl = '\u2028'
69
+
70
+ Zp = '\u2029'
71
+
72
+ Zs = ' \xa0\u1680\u2000-\u200a\u202f\u205f\u3000'
73
+
74
+ xid_continue = '0-9A-Z_a-z\xaa\xb5\xb7\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376-\u0377\u037b-\u037d\u037f\u0386-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u0591-\u05bd\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u05d0-\u05ea\u05ef-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u07fd\u0800-\u082d\u0840-\u085b\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u08d3-\u08e1\u08e3-\u0963\u0966-\u096f\u0971-\u0983\u0985-\u098c\u098f-\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7-\u09c8\u09cb-\u09ce\u09d7\u09dc-\u09dd\u09df-\u09e3\u09e6-\u09f1\u09fc\u09fe\u0a01-\u0a03\u0a05-\u0a0a\u0a0f-\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32-\u0a33\u0a35-\u0a36\u0a38-\u0a39\u0a3c\u0a3e-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2-\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0af9-\u0aff\u0b01-\u0b03\u0b05-\u0b0c\u0b0f-\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32-\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47-\u0b48\u0b4b-\u0b4d\u0b56-\u0b57\u0b5c-\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82-\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99-\u0b9a\u0b9c\u0b9e-\u0b9f\u0ba3-\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c00-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56\u0c58-\u0c5a\u0c60-\u0c63\u0c66-\u0c6f\u0c80-\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5-\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1-\u0cf2\u0d00-\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d54-\u0d57\u0d5f-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82-\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2-\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81-\u0e82\u0e84\u0e87-\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa-\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18-\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1369-\u1371\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772-\u1773\u1780-\u17d3\u17d7\u17dc-\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1878\u1880-\u18aa\u18b0-\u18f5\u1900-\u191e\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19da\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1ab0-\u1abd\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1cd0-\u1cd2\u1cd4-\u1cf9\u1d00-\u1df9\u1dfb-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u203f-\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099-\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua7b9\ua7f7-\ua827\ua840-\ua873\ua880-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua8fd-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\ua9e0-\ua9fe\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabea\uabec-\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufbb1\ufbd3-\ufc5d\ufc64-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdf9\ufe00-\ufe0f\ufe20-\ufe2f\ufe33-\ufe34\ufe4d-\ufe4f\ufe71\ufe73\ufe77\ufe79\ufe7b\ufe7d\ufe7f-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc\U00010000-\U0001000b\U0001000d-\U00010026\U00010028-\U0001003a\U0001003c-\U0001003d\U0001003f-\U0001004d\U00010050-\U0001005d\U00010080-\U000100fa\U00010140-\U00010174\U000101fd\U00010280-\U0001029c\U000102a0-\U000102d0\U000102e0\U00010300-\U0001031f\U0001032d-\U0001034a\U00010350-\U0001037a\U00010380-\U0001039d\U000103a0-\U000103c3\U000103c8-\U000103cf\U000103d1-\U000103d5\U00010400-\U0001049d\U000104a0-\U000104a9\U000104b0-\U000104d3\U000104d8-\U000104fb\U00010500-\U00010527\U00010530-\U00010563\U00010600-\U00010736\U00010740-\U00010755\U00010760-\U00010767\U00010800-\U00010805\U00010808\U0001080a-\U00010835\U00010837-\U00010838\U0001083c\U0001083f-\U00010855\U00010860-\U00010876\U00010880-\U0001089e\U000108e0-\U000108f2\U000108f4-\U000108f5\U00010900-\U00010915\U00010920-\U00010939\U00010980-\U000109b7\U000109be-\U000109bf\U00010a00-\U00010a03\U00010a05-\U00010a06\U00010a0c-\U00010a13\U00010a15-\U00010a17\U00010a19-\U00010a35\U00010a38-\U00010a3a\U00010a3f\U00010a60-\U00010a7c\U00010a80-\U00010a9c\U00010ac0-\U00010ac7\U00010ac9-\U00010ae6\U00010b00-\U00010b35\U00010b40-\U00010b55\U00010b60-\U00010b72\U00010b80-\U00010b91\U00010c00-\U00010c48\U00010c80-\U00010cb2\U00010cc0-\U00010cf2\U00010d00-\U00010d27\U00010d30-\U00010d39\U00010f00-\U00010f1c\U00010f27\U00010f30-\U00010f50\U00011000-\U00011046\U00011066-\U0001106f\U0001107f-\U000110ba\U000110d0-\U000110e8\U000110f0-\U000110f9\U00011100-\U00011134\U00011136-\U0001113f\U00011144-\U00011146\U00011150-\U00011173\U00011176\U00011180-\U000111c4\U000111c9-\U000111cc\U000111d0-\U000111da\U000111dc\U00011200-\U00011211\U00011213-\U00011237\U0001123e\U00011280-\U00011286\U00011288\U0001128a-\U0001128d\U0001128f-\U0001129d\U0001129f-\U000112a8\U000112b0-\U000112ea\U000112f0-\U000112f9\U00011300-\U00011303\U00011305-\U0001130c\U0001130f-\U00011310\U00011313-\U00011328\U0001132a-\U00011330\U00011332-\U00011333\U00011335-\U00011339\U0001133b-\U00011344\U00011347-\U00011348\U0001134b-\U0001134d\U00011350\U00011357\U0001135d-\U00011363\U00011366-\U0001136c\U00011370-\U00011374\U00011400-\U0001144a\U00011450-\U00011459\U0001145e\U00011480-\U000114c5\U000114c7\U000114d0-\U000114d9\U00011580-\U000115b5\U000115b8-\U000115c0\U000115d8-\U000115dd\U00011600-\U00011640\U00011644\U00011650-\U00011659\U00011680-\U000116b7\U000116c0-\U000116c9\U00011700-\U0001171a\U0001171d-\U0001172b\U00011730-\U00011739\U00011800-\U0001183a\U000118a0-\U000118e9\U000118ff\U00011a00-\U00011a3e\U00011a47\U00011a50-\U00011a83\U00011a86-\U00011a99\U00011a9d\U00011ac0-\U00011af8\U00011c00-\U00011c08\U00011c0a-\U00011c36\U00011c38-\U00011c40\U00011c50-\U00011c59\U00011c72-\U00011c8f\U00011c92-\U00011ca7\U00011ca9-\U00011cb6\U00011d00-\U00011d06\U00011d08-\U00011d09\U00011d0b-\U00011d36\U00011d3a\U00011d3c-\U00011d3d\U00011d3f-\U00011d47\U00011d50-\U00011d59\U00011d60-\U00011d65\U00011d67-\U00011d68\U00011d6a-\U00011d8e\U00011d90-\U00011d91\U00011d93-\U00011d98\U00011da0-\U00011da9\U00011ee0-\U00011ef6\U00012000-\U00012399\U00012400-\U0001246e\U00012480-\U00012543\U00013000-\U0001342e\U00014400-\U00014646\U00016800-\U00016a38\U00016a40-\U00016a5e\U00016a60-\U00016a69\U00016ad0-\U00016aed\U00016af0-\U00016af4\U00016b00-\U00016b36\U00016b40-\U00016b43\U00016b50-\U00016b59\U00016b63-\U00016b77\U00016b7d-\U00016b8f\U00016e40-\U00016e7f\U00016f00-\U00016f44\U00016f50-\U00016f7e\U00016f8f-\U00016f9f\U00016fe0-\U00016fe1\U00017000-\U000187f1\U00018800-\U00018af2\U0001b000-\U0001b11e\U0001b170-\U0001b2fb\U0001bc00-\U0001bc6a\U0001bc70-\U0001bc7c\U0001bc80-\U0001bc88\U0001bc90-\U0001bc99\U0001bc9d-\U0001bc9e\U0001d165-\U0001d169\U0001d16d-\U0001d172\U0001d17b-\U0001d182\U0001d185-\U0001d18b\U0001d1aa-\U0001d1ad\U0001d242-\U0001d244\U0001d400-\U0001d454\U0001d456-\U0001d49c\U0001d49e-\U0001d49f\U0001d4a2\U0001d4a5-\U0001d4a6\U0001d4a9-\U0001d4ac\U0001d4ae-\U0001d4b9\U0001d4bb\U0001d4bd-\U0001d4c3\U0001d4c5-\U0001d505\U0001d507-\U0001d50a\U0001d50d-\U0001d514\U0001d516-\U0001d51c\U0001d51e-\U0001d539\U0001d53b-\U0001d53e\U0001d540-\U0001d544\U0001d546\U0001d54a-\U0001d550\U0001d552-\U0001d6a5\U0001d6a8-\U0001d6c0\U0001d6c2-\U0001d6da\U0001d6dc-\U0001d6fa\U0001d6fc-\U0001d714\U0001d716-\U0001d734\U0001d736-\U0001d74e\U0001d750-\U0001d76e\U0001d770-\U0001d788\U0001d78a-\U0001d7a8\U0001d7aa-\U0001d7c2\U0001d7c4-\U0001d7cb\U0001d7ce-\U0001d7ff\U0001da00-\U0001da36\U0001da3b-\U0001da6c\U0001da75\U0001da84\U0001da9b-\U0001da9f\U0001daa1-\U0001daaf\U0001e000-\U0001e006\U0001e008-\U0001e018\U0001e01b-\U0001e021\U0001e023-\U0001e024\U0001e026-\U0001e02a\U0001e800-\U0001e8c4\U0001e8d0-\U0001e8d6\U0001e900-\U0001e94a\U0001e950-\U0001e959\U0001ee00-\U0001ee03\U0001ee05-\U0001ee1f\U0001ee21-\U0001ee22\U0001ee24\U0001ee27\U0001ee29-\U0001ee32\U0001ee34-\U0001ee37\U0001ee39\U0001ee3b\U0001ee42\U0001ee47\U0001ee49\U0001ee4b\U0001ee4d-\U0001ee4f\U0001ee51-\U0001ee52\U0001ee54\U0001ee57\U0001ee59\U0001ee5b\U0001ee5d\U0001ee5f\U0001ee61-\U0001ee62\U0001ee64\U0001ee67-\U0001ee6a\U0001ee6c-\U0001ee72\U0001ee74-\U0001ee77\U0001ee79-\U0001ee7c\U0001ee7e\U0001ee80-\U0001ee89\U0001ee8b-\U0001ee9b\U0001eea1-\U0001eea3\U0001eea5-\U0001eea9\U0001eeab-\U0001eebb\U00020000-\U0002a6d6\U0002a700-\U0002b734\U0002b740-\U0002b81d\U0002b820-\U0002cea1\U0002ceb0-\U0002ebe0\U0002f800-\U0002fa1d\U000e0100-\U000e01ef'
75
+
76
+ xid_start = 'A-Z_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376-\u0377\u037b-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e-\u066f\u0671-\u06d3\u06d5\u06e5-\u06e6\u06ee-\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4-\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f-\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc-\u09dd\u09df-\u09e1\u09f0-\u09f1\u09fc\u0a05-\u0a0a\u0a0f-\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32-\u0a33\u0a35-\u0a36\u0a38-\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2-\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0-\u0ae1\u0af9\u0b05-\u0b0c\u0b0f-\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32-\u0b33\u0b35-\u0b39\u0b3d\u0b5c-\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99-\u0b9a\u0b9c\u0b9e-\u0b9f\u0ba3-\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60-\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0-\u0ce1\u0cf1-\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e40-\u0e46\u0e81-\u0e82\u0e84\u0e87-\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa-\u0eab\u0ead-\u0eb0\u0eb2\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065-\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae-\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5-\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a-\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7b9\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd-\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5-\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufbb1\ufbd3-\ufc5d\ufc64-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdf9\ufe71\ufe73\ufe77\ufe79\ufe7b\ufe7d\ufe7f-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uff9d\uffa0-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc\U00010000-\U0001000b\U0001000d-\U00010026\U00010028-\U0001003a\U0001003c-\U0001003d\U0001003f-\U0001004d\U00010050-\U0001005d\U00010080-\U000100fa\U00010140-\U00010174\U00010280-\U0001029c\U000102a0-\U000102d0\U00010300-\U0001031f\U0001032d-\U0001034a\U00010350-\U00010375\U00010380-\U0001039d\U000103a0-\U000103c3\U000103c8-\U000103cf\U000103d1-\U000103d5\U00010400-\U0001049d\U000104b0-\U000104d3\U000104d8-\U000104fb\U00010500-\U00010527\U00010530-\U00010563\U00010600-\U00010736\U00010740-\U00010755\U00010760-\U00010767\U00010800-\U00010805\U00010808\U0001080a-\U00010835\U00010837-\U00010838\U0001083c\U0001083f-\U00010855\U00010860-\U00010876\U00010880-\U0001089e\U000108e0-\U000108f2\U000108f4-\U000108f5\U00010900-\U00010915\U00010920-\U00010939\U00010980-\U000109b7\U000109be-\U000109bf\U00010a00\U00010a10-\U00010a13\U00010a15-\U00010a17\U00010a19-\U00010a35\U00010a60-\U00010a7c\U00010a80-\U00010a9c\U00010ac0-\U00010ac7\U00010ac9-\U00010ae4\U00010b00-\U00010b35\U00010b40-\U00010b55\U00010b60-\U00010b72\U00010b80-\U00010b91\U00010c00-\U00010c48\U00010c80-\U00010cb2\U00010cc0-\U00010cf2\U00010d00-\U00010d23\U00010f00-\U00010f1c\U00010f27\U00010f30-\U00010f45\U00011003-\U00011037\U00011083-\U000110af\U000110d0-\U000110e8\U00011103-\U00011126\U00011144\U00011150-\U00011172\U00011176\U00011183-\U000111b2\U000111c1-\U000111c4\U000111da\U000111dc\U00011200-\U00011211\U00011213-\U0001122b\U00011280-\U00011286\U00011288\U0001128a-\U0001128d\U0001128f-\U0001129d\U0001129f-\U000112a8\U000112b0-\U000112de\U00011305-\U0001130c\U0001130f-\U00011310\U00011313-\U00011328\U0001132a-\U00011330\U00011332-\U00011333\U00011335-\U00011339\U0001133d\U00011350\U0001135d-\U00011361\U00011400-\U00011434\U00011447-\U0001144a\U00011480-\U000114af\U000114c4-\U000114c5\U000114c7\U00011580-\U000115ae\U000115d8-\U000115db\U00011600-\U0001162f\U00011644\U00011680-\U000116aa\U00011700-\U0001171a\U00011800-\U0001182b\U000118a0-\U000118df\U000118ff\U00011a00\U00011a0b-\U00011a32\U00011a3a\U00011a50\U00011a5c-\U00011a83\U00011a86-\U00011a89\U00011a9d\U00011ac0-\U00011af8\U00011c00-\U00011c08\U00011c0a-\U00011c2e\U00011c40\U00011c72-\U00011c8f\U00011d00-\U00011d06\U00011d08-\U00011d09\U00011d0b-\U00011d30\U00011d46\U00011d60-\U00011d65\U00011d67-\U00011d68\U00011d6a-\U00011d89\U00011d98\U00011ee0-\U00011ef2\U00012000-\U00012399\U00012400-\U0001246e\U00012480-\U00012543\U00013000-\U0001342e\U00014400-\U00014646\U00016800-\U00016a38\U00016a40-\U00016a5e\U00016ad0-\U00016aed\U00016b00-\U00016b2f\U00016b40-\U00016b43\U00016b63-\U00016b77\U00016b7d-\U00016b8f\U00016e40-\U00016e7f\U00016f00-\U00016f44\U00016f50\U00016f93-\U00016f9f\U00016fe0-\U00016fe1\U00017000-\U000187f1\U00018800-\U00018af2\U0001b000-\U0001b11e\U0001b170-\U0001b2fb\U0001bc00-\U0001bc6a\U0001bc70-\U0001bc7c\U0001bc80-\U0001bc88\U0001bc90-\U0001bc99\U0001d400-\U0001d454\U0001d456-\U0001d49c\U0001d49e-\U0001d49f\U0001d4a2\U0001d4a5-\U0001d4a6\U0001d4a9-\U0001d4ac\U0001d4ae-\U0001d4b9\U0001d4bb\U0001d4bd-\U0001d4c3\U0001d4c5-\U0001d505\U0001d507-\U0001d50a\U0001d50d-\U0001d514\U0001d516-\U0001d51c\U0001d51e-\U0001d539\U0001d53b-\U0001d53e\U0001d540-\U0001d544\U0001d546\U0001d54a-\U0001d550\U0001d552-\U0001d6a5\U0001d6a8-\U0001d6c0\U0001d6c2-\U0001d6da\U0001d6dc-\U0001d6fa\U0001d6fc-\U0001d714\U0001d716-\U0001d734\U0001d736-\U0001d74e\U0001d750-\U0001d76e\U0001d770-\U0001d788\U0001d78a-\U0001d7a8\U0001d7aa-\U0001d7c2\U0001d7c4-\U0001d7cb\U0001e800-\U0001e8c4\U0001e900-\U0001e943\U0001ee00-\U0001ee03\U0001ee05-\U0001ee1f\U0001ee21-\U0001ee22\U0001ee24\U0001ee27\U0001ee29-\U0001ee32\U0001ee34-\U0001ee37\U0001ee39\U0001ee3b\U0001ee42\U0001ee47\U0001ee49\U0001ee4b\U0001ee4d-\U0001ee4f\U0001ee51-\U0001ee52\U0001ee54\U0001ee57\U0001ee59\U0001ee5b\U0001ee5d\U0001ee5f\U0001ee61-\U0001ee62\U0001ee64\U0001ee67-\U0001ee6a\U0001ee6c-\U0001ee72\U0001ee74-\U0001ee77\U0001ee79-\U0001ee7c\U0001ee7e\U0001ee80-\U0001ee89\U0001ee8b-\U0001ee9b\U0001eea1-\U0001eea3\U0001eea5-\U0001eea9\U0001eeab-\U0001eebb\U00020000-\U0002a6d6\U0002a700-\U0002b734\U0002b740-\U0002b81d\U0002b820-\U0002cea1\U0002ceb0-\U0002ebe0\U0002f800-\U0002fa1d'
77
+
78
+ cats = ['Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu', 'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf', 'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs']
79
+
80
+ # Generated from unidata 11.0.0
81
+
82
+ def combine(*args):
83
+ return ''.join(globals()[cat] for cat in args)
84
+
85
+
86
+ def allexcept(*args):
87
+ newcats = cats[:]
88
+ for arg in args:
89
+ newcats.remove(arg)
90
+ return ''.join(globals()[cat] for cat in newcats)
91
+
92
+
93
+ def _handle_runs(char_list): # pragma: no cover
94
+ buf = []
95
+ for c in char_list:
96
+ if len(c) == 1:
97
+ if buf and buf[-1][1] == chr(ord(c)-1):
98
+ buf[-1] = (buf[-1][0], c)
99
+ else:
100
+ buf.append((c, c))
101
+ else:
102
+ buf.append((c, c))
103
+ for a, b in buf:
104
+ if a == b:
105
+ yield a
106
+ else:
107
+ yield f'{a}-{b}'
108
+
109
+
110
+ if __name__ == '__main__': # pragma: no cover
111
+ import unicodedata
112
+
113
+ categories = {'xid_start': [], 'xid_continue': []}
114
+
115
+ with open(__file__, encoding='utf-8') as fp:
116
+ content = fp.read()
117
+
118
+ header = content[:content.find('Cc =')]
119
+ footer = content[content.find("def combine("):]
120
+
121
+ for code in range(0x110000):
122
+ c = chr(code)
123
+ cat = unicodedata.category(c)
124
+ if ord(c) == 0xdc00:
125
+ # Hack to avoid combining this combining with the preceding high
126
+ # surrogate, 0xdbff, when doing a repr.
127
+ c = '\\' + c
128
+ elif ord(c) in (0x2d, 0x5b, 0x5c, 0x5d, 0x5e):
129
+ # Escape regex metachars.
130
+ c = '\\' + c
131
+ categories.setdefault(cat, []).append(c)
132
+ # XID_START and XID_CONTINUE are special categories used for matching
133
+ # identifiers in Python 3.
134
+ if c.isidentifier():
135
+ categories['xid_start'].append(c)
136
+ if ('a' + c).isidentifier():
137
+ categories['xid_continue'].append(c)
138
+
139
+ with open(__file__, 'w', encoding='utf-8') as fp:
140
+ fp.write(header)
141
+
142
+ for cat in sorted(categories):
143
+ val = ''.join(_handle_runs(categories[cat]))
144
+ fp.write(f'{cat} = {val!a}\n\n')
145
+
146
+ cats = sorted(categories)
147
+ cats.remove('xid_start')
148
+ cats.remove('xid_continue')
149
+ fp.write(f'cats = {cats!r}\n\n')
150
+
151
+ fp.write(f'# Generated from unidata {unicodedata.unidata_version}\n\n')
152
+
153
+ fp.write(footer)
lib/python3.12/site-packages/pygments/util.py ADDED
@@ -0,0 +1,324 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ pygments.util
3
+ ~~~~~~~~~~~~~
4
+
5
+ Utility functions.
6
+
7
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8
+ :license: BSD, see LICENSE for details.
9
+ """
10
+
11
+ import re
12
+ from io import TextIOWrapper
13
+
14
+
15
+ split_path_re = re.compile(r'[/\\ ]')
16
+ doctype_lookup_re = re.compile(r'''
17
+ <!DOCTYPE\s+(
18
+ [a-zA-Z_][a-zA-Z0-9]*
19
+ (?: \s+ # optional in HTML5
20
+ [a-zA-Z_][a-zA-Z0-9]*\s+
21
+ "[^"]*")?
22
+ )
23
+ [^>]*>
24
+ ''', re.DOTALL | re.MULTILINE | re.VERBOSE)
25
+ tag_re = re.compile(r'<(.+?)(\s.*?)?>.*?</.+?>',
26
+ re.IGNORECASE | re.DOTALL | re.MULTILINE)
27
+ xml_decl_re = re.compile(r'\s*<\?xml[^>]*\?>', re.I)
28
+
29
+
30
+ class ClassNotFound(ValueError):
31
+ """Raised if one of the lookup functions didn't find a matching class."""
32
+
33
+
34
+ class OptionError(Exception):
35
+ """
36
+ This exception will be raised by all option processing functions if
37
+ the type or value of the argument is not correct.
38
+ """
39
+
40
+ def get_choice_opt(options, optname, allowed, default=None, normcase=False):
41
+ """
42
+ If the key `optname` from the dictionary is not in the sequence
43
+ `allowed`, raise an error, otherwise return it.
44
+ """
45
+ string = options.get(optname, default)
46
+ if normcase:
47
+ string = string.lower()
48
+ if string not in allowed:
49
+ raise OptionError('Value for option {} must be one of {}'.format(optname, ', '.join(map(str, allowed))))
50
+ return string
51
+
52
+
53
+ def get_bool_opt(options, optname, default=None):
54
+ """
55
+ Intuitively, this is `options.get(optname, default)`, but restricted to
56
+ Boolean value. The Booleans can be represented as string, in order to accept
57
+ Boolean value from the command line arguments. If the key `optname` is
58
+ present in the dictionary `options` and is not associated with a Boolean,
59
+ raise an `OptionError`. If it is absent, `default` is returned instead.
60
+
61
+ The valid string values for ``True`` are ``1``, ``yes``, ``true`` and
62
+ ``on``, the ones for ``False`` are ``0``, ``no``, ``false`` and ``off``
63
+ (matched case-insensitively).
64
+ """
65
+ string = options.get(optname, default)
66
+ if isinstance(string, bool):
67
+ return string
68
+ elif isinstance(string, int):
69
+ return bool(string)
70
+ elif not isinstance(string, str):
71
+ raise OptionError(f'Invalid type {string!r} for option {optname}; use '
72
+ '1/0, yes/no, true/false, on/off')
73
+ elif string.lower() in ('1', 'yes', 'true', 'on'):
74
+ return True
75
+ elif string.lower() in ('0', 'no', 'false', 'off'):
76
+ return False
77
+ else:
78
+ raise OptionError(f'Invalid value {string!r} for option {optname}; use '
79
+ '1/0, yes/no, true/false, on/off')
80
+
81
+
82
+ def get_int_opt(options, optname, default=None):
83
+ """As :func:`get_bool_opt`, but interpret the value as an integer."""
84
+ string = options.get(optname, default)
85
+ try:
86
+ return int(string)
87
+ except TypeError:
88
+ raise OptionError(f'Invalid type {string!r} for option {optname}; you '
89
+ 'must give an integer value')
90
+ except ValueError:
91
+ raise OptionError(f'Invalid value {string!r} for option {optname}; you '
92
+ 'must give an integer value')
93
+
94
+ def get_list_opt(options, optname, default=None):
95
+ """
96
+ If the key `optname` from the dictionary `options` is a string,
97
+ split it at whitespace and return it. If it is already a list
98
+ or a tuple, it is returned as a list.
99
+ """
100
+ val = options.get(optname, default)
101
+ if isinstance(val, str):
102
+ return val.split()
103
+ elif isinstance(val, (list, tuple)):
104
+ return list(val)
105
+ else:
106
+ raise OptionError(f'Invalid type {val!r} for option {optname}; you '
107
+ 'must give a list value')
108
+
109
+
110
+ def docstring_headline(obj):
111
+ if not obj.__doc__:
112
+ return ''
113
+ res = []
114
+ for line in obj.__doc__.strip().splitlines():
115
+ if line.strip():
116
+ res.append(" " + line.strip())
117
+ else:
118
+ break
119
+ return ''.join(res).lstrip()
120
+
121
+
122
+ def make_analysator(f):
123
+ """Return a static text analyser function that returns float values."""
124
+ def text_analyse(text):
125
+ try:
126
+ rv = f(text)
127
+ except Exception:
128
+ return 0.0
129
+ if not rv:
130
+ return 0.0
131
+ try:
132
+ return min(1.0, max(0.0, float(rv)))
133
+ except (ValueError, TypeError):
134
+ return 0.0
135
+ text_analyse.__doc__ = f.__doc__
136
+ return staticmethod(text_analyse)
137
+
138
+
139
+ def shebang_matches(text, regex):
140
+ r"""Check if the given regular expression matches the last part of the
141
+ shebang if one exists.
142
+
143
+ >>> from pygments.util import shebang_matches
144
+ >>> shebang_matches('#!/usr/bin/env python', r'python(2\.\d)?')
145
+ True
146
+ >>> shebang_matches('#!/usr/bin/python2.4', r'python(2\.\d)?')
147
+ True
148
+ >>> shebang_matches('#!/usr/bin/python-ruby', r'python(2\.\d)?')
149
+ False
150
+ >>> shebang_matches('#!/usr/bin/python/ruby', r'python(2\.\d)?')
151
+ False
152
+ >>> shebang_matches('#!/usr/bin/startsomethingwith python',
153
+ ... r'python(2\.\d)?')
154
+ True
155
+
156
+ It also checks for common windows executable file extensions::
157
+
158
+ >>> shebang_matches('#!C:\\Python2.4\\Python.exe', r'python(2\.\d)?')
159
+ True
160
+
161
+ Parameters (``'-f'`` or ``'--foo'`` are ignored so ``'perl'`` does
162
+ the same as ``'perl -e'``)
163
+
164
+ Note that this method automatically searches the whole string (eg:
165
+ the regular expression is wrapped in ``'^$'``)
166
+ """
167
+ index = text.find('\n')
168
+ if index >= 0:
169
+ first_line = text[:index].lower()
170
+ else:
171
+ first_line = text.lower()
172
+ if first_line.startswith('#!'):
173
+ try:
174
+ found = [x for x in split_path_re.split(first_line[2:].strip())
175
+ if x and not x.startswith('-')][-1]
176
+ except IndexError:
177
+ return False
178
+ regex = re.compile(rf'^{regex}(\.(exe|cmd|bat|bin))?$', re.IGNORECASE)
179
+ if regex.search(found) is not None:
180
+ return True
181
+ return False
182
+
183
+
184
+ def doctype_matches(text, regex):
185
+ """Check if the doctype matches a regular expression (if present).
186
+
187
+ Note that this method only checks the first part of a DOCTYPE.
188
+ eg: 'html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'
189
+ """
190
+ m = doctype_lookup_re.search(text)
191
+ if m is None:
192
+ return False
193
+ doctype = m.group(1)
194
+ return re.compile(regex, re.I).match(doctype.strip()) is not None
195
+
196
+
197
+ def html_doctype_matches(text):
198
+ """Check if the file looks like it has a html doctype."""
199
+ return doctype_matches(text, r'html')
200
+
201
+
202
+ _looks_like_xml_cache = {}
203
+
204
+
205
+ def looks_like_xml(text):
206
+ """Check if a doctype exists or if we have some tags."""
207
+ if xml_decl_re.match(text):
208
+ return True
209
+ key = hash(text)
210
+ try:
211
+ return _looks_like_xml_cache[key]
212
+ except KeyError:
213
+ m = doctype_lookup_re.search(text)
214
+ if m is not None:
215
+ return True
216
+ rv = tag_re.search(text[:1000]) is not None
217
+ _looks_like_xml_cache[key] = rv
218
+ return rv
219
+
220
+
221
+ def surrogatepair(c):
222
+ """Given a unicode character code with length greater than 16 bits,
223
+ return the two 16 bit surrogate pair.
224
+ """
225
+ # From example D28 of:
226
+ # http://www.unicode.org/book/ch03.pdf
227
+ return (0xd7c0 + (c >> 10), (0xdc00 + (c & 0x3ff)))
228
+
229
+
230
+ def format_lines(var_name, seq, raw=False, indent_level=0):
231
+ """Formats a sequence of strings for output."""
232
+ lines = []
233
+ base_indent = ' ' * indent_level * 4
234
+ inner_indent = ' ' * (indent_level + 1) * 4
235
+ lines.append(base_indent + var_name + ' = (')
236
+ if raw:
237
+ # These should be preformatted reprs of, say, tuples.
238
+ for i in seq:
239
+ lines.append(inner_indent + i + ',')
240
+ else:
241
+ for i in seq:
242
+ # Force use of single quotes
243
+ r = repr(i + '"')
244
+ lines.append(inner_indent + r[:-2] + r[-1] + ',')
245
+ lines.append(base_indent + ')')
246
+ return '\n'.join(lines)
247
+
248
+
249
+ def duplicates_removed(it, already_seen=()):
250
+ """
251
+ Returns a list with duplicates removed from the iterable `it`.
252
+
253
+ Order is preserved.
254
+ """
255
+ lst = []
256
+ seen = set()
257
+ for i in it:
258
+ if i in seen or i in already_seen:
259
+ continue
260
+ lst.append(i)
261
+ seen.add(i)
262
+ return lst
263
+
264
+
265
+ class Future:
266
+ """Generic class to defer some work.
267
+
268
+ Handled specially in RegexLexerMeta, to support regex string construction at
269
+ first use.
270
+ """
271
+ def get(self):
272
+ raise NotImplementedError
273
+
274
+
275
+ def guess_decode(text):
276
+ """Decode *text* with guessed encoding.
277
+
278
+ First try UTF-8; this should fail for non-UTF-8 encodings.
279
+ Then try the preferred locale encoding.
280
+ Fall back to latin-1, which always works.
281
+ """
282
+ try:
283
+ text = text.decode('utf-8')
284
+ return text, 'utf-8'
285
+ except UnicodeDecodeError:
286
+ try:
287
+ import locale
288
+ prefencoding = locale.getpreferredencoding()
289
+ text = text.decode()
290
+ return text, prefencoding
291
+ except (UnicodeDecodeError, LookupError):
292
+ text = text.decode('latin1')
293
+ return text, 'latin1'
294
+
295
+
296
+ def guess_decode_from_terminal(text, term):
297
+ """Decode *text* coming from terminal *term*.
298
+
299
+ First try the terminal encoding, if given.
300
+ Then try UTF-8. Then try the preferred locale encoding.
301
+ Fall back to latin-1, which always works.
302
+ """
303
+ if getattr(term, 'encoding', None):
304
+ try:
305
+ text = text.decode(term.encoding)
306
+ except UnicodeDecodeError:
307
+ pass
308
+ else:
309
+ return text, term.encoding
310
+ return guess_decode(text)
311
+
312
+
313
+ def terminal_encoding(term):
314
+ """Return our best guess of encoding for the given *term*."""
315
+ if getattr(term, 'encoding', None):
316
+ return term.encoding
317
+ import locale
318
+ return locale.getpreferredencoding()
319
+
320
+
321
+ class UnclosingTextIOWrapper(TextIOWrapper):
322
+ # Don't close underlying buffer on destruction.
323
+ def close(self):
324
+ self.flush()