Skip to content

Commit 6d7330b

Browse files
authored
Merge pull request #1 from sudo-jarvis/create-lexer
Create the Json Schema lexer using pygments
2 parents 4ac2d45 + 1c300be commit 6d7330b

File tree

6 files changed

+340
-4
lines changed

6 files changed

+340
-4
lines changed

.gitignore

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dirhtml/
14+
dist/
15+
downloads/
16+
eggs/
17+
.eggs/
18+
lib/
19+
lib64/
20+
parts/
21+
sdist/
22+
var/
23+
wheels/
24+
share/python-wheels/
25+
*.egg-info/
26+
.installed.cfg
27+
*.egg
28+
MANIFEST
29+
30+
# PyInstaller
31+
# Usually these files are written by a python script from a template
32+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
33+
*.manifest
34+
*.spec
35+
36+
# Installer logs
37+
pip-log.txt
38+
pip-delete-this-directory.txt
39+
40+
# Unit test / coverage reports
41+
htmlcov/
42+
.tox/
43+
.nox/
44+
.coverage
45+
.coverage.*
46+
.cache
47+
nosetests.xml
48+
coverage.xml
49+
*.cover
50+
*.py,cover
51+
.hypothesis/
52+
.pytest_cache/
53+
cover/
54+
55+
# Translations
56+
*.mo
57+
*.pot
58+
59+
# Django stuff:
60+
*.log
61+
local_settings.py
62+
db.sqlite3
63+
db.sqlite3-journal
64+
65+
# Flask stuff:
66+
instance/
67+
.webassets-cache
68+
69+
# Scrapy stuff:
70+
.scrapy
71+
72+
# Sphinx documentation
73+
docs/_build/
74+
75+
# PyBuilder
76+
.pybuilder/
77+
target/
78+
79+
# Jupyter Notebook
80+
.ipynb_checkpoints
81+
82+
# IPython
83+
profile_default/
84+
ipython_config.py
85+
86+
# pyenv
87+
# For a library or package, you might want to ignore these files since the code is
88+
# intended to run in multiple environments; otherwise, check them in:
89+
# .python-version
90+
91+
# pipenv
92+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
93+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
94+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
95+
# install all needed dependencies.
96+
#Pipfile.lock
97+
98+
# poetry
99+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
100+
# This is especially recommended for binary packages to ensure reproducibility, and is more
101+
# commonly ignored for libraries.
102+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
103+
#poetry.lock
104+
105+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
106+
__pypackages__/
107+
108+
# Celery stuff
109+
celerybeat-schedule
110+
celerybeat.pid
111+
112+
# SageMath parsed files
113+
*.sage.py
114+
115+
# Environments
116+
.env
117+
.venv
118+
env/
119+
venv/
120+
ENV/
121+
env.bak/
122+
venv.bak/
123+
124+
# Spyder project settings
125+
.spyderproject
126+
.spyproject
127+
128+
# Rope project settings
129+
.ropeproject
130+
131+
# mkdocs documentation
132+
/site
133+
134+
# mypy
135+
.mypy_cache/
136+
.dmypy.json
137+
dmypy.json
138+
139+
# Pyre type checker
140+
.pyre/
141+
142+
# pytype static type analyzer
143+
.pytype/
144+
145+
# Cython debug symbols
146+
cython_debug/
147+
148+
# Editor vomit
149+
.idea/
150+
.vscode/
151+
152+
# User defined
153+
_cache
154+
_templates

README.rst

+48-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
====================
1+
=======================
22
``jsonschema-lexer``
3-
====================
3+
=======================
44

55
|PyPI| |Pythons| |CI|
66

@@ -15,3 +15,49 @@
1515
.. |CI| image:: https://github.com/python-jsonschema/jsonschema-lexer/workflows/CI/badge.svg
1616
:alt: Build status
1717
:target: https://github.com/python-jsonschema/jsonschema-lexer/actions?query=workflow%3ACI
18+
19+
Introduction
20+
------------
21+
22+
`jsonschema-lexer` is a Python package that provides a JSON Schema lexer for syntax highlighting JSON Schema documents based on the `2020-12 dialect`.
23+
It utilizes Pygments, a syntax highlighting library, to tokenize JSON Schema documents according to the JSON Schema specification.
24+
25+
Usage
26+
-----
27+
28+
Once installed, you can use it in your Python code to highlight JSON Schema documents.
29+
30+
Here's a simple example:
31+
32+
.. code-block:: python
33+
34+
# Import the JSONSchemaLexer class from the package
35+
from jsonschema_lexer.lexer import JSONSchemaLexer
36+
37+
from rich.console import Console
38+
from rich.syntax import Syntax
39+
40+
console = Console()
41+
42+
code = """
43+
{
44+
"$schema": "https://json-schema.org/draft/2020-12/schema",
45+
"$id": "https://example.com/product.schema.json",
46+
"title": "Product",
47+
"description": "A product from Acme's catalog",
48+
"type": "object",
49+
"properties": {
50+
"productId": {
51+
"description": "The unique identifier for a product",
52+
"type": "integer"
53+
},
54+
"productName": {
55+
"description": "Name of the product",
56+
"type": "string"
57+
}
58+
}
59+
}
60+
"""
61+
62+
syntax = Syntax(code, lexer=JSONSchemaLexer(), background_color="default", word_wrap=True)
63+
console.print(syntax)

