label-start-image.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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 {labelEnd} from './label-end.js'
  8. /** @type {Construct} */
  9. export const labelStartImage = {
  10. name: 'labelStartImage',
  11. tokenize: tokenizeLabelStartImage,
  12. resolveAll: labelEnd.resolveAll
  13. }
  14. /**
  15. * @this {TokenizeContext}
  16. * @type {Tokenizer}
  17. */
  18. function tokenizeLabelStartImage(effects, ok, nok) {
  19. const self = this
  20. return start
  21. /**
  22. * Start of label (image) start.
  23. *
  24. * ```markdown
  25. * > | a ![b] c
  26. * ^
  27. * ```
  28. *
  29. * @type {State}
  30. */
  31. function start(code) {
  32. effects.enter('labelImage')
  33. effects.enter('labelImageMarker')
  34. effects.consume(code)
  35. effects.exit('labelImageMarker')
  36. return open
  37. }
  38. /**
  39. * After `!`, at `[`.
  40. *
  41. * ```markdown
  42. * > | a ![b] c
  43. * ^
  44. * ```
  45. *
  46. * @type {State}
  47. */
  48. function open(code) {
  49. if (code === 91) {
  50. effects.enter('labelMarker')
  51. effects.consume(code)
  52. effects.exit('labelMarker')
  53. effects.exit('labelImage')
  54. return after
  55. }
  56. return nok(code)
  57. }
  58. /**
  59. * After `![`.
  60. *
  61. * ```markdown
  62. * > | a ![b] c
  63. * ^
  64. * ```
  65. *
  66. * This is needed in because, when GFM footnotes are enabled, images never
  67. * form when started with a `^`.
  68. * Instead, links form:
  69. *
  70. * ```markdown
  71. * ![^a](b)
  72. *
  73. * ![^a][b]
  74. *
  75. * [b]: c
  76. * ```
  77. *
  78. * ```html
  79. * <p>!<a href=\"b\">^a</a></p>
  80. * <p>!<a href=\"c\">^a</a></p>
  81. * ```
  82. *
  83. * @type {State}
  84. */
  85. function after(code) {
  86. // To do: use a new field to do this, this is still needed for
  87. // `micromark-extension-gfm-footnote`, but the `label-start-link`
  88. // behavior isn’t.
  89. // Hidden footnotes hook.
  90. /* c8 ignore next 3 */
  91. return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs
  92. ? nok(code)
  93. : ok(code)
  94. }
  95. }