mermaid and I tried to theme it

This commit is contained in:
chyzman
2026-08-28 23:17:02 -04:00
parent 97d26dc43c
commit ab71dd4aeb
10 changed files with 142 additions and 14 deletions
+2 -1
View File
@@ -54,7 +54,8 @@
"pnpm": {
"patchedDependencies": {
"readable-stream@2.3.8": "patches/readable-stream@2.3.8.patch",
"comark@0.6.2": "patches/comark@0.6.2.patch"
"comark@0.6.2": "patches/comark@0.6.2.patch",
"beautiful-mermaid@1.1.3": "patches/beautiful-mermaid@1.1.3.patch"
},
"peerDependencyRules": {
"allowedVersions": {
+12
View File
@@ -953,6 +953,18 @@ a:not(.no-click-animation),
}
}
.mermaid {
@apply bg-surface-2 rounded-xl p-4 border border-solid border-surface-5;
margin-top: 1rem;
overflow-x: auto;
svg {
width: 100%;
max-width: 32rem;
height: auto;
}
}
code {
@apply bg-surface-3 rounded-md p-4 border border-solid border-surface-5;
padding: 0.2em 0.4em;
+1
View File
@@ -74,6 +74,7 @@
"@xterm/xterm": "^6.0.0",
"ace-builds": "^1.43.5",
"apexcharts": "^4.0.0",
"beautiful-mermaid": "^1.1.3",
"comark": "^0.6.2",
"dayjs": "^1.11.10",
"dompurify": "^3.1.7",
@@ -35,6 +35,7 @@ import { computed } from 'vue'
import MarkdownAlert, { alertMarkerTypes } from './markdown/MarkdownAlert.vue'
import MarkdownCollectionEmbed from './markdown/MarkdownCollectionEmbed.vue'
import MarkdownHighlightedPre from './markdown/MarkdownHighlightedPre.vue'
import MarkdownMermaid from './markdown/MarkdownMermaid.vue'
import MarkdownOrganizationEmbed from './markdown/MarkdownOrganizationEmbed.vue'
import MarkdownProjectEmbed from './markdown/MarkdownProjectEmbed.vue'
import MarkdownTaskCheckbox from './markdown/MarkdownTaskCheckbox.vue'
@@ -84,6 +85,7 @@ const components = computed(() =>
organization: MarkdownOrganizationEmbed,
collection: MarkdownCollectionEmbed,
input: MarkdownTaskCheckbox,
mermaid: MarkdownMermaid,
...(props.highlight ? { pre: MarkdownHighlightedPre } : {}),
},
)
@@ -0,0 +1,29 @@
<template>
<Mermaid :content="content" :theme="resolvedTheme" :theme-dark="resolvedThemeDark" />
</template>
<script setup lang="ts">
import { Mermaid } from '@comark/vue/plugins/mermaid'
import type { ThemeNames } from 'comark/plugins/mermaid'
import type { DiagramColors } from 'beautiful-mermaid'
import { computed } from 'vue'
const modrinthMermaidTheme: DiagramColors = {
bg: 'var(--surface-2)',
fg: 'var(--color-contrast)',
line: 'var(--color-secondary)',
accent: 'var(--color-brand)',
muted: 'var(--color-secondary)',
surface: 'var(--color-button-bg)',
border: 'var(--color-divider)',
}
const props = defineProps<{
content: string
theme?: ThemeNames
themeDark?: ThemeNames
}>()
const resolvedTheme = computed(() => props.theme ?? modrinthMermaidTheme)
const resolvedThemeDark = computed(() => props.themeDark ?? modrinthMermaidTheme)
</script>
+2 -1
View File
@@ -11,6 +11,7 @@ import components from 'comark/plugins/components'
import emoji from 'comark/plugins/emoji'
import footnotes from 'comark/plugins/footnotes'
import html from 'comark/plugins/html'
import mermaid from 'comark/plugins/mermaid'
import punctuation from 'comark/plugins/punctuation'
import taskList from 'comark/plugins/task-list'
import { visitAsync } from 'comark/utils'
@@ -48,7 +49,7 @@ export const modrinthPlugins: ComarkPlugin[] = [
modrinthHtmlBlock(),
// json-render()
// math(), // needs dep
// mermaid(), // needs dep
mermaid(),
punctuation(),
// rangi() // needs dep + we have highlight.js + if we do want to switch I'd say shiki is better
modrinthEmbedSyntax(),
+1
View File
@@ -93,6 +93,7 @@ export const attributeAllowlist: Record<string, string[]> = {
li: ['class'],
map: ['name'],
mark: [],
mermaid: ['content', 'theme', 'theme-dark', 'class'],
nav: [],
ol: [],
organization: ['id'],
+56
View File
@@ -0,0 +1,56 @@
diff --git a/dist/index.js b/dist/index.js
index e7e087bcb6f29d0d8f36cd558e0183bc0f162fcb..500c550c2723be4e84775afbb680dc1e06351451 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -6985,14 +6985,18 @@ function markerSuffix(color) {
function renderGroup(group, font) {
const headerHeight = FONT_SIZES.groupHeader + 16;
const parts = [];
+ const clipId = `group-clip-${group.id.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
+ parts.push(
+ `<clipPath id="${clipId}"><rect x="${group.x}" y="${group.y}" width="${group.width}" height="${group.height}" rx="8" ry="8" /></clipPath>`
+ );
parts.push(
`<g class="subgraph" data-id="${escapeAttr(group.id)}" data-label="${escapeAttr(group.label)}">`
);
parts.push(
- ` <rect x="${group.x}" y="${group.y}" width="${group.width}" height="${group.height}" rx="0" ry="0" fill="var(--_group-fill)" stroke="var(--_node-stroke)" stroke-width="${STROKE_WIDTHS.outerBox}" />`
+ ` <rect x="${group.x}" y="${group.y}" width="${group.width}" height="${group.height}" rx="8" ry="8" fill="var(--_group-fill)" stroke="var(--_node-stroke)" stroke-width="${STROKE_WIDTHS.outerBox}" />`
);
parts.push(
- ` <rect x="${group.x}" y="${group.y}" width="${group.width}" height="${headerHeight}" rx="0" ry="0" fill="var(--_group-hdr)" stroke="var(--_node-stroke)" stroke-width="${STROKE_WIDTHS.outerBox}" />`
+ ` <rect x="${group.x}" y="${group.y}" width="${group.width}" height="${headerHeight}" fill="var(--_group-hdr)" stroke="var(--_node-stroke)" stroke-width="${STROKE_WIDTHS.outerBox}" clip-path="url(#${clipId})" />`
);
parts.push(
" " + renderMultilineText(
@@ -7134,10 +7138,10 @@ function renderNodeShape(node) {
}
}
function renderRect(x, y, w, h, fill, stroke, sw) {
- return `<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="0" ry="0" fill="${fill}" stroke="${stroke}" stroke-width="${sw}" />`;
+ return `<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="6" ry="6" fill="${fill}" stroke="${stroke}" stroke-width="${sw}" />`;
}
function renderRoundedRect(x, y, w, h, fill, stroke, sw) {
- return `<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="6" ry="6" fill="${fill}" stroke="${stroke}" stroke-width="${sw}" />`;
+ return `<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="10" ry="10" fill="${fill}" stroke="${stroke}" stroke-width="${sw}" />`;
}
function renderStadium(x, y, w, h, fill, stroke, sw) {
const r2 = h / 2;
@@ -7168,7 +7172,7 @@ function renderDiamond(x, y, w, h, fill, stroke, sw) {
}
function renderSubroutine(x, y, w, h, fill, stroke, sw) {
const inset = 8;
- return `<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="0" ry="0" fill="${fill}" stroke="${stroke}" stroke-width="${sw}" />
+ return `<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="6" ry="6" fill="${fill}" stroke="${stroke}" stroke-width="${sw}" />
<line x1="${x + inset}" y1="${y}" x2="${x + inset}" y2="${y + h}" stroke="${stroke}" stroke-width="${sw}" />
<line x1="${x + w - inset}" y1="${y}" x2="${x + w - inset}" y2="${y + h}" stroke="${stroke}" stroke-width="${sw}" />`;
}
@@ -7645,7 +7649,7 @@ function renderActor(actor) {
} else {
const boxX = x - width / 2;
parts.push(
- ` <rect x="${boxX}" y="${y}" width="${width}" height="${height}" rx="4" ry="4" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="${STROKE_WIDTHS.outerBox}" />`
+ ` <rect x="${boxX}" y="${y}" width="${width}" height="${height}" rx="8" ry="8" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="${STROKE_WIDTHS.outerBox}" />`
);
parts.push(
" " + renderMultilineText(
+2 -2
View File
@@ -1,8 +1,8 @@
diff --git a/dist/internal/parse/token-processor.js b/dist/internal/parse/token-processor.js
index 440841f8d9252067681f09df935dd0287fff2cf0..71c44f24a932a1f900329800f28029206aa5a13f 100644
index 440841f8d9252067681f09df935dd0287fff2cf0..e71c6f763d8520c53d7f7d8a1e9bcdc5e29f0526 100644
--- a/dist/internal/parse/token-processor.js
+++ b/dist/internal/parse/token-processor.js
@@ -483,6 +483,20 @@ function processBlockChildren(tokens, startIndex, closeType, inlineOnly, inHeadi
@@ -483,6 +483,16 @@ function processBlockChildren(tokens, startIndex, closeType, inlineOnly, inHeadi
}
i++;
}
+35 -10
View File
@@ -5,8 +5,11 @@ settings:
excludeLinksFromLockfile: false
patchedDependencies:
beautiful-mermaid@1.1.3:
hash: 51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47
path: patches/beautiful-mermaid@1.1.3.patch
comark@0.6.2:
hash: 4e73fba3ed127a788219ec2e7a413966f48fc7695802a1b0f2694ef2686d475c
hash: c8af805d46dd2a152fda357d551ed56a0a876f61520b78ad6fe250b82afd17f8
path: patches/comark@0.6.2.patch
readable-stream@2.3.8:
hash: 3045f7adf989b4e668a4a13819b7285b0de186b79bbf22408acaf2a41c6eaa86
@@ -654,7 +657,7 @@ importers:
version: 6.39.12
'@comark/vue':
specifier: ^0.6.2
version: 0.6.2(vue@3.5.27(typescript@5.9.3))
version: 0.6.2(beautiful-mermaid@1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47))(vue@3.5.27(typescript@5.9.3))
'@intercom/messenger-js-sdk':
specifier: ^0.0.14
version: 0.0.14
@@ -709,9 +712,12 @@ importers:
apexcharts:
specifier: ^4.0.0
version: 4.7.0
beautiful-mermaid:
specifier: ^1.1.3
version: 1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47)
comark:
specifier: ^0.6.2
version: 0.6.2(patch_hash=4e73fba3ed127a788219ec2e7a413966f48fc7695802a1b0f2694ef2686d475c)
version: 0.6.2(patch_hash=c8af805d46dd2a152fda357d551ed56a0a876f61520b78ad6fe250b82afd17f8)(beautiful-mermaid@1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47))
dayjs:
specifier: ^1.11.10
version: 1.11.19
@@ -856,13 +862,13 @@ importers:
version: 6.39.12
'@comark/html':
specifier: ^0.6.2
version: 0.6.2
version: 0.6.2(beautiful-mermaid@1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47))
'@types/three':
specifier: ^0.172.0
version: 0.172.0
comark:
specifier: ^0.6.2
version: 0.6.2(patch_hash=4e73fba3ed127a788219ec2e7a413966f48fc7695802a1b0f2694ef2686d475c)
version: 0.6.2(patch_hash=c8af805d46dd2a152fda357d551ed56a0a876f61520b78ad6fe250b82afd17f8)(beautiful-mermaid@1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47))
dayjs:
specifier: ^1.11.10
version: 1.11.19
@@ -5571,6 +5577,9 @@ packages:
bcp-47@2.1.0:
resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==}
beautiful-mermaid@1.1.3:
resolution: {integrity: sha512-TItrtrAyHp1vwFfFVYauWGrquouk/6SS21Aq3RsxindSYZODcN4xYrPZD6BiZRU+o5mKJzDPz9MUSMvELdylyg==}
binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
@@ -6242,6 +6251,9 @@ packages:
electron-to-chromium@1.5.286:
resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==}
elkjs@0.11.1:
resolution: {integrity: sha512-zxxR9k+rx5ktMwT/FwyLdPCrq7xN6e4VGGHH8hA01vVYKjTFik7nHOxBnAYtrgYUB1RpAiLvA1/U2YraWxyKKg==}
emmet@2.4.11:
resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==}
@@ -11308,16 +11320,20 @@ snapshots:
style-mod: 4.1.3
w3c-keyname: 2.2.8
'@comark/html@0.6.2':
'@comark/html@0.6.2(beautiful-mermaid@1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47))':
dependencies:
comark: 0.6.2(patch_hash=4e73fba3ed127a788219ec2e7a413966f48fc7695802a1b0f2694ef2686d475c)
comark: 0.6.2(patch_hash=c8af805d46dd2a152fda357d551ed56a0a876f61520b78ad6fe250b82afd17f8)(beautiful-mermaid@1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47))
optionalDependencies:
beautiful-mermaid: 1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47)
transitivePeerDependencies:
- rangi
'@comark/vue@0.6.2(vue@3.5.27(typescript@5.9.3))':
'@comark/vue@0.6.2(beautiful-mermaid@1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47))(vue@3.5.27(typescript@5.9.3))':
dependencies:
comark: 0.6.2(patch_hash=4e73fba3ed127a788219ec2e7a413966f48fc7695802a1b0f2694ef2686d475c)
comark: 0.6.2(patch_hash=c8af805d46dd2a152fda357d551ed56a0a876f61520b78ad6fe250b82afd17f8)(beautiful-mermaid@1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47))
vue: 3.5.27(typescript@5.9.3)
optionalDependencies:
beautiful-mermaid: 1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47)
transitivePeerDependencies:
- rangi
@@ -15692,6 +15708,11 @@ snapshots:
is-alphanumerical: 2.0.1
is-decimal: 2.0.1
beautiful-mermaid@1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47):
dependencies:
elkjs: 0.11.1
entities: 7.0.1
binary-extensions@2.3.0: {}
bindings@1.5.0:
@@ -15951,12 +15972,14 @@ snapshots:
colord@2.9.3: {}
comark@0.6.2(patch_hash=4e73fba3ed127a788219ec2e7a413966f48fc7695802a1b0f2694ef2686d475c):
comark@0.6.2(patch_hash=c8af805d46dd2a152fda357d551ed56a0a876f61520b78ad6fe250b82afd17f8)(beautiful-mermaid@1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47)):
dependencies:
entities: 8.0.0
htmlparser2: 12.0.0
js-yaml: 5.3.0
markdown-exit: 1.1.0-beta.2
optionalDependencies:
beautiful-mermaid: 1.1.3(patch_hash=51834efb99f2945be29ce3a3cbc45a3b9ff4cde6ca80ba6d2c22e85d9b9cbd47)
combined-stream@1.0.8:
dependencies:
@@ -16323,6 +16346,8 @@ snapshots:
electron-to-chromium@1.5.286: {}
elkjs@0.11.1: {}
emmet@2.4.11:
dependencies:
'@emmetio/abbreviation': 2.3.3