option-parser.ts 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import type { ParseRangeResult } from '../interfaces/option-parser';
  2. /**
  3. * Options parser for custom tag
  4. */
  5. export const OptionParser = {
  6. /**
  7. * Parse range expression
  8. *
  9. * <ul>
  10. * <li>ex:</li>
  11. * <ul>
  12. * <li>1:2 -> { start: 1, end: 2 }</li>
  13. * <li>1: -> { start: 1, end: -1 }</li>
  14. * <li>2+3 -> { start: 1, end: 5 }</li>
  15. * </ul>
  16. * </ul>
  17. *
  18. * @see https://regex101.com/r/w4KCwC/4
  19. *
  20. * @static
  21. * @param {string} str
  22. * @returns {ParseRangeResult}
  23. */
  24. parseRange(str: string): ParseRangeResult | null {
  25. if (str == null) {
  26. return null;
  27. }
  28. // see: https://regex101.com/r/w4KCwC/4
  29. const match = str.match(/^(-?[0-9]+)(([:+]{1})(-?[0-9]+)?)?$/);
  30. if (!match) {
  31. return null;
  32. }
  33. // determine start
  34. let start: number;
  35. let end = -1;
  36. // has operator
  37. if (match[3] != null) {
  38. start = +match[1];
  39. const operator = match[3];
  40. // determine end
  41. if (operator === ':') {
  42. end = +match[4] || -1; // set last(-1) if undefined
  43. } else if (operator === '+') {
  44. end = +match[4] || 0; // plus zero if undefined
  45. end += start;
  46. }
  47. }
  48. // don't have operator
  49. else {
  50. start = 1;
  51. end = +match[1];
  52. }
  53. return { start, end };
  54. },
  55. };