flow.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /**
  2. * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct
  3. * @typedef {import('micromark-util-types').Initializer} Initializer
  4. * @typedef {import('micromark-util-types').State} State
  5. * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
  6. */
  7. import {blankLine, content} from 'micromark-core-commonmark'
  8. import {factorySpace} from 'micromark-factory-space'
  9. import {markdownLineEnding} from 'micromark-util-character'
  10. import {codes, types} from 'micromark-util-symbol'
  11. import {ok as assert} from 'devlop'
  12. /** @type {InitialConstruct} */
  13. export const flow = {tokenize: initializeFlow}
  14. /**
  15. * @this {TokenizeContext}
  16. * @type {Initializer}
  17. */
  18. function initializeFlow(effects) {
  19. const self = this
  20. const initial = effects.attempt(
  21. // Try to parse a blank line.
  22. blankLine,
  23. atBlankEnding,
  24. // Try to parse initial flow (essentially, only code).
  25. effects.attempt(
  26. this.parser.constructs.flowInitial,
  27. afterConstruct,
  28. factorySpace(
  29. effects,
  30. effects.attempt(
  31. this.parser.constructs.flow,
  32. afterConstruct,
  33. effects.attempt(content, afterConstruct)
  34. ),
  35. types.linePrefix
  36. )
  37. )
  38. )
  39. return initial
  40. /** @type {State} */
  41. function atBlankEnding(code) {
  42. assert(
  43. code === codes.eof || markdownLineEnding(code),
  44. 'expected eol or eof'
  45. )
  46. if (code === codes.eof) {
  47. effects.consume(code)
  48. return
  49. }
  50. effects.enter(types.lineEndingBlank)
  51. effects.consume(code)
  52. effects.exit(types.lineEndingBlank)
  53. self.currentConstruct = undefined
  54. return initial
  55. }
  56. /** @type {State} */
  57. function afterConstruct(code) {
  58. assert(
  59. code === codes.eof || markdownLineEnding(code),
  60. 'expected eol or eof'
  61. )
  62. if (code === codes.eof) {
  63. effects.consume(code)
  64. return
  65. }
  66. effects.enter(types.lineEnding)
  67. effects.consume(code)
  68. effects.exit(types.lineEnding)
  69. self.currentConstruct = undefined
  70. return initial
  71. }
  72. }