| # -*- 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 |