@hardikg/mdview 0.8.1 → 0.9.1
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/CHANGELOG.md +39 -0
- package/README.md +6 -5
- package/bin/mdview.mjs +89 -73
- package/dist/client/assets/{abnfDiagram-VCTEODGH-DafRYfx3.js → abnfDiagram-VCTEODGH-BJQEGN-7.js} +1 -1
- package/dist/client/assets/{arc-BqKZ1e2b.js → arc-C6Oi4WlG.js} +1 -1
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-_94hPNdL.js → architectureDiagram-5GKGNRK7-CvFdvi3K.js} +1 -1
- package/dist/client/assets/{blockDiagram-NRAW4CY4-BegJqAzx.js → blockDiagram-NRAW4CY4-D8P8a3XW.js} +1 -1
- package/dist/client/assets/{c4Diagram-UCG6FXSJ-DYBJe_j-.js → c4Diagram-UCG6FXSJ-WcmmjfHX.js} +1 -1
- package/dist/client/assets/channel-UA4WTF8Q.js +1 -0
- package/dist/client/assets/{chunk-2Q5K7J3B-CarNPuoG.js → chunk-2Q5K7J3B-LeZsbe9d.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-Bmb8JM_j.js → chunk-5VM5RSS4-COq9euGx.js} +1 -1
- package/dist/client/assets/{chunk-F27PBJKO-BhLIUyGL.js → chunk-F27PBJKO-BxcjnaqW.js} +1 -1
- package/dist/client/assets/{chunk-G27WJ6UU-B_7t7iym.js → chunk-G27WJ6UU-CscpPXiS.js} +1 -1
- package/dist/client/assets/{chunk-JWPE2WC7-6WDfZVE5.js → chunk-JWPE2WC7-DD0M0JL-.js} +1 -1
- package/dist/client/assets/{chunk-LCL6LL3I-BnM13fhY.js → chunk-LCL6LL3I-DXhJ59Qq.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-DQMWRZKQ.js → chunk-POPQ4Y6H-Bj3eKHA8.js} +1 -1
- package/dist/client/assets/{chunk-SVP7TREG-DPpw4ke1.js → chunk-SVP7TREG-CDQ9vZv1.js} +1 -1
- package/dist/client/assets/{chunk-XXDRQBXY-ByC-zeqG.js → chunk-XXDRQBXY-91VBn0TQ.js} +1 -1
- package/dist/client/assets/classDiagram-DTDB5LWJ-Ch3MnxRH.js +1 -0
- package/dist/client/assets/classDiagram-v2-JRS7N3AN-Ch3MnxRH.js +1 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-CiRnFlQp.js → cose-bilkent-JH36ORCC-BaQN6N6K.js} +1 -1
- package/dist/client/assets/{cynefin-OW5HDTMX-DqTFYole.js → cynefin-OW5HDTMX-DFpC3uqz.js} +1 -1
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-B1WAhR06.js → cynefinDiagram-5FMLGOSQ-CSeSIxw6.js} +1 -1
- package/dist/client/assets/{dagre-3AP2YEHR-DQK5a43-.js → dagre-3AP2YEHR-BBkMnw1s.js} +1 -1
- package/dist/client/assets/{diagram-S7CK7UJ4-BMQ8dao_.js → diagram-S7CK7UJ4-BRdjuShi.js} +1 -1
- package/dist/client/assets/{diagram-UQ7AKVKN-CT7KIFG4.js → diagram-UQ7AKVKN-D-RaNNET.js} +1 -1
- package/dist/client/assets/{diagram-VSXAHHWV-By0SbfXs.js → diagram-VSXAHHWV-eL5_j9pa.js} +1 -1
- package/dist/client/assets/{diagram-VX7I27RA-DwshpqNi.js → diagram-VX7I27RA-nlUjCwlX.js} +1 -1
- package/dist/client/assets/{diagram-Z3DM3KII-CG7wA7Kr.js → diagram-Z3DM3KII-DvhXGz8M.js} +1 -1
- package/dist/client/assets/{ebnfDiagram-PWID7BFC-XlNRbCZw.js → ebnfDiagram-PWID7BFC-LgynLQ4Z.js} +1 -1
- package/dist/client/assets/{erDiagram-SSCWMZ5O-BtDUPrpL.js → erDiagram-SSCWMZ5O-Bc2j9FRV.js} +1 -1
- package/dist/client/assets/{flowDiagram-A5DVABFB-DKJ5hkO-.js → flowDiagram-A5DVABFB-ClpDS0y_.js} +1 -1
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-B8rnbHA1.js → ganttDiagram-EL5Y4UJY-_RmNHCQH.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-Conc20s7.js → gitGraphDiagram-WWUBYQGX-F1UGJQ4d.js} +1 -1
- package/dist/client/assets/index-BP_8buXC.css +1 -0
- package/dist/client/assets/index-DqIihcNP.js +2 -0
- package/dist/client/assets/{infoDiagram-RXCK75RN-DNuHlrdu.js → infoDiagram-RXCK75RN-BR20W1yx.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-DkYaQbSy.js → ishikawaDiagram-5VMMS53U-D6bgpoOj.js} +1 -1
- package/dist/client/assets/{journeyDiagram-EYS64GPL-BdoQruin.js → journeyDiagram-EYS64GPL-CBjB_0Bx.js} +1 -1
- package/dist/client/assets/{kanban-definition-3QL26DDD-BD3QQjwp.js → kanban-definition-3QL26DDD-Bz0HhYZd.js} +1 -1
- package/dist/client/assets/{layout-DKu9QfZ6.js → layout-BmTy4KT7.js} +1 -1
- package/dist/client/assets/{linear-DMmTRDu2.js → linear-Cgk2Kw-d.js} +1 -1
- package/dist/client/assets/{mermaid.core-2ESgyZ95.js → mermaid.core-Dq2piIpp.js} +65 -65
- package/dist/client/assets/{mindmap-definition-FBJOCRG2-CokK9_yg.js → mindmap-definition-FBJOCRG2-BSbZ3zKk.js} +1 -1
- package/dist/client/assets/{pegDiagram-XKGWAZYB-CUAn26Uv.js → pegDiagram-XKGWAZYB-BLsHBZ_O.js} +1 -1
- package/dist/client/assets/{pieDiagram-E7YTZNPT-BT-XLIyl.js → pieDiagram-E7YTZNPT-BTtaojGC.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-dDr-ZgjR.js → quadrantDiagram-AXDQQJYC-W-VPz1gZ.js} +1 -1
- package/dist/client/assets/{railroadDiagram-O6MQD6OU-B5rCSICc.js → railroadDiagram-O6MQD6OU-CstXUJhE.js} +1 -1
- package/dist/client/assets/{requirementDiagram-EFPCY7ZU-DyI3FGB5.js → requirementDiagram-EFPCY7ZU-DPpI_Lvd.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-CGXj8eCe.js → sankeyDiagram-P5KCCOFB-B3HiW1sY.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-C3yr2FVq.js → sequenceDiagram-WJ2MYXX4-CfpZAY9b.js} +1 -1
- package/dist/client/assets/{sizeCapture-X5ZJPWSS-CCnkSxko.js → sizeCapture-X5ZJPWSS-Dsdx6W_J.js} +1 -1
- package/dist/client/assets/{stateDiagram-HBIQ2CUA-BG5Dshx6.js → stateDiagram-HBIQ2CUA-DPm-o7Ee.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-4QOOHH4V-DDqXMzve.js +1 -0
- package/dist/client/assets/{swimlanes-XN3QIQJK-MGfvzMlQ.js → swimlanes-XN3QIQJK-BPdZeRls.js} +1 -1
- package/dist/client/assets/swimlanesDiagram-VK2B7HYN-BHORPcrU.js +8 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-Bj3gMrOq.js → timeline-definition-24CTP7MA-1bs3iV0k.js} +1 -1
- package/dist/client/assets/{vennDiagram-4TSXK5OY-CiIW_j8g.js → vennDiagram-4TSXK5OY-vYOlmqTL.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-DQTIyknP.js → wardleyDiagram-VM6X3IG4-DTPUMRNL.js} +1 -1
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-Bg0tzmhJ.js → xychartDiagram-S5SC5T6Z-M5kqQyt7.js} +1 -1
- package/dist/client/bootstrap.js +13 -2
- package/dist/client/index.html +2 -2
- package/package.json +2 -2
- package/dist/client/assets/channel-CzMcbnuI.js +0 -1
- package/dist/client/assets/classDiagram-DTDB5LWJ-RvAHOW66.js +0 -1
- package/dist/client/assets/classDiagram-v2-JRS7N3AN-RvAHOW66.js +0 -1
- package/dist/client/assets/index-CCiGr1hz.js +0 -2
- package/dist/client/assets/index-CJ5_G3gC.css +0 -1
- package/dist/client/assets/stateDiagram-v2-4QOOHH4V-BdraFugH.js +0 -1
- package/dist/client/assets/swimlanesDiagram-VK2B7HYN-LQu07Za2.js +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.1] — 2026-10-04
|
|
11
|
+
|
|
12
|
+
A file tree that keeps deep paths readable, and a dependency refresh.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **File-tree indentation no longer grows with depth.** Each level added its own offset on top of its parent's, so the indent compounded: a file five folders down sat about 310 px in, past the edge of a default-width pane. Every level now adds one fixed 14 px step, so the same file sits under 90 px in.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- **The file tree scrolls sideways**, like the Zed and VS Code sidebars. Long names are no longer truncated with an ellipsis; scroll the tree horizontally to read them instead of widening the pane. The "Files" header stays in place while the tree scrolls.
|
|
19
|
+
|
|
20
|
+
### Security
|
|
21
|
+
- Bumped shipped dependencies to clear advisories: `fastify` 5.12.3 → 5.12.5 (DoS via HTTP/2 trailer responses), `fast-uri` 3.1.6 → 3.1.8 and 4.1.4 → 4.2.1 (host confusion and authority injection in URI handling), `markdown-it` 14.2.0 → 14.3.2 (quadratic paths in `linkify`), and `brace-expansion` 5.0.9 → 5.0.12 (DoS on crafted brace patterns). The `markdown-it` one was reachable: the renderer enables `linkify`, so opening a few hundred KB of crafted markdown could block the server for tens of seconds. The others were not reachable as mdview is configured (the server does not enable HTTP/2), but they ship in the install. Lockfile-only change.
|
|
22
|
+
|
|
23
|
+
## [0.9.0] — 2026-09-14
|
|
24
|
+
|
|
25
|
+
Eight palettes, each with its own ground texture — and code blocks that are
|
|
26
|
+
smaller than they were at five.
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
- **Five new palettes: Everforest, Rosé Pine, Kanagawa, Catppuccin, and Flexoki** — each with a full light and dark variant and its own Shiki theme pair, so code blocks stay inside the palette. Base colours come from each project's own palette file; all six upstream projects are MIT.
|
|
30
|
+
- **Each palette now has its own ground texture.** Previously one texture was defined per light/dark theme, so a warm brown grain (`rgba(120, 70, 30, …)`) was washed over every palette including the cool ones. There are now three patterns, assigned per palette: a dot grain tinted with the palette's own ink on the paper-like palettes (flexoki, paper, solarized), fibre noise on the two lowest-contrast grounds (everforest, kanagawa), and an accent wash — a wide bleed of the palette's accent down from the top edge — on rose-pine and catppuccin. `high-contrast` gets none, because texture over a maximum-contrast ground works against the one thing that palette exists to provide. The noise is an SVG `feTurbulence` data URI, which the existing `img-src 'self' data: blob:` already permits, so the CSP is untouched.
|
|
31
|
+
|
|
32
|
+
Texture is deliberately not a setting. It is part of a palette's identity, and a four-way picker crossed with eight palettes is 32 combinations nobody would author or test.
|
|
33
|
+
- **VS Code extension: two-way cursor sync.** Clicking a heading or an internal link in the preview moves the editor cursor and reveals the line; moving the cursor in the editor scrolls the preview to the nearest heading at or above that line, debounced at 80ms. A suppression window breaks the feedback loop so VS Code's own selection-change event isn't echoed back as a jitter loop. Inbound paths from the webview are canonicalized with `realpath` and rejected unless they stay inside the workspace folder. The extension is still unpublished (`0.1.0`).
|
|
34
|
+
- VS Code extension: `mdview: Open in Browser` command, and the preview now follows the active editor and the VS Code colour theme.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
- **Code blocks are rendered for the active palette only, and are far smaller for it.** Every token used to carry one CSS variable per (palette, mode) pair, so adding palettes inflated every document that contained code — 16 variables per token at eight palettes. A token now carries two, `--shiki-light` and `--shiki-dark`. `/api/file` accepts a `palette` query param, checked against the allow-list and falling back to the default rather than failing the request, and the client refetches when you change palette. The light/dark toggle still repaints with no request, since both its variants ship in every response. `test-fixtures/showcase.md` went from 204 KB to 30 KB — smaller than it was before any of the new palettes landed.
|
|
38
|
+
- **Flexoki is the new default palette**, replacing `classic`. It keeps the warm-cream editorial look but is built on a measured 15-step base ramp rather than hand-picked creams, and it is the only palette here designed for reading prose rather than for reading code.
|
|
39
|
+
- The VS Code extension's `auto` palette no longer picks a different palette for light and dark themes. Light versus dark is a separate axis in the renderer — every palette defines both — so `auto` now follows only the high-contrast kinds and otherwise leaves the palette alone.
|
|
40
|
+
|
|
41
|
+
### Removed
|
|
42
|
+
- **The `classic` and `nord` palettes.** `--palette classic` and `--palette nord` now exit non-zero and list the valid names. A `palette` of either in `.mdview.json` or a stale one in `localStorage` degrades silently to the default, which is the existing behaviour for any unrecognised palette — no migration needed.
|
|
43
|
+
- The VS Code extension drops both from the `mdview.palette` setting enum.
|
|
44
|
+
|
|
45
|
+
### Security
|
|
46
|
+
- `fastify` 5.8.5 → 5.12.3. Closes a schema-validation bypass via root primitive coercion (GHSA-w2qp-rph6-63g4) and `X-Forwarded-*` spoofing under `trustProxy` hop-count (GHSA-3m5p-2c4r-xxw2). Neither is reachable here — the server defines no root-primitive schemas and never sets `trustProxy` — but the dep ships to users.
|
|
47
|
+
- `js-yaml` 3.15.1 → 3.15.2 (transitively, via `gray-matter`). Closes unbounded CPU use on empty merge sources (GHSA-2883-xcg3-v3hh). This one is reachable: `js-yaml` parses frontmatter out of whatever markdown the user opens.
|
|
48
|
+
|
|
10
49
|
## [0.8.1] — 2026-08-24
|
|
11
50
|
|
|
12
51
|
### Fixed
|
package/README.md
CHANGED
|
@@ -70,7 +70,7 @@ mdview stop # stop the background server
|
|
|
70
70
|
mdview --foreground # run in this terminal instead (Ctrl-C to stop)
|
|
71
71
|
mdview --no-open # don't auto-launch the browser
|
|
72
72
|
mdview --port 9000 # one-off server on a specific port (implies --foreground)
|
|
73
|
-
mdview --palette
|
|
73
|
+
mdview --palette kanagawa # palette for this run (implies --foreground)
|
|
74
74
|
mdview --help # show usage
|
|
75
75
|
```
|
|
76
76
|
|
|
@@ -121,7 +121,8 @@ works as-is behind a local proxy like
|
|
|
121
121
|
[portless](https://github.com/vercel-labs/portless) if you want the port gone
|
|
122
122
|
entirely.
|
|
123
123
|
|
|
124
|
-
`--palette` takes `
|
|
124
|
+
`--palette` takes `flexoki`, `paper`, `solarized`, `everforest`, `rose-pine`,
|
|
125
|
+
`kanagawa`, `catppuccin`, or `high-contrast`.
|
|
125
126
|
It wins over both `.mdview.json` and the global config, and never writes to
|
|
126
127
|
either. There is also a `--vscode` flag, used by the VS Code extension to run
|
|
127
128
|
mdview as a sidecar; it implies `--no-open` and prints a single JSON ready line
|
|
@@ -168,7 +169,7 @@ Click the keyboard icon in the header anytime to see the full list.
|
|
|
168
169
|
- 3-pane layout: folder tree, content, outline. Both sidebars collapse to a thin label rail; both have drag handles to resize (widths persist).
|
|
169
170
|
- Editorial typography (serif body, italic accent H1, paper-grain background, JetBrains Mono in code blocks).
|
|
170
171
|
- Light & dark theme — follows your OS preference, with a manual override that persists.
|
|
171
|
-
-
|
|
172
|
+
- Eight built-in palettes: flexoki / paper / solarized / everforest / rose-pine / kanagawa / catppuccin / high-contrast. Pick one from the header palette swatch. Each defines a full light and dark variant and its own ground texture: a dot grain on the paper-like palettes, fibre noise on Everforest and Kanagawa, an accent wash on Rosé Pine and Catppuccin, and none at all on high-contrast. Code blocks follow the palette (Everforest syntax in Everforest, Catppuccin in Catppuccin, etc.).
|
|
172
173
|
- Reading-progress bar pinned to the bottom of the header.
|
|
173
174
|
- Doc stats strip below the H1 (reading time, word count, heading count, "Updated N ago").
|
|
174
175
|
- Focus mode dims everything except the section at the viewport center.
|
|
@@ -184,7 +185,7 @@ Click the keyboard icon in the header anytime to see the full list.
|
|
|
184
185
|
|
|
185
186
|
**Rendering**
|
|
186
187
|
- CommonMark + GFM (tables, task lists, strikethrough, autolinks).
|
|
187
|
-
- Server-side syntax highlighting via Shiki, palette-aware
|
|
188
|
+
- Server-side syntax highlighting via Shiki, palette-aware: two variants per token, light and dark, for whichever palette is active. Zero client highlighter bundle, and the light/dark toggle repaints with no request.
|
|
188
189
|
- Mermaid diagrams, lazy-loaded only when a doc contains a `mermaid` fence.
|
|
189
190
|
- Math via KaTeX (`$inline$` and `$$block$$`), lazy-loaded only when a doc contains math.
|
|
190
191
|
- Custom-styled task list checkboxes (filled accent when checked, hollow when unchecked).
|
|
@@ -216,7 +217,7 @@ Two layered files, both optional, same schema:
|
|
|
216
217
|
|
|
217
218
|
```json
|
|
218
219
|
{
|
|
219
|
-
"palette": "
|
|
220
|
+
"palette": "everforest",
|
|
220
221
|
"fontFamily": "serif",
|
|
221
222
|
"lineWidth": "70ch",
|
|
222
223
|
"defaultCollapsed": { "tree": false, "outline": false },
|
package/bin/mdview.mjs
CHANGED
|
@@ -14,7 +14,17 @@ import os from "os";
|
|
|
14
14
|
import path from "path";
|
|
15
15
|
|
|
16
16
|
// src/shared/types.ts
|
|
17
|
-
var
|
|
17
|
+
var DEFAULT_PALETTE = "flexoki";
|
|
18
|
+
var PALETTES = [
|
|
19
|
+
"flexoki",
|
|
20
|
+
"paper",
|
|
21
|
+
"solarized",
|
|
22
|
+
"everforest",
|
|
23
|
+
"rose-pine",
|
|
24
|
+
"kanagawa",
|
|
25
|
+
"catppuccin",
|
|
26
|
+
"high-contrast"
|
|
27
|
+
];
|
|
18
28
|
|
|
19
29
|
// src/server/config.ts
|
|
20
30
|
var CONFIG_FILENAME = ".mdview.json";
|
|
@@ -1048,20 +1058,21 @@ var COMMON_LANGUAGES = [
|
|
|
1048
1058
|
"diff",
|
|
1049
1059
|
"dockerfile"
|
|
1050
1060
|
];
|
|
1051
|
-
var
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
"
|
|
1056
|
-
"
|
|
1057
|
-
"
|
|
1058
|
-
"
|
|
1059
|
-
"
|
|
1060
|
-
"
|
|
1061
|
-
"
|
|
1061
|
+
var PALETTE_THEMES = {
|
|
1062
|
+
// Flexoki has no upstream TextMate theme. `min-light` and `vesper` are the
|
|
1063
|
+
// closest bundled stand-ins: both are deliberately low-chroma, which is the
|
|
1064
|
+
// one property of Flexoki that a louder theme would contradict.
|
|
1065
|
+
flexoki: { light: "min-light", dark: "vesper" },
|
|
1066
|
+
paper: { light: "min-light", dark: "vitesse-dark" },
|
|
1067
|
+
solarized: { light: "solarized-light", dark: "solarized-dark" },
|
|
1068
|
+
everforest: { light: "everforest-light", dark: "everforest-dark" },
|
|
1069
|
+
"rose-pine": { light: "rose-pine-dawn", dark: "rose-pine" },
|
|
1070
|
+
kanagawa: { light: "kanagawa-lotus", dark: "kanagawa-wave" },
|
|
1071
|
+
catppuccin: { light: "catppuccin-latte", dark: "catppuccin-mocha" },
|
|
1072
|
+
"high-contrast": { light: "github-light-high-contrast", dark: "github-dark-high-contrast" }
|
|
1062
1073
|
};
|
|
1063
1074
|
var UNDERLYING_THEMES = Array.from(
|
|
1064
|
-
new Set(Object.values(
|
|
1075
|
+
new Set(Object.values(PALETTE_THEMES).flatMap((t) => [t.light, t.dark]))
|
|
1065
1076
|
);
|
|
1066
1077
|
var highlighterPromise = null;
|
|
1067
1078
|
function getHighlighter() {
|
|
@@ -1076,7 +1087,7 @@ function getHighlighter() {
|
|
|
1076
1087
|
function escapeHtml(s) {
|
|
1077
1088
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1078
1089
|
}
|
|
1079
|
-
async function highlightCode(code, lang) {
|
|
1090
|
+
async function highlightCode(code, lang, palette = DEFAULT_PALETTE) {
|
|
1080
1091
|
const highlighter = await getHighlighter();
|
|
1081
1092
|
const loaded = highlighter.getLoadedLanguages();
|
|
1082
1093
|
let effectiveLang = lang;
|
|
@@ -1090,7 +1101,7 @@ async function highlightCode(code, lang) {
|
|
|
1090
1101
|
try {
|
|
1091
1102
|
return highlighter.codeToHtml(code, {
|
|
1092
1103
|
lang: effectiveLang || "text",
|
|
1093
|
-
themes:
|
|
1104
|
+
themes: PALETTE_THEMES[palette],
|
|
1094
1105
|
defaultColor: false
|
|
1095
1106
|
});
|
|
1096
1107
|
} catch {
|
|
@@ -1112,7 +1123,7 @@ md.use(anchor, {
|
|
|
1112
1123
|
});
|
|
1113
1124
|
md.use(taskLists, { enabled: false, label: false });
|
|
1114
1125
|
md.use(mathPlugin);
|
|
1115
|
-
async function renderMarkdown(source, bodyStartLine = 0) {
|
|
1126
|
+
async function renderMarkdown(source, bodyStartLine = 0, palette = DEFAULT_PALETTE) {
|
|
1116
1127
|
const tokens = md.parse(source, {});
|
|
1117
1128
|
for (const token of tokens) {
|
|
1118
1129
|
if (token.type === "heading_open" && token.map) {
|
|
@@ -1125,7 +1136,7 @@ async function renderMarkdown(source, bodyStartLine = 0) {
|
|
|
1125
1136
|
token.content = `<div class="mermaid-block" data-source="${encodeURIComponent(token.content)}"></div>
|
|
1126
1137
|
`;
|
|
1127
1138
|
} else {
|
|
1128
|
-
const highlighted = await highlightCode(token.content, lang);
|
|
1139
|
+
const highlighted = await highlightCode(token.content, lang, palette);
|
|
1129
1140
|
token.type = "html_block";
|
|
1130
1141
|
token.content = highlighted + "\n";
|
|
1131
1142
|
}
|
|
@@ -1169,64 +1180,69 @@ function nest(flat) {
|
|
|
1169
1180
|
|
|
1170
1181
|
// src/server/routes/api-file.ts
|
|
1171
1182
|
function registerApiFile(app, roots) {
|
|
1172
|
-
app.get(
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
return reply.code(400).send({ error: "Missing ?path" });
|
|
1183
|
+
app.get(
|
|
1184
|
+
"/api/file",
|
|
1185
|
+
async (req, reply) => {
|
|
1186
|
+
const requested = req.query.path?.trim() ?? "";
|
|
1187
|
+
const rawPalette = req.query.palette?.trim() ?? "";
|
|
1188
|
+
const palette = PALETTES.includes(rawPalette) ? rawPalette : DEFAULT_PALETTE;
|
|
1189
|
+
const primary = roots[0];
|
|
1190
|
+
if (!primary) {
|
|
1191
|
+
return reply.code(404).send({ error: "No folders are open" });
|
|
1182
1192
|
}
|
|
1183
|
-
wsPath =
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1193
|
+
let wsPath = requested;
|
|
1194
|
+
if (!wsPath) {
|
|
1195
|
+
if (primary.root.kind !== "file") {
|
|
1196
|
+
return reply.code(400).send({ error: "Missing ?path" });
|
|
1197
|
+
}
|
|
1198
|
+
wsPath = toWorkspacePath(primary.root.id, primary.root.filePath);
|
|
1199
|
+
}
|
|
1200
|
+
const resolved = parseWorkspacePath(roots, wsPath);
|
|
1201
|
+
if (!resolved) {
|
|
1202
|
+
return reply.code(404).send({ error: "File not found" });
|
|
1203
|
+
}
|
|
1204
|
+
const { state, rel } = resolved;
|
|
1205
|
+
if (state.root.kind === "file" && rel !== state.root.filePath) {
|
|
1206
|
+
return reply.code(404).send({ error: "File not found in single-file mode" });
|
|
1207
|
+
}
|
|
1208
|
+
if (!/\.(md|markdown|mdx)$/i.test(rel)) {
|
|
1209
|
+
return reply.code(400).send({ error: "Only markdown files are supported" });
|
|
1210
|
+
}
|
|
1211
|
+
let absPath;
|
|
1212
|
+
try {
|
|
1213
|
+
absPath = resolveSafePath(state.absPath, rel);
|
|
1214
|
+
} catch (err) {
|
|
1215
|
+
return reply.code(400).send({ error: err.message });
|
|
1216
|
+
}
|
|
1217
|
+
let raw;
|
|
1218
|
+
let mtimeMs;
|
|
1219
|
+
try {
|
|
1220
|
+
const [content, st] = await Promise.all([
|
|
1221
|
+
readFile3(absPath, "utf8"),
|
|
1222
|
+
stat2(absPath)
|
|
1223
|
+
]);
|
|
1224
|
+
raw = content;
|
|
1225
|
+
mtimeMs = st.mtimeMs;
|
|
1226
|
+
} catch {
|
|
1227
|
+
return reply.code(404).send({ error: "File not found" });
|
|
1228
|
+
}
|
|
1229
|
+
const { data, body, bodyStartLine } = parseFrontmatter(raw);
|
|
1230
|
+
const { html: rawHtml, tokens } = await renderMarkdown(body, bodyStartLine, palette);
|
|
1231
|
+
const wsRel = toWorkspacePath(state.root.id, rel);
|
|
1232
|
+
const html = rewriteImageSrc(tagInternalLinks(rawHtml, wsRel), wsRel);
|
|
1233
|
+
const outline = extractOutline(tokens);
|
|
1234
|
+
const title = (typeof data?.title === "string" ? data.title : null) ?? outline[0]?.text ?? null;
|
|
1235
|
+
const result = {
|
|
1236
|
+
relPath: wsRel,
|
|
1237
|
+
html,
|
|
1238
|
+
outline,
|
|
1239
|
+
frontmatter: data,
|
|
1240
|
+
title,
|
|
1241
|
+
lastModified: mtimeMs
|
|
1242
|
+
};
|
|
1243
|
+
return reply.send(result);
|
|
1201
1244
|
}
|
|
1202
|
-
|
|
1203
|
-
let mtimeMs;
|
|
1204
|
-
try {
|
|
1205
|
-
const [content, st] = await Promise.all([
|
|
1206
|
-
readFile3(absPath, "utf8"),
|
|
1207
|
-
stat2(absPath)
|
|
1208
|
-
]);
|
|
1209
|
-
raw = content;
|
|
1210
|
-
mtimeMs = st.mtimeMs;
|
|
1211
|
-
} catch {
|
|
1212
|
-
return reply.code(404).send({ error: "File not found" });
|
|
1213
|
-
}
|
|
1214
|
-
const { data, body, bodyStartLine } = parseFrontmatter(raw);
|
|
1215
|
-
const { html: rawHtml, tokens } = await renderMarkdown(body, bodyStartLine);
|
|
1216
|
-
const wsRel = toWorkspacePath(state.root.id, rel);
|
|
1217
|
-
const html = rewriteImageSrc(tagInternalLinks(rawHtml, wsRel), wsRel);
|
|
1218
|
-
const outline = extractOutline(tokens);
|
|
1219
|
-
const title = (typeof data?.title === "string" ? data.title : null) ?? outline[0]?.text ?? null;
|
|
1220
|
-
const result = {
|
|
1221
|
-
relPath: wsRel,
|
|
1222
|
-
html,
|
|
1223
|
-
outline,
|
|
1224
|
-
frontmatter: data,
|
|
1225
|
-
title,
|
|
1226
|
-
lastModified: mtimeMs
|
|
1227
|
-
};
|
|
1228
|
-
return reply.send(result);
|
|
1229
|
-
});
|
|
1245
|
+
);
|
|
1230
1246
|
}
|
|
1231
1247
|
|
|
1232
1248
|
// src/server/fs/grep.ts
|
package/dist/client/assets/{abnfDiagram-VCTEODGH-DafRYfx3.js → abnfDiagram-VCTEODGH-BJQEGN-7.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-SVP7TREG-
|
|
1
|
+
import{g as p,r as u,d as a}from"./chunk-SVP7TREG-CDQ9vZv1.js";import{p as f}from"./chunk-JWPE2WC7-DD0M0JL-.js";import{_ as n,l as o}from"./mermaid.core-Dq2piIpp.js";import{M as c,b as d}from"./cynefin-OW5HDTMX-DFpC3uqz.js";import"./index-DqIihcNP.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a0 as ln,a1 as an,a2 as y,a3 as tn,a4 as H,a5 as q,a6 as _,a7 as un,a8 as rn,a9 as L,aa as o,ab as B,ac as sn,ad as on,ae as fn}from"./mermaid.core-
|
|
1
|
+
import{a0 as ln,a1 as an,a2 as y,a3 as tn,a4 as H,a5 as q,a6 as _,a7 as un,a8 as rn,a9 as L,aa as o,ab as B,ac as sn,ad as on,ae as fn}from"./mermaid.core-Dq2piIpp.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,C,a){var O=I-l,i=D-h,n=C-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function W(l,h,I,D,v,A,C){var a=l-I,O=h-D,i=(C?A:-A)/L(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,F=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*L(fn(0,T*T*R-P*P)),j=(P*g-m*S)/R,z=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=j-F,e=z-t,r=w-F,G=p-t;return x*x+e*e>r*r+G*G&&(j=w,z=p),{cx:j,cy:z,x01:-n,y01:-d,x11:j*(v/T-1),y11:z*(v/T-1)}}function hn(){var l=cn,h=yn,I=B(0),D=null,v=gn,A=dn,C=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-an,c=A.apply(this,arguments)-an,F=un(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(F>tn-y)a.moveTo(s*H(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*H(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=F,S=F,j=C.apply(this,arguments)/2,z=j>y&&(D?+D.apply(this,arguments):L(u*u+s*s)),w=_(un(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if(z>y){var G=sn(z/u*q(j)),M=sn(z/s*q(j));(P-=G*2)>y?(G*=t?1:-1,R+=G,T-=G):(P=0,R=T=(f+c)/2),(S-=M*2)>y?(M*=t?1:-1,m+=M,g-=M):(S=0,m=g=(f+c)/2)}var J=s*H(m),K=s*q(m),N=u*H(T),Q=u*q(T);if(w>y){var U=s*H(g),V=s*q(g),X=u*H(R),Y=u*q(R),E;if(F<rn)if(E=pn(J,K,X,Y,U,V,N,Q)){var Z=J-E[0],$=K-E[1],b=U-E[0],k=V-E[1],nn=1/q(on((Z*b+$*k)/(L(Z*Z+$*$)*L(b*b+k*k)))/2),en=L(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=W(X,Y,J,K,s,x,t),r=W(U,V,N,Q,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(J,K),a.arc(0,0,s,m,g,!t)):a.moveTo(J,K),!(u>y)||!(P>y)?a.lineTo(N,Q):p>y?(e=W(N,Q,U,V,u,-p,t),r=W(J,K,X,Y,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-rn/2;return[H(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:B(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:B(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:B(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:B(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:B(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:B(+n),i):A},i.padAngle=function(n){return arguments.length?(C=typeof n=="function"?n:B(+n),i):C},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|