summaryrefslogtreecommitdiff
path: root/jni/ruby/lib/rdoc/generator/pot
diff options
context:
space:
mode:
authorJari Vetoniemi <jari.vetoniemi@indooratlas.com>2020-03-16 18:49:26 +0900
committerJari Vetoniemi <jari.vetoniemi@indooratlas.com>2020-03-30 00:39:06 +0900
commitfcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch)
tree64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/lib/rdoc/generator/pot
Fresh start
Diffstat (limited to 'jni/ruby/lib/rdoc/generator/pot')
-rw-r--r--jni/ruby/lib/rdoc/generator/pot/message_extractor.rb67
-rw-r--r--jni/ruby/lib/rdoc/generator/pot/po.rb83
-rw-r--r--jni/ruby/lib/rdoc/generator/pot/po_entry.rb140
3 files changed, 290 insertions, 0 deletions
diff --git a/jni/ruby/lib/rdoc/generator/pot/message_extractor.rb b/jni/ruby/lib/rdoc/generator/pot/message_extractor.rb
new file mode 100644
index 0000000..ceabc52
--- /dev/null
+++ b/jni/ruby/lib/rdoc/generator/pot/message_extractor.rb
@@ -0,0 +1,67 @@
+##
+# Extracts message from RDoc::Store
+
+class RDoc::Generator::POT::MessageExtractor
+
+ ##
+ # Creates a message extractor for +store+.
+
+ def initialize store
+ @store = store
+ @po = RDoc::Generator::POT::PO.new
+ end
+
+ ##
+ # Extracts messages from +store+, stores them into
+ # RDoc::Generator::POT::PO and returns it.
+
+ def extract
+ @store.all_classes_and_modules.each do |klass|
+ extract_from_klass(klass)
+ end
+ @po
+ end
+
+ private
+
+ def extract_from_klass klass
+ extract_text(klass.comment_location, klass.full_name)
+
+ klass.each_section do |section, constants, attributes|
+ extract_text(section.title ,"#{klass.full_name}: section title")
+ section.comments.each do |comment|
+ extract_text(comment, "#{klass.full_name}: #{section.title}")
+ end
+ end
+
+ klass.each_constant do |constant|
+ extract_text(constant.comment, constant.full_name)
+ end
+
+ klass.each_attribute do |attribute|
+ extract_text(attribute.comment, attribute.full_name)
+ end
+
+ klass.each_method do |method|
+ extract_text(method.comment, method.full_name)
+ end
+ end
+
+ def extract_text text, comment, location = nil
+ return if text.nil?
+
+ options = {
+ :extracted_comment => comment,
+ :references => [location].compact,
+ }
+ i18n_text = RDoc::I18n::Text.new(text)
+ i18n_text.extract_messages do |part|
+ @po.add(entry(part[:paragraph], options))
+ end
+ end
+
+ def entry msgid, options
+ RDoc::Generator::POT::POEntry.new(msgid, options)
+ end
+
+end
diff --git a/jni/ruby/lib/rdoc/generator/pot/po.rb b/jni/ruby/lib/rdoc/generator/pot/po.rb
new file mode 100644
index 0000000..6a6b582
--- /dev/null
+++ b/jni/ruby/lib/rdoc/generator/pot/po.rb
@@ -0,0 +1,83 @@
+##
+# Generates a PO format text
+
+class RDoc::Generator::POT::PO
+
+ ##
+ # Creates an object that represents PO format.
+
+ def initialize
+ @entries = {}
+ add_header
+ end
+
+ ##
+ # Adds a PO entry to the PO.
+
+ def add entry
+ existing_entry = @entries[entry.msgid]
+ if existing_entry
+ entry = existing_entry.merge(entry)
+ end
+ @entries[entry.msgid] = entry
+ end
+
+ ##
+ # Returns PO format text for the PO.
+
+ def to_s
+ po = ''
+ sort_entries.each do |entry|
+ po << "\n" unless po.empty?
+ po << entry.to_s
+ end
+ po
+ end
+
+ private
+
+ def add_header
+ add(header_entry)
+ end
+
+ def header_entry
+ comment = <<-COMMENT
+SOME DESCRIPTIVE TITLE.
+Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+This file is distributed under the same license as the PACKAGE package.
+FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+ COMMENT
+
+ content = <<-CONTENT
+Project-Id-Version: PACKAGE VERSEION
+Report-Msgid-Bugs-To:
+PO-Revision-Date: YEAR-MO_DA HO:MI+ZONE
+Last-Translator: FULL NAME <EMAIL@ADDRESS>
+Language-Team: LANGUAGE <LL@li.org>
+Language:
+MIME-Version: 1.0
+Content-Type: text/plain; charset=CHARSET
+Content-Transfer-Encoding: 8bit
+Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;
+ CONTENT
+
+ options = {
+ :msgstr => content,
+ :translator_comment => comment,
+ :flags => ['fuzzy'],
+ }
+ RDoc::Generator::POT::POEntry.new('', options)
+ end
+
+ def sort_entries
+ headers, messages = @entries.values.partition do |entry|
+ entry.msgid.empty?
+ end
+ # TODO: sort by location
+ sorted_messages = messages.sort_by do |entry|
+ entry.msgid
+ end
+ headers + sorted_messages
+ end
+
+end
diff --git a/jni/ruby/lib/rdoc/generator/pot/po_entry.rb b/jni/ruby/lib/rdoc/generator/pot/po_entry.rb
new file mode 100644
index 0000000..d4cef59
--- /dev/null
+++ b/jni/ruby/lib/rdoc/generator/pot/po_entry.rb
@@ -0,0 +1,140 @@
+##
+# A PO entry in PO
+
+class RDoc::Generator::POT::POEntry
+
+ # The msgid content
+ attr_reader :msgid
+
+ # The msgstr content
+ attr_reader :msgstr
+
+ # The comment content created by translator (PO editor)
+ attr_reader :translator_comment
+
+ # The comment content extracted from source file
+ attr_reader :extracted_comment
+
+ # The locations where the PO entry is extracted
+ attr_reader :references
+
+ # The flags of the PO entry
+ attr_reader :flags
+
+ ##
+ # Creates a PO entry for +msgid+. Other valus can be specified by
+ # +options+.
+
+ def initialize msgid, options = {}
+ @msgid = msgid
+ @msgstr = options[:msgstr] || ""
+ @translator_comment = options[:translator_comment]
+ @extracted_comment = options[:extracted_comment]
+ @references = options[:references] || []
+ @flags = options[:flags] || []
+ end
+
+ ##
+ # Returns the PO entry in PO format.
+
+ def to_s
+ entry = ''
+ entry << format_translator_comment
+ entry << format_extracted_comment
+ entry << format_references
+ entry << format_flags
+ entry << <<-ENTRY
+msgid #{format_message(@msgid)}
+msgstr #{format_message(@msgstr)}
+ ENTRY
+ end
+
+ ##
+ # Merges the PO entry with +other_entry+.
+
+ def merge other_entry
+ options = {
+ :extracted_comment => merge_string(@extracted_comment,
+ other_entry.extracted_comment),
+ :translator_comment => merge_string(@translator_comment,
+ other_entry.translator_comment),
+ :references => merge_array(@references,
+ other_entry.references),
+ :flags => merge_array(@flags,
+ other_entry.flags),
+ }
+ self.class.new(@msgid, options)
+ end
+
+ private
+
+ def format_comment mark, comment
+ return '' unless comment
+ return '' if comment.empty?
+
+ formatted_comment = ''
+ comment.each_line do |line|
+ formatted_comment << "#{mark} #{line}"
+ end
+ formatted_comment << "\n" unless formatted_comment.end_with?("\n")
+ formatted_comment
+ end
+
+ def format_translator_comment
+ format_comment('#', @translator_comment)
+ end
+
+ def format_extracted_comment
+ format_comment('#.', @extracted_comment)
+ end
+
+ def format_references
+ return '' if @references.empty?
+
+ formatted_references = ''
+ @references.sort.each do |file, line|
+ formatted_references << "\#: #{file}:#{line}\n"
+ end
+ formatted_references
+ end
+
+ def format_flags
+ return '' if @flags.empty?
+
+ formatted_flags = flags.join(",")
+ "\#, #{formatted_flags}\n"
+ end
+
+ def format_message message
+ return "\"#{escape(message)}\"" unless message.include?("\n")
+
+ formatted_message = '""'
+ message.each_line do |line|
+ formatted_message << "\n"
+ formatted_message << "\"#{escape(line)}\""
+ end
+ formatted_message
+ end
+
+ def escape string
+ string.gsub(/["\\\t\n]/) do |special_character|
+ case special_character
+ when "\t"
+ "\\t"
+ when "\n"
+ "\\n"
+ else
+ "\\#{special_character}"
+ end
+ end
+ end
+
+ def merge_string string1, string2
+ [string1, string2].compact.join("\n")
+ end
+
+ def merge_array array1, array2
+ (array1 + array2).uniq
+ end
+
+end