Last active
December 16, 2015 23:19
-
-
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# | |
# https://gist.github.com/brauliobo/5512890 | |
# Authors: Bráulio Bhavamitra <[email protected]> and Hugo Melo <[email protected]> | |
# 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