translatomatic 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.translatomatic/config.yml +18 -0
  3. data/.travis.yml +33 -33
  4. data/Gemfile +6 -4
  5. data/README.de.md +53 -18
  6. data/README.es.md +55 -20
  7. data/README.fr.md +54 -19
  8. data/README.it.md +58 -23
  9. data/README.ja.md +54 -19
  10. data/README.ko.md +58 -23
  11. data/README.md +167 -141
  12. data/README.ms.md +51 -16
  13. data/README.pt.md +58 -23
  14. data/README.ru.md +53 -18
  15. data/README.sv.md +53 -18
  16. data/README.zh.md +53 -18
  17. data/bin/translatomatic +6 -6
  18. data/bin/travis +24 -26
  19. data/config/locales/translatomatic/de.yml +22 -11
  20. data/config/locales/translatomatic/en.yml +21 -12
  21. data/config/locales/translatomatic/es.yml +22 -11
  22. data/config/locales/translatomatic/fr.yml +22 -12
  23. data/config/locales/translatomatic/it.yml +22 -11
  24. data/config/locales/translatomatic/ja.yml +22 -11
  25. data/config/locales/translatomatic/ko.yml +22 -11
  26. data/config/locales/translatomatic/ms.yml +22 -11
  27. data/config/locales/translatomatic/pt.yml +22 -11
  28. data/config/locales/translatomatic/ru.yml +22 -11
  29. data/config/locales/translatomatic/sv.yml +22 -11
  30. data/config/locales/translatomatic/zh.yml +22 -11
  31. data/db/migrate/201712170000_initial.rb +25 -25
  32. data/lib/translatomatic/cli/base.rb +81 -73
  33. data/lib/translatomatic/cli/config.rb +110 -81
  34. data/lib/translatomatic/cli/main.rb +85 -72
  35. data/lib/translatomatic/cli/translate.rb +141 -106
  36. data/lib/translatomatic/cli.rb +8 -8
  37. data/lib/translatomatic/config.rb +302 -155
  38. data/lib/translatomatic/converter.rb +28 -260
  39. data/lib/translatomatic/database.rb +134 -134
  40. data/lib/translatomatic/define_options.rb +22 -0
  41. data/lib/translatomatic/escaped_unicode.rb +0 -0
  42. data/lib/translatomatic/extractor/base.rb +16 -16
  43. data/lib/translatomatic/extractor/ruby.rb +6 -6
  44. data/lib/translatomatic/extractor.rb +5 -5
  45. data/lib/translatomatic/file_translator.rb +269 -0
  46. data/lib/translatomatic/http_request.rb +162 -162
  47. data/lib/translatomatic/locale.rb +76 -76
  48. data/lib/translatomatic/logger.rb +23 -23
  49. data/lib/translatomatic/model/locale.rb +25 -25
  50. data/lib/translatomatic/model/text.rb +19 -19
  51. data/lib/translatomatic/model.rb +1 -1
  52. data/lib/translatomatic/option.rb +37 -41
  53. data/lib/translatomatic/progress_updater.rb +13 -13
  54. data/lib/translatomatic/resource_file/base.rb +269 -192
  55. data/lib/translatomatic/resource_file/csv.rb +37 -0
  56. data/lib/translatomatic/resource_file/html.rb +54 -47
  57. data/lib/translatomatic/resource_file/markdown.rb +50 -55
  58. data/lib/translatomatic/resource_file/plist.rb +153 -19
  59. data/lib/translatomatic/resource_file/po.rb +107 -0
  60. data/lib/translatomatic/resource_file/properties.rb +91 -90
  61. data/lib/translatomatic/resource_file/resw.rb +50 -30
  62. data/lib/translatomatic/resource_file/subtitle.rb +75 -0
  63. data/lib/translatomatic/resource_file/text.rb +24 -30
  64. data/lib/translatomatic/resource_file/xcode_strings.rb +75 -80
  65. data/lib/translatomatic/resource_file/xml.rb +98 -91
  66. data/lib/translatomatic/resource_file/yaml.rb +94 -116
  67. data/lib/translatomatic/resource_file.rb +87 -78
  68. data/lib/translatomatic/string.rb +188 -188
  69. data/lib/translatomatic/tmx/document.rb +99 -99
  70. data/lib/translatomatic/translation_result.rb +63 -63
  71. data/lib/translatomatic/{converter_stats.rb → translation_stats.rb} +17 -17
  72. data/lib/translatomatic/translator/base.rb +1 -1
  73. data/lib/translatomatic/translator/google.rb +2 -0
  74. data/lib/translatomatic/translator.rb +10 -2
  75. data/lib/translatomatic/util.rb +45 -45
  76. data/lib/translatomatic/version.rb +7 -7
  77. data/lib/translatomatic.rb +52 -49
  78. data/translatomatic.gemspec +3 -2
  79. metadata +25 -5
