| 1 | import { whitespace } from 'hast-util-whitespace' |
| 2 | import { visit } from 'unist-util-visit' |
| 3 | |
| 4 | // Based on remark-unwrap-images |
| 5 | // https://github.com/remarkjs/remark-unwrap-images/blob/main/index.js |
| 6 | const applicable = (node, inLink = false): string | false | null => { |
| 7 | const { children } = node |
| 8 | const { length } = children |
| 9 | |
| 10 | let image: string | false | null = null |
| 11 | let index = -1 |
| 12 | |
| 13 | while (++index < length) { |
| 14 | const child = children[index] |
| 15 | |
| 16 | if (whitespace(child)) { |
| 17 | // No ops |
| 18 | } else if (child.type === 'image' && typeof child.title === 'string') { |
| 19 | image = child.title.trim() |
| 20 | child.title = image || null |
| 21 | } else if ( |
| 22 | !inLink && |
| 23 | (child.type === 'link' || child.type === 'linkReference') |
| 24 | ) { |
| 25 | const linkResult = applicable(child, true) |
| 26 | |
| 27 | if (linkResult === false) return false |
| 28 | if (typeof linkResult === 'string') image = linkResult |
| 29 | } else { |
| 30 | return false |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | return image |
| 35 | } |
| 36 | |
| 37 | // Transform wrapping paragraph for images with title to <figure>. |
| 38 | export const imageParagraphToFigure = () => (tree) => { |
| 39 | visit(tree, 'paragraph', (node) => { |
| 40 | const figureCaption = applicable(node) |
| 41 | |
| 42 | if (typeof figureCaption === 'string') { |
| 43 | node.data = node.data ?? {} |
| 44 | node.data.hName = 'figure' |
| 45 | |
| 46 | if (figureCaption.trim()) { |
| 47 | ;(node.children as any[]).push({ |
| 48 | type: 'strong', |
| 49 | data: { hName: 'figcaption' }, |
| 50 | children: [{ type: 'text', value: figureCaption }], |
| 51 | }) |
| 52 | } |
| 53 | } |
| 54 | }) |
| 55 | } |
| 56 |