babelish_rnc 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.babelish.sample +35 -0
- data/.gitignore +34 -0
- data/.hound.yml +4 -0
- data/.travis.yml +15 -0
- data/CONTRIBUTING.md +12 -0
- data/Dockerfile +6 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +20 -0
- data/README.md +73 -0
- data/Rakefile +17 -0
- data/babelish.gemspec +41 -0
- data/babelish_rnc.gemspec +42 -0
- data/bin/babelish_rnc +6 -0
- data/lib/babelish_rnc.rb +31 -0
- data/lib/babelish_rnc/android2csv.rb +28 -0
- data/lib/babelish_rnc/base2csv.rb +103 -0
- data/lib/babelish_rnc/commandline.rb +188 -0
- data/lib/babelish_rnc/csv2android.rb +53 -0
- data/lib/babelish_rnc/csv2base.rb +189 -0
- data/lib/babelish_rnc/csv2json.rb +21 -0
- data/lib/babelish_rnc/csv2php.rb +25 -0
- data/lib/babelish_rnc/csv2strings.rb +34 -0
- data/lib/babelish_rnc/google_doc.rb +55 -0
- data/lib/babelish_rnc/json2csv.rb +20 -0
- data/lib/babelish_rnc/language.rb +30 -0
- data/lib/babelish_rnc/php2csv.rb +30 -0
- data/lib/babelish_rnc/strings2csv.rb +61 -0
- data/lib/babelish_rnc/version.rb +3 -0
- data/lib/babelish_rnc/xcode_macros.rb +49 -0
- data/test/babelish_rnc/commands/test_command_android2csv.rb +60 -0
- data/test/babelish_rnc/commands/test_command_csv2android.rb +35 -0
- data/test/babelish_rnc/commands/test_command_csv2strings.rb +139 -0
- data/test/babelish_rnc/commands/test_command_strings2csv.rb +110 -0
- data/test/babelish_rnc/test_android2csv.rb +53 -0
- data/test/babelish_rnc/test_base2csv.rb +43 -0
- data/test/babelish_rnc/test_bins.rb +32 -0
- data/test/babelish_rnc/test_commandline.rb +127 -0
- data/test/babelish_rnc/test_csv2android.rb +72 -0
- data/test/babelish_rnc/test_csv2base.rb +44 -0
- data/test/babelish_rnc/test_csv2json.rb +27 -0
- data/test/babelish_rnc/test_csv2php.rb +27 -0
- data/test/babelish_rnc/test_csv2strings.rb +154 -0
- data/test/babelish_rnc/test_json2csv.rb +34 -0
- data/test/babelish_rnc/test_php2csv.rb +73 -0
- data/test/babelish_rnc/test_strings2csv.rb +147 -0
- data/test/babelish_rnc/test_xcode_macros.rb +112 -0
- data/test/data/android-en.xml +9 -0
- data/test/data/android-fr.xml +9 -0
- data/test/data/android.xml +9 -0
- data/test/data/android_special_chars.csv +8 -0
- data/test/data/android_special_chars.xml +12 -0
- data/test/data/android_special_chars_test_result.xml +10 -0
- data/test/data/genstrings.strings +0 -0
- data/test/data/json.json +6 -0
- data/test/data/php_lang.php +8 -0
- data/test/data/test_comments.strings +2 -0
- data/test/data/test_data.csv +3 -0
- data/test/data/test_data.strings +2 -0
- data/test/data/test_data_fr_with_comments.strings +6 -0
- data/test/data/test_data_fr_with_comments.xml +9 -0
- data/test/data/test_data_multiple_langs.csv +3 -0
- data/test/data/test_data_with_comments.csv +3 -0
- data/test/data/test_data_with_percent.csv +3 -0
- data/test/data/test_data_with_percent_space.csv +4 -0
- data/test/data/test_data_with_semicolon.csv +3 -0
- data/test/data/test_data_with_spaces.csv +3 -0
- data/test/data/test_en.strings +2 -0
- data/test/data/test_fr.strings +2 -0
- data/test/data/test_space.strings +10 -0
- data/test/data/test_utf16.strings +0 -0
- data/test/data/test_with_nil.csv +3 -0
- data/test/data/test_with_nil.strings +4 -0
- data/test/data/xcode_empty.strings +7 -0
- data/test/test_helper.rb +17 -0
- metadata +311 -0
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'yaml'
|
3
|
+
class Commandline < Thor
|
4
|
+
include Thor::Actions
|
5
|
+
class_option :verbose, :type => :boolean
|
6
|
+
class_option :config, :type => :string, :aliases => "-c", :desc => "Read configuration from given file", :default => ".babelish"
|
7
|
+
map "-v" => :version
|
8
|
+
|
9
|
+
CSVCLASSES = [
|
10
|
+
{:name => "CSV2Strings", :ext => ".strings"},
|
11
|
+
{:name => "CSV2Android", :ext => ".xml"},
|
12
|
+
{:name => "CSV2JSON", :ext => ".json"},
|
13
|
+
{:name => "CSV2Php", :ext => ".php"},
|
14
|
+
]
|
15
|
+
|
16
|
+
CSVCLASSES.each do |klass|
|
17
|
+
desc "#{klass[:name].downcase}", "Convert CSV file to #{klass[:ext]}"
|
18
|
+
method_option :filename, :type => :string, :aliases => "-i", :desc => "CSV file to convert from or name of file in Google Drive"
|
19
|
+
method_option :langs, :type => :hash, :aliases => "-L", :desc => "Languages to convert. i.e. English:en"
|
20
|
+
|
21
|
+
# optional options
|
22
|
+
method_option :excluded_states, :type => :array, :aliases => "-x", :desc => "Exclude rows with given state"
|
23
|
+
method_option :state_column, :type => :numeric, :aliases => "-s", :desc => "Position of column for state if any"
|
24
|
+
method_option :keys_column, :type => :numeric, :aliases => "-k", :desc => "Position of column for keys"
|
25
|
+
method_option :comments_column, :type => :numeric, :aliases => "-C", :desc => "Position of column for comments if any"
|
26
|
+
method_option :default_lang, :type => :string, :aliases => "-l", :desc => "Default language to use for empty values if any"
|
27
|
+
method_option :csv_separator, :type => :string, :aliases => "-S", :desc => "CSV column separator character, uses ',' by default"
|
28
|
+
method_option :output_dir, :type => :string, :aliases => "-d", :desc => "Path of output files"
|
29
|
+
method_option :output_basenames, :type => :array, :aliases => "-o", :desc => "Basename of output files"
|
30
|
+
method_option :stripping, :type => :boolean, :aliases => "-N", :default => false, :desc => "Strips values of spreadsheet"
|
31
|
+
method_option :ignore_lang_path, :type => :boolean, :aliases => "-I", :lazy_default => false, :desc => "Ignore the path component of langs"
|
32
|
+
method_option :fetch, :type => :boolean, :desc => "Download file from Google Drive"
|
33
|
+
method_option :sheet, :type => :numeric, :desc => "Index of worksheet to download. First index is 0"
|
34
|
+
if klass[:name] == "CSV2Strings"
|
35
|
+
method_option :macros_filename, :type => :boolean, :aliases => "-m", :lazy_default => false, :desc => "Filename containing defines of localized keys"
|
36
|
+
end
|
37
|
+
define_method("#{klass[:name].downcase}") do
|
38
|
+
csv2base(klass[:name])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
BASECLASSES = [
|
43
|
+
{:name => "Strings2CSV", :ext => ".strings"},
|
44
|
+
{:name => "Android2CSV", :ext => ".xml"},
|
45
|
+
{:name => "JSON2CSV", :ext => ".json"},
|
46
|
+
{:name => "Php2CSV", :ext => ".php"},
|
47
|
+
]
|
48
|
+
|
49
|
+
BASECLASSES.each do |klass|
|
50
|
+
desc "#{klass[:name].downcase}", "Convert #{klass[:ext]} files to CSV file"
|
51
|
+
method_option :filenames, :type => :array, :aliases => "-i", :desc => "location of strings files (FILENAMES)"
|
52
|
+
|
53
|
+
# optional options
|
54
|
+
method_option :csv_filename, :type => :string, :aliases => "-o", :desc => "location of output file"
|
55
|
+
method_option :headers, :type => :array, :aliases => "-h", :desc => "override headers of columns, default is name of input files and 'Variables' for reference"
|
56
|
+
method_option :dryrun, :type => :boolean, :aliases => "-n", :desc => "prints out content of hash without writing file"
|
57
|
+
define_method("#{klass[:name].downcase}") do
|
58
|
+
begin
|
59
|
+
base2csv(klass[:name])
|
60
|
+
rescue Errno::ENOENT => e
|
61
|
+
warn e.message
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
desc "csv_download", "Download Google Spreadsheet containing translations"
|
67
|
+
method_option :gd_filename, :type => :string, :desc => "File to download from Google Drive."
|
68
|
+
method_option :sheet, :type => :numeric, :desc => "Index of worksheet to download. First index is 0."
|
69
|
+
method_option :all, :type => :boolean, :lazy_default => true, :desc => "Download all worksheets to individual csv files."
|
70
|
+
method_option :output_filename, :type => :string, :desc => "Filepath of downloaded file."
|
71
|
+
def csv_download
|
72
|
+
all = options[:sheet] ? false : options[:all]
|
73
|
+
filename = options['gd_filename']
|
74
|
+
raise ArgumentError.new("csv_download command : missing file to download") unless filename
|
75
|
+
if all
|
76
|
+
download(filename)
|
77
|
+
else
|
78
|
+
download(filename, options['output_filename'], options['sheet'])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
desc "open FILE", "Open local csv file in default editor or Google Spreadsheet containing translations in default browser"
|
83
|
+
def open(file = "translations.csv")
|
84
|
+
filename = file || options["filename"]
|
85
|
+
if File.exist?(filename)
|
86
|
+
say "Opening local file '#{filename}'"
|
87
|
+
system "open \"#{filename}\""
|
88
|
+
else
|
89
|
+
say "Opening Google Drive file '#{filename}'"
|
90
|
+
gd = BabelishRnc::GoogleDoc.new
|
91
|
+
gd.open filename.to_s
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
desc "init", "Create a configuration file from template"
|
96
|
+
def init
|
97
|
+
if File.exist?(".babelish")
|
98
|
+
say "Config file '.babelish' already exists."
|
99
|
+
else
|
100
|
+
say "Creating new config file '.babelish'."
|
101
|
+
config_file = File.expand_path("../../../.babelish.sample", __FILE__)
|
102
|
+
if File.exist?(config_file)
|
103
|
+
system "cp #{config_file} .babelish"
|
104
|
+
else
|
105
|
+
say "Template '#{config_file}' not found."
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
desc "version", "Display current version"
|
112
|
+
def version
|
113
|
+
require "babelish_rnc/version"
|
114
|
+
say "babelish_rnc #{BabelishRnc::VERSION}"
|
115
|
+
end
|
116
|
+
|
117
|
+
no_tasks do
|
118
|
+
def download(filename, output_filename = nil, worksheet_index = nil)
|
119
|
+
gd = BabelishRnc::GoogleDoc.new
|
120
|
+
if output_filename || worksheet_index
|
121
|
+
file_path = gd.download_spreadsheet filename.to_s, output_filename, worksheet_index
|
122
|
+
files = [file_path].compact
|
123
|
+
else
|
124
|
+
files = gd.download filename.to_s
|
125
|
+
file_path = files.join("\n") unless files.empty?
|
126
|
+
end
|
127
|
+
|
128
|
+
if file_path
|
129
|
+
say "File '#{filename}' downloaded to :\n#{file_path.to_s}"
|
130
|
+
else
|
131
|
+
say "Could not download the requested file: #{filename}"
|
132
|
+
end
|
133
|
+
files
|
134
|
+
end
|
135
|
+
|
136
|
+
def csv2base(classname)
|
137
|
+
args = options.dup
|
138
|
+
if options[:fetch]
|
139
|
+
say "Fetching csv file #{options[:filename]} from Google Drive"
|
140
|
+
files = download(options[:filename], nil, options[:sheet])
|
141
|
+
abort if files.empty? # no file downloaded
|
142
|
+
args.delete(:fetch)
|
143
|
+
else
|
144
|
+
files = [options[:filename]]
|
145
|
+
end
|
146
|
+
args.delete(:langs)
|
147
|
+
args.delete(:filename)
|
148
|
+
|
149
|
+
xcode_macros = BabelishRnc::XcodeMacros.new if options[:macros_filename]
|
150
|
+
files.each_with_index do |filename, index|
|
151
|
+
if options[:output_basenames]
|
152
|
+
args[:output_basename] = options[:output_basenames][index]
|
153
|
+
end
|
154
|
+
|
155
|
+
class_object = eval "BabelishRnc::#{classname}"
|
156
|
+
args = Thor::CoreExt::HashWithIndifferentAccess.new(args)
|
157
|
+
converter = class_object.new(filename, options[:langs], args)
|
158
|
+
say converter.convert
|
159
|
+
xcode_macros.process(converter.table, converter.keys, converter.comments) if options[:macros_filename]
|
160
|
+
end
|
161
|
+
if options[:macros_filename]
|
162
|
+
say "generating macros"
|
163
|
+
xcode_macros.write_content(options[:macros_filename])
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def base2csv(classname)
|
168
|
+
class_object = eval "BabelishRnc::#{classname}"
|
169
|
+
converter = class_object.new(options)
|
170
|
+
|
171
|
+
debug_values = converter.convert(!options[:dryrun])
|
172
|
+
say debug_values.inspect if options[:dryrun]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def self.exit_on_failure?
|
177
|
+
true
|
178
|
+
end
|
179
|
+
|
180
|
+
private
|
181
|
+
|
182
|
+
def options
|
183
|
+
original_options = super
|
184
|
+
return original_options unless File.exist?(original_options["config"])
|
185
|
+
defaults = ::YAML.load_file(original_options["config"]) || {}
|
186
|
+
Thor::CoreExt::HashWithIndifferentAccess.new(defaults.merge(original_options))
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module BabelishRnc
|
2
|
+
class CSV2Android < Csv2Base
|
3
|
+
attr_accessor :file_path
|
4
|
+
|
5
|
+
def initialize(filename, langs, args = {})
|
6
|
+
super(filename, langs, args)
|
7
|
+
|
8
|
+
@file_path = args[:output_dir].to_s
|
9
|
+
@output_basename = args[:output_basename].to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def language_filepaths(language)
|
13
|
+
require 'pathname'
|
14
|
+
output_name = "strings.xml"
|
15
|
+
output_name = "#{@output_basename}.xml" unless @output_basename.empty?
|
16
|
+
filepath = Pathname.new(@file_path) + "values-#{language.code}" + output_name
|
17
|
+
return filepath ? [filepath] : []
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_value(row_value, default_value)
|
21
|
+
value = super(row_value, default_value)
|
22
|
+
# if the value begins and ends with a quote we must leave them unescapted
|
23
|
+
if value.size > 4 && value[0, 2] == "\\\"" && value[value.size - 2, value.size] == "\\\""
|
24
|
+
value[0, 2] = "\""
|
25
|
+
value[value.size - 2, value.size] = "\""
|
26
|
+
end
|
27
|
+
value.to_utf8
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_row_format(row_key, row_value, comment = nil, indentation = 0)
|
31
|
+
entry = comment.to_s.empty? ? "" : "\n\t<!-- #{comment} -->\n"
|
32
|
+
entry + "\t<string name=\"#{row_key}\">#{row_value}</string>\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
def hash_to_output(content = {})
|
36
|
+
output = ''
|
37
|
+
if content && content.size > 0
|
38
|
+
output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
39
|
+
output += "<resources>\n"
|
40
|
+
content.each do |key, value|
|
41
|
+
comment = @comments[key]
|
42
|
+
output += get_row_format(key, value, comment)
|
43
|
+
end
|
44
|
+
output += "</resources>\n"
|
45
|
+
end
|
46
|
+
return output
|
47
|
+
end
|
48
|
+
|
49
|
+
def extension
|
50
|
+
"xml"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
module BabelishRnc
|
3
|
+
class Csv2Base
|
4
|
+
attr_accessor :output_dir, :output_basename
|
5
|
+
attr_accessor :ignore_lang_path
|
6
|
+
attr_accessor :langs
|
7
|
+
attr_accessor :csv_filename
|
8
|
+
attr_accessor :default_lang
|
9
|
+
attr_accessor :csv_separator
|
10
|
+
attr_accessor :excluded_states, :state_column, :keys_column, :comments_column
|
11
|
+
attr_accessor :languages
|
12
|
+
|
13
|
+
def initialize(filename, langs, args = {})
|
14
|
+
default_args = {
|
15
|
+
:excluded_states => [],
|
16
|
+
:state_column => nil,
|
17
|
+
:keys_column => 0,
|
18
|
+
:csv_separator => ","
|
19
|
+
}
|
20
|
+
|
21
|
+
args = default_args.merge!(args)
|
22
|
+
args = Thor::CoreExt::HashWithIndifferentAccess.new(args)
|
23
|
+
@langs = langs
|
24
|
+
|
25
|
+
# check input types
|
26
|
+
raise ArgumentError.new("wrong value of filename: #{filename.inspect}") unless filename.is_a?(String)
|
27
|
+
if !@langs.is_a?(Hash) || @langs.size == 0
|
28
|
+
raise ArgumentError.new("wrong format or/and langs parameter: #{@langs.inspect}")
|
29
|
+
end
|
30
|
+
|
31
|
+
@output_basename = args[:output_basename]
|
32
|
+
@output_dir = args[:output_dir].to_s
|
33
|
+
@csv_filename = filename
|
34
|
+
@excluded_states = args[:excluded_states]
|
35
|
+
@state_column = args[:state_column]
|
36
|
+
@keys_column = args[:keys_column]
|
37
|
+
@comments_column = args[:comments_column]
|
38
|
+
@default_lang = args[:default_lang]
|
39
|
+
@csv_separator = args[:csv_separator]
|
40
|
+
@ignore_lang_path = args[:ignore_lang_path]
|
41
|
+
@stripping = args[:stripping]
|
42
|
+
@languages = []
|
43
|
+
@comments = {}
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_file_from_path(file_path)
|
47
|
+
path = File.dirname(file_path)
|
48
|
+
FileUtils.mkdir_p path
|
49
|
+
return File.new(file_path, "w")
|
50
|
+
end
|
51
|
+
|
52
|
+
def keys
|
53
|
+
@languages.each do |lang|
|
54
|
+
next unless lang
|
55
|
+
return lang.content.keys unless lang.content.keys.empty?
|
56
|
+
end
|
57
|
+
return []
|
58
|
+
end
|
59
|
+
|
60
|
+
def table
|
61
|
+
output_basename
|
62
|
+
end
|
63
|
+
|
64
|
+
def comments
|
65
|
+
@comments
|
66
|
+
end
|
67
|
+
|
68
|
+
def language_filepaths(language)
|
69
|
+
#implement in subclass
|
70
|
+
[]
|
71
|
+
end
|
72
|
+
|
73
|
+
def extension
|
74
|
+
#implement in subclass
|
75
|
+
""
|
76
|
+
end
|
77
|
+
|
78
|
+
def default_filepath
|
79
|
+
Pathname.new(@output_dir) + "#{output_basename}.#{extension}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def process_value(row_value, default_value)
|
83
|
+
value = row_value.nil? ? default_value : row_value
|
84
|
+
value = "" if value.nil?
|
85
|
+
value.gsub!(/\\*\"/, "\\\"") # escape double quotes
|
86
|
+
value.gsub!(/\n/, "\\n") # replace new lines with \n, dont strip
|
87
|
+
value.strip! if @stripping
|
88
|
+
return value.to_utf8
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_row_format(row_key, row_value, comment = nil, indentation = 0)
|
92
|
+
# ignoring comment by default
|
93
|
+
"\"#{row_key}\"" + " " * indentation + " = \"#{row_value}\""
|
94
|
+
end
|
95
|
+
|
96
|
+
# Convert csv file to multiple Localizable.strings files for each column
|
97
|
+
def convert(name = @csv_filename)
|
98
|
+
rowIndex = 0
|
99
|
+
excludedCols = []
|
100
|
+
defaultCol = 0
|
101
|
+
|
102
|
+
CSV.foreach(name, :quote_char => '"', :col_sep => @csv_separator, :row_sep => :auto) do |row|
|
103
|
+
|
104
|
+
if rowIndex == 0
|
105
|
+
#check there's at least two columns
|
106
|
+
return unless row.count > 1
|
107
|
+
else
|
108
|
+
#skip empty lines (or sections)
|
109
|
+
next if row == nil or row[@keys_column].nil?
|
110
|
+
end
|
111
|
+
|
112
|
+
# go through columns
|
113
|
+
row.size.times do |i|
|
114
|
+
next if excludedCols.include? i
|
115
|
+
|
116
|
+
#header
|
117
|
+
if rowIndex == 0
|
118
|
+
# defaultCol can be the keyValue
|
119
|
+
defaultCol = i if self.default_lang == row[i]
|
120
|
+
# ignore all headers not listed in langs to create files
|
121
|
+
(excludedCols << i and next) unless @langs.has_key?(row[i])
|
122
|
+
|
123
|
+
language = Language.new(row[i])
|
124
|
+
if @langs[row[i]].is_a?(Array)
|
125
|
+
@langs[row[i]].each do |id|
|
126
|
+
language.add_language_id(id.to_s)
|
127
|
+
end
|
128
|
+
else
|
129
|
+
language.add_language_id(@langs[row[i]].to_s)
|
130
|
+
end
|
131
|
+
@languages[i] = language
|
132
|
+
elsif !@state_column || (row[@state_column].nil? || row[@state_column] == '' || !@excluded_states.include?(row[@state_column]))
|
133
|
+
key = row[@keys_column]
|
134
|
+
comment = @comments_column ? row[@comments_column] : nil
|
135
|
+
key.strip! if @stripping
|
136
|
+
default_value = self.default_lang ? row[defaultCol] : nil
|
137
|
+
value = self.process_value(row[i], default_value)
|
138
|
+
@comments[key] = comment
|
139
|
+
@languages[i].add_content_pair(key, value)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
rowIndex += 1
|
144
|
+
end
|
145
|
+
|
146
|
+
write_content
|
147
|
+
end
|
148
|
+
|
149
|
+
def write_content
|
150
|
+
info = "List of created files:\n"
|
151
|
+
count = 0
|
152
|
+
@languages.each do |language|
|
153
|
+
next if language.nil?
|
154
|
+
|
155
|
+
files = []
|
156
|
+
if @ignore_lang_path
|
157
|
+
files << create_file_from_path(default_filepath)
|
158
|
+
else
|
159
|
+
language_filepaths(language).each do |filename|
|
160
|
+
files << create_file_from_path(filename)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
files.each do |file|
|
164
|
+
file.write hash_to_output(language.content)
|
165
|
+
info += "- #{File.absolute_path(file)}\n"
|
166
|
+
count += 1
|
167
|
+
|
168
|
+
file.close
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
info = "Created #{count} files.\n" + info
|
173
|
+
return info
|
174
|
+
end
|
175
|
+
|
176
|
+
def hash_to_output(content = {})
|
177
|
+
output = ''
|
178
|
+
indentation = content.map(&:first).max { |a, b| a.length <=> b.length }.length
|
179
|
+
if content && content.size > 0
|
180
|
+
content.each do |key, value|
|
181
|
+
comment = @comments[key]
|
182
|
+
defaultlang = @languages[1].content[key]
|
183
|
+
output += get_row_format(key, value, comment, indentation - key.length, defaultlang)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
return output
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module BabelishRnc
|
2
|
+
require 'json'
|
3
|
+
class CSV2JSON < Csv2Base
|
4
|
+
|
5
|
+
def language_filepaths(language)
|
6
|
+
require 'pathname'
|
7
|
+
filename = @output_basename || language.code
|
8
|
+
filepath = Pathname.new("#{@output_dir}#{filename}.json")
|
9
|
+
|
10
|
+
return filepath ? [filepath] : []
|
11
|
+
end
|
12
|
+
|
13
|
+
def hash_to_output(content = {})
|
14
|
+
return content.to_json
|
15
|
+
end
|
16
|
+
|
17
|
+
def extension
|
18
|
+
"js"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|