mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-15 14:29:25 +02:00
Address review comments
Support ctrl+enter Support mermaid-nocode Use `contenteditable="plaintext-only"` Co-authored-by: Alois Klink <alois@aloisklink.com>
This commit is contained in:
@@ -252,11 +252,12 @@ export function transformMarkdownAst({
|
||||
node.lang = MERMAID_KEYWORD;
|
||||
return [node];
|
||||
} else if (MERMAID_EXAMPLE_KEYWORDS.includes(node.lang)) {
|
||||
// Return 2 nodes:
|
||||
// If Vitepress, return only the original node with the language now set to 'mermaid-example' (will be rendered using custom renderer)
|
||||
// Else Return 2 nodes:
|
||||
// 1. the original node with the language now set to 'mermaid-example' (will be rendered as code), and
|
||||
// 2. a copy of the original node with the language set to 'mermaid' (will be rendered as a diagram)
|
||||
node.lang = MERMAID_CODE_ONLY_KEYWORD;
|
||||
return [node, Object.assign({}, node, { lang: MERMAID_KEYWORD })];
|
||||
return vitepress ? [node] : [node, Object.assign({}, node, { lang: MERMAID_KEYWORD })];
|
||||
}
|
||||
|
||||
// Transform these blocks into block quotes.
|
||||
|
@@ -9,22 +9,15 @@ const MermaidExample = async (md: MarkdownRenderer) => {
|
||||
|
||||
md.renderer.rules.fence = (tokens, index, options, env, slf) => {
|
||||
const token = tokens[index];
|
||||
|
||||
if (token.info.trim() === 'mermaid-example') {
|
||||
if (!md.options.highlight) {
|
||||
// this function is always created by vitepress, but we need to check it
|
||||
// anyway to make TypeScript happy
|
||||
throw new Error(
|
||||
'Missing MarkdownIt highlight function (should be automatically created by vitepress'
|
||||
);
|
||||
}
|
||||
return '';
|
||||
} else if (token.info.trim() === 'mermaid') {
|
||||
const language = token.info.trim();
|
||||
if (language.startsWith('mermaid')) {
|
||||
const key = index;
|
||||
return `
|
||||
<Suspense>
|
||||
<template #default>
|
||||
<Mermaid id="mermaid-${key}" graph="${encodeURIComponent(token.content)}"></Mermaid>
|
||||
<Mermaid id="mermaid-${key}" :showCode="${
|
||||
language === 'mermaid-example'
|
||||
}" graph="${encodeURIComponent(token.content)}"></Mermaid>
|
||||
</template>
|
||||
<!-- loading state via #fallback slot -->
|
||||
<template #fallback>
|
||||
@@ -32,25 +25,18 @@ const MermaidExample = async (md: MarkdownRenderer) => {
|
||||
</template>
|
||||
</Suspense>
|
||||
`;
|
||||
}
|
||||
if (token.info.trim() === 'warning') {
|
||||
} else if (language === 'warning') {
|
||||
return `<div class="warning custom-block"><p class="custom-block-title">WARNING</p><p>${token.content}}</p></div>`;
|
||||
}
|
||||
|
||||
if (token.info.trim() === 'note') {
|
||||
} else if (language === 'note') {
|
||||
return `<div class="tip custom-block"><p class="custom-block-title">NOTE</p><p>${token.content}}</p></div>`;
|
||||
}
|
||||
|
||||
if (token.info.trim() === 'regexp') {
|
||||
} else if (language === 'regexp') {
|
||||
// shiki doesn't yet support regexp code blocks, but the javascript
|
||||
// one still makes RegExes look good
|
||||
token.info = 'javascript';
|
||||
// use trimEnd to move trailing `\n` outside if the JavaScript regex `/` block
|
||||
token.content = `/${token.content.trimEnd()}/\n`;
|
||||
return defaultRenderer(tokens, index, options, env, slf);
|
||||
}
|
||||
|
||||
if (token.info.trim() === 'jison') {
|
||||
} else if (language === 'jison') {
|
||||
return `<div class="language-">
|
||||
<button class="copy"></button>
|
||||
<span class="lang">jison</span>
|
||||
|
@@ -1,12 +1,14 @@
|
||||
<template>
|
||||
<h5>Code:</h5>
|
||||
<div class="language-mermaid">
|
||||
<button class="copy"></button>
|
||||
<span class="lang">mermaid</span>
|
||||
<pre><code contenteditable="true" @input="updateCode" @keydown.meta.enter="renderChart" ref="editableContent" class="editable-code"></code></pre>
|
||||
<div class="buttons-container">
|
||||
<span>{{ ctrlSymbol }} + Enter</span><span>|</span>
|
||||
<button @click="renderChart">Run ▶</button>
|
||||
<div v-if="props.showCode">
|
||||
<h5>Code:</h5>
|
||||
<div class="language-mermaid">
|
||||
<button class="copy"></button>
|
||||
<span class="lang">mermaid</span>
|
||||
<pre><code contenteditable="plaintext-only" @input="updateCode" @keydown.meta.enter="renderChart" @keydown.ctrl.enter="renderChart" ref="editableContent" class="editable-code"></code></pre>
|
||||
<div class="buttons-container">
|
||||
<span>{{ ctrlSymbol }} + Enter</span><span>|</span>
|
||||
<button @click="renderChart">Run ▶</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-html="svg"></div>
|
||||
@@ -25,6 +27,10 @@ const props = defineProps({
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
showCode: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
const svg = ref('');
|
||||
@@ -42,10 +48,12 @@ onMounted(async () => {
|
||||
mut = new MutationObserver(() => renderChart());
|
||||
mut.observe(document.documentElement, { attributes: true });
|
||||
|
||||
// Set the initial value of the contenteditable element
|
||||
// We cannot bind using `{{ code }}` because it will rerender the whole component
|
||||
// when the value changes, shifting the cursor when enter is used
|
||||
editableContent.value.textContent = code.value;
|
||||
if (editableContent.value) {
|
||||
// Set the initial value of the contenteditable element
|
||||
// We cannot bind using `{{ code }}` because it will rerender the whole component
|
||||
// when the value changes, shifting the cursor when enter is used
|
||||
editableContent.value.textContent = code.value;
|
||||
}
|
||||
|
||||
await renderChart();
|
||||
|
||||
|
Reference in New Issue
Block a user