1 var comb = exports, date; 2 3 comb.isString = function(obj) { 4 var undef; 5 return obj != undef && (typeof obj == "string" || obj instanceof String); 6 }; 7 8 var FORMAT_REGEX = /%((?:-?\+?.?\d*)?|(?:\[[^\[|\]]*\]))?([sjdDZ])/g; 9 var INTERP_REGEX = /{(?:\[([^\[|\]]*)\])?(\w+)}/g; 10 var STR_FORMAT = /(-?)(\+?)([A-Z|a-z|\W]?)([1-9][0-9]*)?$/; 11 var OBJECT_FORMAT = /([1-9][0-9]*)$/g; 12 13 var formatString = function(string, format) { 14 var match = format.match(STR_FORMAT), ret = string, cString = comb.string; 15 if (match) { 16 var isLeftJustified = match[1], padChar = match[3], width = match[4]; 17 if (width) { 18 width = parseInt(width); 19 if (ret.length < width) { 20 ret = cString.pad(ret, width, padChar, isLeftJustified); 21 } else { 22 ret = cString.truncate(ret, width); 23 } 24 } 25 } 26 return ret; 27 }; 28 29 var formatNumber = function(number, format) { 30 if (typeof number == "number") { 31 var cString = comb.string, ret = "" + number; 32 var match = format.match(STR_FORMAT); 33 if (match) { 34 var isLeftJustified = match[1], signed = match[2], padChar = match[3], width = match[4]; 35 if (signed) { 36 ret = (number > 0 ? "+" : "") + ret; 37 } 38 if (width) { 39 width = parseInt(width); 40 if (ret.length < width) { 41 ret = cString.pad(ret, width, padChar || "0", isLeftJustified); 42 } else { 43 ret = cString.truncate(ret, width); 44 } 45 } 46 47 } 48 } else { 49 throw new Error("comb.string.format : when using %d the parameter must be a number!"); 50 } 51 return ret; 52 }; 53 54 var formatObject = function(object, format) { 55 var ret, match = format.match(OBJECT_FORMAT), spacing = 0; 56 if (match) { 57 spacing = parseInt(match[0]); 58 if (isNaN(spacing)) spacing = 0; 59 } 60 try { 61 ret = JSON.stringify(object, null, spacing); 62 } catch(e) { 63 throw new Error("comb.string.format : Unable to parse json from ", object); 64 } 65 return ret; 66 }; 67 68 69 var styles = { 70 //styles 71 bold : 1, 72 bright : 1, 73 italic : 3, 74 underline : 4, 75 blink : 5, 76 inverse : 7, 77 crossedOut : 9, 78 79 red : 31, 80 green : 32, 81 yellow : 33, 82 blue : 34, 83 magenta : 35, 84 cyan : 36, 85 white : 37, 86 87 redBackground : 41, 88 greenBackground : 42, 89 yellowBackground : 43, 90 blueBackground : 44, 91 magentaBackground : 45, 92 cyanBackground : 46, 93 whiteBackground : 47, 94 95 encircled : 52, 96 overlined : 53, 97 grey : 90, 98 black : 90 99 }; 100 101 /**@namespace comb characters*/ 102 comb.characters = { 103 /** 104 * ☺ 105 */ 106 SMILEY : "☺", 107 /** 108 * ☻ 109 */ 110 SOLID_SMILEY : "☻", 111 112 /** 113 * ♥ 114 */ 115 HEART:"♥", 116 /** 117 * ♦ 118 */ 119 DIAMOND : "♦", 120 /** 121 * ♣ 122 */ 123 CLOVE : "♣", 124 /** 125 * ♠ 126 */ 127 SPADE : "♠", 128 /** 129 * • 130 */ 131 DOT: "•", 132 /** 133 * ◘ 134 */ 135 SQUARE_CIRCLE: "◘", 136 /** 137 * ○ 138 */ 139 CIRCLE: "○", 140 /** 141 * ◙ 142 */ 143 FILLED_SQUARE_CIRCLE: "◙", 144 /** 145 * ♂ 146 */ 147 MALE : "♂", 148 /** 149 * ♀ 150 */ 151 FEMALE : "♀", 152 /** 153 * ♪ 154 */ 155 EIGHT_NOTE: "♪", 156 /** 157 * ♫ 158 */ 159 DOUBLE_EIGHT_NOTE: "♫", 160 /** 161 * ☼ 162 */ 163 SUN : "☼", 164 /** 165 * ► 166 */ 167 PLAY : "►", 168 /** 169 * ◄ 170 */ 171 REWIND : "◄", 172 /** 173 * ↕ 174 */ 175 UP_DOWN : "↕", 176 /** 177 * ¶ 178 */ 179 PILCROW : "¶", 180 /** 181 * § 182 */ 183 SECTION : "§", 184 /** 185 * ▬ 186 */ 187 THICK_MINUS : "▬", 188 /** 189 * ↨ 190 */ 191 SMALL_UP_DOWN : "↨", 192 /** 193 * ↑ 194 */ 195 UP_ARROW : "↑", 196 /** 197 * ↓ 198 */ 199 DOWN_ARROW: "↓", 200 /** 201 * → 202 */ 203 RIGHT_ARROW : "→", 204 /** 205 * ← 206 */ 207 LEFT_ARROW: "←", 208 /** 209 * ∟ 210 */ 211 RIGHT_ANGLE: "∟", 212 /** 213 * ↔ 214 */ 215 LEFT_RIGHT_ARROW: "↔", 216 /** 217 * ▲ 218 */ 219 TRIANGLE: "▲", 220 /** 221 * ▼ 222 */ 223 DOWN_TRIANGLE: "▼", 224 225 /** 226 * ⌂ 227 */ 228 HOUSE : "⌂", 229 /** 230 * Ç 231 */ 232 C_CEDILLA: "Ç", 233 /** 234 * ü 235 */ 236 U_UMLAUT: "ü", 237 /** 238 * é 239 */ 240 E_ACCENT: "é", 241 /** 242 * â 243 */ 244 A_LOWER_CIRCUMFLEX: "â", 245 /** 246 * ä 247 */ 248 A_LOWER_UMLAUT: "ä", 249 /** 250 * à 251 */ 252 A_LOWER_GRAVE_ACCENT: "à", 253 /** 254 * å 255 */ 256 A_LOWER_CIRCLE_OVER: "å", 257 /** 258 * ç 259 */ 260 C_LOWER_CIRCUMFLEX: "ç", 261 /** 262 * ê 263 */ 264 E_LOWER_CIRCUMFLEX: "ê", 265 /** 266 * ë 267 */ 268 E_LOWER_UMLAUT: "ë", 269 /** 270 * è 271 */ 272 E_LOWER_GRAVE_ACCENT: "è", 273 /** 274 * ï 275 */ 276 I_LOWER_UMLAUT: "ï", 277 /** 278 * î 279 */ 280 I_LOWER_CIRCUMFLEX: "î", 281 /** 282 * ì 283 */ 284 I_LOWER_GRAVE_ACCENT: "ì", 285 /** 286 * Ä 287 */ 288 A_UPPER_UMLAUT: "Ä", 289 /** 290 * Å 291 */ 292 A_UPPER_CIRCLE: "Å", 293 /** 294 * É 295 */ 296 E_UPPER_ACCENT: "É", 297 /** 298 * æ 299 */ 300 A_E_LOWER: "æ", 301 /** 302 * Æ 303 */ 304 A_E_UPPER: "Æ", 305 /** 306 * ô 307 */ 308 O_LOWER_CIRCUMFLEX: "ô", 309 /** 310 * ö 311 */ 312 O_LOWER_UMLAUT: "ö", 313 /** 314 * ò 315 */ 316 O_LOWER_GRAVE_ACCENT: "ò", 317 /** 318 * û 319 */ 320 U_LOWER_CIRCUMFLEX: "û", 321 /** 322 * ù 323 */ 324 U_LOWER_GRAVE_ACCENT: "ù", 325 /** 326 * ÿ 327 */ 328 Y_LOWER_UMLAUT: "ÿ", 329 /** 330 * Ö 331 */ 332 O_UPPER_UMLAUT: "Ö", 333 /** 334 * Ü 335 */ 336 U_UPPER_UMLAUT: "Ü", 337 338 /** 339 * ¢ 340 */ 341 CENTS: "¢", 342 /** 343 * £ 344 */ 345 POUND: "£", 346 /** 347 * ¥ 348 */ 349 YEN: "¥", 350 /** 351 * ¤ 352 */ 353 CURRENCY : "¤", 354 355 /** 356 * ₧ 357 */ 358 PTS: "₧", 359 /** 360 * ƒ 361 */ 362 FUNCTION: "ƒ", 363 /** 364 * á 365 */ 366 A_LOWER_ACCENT: "á", 367 /** 368 * í 369 */ 370 I_LOWER_ACCENT: "í", 371 /** 372 * ó 373 */ 374 O_LOWER_ACCENT: "ó", 375 /** 376 * ú 377 */ 378 U_LOWER_ACCENT: "ú", 379 /** 380 * ñ 381 */ 382 N_LOWER_TILDE: "ñ", 383 /** 384 * Ñ 385 */ 386 N_UPPER_TILDE: "Ñ", 387 /** 388 * ª 389 */ 390 A_SUPER: "ª", 391 /** 392 * º 393 */ 394 O_SUPER: "º", 395 /** 396 * ¿ 397 */ 398 UPSIDEDOWN_QUESTION: "¿", 399 /** 400 * ⌐ 401 */ 402 SIDEWAYS_L : "⌐", 403 /** 404 * ¬ 405 */ 406 NEGATION: "¬", 407 /** 408 * ½ 409 */ 410 ONE_HALF : "½", 411 /** 412 * ¼ 413 */ 414 ONE_FOURTH: "¼", 415 /** 416 * ¡ 417 */ 418 UPSIDEDOWN_EXCLAMATION: "¡", 419 /** 420 * « 421 */ 422 DOUBLE_LEFT: "«", 423 /** 424 * » 425 */ 426 DOUBLE_RIGHT: "»", 427 /** 428 * ░ 429 */ 430 LIGHT_SHADED_BOX: "░", 431 /** 432 * ▒ 433 */ 434 MEDIUM_SHADED_BOX: "▒", 435 /** 436 * ▓ 437 */ 438 DARK_SHADED_BOX: "▓", 439 /** 440 * │ 441 */ 442 VERTICAL_LINE: "│", 443 444 /** 445 * ┤ 446 */ 447 MAZE__SINGLE_RIGHT_T: "┤", 448 /** 449 * ┐ 450 */ 451 MAZE_SINGLE_RIGHT_TOP: "┐", 452 /** 453 * ┘ 454 */ 455 MAZE_SINGLE_RIGHT_BOTTOM_SMALL: "┘", 456 /** 457 * ┌ 458 */ 459 MAZE_SINGLE_LEFT_TOP_SMALL: "┌", 460 /** 461 * └ 462 */ 463 MAZE_SINGLE_LEFT_BOTTOM_SMALL: "└", 464 /** 465 * ├ 466 */ 467 MAZE_SINGLE_LEFT_T: "├", 468 /** 469 * ┴ 470 */ 471 MAZE_SINGLE_BOTTOM_T: "┴", 472 /** 473 * ┬ 474 */ 475 MAZE_SINGLE_TOP_T: "┬", 476 /** 477 * ┼ 478 */ 479 MAZE_SINGLE_CENTER: "┼", 480 /** 481 * ─ 482 */ 483 MAZE_SINGLE_HORIZONTAL_LINE: "─", 484 485 /** 486 * ╡ 487 */ 488 MAZE_SINGLE_RIGHT_DOUBLECENTER_T: "╡", 489 /** 490 * ╛ 491 */ 492 MAZE_SINGLE_RIGHT_DOUBLE_BL: "╛", 493 /** 494 * ╢ 495 */ 496 MAZE_SINGLE_RIGHT_DOUBLE_T: "╢", 497 /** 498 * ╖ 499 */ 500 MAZE_SINGLE_RIGHT_DOUBLEBOTTOM_TOP: "╖", 501 /** 502 * ╕ 503 */ 504 MAZE_SINGLE_RIGHT_DOUBLELEFT_TOP: "╕", 505 /** 506 * ╞ 507 */ 508 MAZE_SINGLE_LEFT_DOUBLE_T: "╞", 509 510 /** 511 * ╧ 512 */ 513 MAZE_SINGLE_BOTTOM_DOUBLE_T: "╧", 514 /** 515 * ╤ 516 */ 517 MAZE_SINGLE_TOP_DOUBLE_T: "╤", 518 /** 519 * ╥ 520 */ 521 MAZE_SINGLE_TOP_DOUBLECENTER_T: "╥", 522 /** 523 * ╨ 524 */ 525 MAZE_SINGLE_BOTTOM_DOUBLECENTER_T: "╨", 526 /** 527 * ╘ 528 */ 529 MAZE_SINGLE_LEFT_DOUBLERIGHT_BOTTOM: "╘", 530 /** 531 * ╒ 532 */ 533 MAZE_SINGLE_LEFT_DOUBLERIGHT_TOP: "╒", 534 /** 535 * ╓ 536 */ 537 MAZE_SINGLE_LEFT_DOUBLEBOTTOM_TOP: "╓", 538 /** 539 * ╙ 540 */ 541 MAZE_SINGLE_LEFT_DOUBLETOP_BOTTOM: "╙", 542 /** 543 * Γ 544 */ 545 MAZE_SINGLE_LEFT_TOP: "Γ", 546 /** 547 * ╜ 548 */ 549 MAZE_SINGLE_RIGHT_BOTTOM: "╜", 550 /** 551 * ╟ 552 */ 553 MAZE_SINGLE_LEFT_CENTER: "╟", 554 /** 555 * ╫ 556 */ 557 MAZE_SINGLE_DOUBLECENTER_CENTER: "╫", 558 /** 559 * ╪ 560 */ 561 MAZE_SINGLE_DOUBLECROSS_CENTER: "╪", 562 563 564 /** 565 * ╣ 566 */ 567 MAZE_DOUBLE_LEFT_CENTER: "╣", 568 /** 569 * ║ 570 */ 571 MAZE_DOUBLE_VERTICAL: "║", 572 /** 573 * ╗ 574 */ 575 MAZE_DOUBLE_RIGHT_TOP: "╗", 576 /** 577 * ╝ 578 */ 579 MAZE_DOUBLE_RIGHT_BOTTOM: "╝", 580 /** 581 * ╚ 582 */ 583 MAZE_DOUBLE_LEFT_BOTTOM: "╚", 584 /** 585 * ╔ 586 */ 587 MAZE_DOUBLE_LEFT_TOP: "╔", 588 /** 589 * ╩ 590 */ 591 MAZE_DOUBLE_BOTTOM_T: "╩", 592 /** 593 * ╦ 594 */ 595 MAZE_DOUBLE_TOP_T : "╦", 596 /** 597 * ╠ 598 */ 599 MAZE_DOUBLE_LEFT_T: "╠", 600 /** 601 * ═ 602 */ 603 MAZE_DOUBLE_HORIZONTAL: "═", 604 /** 605 * ╬ 606 */ 607 MAZE_DOUBLE_CROSS: "╬", 608 609 /** 610 * █ 611 */ 612 SOLID_RECTANGLE: "█", 613 /** 614 * ▌ 615 */ 616 THICK_LEFT_VERTICAL: "▌", 617 /** 618 * ▐ 619 */ 620 THICK_RIGHT_VERTICAL: "▐", 621 /** 622 * ▄ 623 */ 624 SOLID_SMALL_RECTANGLE_BOTTOM: "▄", 625 /** 626 * ▀ 627 */ 628 SOLID_SMALL_RECTANGLE_TOP: "▀", 629 630 /** 631 * Φ 632 */ 633 PHI_UPPER: "Φ", 634 635 /** 636 * ∞ 637 */ 638 INFINITY: "∞", 639 /** 640 * ∩ 641 */ 642 INTERSECTION: "∩", 643 /** 644 * ≡ 645 */ 646 DEFINITION: "≡", 647 /** 648 * ± 649 */ 650 PLUS_MINUS: "±", 651 /** 652 * ≥ 653 */ 654 GT_EQ: "≥", 655 /** 656 * ≤ 657 */ 658 LT_EQ: "≤", 659 /** 660 * ⌠ 661 */ 662 THEREFORE: "⌠", 663 /** 664 * ∵ 665 */ 666 SINCE : "∵", 667 /** 668 * ∄ 669 */ 670 DOESNOT_EXIST : "∄", 671 /** 672 * ∃ 673 */ 674 EXISTS : "∃", 675 /** 676 * ∀ 677 */ 678 FOR_ALL :"∀", 679 /** 680 * ⊕ 681 */ 682 EXCLUSIVE_OR : "⊕", 683 /** 684 * ⌡ 685 */ 686 BECAUSE: "⌡", 687 /** 688 * ÷ 689 */ 690 DIVIDE: "÷", 691 /** 692 * ≈ 693 */ 694 APPROX: "≈", 695 696 /** 697 * ° 698 */ 699 DEGREE: "°", 700 /** 701 * ∙ 702 */ 703 BOLD_DOT: "∙", 704 /** 705 * · 706 */ 707 DOT_SMALL: "·", 708 /** 709 * √ 710 */ 711 CHECK: "√", 712 /** 713 * ✗ 714 */ 715 ITALIC_X : "✗", 716 /** 717 * ⁿ 718 */ 719 SUPER_N: "ⁿ", 720 /** 721 * ² 722 */ 723 SQUARED: "²", 724 /** 725 * ³ 726 */ 727 CUBED : "³", 728 /** 729 * ■ 730 */ 731 SOLID_BOX: "■", 732 /** 733 * ‰ 734 */ 735 PERMILE : "‰", 736 /** 737 * ® 738 */ 739 REGISTERED_TM : "®", 740 /** 741 * © 742 */ 743 COPYRIGHT : "©", 744 /** 745 * ™ 746 */ 747 TRADEMARK : "™", 748 749 /** 750 * β 751 */ 752 BETA: "β", 753 /** 754 * γ 755 */ 756 GAMMA: "γ", 757 /** 758 * ζ 759 */ 760 ZETA: "ζ", 761 /** 762 * η 763 */ 764 ETA: "η", 765 /** 766 * ι 767 */ 768 IOTA: "ι", 769 /** 770 * κ 771 */ 772 KAPPA: "κ", 773 /** 774 * λ 775 */ 776 LAMBDA: "λ", 777 /** 778 * ν 779 */ 780 NU: "ν", 781 /** 782 * ξ 783 */ 784 XI: "ξ", 785 /** 786 * ο 787 */ 788 OMICRON: "ο", 789 /** 790 * ρ 791 */ 792 RHO: "ρ", 793 /** 794 * υ 795 */ 796 UPSILON: "υ", 797 /** 798 * φ 799 */ 800 CHI_LOWER: "φ", 801 /** 802 * χ 803 */ 804 CHI_UPPER: "χ", 805 /** 806 * ψ 807 */ 808 PSI : "ψ", 809 /** 810 * α 811 */ 812 ALPHA: "α", 813 /** 814 * ß 815 */ 816 ESZETT: "ß", 817 /** 818 * π 819 */ 820 PI: "π", 821 /** 822 * Σ 823 */ 824 SIGMA_UPPER: "Σ", 825 /** 826 * σ 827 */ 828 SIGMA_LOWER: "σ", 829 /** 830 * µ 831 */ 832 MU: "µ", 833 /** 834 * τ 835 */ 836 TAU: "τ", 837 /** 838 * Θ 839 */ 840 THETA: "Θ", 841 /** 842 * Ω 843 */ 844 OMEGA: "Ω", 845 /** 846 * δ 847 */ 848 DELTA: "δ", 849 /** 850 * φ 851 */ 852 PHI_LOWER: "φ", 853 /** 854 * ε 855 */ 856 EPSILON: "ε" 857 858 859 } 860 861 /**@namespace String utilities*/ 862 comb.string = { 863 /** 864 * Pads a string 865 * 866 * @example 867 * 868 * comb.string.pad("STR", 5, " ", true) => "STR " 869 * comb.string.pad("STR", 5, "$") => "$$STR" 870 * 871 * @param {String} string the string to pad 872 * @param {Number} length the length of the string when padded 873 * @param {String} [ch= " "] character to pad the string with 874 * @param {Boolean} [end=false] if true then the padding is added to the end 875 * 876 * @returns {String} the padded string 877 */ 878 pad : function(string, length, ch, end) { 879 string = "" + string; //check for numbers 880 ch = ch || " "; 881 var strLen = string.length; 882 while (strLen < length) { 883 if (end) { 884 string += ch; 885 } else { 886 string = ch + string; 887 } 888 strLen++; 889 } 890 return string; 891 }, 892 893 /** 894 * Truncates a string to the specified length. 895 * @example 896 * 897 * //from the beginning 898 * comb.string.truncate("abcdefg", 3) => "abc"; 899 * //from the end 900 * comb.string.truncate("abcdefg", 3,true) => "efg" 901 * //omit the length 902 * comb.string.truncate("abcdefg") => "abcdefg" 903 * 904 * @param {String} string the string to truncate 905 * @param {Number} [length = -1] the max length of the string, if the string is 906 * shorter than the length then the string is returned. 907 * @param {Boolean} [end=false] truncate starting at the end of the string 908 * 909 * @return {String} the truncated string. 910 */ 911 truncate : function(string, length, end) { 912 var ret = string; 913 if (comb.isString(ret)) { 914 if (string.length > length) { 915 if (end) { 916 var l = string.length; 917 ret = string.substring(l - length, l); 918 } else { 919 ret = string.substring(0, length); 920 } 921 } 922 } else { 923 ret = comb.string.truncate("" + ret, length); 924 } 925 return ret; 926 }, 927 928 /** 929 * Formats a string with the specified format 930 * 931 * @example 932 * 933 * var format = comb.string.format; 934 * 935 * format("%s, %s", ["Hello", "World"]) => "Hello, World"; 936 * format("%[ 10]s, %[- 10]s", ["Hello", "World"]) 937 * => " Hello, World "; 938 * format("%-!10s, %#10s, %10s and %-10s", 939 * "apple", "orange", "bananas", "watermelons") 940 * => "apple!!!!!, ####orange, bananas and watermelon" 941 * format("%+d, %+d, %10d, %-10d, %-+#10d, %10d", 942 * 1,-2, 1, 2, 3, 100000000000) 943 * => "+1, -2, 0000000001, 2000000000, +3########, 1000000000" 944 * format("%[h:mm a]D", [date]) => 7:32 PM - local - 945 * format("%[h:mm a]Z", [date]) => 12:32 PM - UTC 946 * //When using object formats they must be in an array otherwise 947 * //format will try to interpolate the properties into the string. 948 * format("%j", [{a : "b"}]) 949 * => '{"a":"b"}' 950 * format("%1j, %4j", [{a : "b"}, {a : "b"}]) 951 * => '{\n "a": "b"\n},\n{\n "a": "b"\n}' 952 * format("{hello}, {world}", {hello : "Hello", world : "World") 953 * => "Hello, World"; 954 * format({[-s10]apple}, {[%#10]orange}, {[10]banana} and {[-10]watermelons}", 955 * { 956 * apple : "apple", 957 * orange : "orange", 958 * banana : "bananas", 959 * watermelons : "watermelons" 960 * }); 961 * => applesssss, ####orange, bananas and watermelon 962 * 963 * @param {String} str the string to format, if you want to use a spacing character as padding (other than \\s) then put your format in brackets. 964 * <ol> 965 * <li>String Formats %[options]s</li> 966 * <ul> 967 * <li>- : left justified</li> 968 * <li>Char : padding character <b>Excludes d,j,s</b></li> 969 * <li>Number : width</li> 970 * </ul> 971 * </li> 972 * <li>Number Formats %[options]d</li> 973 * <ul> 974 * <li>- : left justified</li> 975 * <li>+ : signed number</li> 976 * <li>Char : padding character <b>Excludes d,j,s</b></li> 977 * <li>Number : width</li> 978 * </ul> 979 * </li> 980 * <li>Object Formats %[options]j</li> 981 * <ul> 982 * <li>Number : spacing for object properties.</li> 983 * </ul> 984 * </li> 985 * </ol> 986 * 987 * 988 * @param {Object|Array|Arguments...} obj the parameters to replace in the string 989 * if an array is passed then the array is used sequentially 990 * if an object is passed then the object keys are used 991 * if a variable number of args are passed then they are used like an array 992 * 993 * @returns {String} the formatted string 994 */ 995 format : function(str, obj) { 996 !date && (date = require("./date")); 997 if (obj instanceof Array) { 998 var i = 0, len = obj.length; 999 //find the matches 1000 return str.replace(FORMAT_REGEX, function(m, format, type) { 1001 var replacer, ret; 1002 if (i < len) { 1003 replacer = obj[i++]; 1004 } else { 1005 //we are out of things to replace with so 1006 //just return the match? 1007 return m; 1008 } 1009 if (m == "%s" || m == "%d" || m == "%D") { 1010 //fast path! 1011 ret = replacer; 1012 }else if(m == "%Z"){ 1013 ret = replacer.toUTCString(); 1014 } else if (m == "%j") { 1015 try { 1016 ret = JSON.stringify(replacer); 1017 } catch(e) { 1018 throw new Error("comb.string.format : Unable to parse json from ", replacer); 1019 } 1020 } else { 1021 format = format.replace(/^\[|\]$/g, ""); 1022 switch (type) { 1023 case "s": 1024 ret = formatString(replacer, format); 1025 break; 1026 case "d": 1027 ret = formatNumber(replacer, format); 1028 break; 1029 case "j": 1030 ret = formatObject(replacer, format); 1031 break; 1032 case "D": 1033 ret = date.date.format(replacer, format); 1034 break; 1035 case "Z": 1036 ret = date.date.format(replacer, format, true); 1037 break; 1038 } 1039 } 1040 return ret; 1041 }); 1042 } else if (typeof obj == "object") { 1043 return str.replace(INTERP_REGEX, function(m, format, value) { 1044 value = obj[value]; 1045 if (value) { 1046 if (format) { 1047 if (comb.isString(value)) { 1048 return formatString(value, format); 1049 } else if (typeof value == "number") { 1050 return formatNumber(value, format); 1051 } else if (date.isDate(value)) { 1052 return date.date.format(value, format); 1053 } else if (typeof value == "object") { 1054 return formatObject(value, format); 1055 } 1056 } else { 1057 return "" + value; 1058 } 1059 } 1060 return m; 1061 }); 1062 } else { 1063 var args = Array.prototype.slice.call(arguments).slice(1); 1064 return exports.string.format(str, args); 1065 } 1066 }, 1067 1068 /** 1069 * Converts a string to an array 1070 * 1071 * @example 1072 * 1073 * comb.string.toArray("a|b|c|d", "|") => ["a","b","c","d"] 1074 * comb.string.toArray("a", "|") => ["a"] 1075 * comb.string.toArray("", "|") => [] 1076 * 1077 * @param {String} str the string to parse 1078 * @param {String} delimeter the delimeter to use 1079 */ 1080 toArray : function(testStr, delim) { 1081 var ret = []; 1082 if (testStr) { 1083 if (testStr.indexOf(delim) > 0) return testStr.replace(/\s+/g, "").split(delim); 1084 else return [testStr]; 1085 } 1086 return ret; 1087 }, 1088 1089 /** 1090 * Returns a string duplicated n times; 1091 * 1092 * @example 1093 * 1094 * comb.string.multiply("HELLO", 5) => "HELLOHELLOHELLOHELLOHELLO" 1095 * 1096 * 1097 */ 1098 multiply : function(str, times) { 1099 var ret = []; 1100 if (times) { 1101 for (var i = 0; i < times; i++) { 1102 ret.push(str); 1103 } 1104 } 1105 return ret.join(""); 1106 }, 1107 1108 /** 1109 * Styles a string according to the specified styles. 1110 * 1111 * @example 1112 * //style a string red 1113 * comb.string.style('myStr', 'red'); 1114 * //style a string red and bold 1115 * comb.string.style('myStr', ['red', bold]); 1116 * 1117 * @param {String} str The string to style. 1118 * @param {String|Array} styles the style or styles to apply to a string. 1119 * options include : 1120 * <ul> 1121 * <li>bold</li> 1122 * <li>bright</li> 1123 * <li>italic</li> 1124 * <li>underline</li> 1125 * <li>inverse</li> 1126 * <li>crossedOut</li> 1127 * <li>blink</li> 1128 * <li>red</li> 1129 * <li>green</li> 1130 * <li>yellow</li> 1131 * <li>blue</li> 1132 * <li>magenta</li> 1133 * <li>cyan</li> 1134 * <li>white</li> 1135 * <li>redBackground</li> 1136 * <li>greenBackground</li> 1137 * <li>yellowBackground</li> 1138 * <li>blueBackground</li> 1139 * <li>magentaBackground</li> 1140 * <li>cyanBackground</li> 1141 * <li>whiteBackground</li> 1142 * <li>grey</li> 1143 * <li>black</li> 1144 * 1145 * </ul> 1146 */ 1147 style : function(str, options) { 1148 var ret = str; 1149 if (options) { 1150 if (ret instanceof Array) { 1151 ret = ret.map(function(s) { 1152 return comb.string.style(s, options); 1153 }) 1154 } else if (options instanceof Array) { 1155 options.forEach(function(option) { 1156 ret = comb.string.style(ret, option); 1157 }); 1158 } else if (options in styles) { 1159 ret = '\x1B[' + styles[options] + 'm' + str + '\x1B[0m'; 1160 } 1161 } 1162 return ret; 1163 } 1164 }; 1165 1166 1167