1"""
2 pygments.lexers.json5
3 ~~~~~~~~~~~~~~~~~~~~~
4
5 Lexer for Json5 file format.
6
7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11from pygments.lexer import include, RegexLexer, words
12from pygments.token import Comment, Keyword, Name, Number, Punctuation, \
13 String, Whitespace
14
15__all__ = ['Json5Lexer']
16
17
18def string_rules(quote_mark):
19 return [
20 (rf"[^{quote_mark}\\]+", String),
21 (r"\\.", String.Escape),
22 (r"\\", Punctuation),
23 (quote_mark, String, '#pop'),
24 ]
25
26
27def quoted_field_name(quote_mark):
28 return [
29 (rf'([^{quote_mark}\\]|\\.)*{quote_mark}',
30 Name.Variable, ('#pop', 'object_value'))
31 ]
32
33
34class Json5Lexer(RegexLexer):
35 """Lexer for JSON5 data structures."""
36
37 name = 'JSON5'
38 aliases = ['json5']
39 filenames = ['*.json5']
40 url = "https://json5.org"
41 version_added = '2.19'
42 tokens = {
43 '_comments': [
44 (r'(//|#).*\n', Comment.Single),
45 (r'/\*\*([^/]|/(?!\*))*\*/', String.Doc),
46 (r'/\*([^/]|/(?!\*))*\*/', Comment),
47 ],
48 'root': [
49 include('_comments'),
50 (r"'", String, 'singlestring'),
51 (r'"', String, 'doublestring'),
52 (r'[+-]?0[xX][0-9a-fA-F]+', Number.Hex),
53 (r'[+-.]?[0-9]+[.]?[0-9]?([eE][-]?[0-9]+)?', Number.Float),
54 (r'\{', Punctuation, 'object'),
55 (r'\[', Punctuation, 'array'),
56 (words(['false', 'Infinity', '+Infinity', '-Infinity', 'NaN',
57 'null', 'true',], suffix=r'\b'), Keyword),
58 (r'\s+', Whitespace),
59 (r':', Punctuation),
60 ],
61 'singlestring': string_rules("'"),
62 'doublestring': string_rules('"'),
63 'array': [
64 (r',', Punctuation),
65 (r'\]', Punctuation, '#pop'),
66 include('root'),
67 ],
68 'object': [
69 (r'\s+', Whitespace),
70 (r'\}', Punctuation, '#pop'),
71 (r'\b([^:]+)', Name.Variable, 'object_value'),
72 (r'"', Name.Variable, 'double_field_name'),
73 (r"'", Name.Variable, 'single_field_name'),
74 include('_comments'),
75 ],
76 'double_field_name': quoted_field_name('"'),
77 'single_field_name': quoted_field_name("'"),
78 'object_value': [
79 (r',', Punctuation, '#pop'),
80 (r'\}', Punctuation, '#pop:2'),
81 include('root'),
82 ],
83 }