mermaid

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2023 License: MIT Imports: 13 Imported by: 16

README

goldmark-mermaid

Introduction

Go Reference CI codecov

goldmark-mermaid is an extension for the goldmark Markdown parser that adds support for Mermaid diagrams.

Demo: A web-based demonstration of the extension is available at https://abhinav.github.io/goldmark-mermaid/demo/.

Features
  • Pluggable components
  • Supports client-side rendering by injecting JavaScript
  • Supports server-side rendering with the MermaidJS CLI or with your browser

Installation

Install the latest version of the library with Go modules.

go get go.abhg.dev/goldmark/mermaid@latest

Usage

To use goldmark-mermaid, import the mermaid package.

import "go.abhg.dev/goldmark/mermaid"

Then include the mermaid.Extender in the list of extensions you build your goldmark.Markdown with.

goldmark.New(
  goldmark.WithExtensions(
    // ...
    &mermaid.Extender{},
  ),
  // ...
).Convert(src, out)

The package supports Mermaid diagrams inside fenced code blocks with the language mermaid. For example,

```mermaid
graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;
```

When you render the Markdown as HTML, these will be rendered into diagrams.

You can also render diagrams server-side if you have a Chromium-like browser installed. See Rendering with CDP for details.

Rendering

Rendering methods

goldmark-mermaid supports two rendering modes:

  • Client-side: Diagrams are rendered in-browser by injecting MermaidJS into the generated HTML.
  • Server-side: Diagrams are rendered at the time the HTML is generated. The browser receives only the final SVGs.

You can pick between these by setting the RenderMode field.

goldmark.New(
  goldmark.WithExtensions(
    &mermaid.Extender{
      RenderMode: mermaid.RenderModeServer, // or RenderModeClient
    },
  ),
  // ...
).Convert(src, out)

A third automatic mode is provided as a convenience. It automatically picks between client-side and server-side rendering based on other configurations and system functionality. This mode is the default.

Server-side rendering

goldmark-mermaid offers two options for server-side rendering:

  • CLI-based rendering invokes the MermaidJS CLI (mmdc) on your system to render diagrams
  • CDP-based rendering uses Chrome DevTools Protocol to drive a headless browser on your system, and uses it to render diagrams
Rendering with the MermaidJS CLI

If server-side rendering is chosen, by default, the CLI-based renderer is used. You can request it explicitly by supplying a CLICompiler to mermaid.Extender or mermaid.ServerRenderer.

&mermaid.Extender{
  Compiler: &mermaid.CLICompiler{
    Theme: "neutral",
  },
}

By default, the CLICompiler will search for mmdc on your $PATH. Specify an alternative path with the CLI field:

&mermaid.CLICompiler{
  CLI: mermaid.MMDC(pathToMMDC),
}
Rendering with Chrome DevTools Protocol

If you have a Chromium-like browser installed on your system goldmark-mermaid can spin up a long-running headless process of it, and use that to render MermaidJS diagrams.

To use this, first download a minified copy of the MermaidJS source code. You can get it from https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js. Embed this into your program with go:embed.

import _ "embed" // needed for go:embed

//go:embed mermaid.min.js
var mermaidJSSource string

Next, import go.abhg.dev/goldmark/mermaid/mermaidcdp, and set up a mermaidcdp.Compiler.

compiler, err := mermaidcdp.New(&mermaidcdp.Config{
  JSSource: mermaidJSSource,
})
if err != nil {
  panic(err)
}
defer compiler.Close() // Don't forget this!

Plug this compiler into the mermaid.Extender that you install into your Goldmark Markdown object, and use the Markdown object like usual.

md := goldmark.New(
  goldmark.WithExtensions(
    // ...
    &mermaid.Extender{
      Compiler: compiler,
    },
  ),
  // ...
)

md.Convert(...)

License

This software is made available under the MIT license.

Documentation

Overview

Package mermaid adds support for Mermaid diagrams to the Goldmark Markdown parser.

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultCLI = MMDC("")

DefaultCLI is a CLI implementation that invokes the "mmdc" CLI by searching $PATH for it.

View Source
var Kind = ast.NewNodeKind("MermaidBlock")

Kind is the node kind of a Mermaid Block node.

View Source
var ScriptKind = ast.NewNodeKind("MermaidScriptBlock")

ScriptKind is the node kind of a Mermaid ScriptBlock node.

Functions

This section is empty.

Types

type Block

type Block struct {
	ast.BaseBlock
}

Block is a Mermaid block.

```mermaid
graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;
```

Its raw contents are the plain text of the Mermaid diagram.

func (*Block) Dump

func (b *Block) Dump(src []byte, level int)

Dump dumps the contents of this block to stdout.

