index.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /**
  2. * @typedef {import('micromark-util-types').Effects} Effects
  3. * @typedef {import('micromark-util-types').State} State
  4. */
  5. import {factorySpace} from 'micromark-factory-space'
  6. import {markdownLineEnding, markdownSpace} from 'micromark-util-character'
  7. import {types} from 'micromark-util-symbol'
  8. /**
  9. * Parse spaces and tabs.
  10. *
  11. * There is no `nok` parameter:
  12. *
  13. * * line endings or spaces in markdown are often optional, in which case this
  14. * factory can be used and `ok` will be switched to whether spaces were found
  15. * or not
  16. * * one line ending or space can be detected with
  17. * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace`
  18. *
  19. * @param {Effects} effects
  20. * Context.
  21. * @param {State} ok
  22. * State switched to when successful.
  23. * @returns {State}
  24. * Start state.
  25. */
  26. export function factoryWhitespace(effects, ok) {
  27. /** @type {boolean} */
  28. let seen
  29. return start
  30. /** @type {State} */
  31. function start(code) {
  32. if (markdownLineEnding(code)) {
  33. effects.enter(types.lineEnding)
  34. effects.consume(code)
  35. effects.exit(types.lineEnding)
  36. seen = true
  37. return start
  38. }
  39. if (markdownSpace(code)) {
  40. return factorySpace(
  41. effects,
  42. start,
  43. seen ? types.linePrefix : types.lineSuffix
  44. )(code)
  45. }
  46. return ok(code)
  47. }
  48. }