commit 4b3bc26bae914788c757bedbcdae2852f6fbfb67 Author: Sami Samhuri Date: Sun May 2 21:19:47 2010 -0700 initial commit diff --git a/format.js b/format.js new file mode 100644 index 0000000..16f2346 --- /dev/null +++ b/format.js @@ -0,0 +1,91 @@ +// +// format, printf-like string formatting for JavaScript +// github.com/samsonjs/format +// +// Copyright 2010 Sami Samhuri +// ISC license +// + +var sys = require('sys'); + +exports.extendNativeStrings = function() { + String.prototype.printf = function(/* ... */) { + var args = Array.prototype.slice.call(arguments); + args.unshift(this); + sys.puts(exports.format.apply(this, args)); + }; + String.prototype.format = function(/* ... */) { + var args = Array.prototype.slice.call(arguments); + if (args[0] !== this) args.unshift(this); + exports.format.apply(this, args); + }; +}; + +exports.printf = function(/* ... */) { + sys.puts(exports.format.apply(this, Array.prototype.slice.call(arguments))); +}; + +exports.format = function(format) { + var argIndex = 1 // skip initial format argument + , args = Array.prototype.slice.call(arguments) + , i = 0 + , n = format.length + , result = '' + , c + , escaped = false + , arg + , precision + , nextArg = function() { return args[argIndex++]; } + , slurpNumber = function() { + var digits = ''; + while (format[i].match(/\d/)) + digits += format[i++]; + return digits.length > 0 ? parseInt(digits) : null; + } + ; + for (; i < n; ++i) { + c = format[i]; + if (escaped) { + escaped = false; + precision = slurpNumber(); + switch (c) { + case 'b': // number in binary + result += parseInt(nextArg(), 10).toString(2); + break; + case 'c': // character + arg = nextArg(); + if (typeof arg === 'string' || arg instanceof String) + result += arg; + else + result += String.fromCharCode(parseInt(arg, 10)); + break; + case 'd': // number in decimal + result += parseInt(nextArg(), 10); + break; + case 'f': // floating point number + result += parseFloat(nextArg()).toFixed(precision || 6); + break; + case 'o': // number in octal + result += '0' + parseInt(nextArg(), 10).toString(8); + break; + case 's': // string + result += nextArg(); + break; + case 'x': // lowercase hexadecimal + result += '0x' + parseInt(nextArg(), 10).toString(16); + break; + case 'X': // uppercase hexadecimal + result += '0x' + parseInt(nextArg(), 10).toString(16).toUpperCase(); + break; + default: + result += c; + break; + } + } else if (c === '%') { + escaped = true; + } else { + result += c; + } + } + return result; +}; diff --git a/test_format.js b/test_format.js new file mode 100644 index 0000000..d0f8752 --- /dev/null +++ b/test_format.js @@ -0,0 +1,5 @@ +var format = require('./format'); +format.extendNativeStrings(); +'hello'.printf(); +'hello %s'.printf('sami'); +'b: %b\nc: %c\nd: %d\nf: %f\no: %o\ns: %s\nx: %x\nX: %X'.printf(42, 65, 42*42, 42*42*42/1000000000, 255, 'sami', 0xfeedface, 0xc0ffee);