Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add build mode in markdown-it env #2538

Closed
4 tasks done
tex0l opened this issue Jun 22, 2023 · 1 comment
Closed
4 tasks done

Add build mode in markdown-it env #2538

tex0l opened this issue Jun 22, 2023 · 1 comment
Labels
build Related to the build system enhancement New feature or request

Comments

@tex0l
Copy link

tex0l commented Jun 22, 2023

Is your feature request related to a problem? Please describe.

My issue is related to pre-building the SVGs of Mermaid diagrams upon build using mermaid-cli.

In development mode, I use the normal version of Mermaid:

// .vitepress/components/Mermaid.vue
<template>
  <div>
    <div v-if="isDark" v-html="svgDark"></div>
    <div v-else v-html="svgLight"></div>
  </div>
</template>

<script setup lang="ts">
import {ref, watch} from 'vue';
import {useData} from 'vitepress'
import {type MermaidConfig} from 'mermaid'
import mermaid from 'mermaid'

const render = async (id: string, code: string, config: MermaidConfig): Promise<string> => {
  mermaid.initialize(config)
  const {svg} = await mermaid.render(id, code)
  return svg
}

const {isDark} = useData()

const props = defineProps({
  graph: {
    type: String,
    required: true,
  },
  id: {
    type: String,
    required: true,
  },
});

const svgLight = ref<string>('');
const svgDark = ref<string>('');

const renderChart = async () => {
  console.log('rendering chart' + props.id + props.graph);
  const mermaidConfig = {
    securityLevel: 'loose',
    startOnLoad: false,
  };


  svgLight.value = await render(props.id, decodeURIComponent(props.graph), {
    ...mermaidConfig,
    theme: 'default'
  })
  svgDark.value = await render(props.id, decodeURIComponent(props.graph), {
    ...mermaidConfig,
    theme: 'dark'
  })
}

watch([() => props.graph], () => {
  renderChart()
}, {immediate: true})
</script>

And I adapted the markdown-it instance to replace the mermaid code fences with that component:

// .vitepress/config.ts
import {defineConfig} from 'vitepress'

export default defineConfig({
  // ...
  markdown: {
    config: md => {
      md.renderer.rules.fence = (tokens, index, options, env, slf) => {
        const token = tokens[index]
        if (token.info.trim() === 'mermaid') {
          const key = index
          return `
          <Suspense>
            <template #default>
              <Mermaid id="mermaid-${key}"  graph="${encodeURIComponent(token.content)}"></Mermaid>
            </template>
            <template #fallback>
              Loading...
            </template>
          </Suspense>
`
        }
      }
    }
  }
})

The code is heavily inspired by what has been done by Mermaid in their VitePress.

It works fine, but since most pages of my documentation contain a lot of graphs, I wanted to prebuild them. However, Mermaid is not compatible with SSR (mermaid-js/mermaid#3650).

Describe the solution you'd like

I would like to have access to the env mode in the Markdown-it context (in the env variable for example) so that I can conditionally add either the Mermaid component or a VPImage component with the path to the SVG I'd pre-generate in the buildEnd hook.

Describe alternatives you've considered

I tried to naively use mermaid-cli in Mermaid.vue instead of Mermaid when import.meta.env.SSR is truthy, but it fails as in SSR I apparently don't have access to Node.js modules.

I tried to use a v-if="import.meta.env.SSR" in the Mermaid component, but it gets sanitized with a work break between i and mport before being replaced by its value by Vite.

I considered spawning synchronously a node process that would generate the SVG upon parsing the markdown, but that would drastically slow down the build process.

Additional context

No response

Validations

@github-actions github-actions bot added the stale label Aug 3, 2023
@brc-dd brc-dd added enhancement New feature or request build Related to the build system and removed stale labels Aug 3, 2023
@brc-dd
Copy link
Member

brc-dd commented Aug 4, 2023

You can directly use process.env.NODE_ENV === 'production' check inside your fence function for this.

@brc-dd brc-dd closed this as completed Aug 4, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
build Related to the build system enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants