127 lines
3.3 KiB
Ruby
127 lines
3.3 KiB
Ruby
|
# -*- coding: utf-8 -*- #
|
||
|
# frozen_string_literal: true
|
||
|
|
||
|
module Rouge
|
||
|
module Lexers
|
||
|
class Lua < RegexLexer
|
||
|
title "Lua"
|
||
|
desc "Lua (http://www.lua.org)"
|
||
|
tag 'lua'
|
||
|
filenames '*.lua', '*.wlua'
|
||
|
|
||
|
mimetypes 'text/x-lua', 'application/x-lua'
|
||
|
|
||
|
option :function_highlighting, 'Whether to highlight builtin functions (default: true)'
|
||
|
option :disabled_modules, 'builtin modules to disable'
|
||
|
|
||
|
def initialize(opts={})
|
||
|
@function_highlighting = opts.delete(:function_highlighting) { true }
|
||
|
@disabled_modules = opts.delete(:disabled_modules) { [] }
|
||
|
super(opts)
|
||
|
end
|
||
|
|
||
|
def self.detect?(text)
|
||
|
return true if text.shebang? 'lua'
|
||
|
end
|
||
|
|
||
|
def self.builtins
|
||
|
load File.join(__dir__, 'lua/builtins.rb')
|
||
|
self.builtins
|
||
|
end
|
||
|
|
||
|
def builtins
|
||
|
return [] unless @function_highlighting
|
||
|
|
||
|
@builtins ||= Set.new.tap do |builtins|
|
||
|
self.class.builtins.each do |mod, fns|
|
||
|
next if @disabled_modules.include? mod
|
||
|
builtins.merge(fns)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
state :root do
|
||
|
# lua allows a file to start with a shebang
|
||
|
rule %r(#!(.*?)$), Comment::Preproc
|
||
|
rule %r//, Text, :base
|
||
|
end
|
||
|
|
||
|
state :base do
|
||
|
rule %r(--\[(=*)\[.*?\]\1\])m, Comment::Multiline
|
||
|
rule %r(--.*$), Comment::Single
|
||
|
|
||
|
rule %r((?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?'), Num::Float
|
||
|
rule %r((?i)\d+e[+-]?\d+), Num::Float
|
||
|
rule %r((?i)0x[0-9a-f]*), Num::Hex
|
||
|
rule %r(\d+), Num::Integer
|
||
|
|
||
|
rule %r(\n), Text
|
||
|
rule %r([^\S\n]), Text
|
||
|
# multiline strings
|
||
|
rule %r(\[(=*)\[.*?\]\1\])m, Str
|
||
|
|
||
|
rule %r((==|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#])), Operator
|
||
|
rule %r([\[\]\{\}\(\)\.,:;]), Punctuation
|
||
|
rule %r((and|or|not)\b), Operator::Word
|
||
|
|
||
|
rule %r((break|do|else|elseif|end|for|if|in|repeat|return|then|until|while)\b), Keyword
|
||
|
rule %r((local)\b), Keyword::Declaration
|
||
|
rule %r((true|false|nil)\b), Keyword::Constant
|
||
|
|
||
|
rule %r((function)\b), Keyword, :function_name
|
||
|
|
||
|
rule %r([A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?) do |m|
|
||
|
name = m[0]
|
||
|
if self.builtins.include?(name)
|
||
|
token Name::Builtin
|
||
|
elsif name =~ /\./
|
||
|
a, b = name.split('.', 2)
|
||
|
token Name, a
|
||
|
token Punctuation, '.'
|
||
|
token Name, b
|
||
|
else
|
||
|
token Name
|
||
|
end
|
||
|
end
|
||
|
|
||
|
rule %r('), Str::Single, :escape_sqs
|
||
|
rule %r("), Str::Double, :escape_dqs
|
||
|
end
|
||
|
|
||
|
state :function_name do
|
||
|
rule %r/\s+/, Text
|
||
|
rule %r((?:([A-Za-z_][A-Za-z0-9_]*)(\.))?([A-Za-z_][A-Za-z0-9_]*)) do
|
||
|
groups Name::Class, Punctuation, Name::Function
|
||
|
pop!
|
||
|
end
|
||
|
# inline function
|
||
|
rule %r(\(), Punctuation, :pop!
|
||
|
end
|
||
|
|
||
|
state :escape_sqs do
|
||
|
mixin :string_escape
|
||
|
mixin :sqs
|
||
|
end
|
||
|
|
||
|
state :escape_dqs do
|
||
|
mixin :string_escape
|
||
|
mixin :dqs
|
||
|
end
|
||
|
|
||
|
state :string_escape do
|
||
|
rule %r(\\([abfnrtv\\"']|\d{1,3})), Str::Escape
|
||
|
end
|
||
|
|
||
|
state :sqs do
|
||
|
rule %r('), Str::Single, :pop!
|
||
|
rule %r([^']+), Str::Single
|
||
|
end
|
||
|
|
||
|
state :dqs do
|
||
|
rule %r("), Str::Double, :pop!
|
||
|
rule %r([^"]+), Str::Double
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|