import { unified } from "unified"; import type { Plugin } from "unified"; import parse from "rehype-parse"; import stringify from "rehype-stringify"; import { visit } from 'unist-util-visit' import { fromSelector } from 'hast-util-from-selector'; import { generateSizesString, generateSrcsetString } from "./srcset"; const sizes = [300, 600, 1000, 1500, 2000]; const embedSrcs = [ /'*player.vimeo.com.*/, /.*youtube.com.*/, /.*youtube-nocookie.com.*/, /.*kickstarter.com.*video.html.*/, ]; const processEmbed = (parent: any, node: any) => { const wrapper = fromSelector('div'); wrapper.children = [node]; const width = node.properties.width; const height = node.properties.height; const aspect = height / width; wrapper.properties = { class: ['fluid-width-video-wrapper'], style: `padding-top: ${aspect * 100}%` }; node.properties.height = null; node.properties.width = null; parent.children = parent.children.filter((x: any) => x != node); parent.children.unshift(wrapper); } export const postProcessor: Plugin = () => { return (tree) => { visit(tree, 'element', (node: any, i: number, parent: any) => { // Responsive if (node.tagName == 'img') { const src = node.properties.src; const srcsetString = generateSrcsetString(src); const sizesString = generateSizesString(); node.properties.srcset = srcsetString; node.properties.sizes = `${sizesString}`; } // Embeds if (node.tagName == 'iframe') { embedSrcs.forEach(x => { if (node.properties.src.match(x)) { processEmbed(parent, node); } }); } if (node.tagName == 'object' || node.tagName == 'embed') { processEmbed(parent, node); } }) } } export const processPostHtml = async (postHtml: string) => { const processor = unified() .use(parse) .use(postProcessor) .use(stringify); const result = await processor.process(postHtml); return result.toString(); }