forked from
quillmatiq.com/augment
Fork of Chiri for Astro for my blog
1import { visit } from 'unist-util-visit'
2
3/**
4 * Rehype plugin that adds copy button to code blocks for easy code copying functionality
5 */
6export default function rehypeCopyCode() {
7 return (tree) => {
8 visit(tree, 'element', (node, index, parent) => {
9 // Only process pre elements
10 if (node.tagName !== 'pre') {
11 return
12 }
13
14 // Validate pre element has children
15 if (!node.children?.length) {
16 return
17 }
18
19 // Ensure code element exists
20 const hasCodeElement = node.children.some((child) => child.tagName === 'code')
21 if (!hasCodeElement) {
22 return
23 }
24
25 // Mark the pre element with class for styling
26 node.properties = node.properties || {}
27 node.properties.className = node.properties.className || []
28 if (!node.properties.className.includes('copy-code-block')) {
29 node.properties.className.push('copy-code-block')
30 }
31
32 // Create copy button
33 const copyButton = {
34 type: 'element',
35 tagName: 'button',
36 properties: {
37 className: ['copy-button'],
38 type: 'button',
39 'aria-label': 'Copy code to clipboard'
40 },
41 children: []
42 }
43
44 // Wrap pre and button in a container for better layout control
45 const wrapper = {
46 type: 'element',
47 tagName: 'div',
48 properties: {
49 className: ['copy-code-wrapper']
50 },
51 children: [copyButton, node]
52 }
53
54 // Replace the pre element with the wrapper
55 if (parent && typeof index === 'number') {
56 parent.children[index] = wrapper
57 }
58 })
59 }
60}