rouge 3.19.0 → 3.26.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rouge.rb +1 -0
  3. data/lib/rouge/cli.rb +32 -2
  4. data/lib/rouge/demos/augeas +16 -0
  5. data/lib/rouge/demos/bibtex +12 -0
  6. data/lib/rouge/demos/brightscript +6 -0
  7. data/lib/rouge/demos/email +11 -0
  8. data/lib/rouge/demos/hlsl +20 -0
  9. data/lib/rouge/demos/j +12 -0
  10. data/lib/rouge/demos/janet +3 -0
  11. data/lib/rouge/demos/livescript +15 -0
  12. data/lib/rouge/demos/ocl +4 -0
  13. data/lib/rouge/demos/postscript +9 -0
  14. data/lib/rouge/demos/rescript +26 -0
  15. data/lib/rouge/demos/ssh +4 -0
  16. data/lib/rouge/demos/systemd +4 -0
  17. data/lib/rouge/demos/velocity +9 -0
  18. data/lib/rouge/demos/zig +6 -0
  19. data/lib/rouge/formatters/html_line_highlighter.rb +24 -0
  20. data/lib/rouge/formatters/html_line_table.rb +1 -3
  21. data/lib/rouge/formatters/html_linewise.rb +2 -3
  22. data/lib/rouge/lexer.rb +38 -20
  23. data/lib/rouge/lexers/apex.rb +9 -7
  24. data/lib/rouge/lexers/augeas.rb +93 -0
  25. data/lib/rouge/lexers/batchfile.rb +3 -2
  26. data/lib/rouge/lexers/bibtex.rb +115 -0
  27. data/lib/rouge/lexers/brightscript.rb +147 -0
  28. data/lib/rouge/lexers/cmake.rb +10 -0
  29. data/lib/rouge/lexers/cpp.rb +12 -5
  30. data/lib/rouge/lexers/crystal.rb +14 -9
  31. data/lib/rouge/lexers/css.rb +3 -1
  32. data/lib/rouge/lexers/diff.rb +1 -1
  33. data/lib/rouge/lexers/docker.rb +2 -2
  34. data/lib/rouge/lexers/elm.rb +5 -5
  35. data/lib/rouge/lexers/email.rb +39 -0
  36. data/lib/rouge/lexers/ghc_core.rb +2 -1
  37. data/lib/rouge/lexers/graphql.rb +1 -1
  38. data/lib/rouge/lexers/hack.rb +1 -1
  39. data/lib/rouge/lexers/haskell.rb +27 -19
  40. data/lib/rouge/lexers/hlsl.rb +166 -0
  41. data/lib/rouge/lexers/html.rb +7 -7
  42. data/lib/rouge/lexers/http.rb +8 -2
  43. data/lib/rouge/lexers/isbl.rb +2 -2
  44. data/lib/rouge/lexers/j.rb +244 -0
  45. data/lib/rouge/lexers/janet.rb +218 -0
  46. data/lib/rouge/lexers/javascript.rb +11 -5
  47. data/lib/rouge/lexers/jinja.rb +22 -7
  48. data/lib/rouge/lexers/jsl.rb +20 -8
  49. data/lib/rouge/lexers/jsonnet.rb +4 -3
  50. data/lib/rouge/lexers/jsp.rb +2 -3
  51. data/lib/rouge/lexers/jsx.rb +47 -59
  52. data/lib/rouge/lexers/julia.rb +4 -2
  53. data/lib/rouge/lexers/kotlin.rb +8 -4
  54. data/lib/rouge/lexers/livescript.rb +310 -0
  55. data/lib/rouge/lexers/ocaml/common.rb +1 -1
  56. data/lib/rouge/lexers/ocl.rb +85 -0
  57. data/lib/rouge/lexers/opentype_feature_file.rb +26 -42
  58. data/lib/rouge/lexers/perl.rb +27 -7
  59. data/lib/rouge/lexers/php.rb +274 -128
  60. data/lib/rouge/lexers/postscript.rb +93 -0
  61. data/lib/rouge/lexers/powershell.rb +44 -32
  62. data/lib/rouge/lexers/python.rb +1 -1
  63. data/lib/rouge/lexers/q.rb +1 -1
  64. data/lib/rouge/lexers/reasonml.rb +6 -5
  65. data/lib/rouge/lexers/rego.rb +27 -12
  66. data/lib/rouge/lexers/rescript.rb +119 -0
  67. data/lib/rouge/lexers/ruby.rb +1 -1
  68. data/lib/rouge/lexers/rust.rb +6 -3
  69. data/lib/rouge/lexers/sass/common.rb +1 -0
  70. data/lib/rouge/lexers/smarty.rb +1 -1
  71. data/lib/rouge/lexers/ssh.rb +33 -0
  72. data/lib/rouge/lexers/systemd.rb +34 -0
  73. data/lib/rouge/lexers/tsx.rb +10 -3
  74. data/lib/rouge/lexers/twig.rb +4 -4
  75. data/lib/rouge/lexers/typescript.rb +1 -12
  76. data/lib/rouge/lexers/typescript/common.rb +18 -4
  77. data/lib/rouge/lexers/velocity.rb +71 -0
  78. data/lib/rouge/lexers/wollok.rb +0 -1
  79. data/lib/rouge/lexers/xml.rb +5 -3
  80. data/lib/rouge/lexers/yaml.rb +5 -3
  81. data/lib/rouge/lexers/zig.rb +139 -0
  82. data/lib/rouge/regex_lexer.rb +56 -1
  83. data/lib/rouge/themes/base16.rb +1 -0
  84. data/lib/rouge/themes/bw.rb +1 -0
  85. data/lib/rouge/themes/colorful.rb +1 -0
  86. data/lib/rouge/themes/github.rb +1 -0
  87. data/lib/rouge/themes/gruvbox.rb +2 -0
  88. data/lib/rouge/themes/igor_pro.rb +1 -0
  89. data/lib/rouge/themes/magritte.rb +1 -0
  90. data/lib/rouge/themes/monokai.rb +1 -0
  91. data/lib/rouge/themes/pastie.rb +1 -0
  92. data/lib/rouge/themes/thankful_eyes.rb +1 -0
  93. data/lib/rouge/themes/tulip.rb +1 -0
  94. data/lib/rouge/version.rb +1 -1
  95. metadata +33 -2
