require 'yaml'
module Gherkin
class I18n
KEYWORD_KEYS = %w{name native feature background scenario scenario_outline examples given when then and but}
LANGUAGES = YAML.load_file(File.dirname(__FILE__) + '/i18n.yml')
class << self
# Used by code generators for other lexer tools like pygments lexer and textmate bundle
def all
LANGUAGES.keys.sort.map{|key| get(key)}
end
def get(key)
languages[key] ||= new(key)
end
def languages
@languages ||= {}
end
# Returns all keyword translations and aliases of +keywords+, escaped and joined with |.
# This method is convenient for editor support and syntax highlighting engines for Gherkin, where
# there is typically a code generation tool to generate regular expressions for recognising the
# various I18n translations of Gherkin's keywords.
#
# The +keywords+ arguments can be one of :feature, :background, :scenario,
# :scenario_outline, :examples, :step.
def keyword_regexp(*keywords)
unique_keywords = all.map do |lang|
keywords.map do |keyword|
lang.__send__("#{keyword}_keywords".to_sym)
end
end
unique_keywords.flatten.compact.sort.reverse.uniq.join('|').gsub(/\*/, '\*')
end
end
attr_reader :key
def initialize(key)
@key = key
@keywords = LANGUAGES[key]
raise "Language not supported: #{key.inspect}" if @key.nil?
@keywords['grammar_name'] = @keywords['name'].gsub(/\s/, '')
end
def lexer(listener, force_ruby)
begin
if force_ruby
rb(listener)
else
begin
c(listener)
rescue NameError, LoadError => e
warn("WARNING: #{e.message}. Reverting to Ruby lexer.")
rb(listener)
end
end
rescue LoadError => e
raise I18nLexerNotFound, "No lexer was found for #{i18n_language_name} (#{e.message}). Supported languages are listed in gherkin/i18n.yml."
end
end
def c(listener)
require 'gherkin/c_lexer'
CLexer[sanitized_key].new(listener)
end
def rb(listener)
require 'gherkin/rb_lexer'
RbLexer[sanitized_key].new(listener)
end
def sanitized_key
@key.gsub(/[\s-]/, '_').downcase
end
def incomplete?
KEYWORD_KEYS.detect{|key| @keywords[key].nil?}
end
def feature_keywords
keywords('feature')
end
def scenario_keywords
keywords('scenario')
end
def scenario_outline_keywords
keywords('scenario_outline')
end
def background_keywords
keywords('background')
end
def examples_keywords
keywords('examples')
end
def but_keywords(space=true)
keywords('but', space)
end
def and_keywords(space=true)
keywords('and', space)
end
def step_keywords
%w{given when then and but}.map{|key| keywords(key, true)}.flatten.uniq
end
def gwt_keywords
%w{given when then}.map{|key| keywords(key, true)}.flatten.uniq
end
def keywords(key, space=false)
raise "No #{key} in #{@keywords.inspect}" if @keywords[key].nil?
@keywords[key].split('|').map{|kw| space ? keyword_space(kw) : kw}
end
private
def keyword_space(val)
(val + ' ').sub(/< $/,'')
end
end
end