commit c0391dc7a88ba2661f37fd755057fe90cdbed409 Author: Brett Langdon Date: Mon Feb 18 17:44:51 2013 -0500 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..3866d3d --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +Node Units +========= + +A unit conversion library for Node.JS that comes with a default unit conversion database and the ability to extend the database with custom metrics. + +## Installing + +```bash +npm install node-units +``` + +## Usage + +`node-units` comes with a few built in functions: + +* `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 + +### Simple Usage + +```javascript +var units = require('node-units'); + +var result = units.convert('volume', 5, 'gill', 'mL'); +// result == 591.4705 + +units.convert(units.types.TIME, 5, 'day', 'second'); +``` + +### Custom Units + +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 +``` + +```javascript +var units = require('node-units'); + +units.importDBSync('my_custom.units'); + +var result = units.convert(units.types.GROUP, 5, 'au', 'one_more'); +// result == 10 +``` + +With custom units you can also overwrite any previously defined units. + +``` +time: + minute,m 50s +``` + +```javascript +var units = require('node-units'); + +units.importDBSync('my_custom.units'); + +var result = units.convert('time', 5, 'minute', 's'); +// result == 250 +``` + +## License + +The MIT License (MIT) +Copyright (c) 2013 Brett Langdon + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/lib/default.units b/lib/default.units new file mode 100644 index 0000000..c0c2c03 --- /dev/null +++ b/lib/default.units @@ -0,0 +1,16 @@ +time: + second,sec,s 1s + minute,min,m 60s + hour,hr,h 3600s + day 86400s + +volume: + liter,L 1L + milliliter,mL 0.001L + gallon,gal 3.78541L + pint 0.473176L + quart,qt 0.946353L + tablespoon,tbl 0.03125pint + teaspoon,tsp 0.33333333333tbl + cup 16tbl + gill,gi 0.1182941L diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..95d0364 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,113 @@ +var path = require('path'); +var fs = require('fs'); + +var types = {}; + +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 parseSection = function(section){ + var lines = section.split('\n'); + var section_name = lines.shift(); + section_name = section_name.replace(/[\r\n\t\s:]/g, '').toLowerCase(); + if(!unit_database[section_name]){ + types[section_name.toUpperCase()] = section_name; + unit_database[section_name] = {}; + } + + while(lines.length){ + var next = lines.shift().split(/\t+/g); + if(next.length != 2){ + continue; + } + + 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]; + value = parseFloat(value[0]); + + names.forEach(function(name){ + unit_database[section_name][name] = {'unit': unit, + 'value': value}; + }); + } +}; + +var importDBSync = function(file_name){ + var fp = fs.readFileSync(file_name).toString(); + var parts = fp.match(db_regex); + parts.forEach(parseSection); +}; + +var importDB = function(file_name, cb){ + fs.readFile(file_name, function(err, fp){ + if(!err){ + var parts = fp.toString().match(db_regex); + parts.forEach(parseSection); + } + + if(cb != undefined){ + cb(err); + } + }); +}; + +var convert = function(type, value, from, to, max_calls){ + if(max_calls <= 0){ + return undefined; + } + var section = unit_database[type.toLowerCase()]; + if(!section){ + return undefined; + } + var from_base = section[from]; + var to_base = section[to]; + if(from_base == undefined || to_base == undefined){ + return undefined; + } + + if(from_base.unit == to){ + return value * from_base.value; + } else if(to_base.unit == from_base.unit){ + return (value * from_base.value / to_base.value); + } else{ + var result = convert(type, from_base.value, from_base.unit, to, max_calls - 1); + if(result == undefined || result == null || result == NaN){ + return undefined; + } else{ + return value * result; + } + } +}; + + + +var default_db = path.join(path.dirname(module.filename), 'default.units'); +importDBSync(default_db); + +return module.exports = { + types: types, + importDBSync: importDBSync, + importDB: importDB, + 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; + } + + var result = convert(type, value, from, to, 5); + if(result == undefined){ + throw 'Conversion of ' + from + ' to ' + to + ' was not possible'; + } else{ + return result; + } + }, +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..5448ca1 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "node-units", + "version": "0.1.0", + "description": "Node.JS unit conversion library with customizable units", + "main": "lib/index.js", + "directories": { + "example": "example" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git://github.com/brettlangdon/node-units.git" + }, + "keywords": [ + "unit", + "units", + "conversion", + "unit", + "conversion" + ], + "author": "Brett Langdon (www.brett.is)", + "license": "MIT" +}