mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-07 17:46:44 +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;
|
node.lang = MERMAID_KEYWORD;
|
||||||
return [node];
|
return [node];
|
||||||
} else if (MERMAID_EXAMPLE_KEYWORDS.includes(node.lang)) {
|
} 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
|
// 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)
|
// 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;
|
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.
|
// Transform these blocks into block quotes.
|
||||||
|
@@ -9,22 +9,15 @@ const MermaidExample = async (md: MarkdownRenderer) => {
|
|||||||
|
|
||||||
md.renderer.rules.fence = (tokens, index, options, env, slf) => {
|
md.renderer.rules.fence = (tokens, index, options, env, slf) => {
|
||||||
const token = tokens[index];
|
const token = tokens[index];
|
||||||
|
const language = token.info.trim();
|
||||||
if (token.info.trim() === 'mermaid-example') {
|
if (language.startsWith('mermaid')) {
|
||||||
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 key = index;
|
const key = index;
|
||||||
return `
|
return `
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<template #default>
|
<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>
|
</template>
|
||||||
<!-- loading state via #fallback slot -->
|
<!-- loading state via #fallback slot -->
|
||||||
<template #fallback>
|
<template #fallback>
|
||||||
@@ -32,25 +25,18 @@ const MermaidExample = async (md: MarkdownRenderer) => {
|
|||||||
</template>
|
</template>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
`;
|
`;
|
||||||
}
|
} else if (language === 'warning') {
|
||||||
if (token.info.trim() === 'warning') {
|
|
||||||
return `<div class="warning custom-block"><p class="custom-block-title">WARNING</p><p>${token.content}}</p></div>`;
|
return `<div class="warning custom-block"><p class="custom-block-title">WARNING</p><p>${token.content}}</p></div>`;
|
||||||
}
|
} else if (language === 'note') {
|
||||||
|
|
||||||
if (token.info.trim() === 'note') {
|
|
||||||
return `<div class="tip custom-block"><p class="custom-block-title">NOTE</p><p>${token.content}}</p></div>`;
|
return `<div class="tip custom-block"><p class="custom-block-title">NOTE</p><p>${token.content}}</p></div>`;
|
||||||
}
|
} else if (language === 'regexp') {
|
||||||
|
|
||||||
if (token.info.trim() === 'regexp') {
|
|
||||||
// shiki doesn't yet support regexp code blocks, but the javascript
|
// shiki doesn't yet support regexp code blocks, but the javascript
|
||||||
// one still makes RegExes look good
|
// one still makes RegExes look good
|
||||||
token.info = 'javascript';
|
token.info = 'javascript';
|
||||||
// use trimEnd to move trailing `\n` outside if the JavaScript regex `/` block
|
// use trimEnd to move trailing `\n` outside if the JavaScript regex `/` block
|
||||||
token.content = `/${token.content.trimEnd()}/\n`;
|
token.content = `/${token.content.trimEnd()}/\n`;
|
||||||
return defaultRenderer(tokens, index, options, env, slf);
|
return defaultRenderer(tokens, index, options, env, slf);
|
||||||
}
|
} else if (language === 'jison') {
|
||||||
|
|
||||||
if (token.info.trim() === 'jison') {
|
|
||||||
return `<div class="language-">
|
return `<div class="language-">
|
||||||
<button class="copy"></button>
|
<button class="copy"></button>
|
||||||
<span class="lang">jison</span>
|
<span class="lang">jison</span>
|
||||||
|
@@ -1,14 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div v-if="props.showCode">
|
||||||
<h5>Code:</h5>
|
<h5>Code:</h5>
|
||||||
<div class="language-mermaid">
|
<div class="language-mermaid">
|
||||||
<button class="copy"></button>
|
<button class="copy"></button>
|
||||||
<span class="lang">mermaid</span>
|
<span class="lang">mermaid</span>
|
||||||
<pre><code contenteditable="true" @input="updateCode" @keydown.meta.enter="renderChart" ref="editableContent" class="editable-code"></code></pre>
|
<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">
|
<div class="buttons-container">
|
||||||
<span>{{ ctrlSymbol }} + Enter</span><span>|</span>
|
<span>{{ ctrlSymbol }} + Enter</span><span>|</span>
|
||||||
<button @click="renderChart">Run ▶</button>
|
<button @click="renderChart">Run ▶</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div v-html="svg"></div>
|
<div v-html="svg"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -25,6 +27,10 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
showCode: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const svg = ref('');
|
const svg = ref('');
|
||||||
@@ -42,10 +48,12 @@ onMounted(async () => {
|
|||||||
mut = new MutationObserver(() => renderChart());
|
mut = new MutationObserver(() => renderChart());
|
||||||
mut.observe(document.documentElement, { attributes: true });
|
mut.observe(document.documentElement, { attributes: true });
|
||||||
|
|
||||||
|
if (editableContent.value) {
|
||||||
// Set the initial value of the contenteditable element
|
// Set the initial value of the contenteditable element
|
||||||
// We cannot bind using `{{ code }}` because it will rerender the whole component
|
// We cannot bind using `{{ code }}` because it will rerender the whole component
|
||||||
// when the value changes, shifting the cursor when enter is used
|
// when the value changes, shifting the cursor when enter is used
|
||||||
editableContent.value.textContent = code.value;
|
editableContent.value.textContent = code.value;
|
||||||
|
}
|
||||||
|
|
||||||
await renderChart();
|
await renderChart();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user