func (*Block) IsRaw

func (*Block) IsRaw() bool

IsRaw reports that this block should be rendered as-is.

func (*Block) Kind

func (*Block) Kind() ast.NodeKind

Kind reports that this is a MermaidBlock.

type CLI

type CLI interface {
	// CommandContext builds an exec.Cmd to run the MermaidJS CLI
	// with the provided arguments.
	//
	// The list of arguments DOES NOT include 'mmdc'.
	CommandContext(context.Context, ...string) *exec.Cmd
}

CLI provides access to the MermaidJS CLI. Use it with CLICompiler to override how the "mmdc" CLI is invoked.

func MMDC

func MMDC(path string) CLI

MMDC returns a CLI implementation that invokes the "mmdc" CLI with the provided path.

If path is empty, $PATH will be searched for "mmdc".

type CLICompiler added in v0.5.0

type CLICompiler struct {
	// CLI is the MermaidJS CLI that we'll use
	// to compile Mermaid diagrams into images.
	//
	// If unset, uses DefaultCLI.
	CLI CLI

	// Theme for rendered diagrams.
	//
	// Values include "dark", "default", "forest", and "neutral".
	// See MermaidJS documentation for a full list.
	Theme string
}

CLICompiler compiles Mermaid diagrams into images by shell-executing the "mmdc" command.

Plug it into ServerRenderer to use it.

func (*CLICompiler) Compile added in v0.5.0

func (d *CLICompiler) Compile(ctx context.Context, req *CompileRequest) (_ *CompileResponse, err error)

Compile compiles the provided Mermaid diagram into an SVG.

type ClientRenderer

type ClientRenderer struct {
	// URL of Mermaid Javascript to be included in the page.
	//
	// Defaults to the latest version available on cdn.jsdelivr.net.
	MermaidURL string

	// ContainerTag is the name of the HTML tag to use for the container
	// that holds the Mermaid diagram.
	// The name must be without the angle brackets.
	//
	// Defaults to "pre".
	ContainerTag string
}

ClientRenderer renders Mermaid diagrams as HTML, to be rendered into images client side.

It operates by installing a <script> tag into the document that renders the Mermaid diagrams client-side.

func (*ClientRenderer) RegisterFuncs

func (r *ClientRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer)

RegisterFuncs registers the renderer for Mermaid blocks with the provided Goldmark Registerer.

func (*ClientRenderer) Render

func (r *ClientRenderer) Render(w util.BufWriter, src []byte, node ast.Node, entering bool) (ast.WalkStatus, error)

Render renders mermaid.Block nodes.

func (*ClientRenderer) RenderScript

func (r *ClientRenderer) RenderScript(w util.BufWriter, _ []byte, node ast.Node, entering bool) (ast.WalkStatus, error)

RenderScript renders mermaid.ScriptBlock nodes.

type CompileRequest added in v0.5.0

type CompileRequest struct {
	// Source is the raw Mermaid diagram source.
	Source string
}

CompileRequest is a request to compile a Mermaid diagram.

type CompileResponse added in v0.5.0

type CompileResponse struct {
	// SVG holds the SVG diagram text
	// including the <svg>...</svg> tags.
	SVG string
}

CompileResponse is a response from compiling a Mermaid diagram.

type Compiler added in v0.5.0

type Compiler interface {
	Compile(context.Context, *CompileRequest) (*CompileResponse, error)
}

Compiler compiles Mermaid diagrams into images. It is used with ServerRenderer to render Mermaid diagrams server-side.

type Extender

type Extender struct {
	// RenderMode specifies which renderer the Extender should install.
	//
	// Defaults to AutoRenderMode, picking renderers
	// based on the availability of the Mermaid CLI.
	RenderMode RenderMode

	// Compiler specifies how to compile Mermaid diagrams server-side.
	//
	// If specified, and render mode is not set to client-side,
	// this will be used to render diagrams.
	Compiler Compiler

	// CLI specifies how to invoke the Mermaid CLI
	// to compile Mermaid diagrams server-side.
	//
	// If specified, and render mode is not set to client-side,
	// this will be used to render diagrams.
	//
	// If both CLI and Compiler are specified, Compiler takes precedence.
	CLI CLI

	// URL of Mermaid Javascript to be included in the page
	// for client-side rendering.
	//
	// Ignored if NoScript is true or if we're rendering diagrams server-side.
	//
	// Defaults to the latest version available on cdn.jsdelivr.net.
	MermaidURL string

	// HTML tag to use for the container element for diagrams.
	//
	// Defaults to "pre" for client-side rendering,
	// and "div" for server-side rendering.
	ContainerTag string

	// If true, don't add a <script> including Mermaid to the end of the
	// page even if rendering diagrams client-side.
	//
	// Use this if the page you're including goldmark-mermaid in
	// already has a MermaidJS script included elsewhere.
	NoScript bool

	// Theme for mermaid diagrams.
	//
	// Ignored if we're rendering diagrams client-side.
	//
	// Values include "dark", "default", "forest", and "neutral".
	// See MermaidJS documentation for a full list.
	Theme string
	// contains filtered or unexported fields
}

