PageRenderTime 26ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/js/jquery.strings.js

https://github.com/jthamrick/devbox
JavaScript | 291 lines | 238 code | 9 blank | 44 comment | 90 complexity | 54143de28fbc651031e3e96543e9adb7 MD5 | raw file
  1. /*
  2. jQuery strings - 0.3
  3. http://code.google.com/p/jquery-utils/
  4. (c) Maxime Haineault <haineault@gmail.com>
  5. http://haineault.com
  6. MIT License (http://www.opensource.org/licenses/mit-license.php)
  7. Implementation of Python3K advanced string formatting
  8. http://www.python.org/dev/peps/pep-3101/
  9. Documentation: http://code.google.com/p/jquery-utils/wiki/StringFormat
  10. */
  11. (function($){
  12. var strings = {
  13. strConversion: {
  14. // tries to translate any objects type into string gracefully
  15. __repr: function(i){
  16. switch(this.__getType(i)) {
  17. case 'array':case 'date':case 'number':
  18. return i.toString();
  19. case 'object':
  20. var o = [];
  21. for (x=0; x<i.length; i++) { o.push(i+': '+ this.__repr(i[x])); }
  22. return o.join(', ');
  23. case 'string':
  24. return i;
  25. default:
  26. return i;
  27. }
  28. },
  29. // like typeof but less vague
  30. __getType: function(i) {
  31. if (!i || !i.constructor) { return typeof(i); }
  32. var match = i.constructor.toString().match(/Array|Number|String|Object|Date/);
  33. return match && match[0].toLowerCase() || typeof(i);
  34. },
  35. //+ Jonas Raoni Soares Silva
  36. //@ http://jsfromhell.com/string/pad [v1.0]
  37. __pad: function(str, l, s, t){
  38. var p = s || ' ';
  39. var o = str;
  40. if (l - str.length > 0) {
  41. o = new Array(Math.ceil(l / p.length)).join(p).substr(0, t = !t ? l : t == 1 ? 0 : Math.ceil(l / 2)) + str + p.substr(0, l - t);
  42. }
  43. return o;
  44. },
  45. __getInput: function(arg, args) {
  46. var key = arg.getKey();
  47. switch(this.__getType(args)){
  48. case 'object': // Thanks to Jonathan Works for the patch
  49. var keys = key.split('.');
  50. var obj = args;
  51. for(var subkey = 0; subkey < keys.length; subkey++){
  52. obj = obj[keys[subkey]];
  53. }
  54. if (typeof(obj) != 'undefined') {
  55. if (strings.strConversion.__getType(obj) == 'array') {
  56. return arg.getFormat().match(/\.\*/) && obj[1] || obj;
  57. }
  58. return obj;
  59. }
  60. else {
  61. // TODO: try by numerical index
  62. }
  63. break;
  64. case 'array':
  65. key = parseInt(key, 10);
  66. if (arg.getFormat().match(/\.\*/) && typeof args[key+1] != 'undefined') { return args[key+1]; }
  67. else if (typeof args[key] != 'undefined') { return args[key]; }
  68. else { return key; }
  69. break;
  70. }
  71. return '{'+key+'}';
  72. },
  73. __formatToken: function(token, args) {
  74. var arg = new Argument(token, args);
  75. return strings.strConversion[arg.getFormat().slice(-1)](this.__getInput(arg, args), arg);
  76. },
  77. // Signed integer decimal.
  78. d: function(input, arg){
  79. var o = parseInt(input, 10); // enforce base 10
  80. var p = arg.getPaddingLength();
  81. if (p) { return this.__pad(o.toString(), p, arg.getPaddingString(), 0); }
  82. else { return o; }
  83. },
  84. // Signed integer decimal.
  85. i: function(input, args){
  86. return this.d(input, args);
  87. },
  88. // Unsigned octal
  89. o: function(input, arg){
  90. var o = input.toString(8);
  91. if (arg.isAlternate()) { o = this.__pad(o, o.length+1, '0', 0); }
  92. return this.__pad(o, arg.getPaddingLength(), arg.getPaddingString(), 0);
  93. },
  94. // Unsigned decimal
  95. u: function(input, args) {
  96. return Math.abs(this.d(input, args));
  97. },
  98. // Unsigned hexadecimal (lowercase)
  99. x: function(input, arg){
  100. var o = parseInt(input, 10).toString(16);
  101. o = this.__pad(o, arg.getPaddingLength(), arg.getPaddingString(),0);
  102. return arg.isAlternate() ? '0x'+o : o;
  103. },
  104. // Unsigned hexadecimal (uppercase)
  105. X: function(input, arg){
  106. return this.x(input, arg).toUpperCase();
  107. },
  108. // Floating point exponential format (lowercase)
  109. e: function(input, arg){
  110. return parseFloat(input, 10).toExponential(arg.getPrecision());
  111. },
  112. // Floating point exponential format (uppercase)
  113. E: function(input, arg){
  114. return this.e(input, arg).toUpperCase();
  115. },
  116. // Floating point decimal format
  117. f: function(input, arg){
  118. return this.__pad(parseFloat(input, 10).toFixed(arg.getPrecision()), arg.getPaddingLength(), arg.getPaddingString(),0);
  119. },
  120. // Floating point decimal format (alias)
  121. F: function(input, args){
  122. return this.f(input, args);
  123. },
  124. // Floating point format. Uses exponential format if exponent is greater than -4 or less than precision, decimal format otherwise
  125. g: function(input, arg){
  126. var o = parseFloat(input, 10);
  127. return (o.toString().length > 6) ? Math.round(o.toExponential(arg.getPrecision())): o;
  128. },
  129. // Floating point format. Uses exponential format if exponent is greater than -4 or less than precision, decimal format otherwise
  130. G: function(input, args){
  131. return this.g(input, args);
  132. },
  133. // Single character (accepts integer or single character string).
  134. c: function(input, args) {
  135. var match = input.match(/\w|\d/);
  136. return match && match[0] || '';
  137. },
  138. // String (converts any JavaScript object to anotated format)
  139. r: function(input, args) {
  140. return this.__repr(input);
  141. },
  142. // String (converts any JavaScript object using object.toString())
  143. s: function(input, args) {
  144. return input.toString && input.toString() || ''+input;
  145. }
  146. },
  147. format: function(str, args) {
  148. var end = 0;
  149. var start = 0;
  150. var match = false;
  151. var buffer = [];
  152. var token = '';
  153. var tmp = (str||'').split('');
  154. for(start=0; start < tmp.length; start++) {
  155. if (tmp[start] == '{' && tmp[start+1] !='{') {
  156. end = str.indexOf('}', start);
  157. token = tmp.slice(start+1, end).join('');
  158. if (tmp[start-1] != '{' && tmp[end+1] != '}') {
  159. var tokenArgs = (typeof arguments[1] != 'object')? arguments2Array(arguments, 2): args || [];
  160. buffer.push(strings.strConversion.__formatToken(token, tokenArgs));
  161. }
  162. else {
  163. buffer.push(token);
  164. }
  165. }
  166. else if (start > end || buffer.length < 1) { buffer.push(tmp[start]); }
  167. }
  168. return (buffer.length > 1)? buffer.join(''): buffer[0];
  169. },
  170. calc: function(str, args) {
  171. return eval(format(str, args));
  172. },
  173. repeat: function(s, n) {
  174. return new Array(n+1).join(s);
  175. },
  176. UTF8encode: function(s) {
  177. return unescape(encodeURIComponent(s));
  178. },
  179. UTF8decode: function(s) {
  180. return decodeURIComponent(escape(s));
  181. },
  182. tpl: function() {
  183. var out = '';
  184. var render = true;
  185. // Set
  186. // $.tpl('ui.test', ['<span>', helloWorld ,'</span>']);
  187. if (arguments.length == 2 && $.isArray(arguments[1])) {
  188. this[arguments[0]] = arguments[1].join('');
  189. return $(this[arguments[0]]);
  190. }
  191. // $.tpl('ui.test', '<span>hello world</span>');
  192. if (arguments.length == 2 && $.isString(arguments[1])) {
  193. this[arguments[0]] = arguments[1];
  194. return $(this[arguments[0]]);
  195. }
  196. // Call
  197. // $.tpl('ui.test');
  198. if (arguments.length == 1) {
  199. return $(this[arguments[0]]);
  200. }
  201. // $.tpl('ui.test', false);
  202. if (arguments.length == 2 && arguments[1] == false) {
  203. return this[arguments[0]];
  204. }
  205. // $.tpl('ui.test', {value:blah});
  206. if (arguments.length == 2 && $.isObject(arguments[1])) {
  207. return $($.format(this[arguments[0]], arguments[1]));
  208. }
  209. // $.tpl('ui.test', {value:blah}, false);
  210. if (arguments.length == 3 && $.isObject(arguments[1])) {
  211. return (arguments[2] == true)
  212. ? $.format(this[arguments[0]], arguments[1])
  213. : $($.format(this[arguments[0]], arguments[1]));
  214. }
  215. }
  216. };
  217. var Argument = function(arg, args) {
  218. this.__arg = arg;
  219. this.__args = args;
  220. this.__max_precision = parseFloat('1.'+ (new Array(32)).join('1'), 10).toString().length-3;
  221. this.__def_precision = 6;
  222. this.getString = function(){
  223. return this.__arg;
  224. };
  225. this.getKey = function(){
  226. return this.__arg.split(':')[0];
  227. };
  228. this.getFormat = function(){
  229. var match = this.getString().split(':');
  230. return (match && match[1])? match[1]: 's';
  231. };
  232. this.getPrecision = function(){
  233. var match = this.getFormat().match(/\.(\d+|\*)/g);
  234. if (!match) { return this.__def_precision; }
  235. else {
  236. match = match[0].slice(1);
  237. if (match != '*') { return parseInt(match, 10); }
  238. else if(strings.strConversion.__getType(this.__args) == 'array') {
  239. return this.__args[1] && this.__args[0] || this.__def_precision;
  240. }
  241. else if(strings.strConversion.__getType(this.__args) == 'object') {
  242. return this.__args[this.getKey()] && this.__args[this.getKey()][0] || this.__def_precision;
  243. }
  244. else { return this.__def_precision; }
  245. }
  246. };
  247. this.getPaddingLength = function(){
  248. var match = false;
  249. if (this.isAlternate()) {
  250. match = this.getString().match(/0?#0?(\d+)/);
  251. if (match && match[1]) { return parseInt(match[1], 10); }
  252. }
  253. match = this.getString().match(/(0|\.)(\d+|\*)/g);
  254. return match && parseInt(match[0].slice(1), 10) || 0;
  255. };
  256. this.getPaddingString = function(){
  257. var o = '';
  258. if (this.isAlternate()) { o = ' '; }
  259. // 0 take precedence on alternate format
  260. if (this.getFormat().match(/#0|0#|^0|\.\d+/)) { o = '0'; }
  261. return o;
  262. };
  263. this.getFlags = function(){
  264. var match = this.getString().matc(/^(0|\#|\-|\+|\s)+/);
  265. return match && match[0].split('') || [];
  266. };
  267. this.isAlternate = function() {
  268. return !!this.getFormat().match(/^0?#/);
  269. };
  270. };
  271. var arguments2Array = function(args, shift) {
  272. var o = [];
  273. for (l=args.length, x=(shift || 0)-1; x<l;x++) { o.push(args[x]); }
  274. return o;
  275. };
  276. $.extend(strings);
  277. })(jQuery);