Skip to content

Commit 79bf0bc

Browse files
Akatuorodanjoa
andauthored
Reintroduce interactive diagrams (#2388)
SVGs are normally included as images which makes them non-interactive. They can be imported and included as html, but this requires one to include them in a setup script. This PR adds a small plugin to parse md image links and include them as html: ``` ![](assets/cxl/expr.drawio.svg) <-- using an img tag ![](assets/cxl/expr.drawio.svg?raw) <-- using an svg tag (included as v-html by plugin) ``` In VSCode and Github, the rendered markdown ignores the `?raw`, so the image is still displayed when rendered and can be navigated to. The cxl diagrams now also again contain links to the sections (every element with a name now contains a link, even if it is to the same section). --------- Co-authored-by: Daniel Hutzel <daniel.hutzel@sap.com>
1 parent e0ba936 commit 79bf0bc

File tree

9 files changed

+2067
-195
lines changed

9 files changed

+2067
-195
lines changed

.vitepress/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,12 @@ if (process.env.VITE_CAPIRE_EXTRA_ASSETS) {
194194
import { dl } from '@mdit/plugin-dl'
195195
import * as MdAttrsPropagate from './lib/md-attrs-propagate'
196196
import * as MdTypedModels from './lib/md-typed-models'
197+
import * as MdDiagramSvg from './lib/md-diagram-svg'
197198

198199
config.markdown.config = md => {
199200
MdAttrsPropagate.install(md)
200201
MdTypedModels.install(md)
202+
MdDiagramSvg.install(md)
201203
md.use(dl)
202204
}
203205

.vitepress/lib/md-diagram-svg.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { MarkdownEnv, MarkdownRenderer } from 'vitepress'
2+
3+
/**
4+
* Renders SVG diagrams in markdown files as <svg> element.
5+
* This allows the diagrams to be interactive.
6+
*
7+
* To use, add `?raw` to the end of the image source, e.g. `![](diagram.svg?raw)`.
8+
*/
9+
export function install(md: MarkdownRenderer) {
10+
const defaultImage =
11+
md.renderer.rules.image ||
12+
((tokens, idx, options, env, self) => self.renderToken(tokens, idx, options))
13+
14+
md.renderer.rules.image = (tokens, idx, options, env: MarkdownEnv, self) => {
15+
const token = tokens[idx]
16+
const src = token.attrGet('src') || ''
17+
18+
if (!/\.svg\?raw$/.test(src)) {
19+
return defaultImage(tokens, idx, options, env, self)
20+
}
21+
22+
const name = 'svg_' + src.replace('?raw', '').replace(/[^a-zA-Z0-9_]/g, '_') // stable variable name for the imported SVG content
23+
const importPath = src.startsWith('/') && src.startsWith('.') ? src : './' + src
24+
25+
const sfcBlocks = env.sfcBlocks!
26+
if (!sfcBlocks.scriptSetup) {
27+
sfcBlocks.scriptSetup = {
28+
content: '<script setup>\n</script>',
29+
contentStripped: '\n',
30+
tagClose: '</script>',
31+
tagOpen: '<script setup>',
32+
type: 'script'
33+
}
34+
sfcBlocks.scripts.push(sfcBlocks.scriptSetup)
35+
}
36+
37+
const { scriptSetup } = sfcBlocks
38+
const { tagOpen, tagClose, contentStripped: rest } = scriptSetup
39+
40+
const imp = `import ${name} from "${importPath}";`
41+
42+
if (!scriptSetup.content.includes(imp)) {
43+
scriptSetup.contentStripped = `${imp}\n${rest}`
44+
scriptSetup.content = `${tagOpen}${imp}\n${rest}${tagClose}`
45+
}
46+
47+
// use v-html to render the SVG content as actual elements
48+
// with v-html, vite's HMR update works on diagram change
49+
return `<span class="diagram" v-html="${name}"></span>`
50+
}
51+
}

.vitepress/theme/styles.scss

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,23 @@ img, video.bright {
312312
}
313313
}
314314

315+
// Raw svg diagrams
316+
.diagram {
317+
all: initial; // preserve original svg formatting
318+
svg {
319+
.dark & { // recolor in dark mode
320+
filter: brightness(.884) invert(1) hue-rotate(177deg);
321+
}
322+
max-width: 100%;
323+
height: auto;
324+
margin: 30px auto;
325+
326+
* {
327+
// drawio line-height is not updated when font size is changed leading to misaligned text
328+
line-height: unset !important;
329+
}
330+
}
331+
}
315332

316333

317334
.VPBadge {

cds/assets/cxl/expr.drawio.svg

Lines changed: 865 additions & 4 deletions
Loading

cds/assets/cxl/function.drawio.svg

Lines changed: 145 additions & 174 deletions
Loading

cds/assets/cxl/infix-filter.drawio.svg

Lines changed: 139 additions & 4 deletions
Loading

cds/assets/cxl/operators.drawio.svg

Lines changed: 653 additions & 4 deletions
Loading

cds/assets/cxl/ref.drawio.svg

Lines changed: 190 additions & 4 deletions
Loading

cds/cxl.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ select from Books {
8585

8686
This syntax diagram describes the possible expressions:
8787

88-
![](assets/cxl/expr.drawio.svg)
88+
![](assets/cxl/expr.drawio.svg?raw)
8989

9090
> Using:
9191
> [Path Expressions](#ref),
@@ -262,7 +262,7 @@ A `ref` (short for reference) is used to refer to an element within the model.
262262
It can be used to navigate along path segments. Such a navigation is often
263263
referred to as a **path expression**.
264264

265-
![](assets/cxl/ref.drawio.svg)
265+
![](assets/cxl/ref.drawio.svg?raw)
266266

267267
> Using:
268268
> [Infix Filters](#infix-filters)
@@ -459,7 +459,7 @@ If we apply this terminology to [path-expressions](#ref), an infix filter condit
459459
that is applied to a path-segment of a [path-expression](#ref).
460460
This allows you to filter the target of an association based on certain criteria.
461461

462-
![](assets/cxl/infix-filter.drawio.svg)
462+
![](assets/cxl/infix-filter.drawio.svg?raw)
463463

464464
> Using:
465465
> [Expressions](#expr)
@@ -778,7 +778,7 @@ navigates along the `author` association of the `Books` entity only if the autho
778778

779779
As depicted in below excerpt of the syntax diagram for `expr`, CXL supports all the standard SQL operators as well as a few additional ones, such as the `?` operator to check for the existence of a path.
780780

781-
![](assets/cxl/operators.drawio.svg)
781+
![](assets/cxl/operators.drawio.svg?raw)
782782

783783
> Using:
784784
> [Expressions](#expr)
@@ -814,7 +814,7 @@ Following table gives an overview of the guaranteed supported operators in CXL:
814814
## Functions (`func`)
815815
###### func
816816

817-
![](assets/cxl/function.drawio.svg)
817+
![](assets/cxl/function.drawio.svg?raw)
818818

819819
> Using:
820820
> [Expressions](#expr)

0 commit comments

Comments
 (0)