code.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /**
  2. * @import {Info, Map, State} from 'mdast-util-to-markdown'
  3. * @import {Code, Parents} from 'mdast'
  4. */
  5. import {longestStreak} from 'longest-streak'
  6. import {formatCodeAsIndented} from '../util/format-code-as-indented.js'
  7. import {checkFence} from '../util/check-fence.js'
  8. /**
  9. * @param {Code} node
  10. * @param {Parents | undefined} _
  11. * @param {State} state
  12. * @param {Info} info
  13. * @returns {string}
  14. */
  15. export function code(node, _, state, info) {
  16. const marker = checkFence(state)
  17. const raw = node.value || ''
  18. const suffix = marker === '`' ? 'GraveAccent' : 'Tilde'
  19. if (formatCodeAsIndented(node, state)) {
  20. const exit = state.enter('codeIndented')
  21. const value = state.indentLines(raw, map)
  22. exit()
  23. return value
  24. }
  25. const tracker = state.createTracker(info)
  26. const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3))
  27. const exit = state.enter('codeFenced')
  28. let value = tracker.move(sequence)
  29. if (node.lang) {
  30. const subexit = state.enter(`codeFencedLang${suffix}`)
  31. value += tracker.move(
  32. state.safe(node.lang, {
  33. before: value,
  34. after: ' ',
  35. encode: ['`'],
  36. ...tracker.current()
  37. })
  38. )
  39. subexit()
  40. }
  41. if (node.lang && node.meta) {
  42. const subexit = state.enter(`codeFencedMeta${suffix}`)
  43. value += tracker.move(' ')
  44. value += tracker.move(
  45. state.safe(node.meta, {
  46. before: value,
  47. after: '\n',
  48. encode: ['`'],
  49. ...tracker.current()
  50. })
  51. )
  52. subexit()
  53. }
  54. value += tracker.move('\n')
  55. if (raw) {
  56. value += tracker.move(raw + '\n')
  57. }
  58. value += tracker.move(sequence)
  59. exit()
  60. return value
  61. }
  62. /** @type {Map} */
  63. function map(line, _, blank) {
  64. return (blank ? '' : ' ') + line
  65. }