Skip to content

Commit

Permalink
Unit: Add unit formatting support (1/3)
Browse files Browse the repository at this point in the history
Ref #252
Ref #254
Ref #512
  • Loading branch information
rxaviers committed Oct 20, 2015
1 parent 9c11ad7 commit 1368e85
Show file tree
Hide file tree
Showing 8 changed files with 930 additions and 1 deletion.
32 changes: 32 additions & 0 deletions src/unit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
define([
"./core",
"./unit/format"
], function( Globalize, unitFormat ) {

/**
* Globalize.formatUnit( value, unit, options )
*
* @value [Number]
*
* @unit [String]:
*
* @options [Object]
* - form: [String] "long", "short" (default), or "narrow".
*
* Format units such as seconds, minutes, days, weeks, etc.
*/
Globalize.formatUnit = function( value, unit, options ) {
if ( typeof value !== "number" ) {
throw new Error( "Value is not a number" );
}

if ( !unit ) {
throw new Error( "Missing unit" );
}

return unitFormat( value, unit, options, this.cldr, this );
};

return Globalize;

});
11 changes: 11 additions & 0 deletions src/unit/categories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
define(function() {

/**
* categories()
*
* Return all unit categories.
*/
return [ "acceleration", "angle", "area", "duration", "length", "mass", "power", "pressure",
"speed", "temperature", "volume" ];

});
59 changes: 59 additions & 0 deletions src/unit/format.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
define([
"./get",
"../common/format-message"
], function( unitGet, formatMessage ) {

/**
* format( value, unit, options, cldr, globalize )
*
* @value [Number]
*
* @unit [String]:
*
* @options [Object]
* - form: [String] "long", "short" (default), or "narrow".
*
* FIXME
*
* Format units such as seconds, minutes, days, weeks, etc.
*
* OBS:
*
* Unit Sequences are not implemented.
* http://www.unicode.org/reports/tr35/tr35-35/tr35-general.html#Unit_Sequences
*
* Duration Unit (for composed time unit durations) is not implemented.
* http://www.unicode.org/reports/tr35/tr35-35/tr35-general.html#durationUnit
*/
return function( value, unit, options, cldr, globalize ) {
var dividend, divisor, form, ret;
options = options || {};
form = options.form || "long";

ret = unitGet( unit, form, cldr );

if ( !ret ) {
return;
}

// Compound Unit, eg. "foot-per-second" or "foot/second".
if ( ( /-per-|\// ).test( unit ) ) {

// "For the divisor, the 'one' plural category should be used, while for the
// dividend the appropriate plural form according the placeholder number
// should be used" UTS#35
//
// "There is a known problem with some languages in the long form in that
// the divisor should be inflected. This will probably require the future
// addition of a special 'divisor' form of units commonly used in the
// divisor." UTS#35
dividend = globalize.formatPlural( value, ret[ 0 ] );
divisor = globalize.formatPlural( 1, ret[ 1 ], "" ).trim();
return formatMessage( cldr.main( [ "units", form, "per/compoundUnitPattern" ] ),
[ dividend, divisor ] );
}

return globalize.formatPlural( value, ret );
};

});
76 changes: 76 additions & 0 deletions src/unit/get.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
define([
"./categories"
], function( unitCategories ) {

function stripPluralGarbage( data ) {
var aux, pluralCount;

if ( data ) {
aux = {};
for ( pluralCount in data ) {
aux[ pluralCount.replace( /unitPattern-count-/, "" ) ] = data[ pluralCount ];
}
}

return aux;
}

/**
* get( unit, form, cldr )
*
* @unit [String] The full type-unit name (eg. duration-second), or the short unit name
* (eg. second).
*
* FIXME
*
* Return the plural map of a unit, eg: "second"
* { "one": "{0} second",
* "other": "{0} seconds" }
* }
*
* Or the Array of plural maps of a compound-unit, eg: "foot-per-second"
* [ { "one": "{0} foot",
* "other": "{0} feet" },
* { "one": "{0} second",
* "other": "{0} seconds" } ]
*
* Or undefined in case the unit (or a unit of the compound-unit) doesn't exist.
*/
var get = function( unit, form, cldr ) {
var ret;

// Get unit or <type>-unit (eg. "duration-second").
[ "" ].concat( unitCategories ).some(function( category ) {
return ret = cldr.main([
"units",
form,
category.length ? category + "-" + unit : unit
]);
});

// Rename keys s/unitPattern-count-//g.
ret = stripPluralGarbage( ret );

// Compound Unit, eg. "foot-per-second" or "foot/second".
if ( !ret && ( /-per-|\// ).test( unit ) ) {

// "Some units already have 'precomputed' forms, such as kilometer-per-hour;
// where such units exist, they should be used in preference" UTS#35.
// Note that precomputed form has already been handled above (!ret).

// Get both recursively.
unit = unit.split( /-per-|\// );
ret = unit.map(function( unit ) {
return get( unit, form, cldr );
});
if ( !ret[ 0 ] || !ret[ 1 ] ) {
return;
}
}

return ret;
};

return get;

});
Loading

0 comments on commit 1368e85

Please sign in to comment.