Permalink
Browse files

Merge branch 'i18n-support-extra-file-object' of git://github.com/kou…

…/yard
  • Loading branch information...
2 parents 4a13128 + 7cc3147 commit 6c7a7b3f9442b7c783b76cff268d0c8bac58b6a8 @lsegal committed Jul 9, 2012
View
@@ -298,6 +298,8 @@ def parse_arguments(*args)
add_visibility_verifier
add_api_verifier
+ apply_locale
+
# US-ASCII is invalid encoding for onefile
if defined?(::Encoding) && options.onefile
if ::Encoding.default_internal == ::Encoding::US_ASCII
@@ -489,6 +491,15 @@ def add_api_verifier
options.verifier.add_expressions(expr)
end
+ # Applies the specified locale to collected objects
+ # @return [void]
+ # @since 0.8.3
+ def apply_locale
+ options.files.each do |file|
+ file.locale = options.locale
+ end
+ end
+
# (see Templates::Helpers::BaseHelper#run_verifier)
def run_verifier(list)
options.verifier ? options.verifier.run(list) : list
@@ -735,6 +746,18 @@ def output_options(opts)
opts.on('--no-stats', 'Don\'t print statistics') do
self.statistics = false
end
+
+ opts.on('--locale LOCALE',
+ 'The locale for generated documentation.',
+ ' (defaults to en)') do |locale|
+ options.locale = locale
+ end
+
+ opts.on('--po-dir DIR',
+ 'The directory that has .po files.',
+ ' (defaults to #{YARD::Registry.po_dir})') do |dir|
+ YARD::Registry.po_dir = dir
+ end
end
# Adds tag options
@@ -5,9 +5,10 @@ module YARD::CodeObjects
# compatible with most CodeObject interfaces.
class ExtraFileObject
attr_accessor :filename
- attr_accessor :attributes
+ attr_writer :attributes
attr_accessor :name
- attr_accessor :contents
+ # @since 0.8.3
+ attr_reader :locale
# Creates a new extra file object.
# @param [String] filename the location on disk of the file
@@ -17,15 +18,41 @@ def initialize(filename, contents = nil)
self.filename = filename
self.name = File.basename(filename).gsub(/\.[^.]+$/, '')
self.attributes = SymbolHash.new(false)
- parse_contents(contents || File.read(@filename))
+ @original_contents = contents
+ @parsed = false
+ @locale = nil
+ ensure_parsed
end
alias path name
+ def attributes
+ ensure_parsed
+ @attributes
+ end
+
def title
attributes[:title] || name
end
+ def contents
+ ensure_parsed
+ @contents
+ end
+
+ def contents=(contents)
+ @original_contents = contents
+ @parsed = false
+ end
+
+ # @param [String] locale the locale name to be translated.
+ # @return [void]
+ # @since 0.8.3
+ def locale=(locale)
+ @locale = locale
+ @parsed = false
+ end
+
def inspect
"#<yardoc #{type} #{filename} attrs=#{attributes.inspect}>"
end
@@ -43,10 +70,17 @@ def hash; filename.hash end
private
+ def ensure_parsed
+ return if @parsed
+ @parsed = true
+ @contents = parse_contents(@original_contents || File.read(@filename))
+ end
+
# @param [String] data the file contents
def parse_contents(data)
retried = false
cut_index = 0
+ data = translate(data)
data = data.split("\n")
data.each_with_index do |line, index|
case line
@@ -65,7 +99,7 @@ def parse_contents(data)
end
end
data = data[cut_index..-1] if cut_index > 0
- self.contents = data.join("\n")
+ contents = data.join("\n")
if contents.respond_to?(:force_encoding) && attributes[:encoding]
begin
@@ -74,16 +108,21 @@ def parse_contents(data)
log.warn "Invalid encoding `#{attributes[:encoding]}' in #{filename}"
end
end
+ contents
rescue ArgumentError => e
if retried && e.message =~ /invalid byte sequence/
# This should never happen.
log.warn "Could not read #{filename}, #{e.message}. You probably want to set `--charset`."
- self.contents = ''
- return
+ return ''
end
data.force_encoding('binary') if data.respond_to?(:force_encoding)
retried = true
retry
end
+
+ def translate(data)
+ text = YARD::I18n::Text.new(data, :have_header => true)
+ text.translate(YARD::Registry.locale(locale))
+ end
end
end
View
@@ -25,6 +25,8 @@ def initialize(name)
# {#name}.po.
# @return [Boolean] +true+ if PO file exists, +false+ otherwise.
def load(locale_directory)
+ return false if @name.nil?
+
po_file = File.join(locale_directory, "#{@name}.po")
return false unless File.exist?(po_file)
View
@@ -31,6 +31,7 @@ module YARD
module Registry
DEFAULT_YARDOC_FILE = ".yardoc"
LOCAL_YARDOC_INDEX = File.expand_path('~/.yard/gem_index')
+ DEFAULT_PO_DIR = "po"
extend Enumerable
@@ -239,6 +240,13 @@ def at(path) path ? thread_local_store[path] : nil end
# @return [CodeObjects::RootObject] the root object in the namespace
def root; thread_local_store[:root] end
+ # @param [String] name the locale name.
+ # @return [I18n::Locale] the locale object for +name+.
+ # @since 0.8.3
+ def locale(name)
+ thread_local_store.locale(name)
+ end
+
# Attempts to find an object by name starting at +namespace+, performing
# a lookup similar to Ruby's method of resolving a constant in a namespace.
#
@@ -347,6 +355,17 @@ def proxy_types
thread_local_store.proxy_types
end
+ # @group I18n features
+
+ # Gets/sets the directory that has LANG.po files
+ # @return [String] the directory that has .po files
+ attr_accessor :po_dir
+ undef po_dir, po_dir=
+ def po_dir=(dir) Thread.current[:__yard_po_dir__] = dir end
+ def po_dir
+ Thread.current[:__yard_po_dir__] ||= DEFAULT_PO_DIR
+ end
+
# @group Legacy Methods
# The registry singleton instance.
View
@@ -19,6 +19,7 @@ def initialize
@notfound = {}
@loaded_objects = 0
@available_objects = 0
+ @locales = {}
@store[:root] = CodeObjects::RootObject.allocate
@store[:root].send(:initialize, nil, :root)
end
@@ -108,6 +109,13 @@ def values_for_type(type, reload = false)
# @return [CodeObjects::RootObject] the root object
def root; @store[:root] end
+ # @param [String] name the locale name.
+ # @return [I18n::Locale] the locale object for +name+.
+ # @since 0.8.3
+ def locale(name)
+ @locales[name] ||= load_locale(name)
+ end
+
# @param [String, nil] file the name of the yardoc db to load
# @return [Boolean] whether the database was loaded
def load(file = nil)
@@ -283,6 +291,12 @@ def load_root
end
end
+ def load_locale(name)
+ locale = I18n::Locale.new(name)
+ locale.load(Registry.po_dir)
+ locale
+ end
+
def all_disk_objects
Dir.glob(File.join(objects_path, '**/*')).select {|f| File.file?(f) }
end
@@ -302,4 +316,4 @@ def write_checksums
end
end
end
-end
+end
View
@@ -77,6 +77,10 @@
it "should not embed mixins by default" do
@yardoc.options.embed_mixins.should be_empty
end
+
+ it "should not set any locale by default" do
+ @yardoc.options.locale.should be_nil
+ end
end
describe 'General options' do
@@ -303,6 +307,32 @@ def self.should_accept(*args, &block)
end
end
end
+
+ describe '--locale' do
+ it 'should apply specified locale to all extra file objects' do
+ File.stub!(:read).with('extra_file1').and_return('')
+ File.stub!(:read).with('extra_file2').and_return('')
+
+ extra_file_object1 = CodeObjects::ExtraFileObject.new('extra_file1')
+ extra_file_object2 = CodeObjects::ExtraFileObject.new('extra_file2')
+ extra_file_object1.should_receive(:locale=).with('fr')
+ extra_file_object2.should_receive(:locale=).with('fr')
+
+ CodeObjects::ExtraFileObject.stub!(:new).with('extra_file1').and_return(extra_file_object1)
+ CodeObjects::ExtraFileObject.stub!(:new).with('extra_file2').and_return(extra_file_object2)
+ Dir.stub!(:glob).with('README*').and_return([])
+ File.stub!(:file?).with('extra_file1').and_return(true)
+ File.stub!(:file?).with('extra_file2').and_return(true)
+ @yardoc.run('--locale=fr', '-', 'extra_file1', 'extra_file2')
+ end
+ end
+
+ describe '--po-dir' do
+ it 'should set Registry.po_dir' do
+ Registry.should_receive(:po_dir=).with("locale")
+ @yardoc.run('--po-dir=locale')
+ end
+ end
end
describe '--[no-]api' do
@@ -114,6 +114,18 @@
end
end
+ describe '#locale=' do
+ it "should translate contents" do
+ file = ExtraFileObject.new('file.txt', 'Hello')
+ file.locale = 'fr'
+ fr_locale = I18n::Locale.new('fr')
+ fr_messages = fr_locale.instance_variable_get(:@messages)
+ fr_messages["Hello"] = 'Bonjour'
+ Registry.should_receive(:locale).with('fr').and_return(fr_locale)
+ file.contents.should == 'Bonjour'
+ end
+ end
+
describe '#==' do
it "should define equality on filename alone" do
file1 = ExtraFileObject.new('file.txt', 'A')
View
@@ -81,6 +81,15 @@
end
end
+ describe '.locale' do
+ it "should load locale object" do
+ fr_locale = I18n::Locale.new("fr")
+ store = Registry.send(:thread_local_store)
+ store.should_receive(:locale).with("fr").and_return(fr_locale)
+ Registry.locale("fr").should == fr_locale
+ end
+ end
+
describe '.resolve' do
it "should resolve any existing namespace" do
o1 = ModuleObject.new(:root, :A)
@@ -355,5 +364,30 @@ def self.Bar; end
it "should automatically clear in new threads" do
Thread.new { Registry.all.should be_empty }.join
end
+
+ it "should allow setting of po_dir in separate threads" do
+ barrier = 0
+ mutex = Mutex.new
+ threads = []
+ threads << Thread.new do
+ Registry.po_dir.should == 'po'
+ Registry.po_dir = 'locale'
+ mutex.synchronize { barrier += 1 }
+ while barrier == 1 do
+ s = "barrier = 1, spinning"
+ end
+ Registry.po_dir.should == 'locale'
+ end
+ threads << Thread.new do
+ while barrier == 0 do
+ s = "barrier = 0, spinning"
+ end
+ Registry.po_dir.should == 'po'
+ mutex.synchronize { barrier += 1 }
+ Registry.po_dir = '.'
+ end
+ threads.each {|t| t.join }
+ Registry.po_dir = Registry::DEFAULT_PO_DIR
+ end
end
end
@@ -302,4 +302,14 @@ def saves_to_multidb
@store.destroy(true).should == true
end
end
+
+ describe '#locale' do
+ it "should load ./po/LOCALE_NAME.po" do
+ fr_locale = I18n::Locale.new("fr")
+ I18n::Locale.should_receive(:new).with("fr").and_return(fr_locale)
+ Registry.should_receive(:po_dir).and_return("po")
+ fr_locale.should_receive(:load).with("po")
+ @store.locale("fr").should == fr_locale
+ end
+ end
end

0 comments on commit 6c7a7b3

Please sign in to comment.