Class: I18nliner::PreProcessors::ErbPreProcessor::TBlock

Inherits:
Context
  • Object
show all
Includes:
CallHelpers
Defined in:
lib/i18nliner/pre_processors/erb_pre_processor.rb

Constant Summary collapse

TEMP_PLACEHOLDER =
/(?<content>__I18NLINER_\d+__)/

Constants included from CallHelpers

CallHelpers::ALLOWED_PLURALIZATION_KEYS, CallHelpers::REQUIRED_PLURALIZATION_KEYS

Instance Attribute Summary

Attributes inherited from Context

#buffer, #parent

Instance Method Summary collapse

Methods included from CallHelpers

#infer_arguments, #infer_key, #infer_pluralization_hash, #key_provided?, #keyify, #keyify_underscored, #keyify_underscored_crc32, #normalize_default, #normalize_key, #normalize_whitespace, #pluralization_hash?

Constructor Details

#initialize(parent, content) ⇒ TBlock

Returns a new instance of TBlock.



88
89
90
91
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 88

def initialize(parent, content)
  super(parent)
  @lines = content.count("\n")
end

Instance Method Details

#<<(string) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 93

def <<(string)
  case string
  when ERB_BLOCK_EXPRESSION
    if string =~ ERB_T_BLOCK_EXPRESSION
      TBlock.new(self, $&)
    else
      raise TBlockNestingError.new("can't nest block expressions inside a t block")
    end
  when ERB_STATEMENT
    if string =~ ERB_END_STATEMENT
      @parent << result
    else
      raise TBlockNestingError.new("can't nest statements inside a t block")
    end
  else
    # expressions and the like are handled a bit later
    # TODO: perhaps a tad more efficient to capture/transform them
    # here?
    @buffer << string
    self
  end
end

#extract_helper_wrappers!(source, wrappers, placeholder_map) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 179

def extract_helper_wrappers!(source, wrappers, placeholder_map)
  source.gsub(TEMP_PLACEHOLDER) do |string|
    if (helper = Helper.match_for(placeholder_map[string])) && helper.wrappable?
      placeholder_map.delete(string)
      if helper.placeholder # e.g. link_to(name) -> *%{name}*
        helper.content = "__I18NLINER_#{placeholder_map.size}__"
        placeholder_map[helper.content] = helper.placeholder
      end
      pos = find_or_add_wrapper(helper.wrapper, wrappers)
      wrap(helper.content, pos + 1)
    else
      string
    end
  end
end

#extract_html_wrappers!(source, wrappers, placeholder_map) ⇒ Object

incidentally this converts entities to their corresponding values



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 159

def extract_html_wrappers!(source, wrappers, placeholder_map)
  default = ''
  nodes = Nokogiri::HTML.fragment(source).children
  nodes.each do |node|
    if node.is_a?(Nokogiri::XML::Text)
      default << node.content
    elsif text = extract_text(node)
      wrapper = node.to_s.sub(text, "\\\\1")
      wrapper = prepare_wrapper(wrapper, placeholder_map)
      pos = find_or_add_wrapper(wrapper, wrappers)
      default << wrap(text, pos + 1)
    else # no wrapped text (e.g. <input>)
      key = "__I18NLINER_#{placeholder_map.size}__"
      placeholder_map[key] = node.to_s.inspect << ".html_safe"
      default << key
    end
  end
  default
end

#extract_placeholders!(buffer = @buffer, pattern = ERB_EXPRESSION, wrap_placeholder = true) ⇒ Object



209
210
211
212
213
214
215
216
217
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 209

def extract_placeholders!(buffer = @buffer, pattern = ERB_EXPRESSION, wrap_placeholder = true)
  map = {}
  buffer.gsub!(pattern) do |str|
    key, str = yield($~[:content], map)
    map[key] = str
    wrap_placeholder ? "%{#{key}}" : key
  end
  map
end

#extract_temp_placeholders!Object



203
204
205
206
207
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 203

