Очень странная проблема с Gettext и Haml on Rails / rake updatepo сломалась - PullRequest
2 голосов
/ 05 августа 2009

Я на Rails 2.3.3 и использую Haml 2.0.9 для своих шаблонов и Gettext-Rails 2.0.4 для перевода. Haml работает как шарм, а gettext также работает как надо.

Но я не могу получить Gettext для анализа файлов Haml при использовании "rake updatepo". Я создал собственный синтаксический анализатор, как это:

# lib/haml_parser.rb
require 'gettext_rails/tools'
require 'haml'
# Haml gettext parser
module HamlParser
  module_function

  def target?(file)
    File.extname(file) == ".haml"
  end

  def parse(file, ary = [])
    haml = Haml::Engine.new(IO.readlines(file).join)
    code = haml.precompiled.split(/$/)
    GetText::RubyParser.parse_lines(file, code, ary)
  end
end

GetText::RGetText.add_parser(HamlParser)

Мой Rakefile выглядит так:

# Rakefile
require(File.join(File.dirname(__FILE__), 'config', 'boot'))

require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'

require 'tasks/rails'

desc "Create mo-files for L10n"
task :makemo do
  require 'gettext_rails/tools'
  GetText.create_mofiles(true)  #(true, "po", "locale")
end

desc "Update pot/po files to match new version."
task :updatepo do
  require 'gettext_rails/tools'
  require 'haml_parser'
  MY_APP_TEXT_DOMAIN = "APP" 
  MY_APP_VERSION     = "APP 1.1.0"
  GetText.update_pofiles(MY_APP_TEXT_DOMAIN, Dir.glob("{app,lib}/**/*.{rb,rhtml,html.erb,haml,html.haml,rjs}"),
                         MY_APP_VERSION)
end

Это следует известному подходу для разбора файлов Haml (http://www.paulgillard.me.uk/2008/3/8/rails-haml-and-gettext).

Проблема: из моих файлов Haml не распознаются идентификаторы сообщений. Я проверил с помощью «put» в Haml-Parser, проверял ли он правильные файлы, мог ли их анализировать и так далее. Казалось бы, все в порядке, он просто распознает все и всегда возвращает только найденные сообщения, а для файла Haml - пустой массив.

Странная вещь: когда я вхожу в консоль, все работает:

$$ script/console
Loading development environment (Rails 2.3.3)
>> require 'gettext_rails/tools'
=> []
>> require 'haml'
=> []
>> file = "app/views/sessions/new.haml"
=> "app/views/sessions/new.haml"
>> haml = Haml::Engine.new(IO.readlines(file).join)
=> #<Haml::Engine:0x4254104 @tab_change=0, @block_opened=false, @inden [...]
>> code = haml.precompiled.split(/$/)
=> [" content_for :head do;", "\nhaml_temp =  stylesheet_link [...]
>> GetText::RubyParser.parse_lines(file, code, [])
=> [["Login", "app/views/sessions/new.haml:4"], [...]

Как видите, все работает здесь (я пропустил длинные возвраты). Я немного волнуюсь, почему это не так в моей «Рейк-задаче».

У кого-нибудь есть идея? Ты действительно сделал бы меня счастливым ботаником!

Спасибо!

Ответы [ 3 ]

2 голосов
/ 09 мая 2010

Просто у меня была такая же проблема, и после небольшой отладки я нашел причину: большая часть вывода в Haml генерируется инструкциями внутри #{} в "" строках, и эта конструкция, кажется, обманывает класс RubyParser. Если бы у вас было что-то вроде "#{_('some text')}" в «нормальном» Ruby-файле, это тоже не было бы распознано.

Мое решение состояло в том, чтобы немного перемешать прекомпилированный код Haml и получать вызовы _() за пределами "#{}". Это то, что регулярное выражение делает в строке 4.

  def parse(file, ary = [])
    haml = Haml::Engine.new(IO.readlines(file).join)
    code = haml.precompiled
    code = code.gsub(/(.*#\{(_hamlout.adjust_tabs\(\d+\);\s*)?haml_temp)\s*=\s*(_\(['"].+['"]\))/) { |m| "haml_temp = #{$3}; #{$1}" }
    code = code.split(/$/)
    GetText::RubyParser.parse_lines(file, code, ary)
  end

Это исправляет около 80% случаев в моем проекте, что было достаточно для меня. Оставшиеся 20% иногда можно исправить, изменив:

%tag= _('text')

в

%tag
  = _('text')

И если это не поможет, вы можете воспользоваться следующим приемом:

- txt = _('text')
= txt

Пока еще не пробовал гем ruby_gettext_extractor.

0 голосов
/ 16 октября 2009

Попробуйте изменить ваш haml_parser.rb, чтобы увидеть, где парсер застревает.

  def parse(file, ary = [])
    haml = Haml::Engine.new(IO.readlines(file).join)
    code = haml.precompiled.split(/$/)
    puts "Parsing Haml File: #{file}"
    RubyParser.parse_lines(file, code, ary)
  end

У меня собственные проблемы с обновлением настроек.

Rails 2.3.4
gettext 2.0.4
haml 2.2.8

Из того, что я понял, это во многом связано с изменением HAML 2.2. Движок, который сделал его вывод неразборчивым по умолчанию gettext RubyParser.

Я попробовал драгоценные камни retoo-ruby_gettext_extractor (0.2.1) это зависит от ruby_parser без успеха.

Этот ruby_parser имеет собственный класс RubyParser и конфликтует с Модуль Gettext RubyParser. Итак, вот классический случай, почему мы должны Пространство имен нашего кода. -_-

После взлома его на работу, изменив имена RubyParser в драгоценные камни, я могу заставить его работать для анализа файлов шаблонов, используя retoo's gettext_extractor / rubyparser gems. Однако парсер не работает на мои нелатинские файлы шаблонов. Мой класс HamlParser, как показано ниже. Любой может идти и исправить это? Миллион спасибо!

# haml_parser.rb
require 'rubygems'
require 'haml'
require 'gettext_rails/tools'
require 'ruby_gettext_extractor'

module HamlParser
  module_function

  def target?(file)
    File.extname(file) == '.haml'
  end

  def parse(file, ary = [])
    bypass = ! File.basename(file, 
'.haml').match(/(vi|zh|zh_HK|id|th)$/).nil?
    puts "HamlParser:#{file}:bypass:#{bypass}"
    return ary if bypass

    haml = Haml::Engine.new(IO.readlines(file).join)
    result = nil
    begin
      #result = GetText::RubyParser.parse_lines(file, 
haml.precompiled.split(/$/), ary)
      result = RubyGettextExtractor.parse_string(haml.precompiled, file, 
ary)
    rescue Exception => e
      puts "Error:#{file}"
      raise e
    end
    result
  end
end

GetText::RGetText.add_parser(HamlParser)
0 голосов
/ 15 октября 2009

ruby_gettext_extractor может помочь исправить извлечение строки gettext. Особенно, когда вы используете HAML 2.2, который изменил свой внутренний формат и полностью нарушил процесс извлечения gettext.

...