jsonschema_lexer/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""
2-
Fill me in!
2+
Provides the JSONSchema Lexer.
33
"""

jsonschema_lexer/lexer.py

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
"""
2+
Contains the main functionality of the JSONSchemaLexer.
3+
"""
4+
5+
from typing import ClassVar
6+
7+
from pygments.lexers.data import ( # type: ignore[reportMissingTypeStubs]
8+
JsonLexer,
9+
)
10+
from pygments.token import Token
11+
12+
13+
class JSONSchemaLexer(JsonLexer):
14+
"""
15+
For JSONSchema.
16+
"""
17+
18+
name = "JSON Schema Lexer"
19+
20+
data_types: ClassVar[list[str]] = [
21+
"object",
22+
"integer",
23+
"string",
24+
"number",
25+
"array",
26+
"boolean",
27+
"null",
28+
]
29+
core_keywords: ClassVar[list[str]] = [
30+
"$schema",
31+
"$id",
32+
"$ref",
33+
"$defs",
34+
"$comment",
35+
"$dynamicAnchor",
36+
"$dynamicRef",
37+
"$anchor",
38+
"$vocabulary",
39+
]
40+
applicator_keywords: ClassVar[list[str]] = [
41+
"oneOf",
42+
"allOf",
43+
"anyOf",
44+
"if",
45+
"then",
46+
"else",
47+
"not",
48+
"properties",
49+
"patternProperties",
50+
"additionalProperties",
51+
"dependentSchemas",
52+
"propertyNames",
53+
"prefixItems",
54+
"contains",
55+
"items",
56+
]
57+
meta_data_keywords: ClassVar[list[str]] = [
58+
"title",
59+
"description",
60+
"default",
61+
"deprecated",
62+
"examples",
63+
"readOnly",
64+
"writeOnly",
65+
]
66+
validation_keywords: ClassVar[list[str]] = [
67+
"type",
68+
"enum",
69+
"const",
70+
"minLength",
71+
"maxLength",
72+
"pattern",
73+
"maximum",
74+
"exclusiveMinimum",
75+
"multipleOf",
76+
"exclusiveMaximum",
77+
"minimum",
78+
"dependentRequired",
79+
"minProperties",
80+
"maxProperties",
81+
"required",
82+
"minItems",
83+
"maxItems",
84+
"minContains",
85+
"maxContains",
86+
"uniqueItems",
87+
]
88+
other_keywords: ClassVar[list[str]] = [
89+
"format",
90+
"unevaluatedItems",
91+
"unevaluatedProperties",
92+
"contentEncoding",
93+
"contentMediaType",
94+
"contentSchema",
95+
"format_assertion",
96+
]
97+
98+
parsed_keywords: ClassVar[list[str]] = [
99+
'"%s"' % keyword
100+
for keyword in (
101+
core_keywords
102+
+ applicator_keywords
103+
+ meta_data_keywords
104+
+ validation_keywords
105+
+ other_keywords
106+
)
107+
]
108+
109+
parsed_data_types: ClassVar[list[str]] = [
110+
'"%s"' % data_type for data_type in data_types
111+
]
112+
113+
def get_tokens_unprocessed(self, text: str): # type: ignore[reportUnknownParameterType]
114+
"""
115+
Add token classes to it according to JSON Schema.
116+
"""
117+
for start, token, value in super().get_tokens_unprocessed(text): # type: ignore[reportUnknownVariableType]
118+
if token is Token.Name.Tag and value in self.parsed_keywords:
119+
yield start, Token.Keyword, value
120+
elif (
121+
token is Token.String.Double
122+
and value in self.parsed_data_types
123+
):
124+
yield start, Token.Name.Decorator, value
125+
else:
126+
yield start, token, value

pyproject.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ classifiers = [
2929

3030
]
3131
dynamic = ["version"]
32-
32+
dependencies = [
33+
"Pygments==2.17.2"
34+
]
3335

3436
[project.urls]
3537
Issues = "https://github.com/python-jsonschema/jsonschema-lexer/issues/"

requirements.txt

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#
2+
# This file is autogenerated by pip-compile with Python 3.11
3+
# by the following command:
4+
#
5+
# pip-compile --strip-extras pyproject.toml
6+
#
7+
pygments==2.17.2
8+
# via jsonschema_lexer (pyproject.toml)

0 commit comments

Comments
 (0)