plotly.js
Version:
The open source javascript graphing library that powers plotly
167 lines (139 loc) • 6.16 kB
JavaScript
var path = require('path');
var fs = require('fs');
var constants = require('./util/constants');
var common = require('./util/common');
var args = process.argv.slice(2);
var argLocale = args[0];
var pathToEn = path.join(constants.pathToSrc, 'locale-en.js');
var pathToWCRegions = path.dirname(require.resolve('world-calendars/dist/regional/en-GB'));
if(!argLocale) {
fs.readdir(pathToWCRegions, function(err, items) {
if(err) throw err;
items.forEach(function(item) {
var itemLocale = item.split('.')[0];
if(itemLocale.substr(0, 2) === 'en') {
console.log('skipping English ' + itemLocale);
return;
}
pullOneLocale(itemLocale);
});
});
} else {
pullOneLocale(argLocale);
}
function pullOneLocale(locale) {
var pathToInput = path.join(pathToWCRegions, locale + '.js');
var pathToOutput = path.join(constants.pathToLib, 'locales', locale.toLowerCase() + '.js');
fs.readFile(pathToInput, 'utf8', function(err, wcCode) {
if(err) {
throw new Error('pull_date_format failed: ' + pathToInput + ' not found');
}
var preStartStr = 'prototype.regionalOptions';
var startStr = '] = {';
var endStr = '};';
var startIndex = wcCode.indexOf(startStr, wcCode.indexOf(preStartStr)) + startStr.length - 1;
var endIndex = wcCode.indexOf(endStr, startIndex) + 1;
var dataStr = wcCode.substr(startIndex, endIndex - startIndex);
// strip out `main.substitute(Chinese)?Digits` - we don't care about the digits field for now anyway
dataStr = dataStr.replace(/main[\.][A-Za-z]+\([^\)]*\)/g, '""');
dataStr = cleanHTMLEntities(dataStr);
var wcDataObj = eval('a=' + dataStr);
fs.readFile(pathToOutput, 'utf8', function(err, existingOutputText) {
var isNew = false;
if(err || !existingOutputText.trim()) {
existingOutputText = fs.readFileSync(pathToEn, 'utf8');
isNew = true;
}
var outObjStartStr = 'module.exports = ';
var outObjEndStr = '};';
var outObjStartIndex = existingOutputText.indexOf(outObjStartStr) + outObjStartStr.length;
var outObjEndIndex = existingOutputText.indexOf(outObjEndStr, outObjStartIndex) + 1;
var outPrefix = existingOutputText.substr(0, outObjStartIndex);
var outSuffix = existingOutputText.substr(outObjEndIndex);
var objText = existingOutputText.substr(outObjStartIndex, outObjEndIndex - outObjStartIndex);
var outObj;
try {
outObj = eval('a=' + objText);
} catch(e) {
throw new Error(locale + '--' + objText);
}
if(isNew) {
outObj.name = locale;
outObj.dictionary = {};
outObj.format = {};
}
var format = outObj.format = (outObj.format || {});
format.days = wcDataObj.dayNames;
format.shortDays = wcDataObj.dayNamesShort;
format.months = wcDataObj.monthNames;
format.shortMonths = wcDataObj.monthNamesShort;
format.date = translateDateFormat(wcDataObj.dateFormat);
// leave out `dateTime` and `time` fields. We could include them as cmd line args later
// for now these will get inherited from english.
var outStr = JSON.stringify(outObj, null, 4)
.replace(/'/g, '\\\'') // escape single quotes
.replace(/"([A-Za-z]\w+)":/g, '$1:') // unquote simple identifier keys
.replace(/([^\\])"/g, '$1\'') // replace unescaped doublequotes with singlequotes
.replace(/\\"/g, '"'); // unescape escaped doublequotes
outStr = shortenArrays(outStr);
common.writeFile(pathToOutput, outPrefix + outStr + outSuffix, function() {
console.log('ok pull_date_format ' + locale);
});
});
});
}
/*
* Turn HTML entities into unicode - for explicit compatibility with SVG
* There are just a few in world-calendars that aren't already in unicode anyway.
*/
var entityMap = {
ccedil: '\u00e7',
auml: '\u00e4',
'#x10C': '\u010c'
};
function cleanHTMLEntities(s) {
return s.replace(/&([^;]+);/g, function(entity, entityID) {
var outChar = entityMap[entityID];
if(!outChar) {
throw new Error('no unicode character listed for ' + entity);
}
return outChar;
});
}
/*
* Convert world-calendars date format ('dd.mm.yyyy') to d3 ('%d.%m.%Y')
*/
function translateDateFormat(wcDateFormat) {
var out = wcDateFormat
.replace('yyyy', '%Y')
// bosnian (bs) uses 2-digit year in world-calendars, but I don't want to continue that!
.replace('yy', '%Y')
.replace('mm', '%m')
.replace('dd', '%d')
// gujarati (gu) uses short month name in world-calendars - keep it?
.replace('M', '%b');
return out;
}
/**
* Either put the whole array on one line, split it into 2 lines,
* or leave it as is (one line per item), whatever we can fit into 90 characters.
* A trailing comma may still be after the 90-character limit
*/
function shortenArrays(s) {
var maxLen = 91; // max line length plus one for the initial \n.
return s.replace(/(\n.+\[)\n([^\]]+)\n(\s*)\]/g, function(wholeMatch, prefix, arrayStr, bracketSpaces) {
var parts = arrayStr.trim().split(/,\n\s*/);
var singleLine = prefix + parts.join(', ') + ']';
if(singleLine.length <= maxLen) {
return singleLine;
}
var arraySpaces = bracketSpaces + ' ';
var splitPoint = Math.ceil(parts.length / 2);
var line1 = arraySpaces + parts.slice(0, splitPoint).join(', ') + ',';
var line2 = arraySpaces + parts.slice(splitPoint).join(', ');
if(line1.length <= maxLen && line2.length <= maxLen) {
return [prefix, line1, line2, bracketSpaces + ']'].join('\n');
}
return wholeMatch;
});
}