Skip to content

Instantly share code, notes, and snippets.

@brauliobo
Last active December 16, 2015 23:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brauliobo/5512890 to your computer and use it in GitHub Desktop.
Save brauliobo/5512890 to your computer and use it in GitHub Desktop.
A script to convert your source code`s calls to _() (gettext) to t() (ruby i18n).
#!/usr/bin/env ruby
#
# https://gist.github.com/brauliobo/5512890
# Authors: Bráulio Bhavamitra <brauliobo@gmail.com> and Hugo Melo <hugo@riseup.net>
# License: GPLv3
#
# A script to convert your source code`s calls to _() (gettext) to t() (ruby i18n).
#
# Convert text string to a key along with the file path. Example:
# Call _('Name') into source views/profile/index.index output into config/locales/en.yml:
# views:
# profile:
# index:
# name: Name
#
# Also extract translations from po folders and output to respective yml files in config/locales.
#
# Limitations:
# - Only work within Rails.root directory
# - Ignore calls of _() with multiline strings
# - Can't update yml multiple times
#
### Configurations
SourcePath = 'plugins/distribution'
I18nRootKey = 'distribution_plugin'
CodeLocale = 'en'
PoDir = 'po'
PoFile = 'noosfero.po'
Locales = Dir.chdir(PoDir){ Dir.glob('*').select{ |f| File.directory?(f) } }
KeyTrimSize = 20
require 'rubygems'
require 'ya2yaml'
require File.expand_path(File.join(File.dirname(__FILE__), 'config', 'environment'))
require 'i18n/gettext'
require 'i18n/gettext/po_parser'
class PoData < Hash
def set_comment(msgid_or_sym, comment)
# ignore
end
end
class Hash
def deep_copy
Marshal.load(Marshal.dump(self))
end
end
# result strings for yml
$strings = {CodeLocale => {}}
class CodeFile
SingleQuoteText = /[N]?_\('([^']+)'\)/
DoubleQuoteText = /[N]?_\("([^"]+)"\)/
attr_accessor :filename
attr_accessor :i18n_path
attr_accessor :outdata
attr_accessor :strings
def initialize filename
@filename = filename
@strings = {}
@i18n_path = filename.chomp File.extname(filename)
@i18n_path = @i18n_path.chomp File.extname(@i18n_path)
@i18n_path = @i18n_path.gsub("#{SourcePath}/", '').split('/')
unless I18nRootKey.blank?
# remove/ignore I18nPrefix in parts of path
@i18n_path = [I18nRootKey] + @i18n_path.map do |file|
next if file == I18nRootKey
file.gsub /#{I18nRootKey}_?/, ''
end.compact
end
end
def i18n_method_available?
basename = File.basename filename
not (basename.end_with? '.rb' and not basename.index 'controller')
end
def i18n_method
@i18n_method ||= i18n_method_available? ? 't' : 'I18n.t'
end
def add_key text
key = text.parameterize.underscore.to_s
key = key[0..KeyTrimSize]
key = text if key.blank?
@strings[key] = text
key
end
def migrate_texts
@outdata = File.open(filename).map do |line|
begin
if line =~ SingleQuoteText
regexp = SingleQuoteText
text = $1
elsif line =~ DoubleQuoteText
regexp = DoubleQuoteText
text = $1
else
text = nil
end
if text
key = add_key text
line.sub! regexp, "#{i18n_method}('#{i18n_path.join '.'}.#{key}')"
end
end while text
line
end
end
end
def read_sources
Dir.glob("#{SourcePath}/**/*").each do |filename|
next unless File.file?(filename)
cf = CodeFile.new filename
cf.migrate_texts
next if cf.strings.empty?
# build hash from path parts
file_hash = $strings[CodeLocale]
cf.i18n_path.size.times do |i|
value = cf.i18n_path[i+1]
file_hash[cf.i18n_path[i]] ||= value ? {cf.i18n_path[i+1] => {}} : {}
file_hash = file_hash[cf.i18n_path[i]]
end
file_hash.update cf.strings
# write file
File.open(filename, 'w'){ |o| o << cf.outdata }
end
end
def read_pos
def process po, hash
hash.each do |key, text|
next hash[key] = process(po, text) if text.is_a?(Hash)
text = po[text] if po[text]
hash[key] = text
end
end
Locales.each do |locale|
po = nil
silence_stream(STDERR) do
po = GetText::PoParser.new.parse(File.read("#{PoDir}/#{locale}/#{PoFile}"), PoData.new)
end
$strings[locale] = $strings[CodeLocale].deep_copy
$strings[locale] = process po, $strings[locale]
end
end
def write_yml
locales = ['pt', 'en']
locales.each do |locale|
File.open("config/locales/#{locale}.yml", 'a') do |f|
y = {locale => $strings[locale]}.ya2yaml(:syck_compatible => true).split("\n")
y = y[2..(y.size)].join("\n")
f << "\n#{y}"
end
end
end
read_sources
read_pos
write_yml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment