26 lines
1 KiB
TypeScript
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]
|
|
}
|
|
})
|
|
}
|