class YARD::I18n::PotGenerator

GNU gettext manual about details of PO file
@see www.gnu.org/software/gettext/manual/html_node/PO-Files.html<br>end
pot_file.print(pot)
File.open(po_file_path, “w”) do |pot_file|
po_file_directory_pathname.mkpath
pot = generator.generate
generator.parse_files(files)
generator.parse_objects(objects)
generator = YARD::I18n::PotGenerator.new(relative_base_path)
# relative_base_path -> “..”
relative_base_path = working_directory_pathname.relative_path_from(po_file_directory_pathname).to_s
working_directory_pathname = Pathname.new(“.”)
po_file_directory_pathname = Pathname.new(po_file_path).directory)
po_file_path = “po/yard.pot”
@example Generate a .pot file
“po/yard.pot”.
working directory path is “.” and the POT is wrote into
file. The relative working directory path is “..” when the
objects, generate a POT and write the generated POT to a .pot
{CodeObjects::Base} objects and {CodeObjects::ExtraFileObject}
directory path that has created .pot file, parse
PotGenerator with a relative working directory path from a
To create a .pot file by PotGenerator, instantiate a
== Usage
is extracted as a msgid.
{CodeObjects::ExtraFileObject} object is parsed and a paragraph
{CodeObjects::ExtraFileObject} objects. The file content of
{#parse_files} extracts msgids from
msgids from a tag.
extracted as a msgid. Tag name and tag text are extracted as
{CodeObjects::Base} object is parsed and a paragraph is
{CodeObjects::Base} objects. The docstring of
{#parse_objects} extracts msgids from docstring and tags of
* {#parse_files} for {CodeObjects::ExtraFileObject}
* {#parse_objects} for {CodeObjects::Base}
The PotGenerator has two parse methods:
== How to extract msgids
msgstr. The extension for PO is “.po”.
“Bonjour” in French, “Hello” is the msgid ID and “Bonjour” is
of message ID. If you want to translate “Hello” in English into
message and message string (msgstr) that is translated message
many parts of message ID (msgid) that is translation target
“.pot”. PO file is an acronym for “Portable Object”. PO file has
template file to create PO file. The extension for POT is
POT is an acronym for “Portable Object Template”. POT is a
== POT and PO
{CodeObjects::Base} and {CodeObjects::ExtraFileObject}.
The PotGenerator generates POT format string from

def current_time

def current_time
  @current_time ||= Time.now
end

def escape_message_id(message_id)

def escape_message_id(message_id)
  message_id.gsub(/(\\|")/) do
    special_character = $1
    "\\#{special_character}"
  end
end

def extract_documents(object)

def extract_documents(object)
  return if @extracted_objects.key?(object)
  @extracted_objects[object] = true
  case object
  when CodeObjects::NamespaceObject
    object.children.each do |child|
      extract_documents(child)
    end
  end
  if object.group
    message = register_message(object.group)
    object.files.each do |path, line|
      message.add_location(path, line)
    end
    message.add_comment(object.path) unless object.path.empty?
  end
  docstring = object.docstring
  unless docstring.empty?
    text = Text.new(StringIO.new(docstring))
    text.extract_messages do |type, *args|
      case type
      when :paragraph
        paragraph, line_no = *args
        message = register_message(paragraph.rstrip)
        object.files.each do |path, line|
          message.add_location(path, (docstring.line || line) + line_no)
        end
        message.add_comment(object.path) unless object.path.empty?
      else
        raise "should not reach here: unexpected type: #{type}"
      end
    end
  end
  docstring.tags.each do |tag|
    extract_tag_documents(tag)
  end
end

def extract_paragraphs(file)

def extract_paragraphs(file)
  File.open(file.filename) do |input|
    text = Text.new(input, :have_header => true)
    text.extract_messages do |type, *args|
      case type
      when :attribute
        name, value, line_no = *args
        message = register_message(value)
        message.add_location(file.filename, line_no)
        message.add_comment(name)
      when :paragraph
        paragraph, line_no = *args
        message = register_message(paragraph.rstrip)
        message.add_location(file.filename, line_no)
      else
        raise "should not reach here: unexpected type: #{type}"
      end
    end
  end
end

def extract_tag_documents(tag)

def extract_tag_documents(tag)
  extract_tag_name(tag)
  extract_tag_text(tag)
  extract_documents(tag) if Tags::OverloadTag === tag
end

def extract_tag_name(tag)

def extract_tag_name(tag)
  return if tag.name.nil?
  return if tag.name.is_a?(String) && tag.name.empty?
  key = "tag|#{tag.tag_name}|#{tag.name}"
  message = register_message(key)
  tag.object.files.each do |path, line|
    message.add_location(path, line)
  end
  tag_label = String.new("@#{tag.tag_name}")
  tag_label << " [#{tag.types.join(', ')}]" if tag.types
  message.add_comment(tag_label)
end

def extract_tag_text(tag)

def extract_tag_text(tag)
  return if tag.text.nil?
  return if tag.text.empty?
  message = register_message(tag.text)
  tag.object.files.each do |path, line|
    message.add_location(path, line)
  end
  tag_label = String.new("@#{tag.tag_name}")
  tag_label << " [#{tag.types.join(', ')}]" if tag.types
  tag_label << " #{tag.name}" if tag.name
  message.add_comment(tag_label)
end

def generate

Returns:
  • (String) - POT format string
def generate
  pot = String.new(header)
  sorted_messages = @messages.sort_by do |message|
    sorted_locations = message.locations.sort
    sorted_locations.first || []
  end
  sorted_messages.each do |message|
    generate_message(pot, message)
  end
  pot
end

def generate_message(pot, message)

def generate_message(pot, message)
  message.comments.sort.each do |comment|
    pot << "# #{comment}\n" unless comment.empty?
  end
  message.locations.sort.each do |path, line|
    pot << "#: #{@relative_base_path}/#{path}:#{line}\n"
  end
  escaped_message_id = escape_message_id(message.id)
  escaped_message_id = escaped_message_id.gsub(/\n/, "\\\\n\"\n\"")
  pot << "msgid \"#{escaped_message_id}\"\n"
  pot << "msgstr \"\"\n"
  pot << "\n"
  pot
end

def generate_pot_creation_date_value

def generate_pot_creation_date_value
  current_time.strftime("%Y-%m-%d %H:%M%z")
end

def header

def header
  <<-EOH
 DESCRIPTIVE TITLE.
right (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 file is distributed under the same license as the PACKAGE package.
T AUTHOR <EMAIL@ADDRESS>, YEAR.
zy
""
 ""
ct-Id-Version: PACKAGE VERSION\\n"
t-Msgid-Bugs-To: \\n"
reation-Date: #{generate_pot_creation_date_value}\\n"
vision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
Translator: FULL NAME <EMAIL@ADDRESS>\\n"
age-Team: LANGUAGE <LL@li.org>\\n"
age: \\n"
Version: 1.0\\n"
nt-Type: text/plain; charset=UTF-8\\n"
nt-Transfer-Encoding: 8bit\\n"
end

def initialize(relative_base_path)

Parameters:
  • relative_base_path (String) -- a relative working
def initialize(relative_base_path)
  @relative_base_path = relative_base_path
  @extracted_objects = {}
  @messages = Messages.new
end

def parse_files(files)

Returns:
  • (void) -

Parameters:
  • files (Array) -- a list
def parse_files(files)
  files.each do |file|
    extract_paragraphs(file)
  end
end

def parse_objects(objects)

Returns:
  • (void) -

Parameters:
  • objects (Array) -- a list of
def parse_objects(objects)
  objects.each do |object|
    extract_documents(object)
  end
end

def register_message(id)

def register_message(id)
  @messages.register(id)
end