<html>
<head>
<style><!--
body {background-color:#ffffff;}
.file {border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;}
.pathname {font-family:monospace; float:right;}
.fileheader {margin-bottom:.5em;}
.diff {margin:0;}
.tasklist {padding:4px;border:1px dashed #000000;margin-top:1em;}
.tasklist ul {margin-top:0;margin-bottom:0;}
tr.alt {background-color:#eeeeee}
#added {background-color:#ddffdd;}
#addedchars {background-color:#99ff99;font-weight:bolder;}
tr.alt #added {background-color:#ccf7cc;}
#removed {background-color:#ffdddd;}
#removedchars {background-color:#ff9999;font-weight:bolder;}
tr.alt #removed {background-color:#f7cccc;}
#info {color:#888888;}
#context {background-color:#eeeeee;}
td {padding-left:.3em;padding-right:.3em;}
tr.head {border-bottom-width:1px;border-bottom-style:solid;}
tr.head td {padding:0;padding-top:.2em;}
.task {background-color:#ffff00;}
.comment {padding:4px;border:1px dashed #000000;background-color:#ffffdd}
.error {color:red;}
hr {border-width:0px;height:2px;background:black;}
--></style>
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head"><td colspan="4">Commit in <b><tt>trunk/as2api</tt></b><span id="info"> on MAIN</span></td></tr>
<tr><td><tt><a href="#file1">doc_comment.rb</a></tt></td><td align="right" id="added">+15</td><td></td><td nowrap="nowrap" align="center">283 -> 284</td></tr>
<tr class="alt"><td><tt>localisation/xliff/<a href="#file2"><span id="added">driver.rb</span></a></tt></td><td align="right" id="added">+238</td><td></td><td nowrap="nowrap" align="right">added 284</td></tr>
<tr><td><tt> /<a href="#file3"><span id="added">translation_loader.rb</span></a></tt></td><td align="right" id="added">+183</td><td></td><td nowrap="nowrap" align="right">added 284</td></tr>
<tr class="alt"><td><tt> /<a href="#file4"><span id="added">xliff_doc_utils.rb</span></a></tt></td><td align="right" id="added">+72</td><td></td><td nowrap="nowrap" align="right">added 284</td></tr>
<tr><td><tt> /<a href="#file5"><span id="added">xliff_reader.rb</span></a></tt></td><td align="right" id="added">+158</td><td></td><td nowrap="nowrap" align="right">added 284</td></tr>
<tr class="alt"><td><tt> /<a href="#file6"><span id="added">xliff_writer.rb</span></a></tt></td><td align="right" id="added">+89</td><td></td><td nowrap="nowrap" align="right">added 284</td></tr>
<tr><td><tt>ui/<a href="#file7">cli.rb</a></tt></td><td align="right" id="added">+35</td><td align="right" id="removed">-3</td><td nowrap="nowrap" align="center">283 -> 284</td></tr>
<tr><td></td><td align="right" id="added">+790</td><td align="right" id="removed">-3</td><td></td></tr>
</table>
<small id="info">5 added + 2 modified, total 7 files</small><br />
<div class="tasklist"><ul>
<li><a href="#task1">TODO: remove this hackery</a></li>
</ul></div>
<pre class="comment">
Initial (slightly hairy) cut at XLIFF import / export system for localising the human-readable portions of the API description
</pre>
<hr /><a name="file1" /><div class="file">
<span class="pathname">trunk/as2api</span><br />
<div class="fileheader"><big><b>doc_comment.rb</b></big> <small id="info">283 -> 284</small></div>
<pre class="diff"><small id="info">--- trunk/as2api/doc_comment.rb        2006-02-26 16:07:25 UTC (rev 283)
+++ trunk/as2api/doc_comment.rb        2006-02-27 13:59:52 UTC (rev 284)
@@ -28,6 +28,10 @@
</small></pre><pre class="diff" id="context"> @blocks[i]
end
</pre><pre class="diff" id="added">+ def description
+ @blocks[0]
+ end
+
</pre><pre class="diff" id="context"> def each_block_of_type(type)
each_block do |block|
yield block if block.is_a?(type)
</pre><pre class="diff"><small id="info">@@ -90,6 +94,13 @@
</small></pre><pre class="diff" id="context"> end
return nil
end
</pre><pre class="diff" id="added">+
+ def find_throws(exception_name)
+ each_exception do |block|
+ return block if block.exception_type.name == exception_name
+ end
+ nil
+ end
</pre><pre class="diff" id="context"> end
class OurDocCommentHandler < ActionScript::ParseDoc::DocCommentHandler
</pre><pre class="diff"><small id="info">@@ -239,6 +250,10 @@
</small></pre><pre class="diff" id="context"> @inlines
end
</pre><pre class="diff" id="added">+ def clear
+ @inlines.clear
+ end
+
</pre><pre class="diff" id="context"> def ==(o)
o.respond_to?(:inlines) && inlines==o.inlines
end
</pre></div>
<hr /><a name="file2" /><div class="file">
<span class="pathname" id="added">trunk/as2api/localisation/xliff</span><br />
<div class="fileheader" id="added"><big><b>driver.rb</b></big> <small id="info">added at 284</small></div>
<pre class="diff"><small id="info">--- trunk/as2api/localisation/xliff/driver.rb        2006-02-26 16:07:25 UTC (rev 283)
+++ trunk/as2api/localisation/xliff/driver.rb        2006-02-27 13:59:52 UTC (rev 284)
@@ -0,0 +1,238 @@
</small></pre><pre class="diff" id="added">+
+require 'xmlwriter'
+require 'localisation/xliff/xliff_writer'
+require 'localisation/xliff/xliff_doc_utils'
+require 'output/xml/xml_formatter'
+
+class XLIFFGenerator
+ include XLIFFWriter
+
+ def initialize(xml_writer, source_lang, target_lang)
+ @io = xml_writer
+ @source_lang = source_lang
+ @target_lang = target_lang
+ end
+
+
+ def generate_template_xliff(type_aggregator)
+ xliff_xliff("version"=>"1.0") do
+ type_aggregator.each_type do |astype|
+ generate_file_template(astype);
+ end
+ end
+ end
+
+ def generate_file_template(astype)
+ xliff_file("original"=>astype.input_filename,
+ "source-language"=>@source_lang,
+         "target-language"=>@target_lang,
+         "datatype"=>"plaintext",
+         "xml:space"=>"preserve") do
+ xliff_header do
+ end
+ xliff_body do
+ gen_type_trans_units(astype) if astype.comment
+        gen_member_trans_units(astype)
+ end
+ end
+ end
+
+ def trans_unit(id, *contexts)
+ xliff_trans_unit("id"=>id) do
+ xliff_source do
+        yield
+ end
+ xliff_target do
+ end
+ unless contexts.empty?
+        simple_context_group("api", *contexts)
+ end
+ end
+ end
+
+ def simple_context_group(name, *contexts)
+ xliff_context_group("name"=>name) do
+ until contexts.empty?
+        context_type, value, *contexts = contexts
+        xliff_context("context-type"=>context_type) do
+         pcdata(value)
+        end
+ end
+ end
+ end
+
+ def gen_member_trans_units(astype)
+ if astype.respond_to?(:each_field)
+ astype.each_field do |asfield|
+        gen_field_comment(asfield) if asfield.comment
+ end
+ end
+ astype.each_method do |asmethod|
+ gen_method_comment(asmethod) if asmethod.comment
+ end
+ end
+
+ def gen_method_comment(asmethod)
+ @see_index = 0
+ asmethod.comment.each_block do |block|
+ send("gen_method_block_#{block.class.name}", asmethod, block)
+ @see_index += 1 if block.is_a?(SeeBlockTag)
+ end
+ @see_index = nil
+ end
+
+ def gen_field_comment(asfield)
+ asfield.comment.each_block do |block|
+        send("gen_field_block_#{block.class.name}", asfield, block)
+ end
+ end
+
+ def gen_type_trans_units(astype)
+ @see_index = 0
+ astype.comment.each_block do |block|
+ send("gen_type_block_#{block.class.name}", astype, block)
+ @see_index += 1 if block.is_a?(SeeBlockTag)
+ end
+ @see_index = nil
+ end
+
+ def gen_type_block_BlockTag(astype, block)
+ kind = if astype.is_a?(ASClass)
+ "class"
+ else
+ "interface"
+ end
+ trans_unit(XliffIds.id_for_type_description(astype),
+         "element", kind,
+ "type", astype.qualified_name) do
+ gen_inlines(block)
+ end
+ end
+
+ def gen_method_block_BlockTag(asmethod, block)
+ trans_unit(XliffIds.id_for_method_description(asmethod),
+         "element", "method",
+ "type", asmethod.containing_type.qualified_name,
+ "method", asmethod.name) do
+ gen_inlines(block)
+ end
+ end
+
+ def gen_field_block_BlockTag(asfield, block)
+ trans_unit(XliffIds.id_for_field_description(asfield),
+         "element", "field",
+ "type", asfield.containing_type.qualified_name,
+ "field", asfield.name) do
+ gen_inlines(block)
+ end
+ end
+
+ def gen_method_block_ParamBlockTag(asmethod, block)
+ trans_unit(XliffIds.id_for_parameter_description(asmethod,block.param_name),
+         "element", "parameter",
+ "type", asmethod.containing_type.qualified_name,
+ "method", asmethod.name,
+ "parameter", block.param_name) do
+ gen_inlines(block)
+ end
+ end
+
+ def gen_method_block_ReturnBlockTag(asmethod, block)
+ trans_unit(XliffIds.id_for_method_return(asmethod),
+         "element", "return",
+ "type", asmethod.containing_type.qualified_name,
+ "method", asmethod.name) do
+ gen_inlines(block)
+ end
+ end
+
+ def gen_method_block_ThrowsBlockTag(asmethod, block)
+ trans_unit(XliffIds.id_for_throws_description(asmethod, block.exception_type.resolved_type),
+         "element", "throws",
+ "type", asmethod.containing_type.qualified_name,
+ "method", asmethod.name,
+ "throws", block.exception_type.resolved_type.qualified_name) do
+ gen_inlines(block)
+ end
+ end
+
+ def gen_method_block_SeeBlockTag(asmethod, block)
+ trans_unit(XliffIds.id_for_method_see(asmethod, @see_index),
+         "element", "see",
+ "type", asmethod.containing_type.qualified_name,
+ "method", asmethod.name) do
+ gen_inlines(block)
+ end
+ end
+
+ def gen_type_block_SeeBlockTag(astype, block)
+ trans_unit(XliffIds.id_for_type_see(astype, @see_index),
+         "element", "see",
+ "type", astype.qualified_name) do
+ gen_inlines(block)
+ end
+ end
+
+ def gen_inlines(block)
+ index = 0
+ block.each_inline do |inline|
+ if index==0 && inline.is_a?(String)
+        inline = inline.lstrip
+ end
+ if index==block.inlines.length-1 && inline.is_a?(String)
+        inline = inline.rstrip
+ end
+ gen_inline(inline)
+ index += 1
+ end
+ end
+
+ def gen_inline(inline)
+ if inline.is_a?(String)
+ pcdata(inline)
+ else
+ send("gen_inline_#{inline.class.name}", inline)
+ end
+ end
+
+ def gen_inline_CodeTag(inline)
+ xliff_ph("id"=>"code") do
+ pcdata(inline.text)
+ end
+ end
+
+ def gen_inline_LinkTag(inline)
+ xliff_ph("id"=>"link") do
+ if inline.target
+        pcdata(inline.target.local_name)
+ end
+ if inline.member
+        pcdata("#")
+        pcdata(inline.member)
+ end
+ if inline.text && inline.text != ""
+        xliff_sub("id"=>"link-text") do
+         pcdata(inline.text)
+        end
+ end
+ end
+ end
+end
+
+def generate_xliff(conf, type_aggregator)
+ encoding = "UTF-8"
+ File.open(conf.xliff_export, "w") do |io|
+ xml = XMLWriter.new(io)
+ xml.pi("xml version=\"1.0\" encoding=\"#{encoding}\"")
+ xml.pcdata("\n")
+ xml.doctype("xliff", "PUBLIC",
+ "-//XLIFF//DTD XLIFF//EN",
+         "http://www.oasis-open.org/committees/xliff/documents/xliff.dtd")
+ format = XMLFormatter.new(xml)
+ format.inlines [ "source", "target", "context", "ph", "sub", "it", "bpt", "ept", "g", "x", "bx", "ex", "mrk" ]
+ gen = XLIFFGenerator.new(format, conf.source_lang, conf.target_lang)
+ gen.generate_template_xliff(type_aggregator)
+ end
+end
+
+# vim:softtabstop=2:shiftwidth=2
</pre></div>
<hr /><a name="file3" /><div class="file">
<span class="pathname" id="added">trunk/as2api/localisation/xliff</span><br />
<div class="fileheader" id="added"><big><b>translation_loader.rb</b></big> <small id="info">added at 284</small></div>
<pre class="diff"><small id="info">--- trunk/as2api/localisation/xliff/translation_loader.rb        2006-02-26 16:07:25 UTC (rev 283)
+++ trunk/as2api/localisation/xliff/translation_loader.rb        2006-02-27 13:59:52 UTC (rev 284)
@@ -0,0 +1,183 @@
</small></pre><pre class="diff" id="added">+
+require 'localisation/xliff/xliff_reader'
+require 'localisation/xliff/xliff_doc_utils'
+
+class CodePhHandler
+ def initialize(block); @block = block; end
+ def start_ph; @text=""; end
+ def end_ph; @block.add_inline(CodeTag.new(0, @text)); end
+ def text(text); @text<<text end
+end
+
+class LinkPhHandler
+ def initialize(block, type_resolver)
+ @block = block
+ @type_resolver = type_resolver
+ end
+ def start_ph; @text=@ph_text=""; @sub_text="" end
+ def end_ph;
+ @ph_text =~ /^([^#\s]+)(?:#([^\s]+))?/
+ if $1
+ target = @type_resolver.resolve($1)
+ else
+ target = nil
+ end
+ member = $2
+ @block.add_inline(LinkTag.new(0, target, member, @sub_text))
+ end
+ def text(text); @text<<text end
+ def start_sub; @text=@sub_text; end
+ def end_sub; @text=@ph_text; end
+end
+
+class DocXliffHandler
+ include TranslationHandler
+
+ def initialize(filename_to_type, target_lang)
+ @filename_to_type = filename_to_type
+ @target_lang = target_lang
+ @current_type = nil
+ end
+
+ def start_file(file)
+ @current_type = @filename_to_type[file.original]
+ if @current_type.nil?
+ warn("no type matched #{file.original.inspect}")
+ end
+ if file.target_language == @target_lang
+ @process_this_file = true
+ else
+ @process_this_file = false
+ warn("target language #{file.target_language.inspect} for #{file.original.inspect} isn't #{@target_lang.inspect}; skipping translation data")
+ end
+ end
+ def end_file
+ @current_type = nil
+ end
+
+
+ def get_seeblock(comment, index)
+ i = 0
+ comment.each_seealso do |block|
+ return block if index == i
+ i += 1
+ end
+ return nil
+ end
+
+ def start_trans_unit(id)
+ return unless @process_this_file
+ parts = id.split(/-/)
+ element = parts.shift
+ unless element == "class" || element == "interface"
+ warn("expected id to start with 'class-' or 'interface-'")
+ return
+ end
+ type_name = XliffIds.from_id(parts.shift)
+ unless type_name == @current_type.qualified_name
+ warn("expected type didn't match type in id; #{@current_type.qualified_name.inspect}, #{type_name.inspect}")
+ return
+ end
+ element = parts.shift
+ case element
+ when "description"
+        @current_block = @current_type.comment.description
+ when "method"
+        method_name = XliffIds.from_id(parts.shift)
+        asmethod = @current_type.get_method_called(method_name)
+        element = parts.shift
+        case element
+         when "description"
+         @current_block = asmethod.comment.description
+         when "return"
+         @current_block = asmethod.comment.find_return
+         when "param"
+         param_name = XliffIds.from_id(parts.shift)
+         @current_block = asmethod.comment.find_param(param_name)
+         when "throws"
+         type_name = XliffIds.from_id(parts.shift)
+         @current_block = asmethod.comment.find_throws(type_name)
+         when "see"
+         see_num = parts.shift.to_i
+         @current_block = get_seeblock(asmethod.comment, see_num)
+         else
+         warn("unknown API element #{element.inspect} in id #{id.inspect}")
+         return
+        end
+ when "field"
+        field_name = XliffIds.from_id(parts.shift)
+        asfield = @current_type.get_field_called(field_name)
+        unless asfield
+         warn("no field #{field_name.inspect} in #{@current_type.qualified_name}")
+         return
+        end
+        element = parts.shift
+        case element
+         when "description"
+         @current_block = asfield.comment.description
+         when "see"
+         see_num = parts.shift.to_i
+         @current_block = get_seeblock(asfield.comment, see_num)
+         else
+         warn("unknown API element #{element.inspect} in id #{id.inspect}")
+         return
+        end
+ when "see"
+        see_num = parts.shift.to_i
+        @current_block = get_seeblock(@current_type.comment, see_num)
+ else
+        warn("unknown API element #{element.inspect} in id #{id.inspect}")
+        return
+ end
+ end
+
+ def end_trans_unit
+ return unless @process_this_file
+ @current_block = nil
+ end
+
+ def start_target
+ return unless @process_this_file
+ @current_block.clear if @current_block
+ end
+
+ def text(text)
+ return unless @process_this_file
+ @current_block.add_inline(text) if @current_block
+ end
+
+ def ph(id)
+ # Null-Object pattern,
+ return PhHandler.new unless @current_block && @process_this_file
+
+ case id
+ when "code"
+        return CodePhHandler.new(@current_block)
+ when "link"
+        return LinkPhHandler.new(@current_block, @current_type.type_resolver)
+ else
+        raise "unhandled placeholder id #{id.inspect}"
+ end
+ end
+
+ private
+
+ def warn(text)
+ $stderr.puts("warn: #{text} (#{caller[0]})")
+ end
+end
+
+
+def update_docs(conf, type_aggregator)
+ filename_to_type = {}
+ type_aggregator.each_type do |astype|
+ filename_to_type[astype.input_filename] = astype
+ end
+ File.open(conf.xliff_import) do |io|
+ doc_handler = DocXliffHandler.new(filename_to_type, conf.target_lang)
+ XLIFFReader.new(io, doc_handler).parse
+ end
+end
+
+
+# vim:sw=2:sts=2
</pre></div>
<hr /><a name="file4" /><div class="file">
<span class="pathname" id="added">trunk/as2api/localisation/xliff</span><br />
<div class="fileheader" id="added"><big><b>xliff_doc_utils.rb</b></big> <small id="info">added at 284</small></div>
<pre class="diff"><small id="info">--- trunk/as2api/localisation/xliff/xliff_doc_utils.rb        2006-02-26 16:07:25 UTC (rev 283)
+++ trunk/as2api/localisation/xliff/xliff_doc_utils.rb        2006-02-27 13:59:52 UTC (rev 284)
@@ -0,0 +1,72 @@
</small></pre><pre class="diff" id="added">+
+# utilities pertaining to the use of JavaDoc in XLIFF
+
+
+module XliffIds
+
+ def self.id_prefix_for_type(astype)
+ "class-#{to_id(astype.qualified_name)}"
+ end
+
+ def self.id_prefix_for_method(asmethod)
+ "#{id_prefix_for_type(asmethod.containing_type)}-method-#{to_id(asmethod.name)}"
+ end
+
+ def self.id_prefix_for_field(asfield)
+ "#{id_prefix_for_type(asfield.containing_type)}-field-#{to_id(asfield.name)}"
+ end
+
+ def self.id_prefix_for_parameter(asmethod, param_name)
+ "#{id_prefix_for_method(asmethod)}-param-#{to_id(param_name)}"
+ end
+
+ def self.id_for_type_description(astype)
+ "#{id_prefix_for_type(astype)}-description"
+ end
+
+ def self.id_for_method_description(asmethod)
+ "#{id_prefix_for_method(asmethod)}-description"
+ end
+
+ def self.id_for_method_return(asmethod)
+ "#{id_prefix_for_method(asmethod)}-return"
+ end
+
+ def self.id_for_field_description(asfield)
+ "#{id_prefix_for_field(asfield)}-description"
+ end
+
+ def self.id_for_parameter_description(asmethod, param_name)
+ "#{id_prefix_for_parameter(asmethod, param_name)}-description"
+ end
+
+ def self.id_prefix_for_throws(asmethod, exception_type)
+ "#{id_prefix_for_method(asmethod)}-throws-#{to_id(exception_type.qualified_name)}"
+ end
+
+ def self.id_for_throws_description(asmethod, exception_type)
+ "#{id_prefix_for_throws(asmethod, exception_type)}-description"
+ end
+
+ def self.id_for_type_see(astype, index)
+ "#{id_prefix_for_type(astype)}-see-#{index}"
+ end
+
+ def self.id_for_method_see(asmethod, index)
+ "#{id_prefix_for_method(asmethod)}-see-#{index}"
+ end
+
+ def self.to_id(text)
+ text.gsub(/[^-.a-zA-Z0-9]/) do |match|
+ "_" + match[0].to_s(16)
+ end
+ end
+
+ def self.from_id(text)
+ text.gsub(/_([0-9a-fA-F]{2})/) do |match|
+ $1.to_s.to_i(16).chr
+ end
+ end
+end
+
+# vim:sw=2:sts=2
</pre></div>
<hr /><a name="file5" /><div class="file">
<span class="pathname" id="added">trunk/as2api/localisation/xliff</span><br />
<div class="fileheader" id="added"><big><b>xliff_reader.rb</b></big> <small id="info">added at 284</small></div>
<pre class="diff"><small id="info">--- trunk/as2api/localisation/xliff/xliff_reader.rb        2006-02-26 16:07:25 UTC (rev 283)
+++ trunk/as2api/localisation/xliff/xliff_reader.rb        2006-02-27 13:59:52 UTC (rev 284)
@@ -0,0 +1,158 @@
</small></pre><pre class="diff" id="added">+
+require 'rexml/document'
+
+# So, this code is all a bit of a mess, tbh. Once I've got a working codebase
+# to look at, and I actually understand the indended use of the different
+# parts of the XLIFF spec, this could all do with a nice rewrite
+
+
+XLIFFFile = Struct.new(:original, :source_language, :target_language)
+
+
+module TranslationHandler
+ def start_file(file); end
+ def end_file; end
+
+ def start_trans_unit(id); end
+ def end_trans_unit; end
+
+ def start_source; end
+ def end_source; end
+ def start_target; end
+ def end_target; end
+
+ def text(text); end
+
+ def ph(id); PhHandler.new; end
+end
+
+class PhHandler
+ def start_ph; end
+ def end_ph; end
+
+ def start_sub; end
+ def end_sub; end
+
+ def text(text); end
+end
+
+
+class XLIFFReader
+
+ def initialize(io, translation_handler)
+ @doc = REXML::Document.new(io)
+ @handler = translation_handler
+ end
+
+ def parse
+ @doc.root.each_element("file") do |file_element|
+ file = XLIFFFile.new
+ file.original = file_element.attribute("original").value
+ file.source_language = file_element.attribute("source-language").value
+ file.target_language = file_element.attribute("target-language").value
+
+ @handler.start_file(file)
+ file_element.each_element("body/trans-unit") do |trans_unit_element|
+        parse_trans_unit(trans_unit_element)
+ end
+ @handler.end_file
+ end
+ end
+
+ def parse_trans_unit(trans_unit_element)
+ id = trans_unit_element.attribute("id")
+ @handler.start_trans_unit(id.value)
+ trans_unit_element.each_element("source") do |source_element|
+ parse_source(source_element)
+ end
+ trans_unit_element.each_element("target") do |target_element|
+ parse_target(target_element)
+ end
+ @handler.end_trans_unit
+ end
+
+ def parse_source(source_element)
+ return if source_element.size == 0
+
+ @handler.start_source
+ source_element.each_element do |element|
+ end
+ @handler.end_source
+ end
+
+ def parse_target(target_element)
+ return if target_element.size == 0
+
+ @handler.start_target
+ target_element.each_child do |element|
+ case element.node_type
+        when :text
+         @handler.text(element.value)
+        when :element
+         case element.name
+         when "ph"
+         parse_ph(element)
+         else
+         raise "unhandled element #{element.name.inspect}"
+         end
+        else
+         raise "unhandled node type #{element.inspect}"
+ end
+ end
+ @handler.end_target
+ end
+
+ def parse_ph(ph_element)
+ ph_handler = @handler.ph(ph_element.attribute("id").value)
+ ph_handler.start_ph
+ ph_element.each_child do |element|
+ case element.node_type
+        when :text
+         ph_handler.text(element.value)
+        when :element
+         case element.name
+         when "sub"
+         parse_sub(ph_handler, element)
+         else
+         raise "unhandled element #{element.name.inspect}"
+         end
+        else
+         raise "unhandled node type #{element.inspect}"
+ end
+ end
+ ph_handler.end_ph()
+ end
+
+ def parse_sub(ph_handler, sub_element)
+ ph_handler.start_sub
+ sub_element.each_child do |element|
+ case element.node_type
+        when :text
+         ph_handler.text(element.value)
+        else
+         raise "unhandled node type #{element.inspect}"
+ end
+ end
+ ph_handler.end_sub
+ end
+end
+
+if __FILE__ == $0
+
+ class MyListener
+ include TranslationHandler
+
+ def start_file(file); puts "file(#{file.original}),"; end
+ def start_trans_unit(id); puts " unit(#{id}),"; end
+ def start_target; print " target<"; end
+ def end_target; puts ">"; end
+ def text(text); print text; end
+ end
+
+ File.open(ARGV[0]) do |io|
+ XLIFFReader.new(io, MyListener.new).parse
+ end
+
+end
+
+# vim:sw=2:sts=2
</pre></div>
<hr /><a name="file6" /><div class="file">
<span class="pathname" id="added">trunk/as2api/localisation/xliff</span><br />
<div class="fileheader" id="added"><big><b>xliff_writer.rb</b></big> <small id="info">added at 284</small></div>
<pre class="diff"><small id="info">--- trunk/as2api/localisation/xliff/xliff_writer.rb        2006-02-26 16:07:25 UTC (rev 283)
+++ trunk/as2api/localisation/xliff/xliff_writer.rb        2006-02-27 13:59:52 UTC (rev 284)
@@ -0,0 +1,89 @@
</small></pre><pre class="diff" id="added">+
+module XLIFFWriter
+ private
+
+ TAGS = [
+ "alt-trans",
+ "bin-source",
+ "bin-target",
+ "bin-unit",
+ "body",
+ "bpt",
+ "bx",
+ "context",
+ "context-group",
+ "count",
+ "count-group",
+ "ept",
+ "ex",
+ "external-file",
+ "file",
+ "g",
+ "glossary",
+ "group",
+ "header",
+ "internal-file",
+ "it",
+ "mrk",
+ "note",
+ "ph",
+ "phase",
+ "phase-group",
+ "prop",
+ "prop-group",
+ "reference",
+ "skl",
+ "source",
+ "sub",
+ "target",
+ "tool",
+ "trans-unit",
+ "x",
+ "xliff"
+ ]
+
+
+ TAGS.each do |name|
+ class_eval <<-HERE
+ def xliff_#{name.gsub(/-/, "_")}(*args)
+        if block_given?
+         @io.element("#{name}", *args) { yield }
+        else
+         if args.length == 0
+         @io.empty_tag("#{name}")
+         else
+         if args[0].instance_of?(String)
+         @io.simple_element("#{name}", *args)
+         else
+         @io.empty_tag("#{name}", *args)
+         end
+         end
+        end
+ end
+ HERE
+ end
+
+ public
+
+ def pcdata(text)
+ @io.pcdata(text)
+ end
+
+ def pi(text)
+ @io.pi(text)
+ end
+
+ def comment(text)
+ @io.comment(text)
+ end
+
+ def doctype(name, syspub, public_id, system_id)
+ @io.doctype(name, syspub, public_id, system_id)
+ end
+
+ def passthrough(text)
+ @io.passthrough(text)
+ end
+
+ def xml; @io end
+end
</pre></div>
<hr /><a name="file7" /><div class="file">
<span class="pathname">trunk/as2api/ui</span><br />
<div class="fileheader"><big><b>cli.rb</b></big> <small id="info">283 -> 284</small></div>
<pre class="diff"><small id="info">--- trunk/as2api/ui/cli.rb        2006-02-26 16:07:25 UTC (rev 283)
+++ trunk/as2api/ui/cli.rb        2006-02-27 13:59:52 UTC (rev 284)
@@ -14,6 +14,8 @@
</small></pre><pre class="diff" id="context"> require 'set'
require 'output/html/driver'
require 'output/html/diff'
</pre><pre class="diff" id="added">+require 'localisation/xliff/driver.rb'
+require 'localisation/xliff/translation_loader.rb'
</pre><pre class="diff" id="context">
include GetText
</pre><pre class="diff"><small id="info">@@ -31,7 +33,9 @@
</small></pre><pre class="diff" id="context">                  :sources,
                 :format_html,
                 :source_lang,
</pre><pre class="diff" id="removed">-                 :target_lang<span id="removedchars">)</span>
</pre><pre class="diff" id="added">+                 :target_lang<span id="addedchars">,</span>
+                 :xliff_import,
+                 :xliff_export)
</pre><pre class="diff" id="context">
SourceFile = Struct.new(:prefix, :suffix)
</pre><pre class="diff"><small id="info">@@ -115,7 +119,9 @@
</small></pre><pre class="diff" id="context"> [ "--sources", GetoptLong::NO_ARGUMENT ],
[ "--format-html", GetoptLong::NO_ARGUMENT ],
[ "--source-lang", GetoptLong::REQUIRED_ARGUMENT ],
</pre><pre class="diff" id="removed">- [ "--target-lang", GetoptLong::REQUIRED_ARGUMENT ]
</pre><pre class="diff" id="added">+ [ "--target-lang", GetoptLong::REQUIRED_ARGUMENT ]<span id="addedchars">,</span>
+ [ "--xliff-import", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--xliff-export", GetoptLong::REQUIRED_ARGUMENT ]
</pre><pre class="diff" id="context"> )
conf = Conf.new
</pre><pre class="diff"><small id="info">@@ -154,12 +160,22 @@
</small></pre><pre class="diff" id="context">          conf.source_lang = arg
        when "--target-lang"
         conf.target_lang = arg
</pre><pre class="diff" id="added">+        when "--xliff-import"
+         conf.xliff_import = arg
+        when "--xliff-export"
+         conf.xliff_export = arg
</pre><pre class="diff" id="context"> end
end
if ARGV.empty?
usage
error(_("No packages specified"))
end
</pre><pre class="diff" id="added">+ if conf.xliff_import && conf.xliff_export
+ error(_("Options can't be used together: %s") % "--xliff-import --xliff-export")
+ end
+ if conf.xliff_export && (conf.source_lang.nil? || conf.target_lang.nil?)
+ error(_("Both --source-lang and --target-lang must be provided with --xliff-export"))
+ end
</pre><pre class="diff" id="context"> ARGV.each do |package_spec|
conf.package_filters << to_filter(package_spec)
end
</pre><pre class="diff"><small id="info">@@ -237,14 +253,30 @@
</small></pre><pre class="diff" id="context"> type_agregator
end
</pre><pre class="diff" id="added">+ def xliff_import(type_aggregator)
+ update_docs(@conf, type_aggregator)
+ end
+
+ def xliff_export(type_aggregator)
+ generate_xliff(@conf, type_aggregator)
+ end
+
</pre><pre class="diff" id="context"> def main
@conf = parse_opts
files = find_sources(@conf.classpath)
error(_("No source files matching specified packages")) if files.empty?
type_agregator = parse_all(files, @conf.classpath)
</pre><pre class="diff" id="added">+ if @conf.xliff_import
+ xliff_import(type_agregator)
+ end
</pre><pre class="diff" id="context"> type_agregator.resolve_types
</pre><pre class="diff" id="removed">- document_types(@conf, type_agregator)
</pre><pre class="diff" id="added">+ if @conf.xliff_export
+ xliff_export(type_agregator)
+ else
+ document_types(@conf, type_agregator)
+ end
</pre><pre class="diff" id="context">
</pre><pre class="diff" id="added"><a name="task1" />+ # <span class="task">TODO</span>: remove this hackery
</pre><pre class="diff" id="context"> unless @conf.oldrev_classpath.empty?
old_files = find_sources(@conf.oldrev_classpath)
error(_("No source files matching specified packages in oldrev-classpath")) if old_files.empty?
</pre></div>
<center><small><a href="http://www.badgers-in-foil.co.uk/projects/cvsspam/" title="commit -> email">CVSspam</a> 0.2.11</small></center>
</body></html>