File: lua.rb

package info (click to toggle)
ruby-rouge 4.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,844 kB
  • sloc: ruby: 38,489; sed: 2,071; perl: 152; makefile: 8
file content (185 lines) | stat: -rw-r--r-- 4,780 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# -*- 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
        Kernel::load File.join(Lexers::BASE_DIR, 'lua/keywords.rb')
        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 name == "gsub"
            token Name::Builtin
            push :gsub
          elsif 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 :gsub do
        rule %r/\)/, Punctuation, :pop!
        rule %r/[(,]/, Punctuation
        rule %r/\s+/, Text
        rule %r/'/, Str::Regex, :regex_sq
        rule %r/"/, Str::Regex, :regex_dq
      end

      state :regex_sq do
        rule %r(') do
          token Str::Regex
          goto :regex_end
        end

        mixin :regex
      end

      state :regex_dq do
        rule %r(") do
          token Str::Regex
          goto :regex_end
        end

        mixin :regex
      end

      state :regex do
        rule %r(") do
          token Str::Regex
          goto :regex_end
        end

        rule %r/\[\^?/, Str::Escape, :regex_group
        rule %r/\\./, Str::Escape
        rule %r{[(][?][:=<!]}, Str::Escape
        rule %r/[{][\d,]+[}]/, Str::Escape
        rule %r/[()?]/, Str::Escape
        rule %r/./, Str::Regex
      end

      state :regex_end do
        rule %r/[$]+/, Str::Regex, :pop!
        rule(//) { pop! }
      end

      state :regex_group do
        rule %r(/), Str::Escape
        rule %r/\]/, Str::Escape, :pop!
        rule %r/(\\)(.)/ do |m|
          groups Str::Escape, Str::Regex
        end
        rule %r/./, Str::Regex
      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::Escape
        rule %r('), Str::Single, :pop!
        rule %r([^'\\]+), Str::Single
      end

      state :dqs do
        rule %r(\\"), Str::Escape
        rule %r("), Str::Double, :pop!
        rule %r([^"\\]+), Str::Double
      end
    end
  end
end