UNPKG

granula

Version:

i18n tool for angular.js applications

195 lines (176 loc) 7.08 kB
(function() { var SETTINGS_TEMPLATE, appliableOptions, fs, granula, htmlDocument, merge, merger, parseOptions, path, processHtmlFile, processor, wrench, writeSettings, _, _try; _ = require('underscore'); granula = require('../granula/granula'); processor = require('./processor'); htmlDocument = require('./documents').htmlDocument; fs = require('fs'); wrench = require('wrench'); merger = require('./merger'); path = require('path'); SETTINGS_TEMPLATE = "angular.module('granula').config([\"grServiceProvider\", function(grServiceProvider) {\n grServiceProvider.config(__OPTIONS__);\n}]);"; module.exports = { /* # options = # src: string = '.' - directory to scan # fileTypes: comma-separated string - which files to process ('html', 'js') # out: string = './lang' - where to search/store language files # languages: comma-separated tring - language files to create # mapping: # onlyMarked: boolean = true - if true then only elements marked with gr-key will be processed # textAsKey: string = "nokey" - "always" - key is obtained from gr-key, error if empty. # "never" - key is always obtained from text # "nokey" - key obtains from gr-key if presents, from text otherwise # wordsLimitForKey: int = 10 - how many first words will be taken for key # replaceSpaces: false or string = false - shall spaces be replaced or not # attrsToTranslate: comma-separated string - which attributes shall be translated. "title,alt,placeholder" by default # generateSettingsFile: false or file name - generate file with these settings under 'out' directory # translateMe: string - symbol or string to use as suffix for non-translated strings */ processFiles: function(options, cb) { var processingResult, _this = this; options = parseOptions(options); processingResult = {}; return wrench.readdirRecursive(options.src, function(error, files) { var htmlFiles; if (error) { return cb(error); } if ((error === files && files === null)) { return merge(options, processingResult, cb); } htmlFiles = files.filter(function(f) { return f.toLowerCase().slice(-5) === '.html'; }); return htmlFiles.forEach(function(file) { console.log("Processing " + file); return processHtmlFile(processingResult, path.join(options.src, file), options); }); }); } }; _try = function(action) { return { "catch": function(react) { var e; try { return action(); } catch (_error) { e = _error; return react(); } } }; }; merge = function(options, _arg, cb) { var errors, lang, warnings, _this = this; errors = _arg.errors, warnings = _arg.warnings, lang = _arg.lang; if (errors.length > 0) { errors.forEach(function(e) { return console.error("Error: " + e); }); return cb("Processing interrupted due to errors"); } warnings.forEach(function(w) { return console.info(" -- Warning: " + w); }); options.languages.forEach(function(language) { var langFilePath, newJson, oldJson; langFilePath = path.join(options.out, language + '.json'); oldJson = _try(function() { return JSON.parse(fs.readFileSync(langFilePath)); })["catch"](function() { return {}; }); newJson = merger.merge(oldJson, lang, options.mapping); fs.writeFileSync(langFilePath, JSON.stringify(newJson, null, 4)); return console.log("Created " + langFilePath); }); return writeSettings(options, lang, cb); }; writeSettings = function(options, lang, cb) { var settings, settingsFilePath; if (options.mapping.generateSettingsFile) { settingsFilePath = path.join(options.out, options.mapping.generateSettingsFile); settings = SETTINGS_TEMPLATE.replace(/__OPTIONS__/, JSON.stringify(appliableOptions(options.mapping))); fs.writeFileSync(settingsFilePath, settings); console.log("Created " + settingsFilePath); } return cb(null); }; appliableOptions = function(options) { return _.pick(options, "textAsKey", "wordsLimitForKey", "replaceSpaces", "translateMe"); }; parseOptions = function(options) { var csToList, mapping, validateEnum, validateInteger, _ref; mapping = (_ref = options.mapping) != null ? _ref : {}; delete options.mapping; options = _.defaults(options, { src: '.', fileTypes: 'html', out: './lang', languages: "" }); options.mapping = _.defaults(mapping, { onlyMarked: true, textAsKey: "nokey", wordsLimitForKey: 10, replaceSpaces: false, generateSettingsFile: "settings.js", attrsToTranslate: "title,alt,placeholder", translateMe: "✍ " }); csToList = function(str) { if (_.isEmpty(str)) { return []; } return str.split(','); }; options.fileTypes = csToList(options.fileTypes); options.languages = csToList(options.languages); options.mapping.attrsToTranslate = csToList(options.mapping.attrsToTranslate); validateEnum = function(name, value, possible) { if (_.isArray(value)) { if (_.difference(value, possible).length > 0) { throw new Error("Option '" + name + "' shall contain only following values: " + (possible.join(', '))); } } else { if (_.indexOf(possible, value) === -1) { throw new Error("Option '" + name + "' shall be one of the following values: " + (possible.join(', '))); } } }; validateInteger = function(name, value) { if (_.isNaN(parseInt(value))) { throw new Error("Option '" + name + "' shall be number "); } }; validateEnum("fileTypes", options.fileTypes, ["html"]); validateEnum("onlyMarked", options.mapping.onlyMarked, [true, false]); validateEnum("textAsKey", options.mapping.textAsKey, ["nokey", "always", "never"]); validateInteger("wordsLimitForKey", options.mapping.wordsLimitForKey); if (options.languages.length === 0) { throw new Error("At least one language shall be provided"); } return options; }; processHtmlFile = function(outputStruct, filePath, options) { var htmlText, _ref; htmlText = fs.readFileSync(filePath, (_ref = options.encoding) != null ? _ref : "utf-8"); outputStruct = _.defaults(outputStruct, { lang: {}, errors: [], warnings: [] }); return processor().processHtml(outputStruct.lang, htmlDocument(htmlText), options.mapping, { addError: function(e) { return outputStruct.errors.push(e); }, addWarning: function(w) { return outputStruct.warnings.push(w); } }); }; }).call(this);