string-format.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. String.prototype.format = function string_format() {
  5. // there are two modes of operation... unnamed indices are read in order;
  6. // named indices using %(name)s. The two styles cannot be mixed.
  7. // Unnamed indices can be passed as either a single argument to this function,
  8. // multiple arguments to this function, or as a single array argument
  9. let curindex = 0;
  10. let d;
  11. if (arguments.length > 1) {
  12. d = arguments;
  13. }
  14. else
  15. d = arguments[0];
  16. function r(s, key, type) {
  17. if (type == '%')
  18. return '%';
  19. let v;
  20. if (key == "") {
  21. if (curindex == -1)
  22. throw Error("Cannot mix named and positional indices in string formatting.");
  23. if (curindex == 0 && (!(d instanceof Object) || !(0 in d))) {
  24. v = d;
  25. }
  26. else if (!(curindex in d))
  27. throw Error("Insufficient number of items in format, requesting item %i".format(curindex));
  28. else {
  29. v = d[curindex];
  30. }
  31. ++curindex;
  32. }
  33. else {
  34. key = key.slice(1, -1);
  35. if (curindex > 0)
  36. throw Error("Cannot mix named and positional indices in string formatting.");
  37. curindex = -1;
  38. if (!(key in d))
  39. throw Error("Key '%s' not present during string substitution.".format(key));
  40. v = d[key];
  41. }
  42. switch (type) {
  43. case "s":
  44. if (v === undefined)
  45. return "<undefined>";
  46. return v.toString();
  47. case "r":
  48. return uneval(v);
  49. case "i":
  50. return parseInt(v);
  51. case "f":
  52. return Number(v);
  53. default:
  54. throw Error("Unexpected format character '%s'.".format(type));
  55. }
  56. }
  57. return this.replace(/%(\([^)]+\))?(.)/g, r);
  58. };