@@ -1,55 +1,50 @@
1
- require 'kramdown'
2
- require 'reverse_markdown'
3
-
4
- module Translatomatic::ResourceFile
5
- # Markdown resource file
6
- class Markdown < HTML
7
-
8
- # (see Translatomatic::ResourceFile::Base.extensions)
9
- def self.extensions
10
- %w{md}
11
- end
12
-
13
- # (see Translatomatic::ResourceFile::Base#save)
14
- def save(target = path, options = {})
15
- if @doc
16
- begin
17
- add_created_by unless options[:no_created_by]
18
- html = @doc.to_html
19
- # convert html back to markdown
20
- markdown = ReverseMarkdown.convert(html, unknown_tags: :bypass)
21
- target.write(markdown.chomp)
22
- rescue Exception => e
23
- log.error t("resource.error", message: e.message)
24
- end
25
- end
26
- end
27
-
28
- private
29
-
30
- def add_created_by
31
- @created_by ||= begin
32
- body = @doc.at('body')
33
- body.add_child("<p><i>#{created_by}</i></p>")
34
- end
35
- end
36
-
37
- def read(path)
38
- begin
39
- # read markdown and convert to html
40
- markdown = path.read
41
- html = Kramdown::Document.new(markdown).to_html
42
- # parse html with nokogiri
43
- @doc = Nokogiri::HTML(html) do |config|
44
- config.noblanks
45
- end
46
- init_nodemap(@doc)
47
- rescue Exception => e
48
- log.error t("resource.error", message: e.message)
49
- @valid = false
50
- {}
51
- end
52
- end
53
-
54
- end # class
55
- end # module
1
+ require 'kramdown'
2
+ require 'reverse_markdown'
3
+
4
+ module Translatomatic::ResourceFile
5
+ # Markdown resource file
6
+ class Markdown < HTML
7
+
8
+ # (see Translatomatic::ResourceFile::Base.extensions)
9
+ def self.extensions
10
+ %w{md}
11
+ end
12
+
13
+ # (see Translatomatic::ResourceFile::Base#save)
14
+ def save(target = path, options = {})
15
+ if @doc
16
+ add_created_by unless options[:no_created_by]
17
+ html = @doc.to_html
18
+ # convert html back to markdown
19
+ markdown = ReverseMarkdown.convert(html, unknown_tags: :bypass)
20
+ target.write(markdown.chomp)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def add_created_by
27
+ @created_by ||= begin
28
+ body = @doc.at('body')
29
+ body.add_child("<p><i>#{created_by}</i></p>")
30
+ end
31
+ end
32
+
33
+ def read_doc
34
+ # read markdown and convert to html
35
+ markdown = read_contents(@path)
36
+ if markdown.blank?
37
+ empty_doc
38
+ else
39
+ html = Kramdown::Document.new(markdown).to_html
40
+ # parse html with nokogiri
41
+ doc = Nokogiri::HTML(html) do |config|
42
+ config.noblanks
43
+ end
44
+ parse_error(doc.errors[0]) if doc.errors.present?
45
+ doc
46
+ end
47
+ end
48
+
49
+ end # class
50
+ end # module
@@ -1,19 +1,153 @@
1
- module Translatomatic::ResourceFile
2
- # Property list resource file
3
- # @see https://en.wikipedia.org/wiki/Property_list
4
- class Plist < XML
5
- include Translatomatic::ResourceFile::XCodeStringsLocalePath
6
-
7
- # (see Translatomatic::ResourceFile::Base.extensions)
8
- def self.extensions
9
- %w{plist}
10
- end
11
-
12
- private
13
-
14
- def text_nodes_xpath
15
- '//*[not(self::key)]/text()'
16
- end
17
-
18
- end # class
19
- end # module
1
+ module Translatomatic::ResourceFile
2
+ # Property list resource file
3
+ # @see https://en.wikipedia.org/wiki/Property_list
4
+ class Plist < XML
5
+ # property list types:
6
+ # array, dict, string, data, date, integer, real, boolean
7
+ # boolean is <true /> or <false />
8
+
9
+ include Translatomatic::ResourceFile::XCodeStringsLocalePath
10
+
11
+ # (see Translatomatic::ResourceFile::Base.extensions)
12
+ def self.extensions
13
+ %w{plist}
14
+ end
15
+
16
+ # (see Translatomatic::ResourceFile::Base.is_key_value?)
17
+ def self.is_key_value?
18
+ true
19
+ end
20
+
21
+ private
22
+
23
+ def init_nodemap
24
+ result = Parser.new.parse(@doc)
25
+ #puts "parser result:"
26
+ #p result
27
+ @flattened_data = flatten(result)
28
+ @nodemap = @flattened_data.transform_values { |i| i.node }
29
+ #puts "nodemap:"
30
+ #p @nodemap
31
+ end
32
+
33
+ def init_properties
34
+ @properties = @flattened_data.transform_values { |i| i.content }
35
+ end
36
+
37
+ def create_node(key, value)
38
+ # add properties to first dict found
39
+ dict = @doc.xpath("//dict")
40
+ # TODO: not sure sure what to do if dict is missing
41
+ raise "missing top level dictionary" unless dict.present?
42
+ dict = dict[0]
43
+
44
+ # add xml: <data name="key"><value>value</value></data>
45
+ key_node = Nokogiri::XML::Node.new("key", @doc)
46
+ key_node.content = key
47
+ value_node = Nokogiri::XML::Node.new("string", @doc)
48
+ value_node.content = value
49
+ dict.add_child(key_node)
50
+ dict.add_child(value_node)
51
+
52
+ @nodemap[key] = value_node
53
+ @properties[key] = value
54
+ end
55
+
56
+ def empty_doc
57
+ Nokogiri::XML(EMPTY_DOC)
58
+ end
59
+
60
+ EMPTY_DOC=<<EOM
61
+ <?xml version="1.0" encoding="UTF-8"?>
62
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
63
+ <plist version="1.0">
64
+ <dict>
65
+ </dict>
66
+ </plist>
67
+ EOM
68
+
69
+ PlistNode = Struct.new(:node, :content) do
70
+ def inspect
71
+ "PlistNode:#{content}"
72
+ end
73
+ end
74
+
75
+ # Adapted from nokogiri-plist parser
76
+ # @see https://github.com/caseyhoward/nokogiri-plist
77
+ class Parser
78
+
79
+ def parse(xml, options = {})
80
+ @converters = {
81
+ 'integer' => Proc.new { |node| node.content.to_i },
82
+ 'real' => Proc.new { |node| node.content.to_f },
83
+ 'string' => Proc.new { |node| node.content.to_s },
84
+ # DateTime.parse(node.content)
85
+ 'date' => Proc.new { |node| node.content.to_s },
86
+ 'true' => Proc.new { |node| true },
87
+ 'false' => Proc.new { |node| false },
88
+ 'dict' => Proc.new { |node| parse_dict(node) },
89
+ 'array' => Proc.new { |node| parse_array(node) },
90
+ 'data' => Proc.new { |node| node.content.to_s }
91
+ }.merge(options[:converters] || {})
92
+
93
+ @dict_class = options[:dict_class] || Hash
94
+ plist = xml.root
95
+ plist = plist.children.first if plist.name == "plist"
96
+ result = parse_value_node(next_valid_sibling plist)
97
+ plist_node_value(result)
98
+ end
99
+
100
+ def parse_value_node(value_node)
101
+ value = @converters[value_node.name].call(value_node)
102
+ PlistNode.new(value_node, value)
103
+ end
104
+
105
+ def valid_type?(type)
106
+ @converters.has_key? type
107
+ end
108
+
109
+ def valid_node?(node)
110
+ valid_type?(node.name) or node.name == "key"
111
+ end
112
+
113
+ def parse_dict(node)
114
+ node.xpath('./key').inject(@dict_class.new) do |result, key_node|
115
+ plist_node = parse_value_node(next_valid_sibling key_node)
116
+ value = plist_node_value(plist_node)
117
+ result[key_node.content] = value
118
+ result
119
+ end
120
+ end
121
+
122
+ # if the PlistNode value is an array or hash, use that directly
123
+ # instead of the PlistNode.
124
+ def plist_node_value(plist_node)
125
+ content = plist_node.content
126
+ if content.kind_of?(Array) || content.kind_of?(Hash)
127
+ content
128
+ else
129
+ plist_node
130
+ end
131
+ end
132
+
133
+ def parse_array(node)
134
+ node.children.inject([]) do |result, child|
135
+ if valid_node?(child)
136
+ plist_node = parse_value_node(child)
137
+ result << plist_node_value(plist_node)
138
+ end
139
+ result
140
+ end
141
+ end
142
+
143
+ def next_valid_sibling(node)
144
+ until node.nil? or valid_type? node.name
145
+ node = node.next_sibling
146
+ end
147
+ node
148
+ end
149
+
150
+ end
151
+
152
+ end # class
153
+ end # module
@@ -0,0 +1,107 @@
1
+ require 'poparser'
2
+
3
+ module Translatomatic::ResourceFile
4
+ # Property list resource file
5
+ # @see https://en.wikipedia.org/wiki/Property_list
6
+ class PO < Base
7
+
8
+ # (see Translatomatic::ResourceFile::Base.extensions)
9
+ def self.extensions
10
+ %w{po pot}
11
+ end
12
+
13
+ # (see Translatomatic::ResourceFile::Base.is_key_value?)
14
+ def self.is_key_value?
15
+ true
16
+ end
17
+
18
+ # (see Translatomatic::ResourceFile::Base#set)
19
+ def set(key, value)
20
+ super(key, value)
21
+
22
+ unless @pomap.include?(key)
23
+ # new key, create po entry
24
+ po << {
25
+ msgid: key,
26
+ msgstr: value
27
+ }
28
+ entry = po.entries[-1]
29
+ add_entry(entry, :msgid, 0)
30
+ else
31
+ po_property = @pomap[key]
32
+ entry = po_property.entry
33
+ if entry.plural?
34
+ msgstr = entry.msgstr || []
35
+ msgstr[po_property.index] = value
36
+ entry.msgstr = msgstr
37
+ else
38
+ entry.msgstr = value
39
+ end
40
+ end
41
+ end
42
+
43
+ # (see Translatomatic::ResourceFile::Base#save)
44
+ def save(target = path, options = {})
45
+ if @po
46
+ add_created_by unless options[:no_created_by]
47
+ target.write(@po.to_s)
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ class PoProperty
54
+ attr_reader :entry
55
+ attr_reader :value_index
56
+
57
+ def initialize(entry, value_index)
58
+ @entry = entry
59
+ @value_index = value_index
60
+ end
61
+
62
+ def value
63
+ if entry.plural?
64
+ entry.msgstr[value_index]
65
+ else
66
+ entry.msgstr
67
+ end
68
+ end
69
+ end
70
+
71
+ def init
72
+ @po = PoParser.parse('')
73
+ @pomap = {}
74
+ end
75
+
76
+ def load
77
+ content = read_contents(@path)
78
+ @po = PoParser.parse(content)
79
+ @pomap = init_pomap(@po)
80
+ @properties = pomap_to_properties
81
+ end
82
+
83
+ def add_created_by
84
+ # TODO
85
+ end
86
+
87
+ # create mapping from key to PoProperty
88
+ def init_pomap(po)
89
+ pomap = {}
90
+ po.entries.each do |entry|
91
+ add_entry(entry, :msgid, 0)
92
+ add_entry(entry, :msgid_plural, 1) if entry.plural?
93
+ end
94
+ pomap
95
+ end
96
+
97
+ def pomap_to_properties
98
+ @pomap.transform_values { |i| i.value }
99
+ end
100
+
101
+ def add_entry(entry, key, index)
102
+ untranslated = entry.send(key)
103
+ @pomap[untranslated] = PoProperty.new(entry, index) if untranslated
104
+ end
105
+
106
+ end # class
107
+ end # module
@@ -1,90 +1,91 @@
1
- require 'date'
2
-
3
- module Translatomatic::ResourceFile
4
- # Properties resource file
5
- # @see https://docs.oracle.com/javase/tutorial/essential/environment/properties.html
6
- class Properties < Base
7
-
8
- # (see Translatomatic::ResourceFile::Base.extensions)
9
- def self.extensions
10
- %w{properties}
11
- end
12
-
13
- # (see Translatomatic::ResourceFile::Base#initialize)
14
- def initialize(path, locale = nil)
15
- super(path, locale)
16
- @valid = true
17
- @properties = @path.exist? ? read(@path) : {}
18
- end
19
-
20
- # (see Translatomatic::ResourceFile::Base#save)
21
- def save(target = path, options = {})
22
- out = ""
23
- out += add_created_by unless options[:no_created_by]
24
- properties.each do |key, value|
25
- # TODO: maintain original line ending format?
26
- value = value.gsub("\n", "\\n") if value # convert newlines to \n
27
- out += "#{key} = #{value}\n"
28
- end
29
- # escape unicode characters
30
- out = Translatomatic::EscapedUnicode.escape(out)
31
- target.write(out)
32
- end
33
-
34
- # (see Translatomatic::ResourceFile::Base#supports_variable_interpolation?)
35
- def supports_variable_interpolation?
36
- true
37
- end
38
-
39
- # (see Translatomatic::ResourceFile::Base#create_variable)
40
- def create_variable(name)
41
- return "{#{name}}"
42
- end
43
-
44
- # (see Translatomatic::ResourceFile::Base#variable_regex)
45
- def variable_regex
46
- /\{.*?\}/
47
- end
48
-
49
- private
50
-
51
- def add_created_by
52
- comment(created_by)
53
- end
54
-
55
- def comment(text)
56
- "# #{text}\n"
57
- end
58
-
59
- # parse key = value property file
60
- def read(path)
61
- contents = path.read
62
- # convert escaped unicode characters into unicode
63
- contents = Translatomatic::EscapedUnicode.unescape(contents)
64
- result = {}
65
- contents.gsub!(/\\\s*\n\s*/m, '') # put multi line strings on one line
66
- lines = contents.split("\n")
67
-
68
- lines.each do |line|
69
- line.strip!
70
- next if line.length == 0
71
- equal_idx = line.index("=")
72
- colon_idx = line.index(":")
73
-
74
- if line[0] == ?! || line[0] == ?#
75
- # comment
76
- # TODO: translate comments or keep originals?
77
- next
78
- elsif equal_idx.nil? && colon_idx.nil?
79
- @valid = false
80
- return {}
81
- end
82
- name, value = line.split(/\s*[=:]\s*/, 2)
83
- value = value.gsub("\\n", "\n") # convert \n to newlines
84
- result[name] = value
85
- end
86
- result
87
- end
88
-
89
- end
90
- end
1
+ require 'date'
2
+
3
+ module Translatomatic::ResourceFile
4
+ # Properties resource file
5
+ # @see https://docs.oracle.com/javase/tutorial/essential/environment/properties.html
6
+ class Properties < Base
7
+
8
+ # (see Translatomatic::ResourceFile::Base.extensions)
9
+ def self.extensions
10
+ %w{properties}
11
+ end
12
+
13
+ # (see Translatomatic::ResourceFile::Base.is_key_value?)
14
+ def self.is_key_value?
15
+ true
16
+ end
17
+
18
+ # (see Translatomatic::ResourceFile::Base.supports_variable_interpolation?)
19
+ def self.supports_variable_interpolation?
20
+ true
21
+ end
22
+
23
+ # (see Translatomatic::ResourceFile::Base#save)
24
+ def save(target = path, options = {})
25
+ out = ""
26
+ out += add_created_by unless options[:no_created_by]
27
+ properties.each do |key, value|
28
+ # TODO: maintain original line ending format?
29
+ value = value.gsub("\n", "\\n") if value # convert newlines to \n
30
+ out += "#{key} = #{value}\n"
31
+ end
32
+ # escape unicode characters
33
+ out = Translatomatic::EscapedUnicode.escape(out)
34
+ target.write(out)
35
+ end
36
+
37
+ # (see Translatomatic::ResourceFile::Base#create_variable)
38
+ def create_variable(name)
39
+ return "{#{name}}"
40
+ end
41
+
42
+ # (see Translatomatic::ResourceFile::Base#variable_regex)
43
+ def variable_regex
44
+ /\{.*?\}/
45
+ end
46
+
47
+ private
48
+
49
+ def load
50
+ @properties = read_properties
51
+ end
52
+
53
+ def add_created_by
54
+ comment(created_by)
55
+ end
56
+
57
+ def comment(text)
58
+ "# #{text}\n"
59
+ end
60
+
61
+ def read_properties
62
+ contents = read_contents(@path)
63
+ # convert escaped unicode characters into unicode
64
+ contents = Translatomatic::EscapedUnicode.unescape(contents)
65
+ result = {}
66
+ contents.gsub!(/\\\s*\n\s*/m, '') # put multi line strings on one line
67
+ lines = contents.split("\n")
68
+
69
+ lines.each do |line|
70
+ line.strip!
71
+ next if line.length == 0
72
+ equal_idx = line.index("=")
73
+ colon_idx = line.index(":")
74
+
75
+ if line[0] == ?! || line[0] == ?#
76
+ # comment
77
+ # TODO: translate comments or keep originals?
78
+ next
79
+ elsif equal_idx.nil? && colon_idx.nil?
80
+ # TODO: throw exception here?
81
+ return {}
82
+ end
83
+ name, value = line.split(/\s*[=:]\s*/, 2)
84
+ value = value.gsub("\\n", "\n") # convert \n to newlines
85
+ result[name] = value
86
+ end
87
+ result
88
+ end
89
+
90
+ end
91
+ end
@@ -1,31 +1,51 @@
1
- module Translatomatic::ResourceFile
1
+ module Translatomatic::ResourceFile
2
2
  # Windows resources file (XML)
