forked from
quillmatiq.com/augment
Fork of Chiri for Astro for my blog
1import { visit } from 'unist-util-visit'
2import { themeConfig } from '../config.ts'
3
4/**
5 * Rehype plugin that processes images in markdown content:
6 * - Wraps images with alt text in figure/figcaption elements
7 * - Adds data-preview attribute for image viewer functionality
8 * - Adds lazy loading for better performance
9 * - Handles multiple images in a single paragraph
10 */
11export default function rehypeImageProcessor() {
12 return (tree) => {
13 visit(tree, 'element', (node, index, parent) => {
14 if (node.tagName !== 'p') {
15 return
16 }
17 if (!parent || typeof index !== 'number') {
18 return
19 }
20
21 const imgNodes = []
22 let hasNonImageContent = false
23
24 for (const child of node.children) {
25 if (child.type === 'element' && child.tagName === 'img') {
26 imgNodes.push(child)
27 } else if (child.type !== 'text' || child.value.trim() !== '') {
28 hasNonImageContent = true
29 }
30 }
31
32 if (hasNonImageContent || imgNodes.length === 0) {
33 return
34 }
35
36 const newNodes = []
37
38 for (const imgNode of imgNodes) {
39 const alt = imgNode.properties?.alt?.trim()
40
41 // Enhanced image properties with performance optimizations
42 imgNode.properties = {
43 ...imgNode.properties,
44 'data-preview': themeConfig.post.imageViewer ? 'true' : 'false',
45 // Add lazy loading for better performance
46 loading: 'lazy',
47 // Add decoding hint for better performance
48 decoding: 'async',
49 // Add fetchpriority for critical images (first image gets high priority)
50 fetchpriority: newNodes.length === 0 ? 'high' : 'auto'
51 }
52
53 if (!alt || alt.includes('_')) {
54 newNodes.push(imgNode)
55 continue
56 }
57
58 const figure = {
59 type: 'element',
60 tagName: 'figure',
61 properties: {
62 className: ['image-caption-wrapper']
63 },
64 children: [
65 imgNode,
66 {
67 type: 'element',
68 tagName: 'figcaption',
69 properties: {
70 className: ['img-caption']
71 },
72 children: [
73 {
74 type: 'text',
75 value: alt
76 }
77 ]
78 }
79 ]
80 }
81
82 newNodes.push(figure)
83 }
84
85 if (newNodes.length > 0) {
86 parent.children.splice(index, 1, ...newNodes)
87 return index + newNodes.length - 1
88 }
89 })
90 }
91}