Use Edge template engine to render Dimer markdown AST
Note: This package is ESM only
The @dimerapp/edge allows you to render the @dimerapp/markdown AST using Edge templates.
By using Edge as the rendering layer for Markdown, you can capture any AST node and render them using components.
Install the package from the npm registry as follows:
npm i @dimerapp/edge
# yarn
yarn add @dimerapp/edgeThis package has a peer dependency on @dimerapp/markdown. So make sure to install it as well.
npm i @dimerapp/markdown
# yarn
yarn add @dimerapp/markdownImport the dimer function and register it as the edge plugin. The function registers the neccessary helpers and in-memory templates to render the markdown AST.
import { Edge } from 'edge.js'
import { fileURLToPath } from 'node:url'
import { dimer, RenderingPipeline } from '@dimerapp/edge'
const viewsPath = fileURLToPath(new URL('./views', import.meta.url))
const edge = new Edge()
edge.mount(viewsPath)
edge.use(dimer)
const pipeline = new RenderingPipeline()
await edge.render('guide.edge', {
file: md,
pipeline
})Next, create the guide.edge file and paste the following markup inside it.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
@!component('dimer_contents', { nodes: file.ast.children, pipeline })~
</body>
</html>That's all you need to do.
The benefit of generating the AST and then using a template engine to render its nodes comes in the form of flexbility.
In the following example, we capture the node with the tagName of pre and render it using the elements/pre.edge file. The second element inside the array is the props for edge component. You can name them as you like.
import { hasClass } from '@dimerapp/edge/utils'
import { RenderingPipeline } from '@dimerapp/edge'
const pipeline = new RenderingPipeline()
pipeline.use((node) => {
if (node.tagName === 'pre') {
return pipeline.component('elements/pre', { node })
}
})Inside the edge file we wrap the pre tag inside a custom div and create a Copy to clipboard button to copy the contents of the codeblock to the clipboard.
Also, we are using Alpine.js to implement the frontend. For this example, you can pull in Alpine from the CDN.
<script src="//unpkg.com/alpinejs" defer></script><div x-data="{
copy() {
navigator.clipboard.writeText($root.querySelector('code').textContent)
}
}">
<button @click="copy"> Copy to clipboard </button>
@!component('dimer_element', { node, pipeline })~
</div>