lib/rouge/lexers/elixir.rb in rouge-2.0.7 vs lib/rouge/lexers/elixir.rb in rouge-2.1.0
- old
+ new
@@ -13,17 +13,10 @@
filenames '*.ex', '*.exs'
mimetypes 'text/x-elixir', 'application/x-elixir'
- BRACES = [
- ['\{', '\}', 'cb'],
- ['\[', '\]', 'sb'],
- ['\(', '\)', 'pa'],
- ['\<', '\>', 'lt']
- ]
-
state :root do
rule /\s+/m, Text
rule /#.*$/, Comment::Single
rule %r{\b(case|cond|end|bc|lc|if|unless|try|loop|receive|fn|defmodule|
defp?|defprotocol|defimpl|defrecord|defmacrop?|defdelegate|
@@ -44,43 +37,24 @@
rule /[a-zA-Z_!][\w_]*[!\?]?/, Name
rule %r{::|[%(){};,/\|:\\\[\]]}, Punctuation
rule /@[a-zA-Z_]\w*|&\d/, Name::Variable
rule %r{\b(0[xX][0-9A-Fa-f]+|\d(_?\d)*(\.(?![^\d\s])
(_?\d)*)?([eE][-+]?\d(_?\d)*)?|0[bB][01]+)\b}x, Num
- rule %r{~r\/.*\/}, Str::Regex
mixin :strings
+ mixin :sigil_strings
end
state :strings do
rule /(%[A-Ba-z])?"""(?:.|\n)*?"""/, Str::Doc
rule /'''(?:.|\n)*?'''/, Str::Doc
rule /"/, Str::Doc, :dqs
rule /'.*?'/, Str::Single
rule %r{(?<!\w)\?(\\(x\d{1,2}|\h{1,2}(?!\h)\b|0[0-7]{0,2}(?![0-7])\b[^x0MC])|(\\[MC]-)+\w|[^\s\\])}, Str::Other
- BRACES.each do |_, _, name|
- mixin :"braces_#{name}"
- end
end
- BRACES.each do |lbrace, rbrace, name|
- state :"braces_#{name}" do
- rule /%[a-z]#{lbrace}/, Str::Double, :"braces_#{name}_intp"
- rule /%[A-Z]#{lbrace}/, Str::Double, :"braces_#{name}_no_intp"
- end
-
- state :"braces_#{name}_intp" do
- rule /#{rbrace}[a-z]*/, Str::Double, :pop!
- mixin :enddoublestr
- end
-
- state :"braces_#{name}_no_intp" do
- rule /.*#{rbrace}[a-z]*/, Str::Double, :pop!
- end
- end
-
state :dqs do
rule /"/, Str::Double, :pop!
mixin :enddoublestr
end
@@ -100,9 +74,60 @@
end
state :enddoublestr do
mixin :interpoling
rule /[^#"]+/, Str::Double
+ end
+
+ state :sigil_strings do
+ # ~-sigiled strings
+ # ~(abc), ~[abc], ~<abc>, ~|abc|, ~r/abc/, etc
+ # Cribbed and adjusted from Ruby lexer
+ delimiter_map = { '{' => '}', '[' => ']', '(' => ')', '<' => '>' }
+ # Match a-z for custom sigils too
+ sigil_opens = Regexp.union(delimiter_map.keys + %w(| / ' "))
+ rule /~([A-Za-z])?(#{sigil_opens})/ do |m|
+ open = Regexp.escape(m[2])
+ close = Regexp.escape(delimiter_map[m[2]] || m[2])
+ interp = /[SRCW]/ === m[1]
+ toktype = Str::Other
+
+ puts " open: #{open.inspect}" if @debug
+ puts " close: #{close.inspect}" if @debug
+
+ # regexes
+ if 'Rr'.include? m[1]
+ toktype = Str::Regex
+ push :regex_flags
+ end
+
+ if 'Ww'.include? m[1]
+ push :list_flags
+ end
+
+ token toktype
+
+ push do
+ rule /#{close}/, toktype, :pop!
+
+ if interp
+ mixin :interpoling
+ rule /#/, toktype
+ else
+ rule /[\\#]/, toktype
+ end
+
+ rule /[^##{open}#{close}\\]+/m, toktype
+ end
+ end
+ end
+
+ state :regex_flags do
+ rule /[fgimrsux]*/, Str::Regex, :pop!
+ end
+
+ state :list_flags do
+ rule /[csa]?/, Str::Other, :pop!
end
end
end
end