Kouhei Sutou
null+****@clear*****
Thu Dec 19 14:52:36 JST 2013
Kouhei Sutou 2013-12-19 14:52:36 +0900 (Thu, 19 Dec 2013) New Revision: a118deff8bfcadb455aceaf7872cf69caf005952 https://github.com/droonga/droonga.org/commit/a118deff8bfcadb455aceaf7872cf69caf005952 Message: Add i18n feature See _doc/i18n.md for workflow. Added files: Rakefile _doc/i18n.md _tasks/i18n.rb Modified files: .gitignore _config.yml Modified: .gitignore (+5 -1) =================================================================== --- .gitignore 2013-12-18 19:41:53 +0900 (0baf015) +++ .gitignore 2013-12-19 14:52:36 +0900 (a67bcc6) @@ -1 +1,5 @@ -/_site +*.edit.po +*.edit.po~ +*.pot +/_site/ +/_po/*.po Added: Rakefile (+30 -0) 100644 =================================================================== --- /dev/null +++ Rakefile 2013-12-19 14:52:36 +0900 (cd660ac) @@ -0,0 +1,30 @@ +# -*- ruby -*- +# +# Copyright (C) 2013 Droonga Project +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +require_relative "_tasks/i18n" + +I18nTask.define do |task| + task.locales = ["ja"] + task.files = Rake::FileList["**/*.md"] + task.files -= Rake::FileList["_*/**/*.md"] + task.files -= Rake::FileList["news/**/*.md"] + task.locales.each do |locale| + task.files -= Rake::FileList["#{locale}/**/*.md"] + end +end + +task :default => "i18n:translate" Modified: _config.yml (+1 -0) =================================================================== --- _config.yml 2013-12-18 19:41:53 +0900 (09cb046) +++ _config.yml 2013-12-19 14:52:36 +0900 (b603a22) @@ -2,3 +2,4 @@ title: Droonga markdown: kramdown droonga_version: 0.7.0 copyright_year: 2013 +exclude: ["Rakefile"] Added: _doc/i18n.md (+48 -0) 100644 =================================================================== --- /dev/null +++ _doc/i18n.md 2013-12-19 14:52:36 +0900 (7ea75d2) @@ -0,0 +1,48 @@ +# Internationalization + +This documentation describes how to translate the original documentations in English to other languates. + +## Workflow + + 1. Run `rake`. + 2. Translate `_po/${YOUR_LOCALE}/${PATH_TO_TARGET_FILE}.edit.po`. + 3. Run `rake`. + 4. Confirm `${YOUR_LOCALE}/${PATH_TO_TARGET_FILE}.html`. + 5. Commit `_po/${YOUR_LOCALE}/${PATH_TO_TARGET_FILE}.po` (not `.edit.po`) and ``${YOUR_LOCALE}/${PATH_TO_TARGET_FILE}.html`. + +Here is an example to translate `overview/index.md` into Japanese. + +Run `rake`: + +``` +% rake +``` + +Translate `_po/ja/overview/index.edit.po`: + +``` +% gedit _po/ja/overview/index.edit.po +``` + +Note: You can use PO editor instead of text editor. For example, Emacs's po-mode, Vim, [Gtranslator](https://wiki.gnome.org/Apps/Gtranslator), [Lokalize](http://userbase.kde.org/Lokalize) and so on. + +Run `rake`: + +``` +% rake +``` + +Confirm `ja/overview/index.html`: + +``` +% firefox ja/overview/index.html +``` + +Commit `_po/ja/overview/index.po` and `ja/overview/index.html`: + +``` +% git add _po/ja/overview/index.po +% git add ja/overview/index.html +% git commit +% git push +``` Added: _tasks/i18n.rb (+212 -0) 100644 =================================================================== --- /dev/null +++ _tasks/i18n.rb 2013-12-19 14:52:36 +0900 (1dc5214) @@ -0,0 +1,212 @@ +# Copyright (C) 2013 Droonga Project +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +require "pathname" +require "yard" +require "gettext/tools" + +class I18nTask + class << self + def define(&block) + task = new + yield(task) if block_given? + task.define + end + end + + include Rake::DSL + + attr_accessor :locales + attr_accessor :files + def initialize + @po_dir_path = Pathname.new("_po") + @base_dir_path = Pathname.new(".") + @locales = [] + @files = [] + @yard_locales = {} + end + + def define + namespace :i18n do + namespace :po do + namespace :edit do + define_edit_po_update_task + end + + define_po_update_task + end + + define_translate_task + end + end + + private + def define_edit_po_update_task + @locales.each do |locale| + namespace locale do + define_edit_po_locale_update_task(locale) + end + end + end + + def define_edit_po_locale_update_task(locale) + base_po_dir_path = @po_dir_path + locale + all_po_file_path = @po_dir_path + "#{locale}.po" + + edit_po_file_paths = [] + @files.each do |target_file| + base_name = File.basename(target_file, ".*") + po_dir_path = base_po_dir_path + File.dirname(target_file) + edit_po_file_path = po_dir_path + "#{base_name}.edit.po" + edit_po_file_paths << edit_po_file_path + + directory po_dir_path.to_s + file edit_po_file_path.to_s => [target_file, po_dir_path.to_s] do + relative_base_path = @base_dir_path.relative_path_from(po_dir_path) + generator = YARD::I18n::PotGenerator.new(relative_base_path.to_s) + yard_file = YARD::CodeObjects::ExtraFileObject.new(target_file) + generator.parse_files([yard_file]) + pot_file_path = po_dir_path + "#{base_name}.pot" + pot_file_path.open("w") do |pot_file| + pot_file.puts(generator.generate) + end + if edit_po_file_path.exist? + GetText::Tools::MsgMerge.run("--update", + "--sort-by-file", + "--no-wrap", + edit_po_file_path.to_s, + pot_file_path.to_s) + else + GetText::Tools::MsgInit.run("--input", pot_file_path.to_s, + "--output", edit_po_file_path.to_s, + "--locale", "ja") + end + if all_po_file_path.exist? + GetText::Tools::MsgMerge.run("--output", edit_po_file_path.to_s, + "--sort-by-file", + "--no-fuzzy-matching", + all_po_file_path.to_s, + edit_po_file_path.to_s) + end + end + end + + desc "Update .edit.po files for [#{locale}] locale" + task :update => edit_po_file_paths.collect(&:to_s) + end + + def define_po_update_task + @locales.each do |locale| + namespace locale do + define_po_locale_update_task(locale) + end + end + + all_update_tasks =****@local***** do |locale| + "i18n:po:#{locale}:update" + end + desc "Update .po files for all locales" + task :update => all_update_tasks + end + + def define_po_locale_update_task(locale) + base_po_dir_path = @po_dir_path + locale + all_po_file_path = @po_dir_path + "#{locale}.po" + + po_file_paths = [] + @files.each do |target_file| + base_name = File.basename(target_file, ".*") + po_dir_path = base_po_dir_path + File.dirname(target_file) + po_file_path = po_dir_path + "#{base_name}.po" + edit_po_file_path = po_dir_path + "#{base_name}.edit.po" + po_file_paths << po_file_path + + file po_file_path.to_s => [edit_po_file_path.to_s] do + GetText::Tools::MsgMerge.run("--output", po_file_path.to_s, + "--sort-by-file", + "--no-location", + "--no-fuzzy-matching", + edit_po_file_path.to_s, + edit_po_file_path.to_s) + end + end + + file all_po_file_path.to_s => po_file_paths.collect(&:to_s) do + sh("msgcat", + "--output", all_po_file_path.to_s, + "--use-first", + "--no-location", + "--sort-output", + *po_file_paths.collect(&:to_s)) + end + + desc "Update .po files for [#{locale}] locale" + task :update => all_po_file_path.to_s + end + + def define_translate_task + @locales.each do |locale| + namespace locale do + define_locale_translate_task(locale) + end + end + + all_translate_tasks =****@local***** do |locale| + "i18n:#{locale}:translate" + end + desc "Translate files for all locales" + task :translate => all_translate_tasks + end + + def define_locale_translate_task(locale) + translated_files = [] + @files.each do |target_file| + translated_file = Pathname(locale) + target_file + translated_files << translated_file + + translated_file_dir = translated_file.parent + directory translated_file_dir.to_s + dependencies = [ + target_file, + "i18n:po:#{locale}:update", + translated_file_dir.to_s, + ] + file translated_file.to_s => dependencies do + File.open(target_file) do |input| + text = YARD::I18n::Text.new(input) + File.open(translated_file, "w") do |output| + output.puts(text.translate(yard_locale(locale))) + end + end + end + end + + desc "Translate files for [#{locale}] locale" + task :translate => translated_files + end + + def yard_locale(locale) + @yard_locales[locale] ||= create_yard_locale(locale) + end + + def create_yard_locale(locale) + yard_locale = YARD::I18n::Locale.new(locale) + messages = GetText::MO.new + po_parser = GetText::POParser.new + po_parser.parse_file(@po_dir_path + "#{locale}.po", messages) + yard_locale.instance_variable_get("@messages").merge!(messages) + yard_locale + end +end -------------- next part -------------- HTML����������������������������...Download