From beaa28c234eecd50b3370b4f5941535880dd50c2 Mon Sep 17 00:00:00 2001 From: brettlangdon Date: Tue, 19 Feb 2013 09:28:35 -0500 Subject: [PATCH] version bump to 0.1.1 units.convert now accepts a string for conversion rather than parameters, the unit types are now determined rather than needed to be given, the plurarl forms of units are now accepted, numerizer was added to accept values such as 'forty two', fixed some incorrect units in default unit db, update README, added some simple examples --- README.md | 16 +++---- examples/custom/index.js | 10 +++++ examples/custom/my_custom.units | 9 ++++ examples/simple/index.js | 13 ++++++ lib/default.units | 6 +-- lib/index.js | 76 +++++++++++++++++++++++++++------ package.json | 10 ++++- 7 files changed, 113 insertions(+), 27 deletions(-) create mode 100644 examples/custom/index.js create mode 100644 examples/custom/my_custom.units create mode 100644 examples/simple/index.js diff --git a/README.md b/README.md index 21764a3..65f0c70 100644 --- a/README.md +++ b/README.md @@ -15,7 +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 -* `convert(type, value, from, to)` - converts `value` of `from` to `to`, returns the result or raises exception if conversion cannot be made +* `convert(conversion_string)` - where `conversion_string` is of the form ` to ` ### Properties * `types` - `types` is an object containing constants for each unit group. @@ -31,10 +31,10 @@ npm install node-units ```javascript var units = require('node-units'); -var result = units.convert('volume', 5, 'gill', 'mL'); +var result = units.convert('5 gills to mL'); // result == 591.4705 -units.convert(units.types.TIME, 5, 'day', 'second'); +units.convert('five days to seconds'); ``` ### Custom Units @@ -42,9 +42,9 @@ units.convert(units.types.TIME, 5, 'day', 'second'); With `node-units` you can import custom unit definitions from files defined like the following: ``` group: - long_name,longname,ln 1ln - another_unit,au 5ln - one_more,om 2au + longname,longname,ln 1ln + anotherunit,au 5ln + onemore,om 2au ``` ```javascript @@ -52,7 +52,7 @@ var units = require('node-units'); units.importDBSync('my_custom.units'); -var result = units.convert(units.types.GROUP, 5, 'au', 'one_more'); +var result = units.convert('five au to onemores'); // result == 10 ``` @@ -68,7 +68,7 @@ var units = require('node-units'); units.importDBSync('my_custom.units'); -var result = units.convert('time', 5, 'minute', 's'); +var result = units.convert('5 minutes to s'); // result == 250 ``` diff --git a/examples/custom/index.js b/examples/custom/index.js new file mode 100644 index 0000000..c76b27f --- /dev/null +++ b/examples/custom/index.js @@ -0,0 +1,10 @@ +var path = require('path'); +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.log(units.convert('30 jings to jong')); diff --git a/examples/custom/my_custom.units b/examples/custom/my_custom.units new file mode 100644 index 0000000..8fd0bf5 --- /dev/null +++ b/examples/custom/my_custom.units @@ -0,0 +1,9 @@ +elements: + button,btn 5wg + widget,wg 2tbl + table,tbl 1tbl + +things: + jing 2jabber + jabber 30jong + jong 1jong diff --git a/examples/simple/index.js b/examples/simple/index.js new file mode 100644 index 0000000..4f85b04 --- /dev/null +++ b/examples/simple/index.js @@ -0,0 +1,13 @@ +var units = require('../../'); + +var result = units.convert('20 quarts to gallons'); + +console.log(result === 5); + + +try{ + var value = units.convert('5 days to gallon'); + console.log(value); +} catch(e){ + console.log(e); +} diff --git a/lib/default.units b/lib/default.units index c0c2c03..4140e12 100644 --- a/lib/default.units +++ b/lib/default.units @@ -7,9 +7,9 @@ time: volume: liter,L 1L milliliter,mL 0.001L - gallon,gal 3.78541L - pint 0.473176L - quart,qt 0.946353L + gallon,gal 8pint + pint 0.125gal + quart,qt 2pint tablespoon,tbl 0.03125pint teaspoon,tsp 0.33333333333tbl cup 16tbl diff --git a/lib/index.js b/lib/index.js index 95d0364..b1abe82 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,11 +1,16 @@ var path = require('path'); var fs = require('fs'); +var numerizer = require('numerizer'); var types = {}; +var conversion_regex = /^(.*?)\s([a-zA-Z]+)\sto\s([a-zA-Z]+)$/i; + var db_regex = /[a-zA-Z]+:\n([\s\t]+([a-zA-Z]+,?)+[\s\t]+[0-9.]+[a-zA-Z]+\n)+/g; var unit_database = {}; +var forms = [/s$/i, /es$/i, /ies$/i]; + var parseSection = function(section){ var lines = section.split('\n'); var section_name = lines.shift(); @@ -23,12 +28,12 @@ var parseSection = function(section){ var names = next[0].replace(/[\s\t]/g, '').split(','); var value = next[1].replace(/[\s\t]/g, '').match(/([0-9.]+)|([a-zA-Z]+)/g); - var unit = value[1]; + var unit = value[1].toLowerCase(); value = parseFloat(value[0]); names.forEach(function(name){ - unit_database[section_name][name] = {'unit': unit, - 'value': value}; + unit_database[section_name][name.toLowerCase()] = {'unit': unit, + 'value': value}; }); } }; @@ -81,6 +86,26 @@ var convert = function(type, value, from, to, max_calls){ }; +var get_variations = function(unit){ + var variations = [unit]; + forms.forEach(function(form){ + if(unit.match(form)){ + variations.push(unit.replace(form, '')); + } + }); + return variations; +}; + + +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]}; + } + } + } +}; var default_db = path.join(path.dirname(module.filename), 'default.units'); importDBSync(default_db); @@ -92,20 +117,43 @@ return module.exports = { getDB: function(){ return unit_database; }, - convert: function(type, value, from, to){ - type = type.toLowerCase(); - - if(unit_database[type] == undefined){ - throw 'Unit group ' + type + ' does not exist'; - } else if(unit_database[type][from] == undefined){ - throw 'Unit ' + from + ' does not belong to unit group ' + type; - } else if(unit_database[type][to] == undefined){ - throw 'Unit ' + to + ' does not belong to unit group ' + type; + convert: function(str){ + var type, value, from, to, max_tries; + + var parts = conversion_regex.exec(str); + if(parts == null){ + throw 'Invalid conversion string: "' + str + '", expected " to "'; + return; + } + + value = parseFloat(numerizer(parts[1])); + var from_variations = get_variations(parts[2].toLowerCase()); + var to_variations = get_variations(parts[3].toLowerCase()); + + var from_type = determine_type(from_variations); + var to_type = determine_type(to_variations); + + if(!from_type){ + throw 'Unknown unit: "' + parts[2] + '"'; + return; } + if(!to_type){ + throw 'Unknown unit: "' + parts[3] + '"'; + return; + } + + if(from_type.type !== to_type.type){ + throw 'Units "' + from_type.unit + '" and "' + to_type.unit + '" do not belong in the same unit group'; + return; + } + + type = from_type.type; + from = from_type.unit; + to = to_type.unit; - var result = convert(type, value, from, to, 5); + var result = convert(type, value, from, to, max_tries); if(result == undefined){ - throw 'Conversion of ' + from + ' to ' + to + ' was not possible'; + throw 'Conversion of "' + from + '" to "' + to + '" was not possible'; } else{ return result; } diff --git a/package.json b/package.json index 5448ca1..a51af27 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-units", - "version": "0.1.0", + "version": "0.1.1", "description": "Node.JS unit conversion library with customizable units", "main": "lib/index.js", "directories": { @@ -21,5 +21,11 @@ "conversion" ], "author": "Brett Langdon (www.brett.is)", - "license": "MIT" + "license": "MIT", + "dependencies": { + "numerizer": "0.0.2" + }, + "devDependencies": { + "mocha": "*" + } }