aboutsummaryrefslogtreecommitdiffstats
path: root/i18n/src
diff options
context:
space:
mode:
Diffstat (limited to 'i18n/src')
-rw-r--r--i18n/src/closureSlurper.js106
-rw-r--r--i18n/src/converter.js60
-rw-r--r--i18n/src/parser.js64
-rw-r--r--i18n/src/util.js7
4 files changed, 237 insertions, 0 deletions
diff --git a/i18n/src/closureSlurper.js b/i18n/src/closureSlurper.js
new file mode 100644
index 00000000..32ef022c
--- /dev/null
+++ b/i18n/src/closureSlurper.js
@@ -0,0 +1,106 @@
+#!/usr/bin/env node
+'use strict';
+
+require.paths.push(__dirname);
+var Q = require('qq'),
+ qfs = require('q-fs'),
+ converter = require('converter.js'),
+ util = require('util.js'),
+ localeInfo = {},
+ localeIds = [],
+ currencySymbols,
+ goog = { provide: function() {},
+ require: function() {},
+ i18n: {currency: {}} };
+
+createFolder('../locale/').then(function() {
+ var promiseA = Q.defer(),
+ promiseB = Q.defer();
+
+ qfs.read(__dirname + '/../closure/currencySymbols.js', 'b').then(function(content) {
+ eval(content.toString());
+ currencySymbols = goog.i18n.currency.CurrencyInfo;
+ currencySymbols.__proto__ = goog.i18n.currency.CurrencyInfoTier2;
+
+ qfs.read(__dirname + '/../closure/numberSymbols.js', 'b').then(function(content) {
+ //eval script in the current context so that we get access to all the symbols
+ eval(content.toString());
+ for (propName in goog.i18n) {
+ var localeID = util.findLocaleId(propName, 'num');
+ if (localeID) {
+ if (!localeInfo[localeID]) {
+ localeInfo[localeID] = {};
+ localeIds.push(localeID);
+ }
+ var convertedData = converter.convertNumberData(goog.i18n[propName], currencySymbols);
+ localeInfo[localeID].NUMBER_FORMATS = convertedData;
+ }
+ }
+
+ promiseA.resolve();
+ });
+ });
+
+
+ qfs.read(__dirname + '/../closure/datetimeSymbols.js', 'b').then(function(content) {
+ eval(content.toString());
+ for (propName in goog.i18n) {
+ var localeID = util.findLocaleId(propName, 'datetime');
+ if (localeID) {
+ if (!localeInfo[localeID]) {
+ localeInfo[localeID] = {};
+ localeIds.push(localeID);
+ }
+ var convertedData = converter.convertDatetimeData(goog.i18n[propName]);
+ localeInfo[localeID].DATETIME_FORMATS = convertedData;
+ }
+ }
+
+ promiseB.resolve();
+ });
+
+ return Q.join(promiseA.promise, promiseB.promise, noop);
+}).then(function() {
+ localeIds.forEach(function(localeID) {
+ var fallBackID = localeID.match(/[A-Za-z]+/)[0],
+ localeObj = localeInfo[localeID],
+ fallBackObj = localeInfo[fallBackID];
+
+ // fallBack to language formats when country format is missing
+ // e.g. if NUMBER_FORMATS of en_xyz is not present, use the NUMBER_FORMATS of en instead
+ if (!localeObj.NUMBER_FORMATS) {
+ localeObj.NUMBER_FORMATS = fallBackObj.NUMBER_FORMATS;
+ }
+
+ if (!localeObj.DATETIME_FORMATS) {
+ localeObj.DATETIME_FORMATS = fallBackObj.DATETIME_FORMATS;
+ }
+
+ // e.g. from zh_CN to zh-CN, from en_US to en-US
+ var correctedLocaleId = localeID.replace(/_/g, '-').toLowerCase();
+ localeObj.id = correctedLocaleId;
+
+ var prefix = 'angular.service("$locale", function() {\nreturn ',
+ content = JSON.stringify(localeInfo[localeID]).replace(/\¤/g,'\\u00A4'),
+ suffix;
+
+ suffix = ';\n});';
+
+ var toWrite = prefix + content + suffix;
+
+ qfs.write(__dirname + '/../locale/' + 'angular-locale_' + correctedLocaleId + '.js', toWrite);
+ });
+ console.log('Generated ' + localeIds.length + ' locale files!');
+}).end();
+
+function noop() {};
+
+/**
+* Make a folder under current directory.
+* @param folder {string} name of the folder to be made
+*/
+function createFolder(folder) {
+ return qfs.isDirectory(__dirname + '/' + folder).then(function(isDir) {
+ if (!isDir) return qfs.makeDirectory(__dirname + '/' + folder);
+ });
+}
diff --git a/i18n/src/converter.js b/i18n/src/converter.js
new file mode 100644
index 00000000..586bdb95
--- /dev/null
+++ b/i18n/src/converter.js
@@ -0,0 +1,60 @@
+/**
+ * after obtaining data from closure files, use converter to massage the data into the formats
+ * we want
+ */
+exports.convertDatetimeData = convertDatetimeData;
+exports.convertNumberData = convertNumberData;
+
+
+require.paths.push(__dirname);
+
+
+var parsePattern = require('parser').parsePattern;
+
+
+function convertNumberData(dataObj, currencySymbols) {
+ var numberFormats = {},
+
+ numberFormats = {
+ DECIMAL_SEP: dataObj.DECIMAL_SEP,
+ GROUP_SEP: dataObj.GROUP_SEP,
+ PATTERNS: [parsePattern(dataObj.DECIMAL_PATTERN),
+ parsePattern(dataObj.CURRENCY_PATTERN)]
+ }
+
+ if (currencySymbols[dataObj.DEF_CURRENCY_CODE]) {
+ numberFormats.CURRENCY_SYM = currencySymbols[dataObj.DEF_CURRENCY_CODE][1];
+ } else {
+ if (dataObj.DEF_CURRENCY_CODE == 'MTL') {
+ numberFormats.CURRENCY_SYM = '₤'; //for some reason this is missing in closure
+ } else {
+ // if there is no corresponding currency symbol, just use currency code.
+ var code = numberFormats.CURRENCY_SYM = dataObj.DEF_CURRENCY_CODE;
+ console.log(code +' has no currency symbol in closure, used ' + code + ' instead!');
+ }
+ }
+ return numberFormats;
+}
+
+
+function convertDatetimeData(dataObj) {
+ var datetimeFormats = {};
+
+ datetimeFormats.MONTH = dataObj.MONTHS;
+ datetimeFormats.SHORTMONTH = dataObj.SHORTMONTHS;
+ datetimeFormats.DAY = dataObj.WEEKDAYS;
+ datetimeFormats.SHORTDAY = dataObj.SHORTWEEKDAYS;
+ datetimeFormats.AMPMS = dataObj.AMPMS;
+
+
+ datetimeFormats.medium = dataObj.DATEFORMATS[2] + ' ' + dataObj.TIMEFORMATS[2];
+ datetimeFormats.short = dataObj.DATEFORMATS[3] + ' ' + dataObj.TIMEFORMATS[3];
+ datetimeFormats.fullDate = dataObj.DATEFORMATS[0];
+ datetimeFormats.longDate = dataObj.DATEFORMATS[1];
+ datetimeFormats.mediumDate = dataObj.DATEFORMATS[2];
+ datetimeFormats.shortDate = dataObj.DATEFORMATS[3];
+ datetimeFormats.mediumTime = dataObj.TIMEFORMATS[2];
+ datetimeFormats.shortTime = dataObj.TIMEFORMATS[3];
+
+ return datetimeFormats;
+}
diff --git a/i18n/src/parser.js b/i18n/src/parser.js
new file mode 100644
index 00000000..db31aeef
--- /dev/null
+++ b/i18n/src/parser.js
@@ -0,0 +1,64 @@
+/**
+* A simple parser to parse a number format into a pattern object
+*/
+
+exports.parsePattern = parsePattern;
+
+var PATTERN_SEP = ';',
+ DECIMAL_SEP = '.',
+ GROUP_SEP = ',',
+ ZERO = '0',
+ DIGIT = '#';
+
+/**
+ * main funciton for parser
+ * @param str {string} pattern to be parsed (e.g. #,##0.###).
+ */
+function parsePattern(pattern) {
+ var p = {
+ minInt: 1,
+ minFrac: 0,
+ macFrac: 0,
+ posPre: '',
+ posSuf: '',
+ negPre: '',
+ negSuf: '',
+ gSize: 0,
+ lgSize: 0
+ };
+
+ var parts = pattern.split(PATTERN_SEP),
+ positive = parts[0],
+ negative = parts[1];
+
+ var parts = positive.split(DECIMAL_SEP),
+ integer = parts[0],
+ fraction = parts[1];
+
+ p.posPre = integer.substr(0, integer.indexOf(DIGIT));
+
+ for (var i = 0; i < fraction.length; i++) {
+ var ch = fraction.charAt(i);
+ if (ch == ZERO) p.minFrac = p.maxFrac = i + 1;
+ else if (ch == DIGIT) p.maxFrac = i + 1;
+ else p.posSuf += ch;
+ }
+
+ var groups = integer.split(GROUP_SEP);
+ p.gSize = groups[1].length;
+ p.lgSize = (groups[2] || groups[1]).length;
+
+ if (negative) {
+ var trunkLen = positive.length - p.posPre.length - p.posSuf.length,
+ pos = negative.indexOf(DIGIT);
+
+ p.negPre = negative.substr(0, pos).replace(/\'/g, '');
+ p.negSuf = negative.substr(pos + trunkLen).replace(/\'/g, '');
+ } else {
+ // hardcoded '-' sign is fine as all locale use '-' as MINUS_SIGN. (\u2212 is the same as '-')
+ p.negPre = p.posPre + '-';
+ p.negSuf = p.posSuf;
+ }
+
+ return p;
+}
diff --git a/i18n/src/util.js b/i18n/src/util.js
new file mode 100644
index 00000000..82e2a7e4
--- /dev/null
+++ b/i18n/src/util.js
@@ -0,0 +1,7 @@
+exports.findLocaleId = function findLocaleId(str, type) {
+ if (type === 'num') {
+ return (str.match(/^NumberFormatSymbols_(.+)$/) || [])[1];
+ } else if (type == 'datetime') {
+ return (str.match(/^DateTimeSymbols_(.+)$/) || [])[1];
+ }
+}