-
Notifications
You must be signed in to change notification settings - Fork 22
/
import-csv.js
234 lines (189 loc) · 8.33 KB
/
import-csv.js
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
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
var _ = require('lodash');
var stripJsonComments = require('strip-json-comments');
var fs = require('fs');
var Q = require('q');
var csv = require('csv');
var _debug = require('debug');
_debug.enable('import-csv:errors');
String.prototype.sentenceCase = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
};
var debug = function(prefix) {
var d = _debug(prefix);
return function() {
var args = Array.prototype.slice.call(arguments);
return d.apply(void 0, [args.map(function() { return '%o'; }).join(" ")].concat(args));
};
};
// the BASE_LANGUAGE is used to determine which keys should be present
var BASE_LANGUAGE = "english";
var BLACKLIST = ['package.json'];
var DIR = __dirname + "/translations";
var MOBILE_DIR = DIR + "/mobile";
var SENTENCE_CASE = false;
// store all translations in here before writing to .json files
var translations = {};
// read existing translation files
fs.readdirSync(DIR).forEach(function(filename) {
if (filename.match(/\.json$/) && BLACKLIST.indexOf(filename) === -1) {
var language = filename.replace(/\.json$/, "");
var raw = fs.readFileSync(DIR + "/" + filename);
translations[language] = JSON.parse(stripJsonComments(raw.toString('utf8')));
}
});
// read existing translation files for mobile
fs.readdirSync(MOBILE_DIR).forEach(function(filename) {
if (filename.match(/\.json$/) && BLACKLIST.indexOf(filename) === -1) {
var language = filename.replace(/\.json$/, "");
var raw = fs.readFileSync(MOBILE_DIR + "/" + filename);
translations[language + "_mobile"] = JSON.parse(stripJsonComments(raw.toString('utf8')));
}
});
var languages = Object.keys(translations).sort();
// bring BASE_LANGUAGE to front
languages.splice(languages.indexOf(BASE_LANGUAGE), 1);
languages.unshift(BASE_LANGUAGE);
// put _mobile behind it's parent
_.forEach(languages, function(language, idx) {
if (language.match(/_mobile$/)) {
var _language = language.substr(0, language.length -7);
languages.splice(languages.indexOf(language), 1);
languages.splice(languages.indexOf(_language)+1, 0, language);
}
});
// determine keys based on BASE_LANGUAGE
var keys = Object.keys(translations[BASE_LANGUAGE]).filter(function(key) { return ['NULL'].indexOf(key) === -1; });
// read and parse the CSV file
var raw = fs.readFileSync(__dirname + "/translations.csv").toString('utf8');
csv.parse(raw, {delimiter: ";", columns: true}, function(err, data) {
if (err) throw err;
// process rows
data.forEach(function(row) {
// check each language
languages.forEach(function(language) {
// check if this row has a translation for this language
if (row[language]) {
// if it contains newlines we split it on
if (row[language].match(/\n/)) {
row[language] = row[language].replace(/\r\n/, '\n'); // windows to unix newlines
row[language] = row[language].split(/\n/);
}
if (SENTENCE_CASE) {
if (_.isArray(row[language])) {
row[language] = row[language].map(function(line) {
return line.sentenceCase();
});
} else {
row[language] = row[language].sentenceCase();
}
}
// only store translations of which the keys are known (in BASE_LANGUAGE)
if (keys.indexOf(row.KEY) !== -1) {
translations[language][row.KEY] = row[language];
} else {
debug('import-csv:errors')("key [" + row.KEY + "] not in BASE_LANGUAGE");
}
}
});
});
// process comments and blank lines from BASE_LANGUAGE so we can apply them to the other files as well
var commentLines = {};
var blankLines = {};
var comments = {};
[true, false].forEach(function(isMobile) {
var rawOriginal = fs.readFileSync((isMobile ? MOBILE_DIR : DIR) + "/" + BASE_LANGUAGE + ".json").toString('utf8');
var rowsOriginal = rawOriginal.split("\n");
var _commentLines = commentLines[isMobile] = {};
var _blankLines = blankLines[isMobile] = {};
var _comments = comments[isMobile] = {};
var skip = 0;
// process the original file for blank lines and comments so we can apply them back into the new JSON file
_.forEach(rowsOriginal, function(row, idx) {
if (skip > 0) {
skip--;
return;
}
var blankLine = row.match(/^\s*$/);
var commentLine = row.match(/^( *?)\/\/(.+)/);
var comment = row.match(/".+?[^\\]",(( *?)\/\/(.+))$/);
var beforeKey;
debug('import-csv:parse-original')("-----------");
debug('import-csv:parse-original')(row, !!blankLine, !!commentLine, !!comment);
if (blankLine) {
beforeKey = null;
_.any(rowsOriginal.slice(idx + 1), function(nextRow, nextIdx) {
var key = nextRow.match(/^( +?)"(.+?)"( *?):/);
debug('import-csv:parse-original')(nextRow, !!commentLine, !!key);
if (key) {
beforeKey = key[2];
return true;
}
});
if (beforeKey) {
_blankLines[beforeKey] = true;
}
} else if (commentLine) {
var _commentLine = [commentLine[0]];
beforeKey = null;
_.any(rowsOriginal.slice(idx + 1), function(nextRow, nextIdx) {
var commentLine = nextRow.match(/^( *)\/\/(.+)/);
var key = nextRow.match(/^( +?)"(.+?)"( *?):/);
debug('import-csv:parse-original')(nextRow, !!commentLine, !!key);
if (key) {
beforeKey = key[2];
return true;
} else if (commentLine) {
_commentLine.push(commentLine[0]);
skip++;
} else {
debug('import-csv:parse-original')('WHAT IS THIS?', nextRow);
}
});
debug('import-csv:parse-original')(_commentLine);
if (beforeKey) {
_commentLines[beforeKey] = _commentLine;
}
} else if (comment) {
var key = row.match(/^( +?)"(.+?)"( *?):/);
debug('import-csv:parse-original')(!!comment && comment[1], !!key && key[2]);
if (key) {
_comments[key[2]] = comment[1];
}
}
});
});
// store each language
languages.forEach(function(language) {
var isMobile = !!language.match(/_mobile$/);
var filename = isMobile ? language.substr(0, language.length -7) : language;
var _commentLines = commentLines[isMobile];
var _blankLines = blankLines[isMobile];
var _comments = comments[isMobile];
// create new JSON file
var preJson = {};
_.forEach(keys, function(key) {
if (typeof translations[language][key] !== "undefined") {
preJson[key] = translations[language][key];
}
});
var json = JSON.stringify(preJson, null, 4).split("\n");
// apply comments and blank lines to new JSON file
json.slice().forEach(function(line) {
var key = line.match(/^( +?)"(.+?)"( *?):/);
debug('import-csv:output')(line, !!key && key[2], !!key && typeof _commentLines[key[2]] !== "undefined");
if (!!key && _blankLines[key[2]]) {
json.splice(json.indexOf(line), 0, "");
}
if (!!key && _commentLines[key[2]]) {
_commentLines[key[2]].reverse().forEach(function(comment) {
json.splice(json.indexOf(line), 0, comment);
});
}
if (!!key && _comments[key[2]]) {
json.splice(json.indexOf(line), 1, line + _comments[key[2]]);
}
});
// save
fs.writeFileSync((isMobile ? MOBILE_DIR : DIR) + "/" + filename + ".json", json.join("\n") + "\n");
});
});