Class: Tml::Tokens::Transform

Inherits:
Data
  • Object
show all
Defined in:
lib/tml/tokens/transform.rb

Overview

Transform Token Form

|| one: message, many: messages || one: сообщение, few: сообщения, many: сообщений, other: много сообщений in other case the number is not displayed#

| message - will not include count, resulting in “messages” with implied count | message, messages

| message, messages

| he, she, he/she

| male: he, female: she, other: he/she

| did, does, will do | all male, all female, mixed genders

|| message, messages - will include count: “5 messages”

Instance Attribute Summary collapse

Attributes inherited from Data

#case_keys, #context_keys, #full_name, #label, #short_name

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Data

#apply_case, #apply_language_cases, #context_for_language, #decorate, #decoration_name, #error, #initialize, #key, #language_cases_enabled?, #name, #name_for_case_keys, parse, #sanitize, #sanitized_name, #to_s, token_object, #token_object, #token_value, #token_value_from_array_param, #token_value_from_hash_param, #token_values_from_array

Constructor Details

This class inherits a constructor from Tml::Tokens::Data

Instance Attribute Details

#pipe_separatorObject (readonly)

Returns the value of attribute pipe_separator.



57
58
59
# File 'lib/tml/tokens/transform.rb', line 57

def pipe_separator
  @pipe_separator
end

#piped_paramsObject (readonly)

Returns the value of attribute piped_params.



57
58
59
# File 'lib/tml/tokens/transform.rb', line 57

def piped_params
  @piped_params
end

Class Method Details

.expressionObject



59
60
61
# File 'lib/tml/tokens/transform.rb', line 59

def self.expression
  /(%?\{{1,2}\s*[\w]+\s*(:\s*\w+)*\s*\|\|?[^\{\}\|]+\}{1,2})/
end

Instance Method Details

#decoation_nameObject



224
225
226
# File 'lib/tml/tokens/transform.rb', line 224

def decoation_name
  'piped'
end

#displayed_in_translation?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/tml/tokens/transform.rb', line 75

def displayed_in_translation?
  pipe_separator == "||"
end

#generate_value_map(params, context) ⇒ Object

token: one: message, many: messages results in: “message”, “many”: “messages”

token: message transform: [“{$0”, “other”: “Tml::Tokens::Transform.$0$0::plural”}, “{$0”, “other”: “$1”}] results in: “message”, “other”: “messages”

token: message, messages transform: [“{$0”, “other”: “Tml::Tokens::Transform.$0$0::plural”}, “{$0”, “other”: “$1”}] results in: “message”, “other”: “messages”

token: Dorogoi, Dorogaya transform: [“unsupported”, “{$0”, “female”: “$1”, “other”: “$0/$1”}] results in: “Dorogoi”, “female”: “Dorogaya”, “other”: “Dorogoi/Dorogaya”

token: || likes, like transform: [“unsupported”, “{$0”, “other”: “$1”}] results in: “likes”, “other”: “like”



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
# File 'lib/tml/tokens/transform.rb', line 108

def generate_value_map(params, context)
  values = {}

  if params.first.index(':')
    params.each do |p|
      nv = p.split(':')
      values[nv.first.strip] = nv.last.strip
    end
    return values
  end

  unless context.token_mapping
    error("The token context #{context.keyword} does not support transformation for unnamed params: #{full_name}")
    return nil
  end

  token_mapping = context.token_mapping

  # "unsupported"
  if token_mapping.is_a?(String)
    error("The token mapping #{token_mapping} does not support #{params.size} params: #{full_name}")
    return nil
  end

  # ["unsupported", "unsupported", {}]
  if token_mapping.is_a?(Array)
    if params.size > token_mapping.size
      error("The token mapping #{token_mapping} does not support #{params.size} params: #{full_name}")
      return nil
    end
    token_mapping = token_mapping[params.size-1]
    if token_mapping.is_a?(String)
      error("The token mapping #{token_mapping} does not support #{params.size} params: #{full_name}")
      return nil
    end
  end

  # {}
  token_mapping.each do |key, value|
    values[key] = value
    value.scan(/({\$\d(::\w+)*})/).each do |matches|
      token = matches.first
      parts = token[1..-2].split('::')
      index = parts.first.gsub('$', '').to_i

      if params.size < index
        error("The index inside #{context.token_mapping} is out of bound: #{full_name}")
        return nil
      end

      # apply settings cases
      value = params[index]
      if language_cases_enabled?
        parts[1..-1].each do |case_key|
          lcase = context.language.case_by_keyword(case_key)
          unless lcase
            error("Language case #{case_key} for context #{context.keyword} is not defined: #{full_name}")
            return nil
          end
          value = lcase.apply(value)
        end
      end
      values[key] = values[key].gsub(token, value)
    end
  end

  values
end

#implied?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/tml/tokens/transform.rb', line 79

def implied?
  not displayed_in_translation?
end

#parse_elementsObject



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/tml/tokens/transform.rb', line 63

def parse_elements
  name_without_parens = @full_name.gsub(/^%/, '')[1..-2]
  name_without_pipes = name_without_parens.split('|').first.strip
  name_without_case_keys = name_without_pipes.split('::').first.strip

  @short_name = name_without_pipes.split(':').first.strip
  @case_keys = name_without_pipes.scan(/(::\w+)/).flatten.uniq.collect{|c| c.gsub('::', '')}
  @context_keys = name_without_case_keys.scan(/(:\w+)/).flatten.uniq.collect{|c| c.gsub(':', '')}
  @pipe_separator = (full_name.index('||') ? '||' : '|')
  @piped_params = name_without_parens.split(pipe_separator).last.split(",").collect{|param| param.strip}
end

#prepare_label_for_suggestion(label, index, language) ⇒ Object



83
84
85
86
87
88
# File 'lib/tml/tokens/transform.rb', line 83

def prepare_label_for_suggestion(label, index, language)
  context = context_for_language(language)
  values = generate_value_map(piped_params, context)

  label.gsub(full_name, values[context.default_rule] || values.values.first)
end

#substitute(label, context, language, options = {}) ⇒ Object



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
# File 'lib/tml/tokens/transform.rb', line 177

def substitute(label, context, language, options = {})
  object = self.class.token_object(context, key)

  unless object
    return error("Missing value for a token \"#{key}\" in \"#{label}\"", false)
  end

  if piped_params.empty?
    return error("Piped params may not be empty for token \"#{key}\" in \"#{label}\"", false)
  end

  language_context = context_for_language(language)

  unless language_context
    return error("Unknown context for a token: #{full_name} in #{language.locale}", false)
  end

  piped_values = generate_value_map(piped_params, language_context)

  unless piped_values
    return error("Failed to generate value map for: #{full_name} in #{language.locale}", false)
  end

  rule = language_context.find_matching_rule(object)
  return label unless rule

  value = piped_values[rule.keyword]
  if value.nil? and language_context.fallback_rule
    value = piped_values[language_context.fallback_rule.keyword]
  end

  return label unless value

  decorated_value = decorate(token_value(Tml::Utils.hash_value(context, key), language, options), options)

  substitution_value = []
  if displayed_in_translation?
    substitution_value << decorated_value
    substitution_value << ' '
  else
    value = value.gsub("##{short_name}#", decorated_value)
  end
  substitution_value << value

  label.gsub(full_name, substitution_value.join(''))
end