Extender adds support for Mermaid diagrams to a Goldmark Markdown parser.

Use it by installing it to the goldmark.Markdown object upon creation.

Example
package main

import (
	"github.com/yuin/goldmark"
	"go.abhg.dev/goldmark/mermaid"
)

func main() {
	goldmark.New(
		// ...
		goldmark.WithExtensions(
			&mermaid.Extender{
				RenderMode: mermaid.RenderModeServer,
			},
			// ...
		),
	)
}
Output:

func (*Extender) Extend

func (e *Extender) Extend(md goldmark.Markdown)

Extend extends the provided Goldmark parser with support for Mermaid diagrams.

type RenderMode

type RenderMode int

RenderMode specifies which renderer the Extender should use.

const (
	// RenderModeAuto picks the renderer automatically.
	//
	// If a server-side compiler or CLI is specified,
	// or if the 'mmdc' CLI is available on $PATH,
	// this will generate diagrams server-side.
	//
	// Otherwise, it'll generate them client-side.
	RenderModeAuto RenderMode = iota

	// RenderModeClient renders Mermaid diagrams client-side
	// by adding <script> tags.
	RenderModeClient

	// RenderModeServer renders Mermaid diagrams server-side
	// using the Mermaid CLI.
	//
	// Fails rendering if the Mermaid CLI is absent.
	RenderModeServer
)

func (RenderMode) String

func (i RenderMode) String() string

type ScriptBlock

type ScriptBlock struct {
	ast.BaseBlock
}

ScriptBlock marks where the Mermaid Javascript will be included.

This is a placeholder and does not contain anything.

func (*ScriptBlock) Dump

func (b *ScriptBlock) Dump(src []byte, level int)

Dump dumps the contents of this block to stdout.

func (*ScriptBlock) IsRaw

func (*ScriptBlock) IsRaw() bool

IsRaw reports that this block should be rendered as-is.

func (*ScriptBlock) Kind

func (*ScriptBlock) Kind() ast.NodeKind

Kind reports that this is a MermaidScriptBlock.

type ServerRenderer

type ServerRenderer struct {
	// Compiler specifies how to compile Mermaid diagrams into images.
	//
	// If unspecified, this uses CLICompiler.
	Compiler Compiler

	// ContainerTag is the name of the HTML tag to use for the container
	// that holds the Mermaid diagram.
	// The name must be without the angle brackets.
	//
	// Defaults to "div".
	ContainerTag string
}

ServerRenderer renders Mermaid diagrams into images server-side.

By default, it uses CLICompiler to compile Mermaid diagrams. You can specify a different compiler with Compiler. For long-running processes, you should use the compiler provided by the mermaidcdp package.

func (*ServerRenderer) RegisterFuncs

func (r *ServerRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer)

RegisterFuncs registers the renderer for Mermaid blocks with the provided Goldmark Registerer.

func (*ServerRenderer) Render

func (r *ServerRenderer) Render(w util.BufWriter, src []byte, node ast.Node, entering bool) (ast.WalkStatus, error)

Render renders Block nodes.

type Transformer

type Transformer struct {
	// Don't add a ScriptBlock to the end of the page
	// even if the page doesn't already have one.
	NoScript bool
}

Transformer transforms a Goldmark Markdown AST with support for Mermaid diagrams. It makes the following transformations:

  • replace mermaid code blocks with mermaid.Block nodes
  • add a mermaid.ScriptBlock node if the document uses Mermaid and one does not already exist

func (*Transformer) Transform

func (t *Transformer) Transform(doc *ast.Document, reader text.Reader, _ parser.Context)

Transform transforms the provided Markdown AST.

Directories

Path Synopsis
internal
exectest
Package exectest provides a means of mocking [os/exec.Cmd]s allowing injection of arbitrary behavior into an external executable from a test.
Package exectest provides a means of mocking [os/exec.Cmd]s allowing injection of arbitrary behavior into an external executable from a test.
svgtest
Package svgtest includes helpers for validating SVGs in tests.
Package svgtest includes helpers for validating SVGs in tests.
Package mermaidcdp implements a server-side compiler for Mermaid diagrams that uses a headless Chromium-based browser to render the diagrams.
Package mermaidcdp implements a server-side compiler for Mermaid diagrams that uses a headless Chromium-based browser to render the diagrams.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL