diff --git a/src/render.ts b/src/render.ts index aab90dd..2c5be3e 100644 --- a/src/render.ts +++ b/src/render.ts @@ -1,6 +1,6 @@ import { MarkdownRenderer, MarkdownView, TFile, Component, Notice, App, FrontMatterCache, TFolder } from "obsidian"; import { TConfig } from "./modal"; -import { modifyAnchors, modifyDest, waitFor } from "./utils"; +import { copyAttributes, fixAnchors, modifyDest, waitFor } from "./utils"; export function getAllStyles() { const cssTexts: string[] = []; @@ -206,6 +206,7 @@ export async function renderMarkdown( }); if (data.includes("```dataview") || data.includes("```gEvent") || data.includes("![[")) { try { + await waitFor(() => false, 3000); await waitForDomChange(viewEl); } catch (error) { console.warn(error); @@ -217,6 +218,8 @@ export async function renderMarkdown( } } + fixCanvasToImage(viewEl); + const doc = document.implementation.createHTMLDocument("document"); doc.body.appendChild(printEl.cloneNode(true)); @@ -231,20 +234,17 @@ export async function renderMarkdown( export function fixDoc(doc: Document, title: string) { const dest = modifyDest(doc); - modifyAnchors(doc, dest, title); - modifyEmbedSpan(doc); + fixAnchors(doc, dest, title); + fixEmbedSpan(doc); } -export function modifyEmbedSpan(doc: Document) { +export function fixEmbedSpan(doc: Document) { const spans = doc.querySelectorAll("span.markdown-embed"); spans.forEach((span: HTMLElement) => { const newDiv = document.createElement("div"); - // copy attributes - Array.from(span.attributes).forEach((attr) => { - newDiv.setAttribute(attr.name, attr.value); - }); + copyAttributes(newDiv, span.attributes); newDiv.innerHTML = span.innerHTML; @@ -252,6 +252,20 @@ export function modifyEmbedSpan(doc: Document) { }); } +// TODO: base64 to canvas +// TODO: light render canvas +export function fixCanvasToImage(el: HTMLElement) { + for (const canvas of Array.from(el.querySelectorAll("canvas"))) { + const data = canvas.toDataURL(); + const img = document.createElement("img"); + img.src = data; + copyAttributes(img, canvas.attributes); + img.className = "__canvas__"; + + canvas.replaceWith(img); + } +} + export function createWebview() { const webview = document.createElement("webview"); webview.src = `app://obsidian.md/help.html`; diff --git a/src/setting.ts b/src/setting.ts index 6d734bf..4a56f1f 100644 --- a/src/setting.ts +++ b/src/setting.ts @@ -1,5 +1,6 @@ import { App, PluginSettingTab, Setting, TextAreaComponent } from "obsidian"; import BetterExportPdfPlugin from "./main"; + function setAttributes(element: HTMLTextAreaElement, attributes: { [x: string]: string }) { for (const key in attributes) { element.setAttribute(key, attributes[key]); @@ -85,8 +86,6 @@ export default class ConfigSettingTab extends PluginSettingTab { }), ); - - new Setting(containerEl).setName("Max headings level of the outline").addDropdown((dropdown) => { dropdown .addOptions(Object.fromEntries(["1", "2", "3", "4", "5", "6"].map((level) => [level, `h${level}`]))) diff --git a/src/utils.ts b/src/utils.ts index 85e9380..93a844b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -66,7 +66,7 @@ export function modifyDest(doc: Document) { return data; } -export function modifyAnchors(doc: Document, dest: Map, basename: string) { +export function fixAnchors(doc: Document, dest: Map, basename: string) { doc.querySelectorAll("a.internal-link").forEach((el: HTMLAnchorElement, i) => { const [title, anchor] = el.dataset.href?.split("#") ?? []; if (anchor?.length > 0) { @@ -128,3 +128,10 @@ export function traverseFolder(path: TFolder | TFile): TFile[] { } return arr; } + +// copy element attributes +export function copyAttributes(node: HTMLElement, attributes: NamedNodeMap) { + Array.from(attributes).forEach((attr) => { + node.setAttribute(attr.name, attr.value); + }); +}