markdown.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import { marked } from "marked"
  2. import markedCodePreview from "marked-code-preview"
  3. import { escapeHtmlAttr, slugifyString } from "../../util/index.js"
  4. export function createMarkdownRenderer(meta) {
  5. const allowHtml = meta?.opts?.markdown?.allowHtml === true
  6. return marked
  7. .use({ gfm: true })
  8. .use(markedCodePreview)
  9. .use({
  10. renderer: {
  11. html(html) {
  12. return allowHtml ? html : ""
  13. },
  14. image({ href, title, text }) {
  15. const attrs = [`alt="${escapeHtmlAttr(text)}"`]
  16. const foundSrcSet = meta.resources.images?.[slugifyString(href)]
  17. if (foundSrcSet && foundSrcSet.detail.srcSet?.length > 0) {
  18. const srcSetString = foundSrcSet.detail.srcSet
  19. .map(src => src.join(" "))
  20. .join(", ")
  21. const defaultSrc = foundSrcSet.detail.srcSet[0][0]
  22. attrs.push(`src="${escapeHtmlAttr(defaultSrc)}"`)
  23. attrs.push(`srcset="${escapeHtmlAttr(srcSetString)}"`)
  24. attrs.push("sizes=\"(min-width: 800px) 40vw, 100vw\"")
  25. attrs.push(
  26. `style=\"aspect-ratio: ${escapeHtmlAttr(foundSrcSet.detail.aspectRatio)}\"`,
  27. )
  28. } else {
  29. attrs.push(`src="${escapeHtmlAttr(href)}"`)
  30. }
  31. if (title) {
  32. attrs.push(`title="${escapeHtmlAttr(title)}"`)
  33. }
  34. return `<img ${attrs.join(" ")} >`
  35. },
  36. },
  37. })
  38. }