Permalink
Browse files

updated parsing library to recognize prefixes, version bump,

also updated the examples, updated README, added 'getUnitType' function
  • Loading branch information...
1 parent 0423c04 commit 8e739a214cc83358c9532e3fdadcdae9f5f0c529 @brettlangdon committed Feb 19, 2013
Showing with 158 additions and 12 deletions.
  1. +22 −0 README.md
  2. +3 −1 examples/custom/index.js
  3. +3 −2 examples/simple/index.js
  4. +129 −8 lib/index.js
  5. +1 −1 package.json
View
@@ -15,6 +15,7 @@ npm install node-units
* `importDB(file_name, cb)` - imports a custom unit database, `cb` takes a single argument `err`
* `importDBSync(file_name)` - the sync version of `importDB`
* `getDB()` - returns he currently used database of units as an object
+* `getUnitType(unit)` - given a single unit it will return back `{'type': <unit_group>, 'unit': <base_unit>, 'modifier': <unit_modifier>}`
* `convert(conversion_string)` - where `conversion_string` is of the form `<value> <from_unit> to <to_unit>`
### Properties
@@ -72,6 +73,27 @@ var result = units.convert('5 minutes to s');
// result == 250
```
+## Values
+`node-units` uses `numberizer` which is used to convert string versions of numbers into digits, for example, `forty two` becomes `42` and `one fifth` becomes `0.2`.
+
+What is currently not supported is mathematical symbols like `1/5 days`.
+
+## Prefixes
+
+`node-units` comes with a plethora of built in long and shortname unit prefixes like:
+* nano-, n-
+* micro-, mu-
+* mega-
+* giga-
+* milli-, m-
+* centi-, c-
+* and others
+
+## Variations
+
+`node-units` also understands that it makes more sense to say things like `five days` rather than `five day` so when a unit is not know it will automatically look if the unit
+ends with either `s`, `es` or `ies`.
+
## License
The MIT License (MIT)
View
@@ -4,7 +4,9 @@ var units = require('../../');
var db = path.join(path.dirname(module.filename), 'my_custom.units');
units.importDBSync(db);
-console.log(units.convert('5 buttons to widgets'));
+console.dir(units.getUnitType('jong'));
+console.dir(units.getUnitType('megajongs'));
+console.log(units.convert('5 buttons to widgets'));
console.log(units.convert('30 jings to jong'));
View
@@ -1,10 +1,11 @@
var units = require('../../');
-var result = units.convert('20 quarts to gallons');
+console.dir(units.getUnitType('gallons'));
+console.dir(units.getUnitType('milliliters'));
+var result = units.convert('20 quarts to gallons');
console.log(result === 5);
-
try{
var value = units.convert('5 days to gallon');
console.log(value);
View
@@ -11,6 +11,92 @@ var unit_database = {};
var forms = [/s$/i, /es$/i, /ies$/i];
+var short_prefixes = [
+ {'pattern': /^da/,
+ 'modifier': 10},
+ {'pattern': /^mu/,
+ 'modifier': 1e-6},
+ {'pattern': /^m/,
+ 'modifier': 1e-3},
+ {'pattern': /^h/,
+ 'modifier': 100},
+ {'pattern': /^k/,
+ 'modifier': 1000},
+ {'pattern': /^M/,
+ 'modifier': 1e6},
+ {'pattern': /^G/,
+ 'modifier': 1e9},
+ {'pattern': /^T/,
+ 'modifier': 1e12},
+ {'pattern': /^P/,
+ 'modifier': 1e15},
+ {'pattern': /^E/,
+ 'modifier': 1e18},
+ {'pattern': /^Z/,
+ 'modifier': 1e21},
+ {'pattern': /^Y/,
+ 'modifier': 1e24},
+ {'pattern': /^n/,
+ 'modifier': 1e-9},
+ {'pattern': /^p/,
+ 'modifier': 1e-12},
+ {'pattern': /^c/,
+ 'modifier': 1e-2},
+ {'pattern': /^d/,
+ 'modifier': 1e-1},
+ {'pattern': /^f/,
+ 'modifier': 1e-15},
+ {'pattern': /^a/,
+ 'modifier': 1e-18},
+ {'pattern': /^z/,
+ 'modifier': 1e-21},
+ {'pattern': /^y/,
+ 'modifier': 1e-24},
+];
+
+var long_prefixes = [
+ {'pattern': /^milli/i,
+ 'modifier': 1e-3},
+ {'pattern': /^micro/i,
+ 'modifier': 1e-6},
+ {'pattern': /^nano/i,
+ 'modifier': 1e-9},
+ {'pattern': /^pico/i,
+ 'modifier': 1e-12},
+ {'pattern': /^centi/i,
+ 'modifier': 1e-2},
+ {'pattern': /^deci/i,
+ 'modifier': 1e-1},
+ {'pattern': /^femto/i,
+ 'modifier': 1e-15},
+ {'pattern': /^atto/i,
+ 'modifier': 1e-18},
+ {'pattern': /^zepto/i,
+ 'modifier': 1e-21},
+ {'pattern': /^yocto/i,
+ 'modifier': 1e-24},
+ {'pattern': /^deka/i,
+ 'modifier': 10},
+ {'pattern': /^hecto/i,
+ 'modifier': 100},
+ {'pattern': /^kilo/i,
+ 'modifier': 1000},
+ {'pattern': /^mega/i,
+ 'modifier': 1e6},
+ {'pattern': /^giga/i,
+ 'modifier': 1e9},
+ {'pattern': /^tera/i,
+ 'modifier': 1e12},
+ {'pattern': /^peta/i,
+ 'modifier': 1e15},
+ {'pattern': /^exa/i,
+ 'modifier': 1e18},
+ {'pattern': /^zeta/i,
+ 'modifier': 1e21},
+ {'pattern': /^yotta/i,
+ 'modifier': 1e24},
+];
+
var parseSection = function(section){
var lines = section.split('\n');
var section_name = lines.shift();
@@ -32,8 +118,8 @@ var parseSection = function(section){
value = parseFloat(value[0]);
names.forEach(function(name){
- unit_database[section_name][name.toLowerCase()] = {'unit': unit,
- 'value': value};
+ unit_database[section_name][name] = {'unit': unit,
+ 'value': value};
});
}
};
@@ -61,7 +147,7 @@ var convert = function(type, value, from, to, max_calls){
if(max_calls <= 0){
return undefined;
}
- var section = unit_database[type.toLowerCase()];
+ var section = unit_database[type];
if(!section){
return undefined;
}
@@ -88,6 +174,10 @@ var convert = function(type, value, from, to, max_calls){
var get_variations = function(unit){
var variations = [unit];
+ if(unit.length == 2){
+ return variations;
+ }
+
forms.forEach(function(form){
if(unit.match(form)){
variations.push(unit.replace(form, ''));
@@ -97,11 +187,32 @@ var get_variations = function(unit){
};
+var get_modifier = function(unit){
+ var prefixes = short_prefixes;
+ if(unit.length > 3){
+ prefixes = long_prefixes;
+ }
+ for(var i in prefixes){
+ var prefix = prefixes[i];
+ if(unit.match(prefix.pattern)){
+ return {'unit': unit.replace(prefix.pattern, ''),
+ 'modifier': prefix.modifier};
+ }
+ }
+ return {'unit': unit,
+ 'modifier': 1};
+};
+
var determine_type = function(variations){
for(var i in types){
for(var k in variations){
if(unit_database[types[i]][variations[k]] !== undefined){
- return {'type': types[i], 'unit': variations[k]};
+ return {'type': types[i], 'unit': variations[k], 'modifier': 1};
+ } else{
+ var modified = get_modifier(variations[k]);
+ if(unit_database[types[i]][modified.unit] !== undefined){
+ return {'type': types[i], 'unit': modified.unit, 'modifier': modified.modifier};
+ }
}
}
}
@@ -117,8 +228,17 @@ return module.exports = {
getDB: function(){
return unit_database;
},
+ getUnitType: function(unit){
+ var type = determine_type(get_variations(unit));
+ if(!type){
+ return null;
+ }
+
+ return type;
+ },
convert: function(str){
- var type, value, from, to, max_tries;
+ var type, value, from, to;
+ var max_tries = 5;
var parts = conversion_regex.exec(str);
if(parts == null){
@@ -127,8 +247,8 @@ return module.exports = {
}
value = parseFloat(numerizer(parts[1]));
- var from_variations = get_variations(parts[2].toLowerCase());
- var to_variations = get_variations(parts[3].toLowerCase());
+ var from_variations = get_variations(parts[2]);
+ var to_variations = get_variations(parts[3]);
var from_type = determine_type(from_variations);
var to_type = determine_type(to_variations);
@@ -147,6 +267,7 @@ return module.exports = {
return;
}
+ value = value * from_type.modifier;
type = from_type.type;
from = from_type.unit;
to = to_type.unit;
@@ -155,7 +276,7 @@ return module.exports = {
if(result == undefined){
throw 'Conversion of "' + from + '" to "' + to + '" was not possible';
} else{
- return result;
+ return result / to_type.modifier;
}
},
};
View
@@ -1,6 +1,6 @@
{
"name": "node-units",
- "version": "0.1.1",
+ "version": "0.1.2",
"description": "Node.JS unit conversion library with customizable units",
"main": "lib/index.js",
"directories": {

0 comments on commit 8e739a2

Please sign in to comment.