parse-precision-blueprint.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { BadOptionError, TooManyOptionsError } from '../errors.js';
  2. function parseBlueprintDigits(src, style) {
  3. const re = style === 'fraction' ? /^\.(0*)(\+|#*)$/ : /^(@+)(\+|#*)$/;
  4. const match = src && src.match(re);
  5. if (match) {
  6. const min = match[1].length;
  7. switch (match[2].charAt(0)) {
  8. case '':
  9. return { min, max: min };
  10. case '+':
  11. return { min, max: null };
  12. case '#': {
  13. return { min, max: min + match[2].length };
  14. }
  15. }
  16. }
  17. return null;
  18. }
  19. export function parsePrecisionBlueprint(stem, options, onError) {
  20. const fd = parseBlueprintDigits(stem, 'fraction');
  21. if (fd) {
  22. if (options.length > 1)
  23. onError(new TooManyOptionsError(stem, options, 1));
  24. const res = {
  25. style: 'precision-fraction',
  26. source: stem,
  27. minFraction: fd.min
  28. };
  29. if (fd.max != null)
  30. res.maxFraction = fd.max;
  31. const option = options[0];
  32. const sd = parseBlueprintDigits(option, 'significant');
  33. if (sd) {
  34. res.source = `${stem}/${option}`;
  35. res.minSignificant = sd.min;
  36. if (sd.max != null)
  37. res.maxSignificant = sd.max;
  38. }
  39. else if (option)
  40. onError(new BadOptionError(stem, option));
  41. return res;
  42. }
  43. const sd = parseBlueprintDigits(stem, 'significant');
  44. if (sd) {
  45. for (const opt of options)
  46. onError(new BadOptionError(stem, opt));
  47. const res = {
  48. style: 'precision-fraction',
  49. source: stem,
  50. minSignificant: sd.min
  51. };
  52. if (sd.max != null)
  53. res.maxSignificant = sd.max;
  54. return res;
  55. }
  56. return null;
  57. }