blob: abdc3018d254b5a5fdeea24a68e03b24a0cc1ed0 [file] [log] [blame]
# -*- coding: utf-8 -*- #
module Rouge
module Lexers
# Direct port of pygments Lexer.
# See: https://bitbucket.org/birkenfeld/pygments-main/src/7304e4759ae65343d89a51359ca538912519cc31/pygments/lexers/functional.py?at=default#cl-2362
class Elixir < RegexLexer
title "Elixir"
desc "Elixir language (elixir-lang.org)"
tag 'elixir'
aliases 'elixir', 'exs'
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|
defexception|exit|raise|throw|unless|after|rescue|catch|else)\b(?![?!])|
(?<!\.)\b(do|\-\>)\b}x, Keyword
rule /\b(import|require|use|recur|quote|unquote|super|refer)\b(?![?!])/, Keyword::Namespace
rule /(?<!\.)\b(and|not|or|when|xor|in)\b/, Operator::Word
rule %r{%=|\*=|\*\*=|\+=|\-=|\^=|\|\|=|
<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|(?=[\s\t])\?|
(?<=[\s\t])!+|&(&&?|(?!\d))|\|\||\^|\*|\+|\-|/|
\||\+\+|\-\-|\*\*|\/\/|\<\-|\<\>|<<|>>|=|\.|~~~}x, Operator
rule %r{(?<!:)(:)([a-zA-Z_]\w*([?!]|=(?![>=]))?|\<\>|===?|>=?|<=?|
<=>|&&?|%\(\)|%\[\]|%\{\}|\+\+?|\-\-?|\|\|?|\!|//|[%&`/\|]|
\*\*?|=?~|<\-)|([a-zA-Z_]\w*([?!])?)(:)(?!:)}, Str::Symbol
rule /:"/, Str::Symbol, :interpoling_symbol
rule /\b(nil|true|false)\b(?![?!])|\b[A-Z]\w*\b/, Name::Constant
rule /\b(__(FILE|LINE|MODULE|MAIN|FUNCTION)__)\b(?![?!])/, Name::Builtin::Pseudo
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
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
state :interpoling do
rule /#\{/, Str::Interpol, :interpoling_string
end
state :interpoling_string do
rule /\}/, Str::Interpol, :pop!
mixin :root
end
state :interpoling_symbol do
rule /"/, Str::Symbol, :pop!
mixin :interpoling
rule /[^#"]+/, Str::Symbol
end
state :enddoublestr do
mixin :interpoling
rule /[^#"]+/, Str::Double
end
end
end
end