ntk 3.10.2 → 4.1.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 +2 -3
- package/lib/app.js +15 -0
- package/lib/clipboard.js +18 -26
- package/lib/events_map.js +3 -0
- package/lib/index.js +4 -1
- package/lib/keyboard.js +114 -0
- package/lib/text/keysym-unicode.js +1186 -0
- package/lib/widgets/markdownview.js +2 -64
- package/lib/window.js +833 -121
- package/package.json +2 -5
- package/lib/widgets/mermaid.js +0 -720
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { TextLayout } from '../text/layout.js';
|
|
2
2
|
import { tokenize } from './highlight.js';
|
|
3
3
|
import { parseMarkdown } from './markdown.js';
|
|
4
|
-
import { layoutMermaid, parseMermaid } from './mermaid.js';
|
|
5
4
|
import { layoutTex } from './tex.js';
|
|
6
5
|
|
|
7
6
|
const MATH_LANGS = new Set(['math', 'tex', 'latex', 'katex']);
|
|
@@ -51,10 +50,8 @@ const DEFAULT_THEME = {
|
|
|
51
50
|
* wnd.map();
|
|
52
51
|
*
|
|
53
52
|
* Standalone use (no window attach): `view.layout(width)` then
|
|
54
|
-
* `view.draw(ctx, x, y)`; `view.contentHeight` after layout.
|
|
55
|
-
*
|
|
56
|
-
* `onInvalidate` to re-layout/redraw when that happens (window mode
|
|
57
|
-
* repaints automatically).
|
|
53
|
+
* `view.draw(ctx, x, y)`; `view.contentHeight` after layout. Layout is
|
|
54
|
+
* synchronous throughout — nothing here loads in the background.
|
|
58
55
|
*/
|
|
59
56
|
export default class MarkdownView {
|
|
60
57
|
constructor(window, opts = {}) {
|
|
@@ -73,10 +70,6 @@ export default class MarkdownView {
|
|
|
73
70
|
/** called with (href, event) when a rendered link is clicked (window
|
|
74
71
|
* mode wires mousedown automatically; standalone callers use linkAt) */
|
|
75
72
|
this.onLink = opts.onLink ?? null;
|
|
76
|
-
/** called when async content (a mermaid model) invalidates the layout;
|
|
77
|
-
* standalone hosts re-layout/redraw here — window mode also repaints
|
|
78
|
-
* on its own */
|
|
79
|
-
this.onInvalidate = opts.onInvalidate ?? null;
|
|
80
73
|
|
|
81
74
|
if (this.window) {
|
|
82
75
|
this._ctx = this.window.getContext('2d');
|
|
@@ -105,41 +98,11 @@ export default class MarkdownView {
|
|
|
105
98
|
|
|
106
99
|
setMarkdown(src) {
|
|
107
100
|
this._blocks = parseMarkdown(src);
|
|
108
|
-
this._mermaid = new Map();
|
|
109
101
|
this._layoutWidth = -1;
|
|
110
102
|
if (this.window && this.window._mapped) this.render();
|
|
111
103
|
return this;
|
|
112
104
|
}
|
|
113
105
|
|
|
114
|
-
// ```mermaid fences parse asynchronously (the mermaid grammar loads
|
|
115
|
-
// lazily); the fence shows as a code block until the model arrives, then
|
|
116
|
-
// layout is invalidated — same pattern as image loading in HtmlView
|
|
117
|
-
_mermaidEntry(text) {
|
|
118
|
-
if (!this._mermaid) this._mermaid = new Map();
|
|
119
|
-
let entry = this._mermaid.get(text);
|
|
120
|
-
if (!entry) {
|
|
121
|
-
entry = { model: null, failed: false };
|
|
122
|
-
this._mermaid.set(text, entry);
|
|
123
|
-
parseMermaid(text).then(
|
|
124
|
-
(model) => {
|
|
125
|
-
entry.model = model;
|
|
126
|
-
this._invalidate();
|
|
127
|
-
},
|
|
128
|
-
() => {
|
|
129
|
-
entry.failed = true; // unsupported/invalid: stays a code block
|
|
130
|
-
}
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
return entry;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/** async content arrived: drop the cached layout, repaint and/or notify */
|
|
137
|
-
_invalidate() {
|
|
138
|
-
this._layoutWidth = -1;
|
|
139
|
-
if (this.window && this.window._mapped) this.render();
|
|
140
|
-
if (this.onInvalidate) this.onInvalidate();
|
|
141
|
-
}
|
|
142
|
-
|
|
143
106
|
/** lay content out for a container width; returns total content height */
|
|
144
107
|
layout(width) {
|
|
145
108
|
const fonts = this._fonts();
|
|
@@ -208,31 +171,6 @@ export default class MarkdownView {
|
|
|
208
171
|
}
|
|
209
172
|
|
|
210
173
|
case 'code': {
|
|
211
|
-
// ```mermaid fences render as diagrams (flowchart / sequence);
|
|
212
|
-
// unsupported types or parse errors fall back to the code block
|
|
213
|
-
if ((block.lang || '').toLowerCase() === 'mermaid') {
|
|
214
|
-
let box = null;
|
|
215
|
-
const entry = this._mermaidEntry(block.text);
|
|
216
|
-
if (entry.model) {
|
|
217
|
-
try {
|
|
218
|
-
box = layoutMermaid(entry.model, {
|
|
219
|
-
fonts,
|
|
220
|
-
size: Math.round(t.size * 0.82),
|
|
221
|
-
family: t.family,
|
|
222
|
-
maxWidth: width,
|
|
223
|
-
theme: { labelBg: t.background, text: t.color }
|
|
224
|
-
});
|
|
225
|
-
} catch {
|
|
226
|
-
// fall through to the plain code block
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
if (box) {
|
|
230
|
-
const bx = x + Math.max(0, (width - box.width) / 2);
|
|
231
|
-
this._items.push({ kind: 'tex', x: bx, y, box });
|
|
232
|
-
y += box.height;
|
|
233
|
-
break;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
174
|
// ```math / ```latex fences render as display-mode formulas
|
|
237
175
|
if (MATH_LANGS.has((block.lang || '').toLowerCase())) {
|
|
238
176
|
let box = null;
|