blog.hangerthem.com/lib/rehype-unwrap-images.tsx

26 lines
1 KiB
TypeScript

import type { Root, Element, ElementContent } from 'hast'
import type { Plugin } from 'unified'
import { visit } from 'unist-util-visit'
function isWhitespaceText(node: ElementContent) {
return node.type === 'text' && node.value.trim() === ''
}
/**
* A rehype plugin that unwraps <img> elements from <p> tags if the <p> contains only the <img> and optional whitespace.
* For example, a paragraph like "<p><img src='image.png' alt='An image'></p>" will be transformed into "<img src='image.png' alt='An image'>".
*/
export const rehypeUnwrapImages: Plugin<[], Root> = () => (tree: Root) => {
visit(tree, 'element', (node: Element, index, parent) => {
if (node.tagName !== 'p' || !parent || typeof index !== 'number') return
const meaningfulChildren = node.children.filter((c) => !isWhitespaceText(c))
if (
meaningfulChildren.length === 1 &&
meaningfulChildren[0].type === 'element' &&
meaningfulChildren[0].tagName === 'img'
) {
parent.children[index] = meaningfulChildren[0]
}
})
}