translatomatic 0.1.0 → 0.1.1
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.
- checksums.yaml +5 -5
- data/.gitattributes +1 -0
- data/.gitignore +15 -12
- data/.rspec +3 -3
- data/.travis.yml +32 -50
- data/CODE_OF_CONDUCT.md +74 -74
- data/Gemfile +29 -5
- data/Guardfile +48 -0
- data/LICENSE.txt +21 -21
- data/README.de.md +92 -0
- data/README.es.md +92 -0
- data/README.fr.md +92 -0
- data/README.it.md +92 -0
- data/README.ja.md +92 -0
- data/README.md +96 -74
- data/Rakefile +6 -6
- data/bin/setup +8 -8
- data/bin/translatomatic +6 -6
- data/bin/travis +26 -0
- data/db/database.yml +9 -9
- data/db/migrate/201712170000_initial.rb +24 -23
- data/lib/translatomatic/cli.rb +204 -80
- data/lib/translatomatic/config.rb +12 -26
- data/lib/translatomatic/converter.rb +206 -142
- data/lib/translatomatic/converter_stats.rb +27 -27
- data/lib/translatomatic/database.rb +139 -99
- data/lib/translatomatic/escaped_unicode.rb +90 -90
- data/lib/translatomatic/extractor/base.rb +14 -0
- data/lib/translatomatic/extractor/ruby.rb +5 -0
- data/lib/translatomatic/extractor.rb +4 -0
- data/lib/translatomatic/http_request.rb +133 -0
- data/lib/translatomatic/locale.rb +52 -0
- data/lib/translatomatic/logger.rb +28 -0
- data/lib/translatomatic/model/locale.rb +21 -22
- data/lib/translatomatic/model/text.rb +17 -13
- data/lib/translatomatic/model.rb +4 -4
- data/lib/translatomatic/option.rb +24 -24
- data/lib/translatomatic/progress_updater.rb +15 -0
- data/lib/translatomatic/resource_file/base.rb +169 -137
- data/lib/translatomatic/resource_file/html.rb +46 -28
- data/lib/translatomatic/resource_file/markdown.rb +54 -0
- data/lib/translatomatic/resource_file/plist.rb +30 -29
- data/lib/translatomatic/resource_file/properties.rb +72 -60
- data/lib/translatomatic/resource_file/resw.rb +30 -0
- data/lib/translatomatic/resource_file/text.rb +29 -28
- data/lib/translatomatic/resource_file/xcode_strings.rb +71 -65
- data/lib/translatomatic/resource_file/xml.rb +79 -59
- data/lib/translatomatic/resource_file/yaml.rb +82 -80
- data/lib/translatomatic/resource_file.rb +76 -74
- data/lib/translatomatic/string.rb +160 -0
- data/lib/translatomatic/tmx/document.rb +100 -0
- data/lib/translatomatic/tmx/translation_unit.rb +19 -0
- data/lib/translatomatic/tmx.rb +4 -0
- data/lib/translatomatic/translation_result.rb +75 -57
- data/lib/translatomatic/translator/base.rb +83 -47
- data/lib/translatomatic/translator/frengly.rb +57 -64
- data/lib/translatomatic/translator/google.rb +31 -30
- data/lib/translatomatic/translator/microsoft.rb +33 -32
- data/lib/translatomatic/translator/my_memory.rb +64 -55
- data/lib/translatomatic/translator/yandex.rb +39 -37
- data/lib/translatomatic/translator.rb +63 -63
- data/lib/translatomatic/util.rb +15 -24
- data/lib/translatomatic/version.rb +4 -3
- data/lib/translatomatic.rb +32 -27
- data/translatomatic.gemspec +43 -45
- metadata +52 -18
- data/Gemfile.lock +0 -137
@@ -1,137 +1,169 @@
|
|
1
|
-
# @abstract Subclasses implement different types of resource files
|
2
|
-
class Translatomatic::ResourceFile::Base
|
3
|
-
|
4
|
-
attr_accessor :locale
|
5
|
-
attr_accessor :path
|
6
|
-
|
7
|
-
# @return [Hash<String,String>] key -> value properties
|
8
|
-
attr_reader :properties
|
9
|
-
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
# @
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
#
|
57
|
-
# @
|
58
|
-
def
|
59
|
-
@properties
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
1
|
+
# @abstract Subclasses implement different types of resource files
|
2
|
+
class Translatomatic::ResourceFile::Base
|
3
|
+
|
4
|
+
attr_accessor :locale
|
5
|
+
attr_accessor :path
|
6
|
+
|
7
|
+
# @return [Hash<String,String>] key -> value properties
|
8
|
+
attr_reader :properties
|
9
|
+
|
10
|
+
# @return [Array<String>] File extensions supported by this resource file
|
11
|
+
def self.extensions
|
12
|
+
raise "extensions must be implemented by subclass"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create a new resource file.
|
16
|
+
# If locale is unspecified, attempts to determine the locale of the file
|
17
|
+
# automatically, and if that fails, uses the default locale.
|
18
|
+
# @param [String] path Path to the file
|
19
|
+
# @param [String] locale Locale of the file contents
|
20
|
+
# @return [Translatomatic::ResourceFile::Base] the resource file.
|
21
|
+
def initialize(path, locale = nil)
|
22
|
+
@path = path.kind_of?(Pathname) ? path : Pathname.new(path)
|
23
|
+
@locale = locale || detect_locale || Translatomatic::Locale.default
|
24
|
+
raise "unable to determine locale" unless @locale && @locale.language
|
25
|
+
@valid = false
|
26
|
+
@properties = {}
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [String] The format of this resource file, e.g. "Properties"
|
30
|
+
def format
|
31
|
+
self.class.name.demodulize.downcase.to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
# Create a path for the current resource file with a given locale
|
35
|
+
# @param [String] locale for the path
|
36
|
+
# @return [Pathname] The path of this resource file modified for the given locale
|
37
|
+
def locale_path(locale)
|
38
|
+
basename = path.sub_ext('').basename.to_s
|
39
|
+
|
40
|
+
extlist = extension_list
|
41
|
+
if extlist.length >= 2 && loc_idx = find_locale(extlist)
|
42
|
+
# extension(s) contains locale, replace it
|
43
|
+
extlist[loc_idx] = locale.to_s
|
44
|
+
elsif valid_locale?(basename)
|
45
|
+
# basename is a locale name, replace it
|
46
|
+
path.dirname + (locale.to_s + path.extname)
|
47
|
+
else
|
48
|
+
# remove any underscore and trailing text from basename
|
49
|
+
deunderscored = basename.sub(/_.*?$/, '')
|
50
|
+
# add _locale.ext
|
51
|
+
filename = deunderscored + "_" + locale.to_s + path.extname
|
52
|
+
path.dirname + filename
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Set all properties
|
57
|
+
# @param [Hash<String,String>] properties New properties
|
58
|
+
def properties=(properties)
|
59
|
+
# use set rather that set @properties directly as subclasses override set()
|
60
|
+
properties.each do |key, value|
|
61
|
+
set(key, value)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Get the value of a property
|
66
|
+
# @param [String] name The name of the property
|
67
|
+
# @return [String] The value of the property
|
68
|
+
def get(name)
|
69
|
+
@properties[name]
|
70
|
+
end
|
71
|
+
|
72
|
+
# Set a property
|
73
|
+
# @param [String] key The name of the property
|
74
|
+
# @param [String] value The new value of the property
|
75
|
+
# @return [String] The new value of the property
|
76
|
+
def set(name, value)
|
77
|
+
@properties[name] = value
|
78
|
+
end
|
79
|
+
|
80
|
+
# Test if the current resource file is valid
|
81
|
+
# @return true if the current file is valid
|
82
|
+
def valid?
|
83
|
+
@valid
|
84
|
+
end
|
85
|
+
|
86
|
+
# Save the resource file.
|
87
|
+
# @param [Pathname] target The destination path
|
88
|
+
# @param [Hash<Symbol, Object>] options Output format options
|
89
|
+
# @return [void]
|
90
|
+
def save(target = path, options = {})
|
91
|
+
raise "save(path) must be implemented by subclass"
|
92
|
+
end
|
93
|
+
|
94
|
+
# @return [String] String representation of this file
|
95
|
+
def to_s
|
96
|
+
"#{path.basename.to_s} (#{locale})"
|
97
|
+
end
|
98
|
+
|
99
|
+
def sentences
|
100
|
+
sentences = []
|
101
|
+
properties.values.each do |value|
|
102
|
+
string = Translatomatic::String.new(value, locale)
|
103
|
+
sentences += string.sentences
|
104
|
+
end
|
105
|
+
sentences
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
include Translatomatic::Util
|
111
|
+
|
112
|
+
def created_by
|
113
|
+
date = DateTime.now.strftime("%Y-%m-%d %H:%M")
|
114
|
+
"Created by Translatomatic #{Translatomatic::VERSION} #{date}"
|
115
|
+
end
|
116
|
+
|
117
|
+
# detect locale from filename
|
118
|
+
def detect_locale
|
119
|
+
tag = nil
|
120
|
+
basename = path.sub_ext('').basename.to_s
|
121
|
+
directory = path.dirname.basename.to_s
|
122
|
+
extlist = extension_list
|
123
|
+
|
124
|
+
if basename.match(/_([-\w]{2,})$/i)
|
125
|
+
# locale after underscore in filename
|
126
|
+
tag = $1
|
127
|
+
elsif directory.match(/^([-\w]+)\.lproj$/)
|
128
|
+
# xcode localized strings
|
129
|
+
tag = $1
|
130
|
+
elsif extlist.length >= 2 && loc_idx = find_locale(extlist)
|
131
|
+
# multiple parts to extension, e.g. index.html.en
|
132
|
+
tag = extlist[loc_idx]
|
133
|
+
elsif valid_locale?(basename)
|
134
|
+
# try to match on entire basename
|
135
|
+
# (support for rails en.yml)
|
136
|
+
tag = basename
|
137
|
+
elsif valid_locale?(path.parent.basename)
|
138
|
+
# try to match on parent directory, e.g. strings/en-US/text.resw
|
139
|
+
tag = path.parent.basename
|
140
|
+
end
|
141
|
+
|
142
|
+
tag ? Translatomatic::Locale.parse(tag, true) : nil
|
143
|
+
end
|
144
|
+
|
145
|
+
def valid_locale?(tag)
|
146
|
+
Translatomatic::Locale.new(tag).valid?
|
147
|
+
end
|
148
|
+
|
149
|
+
# test if the list of strings contains a valid locale
|
150
|
+
# return the index to the locale, or nil if no locales found
|
151
|
+
def find_locale(list)
|
152
|
+
list.find_index { |i| valid_locale?(i) }
|
153
|
+
end
|
154
|
+
|
155
|
+
# ext_sub() only removes the last extension
|
156
|
+
def strip_extensions
|
157
|
+
filename = path.basename.to_s
|
158
|
+
filename.sub!(/\..*$/, '')
|
159
|
+
path.parent + filename
|
160
|
+
end
|
161
|
+
|
162
|
+
# for index.html.de, returns ['html', 'de']
|
163
|
+
def extension_list
|
164
|
+
filename = path.basename.to_s
|
165
|
+
idx = filename.index('.')
|
166
|
+
idx && idx < filename.length - 1 ? filename[idx + 1..-1].split('.') : []
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
@@ -1,33 +1,51 @@
|
|
1
|
-
module Translatomatic::ResourceFile
|
2
|
-
class HTML < XML
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
1
|
+
module Translatomatic::ResourceFile
|
2
|
+
class HTML < XML
|
3
|
+
|
4
|
+
# (see Translatomatic::ResourceFile::Base.extensions)
|
5
|
+
def self.extensions
|
6
|
+
%w{html htm shtml}
|
7
|
+
end
|
8
|
+
|
9
|
+
# (see Translatomatic::ResourceFile::Base#locale_path)
|
10
|
+
def locale_path(locale)
|
11
|
+
extlist = extension_list
|
12
|
+
if extlist.length >= 2 && loc_idx = find_locale(extlist)
|
13
|
+
# part of the extension is the locale
|
14
|
+
# replace that part with the new locale
|
15
|
+
extlist[loc_idx] = locale.to_s
|
16
|
+
new_extension = extlist.join(".")
|
17
|
+
return strip_extensions.sub_ext("." + new_extension)
|
18
|
+
else
|
19
|
+
# add locale extension
|
19
20
|
ext = path.extname
|
20
|
-
|
21
|
-
|
21
|
+
# TODO: need configurable order for locale & ext here?
|
22
|
+
#path.sub_ext("#{ext}." + locale.to_s)
|
23
|
+
path.sub_ext("." + locale.to_s + ext)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# (see Translatomatic::ResourceFile::Base#save)
|
28
|
+
def save(target = path, options = {})
|
29
|
+
if @doc
|
30
|
+
add_created_by unless options[:no_created_by]
|
31
|
+
target.write(@doc.to_html)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
22
36
|
|
23
|
-
|
24
|
-
|
37
|
+
def text_nodes_xpath
|
38
|
+
'//*[not(self::code)]/text()'
|
25
39
|
end
|
26
40
|
|
27
|
-
|
28
|
-
|
29
|
-
target.write(@doc.to_html) if @doc
|
41
|
+
def add_created_by
|
42
|
+
@created_by ||= @doc.root.add_previous_sibling(comment(created_by))
|
30
43
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
44
|
+
|
45
|
+
def read_doc(path)
|
46
|
+
Nokogiri::HTML(path.open) do |config|
|
47
|
+
config.noblanks
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'kramdown'
|
2
|
+
require 'reverse_markdown'
|
3
|
+
|
4
|
+
module Translatomatic::ResourceFile
|
5
|
+
class Markdown < HTML
|
6
|
+
|
7
|
+
# (see Translatomatic::ResourceFile::Base.extensions)
|
8
|
+
def self.extensions
|
9
|
+
%w{md}
|
10
|
+
end
|
11
|
+
|
12
|
+
# (see Translatomatic::ResourceFile::Base#save)
|
13
|
+
def save(target = path, options = {})
|
14
|
+
if @doc
|
15
|
+
begin
|
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
|
+
rescue Exception => e
|
22
|
+
puts "error: #{e.message}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def add_created_by
|
30
|
+
@created_by ||= begin
|
31
|
+
body = @doc.at('body')
|
32
|
+
body.add_child("<p><i>#{created_by}</i></p>")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def read(path)
|
37
|
+
begin
|
38
|
+
# read markdown and convert to html
|
39
|
+
markdown = path.read
|
40
|
+
html = Kramdown::Document.new(markdown).to_html
|
41
|
+
# parse html with nokogiri
|
42
|
+
@doc = Nokogiri::HTML(html) do |config|
|
43
|
+
config.noblanks
|
44
|
+
end
|
45
|
+
init_nodemap(@doc)
|
46
|
+
rescue Exception => e
|
47
|
+
log.error(e.message)
|
48
|
+
@valid = false
|
49
|
+
{}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end # class
|
54
|
+
end # module
|
@@ -1,29 +1,30 @@
|
|
1
|
-
module Translatomatic::ResourceFile
|
2
|
-
class Plist < XML
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
1
|
+
module Translatomatic::ResourceFile
|
2
|
+
class Plist < XML
|
3
|
+
|
4
|
+
# (see Translatomatic::ResourceFile::Base.extensions)
|
5
|
+
def self.extensions
|
6
|
+
%w{plist}
|
7
|
+
end
|
8
|
+
|
9
|
+
# (see Translatomatic::ResourceFile::Base#locale_path)
|
10
|
+
# @note localization files in XCode use the following file name
|
11
|
+
# convention: Project/locale.lproj/filename
|
12
|
+
# @todo refactor this and xcode_strings.rb to use the same code
|
13
|
+
def locale_path(locale)
|
14
|
+
if path.to_s.match(/\/([-\w]+).lproj\/.+.plist$/)
|
15
|
+
# xcode style
|
16
|
+
filename = path.basename
|
17
|
+
path.parent.parent + (locale.to_s + ".lproj") + filename
|
18
|
+
else
|
19
|
+
super(locale)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def text_nodes_xpath
|
26
|
+
'//*[not(self::key)]/text()'
|
27
|
+
end
|
28
|
+
|
29
|
+
end # class
|
30
|
+
end # module
|
@@ -1,60 +1,72 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Translatomatic::ResourceFile
|
4
|
+
class Properties < Base
|
5
|
+
|
6
|
+
# (see Translatomatic::ResourceFile::Base.extensions)
|
7
|
+
def self.extensions
|
8
|
+
%w{properties}
|
9
|
+
end
|
10
|
+
|
11
|
+
# (see Translatomatic::ResourceFile::Base#initialize)
|
12
|
+
def initialize(path, locale = nil)
|
13
|
+
super(path, locale)
|
14
|
+
@valid = true
|
15
|
+
@properties = @path.exist? ? read(@path) : {}
|
16
|
+
end
|
17
|
+
|
18
|
+
# (see Translatomatic::ResourceFile::Base#save)
|
19
|
+
def save(target = path, options = {})
|
20
|
+
out = ""
|
21
|
+
out += add_created_by unless options[:no_created_by]
|
22
|
+
properties.each do |key, value|
|
23
|
+
# TODO: maintain original line ending format?
|
24
|
+
value = value.gsub("\n", "\\n") # convert newlines to \n
|
25
|
+
out += "#{key} = #{value}\n"
|
26
|
+
end
|
27
|
+
# escape unicode characters
|
28
|
+
out = Translatomatic::EscapedUnicode.escape(out)
|
29
|
+
target.write(out)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def add_created_by
|
35
|
+
comment(created_by)
|
36
|
+
end
|
37
|
+
|
38
|
+
def comment(text)
|
39
|
+
"# #{text}\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
# parse key = value property file
|
43
|
+
def read(path)
|
44
|
+
contents = path.read
|
45
|
+
# convert escaped unicode characters into unicode
|
46
|
+
contents = Translatomatic::EscapedUnicode.unescape(contents)
|
47
|
+
result = {}
|
48
|
+
contents.gsub!(/\\\s*\n\s*/m, '') # put multi line strings on one line
|
49
|
+
lines = contents.split("\n")
|
50
|
+
|
51
|
+
lines.each do |line|
|
52
|
+
line.strip!
|
53
|
+
next if line.length == 0
|
54
|
+
equal_idx = line.index("=")
|
55
|
+
|
56
|
+
if line[0] == ?! || line[0] == ?#
|
57
|
+
# comment
|
58
|
+
# TODO: translate comments or keep originals?
|
59
|
+
next
|
60
|
+
elsif equal_idx.nil?
|
61
|
+
@valid = false
|
62
|
+
return {}
|
63
|
+
end
|
64
|
+
name, value = line.split(/\s*=\s*/, 2)
|
65
|
+
value = value.gsub("\\n", "\n") # convert \n to newlines
|
66
|
+
result[name] = value
|
67
|
+
end
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|