pygments-citry 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,42 @@
1
+ """
2
+ pygments-citry: a Pygments lexer for Citry components.
3
+
4
+ Importing this package registers the ``citry`` lexer with Pygments, so
5
+ ``get_lexer_by_name("citry")`` resolves even in an environment where the plugin
6
+ entry point was not picked up (for example an editable checkout whose plugin
7
+ metadata is not written). For an installed package, the ``pygments.lexers``
8
+ entry point in ``pyproject.toml`` is the primary registration and needs no
9
+ import.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from pygments.lexers import LEXERS
15
+
16
+ from pygments_citry.citry_html import CitryHtmlLexer
17
+ from pygments_citry.lexers import CitryPythonLexer
18
+
19
+ __all__ = ["CitryHtmlLexer", "CitryPythonLexer"]
20
+
21
+ # Register in Pygments' builtin lexer table. get_lexer_by_name scans this table
22
+ # before the entry-point plugins, so an explicit `import pygments_citry` becomes
23
+ # a deterministic loader. Each tuple is (module, name, aliases, filenames,
24
+ # mimetypes); _load_lexers imports the module and finds the class via __all__.
25
+ #
26
+ # `citry` is the full component lexer (Python + embedded template/js/css);
27
+ # `citry-html` is the template lexer alone, for a fence that shows only a
28
+ # template (`<c-*>` tags, `{{ }}`, `{# #}`) with no surrounding Python.
29
+ LEXERS["CitryPythonLexer"] = (
30
+ "pygments_citry",
31
+ "Citry Python",
32
+ ("citry",),
33
+ (),
34
+ (),
35
+ )
36
+ LEXERS["CitryHtmlLexer"] = (
37
+ "pygments_citry",
38
+ "Citry HTML",
39
+ ("citry-html",),
40
+ (),
41
+ (),
42
+ )
@@ -0,0 +1,195 @@
1
+ """
2
+ The lexer for the HTML that lives inside a Citry component's ``template``.
3
+
4
+ Citry templates are HTML with a few additions: ``<c-*>`` component and
5
+ control-flow tags, ``c-*`` dynamic attributes whose values are Python
6
+ expressions, ``{{ python }}`` interpolation, ``{# comment #}``, and a verbatim
7
+ ``<c-raw>`` element. This lexer extends Pygments' plain ``HtmlLexer`` with those,
8
+ so a Citry template highlights as HTML with the Citry bits called out, and the
9
+ Python inside ``{{ }}`` and ``c-*`` values is handed to the Python lexer.
10
+
11
+ It is registered as ``citry-html``, both on its own (for a fenced block that
12
+ shows only a template) and embedded by ``CitryPythonLexer`` to highlight the
13
+ ``template`` string of a component.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from typing import TYPE_CHECKING, Any, ClassVar
19
+
20
+ from pygments.lexer import ExtendedRegexLexer, bygroups, using
21
+ from pygments.lexers.html import HtmlLexer
22
+ from pygments.lexers.javascript import JavascriptLexer
23
+ from pygments.lexers.python import PythonLexer
24
+ from pygments.token import Comment, Name, Operator, Punctuation, Text
25
+
26
+ if TYPE_CHECKING:
27
+ import re
28
+ from collections.abc import Iterator
29
+
30
+ # An exact Citry tag name ends where the template grammar's tag name ends. The
31
+ # explicit lookahead stops a built-in prefix such as ``c-slot`` from stealing
32
+ # the start of a user component name such as ``c-slot-panel``.
33
+ _TAG_END = r"(?=\s|/?>|\{#)"
34
+
35
+ # One Python lexer, reused for the bodies of {{ ... }} interpolations.
36
+ _PYTHON = PythonLexer()
37
+
38
+
39
+ def _interpolation(_lexer: Any, match: re.Match[str], ctx: Any) -> Iterator[tuple[int, Any, str]]:
40
+ """
41
+ Tokenise a ``{{ ... }}`` interpolation, handing the expression to Python.
42
+
43
+ The closing ``}}`` is found by scanning for one at brace depth zero and
44
+ skipping Python string literals along the way, so a ``}}`` inside a string
45
+ (``{{ "}}" }}``) or a nested dict literal (``{{ {"a": {1: 2}} }}``) does not
46
+ end the block early. This mirrors how the engine's grammar finds the
47
+ boundary; a plain regex cannot, because it cannot count nesting.
48
+
49
+ Surrounding whitespace stays plain text and only the expression in the
50
+ middle is highlighted, matching how the rest of the lexer treats a value.
51
+ """
52
+ text = match.string
53
+ yield match.start(), Punctuation, "{{"
54
+ start = match.end()
55
+ length = len(text)
56
+ i = start
57
+ depth = 0
58
+ close = None
59
+ while i < length:
60
+ char = text[i]
61
+ if char in "\"'": # skip a Python string literal, honouring backslash escapes
62
+ quote = char
63
+ i += 1
64
+ while i < length:
65
+ if text[i] == "\\":
66
+ i += 2
67
+ continue
68
+ if text[i] == quote:
69
+ i += 1
70
+ break
71
+ i += 1
72
+ continue
73
+ if char == "{":
74
+ depth += 1
75
+ elif char == "}":
76
+ if depth:
77
+ depth -= 1
78
+ elif i + 1 < length and text[i + 1] == "}":
79
+ close = i
80
+ break
81
+ i += 1
82
+
83
+ body = text[start : close if close is not None else length]
84
+ lead = body[: len(body) - len(body.lstrip())]
85
+ expr = body.strip()
86
+ if lead:
87
+ yield start, Text, lead
88
+ for offset, token, value in _PYTHON.get_tokens_unprocessed(expr):
89
+ yield start + len(lead) + offset, token, value
90
+ trail = body[len(lead) + len(expr) :]
91
+ if trail:
92
+ yield start + len(lead) + len(expr), Text, trail
93
+
94
+ if close is not None:
95
+ yield close, Punctuation, "}}"
96
+ ctx.pos = close + 2
97
+ else:
98
+ ctx.pos = length
99
+
100
+
101
+ # The value of a c-* (or built-in) attribute is a Python expression, quoted or bare.
102
+ _PY_ATTR_STATE = "python-attr"
103
+ _JS_ATTR_STATE = "javascript-attr"
104
+ # Attribute rules shared by ordinary and built-in tags: framework passthrough
105
+ # names plain HtmlLexer cannot tokenise (@click, [style], (click)), ordinary
106
+ # attributes (covers :class and v-model, which HtmlLexer handles), and the close.
107
+ _COMMON_ATTR_RULES = [
108
+ (r"([@\[(][\w:@.()\[\]-]*)(\s*)(=)(\s*)", bygroups(Name.Attribute, Text, Operator, Text), "attr"),
109
+ (r"[@\[(][\w:@.()\[\]-]*", Name.Attribute),
110
+ (r"([\w:-]+)(\s*)(=)(\s*)", bygroups(Name.Attribute, Text, Operator, Text), "attr"),
111
+ (r"[\w:-]+", Name.Attribute),
112
+ (r"(/?)(\s*)(>)", bygroups(Punctuation, Text, Punctuation), "#pop"),
113
+ ]
114
+ _WS_RULE = (r"\s+", Text)
115
+ # `$c-props` is evaluated by the client runtime, so its value is JavaScript.
116
+ _CLIENT_PROPS_ATTR_RULE = (
117
+ r"(\$c-props)(\s*)(=)(\s*)",
118
+ bygroups(Name.Attribute, Text, Operator, Text),
119
+ _JS_ATTR_STATE,
120
+ )
121
+ # A c-* dynamic attribute: the value is a Python expression.
122
+ _C_ATTR_RULE = (r"(c-[\w$:@.-]*)(\s*)(=)(\s*)", bygroups(Name.Attribute, Text, Operator, Text), _PY_ATTR_STATE)
123
+ # Structural control-flow tags carry Python-valued attributes that are not
124
+ # c-*-prefixed. These rules live in tag-specific states because the same names
125
+ # on other elements are ordinary static HTML attributes.
126
+ _COND_ATTR_RULE = (r"(cond)(\s*)(=)(\s*)", bygroups(Name.Attribute, Text, Operator, Text), _PY_ATTR_STATE)
127
+ _EACH_ATTR_RULE = (r"(each)(\s*)(=)(\s*)", bygroups(Name.Attribute, Text, Operator, Text), _PY_ATTR_STATE)
128
+
129
+
130
+ class CitryHtmlLexer(ExtendedRegexLexer, HtmlLexer):
131
+ """Highlights the HTML (plus Citry tags and interpolation) of a Citry template."""
132
+
133
+ name = "Citry HTML"
134
+ aliases: ClassVar[list[str]] = ["citry-html"]
135
+
136
+ tokens: ClassVar[dict[str, Any]] = {
137
+ **HtmlLexer.tokens,
138
+ "root": [
139
+ # {# template comment #}
140
+ (r"\{#.*?#\}", Comment),
141
+ # {{ python-expression }}: a callback scans to the balanced }}
142
+ (r"\{\{", _interpolation),
143
+ # a lone { that is not part of {{ or {#
144
+ (r"\{", Text),
145
+ # <c-raw> ... </c-raw>: the body is verbatim (not interpreted)
146
+ (
147
+ r"(<)(\s*)(c-raw)" + _TAG_END,
148
+ bygroups(Punctuation, Text, Name.Tag),
149
+ ("raw-content", "tag"),
150
+ ),
151
+ # Only the structural tags with unprefixed Python attributes need
152
+ # special states. Every other c-* name falls through to HtmlLexer.
153
+ (
154
+ r"(</?)(\s*)(c-(?:if|elif))" + _TAG_END,
155
+ bygroups(Punctuation, Text, Name.Tag),
156
+ "condition-tag",
157
+ ),
158
+ (
159
+ r"(</?)(\s*)(c-for)" + _TAG_END,
160
+ bygroups(Punctuation, Text, Name.Tag),
161
+ "for-tag",
162
+ ),
163
+ # ordinary text, stopped at { so the interpolation/comment rules fire;
164
+ # everything after this is HtmlLexer's own root (its [^<&]+ text rule,
165
+ # which does not stop at {, is dropped by the [1:] slice)
166
+ (r"[^<&{]+", Text),
167
+ *HtmlLexer.tokens["root"][1:],
168
+ ],
169
+ # An ordinary element's attributes.
170
+ "tag": [_WS_RULE, _CLIENT_PROPS_ATTR_RULE, _C_ATTR_RULE, *_COMMON_ATTR_RULES],
171
+ "condition-tag": [_WS_RULE, _CLIENT_PROPS_ATTR_RULE, _C_ATTR_RULE, _COND_ATTR_RULE, *_COMMON_ATTR_RULES],
172
+ "for-tag": [_WS_RULE, _CLIENT_PROPS_ATTR_RULE, _C_ATTR_RULE, _EACH_ATTR_RULE, *_COMMON_ATTR_RULES],
173
+ # The value of a c-* (or built-in) attribute: a Python expression.
174
+ "python-attr": [
175
+ (r'(")((?:[^"\\]|\\.)*)(")', bygroups(Punctuation, using(PythonLexer), Punctuation), "#pop"),
176
+ (r"(')((?:[^'\\]|\\.)*)(')", bygroups(Punctuation, using(PythonLexer), Punctuation), "#pop"),
177
+ (r"[^\s>]+", using(PythonLexer), "#pop"),
178
+ ],
179
+ # The direct client props value is an Alpine/JavaScript expression.
180
+ "javascript-attr": [
181
+ (r'(")((?:[^"\\]|\\.)*)(")', bygroups(Punctuation, using(JavascriptLexer), Punctuation), "#pop"),
182
+ (r"(')((?:[^'\\]|\\.)*)(')", bygroups(Punctuation, using(JavascriptLexer), Punctuation), "#pop"),
183
+ (r"[^\s>]+", using(JavascriptLexer), "#pop"),
184
+ ],
185
+ # The verbatim body of <c-raw>...</c-raw>: plain text until the close tag.
186
+ "raw-content": [
187
+ (
188
+ r"(<)(\s*)(/)(\s*)(c-raw)(\s*)(>)",
189
+ bygroups(Punctuation, Text, Punctuation, Text, Name.Tag, Text, Punctuation),
190
+ "#pop",
191
+ ),
192
+ (r"[^<]+", Text),
193
+ (r"<", Text),
194
+ ],
195
+ }
@@ -0,0 +1,79 @@
1
+ """
2
+ The ``citry`` lexer: Python, with the embedded ``template``/``js``/``css`` highlighted.
3
+
4
+ ``CitryPythonLexer`` behaves like Pygments' ``PythonLexer`` but recognises the
5
+ three multiline string attributes a Citry component uses and hands each body to
6
+ the right language:
7
+
8
+ - ``template = \"\"\"...\"\"\"`` to the Citry HTML lexer (``<c-*>`` tags, ``{{ }}``, ...),
9
+ - ``js = \"\"\"...\"\"\"`` to the JavaScript lexer,
10
+ - ``css = \"\"\"...\"\"\"`` to the CSS lexer.
11
+
12
+ The detection is deliberately simple, matching the upstream ``pygments-djc``: it
13
+ fires on any ``template``/``js``/``css`` triple-quoted assignment, even one not
14
+ on a component class. That is fine for documentation, where these names almost
15
+ always mean a component.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from typing import Any, ClassVar
21
+
22
+ from pygments.lexer import bygroups, using
23
+ from pygments.lexers.css import CssLexer
24
+ from pygments.lexers.javascript import JavascriptLexer
25
+ from pygments.lexers.python import PythonLexer
26
+ from pygments.token import Name, Operator, Punctuation, String, Text
27
+
28
+ from pygments_citry.citry_html import CitryHtmlLexer
29
+
30
+ # Matches `template = """` or the typed `template: some.Type = """` (and the ''' form).
31
+ # The nine capture groups are highlighted individually by the bygroups action below.
32
+ _CAPTURE = r'({name})(\s*)(?:(:)(\s*)([^\s=]+))?(\s*)(=)(\s*)((?:"""|\'\'\'))'
33
+
34
+ # Highlights the nine groups of _CAPTURE. Reused for all three openers, which
35
+ # differ only in the attribute name and the state they push.
36
+ _OPENER = bygroups(
37
+ Name.Variable, # the attribute name (template / js / css)
38
+ Text,
39
+ Punctuation, # the ':' of an optional type annotation
40
+ Text,
41
+ Name.Class, # the annotation type, if present
42
+ Text,
43
+ Operator, # the '='
44
+ Text,
45
+ String.Doc, # the opening triple quote
46
+ )
47
+
48
+
49
+ class CitryPythonLexer(PythonLexer):
50
+ """Lexer for Citry component code: Python plus the embedded template/js/css."""
51
+
52
+ name = "Citry Python"
53
+ aliases: ClassVar[list[str]] = ["citry"]
54
+
55
+ tokens: ClassVar[dict[str, Any]] = {
56
+ **PythonLexer.tokens,
57
+ # The three openers are prepended to Python's root so they win over its
58
+ # own string handling; each pushes a state that re-lexes the body.
59
+ "root": [
60
+ (_CAPTURE.format(name="template"), _OPENER, "template_string"),
61
+ (_CAPTURE.format(name="js"), _OPENER, "js_string"),
62
+ (_CAPTURE.format(name="css"), _OPENER, "css_string"),
63
+ *PythonLexer.tokens["root"],
64
+ ],
65
+ # Inside a body: the closing triple quote pops (first, so it wins);
66
+ # otherwise the run up to the close is handed to the embedded lexer.
67
+ "template_string": [
68
+ (r'(?:"""|\'\'\')', String.Doc, "#pop"),
69
+ (r'((?!"""|\'\'\')(?:.|\n))+', using(CitryHtmlLexer)),
70
+ ],
71
+ "js_string": [
72
+ (r'(?:"""|\'\'\')', String.Doc, "#pop"),
73
+ (r'((?!"""|\'\'\')(?:.|\n))+', using(JavascriptLexer)),
74
+ ],
75
+ "css_string": [
76
+ (r'(?:"""|\'\'\')', String.Doc, "#pop"),
77
+ (r'((?!"""|\'\'\')(?:.|\n))+', using(CssLexer)),
78
+ ],
79
+ }
File without changes
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.4
2
+ Name: pygments-citry
3
+ Version: 0.1.0
4
+ Summary: Pygments lexer for Citry components: highlights the HTML, JS, and CSS embedded in a component's template/js/css strings
5
+ Author-email: Juro Oravec <juraj.oravec.josefson@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://citry.dev
8
+ Project-URL: Repository, https://github.com/citry-dev/citry
9
+ Project-URL: Changelog, https://github.com/citry-dev/citry/blob/main/packages/py/pygments_citry/CHANGELOG.md
10
+ Project-URL: Issues, https://github.com/citry-dev/citry/issues
11
+ Keywords: citry,pygments,lexer,syntax highlighting,components,html
12
+ Classifier: Environment :: Plugins
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Text Processing :: Markup :: HTML
23
+ Classifier: Topic :: Software Development :: Documentation
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: <4.0,>=3.10
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: pygments>=2.15
29
+ Dynamic: license-file
30
+
31
+ # pygments-citry
32
+
33
+ A [Pygments](https://pygments.org/) lexer for [Citry](https://citry.dev)
34
+ components. It highlights a component the way an editor would: the Python class,
35
+ plus the HTML, JavaScript, and CSS embedded in its `template`, `js`, and `css`
36
+ string attributes, each in its own language.
37
+
38
+ Without it, a Citry component in a ` ```python ` block renders the template,
39
+ JS script, and CSS stylesheet as flat string literals. With it, a ` ```citry `
40
+ block colours the `<c-*>` tags, the `{{ ... }}` interpolation, the embedded
41
+ stylesheet, and the embedded script.
42
+
43
+ ## Install
44
+
45
+ ```bash
46
+ pip install pygments-citry
47
+ ```
48
+
49
+ The package registers a `citry` lexer as a Pygments plugin, so any tool that
50
+ resolves lexers by name picks it up once it is installed.
51
+
52
+ ## Use it
53
+
54
+ On the command line:
55
+
56
+ ```bash
57
+ pygmentize -l citry my_component.py
58
+ ```
59
+
60
+ In Python:
61
+
62
+ ```python
63
+ from pygments import highlight
64
+ from pygments.formatters import HtmlFormatter
65
+ from pygments.lexers import get_lexer_by_name
66
+
67
+ lexer = get_lexer_by_name("citry")
68
+ html = highlight(source, lexer, HtmlFormatter())
69
+ ```
70
+
71
+ In a Markdown site (mkdocs with `pymdownx.highlight` / `pymdownx.superfences`,
72
+ or any python-markdown setup that resolves Pygments lexers by name), tag the
73
+ fence with `citry`:
74
+
75
+ ````markdown
76
+ ```citry
77
+ from citry import Component
78
+
79
+ class Welcome(Component):
80
+ template = """
81
+ <div class="card">
82
+ <h1>{{ title }}</h1>
83
+ <p c-if="count">You have {{ count }} new messages.</p>
84
+ </div>
85
+ """
86
+ ```
87
+ ````
88
+
89
+ No superfences `custom_fences` entry is needed: once the package is installed,
90
+ `citry` resolves like any other Pygments lexer.
91
+
92
+ ## What it highlights
93
+
94
+ A `citry` block is highlighted as Python, and the following Citry constructs
95
+ inside the `template` / `js` / `css` attributes are highlighted in their own
96
+ language:
97
+
98
+ - The HTML in `template`, including the `<c-*>` component and control-flow tags
99
+ (the built-ins `c-if`, `c-for`, `c-slot`, `<c-raw>`, and so on) and `c-*`
100
+ dynamic attributes.
101
+ - `{{ ... }}` interpolation, whose body is a Python expression.
102
+ - `{# ... #}` template comments.
103
+ - The JavaScript in `js` and the CSS in `css`.
104
+
105
+ The `<c-raw>...</c-raw>` element is treated as verbatim text, matching the
106
+ engine: `{{ }}` and tags inside it are not interpreted.
107
+
108
+ ## Template-only blocks: `citry-html`
109
+
110
+ For a fenced block that shows only a template, with no surrounding Python (just
111
+ `<c-*>` tags, `{{ ... }}`, and `{# ... #}`), tag it `citry-html`:
112
+
113
+ ````markdown
114
+ ```citry-html
115
+ <c-for each="item in items">
116
+ <li c-if="item.visible">{{ item.label }}</li>
117
+ </c-for>
118
+ ```
119
+ ````
120
+
121
+ `citry` expects full component code (Python with embedded strings), so a bare
122
+ template belongs in a `citry-html` block instead.
123
+
124
+ ## License
125
+
126
+ MIT. Part of the [Citry](https://github.com/citry-dev/citry) project.
@@ -0,0 +1,10 @@
1
+ pygments_citry/__init__.py,sha256=jqjp95MlE7Rwt2TGvSS3ouWKlzbS3W0mBoEcqRuYh9U,1432
2
+ pygments_citry/citry_html.py,sha256=qSxLRwqAfN5NKxBbtanxzqzZFdqXd0wiqK4Tky7XqjQ,8357
3
+ pygments_citry/lexers.py,sha256=IU2oGLbDY9WWYTI1GK6p5HCV3cySGzrfooUbjq4wAdU,3130
4
+ pygments_citry/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ pygments_citry-0.1.0.dist-info/licenses/LICENSE,sha256=DWFXareDLD3iWrd8m9GgkBR6iIZC8AzSoaI35Rkr8y8,1063
6
+ pygments_citry-0.1.0.dist-info/METADATA,sha256=ssqsww7vE06fBgC4B27cHdpNRNmU_hOa_LfKhEFCeGc,4153
7
+ pygments_citry-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
8
+ pygments_citry-0.1.0.dist-info/entry_points.txt,sha256=_-eEsJ8zqulB42wm3CzbVZWySO-Zr-gVbtMeMChwjIQ,119
9
+ pygments_citry-0.1.0.dist-info/top_level.txt,sha256=AFAUv1A1S3yVGiOWkqgLJabSJRZt_CjOax56ueluKI4,15
10
+ pygments_citry-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [pygments.lexers]
2
+ citry = pygments_citry.lexers:CitryPythonLexer
3
+ citry-html = pygments_citry.citry_html:CitryHtmlLexer
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 citry
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1 @@
1
+ pygments_citry