image.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /**
  2. * @import {Info, State} from 'mdast-util-to-markdown'
  3. * @import {Image, Parents} from 'mdast'
  4. */
  5. import {checkQuote} from '../util/check-quote.js'
  6. image.peek = imagePeek
  7. /**
  8. * @param {Image} node
  9. * @param {Parents | undefined} _
  10. * @param {State} state
  11. * @param {Info} info
  12. * @returns {string}
  13. */
  14. export function image(node, _, state, info) {
  15. const quote = checkQuote(state)
  16. const suffix = quote === '"' ? 'Quote' : 'Apostrophe'
  17. const exit = state.enter('image')
  18. let subexit = state.enter('label')
  19. const tracker = state.createTracker(info)
  20. let value = tracker.move('![')
  21. value += tracker.move(
  22. state.safe(node.alt, {before: value, after: ']', ...tracker.current()})
  23. )
  24. value += tracker.move('](')
  25. subexit()
  26. if (
  27. // If there’s no url but there is a title…
  28. (!node.url && node.title) ||
  29. // If there are control characters or whitespace.
  30. /[\0- \u007F]/.test(node.url)
  31. ) {
  32. subexit = state.enter('destinationLiteral')
  33. value += tracker.move('<')
  34. value += tracker.move(
  35. state.safe(node.url, {before: value, after: '>', ...tracker.current()})
  36. )
  37. value += tracker.move('>')
  38. } else {
  39. // No whitespace, raw is prettier.
  40. subexit = state.enter('destinationRaw')
  41. value += tracker.move(
  42. state.safe(node.url, {
  43. before: value,
  44. after: node.title ? ' ' : ')',
  45. ...tracker.current()
  46. })
  47. )
  48. }
  49. subexit()
  50. if (node.title) {
  51. subexit = state.enter(`title${suffix}`)
  52. value += tracker.move(' ' + quote)
  53. value += tracker.move(
  54. state.safe(node.title, {
  55. before: value,
  56. after: quote,
  57. ...tracker.current()
  58. })
  59. )
  60. value += tracker.move(quote)
  61. subexit()
  62. }
  63. value += tracker.move(')')
  64. exit()
  65. return value
  66. }
  67. /**
  68. * @returns {string}
  69. */
  70. function imagePeek() {
  71. return '!'
  72. }