affix-tokens.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { PatternError } from '../errors.js';
  2. export function parseAffixToken(src, pos, onError) {
  3. const char = src[pos];
  4. switch (char) {
  5. case '%':
  6. return { char: '%', style: 'percent', width: 1 };
  7. case '‰':
  8. return { char: '%', style: 'permille', width: 1 };
  9. case '¤': {
  10. let width = 1;
  11. while (src[++pos] === '¤')
  12. ++width;
  13. switch (width) {
  14. case 1:
  15. return { char, currency: 'default', width };
  16. case 2:
  17. return { char, currency: 'iso-code', width };
  18. case 3:
  19. return { char, currency: 'full-name', width };
  20. case 5:
  21. return { char, currency: 'narrow', width };
  22. default: {
  23. const msg = `Invalid number (${width}) of ¤ chars in pattern`;
  24. onError(new PatternError('¤', msg));
  25. return null;
  26. }
  27. }
  28. }
  29. case '*': {
  30. const pad = src[pos + 1];
  31. if (pad)
  32. return { char, pad, width: 2 };
  33. break;
  34. }
  35. case '+':
  36. case '-':
  37. return { char, width: 1 };
  38. case "'": {
  39. let str = src[++pos];
  40. let width = 2;
  41. if (str === "'")
  42. return { char, str, width };
  43. while (true) {
  44. const next = src[++pos];
  45. ++width;
  46. if (next === undefined) {
  47. const msg = `Unterminated quoted literal in pattern: ${str}`;
  48. onError(new PatternError("'", msg));
  49. return { char, str, width };
  50. }
  51. else if (next === "'") {
  52. if (src[++pos] !== "'")
  53. return { char, str, width };
  54. else
  55. ++width;
  56. }
  57. str += next;
  58. }
  59. }
  60. }
  61. return null;
  62. }