footnote-reference.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /**
  2. * @import {Element} from 'hast'
  3. * @import {FootnoteReference} from 'mdast'
  4. * @import {State} from '../state.js'
  5. */
  6. import {normalizeUri} from 'micromark-util-sanitize-uri'
  7. /**
  8. * Turn an mdast `footnoteReference` node into hast.
  9. *
  10. * @param {State} state
  11. * Info passed around.
  12. * @param {FootnoteReference} node
  13. * mdast node.
  14. * @returns {Element}
  15. * hast node.
  16. */
  17. export function footnoteReference(state, node) {
  18. const clobberPrefix =
  19. typeof state.options.clobberPrefix === 'string'
  20. ? state.options.clobberPrefix
  21. : 'user-content-'
  22. const id = String(node.identifier).toUpperCase()
  23. const safeId = normalizeUri(id.toLowerCase())
  24. const index = state.footnoteOrder.indexOf(id)
  25. /** @type {number} */
  26. let counter
  27. let reuseCounter = state.footnoteCounts.get(id)
  28. if (reuseCounter === undefined) {
  29. reuseCounter = 0
  30. state.footnoteOrder.push(id)
  31. counter = state.footnoteOrder.length
  32. } else {
  33. counter = index + 1
  34. }
  35. reuseCounter += 1
  36. state.footnoteCounts.set(id, reuseCounter)
  37. /** @type {Element} */
  38. const link = {
  39. type: 'element',
  40. tagName: 'a',
  41. properties: {
  42. href: '#' + clobberPrefix + 'fn-' + safeId,
  43. id:
  44. clobberPrefix +
  45. 'fnref-' +
  46. safeId +
  47. (reuseCounter > 1 ? '-' + reuseCounter : ''),
  48. dataFootnoteRef: true,
  49. ariaDescribedBy: ['footnote-label']
  50. },
  51. children: [{type: 'text', value: String(counter)}]
  52. }
  53. state.patch(node, link)
  54. /** @type {Element} */
  55. const sup = {
  56. type: 'element',
  57. tagName: 'sup',
  58. properties: {},
  59. children: [link]
  60. }
  61. state.patch(node, sup)
  62. return state.applyData(node, sup)
  63. }