character-escape.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /**
  2. * @typedef {import('micromark-util-types').Construct} Construct
  3. * @typedef {import('micromark-util-types').State} State
  4. * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
  5. * @typedef {import('micromark-util-types').Tokenizer} Tokenizer
  6. */
  7. import {asciiPunctuation} from 'micromark-util-character'
  8. /** @type {Construct} */
  9. export const characterEscape = {
  10. name: 'characterEscape',
  11. tokenize: tokenizeCharacterEscape
  12. }
  13. /**
  14. * @this {TokenizeContext}
  15. * @type {Tokenizer}
  16. */
  17. function tokenizeCharacterEscape(effects, ok, nok) {
  18. return start
  19. /**
  20. * Start of character escape.
  21. *
  22. * ```markdown
  23. * > | a\*b
  24. * ^
  25. * ```
  26. *
  27. * @type {State}
  28. */
  29. function start(code) {
  30. effects.enter('characterEscape')
  31. effects.enter('escapeMarker')
  32. effects.consume(code)
  33. effects.exit('escapeMarker')
  34. return inside
  35. }
  36. /**
  37. * After `\`, at punctuation.
  38. *
  39. * ```markdown
  40. * > | a\*b
  41. * ^
  42. * ```
  43. *
  44. * @type {State}
  45. */
  46. function inside(code) {
  47. // ASCII punctuation.
  48. if (asciiPunctuation(code)) {
  49. effects.enter('characterEscapeValue')
  50. effects.consume(code)
  51. effects.exit('characterEscapeValue')
  52. effects.exit('characterEscape')
  53. return ok
  54. }
  55. return nok(code)
  56. }
  57. }