def extract_temp_placeholders!
  extract_placeholders!(@buffer, ERB_EXPRESSION, false) do |str, map|
    ["__I18NLINER_#{map.size}__", str]
  end
end

#extract_text(root_node) ⇒ Object



251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 251

def extract_text(root_node)
  text = nil
  nodes = root_node.children.to_a
  while node = nodes.shift
    if node.is_a?(Nokogiri::XML::Text) && !node.content.strip.empty?
      raise UnwrappableContentError.new "multiple text nodes in html markup" if text
      text = node.content
    else
      nodes.concat node.children
    end
  end
  text
end

#extract_wrappers!(source, wrappers, placeholder_map) ⇒ Object



144
145
146
147
148
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 144

def extract_wrappers!(source, wrappers, placeholder_map)
  source = extract_html_wrappers!(source, wrappers, placeholder_map)
  source = extract_helper_wrappers!(source, wrappers, placeholder_map)
  source
end

#find_or_add_wrapper(wrapper, wrappers) ⇒ Object



150
151
152
153
154
155
156
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 150

def find_or_add_wrapper(wrapper, wrappers)
  unless pos = wrappers.index(wrapper)
    pos = wrappers.size
    wrappers << wrapper
  end
  pos
end

#infer_interpolation_key(string, others) ⇒ Object

get a unique and reasonable looking key for a given erb expression



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 128

def infer_interpolation_key(string, others)
  key = string.downcase
  key.sub!(/\.html_safe\z/, '')
  key.gsub!(/[^a-z0-9]/, ' ')
  key.strip!
  key.gsub!(/ +/, '_')
  key.slice!(20)
  i = 0
  base_key = key
  while others.key?(key) && others[key] != string
    key = "#{base_key}_#{i}"
    i += 1
  end
  key
end

#infer_wrappers(source) ⇒ Object



270
271
272
273
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 270

def infer_wrappers(source)
  wrappers = []
  [source, wrappers]
end

#normalize_callObject



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 220

def normalize_call
  wrappers = []

  temp_map = extract_temp_placeholders!
  default = extract_wrappers!(@buffer, wrappers, temp_map)
  options = extract_placeholders!(default, TEMP_PLACEHOLDER) do |str, map|
    [infer_interpolation_key(temp_map[str], map), temp_map[str]]
  end

  default.strip!
  default.gsub!(/\s+/, ' ')

  key = infer_key(default, options)
  default = default.inspect
  options = options_to_ruby(options)
  wrappers = wrappers_to_ruby(wrappers)
  [key, default, options, wrappers]
end

#options_to_ruby(options) ⇒ Object



239
240
241
242
243
244
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 239

def options_to_ruby(options)
  options["i18nliner_inferred_key"] = "true"
  options.map do |key, value|
    ":" << key << " => (" << value << ")"
  end.join(", ")
end

#prepare_wrapper(content, placeholder_map) ⇒ Object



195
196
197
198
199
200
201
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 195

def prepare_wrapper(content, placeholder_map)
  content = content.inspect
  content.gsub!(TEMP_PLACEHOLDER) do |key|
    "\#{#{placeholder_map[key]}}"
  end
  content
end

#resultObject



116
117
118
119
120
121
122
123
124
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 116

def result
  @lines += @buffer.count("\n")
  key, default, options, wrappers = normalize_call
  result = "<%= t :#{key}, #{default}"
  result << ", " << options if options
  result << ", " << wrappers if wrappers
  result << (@lines > 0 ? "\n" * @lines : " ")
  result << "%>"
end

#wrap(text, index) ⇒ Object



265
266
267
268
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 265

def wrap(text, index)
  delimiter = "*" * index
  "" << delimiter << text << delimiter
end

#wrappers_to_ruby(wrappers) ⇒ Object



246
247
248
249
# File 'lib/i18nliner/pre_processors/erb_pre_processor.rb', line 246

def wrappers_to_ruby(wrappers)
  return if wrappers.size == 0
  ":wrappers => [" << wrappers.join(", ") << "]"
end