` because the image renderer returns
+// a block element from an inline slot. Strip the `
` wrapper when the
+// paragraph contains nothing but figures (and whitespace / ), so the
+// figure-grouping step below can see contiguous runs.
+function unwrapFiguresFromParagraphs(html: string): string {
+ return html.replace(/
([\s\S]*?)<\/p>/g, (match, inner: string) => {
+ const stripped = inner.replace(/ /g, '').trim();
+ if (!stripped) return match;
+ if (/^(?:\s*[\s\S]*?<\/figure>\s*)+$/.test(stripped)) {
+ return stripped;
+ }
+ return match;
+ });
+}
+
+// Wrap runs of 2+ consecutive elements in a `.figure-row` flex
+// container. Each figure gets `flex: ` so widths divide the
+// row proportionally and the final heights match.
+function groupFigures(html: string): string {
+ return html.replace(
+ /(?:[\s\S]*?<\/figure>\s*){2,}/g,
+ (run) => {
+ const figures = run.match(/[\s\S]*?<\/figure>/g) ?? [];
+ const items = figures.map((fig) => {
+ const m = fig.match(/]*\swidth="(\d+)"[^>]*\sheight="(\d+)"/);
+ const ratio = m ? Number(m[1]) / Number(m[2]) : 1;
+ const safe = Number.isFinite(ratio) && ratio > 0 ? ratio : 1;
+ return fig.replace('', ``);
+ });
+ return `