lib/rouge/lexers/gherkin.rb
# -*- coding: utf-8 -*- # module Rouge module Lexers class Gherkin < RegexLexer tag 'gherkin' aliases 'cucumber', 'behat' desc 'A business-readable spec DSL ( github.com/cucumber/cucumber/wiki/Gherkin )' filenames '*.feature' mimetypes 'text/x-gherkin' def self.analyze_text(text) return 1 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