content.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /**
  2. * @import {
  3. * InitialConstruct,
  4. * Initializer,
  5. * State,
  6. * TokenizeContext,
  7. * Token
  8. * } from 'micromark-util-types'
  9. */
  10. import {ok as assert} from 'devlop'
  11. import {factorySpace} from 'micromark-factory-space'
  12. import {markdownLineEnding} from 'micromark-util-character'
  13. import {codes, constants, types} from 'micromark-util-symbol'
  14. /** @type {InitialConstruct} */
  15. export const content = {tokenize: initializeContent}
  16. /**
  17. * @this {TokenizeContext}
  18. * Context.
  19. * @type {Initializer}
  20. * Content.
  21. */
  22. function initializeContent(effects) {
  23. const contentStart = effects.attempt(
  24. this.parser.constructs.contentInitial,
  25. afterContentStartConstruct,
  26. paragraphInitial
  27. )
  28. /** @type {Token} */
  29. let previous
  30. return contentStart
  31. /** @type {State} */
  32. function afterContentStartConstruct(code) {
  33. assert(
  34. code === codes.eof || markdownLineEnding(code),
  35. 'expected eol or eof'
  36. )
  37. if (code === codes.eof) {
  38. effects.consume(code)
  39. return
  40. }
  41. effects.enter(types.lineEnding)
  42. effects.consume(code)
  43. effects.exit(types.lineEnding)
  44. return factorySpace(effects, contentStart, types.linePrefix)
  45. }
  46. /** @type {State} */
  47. function paragraphInitial(code) {
  48. assert(
  49. code !== codes.eof && !markdownLineEnding(code),
  50. 'expected anything other than a line ending or EOF'
  51. )
  52. effects.enter(types.paragraph)
  53. return lineStart(code)
  54. }
  55. /** @type {State} */
  56. function lineStart(code) {
  57. const token = effects.enter(types.chunkText, {
  58. contentType: constants.contentTypeText,
  59. previous
  60. })
  61. if (previous) {
  62. previous.next = token
  63. }
  64. previous = token
  65. return data(code)
  66. }
  67. /** @type {State} */
  68. function data(code) {
  69. if (code === codes.eof) {
  70. effects.exit(types.chunkText)
  71. effects.exit(types.paragraph)
  72. effects.consume(code)
  73. return
  74. }
  75. if (markdownLineEnding(code)) {
  76. effects.consume(code)
  77. effects.exit(types.chunkText)
  78. return lineStart
  79. }
  80. // Data.
  81. effects.consume(code)
  82. return data
  83. }
  84. }