lib/packnga/reference-task.rb in packnga-0.9.5 vs lib/packnga/reference-task.rb in packnga-0.9.6

- old
+ new

@@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2011 Haruka Yoshihara <yoshihara@clear-code.com> +# Copyright (C) 2011-2012 Haruka Yoshihara <yoshihara@clear-code.com> +# Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com> # # 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. # @@ -44,22 +45,33 @@ # This attribute is used to set text files for document. # @return [Array<String>] target text files attr_accessor :text_files + # This attribute is used to set the language you wrote original + # document. Its default value is your current locale. + # @return [String] language you used to write document + attr_accessor :original_language + + # This attribute is used to set languages for tnanslated document. + # If original_language isn't one, its default value is English. + # Otherwise, it is not specified. + # @return [Array<String>] target languages + attr_accessor :translate_languages + # @private def initialize(spec) @spec = spec @base_dir = nil + @original_language = nil @translate_languages = nil @supported_languages = nil @source_files = nil @text_files = nil @readme = nil @extra_files = nil @files = nil - @html_files = nil @po_dir = nil @pot_file = nil end # @private @@ -74,28 +86,40 @@ end private def set_default_values @base_dir ||= Pathname.new("doc") - @translate_languages ||= [:ja] - @supported_languages = [:en, *@translate_languages] - @html_files = FileList[(doc_en_dir + "**/*.html").to_s].to_a + @original_language ||= current_language + if @original_language == "en" + @translate_languages ||= [] + else + @translate_languages ||= ["en"] + end + @supported_languages = [@original_language, *@translate_languages] @po_dir = "#{@base_dir}/po" @pot_file = "#{@po_dir}/#{@spec.name}.pot" @extra_files = @text_files @extra_files += [@readme] if @readme @files = @source_files + @extra_files end + def current_language + locale = Locale.current + language = locale.language + region = locale.region + + if region.nil? + language + else + "#{language}_#{region}" + end + end + def reference_base_dir @base_dir + "reference" end - def doc_en_dir - @base_dir + "reference/en" - end - def html_base_dir @base_dir + "html" end def html_reference_dir @@ -132,12 +156,12 @@ if File.exist?(po_file) file po_file => @files do |t| current_pot_file = "tmp.pot" create_pot_file(current_pot_file) - GetText.msgmerge(po_file, current_pot_file, - "#{@spec.name} #{Packnga::VERSION}") + GetText::Tools::MsgMerge.run(po_file, current_pot_file, + "-o", po_file) FileUtils.rm_f(current_pot_file) end else file po_file => @pot_file do |t| GetText::Tools::MsgInit.run("--input", @pot_file, @@ -369,404 +393,8 @@ end translate_text = translate_text.each_line.collect do |line| "\\1#{line}" end content.sub(/#{original_text.join}/, translate_text.join) - end - end -end - -# XXX: This module is the patch to translate documents. -# This module should be deleted after -# https://github.com/lsegal/yard/pull/594 is merged and released. -# @private -module YARD - # @private - module I18n - # @private - class Locale - def translate(message) - return message if @messages[message].nil? - return message if @messages[message].empty? - @messages[message] - end - end - end -end - -# XXX: This module is the re-definition of YARD module. -# this module should be deleted in the next release of YARD. -# @private -module YARD - module CLI - # @private - class Yardoc - def parse_arguments(*args) - parse_yardopts_options(*args) - - # Parse files and then command line arguments - optparse(*support_rdoc_document_file!) if use_document_file - optparse(*yardopts) if use_yardopts_file - optparse(*args) - - # Last minute modifications - self.files = ['{lib,app}/**/*.rb', 'ext/**/*.c'] if self.files.empty? - self.files.delete_if {|x| x =~ /\A\s*\Z/ } # remove empty ones - readme = Dir.glob('README*').first - readme ||= Dir.glob(files.first).first if options.onefile - options.readme ||= CodeObjects::ExtraFileObject.new(readme) if readme - options.files.unshift(options.readme).uniq! if options.readme - - Tags::Library.visible_tags -= hidden_tags - 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 - log.warn "--one-file is not compatible with US-ASCII encoding, using ASCII-8BIT" - ::Encoding.default_external, ::Encoding.default_internal = ['ascii-8bit'] * 2 - end - end - - if generate && !verify_markup_options - false - else - true - end - end - - def apply_locale - options.files.each do |file| - file.locale = options.locale - end - end - - def output_options(opts) - opts.separator "" - opts.separator "Output options:" - - opts.on('--one-file', 'Generates output as a single file') do - options.onefile = true - end - - opts.on('--list', 'List objects to standard out (implies -n)') do |format| - self.generate = false - self.list = true - end - - opts.on('--no-public', "Don't show public methods. (default shows public)") do - visibilities.delete(:public) - end - - opts.on('--protected', "Show protected methods. (default hides protected)") do - visibilities.push(:protected) - end - - opts.on('--private', "Show private methods. (default hides private)") do - visibilities.push(:private) - end - - opts.on('--no-private', "Hide objects with @private tag") do - options.verifier.add_expressions '!object.tag(:private) && - (object.namespace.is_a?(CodeObjects::Proxy) || !object.namespace.tag(:private))' - end - - opts.on('--[no-]api API', 'Generates documentation for a given API', - '(objects which define the correct @api tag).', - 'If --no-api is given, displays objects with', - 'no @api tag.') do |api| - api = '' if api == false - apis.push(api) - end - - opts.on('--embed-mixins', "Embeds mixin methods into class documentation") do - options.embed_mixins << '*' - end - - opts.on('--embed-mixin [MODULE]', "Embeds mixin methods from a particular", - " module into class documentation") do |mod| - options.embed_mixins << mod - end - - opts.on('--no-highlight', "Don't highlight code blocks in output.") do - options.highlight = false - end - - opts.on('--default-return TYPE', "Shown if method has no return type. ", - " (defaults to 'Object')") do |type| - options.default_return = type - end - - opts.on('--hide-void-return', "Hides return types specified as 'void'. ", - " (default is shown)") do - options.hide_void_return = true - end - - opts.on('--query QUERY', "Only show objects that match a specific query") do |query| - next if YARD::Config.options[:safe_mode] - options.verifier.add_expressions(query.taint) - end - - opts.on('--title TITLE', 'Add a specific title to HTML documents') do |title| - options.title = title - end - - opts.on('-r', '--readme FILE', '--main FILE', 'The readme file used as the title page', - ' of documentation.') do |readme| - if File.file?(readme) - options.readme = CodeObjects::ExtraFileObject.new(readme) - else - log.warn "Could not find readme file: #{readme}" - end - end - - opts.on('--files FILE1,FILE2,...', 'Any extra comma separated static files to be ', - ' included (eg. FAQ)') do |files| - add_extra_files(*files.split(",")) - end - - opts.on('--asset FROM[:TO]', 'A file or directory to copy over to output ', - ' directory after generating') do |asset| - re = /^(?:\.\.\/|\/)/ - from, to = *asset.split(':').map {|f| File.cleanpath(f) } - to ||= from - if from =~ re || to =~ re - log.warn "Invalid file '#{asset}'" - else - assets[from] = to - end - end - - opts.on('-o', '--output-dir PATH', - 'The output directory. (defaults to ./doc)') do |dir| - options.serializer.basepath = dir - end - - opts.on('-m', '--markup MARKUP', - 'Markup style used in documentation, like textile, ', - ' markdown or rdoc. (defaults to rdoc)') do |markup| - self.has_markup = true - options.markup = markup.to_sym - end - - opts.on('-M', '--markup-provider MARKUP_PROVIDER', - 'Overrides the library used to process markup ', - ' formatting (specify the gem name)') do |markup_provider| - options.markup_provider = markup_provider.to_sym - end - - opts.on('--charset ENC', 'Character set to use when parsing files ', - ' (default is system locale)') do |encoding| - begin - if defined?(Encoding) && Encoding.respond_to?(:default_external=) - Encoding.default_external, Encoding.default_internal = encoding, encoding - end - rescue ArgumentError => e - raise OptionParser::InvalidOption, e - end - end - - opts.on('-t', '--template TEMPLATE', - 'The template to use. (defaults to "default")') do |template| - options.template = template.to_sym - end - - opts.on('-p', '--template-path PATH', - 'The template path to look for templates in.', - ' (used with -t).') do |path| - next if YARD::Config.options[:safe_mode] - YARD::Templates::Engine.register_template_path(File.expand_path(path)) - end - - opts.on('-f', '--format FORMAT', - 'The output format for the template.', - ' (defaults to html)') do |format| - options.format = format.to_sym - end - - 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 - end - end - - module CodeObjects - # @private - class ExtraFileObject - attr_writer :attributes - attr_reader :locale - - def initialize(filename, contents = nil) - self.filename = filename - self.name = File.basename(filename).gsub(/\.[^.]+$/, '') - self.attributes = SymbolHash.new(false) - @original_contents = contents - @parsed = false - @locale = nil - ensure_parsed - end - - def attributes - ensure_parsed - @attributes - end - - def contents - ensure_parsed - @contents - end - - def contents=(contents) - @original_contents = contents - @parsed = false - end - - def locale=(locale) - @locale = locale - @parsed = false - end - - private - def ensure_parsed - return if @parsed - @parsed = true - @contents = parse_contents(@original_contents || File.read(@filename)) - end - - 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 - when /^#!(\S+)\s*$/ - if index == 0 - attributes[:markup] = $1 - else - cut_index = index - break - end - when /^\s*#\s*@(\S+)\s*(.+?)\s*$/ - attributes[$1] = $2 - else - cut_index = index - break - end - end - data = data[cut_index..-1] if cut_index > 0 - contents = data.join("\n") - - if contents.respond_to?(:force_encoding) && attributes[:encoding] - begin - contents.force_encoding(attributes[:encoding]) - rescue ArgumentError - 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`." - 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 - - module I18n - # @private - class Locale - def load(locale_directory) - return false if @name.nil? - - po_file = File.join(locale_directory, "#{@name}.po") - return false unless File.exist?(po_file) - - begin - require "gettext/tools/poparser" - require "gettext/runtime/mofile" - rescue LoadError - log.warn "Need gettext gem for i18n feature:" - log.warn " gem install gettext" - return false - end - - parser = GetText::PoParser.new - parser.report_warning = false - data = GetText::MoFile.new - parser.parse_file(po_file, data) - @messages.merge!(data) - true - end - end - end - - # @private - module Registry - DEFAULT_PO_DIR = "po" - class << self - def locale(name) - thread_local_store.locale(name) - end - - 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 - end - end - - # @private - class RegistryStore - def initialize - @file = nil - @checksums = {} - @store = {} - @proxy_types = {} - @object_types = {:root => [:root]} - @notfound = {} - @loaded_objects = 0 - @available_objects = 0 - @locales = {} - @store[:root] = CodeObjects::RootObject.allocate - @store[:root].send(:initialize, nil, :root) - end - - def locale(name) - @locales[name] ||= load_locale(name) - end - - def load_locale(name) - locale = I18n::Locale.new(name) - locale.load(Registry.po_dir) - locale end end end