Files
outline/server/utils/turndown/images.ts

51 lines
1.6 KiB
TypeScript

import TurndownService from "turndown";
/**
* A turndown plugin overriding inbuilt image parsing behavior
*
* @param turndownService The TurndownService instance.
*/
export default function images(turndownService: TurndownService) {
turndownService.addRule("image", {
filter(node) {
return node.nodeName === "IMG" && !node?.className.includes("emoticon");
},
replacement(content, node) {
if (!("className" in node)) {
return content;
}
const alt = cleanAttribute(node.getAttribute("alt") || "");
const src = cleanAttribute(node.getAttribute("src") || "");
const title = cleanAttribute(node.getAttribute("title") || "");
// Remove icons in issue keys as they will not resolve correctly and mess
// up the layout.
if (
node.className === "icon" &&
node.parentElement?.className.includes("jira-issue-key")
) {
return "";
}
// Respect embedded Confluence image size
let size;
const naturalWidth = node.getAttribute("data-width");
const naturalHeight = node.getAttribute("data-height");
const width = node.getAttribute("width");
if (naturalWidth && naturalHeight && width) {
const ratio = parseInt(naturalWidth) / parseInt(width);
size = ` =${width}x${parseInt(naturalHeight) / ratio}`;
}
const titlePart = title || size ? ` "${title}${size}"` : "";
return src ? `![${alt}](${src}${titlePart})` : "";
},
});
}
function cleanAttribute(attribute: string) {
return (attribute ? attribute.replace(/\n+/g, "") : "").trim();
}