Exporting Canvas to HTML (and PDF)

This is really great!!

I slightly modified the original script and set the following as a QuickAdd Macro. Now I can use it as an Obsidian command!

Also, now the exported file path is automatically copied to the clipboard.

(P.S. I tried to open the resulting HTML without saving it to a file, but had no luck…)

const DEFAULT_EXPORT_PATH = "Plugins/Canvas/export.html";

module.exports = {
    entry: async (params, settings) => {
        const {
            app,
            quickAddApi,
            obsidian: { Notice },
        } = params;

        // Get a copy of the canvas content element
        let view = app.workspace.activeLeaf.view;
        if (view.getViewType() !== "canvas") {
            new Notice("The active view is not a canvas", 5000);
        }
        let content = view.contentEl.cloneNode(true);

        // Remove the canvas background dots
        content.querySelector(".canvas-background").remove();

        // Remove the canvas UI controls
        content.querySelector(".canvas-card-menu").remove();
        content.querySelector(".canvas-controls").remove();

        // Remove the canvas node labels (image filenames)
        content.querySelectorAll(".canvas-node-label").forEach((el) => el.remove());

        // Get all the CSS, except for print styles
        // https://developer.mozilla.org/en-US/docs/Web/API/StyleSheetList#get_all_css_rules_for_the_document_using_array_methods
        let allCSS = [...document.styleSheets]
            .map((styleSheet) =>
                [...styleSheet.cssRules]
                    .map((rule) => rule.cssText)
                    .filter((cssText) => !cssText.includes("@media print")) // No print styles
                    .join("\n")
            )
            .join("\n");

        // Global regex matches app:// followed by any characters except /
        let pattern = /app:\/\/[^\/]*/g;

        // Generate HTML & CSS. Remove any app:// prefixes from URLs.
        let html = `
    <!DOCTYPE HTML>
    <html>
    <head>
    <style>
    ${allCSS}
    /* Use exact colors for card backgrounds and bullets */
    body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    </style>
    </head>
    <body class="${document.querySelector("body").className}">
    ${content.outerHTML}
    </body>
    </html>`.replaceAll(pattern, "");

        // Save html file
        let filename = settings["Export path"] ?? DEFAULT_EXPORT_PATH;
        let existingFile = app.vault.getAbstractFileByPath(filename);
        if (existingFile) {
            await app.vault.modify(existingFile, html);
        } else {
            await app.vault.create(filename, html)
        }

        await quickAddApi.utility.setClipboard(`${app.vault.adapter.basePath}/${filename}`);
        new Notice("Path copied to clipboard!", 5000);
    },
    settings: {
        name: "Export Canvas to HTML",
        author: "rrherr",
        options: {
            "Export path": {
                type: "text",
                defaultValue: DEFAULT_EXPORT_PATH,
            }
        }
    }
}
3 Likes