diff options
Diffstat (limited to 'i18n/src')
| -rw-r--r-- | i18n/src/closureSlurper.js | 106 | ||||
| -rw-r--r-- | i18n/src/converter.js | 60 | ||||
| -rw-r--r-- | i18n/src/parser.js | 64 | ||||
| -rw-r--r-- | i18n/src/util.js | 7 |
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]; + } +} |
