andrewlb notes

rehype-jsoncanvas

rehype-jsoncanvas

This project is currently in active development/prove of concept stage and has a number of limitations. But feel free to fork, PR, or add issues if you have requests and I will respond quickly.

View on Github
View on NPM

Read a writeup about building it here building-for-an-ecosystem

What does this do?

A rehype plugin that renders a json-canvas element, probably downstream from a markdown file.

TODO List

  • Refine the SVG generation to be cleaner and reflect Obsidian's rendering itself (eg. fix that fromLeft/right edge)
  • Styling options/CSS
  • Adding tests and json-canvas spec validation
  • Cleaning up logging and error messages
  • Regex replace for embed paths in canvas (useful if you're using enveloppe to publish)
  • Hopefully get it working client side (to work with this project)

Here's a look at where rehype sits unifiedjs-ecosystem.canvas

Install and Use

npm i rehype-jsoncanvas

And then import it

import rehypeJsonCanvas from "rehype-jsoncanvas"

Then use it however you use rehype plugins. Please note, it will not work with react-markdown as that component doesn't currently support async rehype plugins.

This is an example of using Unified to render out the base.md markdown. Basically you need to process the markdown first, then transform the markdown rehype. The plugin will then look for rendered images with a .canvas extension to render out the jsonCanvas.

async function renderMarkdown(markdown: string) {

const md = await unified()
.use(parser)
.use(mdast2hast)
.use(remarkGfm)
.use(remarkRehype)
.use(rehypeRaw)
.use(rehypePrism)
.use(rehypeJsonCanvas, { ssrPath: "public", mdPath: "_content" })
.use(rehypeStringify)
.process(markdown);

return md;
}

const markdown = await renderMarkdown(content);
const rendered = (await markdown.value) as string;

and pull that rendered markdown into your dom somehow

<div
className={markdownStyles["markdown"]}
dangerouslySetInnerHTML={{ __html: rendered }}
/>

See base.md for an examples. A simple nextjs app lives in this repo to see how it might be used (rehype-jsoncanvas-ssr), though the react app doesn't currently work.

Options

The options file has everything, but I'll just share the used ones currently. Please note that these are likely to change before I hit v1.0. They currently define the path broadly, and an overview might look like this:

  • Grab a file via filesync: ProjectDirectory/ssrPath/assetpath/filename.extension
  • Grab a file via fetch: url/assetpath/filename.extension
  • Read a mdfile ssr NOT stored in static directory: ProjectDirectory/mdPath/filename.md

There's definitely a better way to do this but...

options.ssrPath

Takes a string and defaults to 'public' from the nextjs ecosystem. This defines where any static files are stored within the relative project directory.

options.assetPath

Takes a string or null, and if the .canvas and image files lives somewhere underneath the SSR path. Think of this as the relative path within your static folder as the top level directory. This is used when embedding images within the svg.

options.mdPath

Path to markdown files relative to project directory. Assuming you don't store the markdown directory in your static folder.

options.nodeStrokeWidth

Defines the stroke width of node box borders

options.lineStrokeWidth

Defines the stroke width of lines between nodes.

options.openEmbededInNewTab

Currently doesn't do anything. Will basically define whether clicking on an embedded image or markdown file will open as a new tab.

References along the way