nicojensen.de/vendor/bundle/gems/rouge-3.3.0/lib/rouge/lexers/gherkin.rb

139 lines
3.2 KiB
Ruby
Raw Normal View History

2019-03-12 13:49:49 +01:00
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
module Rouge
module Lexers
class Gherkin < RegexLexer
tag 'gherkin'
aliases 'cucumber', 'behat'
title "Gherkin"
desc 'A business-readable spec DSL ( github.com/cucumber/cucumber/wiki/Gherkin )'
filenames '*.feature'
mimetypes 'text/x-gherkin'
def self.detect?(text)
return true if text.shebang? 'cucumber'
end
# self-modifying method that loads the keywords file
def self.keywords
load Pathname.new(__FILE__).dirname.join('gherkin/keywords.rb')
keywords
end
def self.step_regex
# in Gherkin's config, keywords that end in < don't
# need word boundaries at the ends - all others do.
@step_regex ||= Regexp.new(
keywords[:step].map do |w|
if w.end_with? '<'
Regexp.escape(w.chop)
else
"#{Regexp.escape(w)}\\b"
end
end.join('|')
)
end
rest_of_line = /.*?(?=[#\n])/
state :basic do
rule %r(#.*$), Comment
rule /[ \r\t]+/, Text
end
state :root do
mixin :basic
rule %r(\n), Text
rule %r(""".*?""")m, Str
rule %r(@[^\s@]+), Name::Tag
mixin :has_table
mixin :has_examples
end
state :has_scenarios do
rule %r((.*?)(:)) do |m|
reset_stack
keyword = m[1]
keyword_tok = if self.class.keywords[:element].include? keyword
push :description; Keyword::Namespace
elsif self.class.keywords[:feature].include? keyword
push :feature_description; Keyword::Declaration
elsif self.class.keywords[:examples].include? keyword
push :example_description; Name::Namespace
else
Error
end
groups keyword_tok, Punctuation
end
end
state :has_examples do
mixin :has_scenarios
rule Gherkin.step_regex, Name::Function do
token Name::Function
reset_stack; push :step
end
end
state :has_table do
rule(/(?=[|])/) { push :table_header }
end
state :table_header do
rule /[^|\s]+/, Name::Variable
rule /\n/ do
token Text
goto :table
end
mixin :table
end
state :table do
mixin :basic
rule /\n/, Text, :table_bol
rule /[|]/, Punctuation
rule /[^|\s]+/, Name
end
state :table_bol do
rule(/(?=\s*[^\s|])/) { reset_stack }
rule(//) { pop! }
end
state :description do
mixin :basic
mixin :has_examples
rule /\n/, Text
rule rest_of_line, Text
end
state :feature_description do
mixin :basic
mixin :has_scenarios
rule /\n/, Text
rule rest_of_line, Text
end
state :example_description do
mixin :basic
mixin :has_table
rule /\n/, Text
rule rest_of_line, Text
end
state :step do
mixin :basic
rule /<.*?>/, Name::Variable
rule /".*?"/, Str
rule /\S+/, Text
rule rest_of_line, Text, :pop!
end
end
end
end