1"""
2 pygments.lexers.graphql
3 ~~~~~~~~~~~~~~~~~~~~~~~
4
5 Lexer for GraphQL, an open-source data query and manipulation
6 language for APIs.
7
8 More information:
9 https://graphql.org/
10
11 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
12 :license: BSD, see LICENSE for details.
13"""
14
15from pygments.lexer import RegexLexer, words, include, bygroups, default
16from pygments.token import (Comment, Keyword, Name, Number, Punctuation, String,
17 Whitespace)
18
19
20__all__ = ["GraphQLLexer"]
21
22OPERATION_TYPES = ("query", "mutation", "subscription")
23BUILTIN_TYPES = ("Int", "Float", "String", "Boolean", "ID")
24BOOLEAN_VALUES = ("true", "false", "null")
25KEYWORDS = (
26 "type",
27 "schema",
28 "extend",
29 "enum",
30 "scalar",
31 "implements",
32 "interface",
33 "union",
34 "input",
35 "directive",
36 "QUERY",
37 "MUTATION",
38 "SUBSCRIPTION",
39 "FIELD",
40 "FRAGMENT_DEFINITION",
41 "FRAGMENT_SPREAD",
42 "INLINE_FRAGMENT",
43 "SCHEMA",
44 "SCALAR",
45 "OBJECT",
46 "FIELD_DEFINITION",
47 "ARGUMENT_DEFINITION",
48 "INTERFACE",
49 "UNION",
50 "ENUM",
51 "ENUM_VALUE",
52 "INPUT_OBJECT",
53 "INPUT_FIELD_DEFINITION",
54)
55
56
57class GraphQLLexer(RegexLexer):
58 """
59 Lexer for GraphQL syntax
60 """
61 name = "GraphQL"
62 aliases = ["graphql"]
63 filenames = ["*.graphql"]
64 url = "https://graphql.org"
65 version_added = '2.16'
66
67 tokens = {
68 "ignored_tokens": [
69 (r"\s+", Whitespace), # Whitespaces
70 (r"#.*$", Comment),
71 (",", Punctuation), # Insignificant commas
72 ],
73 "value": [
74 include("ignored_tokens"),
75 (r"-?\d+(?![.eE])", Number.Integer, "#pop"),
76 (
77 r"-?\d+(\.\d+)?([eE][+-]?\d+)?",
78 Number.Float,
79 "#pop",
80 ),
81 (r'"', String, ("#pop", "string")),
82 (words(BOOLEAN_VALUES, suffix=r"\b"), Name.Builtin, "#pop"),
83 (r"\$[a-zA-Z_]\w*", Name.Variable, "#pop"),
84 (r"[a-zA-Z_]\w*", Name.Constant, "#pop"),
85 (r"\[", Punctuation, ("#pop", "list_value")),
86 (r"\{", Punctuation, ("#pop", "object_value")),
87 ],
88 "list_value": [
89 include("ignored_tokens"),
90 ("]", Punctuation, "#pop"),
91 default("value"),
92 ],
93 "object_value": [
94 include("ignored_tokens"),
95 (r"[a-zA-Z_]\w*", Name),
96 (r":", Punctuation, "value"),
97 (r"\}", Punctuation, "#pop"),
98 ],
99 "string": [
100 (r'\\(["\\/bfnrt]|u[a-fA-F0-9]{4})', String.Escape),
101 (r'[^\\"\n]+', String), # all other characters
102 (r'"', String, "#pop"),
103 ],
104 "root": [
105 include("ignored_tokens"),
106 (words(OPERATION_TYPES, suffix=r"\b"), Keyword, "operation"),
107 (words(KEYWORDS, suffix=r"\b"), Keyword),
108 (r"\{", Punctuation, "selection_set"),
109 (r"fragment\b", Keyword, "fragment_definition"),
110 ],
111 "operation": [
112 include("ignored_tokens"),
113 (r"[a-zA-Z_]\w*", Name.Function),
114 (r"\(", Punctuation, "variable_definition"),
115 (r"\{", Punctuation, ("#pop", "selection_set")),
116 ],
117 "variable_definition": [
118 include("ignored_tokens"),
119 (r"\$[a-zA-Z_]\w*", Name.Variable),
120 (r"[\]!]", Punctuation),
121 (r":", Punctuation, "type"),
122 (r"=", Punctuation, "value"),
123 (r"\)", Punctuation, "#pop"),
124 ],
125 "type": [
126 include("ignored_tokens"),
127 (r"\[", Punctuation),
128 (words(BUILTIN_TYPES, suffix=r"\b"), Name.Builtin, "#pop"),
129 (r"[a-zA-Z_]\w*", Name.Class, "#pop"),
130 ],
131 "selection_set": [
132 include("ignored_tokens"),
133 (r"([a-zA-Z_]\w*)(\s*)(:)", bygroups(Name.Label, Whitespace, Punctuation)),
134 (r"[a-zA-Z_]\w*", Name), # Field
135 (
136 r"(\.\.\.)(\s+)(on)\b",
137 bygroups(Punctuation, Whitespace, Keyword),
138 "inline_fragment",
139 ),
140 (r"\.\.\.", Punctuation, "fragment_spread"),
141 (r"\(", Punctuation, "arguments"),
142 (r"@[a-zA-Z_]\w*", Name.Decorator, "directive"),
143 (r"\{", Punctuation, "selection_set"),
144 (r"\}", Punctuation, "#pop"),
145 ],
146 "directive": [
147 include("ignored_tokens"),
148 (r"\(", Punctuation, ("#pop", "arguments")),
149 ],
150 "arguments": [
151 include("ignored_tokens"),
152 (r"[a-zA-Z_]\w*", Name),
153 (r":", Punctuation, "value"),
154 (r"\)", Punctuation, "#pop"),
155 ],
156 # Fragments
157 "fragment_definition": [
158 include("ignored_tokens"),
159 (r"[\]!]", Punctuation), # For NamedType
160 (r"on\b", Keyword, "type"),
161 (r"[a-zA-Z_]\w*", Name.Function),
162 (r"@[a-zA-Z_]\w*", Name.Decorator, "directive"),
163 (r"\{", Punctuation, ("#pop", "selection_set")),
164 ],
165 "fragment_spread": [
166 include("ignored_tokens"),
167 (r"@[a-zA-Z_]\w*", Name.Decorator, "directive"),
168 (r"[a-zA-Z_]\w*", Name, "#pop"), # Fragment name
169 ],
170 "inline_fragment": [
171 include("ignored_tokens"),
172 (r"[a-zA-Z_]\w*", Name.Class), # Type condition
173 (r"@[a-zA-Z_]\w*", Name.Decorator, "directive"),
174 (r"\{", Punctuation, ("#pop", "selection_set")),
175 ],
176 }