From 1ec826d216ac969ba2cbc01944e9efbc5c92e26b Mon Sep 17 00:00:00 2001 From: Andrew Lovett-Barron Date: Fri, 5 Jul 2024 13:00:48 +0200 Subject: [PATCH] IT WORKS --- readme.md | 2 +- src/embed.ts | 4 ++-- src/index.ts | 10 +++++++-- src/jsoncanvas.ts | 21 ++++++++++-------- src/options.ts | 8 +++++++ src/plugin.ts | 54 +++++++++++++++++++++++++++++------------------ 6 files changed, 65 insertions(+), 34 deletions(-) diff --git a/readme.md b/readme.md index 31dcc45..13ade4b 100644 --- a/readme.md +++ b/readme.md @@ -26,7 +26,7 @@ const md = await unified() .use(mdast2hast) .use(remarkGfm) .use(remarkRehype) - .use(rehypeJsonCanvas) + .use(rehypeJsonCanvas, { assetPath: "public" }) .use(compiler, production) .process(markdown); ``` diff --git a/src/embed.ts b/src/embed.ts index a754438..65f2bd9 100644 --- a/src/embed.ts +++ b/src/embed.ts @@ -6,6 +6,7 @@ import { toHast } from "mdast-util-to-hast"; import { GenericNode } from "@trbn/jsoncanvas"; // import { applyDefaults, Options } from "./options"; +import { getCanvasFromEmbed } from "./plugin"; const imagesLoaded = [] as Array; @@ -39,8 +40,7 @@ export async function drawEmbedded(svg: Element, node: GenericNode | any) { export async function drawMarkdownEmbed(svg: Element, node: GenericNode | any) { if (node.type === "file" && svg) { if (node.file.match(/\.(md|mdx)$/i)) { - const resp = await fetch(node.file); - const mdFile = await resp.text(); + const mdFile = await getCanvasFromEmbed(node.file); const mdast = fromMarkdown(mdFile); const hast = toHast(mdast); diff --git a/src/index.ts b/src/index.ts index f31e4ff..6b3c677 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,12 @@ import { rehypeJsonCanvas } from "./plugin"; -// export { Options } from "./options"; -export { rehypeJsonCanvas }; +export type { Options } from "./options"; +export { rehypeJsonCanvas }; export default rehypeJsonCanvas; + +// CommonJS default export hack +/* eslint-env commonjs */ +// if (typeof module === "object" && typeof module.exports === "object") { +// module.exports = Object.assign(module.exports.default, module.exports); +// } diff --git a/src/jsoncanvas.ts b/src/jsoncanvas.ts index 5c1a151..430a64d 100644 --- a/src/jsoncanvas.ts +++ b/src/jsoncanvas.ts @@ -35,7 +35,7 @@ export function validate(jsonCanvasData: JSONCanvas) { export function render( jsc: JSONCanvas, config?: Partial -): String | any | null { +): Element | null { const options = applyDefaults(config); const { canvasWidth, canvasHeight, offsetX, offsetY } = @@ -62,10 +62,10 @@ export function render( return checkImagesLoaded(() => renderToBuffer(svg)); } -function renderToBuffer(svg: Element, config?: Partial) { +function renderToBuffer(svg: Element, config?: Partial): Element { const options = applyDefaults(config); console.log("Rendering", svg, options); - return null; + return svg; } function initRender( @@ -89,9 +89,12 @@ function initRender( const props = { ...BASE_SVG_PROPS, - width: width as number, - height: height as number, + width: "100%", + height: "100%", + renWidth: width as number, + renHeight: height as number, viewBox: `0 0 ${width} ${height}`, + preserveAspectRatio: "none", }; const svg = s("svg", props); @@ -132,8 +135,8 @@ async function drawNode( const group = s("g"); const rect = s("rect", { - x: node.x + svg.properties!.width / 2, - y: node.y + svg.properties!.height / 2, + x: node.x + svg.properties!.renWidth / 2, + y: node.y + svg.properties!.renHeight / 2, width: node.width, height: node.height, rx: 5, @@ -178,8 +181,8 @@ function drawEdge( const options = applyDefaults(config); if (svg === null || svg == undefined) return; - const cWidth = svg.properties.width || (1 as number); - const cHeight = svg.properties.height || (1 as number); + const cWidth = svg.properties.renWidth || (1 as number); + const cHeight = svg.properties.renHeight || (1 as number); if (fromNode && toNode) { let startX = diff --git a/src/options.ts b/src/options.ts index d535494..4b57679 100644 --- a/src/options.ts +++ b/src/options.ts @@ -9,6 +9,13 @@ export interface Options { */ openEmbededInNewTab: boolean; + /** + * Define an asset path where the .canvas files exists. This will add the asset path before the filename. Otherwise uses cwd.process() path + filename + * + * Defaults to null + */ + assetPath: string | null; + /** * Render mode. Determines the canvas output mode * @@ -47,6 +54,7 @@ export function applyDefaults(config: Partial = {}): Options { config.openEmbededInNewTab === undefined ? true : config.openEmbededInNewTab, + assetPath: config.assetPath === undefined ? "public" : config.assetPath, renderMode: config.renderMode === undefined ? "canvas" : config.renderMode, canvasBuffer: config.canvasBuffer === undefined ? 30 : config.canvasBuffer, nodeStrokeWidth: diff --git a/src/plugin.ts b/src/plugin.ts index 95277c0..76e730a 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,11 +1,14 @@ +import path from "path"; +import fs from "fs"; import type { Plugin } from "unified"; -import type { Element, ElementContent, Root } from "hast"; -import { fromHtmlIsomorphic } from "hast-util-from-html-isomorphic"; +import type { Element, Root } from "hast"; +// import { fromHtmlIsomorphic } from "hast-util-from-html-isomorphic"; import { visit } from "unist-util-visit"; -import fs from "fs"; import { validate, render } from "./jsoncanvas"; import JSONCanvas from "@trbn/jsoncanvas"; +import { h } from "hastscript"; +import { applyDefaults, Options } from "./options"; /* Let's think this through. @@ -46,10 +49,8 @@ export const rehypeJsonCanvas: Plugin<[], Root> = () => { for (const node of nodesToReplace) { const canvasPath = node.properties.src as string; - console.log("Detected", canvasPath); let canvasMarkdown = await getCanvasFromEmbed(canvasPath); - console.log("Got markdown", canvasMarkdown); const jsonCanvasFromString = JSONCanvas.fromString(canvasMarkdown); let canvas; @@ -57,40 +58,53 @@ export const rehypeJsonCanvas: Plugin<[], Root> = () => { if (validate(jsonCanvasFromString)) { canvas = render(jsonCanvasFromString, {}); } else { - canvas = "
Not a properly formatted JsonCanvas
"; + canvas = h("div", "
Not a properly formatted JsonCanvas
"); } console.log(canvas); - const canvasHast = fromHtmlIsomorphic( - ``, - { - fragment: true, - } - ); + // const canvasHast = fromHtmlIsomorphic( + // ``, + // { + // fragment: true, + // } + // ); node.properties = { ...node.properties, }; node.tagName = "div"; - node.children = canvasHast.children as ElementContent[]; + node.children = []; + node.children.push(canvas!); //canvasHast.children as ElementContent[]; } }; }; -async function getCanvasFromEmbed(path: string): Promise { +export async function getCanvasFromEmbed( + markdownPath: string, + config?: Partial +): Promise { + const options = applyDefaults(config); let canvasMarkdown = "Loading"; - const webcheck = path.trim().toLowerCase(); + const webcheck = markdownPath.trim().toLowerCase(); if (webcheck.startsWith("https://") || typeof window !== "undefined") { - await fetch(path) + await fetch(markdownPath) .then((res) => res.text()) .then((text) => (canvasMarkdown = text)); } else { // To accomodate ssr - canvasMarkdown = fs.readFileSync(path, { - encoding: "utf8", - flag: "r", - }); + const ssrPath = options.assetPath + ? path.join(process.cwd(), options.assetPath, markdownPath) + : path.join(process.cwd(), markdownPath); + console.log("File Path", ssrPath); + try { + canvasMarkdown = fs.readFileSync(ssrPath, { + encoding: "utf8", + flag: "r", + }); + } catch (err) { + console.log("No Canvas File Found. Try using the assetPath option!", err); + } } if (canvasMarkdown === null) return "";