File: robot_framework.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 (249 lines) | stat: -rw-r--r-- 5,959 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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

module Rouge
  module Lexers
    class RobotFramework < RegexLexer
      tag 'robot_framework'
      aliases 'robot', 'robot-framework'

      title "Robot Framework"
      desc 'Robot Framework is a generic open source automation testing framework (robotframework.org)'

      filenames '*.robot', '*.resource'
      mimetypes 'text/x-robot'

      def initialize(opts = {})
        super(opts)
        @col = 0
        @next = nil
        @is_template = false
      end

      def self.settings_with_keywords
        @settings_with_keywords ||= Set.new [
          "library", "resource", "setup", "teardown", "template", "suite setup",
          "suite teardown", "task setup", "task teardown", "task template",
          "test setup", "test teardown", "test template", "variables"
        ]
      end
      
      def self.settings_with_args
        @settings_with_args ||= Set.new [
          "arguments", "default tags", "documentation", "force tags",
          "metadata", "return", "tags", "timeout", "task timeout",
          "test timeout"
        ]
      end

      id = %r/(?:\\|[^|$@&% \t\n])+(?: (?:\\.|[^|$@&% \t\n])+)*/
      bdd = %r/(?:Given|When|Then|And|But) /i
      sep = %r/ +\| +|[ ]{2,}|\t+/

      start do
        push :prior_text
      end

      state :prior_text do
        rule %r/^[^*].*/, Text
        rule(//) { pop! }
      end

      # Mixins

      state :whitespace do
        rule %r/\s+/, Text::Whitespace
      end

      state :section_include do
        mixin :end_section
        mixin :sep
        mixin :newline
      end

      state :end_section do
        rule(/(?=^(?:\| )?\*)/) { pop! }
      end

      state :return do
        rule(//) { pop! }
      end

      state :sep do
        rule %r/\| /, Text::Whitespace

        rule sep do
          token Text::Whitespace
          @col = @col + 1
          if @next
            push @next
          elsif @is_template
            push :args
          elsif @col == 1
            @next = :keyword
            push :keyword
          else
            push :args
          end
          push :cell_start
        end

        rule %r/\.\.\. */ do
          token Text::Whitespace
          @col = @col + 1
          push :args
        end
        
        rule %r/ ?\|/, Text::Whitespace
      end

      state :newline do
        rule %r/\n/ do
          token Text::Whitespace
          @col = 0
          @next = nil
          push :cell_start
        end
      end

      # States

      state :root do
        mixin :whitespace

        rule %r/^(?:\| )?\*[* ]*([A-Z]+(?: [A-Z]+)?).*/i do |m|
          token Generic::Heading, m[0]
          case m[1].chomp("s").downcase
          when "setting" then push :section_settings
          when "test case" then push :section_tests
          when "task" then push :section_tasks
          when "keyword" then push :section_keywords
          when "variable" then push :section_variables
          end
        end
      end

      state :section_settings do
        mixin :section_include

        rule %r/([A-Z]+(?: [A-Z]+)?)(:?)/i do |m|
          match = m[1].downcase
          @next = if self.class.settings_with_keywords.include? match
                    :keyword
                  elsif self.class.settings_with_args.include? match
                    :args
                  end
          groups Name::Builtin::Pseudo, Punctuation
        end
      end

      state :section_tests do
        mixin :section_include
        
        rule %r/[$@&%{}]+/, Name::Label
        rule %r/( )(?![ |])/, Name::Label

        rule id do
          @is_template = false
          token Name::Label
        end
      end

      state :section_tasks do
        mixin :section_tests
      end

      state :section_keywords do
        mixin :section_include
  
        rule %r/[$@&%]\{/ do
          token Name::Variable
          push :var
        end
        
        rule %r/[$@&%{}]+/, Name::Label
        rule %r/( )(?![ |])/, Name::Label
        
        rule id, Name::Label
      end

      state :section_variables do
        mixin :section_include

        rule %r/[$@&%]\{/ do
          token Name::Variable
          @next = :args
          push :var
        end
      end

      state :cell_start do
        rule %r/#.*/, Comment
        mixin :return
      end

      state :keyword do
        rule %r/(\[)([A-Z]+(?: [A-Z]+)?)(\])/i do |m|
          groups Punctuation, Name::Builtin::Pseudo, Punctuation
          
          match = m[2].downcase
          @is_template = true if match == "template"
          if self.class.settings_with_keywords.include? match
            @next = :keyword
          elsif self.class.settings_with_args.include? match
            @next = :args
          end

          pop!
        end

        rule %r/[$@&%]\{/ do
          token Name::Variable
          @next = :keyword unless @next.nil?
          push :var
        end

        rule %r/FOR/i do
          token Name::Function
          @next = :keyword unless @next.nil?
        end

        rule %r/( )(?![ |])/, Name::Function

        rule bdd, Name::Builtin
        rule id do
          token Name::Function
          @next = nil
        end

        mixin :return
      end

      state :args do
        rule %r/[$@&%]\{/ do
          token Name::Variable
          @next = :keyword unless @next.nil?
          push :var
        end

        rule %r/[$@&%]+/, Str
        rule %r/( )(?![ |])/, Str
        rule id, Str
        
        mixin :return
      end

      state :var do
        rule %r/(\})( )(=)/ do
          groups Name::Variable, Text::Whitespace, Punctuation
          pop!
        end
        rule %r/[$@&%]\{/, Name::Variable, :var
        rule %r/[{\[]/, Name::Variable, :var
        rule %r/[}\]]/, Name::Variable, :pop!
        rule %r/[^$@&%{}\[\]]+/, Name::Variable
        rule %r/\}\[/, Name::Variable
      end
    end
  end
end