@@ -8,16 +8,22 @@ module Rouge
8
8
  title "HTTP"
9
9
  desc 'http requests and responses'
10
10
 
11
+ option :content, "the language for the content (default: auto-detect)"
12
+
11
13
  def self.http_methods
12
14
  @http_methods ||= %w(GET POST PUT DELETE HEAD OPTIONS TRACE PATCH)
13
15
  end
14
16
 
15
17
  def content_lexer
18
+ @content_lexer ||= (lexer_option(:content) || guess_content_lexer)
19
+ end
20
+
21
+ def guess_content_lexer
16
22
  return Lexers::PlainText unless @content_type
17
23
 
18
- @content_lexer ||= Lexer.guess_by_mimetype(@content_type)
24
+ Lexer.guess_by_mimetype(@content_type)
19
25
  rescue Lexer::AmbiguousGuess
20
- @content_lexer = Lexers::PlainText
26
+ Lexers::PlainText
21
27
  end
22
28
 
23
29
  start { @content_type = 'text/plain' }
@@ -41,7 +41,7 @@ module Rouge
41
41
 
42
42
  state :dotted do
43
43
  mixin :whitespace
44
- rule %r/[a-zа-яё_0-9]*/i do |m|
44
+ rule %r/[a-zа-яё_0-9]+/i do |m|
45
45
  name = m[0]
46
46
  if self.class.constants.include? name.downcase
47
47
  token Name::Builtin
@@ -56,7 +56,7 @@ module Rouge
56
56
 
57
57
  state :type do
58
58
  mixin :whitespace
