@inovus-medical/docs 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,7 +27,8 @@ Flags: `--root <dir>` `--in <docs>` `--out <dist>` `--port <n>`.
27
27
  ## What it does
28
28
 
29
29
  - Renders markdown with `markdown-it` + `@shikijs/markdown-it` (dual light/dark
30
- syntax highlighting), heading anchors, tables, and frontmatter.
30
+ syntax highlighting), Mermaid diagrams (` ```mermaid ` fences), heading anchors,
31
+ tables, and frontmatter.
31
32
  - Generates sidebar navigation from your folder structure.
32
33
  - Builds a client-side search index, light/dark theme, on-page table of contents,
33
34
  and prev/next paging.
package/assets/client.js CHANGED
@@ -1,6 +1,52 @@
1
1
  (function () {
2
2
  var root = document.documentElement
3
3
 
4
+ // ---------- Mermaid (loaded only when diagrams are present) ----------
5
+ var mermaidLoading = null
6
+
7
+ function mermaidTheme() {
8
+ return root.getAttribute('data-theme') === 'dark' ? 'dark' : 'default'
9
+ }
10
+
11
+ function prepareMermaidNodes() {
12
+ var nodes = document.querySelectorAll('.mermaid')
13
+ for (var i = 0; i < nodes.length; i++) {
14
+ var el = nodes[i]
15
+ if (!el.getAttribute('data-src')) {
16
+ el.setAttribute('data-src', el.textContent)
17
+ }
18
+ el.removeAttribute('data-processed')
19
+ el.removeAttribute('data-mermaid-svg')
20
+ el.textContent = el.getAttribute('data-src')
21
+ }
22
+ return nodes
23
+ }
24
+
25
+ function renderMermaid() {
26
+ var nodes = document.querySelectorAll('.mermaid')
27
+ if (!nodes.length) return Promise.resolve()
28
+
29
+ if (!mermaidLoading) {
30
+ mermaidLoading = import('https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs')
31
+ .then(function (mod) { return mod.default })
32
+ .catch(function (err) {
33
+ mermaidLoading = null
34
+ console.error('Failed to load Mermaid', err)
35
+ throw err
36
+ })
37
+ }
38
+
39
+ return mermaidLoading.then(function (mermaid) {
40
+ var list = prepareMermaidNodes()
41
+ mermaid.initialize({
42
+ startOnLoad: false,
43
+ securityLevel: 'strict',
44
+ theme: mermaidTheme()
45
+ })
46
+ return mermaid.run({ nodes: list })
47
+ })
48
+ }
49
+
4
50
  // Theme toggle
5
51
  var toggle = document.getElementById('theme-toggle')
6
52
  if (toggle) {
@@ -8,9 +54,14 @@
8
54
  var next = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'
9
55
  root.setAttribute('data-theme', next)
10
56
  try { localStorage.setItem('theme', next) } catch (e) {}
57
+ if (document.querySelector('.mermaid')) renderMermaid()
11
58
  })
12
59
  }
13
60
 
61
+ if (document.querySelector('.mermaid')) {
62
+ renderMermaid()
63
+ }
64
+
14
65
  // Mobile sidebar
15
66
  var menuBtn = document.getElementById('menu-toggle')
16
67
  var sidebar = document.querySelector('.sidebar')
package/assets/styles.css CHANGED
@@ -173,6 +173,31 @@ a:hover { text-decoration: underline; }
173
173
  .header-anchor { color: var(--text-soft); opacity: 0; margin-left: .3em; font-weight: 400; text-decoration: none; }
174
174
  .prose h2:hover .header-anchor, .prose h3:hover .header-anchor { opacity: 1; }
175
175
 
176
+ /* ---------- Mermaid ---------- */
177
+ .mermaid-wrap {
178
+ margin: 1.4em 0;
179
+ padding: 18px 16px;
180
+ background: var(--bg-soft);
181
+ border: 1px solid var(--border);
182
+ border-radius: 10px;
183
+ overflow-x: auto;
184
+ text-align: center;
185
+ }
186
+ .prose .mermaid-wrap pre.mermaid {
187
+ background: transparent;
188
+ border: none;
189
+ padding: 0;
190
+ margin: 0;
191
+ overflow: visible;
192
+ font-size: inherit;
193
+ line-height: normal;
194
+ text-align: center;
195
+ }
196
+ .mermaid-wrap .mermaid svg {
197
+ max-width: 100%;
198
+ height: auto;
199
+ }
200
+
176
201
  /* Shiki dual-theme color swap */
177
202
  [data-theme='dark'] .shiki,
178
203
  [data-theme='dark'] .shiki span {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inovus-medical/docs",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Turn a folder of markdown into a themed, Cloudflare-ready docs site.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/markdown.js CHANGED
@@ -58,6 +58,21 @@ export async function createRenderer() {
58
58
  })
59
59
  )
60
60
 
61
+ // Mermaid fences must not go through Shiki — emit source for client-side render.
62
+ const defaultFence = md.renderer.rules.fence
63
+ md.renderer.rules.fence = (tokens, idx, options, env, self) => {
64
+ const info = String(tokens[idx].info || '')
65
+ .trim()
66
+ .split(/\s+/)[0]
67
+ .toLowerCase()
68
+ if (info === 'mermaid' || info === 'mmd') {
69
+ const code = tokens[idx].content.replace(/\n$/, '')
70
+ const escaped = md.utils.escapeHtml(code)
71
+ return `<div class="mermaid-wrap"><pre class="mermaid">${escaped}</pre></div>\n`
72
+ }
73
+ return defaultFence(tokens, idx, options, env, self)
74
+ }
75
+
61
76
  return {
62
77
  render(content) {
63
78
  const tokens = md.parse(content, {})