/*______________ | ______ | U I Z E J A V A S C R I P T F R A M E W O R K | / / | --------------------------------------------------- | / O / | MODULE : Uize.Loc.Plurals.RuleParser Package | / / / | | / / / /| | ONLINE : http://uize.com | /____/ /__/_| | COPYRIGHT : (c)2014-2016 UIZE | /___ | LICENSE : Available under MIT License or GNU General Public License |_______________| http://uize.com/license.html */ /* Module Meta Data type: Package importance: 1 codeCompleteness: 5 docCompleteness: 5 */ /*? Introduction The =Uize.Loc.Plurals.RuleParser= module provides methods for parsing [[http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html][CLDR plural rules]] defined using the [[http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules][CLDR plural rule syntax]]. *DEVELOPERS:* `Chris van Rensburg` */ Uize.module ({ name:'Uize.Loc.Plurals.RuleParser', required:[ 'Uize.Str.Split', 'Uize.Str.Trim', 'Uize.Util.RegExpComposition' ], builder:function () { 'use strict'; var /*** Variables for Scruncher Optimization ***/ _split = Uize.Str.Split.split, /*** references to static methods used internally ***/ _ruleToJs, _rulesToJs, /*** General Variables ***/ _ruleRegExpComposition = Uize.Util.RegExpComposition ({ digit:/\d/, value:/{digit}+/, decimalValue:/{value}(\.{value})?/, range:/{value}\.\.{value}/, sampleRange:/{decimalValue}(~{decimalValue})?/, samples:/{sampleRange}(\s*,\s*{sampleRange})*(\s*,\s*(…|\.\.\.))?/, integerOrDecimalSamples:/@(integer|decimal)\s+{samples}/g }), _samplesRegExp = _ruleRegExpComposition.get ('integerOrDecimalSamples'), _orRegExp = /\s+or\s+/, _andRegExp = /\s+and\s+/, _relationPartsRegExp = /^\s*(.+?)\s*(!?=)\s*(.+?)\s*$/, _rangeDetectorRegExp = /\.\.|,/ ; return Uize.package ({ ruleToJs:_ruleToJs = function (_pluralRuleStr) { return Uize.Str.Trim.trim ( Uize.map ( _split (_pluralRuleStr.replace (_samplesRegExp,''),_orRegExp), // remove samples, split or conditions function (_andCondition) { return Uize.map ( _split (_andCondition,_andRegExp), function (_relation) { var _relationParts = _relation.match (_relationPartsRegExp), _operandA = _relationParts [1], _operator = _relationParts [2], _operandB = _relationParts [3] ; if (_operator == '=') _operator = '==' ; return ( _rangeDetectorRegExp.test (_operandB) ? (_operator == '!=' ? '!' : '') + 'within (' + _operandA + ',' + '[' + _operandB.replace ( /(\d+)\.\.(\d+)/g, function (_match,_rangeLimitA,_rangeLimitB) { return '[' + _rangeLimitA + ',' + _rangeLimitB + ']'; } ) + ']' + ')' : _operandA + ' ' + _operator + ' ' + _operandB ); } ).join (' && '); } ).join (' || ') ); /*? Static Methods Uize.Loc.Plurals.RuleParser.ruleToJs Returns a string, representing the CLDR plural rule in the form of a JavaScript expression. SYNTAX ....................................................................... jsExpressionSTR = Uize.Loc.Plurals.RuleParser.ruleToJs (pluralRuleSTR); ....................................................................... */ }, rulesToJs:_rulesToJs = function (_pluralRulesMap) { delete (_pluralRulesMap = Uize.copy (_pluralRulesMap)).other; var _pluralRuleNo = -1, _pluralRuleNames = Uize.keys (_pluralRulesMap) ; function _getPluralRuleCondition () { var _pluralRuleName = _pluralRuleNames [++_pluralRuleNo]; return ( _pluralRuleName ? ( _ruleToJs (_pluralRulesMap [_pluralRuleName]) + ' ? \'' + _pluralRuleName + '\'' + ' : ' + _getPluralRuleCondition () ) : '\'other\'' ); } return _getPluralRuleCondition (); }, rulesToJsFunctionStr:function (_pluralRulesMap) { return ( 'function (n,i,f,t,v,w,within) {\n' + '\treturn ' + _rulesToJs (_pluralRulesMap) + ';\n' + '}\n' ); }, rulesToJsFunction:function (_pluralRulesMap) { return Function ( 'n', 'i', 'f', 't', 'v', 'w', 'within', 'return ' + _rulesToJs (_pluralRulesMap) + ';' ); } }); } });