59
- rule %r/[a-zа-яё_0-9]*/i do |m|
59
+ rule %r/[a-zа-яё_0-9]+/i do |m|
60
60
  name = m[0]
61
61
  if self.class.interfaces.include? name.downcase
62
62
  token Keyword::Type
@@ -0,0 +1,244 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Lexers
6
+ class J < RegexLexer
7
+ title 'J'
8
+ desc "The J programming language (jsoftware.com)"
9
+ tag 'j'
10
+ filenames '*.ijs', '*.ijt'
11
+
12
+ # For J-specific terms we use, see:
13
+ # https://code.jsoftware.com/wiki/Vocabulary/AET
14
+ # https://code.jsoftware.com/wiki/Vocabulary/Glossary
15
+
16
+ # https://code.jsoftware.com/wiki/Vocabulary/PartsOfSpeech
17
+ def self.token_map
18
+ @token_map ||= {
19
+ noun: Keyword::Constant,
20
+ verb: Name::Function,
21
+ modifier: Operator,
22
+ name: Name,
23
+ param: Name::Builtin::Pseudo,
24
+ other: Punctuation,
25
+ nil => Error,
26
+ }
27
+ end
28
+
29
+ # https://code.jsoftware.com/wiki/NuVoc
30
+ def self.inflection_list
31
+ @inflection_list ||= ['', '.', ':', '..', '.:', ':.', '::']
32
+ end
33
+
34
+ def self.primitive_table
35
+ @primitive_table ||= Hash.new([:name]).tap do |h|
36
+ {
37
+ '()' => [:other],
38
+ '=' => [:verb, :other, :other],
39
+ '<>+-*%$|,#' => [:verb, :verb, :verb],
40
+ '^' => [:verb, :verb, :modifier],
41
+ '~"' => [:modifier, :verb, :verb],
42
+ '.:@' => [:modifier, :modifier, :modifier],
43
+ ';' => [:verb, :modifier, :verb],
44
+ '!' => [:verb, :modifier, :modifier],
45
+ '/\\' => [:modifier, :modifier, :verb],
46
+ '[' => [:verb, nil, :verb],
47
+ ']' => [:verb],
48
+ '{' => [:verb, :verb, :verb, nil, nil, nil, :verb],
49
+ '}' => [:modifier, :verb, :verb, nil, nil, nil, :modifier],
50
+ '`' => [:modifier, nil, :modifier],
51
+ '&' => [:modifier, :modifier, :modifier, nil, :modifier],
52
+ '?' => [:verb, :verb],
53
+ 'a' => [:name, :noun, :noun],
54
+ 'ACeEIjorv' => [:name, :verb],
55
+ 'bdfHMT' => [:name, :modifier],
56
+ 'Dt' => [:name, :modifier, :modifier],
57
+ 'F' => [:name, :modifier, :modifier, :modifier, :modifier,
58
+ :modifier, :modifier],
59
+ 'iu' => [:name, :verb, :verb],
60
+ 'L' => [:name, :verb, :modifier],
61
+ 'mny' => [:param],
62
+ 'p' => [:name, :verb, :verb, :verb],
63
+ 'qsZ' => [:name, nil, :verb],
64
+ 'S' => [:name, nil, :modifier],
65
+ 'u' => [:param, :verb, :verb],
66
+ 'v' => [:param, :verb],
67
+ 'x' => [:param, nil, :verb],
68
+ }.each {|k, v| k.each_char {|c| h[c] = v } }
69
+ end
70
+ end
71
+
72
+ def self.primitive(char, inflection)
73
+ i = inflection_list.index(inflection) or return Error
74
+ token_map[primitive_table[char][i]]
75
+ end
76
+
77
+ def self.control_words
78
+ @control_words ||= Set.new %w(
79
+ assert break case catch catchd catcht continue do else elseif end
80
+ fcase for if return select throw try while whilst
81
+ )
82
+ end
83
+
84
+ def self.control_words_id
85
+ @control_words_id ||= Set.new %w(for goto label)
86
+ end
87
+
88
+ state :expr do
89
+ rule %r/\s+/, Text
90
+
91
+ rule %r'([!-&(-/:-@\[-^`{-~]|[A-Za-z]\b)([.:]*)' do |m|
92
+ token J.primitive(m[1], m[2])
93
+ end
94
+
95
+ rule %r/(?:\d|_\d?):([.:]*)/ do |m|
96
+ token m[1].empty? ? J.token_map[:verb] : Error
97
+ end
98
+
99
+ rule %r/[\d_][\w.]*([.:]*)/ do |m|
100
+ token m[1].empty? ? Num : Error
101
+ end
102
+
103
+ rule %r/'/, Str::Single, :str
104
+
105
+ rule %r/NB\.(?![.:]).*/, Comment::Single
106
+
107
+ rule %r/([A-Za-z]\w*)([.:]*)/ do |m|
108
+ if m[2] == '.'
109
+ word, sep, id = m[1].partition '_'
110
+ list = if sep.empty?
111
+ J.control_words
112
+ elsif not id.empty?
113
+ J.control_words_id
114
+ end
115
+ if list and list.include? word
116
+ token Keyword, word + sep
117
+ token((word == 'for' ? Name : Name::Label), id)
118
+ token Keyword, m[2]
119
+ else
120
+ token Error
121
+ end
122
+ else
123
+ token m[2].empty? ? Name : Error
124
+ end
125
+ end
126
+ end
127
+
128
+ state :str do
129
+ rule %r/''/, Str::Escape
130
+ rule %r/[^'\n]+/, Str::Single
131
+ rule %r/'|$/, Str::Single, :pop!
132
+ end
133
+
134
+ start do
135
+ @note_next = false
136
+ end
137
+
138
+ state :root do
139
+ rule %r/\n/ do
140
+ token Text
141
+ if @note_next
142
+ push :note
143
+ @note_next = false
144
+ end
145
+ end
146
+
147
+ # https://code.jsoftware.com/wiki/Vocabulary/com
148
+ # https://code.jsoftware.com/wiki/Vocabulary/NounExplicitDefinition
149
+ rule %r/
150
+ ([0-4]|13|adverb|conjunction|dyad|monad|noun|verb)([\ \t]+)
151
+ (def(?:ine)?\b|:)(?![.:])([\ \t]*)
152
+ /x do |m|
153
+ groups Keyword::Pseudo, Text, Keyword::Pseudo, Text
154
+ @def_body = (m[1] == '0' || m[1] == 'noun') ? :noun : :code
155
+ if m[3] == 'define'
156
+ # stack: [:root]
157
+ # or [:root, ..., :def_next]
158
+ pop! if stack.size > 1
159
+ push @def_body
160
+ push :def_next # [:root, ..., @def_body, :def_next]
161
+ else
162
+ push :expl_def
163
+ end
164
+ end
165
+
166
+ rule %r/^([ \t]*)(Note\b(?![.:]))([ \t\r]*)(?!=[.:]|$)/ do
167
+ groups Text, Name, Text
168
+ @note_next = true
169
+ end
170
+
171
+ rule %r/[mnuvxy]\b(?![.:])/, Name
172
+ mixin :expr
173
+ end
174
+
175
+ state :def_next do
176
+ rule %r/\n/, Text, :pop!
177
+ mixin :root
178
+ end
179
+
180
+ state :expl_def do
181
+ rule %r/0\b(?![.:])/ do
182
+ token Keyword::Pseudo
183
+ # stack: [:root, :expl_def]
184
+ # or [:root, ..., :def_next, :expl_def]
185
+ pop! if stack.size > 2
186
+ goto @def_body
187
+ push :def_next # [:root, ..., @def_body, :def_next]
188
+ end
189
+ rule %r/'/ do
190
+ if @def_body == :noun
191
+ token Str::Single
192
+ goto :str
193
+ else
194
+ token Punctuation
195
+ goto :q_expr
196
+ end
197
+ end
198
+ rule(//) { pop! }
199
+ end
200
+
201
+ # `q_expr` lexes the content of a string literal which is a part of an
202
+ # explicit definition.
203
+ # e.g. dyad def 'x + y'
204
+ state :q_expr do
205
+ rule %r/''/, Str::Single, :q_str
206
+ rule %r/'|$/, Punctuation, :pop!
207
+ rule %r/NB\.(?![.:])([^'\n]|'')*/, Comment::Single
208
+ mixin :expr
209
+ end
210
+
211
+ state :q_str do
212
+ rule %r/''''/, Str::Escape
213
+ rule %r/[^'\n]+/, Str::Single
214
+ rule %r/''/, Str::Single, :pop!
215
+ rule(/'|$/) { token Punctuation; pop! 2 }
216
+ end
217
+
218
+ state :note do
219
+ mixin :delimiter
220
+ rule %r/.+\n?/, Comment::Multiline
221
+ end
222
+
223
+ state :noun do
224
+ mixin :delimiter
225
+ rule %r/.+\n?/, Str::Heredoc
226
+ end
227
+
228
+ state :code do
229
+ mixin :delimiter
230
+ rule %r/^([ \t]*)(:)([ \t\r]*)$/ do
231
+ groups Text, Punctuation, Text
232
+ end
233
+ mixin :expr
234
+ end
235
+
236
+ state :delimiter do
237
+ rule %r/^([ \t]*)(\))([ \t\r]*$\n?)/ do
238
+ groups Text, Punctuation, Text
239
+ pop!
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,218 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Lexers
6
+ class Janet < RegexLexer
7
+ title "Janet"
8
+ desc "The Janet programming language (janet-lang.org)"
9
+
10
+ tag 'janet'
11
+ aliases 'jdn'
12
+
13
+ filenames '*.janet', '*.jdn'
14
+
15
+ mimetypes 'text/x-janet', 'application/x-janet'
16
+
17
+ def self.specials
18
+ @specials ||= Set.new %w(
19
+ break def do fn if quote quasiquote splice set unquote var while
20
+ )
21
+ end
22
+
23
+ def self.bundled
24
+ @bundled ||= Set.new %w(
25
+ % %= * *= + ++ += - -- -= -> ->> -?> -?>> / /= < <= = > >=
26
+ abstract? accumulate accumulate2 all all-bindings
27
+ all-dynamics and apply array array/concat array/ensure
28
+ array/fill array/insert array/new array/new-filled
29
+ array/peek array/pop array/push array/remove array/slice
30
+ array? as-> as?-> asm assert bad-compile bad-parse band
31
+ blshift bnot boolean? bor brshift brushift buffer buffer/bit
32
+ buffer/bit-clear buffer/bit-set buffer/bit-toggle
33
+ buffer/blit buffer/clear buffer/fill buffer/format
34
+ buffer/new buffer/new-filled buffer/popn buffer/push-byte
35
+ buffer/push-string buffer/push-word buffer/slice buffer?
36
+ bxor bytes? case cfunction? chr cli-main comment comp
37
+ compare compare= compare< compare<= compare> compare>=
38
+ compile complement comptime cond coro count debug
39
+ debug/arg-stack debug/break debug/fbreak debug/lineage
40
+ debug/stack debug/stacktrace debug/step debug/unbreak
41
+ debug/unfbreak debugger-env dec deep-not= deep= default
42
+ default-peg-grammar def- defer defmacro defmacro- defn defn-
43
+ defglobal describe dictionary? disasm distinct doc doc*
44
+ doc-format dofile drop drop-until drop-while dyn each eachk
45
+ eachp eachy edefer eflush empty? env-lookup eprin eprinf
46
+ eprint eprintf error errorf eval eval-string even? every?
47
+ extreme false? fiber/can-resume? fiber/current fiber/getenv
48
+ fiber/maxstack fiber/new fiber/root fiber/setenv
49
+ fiber/setmaxstack fiber/status fiber? file/close file/flush
50
+ file/open file/popen file/read file/seek file/temp
51
+ file/write filter find find-index first flatten flatten-into
52
+ flush for forv freeze frequencies function? gccollect
53
+ gcinterval gcsetinterval generate gensym get get-in getline
54
+ hash idempotent? identity import import* if-let if-not
55
+ if-with in inc indexed? int/s64 int/u64 int? interleave
56
+ interpose invert janet/build janet/config-bits janet/version
57
+ juxt juxt* keep keys keyword keyword? kvs label last length
58
+ let load-image load-image-dict loop macex macex1 make-env
59
+ make-image make-image-dict map mapcat marshal math/-inf
60
+ math/abs math/acos math/acosh math/asin math/asinh math/atan
61
+ math/atan2 math/atanh math/cbrt math/ceil math/cos math/cosh
62
+ math/e math/erf math/erfc math/exp math/exp2 math/expm1
63
+ math/floor math/gamma math/hypot math/inf math/log
64
+ math/log10 math/log1p math/log2 math/next math/pi math/pow
65
+ math/random math/rng math/rng-buffer math/rng-int
66
+ math/rng-uniform math/round math/seedrandom math/sin
67
+ math/sinh math/sqrt math/tan math/tanh math/trunc match max
68
+ mean merge merge-into min mod module/add-paths module/cache
69
+ module/expand-path module/find module/loaders module/loading
70
+ module/paths nan? nat? native neg? net/chunk net/close
71
+ net/connect net/read net/server net/write next nil? not not=
72
+ number? odd? one? or os/arch os/cd os/chmod os/clock
73
+ os/cryptorand os/cwd os/date os/dir os/environ os/execute
74
+ os/exit os/getenv os/link os/lstat os/mkdir os/mktime
75
+ os/perm-int os/perm-string os/readlink os/realpath os/rename
76
+ os/rm os/rmdir os/setenv os/shell os/sleep os/stat
77
+ os/symlink os/time os/touch os/umask os/which pairs parse
78
+ parser/byte parser/clone parser/consume parser/eof
79
+ parser/error parser/flush parser/has-more parser/insert
80
+ parser/new parser/produce parser/state parser/status
81
+ parser/where partial partition peg/compile peg/match pos?
82
+ postwalk pp prewalk prin prinf print printf product prompt
83
+ propagate protect put put-in quit range reduce reduce2
84
+ repeat repl require resume return reverse reversed root-env
85
+ run-context scan-number seq setdyn shortfn signal slice
86
+ slurp some sort sort-by sorted sorted-by spit stderr stdin
87
+ stdout string string/ascii-lower string/ascii-upper
88
+ string/bytes string/check-set string/find string/find-all
89
+ string/format string/from-bytes string/has-prefix?
90
+ string/has-suffix? string/join string/repeat string/replace
91
+ string/replace-all string/reverse string/slice string/split
92
+ string/trim string/triml string/trimr string? struct struct?
93
+ sum symbol symbol? table table/clone table/getproto
94
+ table/new table/rawget table/setproto table/to-struct table?
95
+ take take-until take-while tarray/buffer tarray/copy-bytes
96
+ tarray/length tarray/new tarray/properties tarray/slice
97
+ tarray/swap-bytes thread/close thread/current thread/new
98
+ thread/receive thread/send trace tracev true? truthy? try
99
+ tuple tuple/brackets tuple/setmap tuple/slice
100
+ tuple/sourcemap tuple/type tuple? type unless unmarshal
101
+ untrace update update-in use values var- varfn varglobal
102
+ walk walk-ind walk-dict when when-let when-with with
103
+ with-dyns with-syms with-vars yield zero? zipcoll
104
+ )
105
+ end
106
+
107
+ def name_token(name)
108
+ if self.class.specials.include? name
109
+ Keyword
110
+ elsif self.class.bundled.include? name
111
+ Keyword::Reserved
112
+ else
113
+ Name::Function
114
+ end
115
+ end
116
+
117
+ punctuation = %r/[_!$%^&*+=~<>.?\/-]/o
118
+ symbol = %r/([[:alpha:]]|#{punctuation})([[:word:]]|#{punctuation}|:)*/o
119
+
120
+ state :root do
121
+ rule %r/#.*?$/, Comment::Single
122
+ rule %r/\s+/m, Text::Whitespace
123
+
124
+ rule %r/(true|false|nil)\b/, Name::Constant
125
+ rule %r/(['~])(#{symbol})/ do
126
+ groups Operator, Str::Symbol
127
+ end
128
+ rule %r/:([[:word:]]|#{punctuation}|:)*/, Keyword::Constant
129
+
130
+ # radix-specified numbers
131
+ rule %r/[+-]?\d{1,2}r[\w.]+(&[+-]?\w+)?/, Num::Float
132
+
133
+ # hex numbers
134
+ rule %r/[+-]?0x\h[\h_]*(\.\h[\h_]*)?/, Num::Hex
135
+ rule %r/[+-]?0x\.\h[\h_]*/, Num::Hex
136
+
137
+ # decimal numbers (Janet treats all decimals as floats)
138
+ rule %r/[+-]?\d[\d_]*(\.\d[\d_]*)?([e][+-]?\d+)?/i, Num::Float
139
+ rule %r/[+-]?\.\d[\d_]*([e][+-]?\d+)?/i, Num::Float
140
+
141
+ rule %r/@?"/, Str::Double, :string
142
+ rule %r/@?(`+).*?\1/m, Str::Heredoc
143
+
144
+ rule %r/\(/, Punctuation, :function
145
+
146
+ rule %r/(')(@?[(\[{])/ do
147
+ groups Operator, Punctuation
148
+ push :quote
149
+ end
150
+
151
+ rule %r/(~)(@?[(\[{])/ do
152
+ groups Operator, Punctuation
153
+ push :quasiquote
154
+ end
155
+
156
+ rule %r/[\#~,';\|]/, Operator
157
+
158
+ rule %r/@?[(){}\[\]]/, Punctuation
159
+
160
+ rule symbol, Name
161
+ end
162
+
163
+ state :string do
164
+ rule %r/"/, Str::Double, :pop!
165
+ rule %r/\\(u\h{4}|U\h{6})/, Str::Escape
166
+ rule %r/\\./, Str::Escape
167
+ rule %r/[^"\\]+/, Str::Double
168
+ end
169
+
170
+ state :function do
171
+ rule %r/[\)]/, Punctuation, :pop!
172
+
173
+ rule symbol do |m|
174
+ case m[0]
175
+ when "quote"
176
+ token Keyword
177
+ goto :quote
178
+ when "quasiquote"
179
+ token Keyword
180
+ goto :quasiquote
181
+ else
182
+ token name_token(m[0])
183
+ goto :root
184
+ end
185
+ end
186
+
187
+ mixin :root
188
+ end
189
+
190
+ state :quote do
191
+ rule %r/[(\[{]/, Punctuation, :push
192
+ rule %r/[)\]}]/, Punctuation, :pop!
193
+ rule symbol, Str::Escape
194
+ mixin :root
195
+ end
196
+
197
+ state :quasiquote do
198
+ rule %r/(,)(\()/ do
199
+ groups Operator, Punctuation
200
+ push :function
201
+ end
202
+ rule %r/(\()(\s*)(unquote)(\s+)(\()/ do
203
+ groups Punctuation, Text, Keyword, Text, Punctuation
204
+ push :function
205
+ end
206
+
207
+ rule %r/(,)(#{symbol})/ do
208
+ groups Operator, Name
209
+ end
210
+ rule %r/(\()(\s*)(unquote)(\s+)(#{symbol})/ do
211
+ groups Punctuation, Text, Keyword, Text, Name
212
+ end
213
+
214
+ mixin :quote
215
+ end
216
+ end
217
+ end
218
+ end