262 lines
5.9 KiB
Ruby
262 lines
5.9 KiB
Ruby
# -*- coding: utf-8 -*- #
|
|
# frozen_string_literal: true
|
|
|
|
module Rouge
|
|
module Lexers
|
|
class GraphQL < RegexLexer
|
|
desc 'GraphQL'
|
|
tag 'graphql'
|
|
filenames '*.graphql', '*.gql'
|
|
mimetypes 'application/graphql'
|
|
|
|
name = /[_A-Za-z][_0-9A-Za-z]*/
|
|
|
|
state :root do
|
|
rule %r/\b(?:query|mutation|subscription)\b/, Keyword, :query_definition
|
|
rule %r/\{/ do
|
|
token Punctuation
|
|
push :query_definition
|
|
push :selection_set
|
|
end
|
|
|
|
rule %r/\bfragment\b/, Keyword, :fragment_definition
|
|
|
|
rule %r/\bscalar\b/, Keyword, :value
|
|
|
|
rule %r/\b(?:type|interface|enum)\b/, Keyword, :type_definition
|
|
|
|
rule %r/\b(?:input|schema)\b/, Keyword, :type_definition
|
|
|
|
rule %r/\bunion\b/, Keyword, :union_definition
|
|
|
|
rule %r/\bextend\b/, Keyword
|
|
|
|
mixin :basic
|
|
|
|
# Markdown descriptions
|
|
rule %r/(""")(\n)(.*?)(\n)(""")/m do |m|
|
|
token Str::Double, m[1]
|
|
token Text::Whitespace, m[2]
|
|
delegate Markdown, m[3]
|
|
token Text::Whitespace, m[4]
|
|
token Str::Double, m[5]
|
|
end
|
|
end
|
|
|
|
state :basic do
|
|
rule %r/\s+/m, Text::Whitespace
|
|
rule %r/#.*$/, Comment
|
|
|
|
rule %r/[!,]/, Punctuation
|
|
end
|
|
|
|
state :has_directives do
|
|
rule %r/(@#{name})(\s*)(\()/ do
|
|
groups Keyword, Text::Whitespace, Punctuation
|
|
push :arguments
|
|
end
|
|
rule %r/@#{name}\b/, Keyword
|
|
end
|
|
|
|
state :fragment_definition do
|
|
rule %r/\bon\b/, Keyword
|
|
|
|
mixin :query_definition
|
|
end
|
|
|
|
state :query_definition do
|
|
mixin :has_directives
|
|
|
|
rule %r/\b#{name}\b/, Name
|
|
rule %r/\(/, Punctuation, :variable_definitions
|
|
rule %r/\{/, Punctuation, :selection_set
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :type_definition do
|
|
rule %r/\bimplements\b/, Keyword
|
|
rule %r/\b#{name}\b/, Name
|
|
rule %r/\(/, Punctuation, :variable_definitions
|
|
rule %r/\{/, Punctuation, :type_definition_set
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :union_definition do
|
|
rule %r/\b#{name}\b/, Name
|
|
rule %r/\=/, Punctuation, :union_definition_variant
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :union_definition_variant do
|
|
rule %r/\b#{name}\b/ do
|
|
token Name
|
|
pop!
|
|
push :union_definition_pipe
|
|
end
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :union_definition_pipe do
|
|
rule %r/\|/ do
|
|
token Punctuation
|
|
pop!
|
|
push :union_definition_variant
|
|
end
|
|
|
|
rule %r/(?!\||\s+|#[^\n]*)/ do
|
|
pop! 2
|
|
end
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :type_definition_set do
|
|
rule %r/\}/ do
|
|
token Punctuation
|
|
pop! 2
|
|
end
|
|
|
|
rule %r/\b(#{name})(\s*)(\()/ do
|
|
groups Name, Text::Whitespace, Punctuation
|
|
push :variable_definitions
|
|
end
|
|
rule %r/\b#{name}\b/, Name
|
|
|
|
rule %r/:/, Punctuation, :type_names
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :arguments do
|
|
rule %r/\)/ do
|
|
token Punctuation
|
|
pop!
|
|
end
|
|
|
|
rule %r/\b#{name}\b/, Name
|
|
rule %r/:/, Punctuation, :value
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :variable_definitions do
|
|
rule %r/\)/ do
|
|
token Punctuation
|
|
pop!
|
|
end
|
|
|
|
rule %r/\$#{name}\b/, Name::Variable
|
|
rule %r/\b#{name}\b/, Name
|
|
rule %r/:/, Punctuation, :type_names
|
|
rule %r/\=/, Punctuation, :value
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :type_names do
|
|
rule %r/\b(?:Int|Float|String|Boolean|ID)\b/, Name::Builtin, :pop!
|
|
rule %r/\b#{name}\b/, Name, :pop!
|
|
|
|
rule %r/\[/, Punctuation, :type_name_list
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :type_name_list do
|
|
rule %r/\b(?:Int|Float|String|Boolean|ID)\b/, Name::Builtin
|
|
rule %r/\b#{name}\b/, Name
|
|
|
|
rule %r/\]/ do
|
|
token Punctuation
|
|
pop! 2
|
|
end
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :selection_set do
|
|
mixin :has_directives
|
|
|
|
rule %r/\}/ do
|
|
token Punctuation
|
|
pop!
|
|
pop! if state?(:query_definition) || state?(:fragment_definition)
|
|
end
|
|
|
|
rule %r/\b(#{name})(\s*)(\()/ do
|
|
groups Name, Text::Whitespace, Punctuation
|
|
push :arguments
|
|
end
|
|
|
|
rule %r/\b(#{name})(\s*)(:)/ do
|
|
groups Name, Text::Whitespace, Punctuation
|
|
end
|
|
|
|
rule %r/\b#{name}\b/, Name
|
|
|
|
rule %r/(\.\.\.)(\s+)(on)\b/ do
|
|
groups Punctuation, Text::Whitespace, Keyword
|
|
end
|
|
rule %r/\.\.\./, Punctuation
|
|
|
|
rule %r/\{/, Punctuation, :selection_set
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :list do
|
|
rule %r/\]/ do
|
|
token Punctuation
|
|
pop!
|
|
pop! if state?(:value)
|
|
end
|
|
|
|
mixin :value
|
|
end
|
|
|
|
state :object do
|
|
rule %r/\}/ do
|
|
token Punctuation
|
|
pop!
|
|
pop! if state?(:value)
|
|
end
|
|
|
|
rule %r/\b(#{name})(\s*)(:)/ do
|
|
groups Name, Text::Whitespace, Punctuation
|
|
push :value
|
|
end
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :value do
|
|
pop_unless_list = ->(t) {
|
|
->(m) {
|
|
token t
|
|
pop! unless state?(:list)
|
|
}
|
|
}
|
|
|
|
# Multiline strings
|
|
rule %r/""".*?"""/m, Str::Double
|
|
|
|
rule %r/\$#{name}\b/, &pop_unless_list[Name::Variable]
|
|
rule %r/\b(?:true|false|null)\b/, &pop_unless_list[Keyword::Constant]
|
|
rule %r/[+-]?[0-9]+\.[0-9]+(?:[eE][+-]?[0-9]+)?/, &pop_unless_list[Num::Float]
|
|
rule %r/[+-]?[1-9][0-9]*(?:[eE][+-]?[0-9]+)?/, &pop_unless_list[Num::Integer]
|
|
rule %r/"(\\[\\"]|[^"])*"/, &pop_unless_list[Str::Double]
|
|
rule %r/\b#{name}\b/, &pop_unless_list[Name]
|
|
|
|
rule %r/\{/, Punctuation, :object
|
|
rule %r/\[/, Punctuation, :list
|
|
|
|
mixin :basic
|
|
end
|
|
end
|
|
end
|
|
end
|