3
- class RESW < XML
4
-
5
- # (see Translatomatic::ResourceFile::Base.extensions)
6
- def self.extensions
7
- %w{resw}
8
- end
9
-
10
- # (see Translatomatic::ResourceFile::Base#locale_path)
11
- def locale_path(locale)
12
- # e.g. strings/en-US/resources.resw
13
- dir = path.dirname
14
- dir.parent + locale.to_s + path.basename
15
- end
16
-
17
- private
18
-
19
- def create_nodemap(doc)
20
- result = {}
21
- key_values = doc.search('//data/@name|//text()')
22
- key_values.each_slice(2) do |key, value|
23
- key = key.value
24
- value = value
25
- result[key] = value
26
- end
27
- result
28
- end
29
-
30
- end # class
31
- end # module
3
+ class RESW < XML
4
+
5
+ # (see Translatomatic::ResourceFile::Base.extensions)
6
+ def self.extensions
7
+ %w{resw resx}
8
+ end
9
+
10
+ # (see Translatomatic::ResourceFile::Base.is_key_value?)
11
+ def self.is_key_value?
12
+ true
13
+ end
14
+
15
+ # (see Translatomatic::ResourceFile::Base#locale_path)
16
+ def locale_path(locale)
17
+ # e.g. strings/en-US/resources.resw
18
+ dir = path.dirname
19
+ dir.parent + locale.to_s + path.basename
20
+ end
21
+
22
+ private
23
+
24
+ def init_nodemap
25
+ result = {}
26
+ key_values = @doc.search('//data/@name|//text()')
27
+ key_values.each_slice(2) do |key, value|
28
+ key = key.value
29
+ value = value
30
+ result[key] = value
31
+ end
32
+ @nodemap = result
33
+ end
34
+
35
+ def create_node(key, value)
36
+ # add xml: <data name="key"><value>value</value></data>
37
+ data_node = Nokogiri::XML::Node.new("data", @doc)
38
+ data_node["name"] = key
39
+ value_node = Nokogiri::XML::Node.new("value", @doc)
40
+ text_node = Nokogiri::XML::Text.new(value, @doc)
41
+ value_node.add_child(text_node)
42
+ data_node.add_child(value_node)
43
+
44
+ @doc.root.add_child(data_node)
45
+
46
+ @nodemap[key] = text_node
47
+ @properties[key] = value
48
+ end
49
+
50
+ end # class
51
+ end # module