label-start-image.js 1.9 KB

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