sketchmark 0.2.3 → 0.2.5
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/dist/ast/types.d.ts +2 -1
- package/dist/ast/types.d.ts.map +1 -1
- package/dist/index.cjs +134 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +134 -20
- package/dist/index.js.map +1 -1
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/tokenizer.d.ts.map +1 -1
- package/dist/renderer/canvas/index.d.ts.map +1 -1
- package/dist/renderer/svg/index.d.ts.map +1 -1
- package/dist/scene/index.d.ts +1 -0
- package/dist/scene/index.d.ts.map +1 -1
- package/dist/sketchmark.iife.js +134 -20
- package/package.json +1 -1
package/dist/ast/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type NodeShape = 'box' | 'circle' | 'diamond' | 'hexagon' | 'triangle' | 'cylinder' | 'parallelogram' | 'text' | 'image';
|
|
1
|
+
export type NodeShape = 'box' | 'circle' | 'diamond' | 'hexagon' | 'triangle' | 'cylinder' | 'parallelogram' | 'text' | 'image' | 'icon';
|
|
2
2
|
export type EdgeConnector = '->' | '<-' | '<->' | '-->' | '<-->' | '---' | '--';
|
|
3
3
|
export type LayoutType = 'row' | 'column' | 'grid';
|
|
4
4
|
export type AlignItems = 'start' | 'center' | 'end';
|
|
@@ -66,6 +66,7 @@ export interface ASTNode {
|
|
|
66
66
|
label: string;
|
|
67
67
|
groupId?: string;
|
|
68
68
|
imageUrl?: string;
|
|
69
|
+
iconName?: string;
|
|
69
70
|
width?: number;
|
|
70
71
|
height?: number;
|
|
71
72
|
theme?: string;
|
package/dist/ast/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ast/types.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GACjB,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GACrD,UAAU,GAAG,eAAe,GAAG,MAAM,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ast/types.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -19,6 +19,7 @@ const KEYWORDS = new Set([
|
|
|
19
19
|
"parallelogram",
|
|
20
20
|
"text",
|
|
21
21
|
"image",
|
|
22
|
+
"icon",
|
|
22
23
|
"group",
|
|
23
24
|
"style",
|
|
24
25
|
"step",
|
|
@@ -232,6 +233,7 @@ const SHAPES = [
|
|
|
232
233
|
"parallelogram",
|
|
233
234
|
"text",
|
|
234
235
|
"image",
|
|
236
|
+
"icon",
|
|
235
237
|
];
|
|
236
238
|
const CHART_TYPES = [
|
|
237
239
|
"bar-chart",
|
|
@@ -422,7 +424,7 @@ function parse(src) {
|
|
|
422
424
|
kind: "node",
|
|
423
425
|
id,
|
|
424
426
|
shape,
|
|
425
|
-
label: props.label || id,
|
|
427
|
+
label: props.label || (shape === "image" || shape === "icon" ? "" : id),
|
|
426
428
|
...(groupId ? { groupId } : {}),
|
|
427
429
|
...(props.width ? { width: parseFloat(props.width) } : {}),
|
|
428
430
|
...(props.height ? { height: parseFloat(props.height) } : {}),
|
|
@@ -431,6 +433,8 @@ function parse(src) {
|
|
|
431
433
|
};
|
|
432
434
|
if (props.url)
|
|
433
435
|
node.imageUrl = props.url;
|
|
436
|
+
if (props.name)
|
|
437
|
+
node.iconName = props.name;
|
|
434
438
|
return node;
|
|
435
439
|
}
|
|
436
440
|
function parseEdge(fromId, connector, rest) {
|
|
@@ -499,7 +503,7 @@ function parse(src) {
|
|
|
499
503
|
j++;
|
|
500
504
|
}
|
|
501
505
|
// Support multiline via literal \n in label string
|
|
502
|
-
const rawLabel = props.label ??
|
|
506
|
+
const rawLabel = props.label ?? "";
|
|
503
507
|
return {
|
|
504
508
|
kind: "note",
|
|
505
509
|
id,
|
|
@@ -1278,6 +1282,7 @@ function buildSceneGraph(ast) {
|
|
|
1278
1282
|
height: n.height,
|
|
1279
1283
|
meta: n.meta,
|
|
1280
1284
|
imageUrl: n.imageUrl,
|
|
1285
|
+
iconName: n.iconName,
|
|
1281
1286
|
x: 0,
|
|
1282
1287
|
y: 0,
|
|
1283
1288
|
w: 0,
|
|
@@ -1504,6 +1509,10 @@ function sizeNode(n) {
|
|
|
1504
1509
|
}
|
|
1505
1510
|
break;
|
|
1506
1511
|
}
|
|
1512
|
+
case "icon":
|
|
1513
|
+
n.w = n.w || 48;
|
|
1514
|
+
n.h = n.h || (n.label !== n.id ? 64 : 48); // extra height for label
|
|
1515
|
+
break;
|
|
1507
1516
|
default:
|
|
1508
1517
|
n.w = n.w || Math.max(MIN_W, Math.min(MAX_W, labelW));
|
|
1509
1518
|
n.h = n.h || 52;
|
|
@@ -1540,9 +1549,8 @@ function sizeTable(t) {
|
|
|
1540
1549
|
const nData = rows.filter((r) => r.kind === "data").length;
|
|
1541
1550
|
t.h = labelH + nHeader * headerH + nData * rowH;
|
|
1542
1551
|
}
|
|
1543
|
-
function sizeChart(
|
|
1544
|
-
|
|
1545
|
-
c.h = c.h || 240;
|
|
1552
|
+
function sizeChart(_c) {
|
|
1553
|
+
// defaults already applied in buildSceneGraph
|
|
1546
1554
|
}
|
|
1547
1555
|
function sizeMarkdown(m) {
|
|
1548
1556
|
const pad = Number(m.style?.padding ?? 16);
|
|
@@ -5100,6 +5108,58 @@ function renderShape$1(rc, n, palette) {
|
|
|
5100
5108
|
}
|
|
5101
5109
|
case "text":
|
|
5102
5110
|
return [];
|
|
5111
|
+
case "icon": {
|
|
5112
|
+
if (n.iconName) {
|
|
5113
|
+
const [prefix, name] = n.iconName.includes(":")
|
|
5114
|
+
? n.iconName.split(":", 2)
|
|
5115
|
+
: ["mdi", n.iconName];
|
|
5116
|
+
const iconColor = s.color
|
|
5117
|
+
? encodeURIComponent(String(s.color))
|
|
5118
|
+
: encodeURIComponent(String(palette.nodeStroke));
|
|
5119
|
+
const iconSize = Math.min(n.w, n.h) - 4;
|
|
5120
|
+
const iconUrl = `https://api.iconify.design/${prefix}/${name}.svg?color=${iconColor}&width=${iconSize}&height=${iconSize}`;
|
|
5121
|
+
const img = document.createElementNS(NS, "image");
|
|
5122
|
+
img.setAttribute("href", iconUrl);
|
|
5123
|
+
img.setAttribute("x", String(n.x + 1));
|
|
5124
|
+
img.setAttribute("y", String(n.y + 1));
|
|
5125
|
+
img.setAttribute("width", String(n.w - 2));
|
|
5126
|
+
img.setAttribute("height", String(n.h - 2));
|
|
5127
|
+
img.setAttribute("preserveAspectRatio", "xMidYMid meet");
|
|
5128
|
+
if (s.opacity != null)
|
|
5129
|
+
img.setAttribute("opacity", String(s.opacity));
|
|
5130
|
+
// clip-path for rounded corners (same as image)
|
|
5131
|
+
const clipId = `clip-${n.id}`;
|
|
5132
|
+
const defs = document.createElementNS(NS, "defs");
|
|
5133
|
+
const clip = document.createElementNS(NS, "clipPath");
|
|
5134
|
+
clip.setAttribute("id", clipId);
|
|
5135
|
+
const rect = document.createElementNS(NS, "rect");
|
|
5136
|
+
rect.setAttribute("x", String(n.x + 1));
|
|
5137
|
+
rect.setAttribute("y", String(n.y + 1));
|
|
5138
|
+
rect.setAttribute("width", String(n.w - 2));
|
|
5139
|
+
rect.setAttribute("height", String(n.h - 2));
|
|
5140
|
+
rect.setAttribute("rx", "6");
|
|
5141
|
+
clip.appendChild(rect);
|
|
5142
|
+
defs.appendChild(clip);
|
|
5143
|
+
img.setAttribute("clip-path", `url(#${clipId})`);
|
|
5144
|
+
// only draw border when stroke is explicitly set
|
|
5145
|
+
const els = [defs, img];
|
|
5146
|
+
if (s.stroke) {
|
|
5147
|
+
els.push(rc.rectangle(n.x + 1, n.y + 1, n.w - 2, n.h - 2, {
|
|
5148
|
+
...opts,
|
|
5149
|
+
fill: "none",
|
|
5150
|
+
}));
|
|
5151
|
+
}
|
|
5152
|
+
return els;
|
|
5153
|
+
}
|
|
5154
|
+
// fallback: placeholder square
|
|
5155
|
+
return [
|
|
5156
|
+
rc.rectangle(n.x + 1, n.y + 1, n.w - 2, n.h - 2, {
|
|
5157
|
+
...opts,
|
|
5158
|
+
fill: "#e0e0e0",
|
|
5159
|
+
stroke: "#999999",
|
|
5160
|
+
}),
|
|
5161
|
+
];
|
|
5162
|
+
}
|
|
5103
5163
|
case "image": {
|
|
5104
5164
|
if (n.imageUrl) {
|
|
5105
5165
|
const img = document.createElementNS(NS, "image");
|
|
@@ -5122,11 +5182,15 @@ function renderShape$1(rc, n, palette) {
|
|
|
5122
5182
|
clip.appendChild(rect);
|
|
5123
5183
|
defs.appendChild(clip);
|
|
5124
5184
|
img.setAttribute("clip-path", `url(#${clipId})`);
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5185
|
+
// only draw border when stroke is explicitly set
|
|
5186
|
+
const els = [defs, img];
|
|
5187
|
+
if (s.stroke) {
|
|
5188
|
+
els.push(rc.rectangle(n.x + 1, n.y + 1, n.w - 2, n.h - 2, {
|
|
5189
|
+
...opts,
|
|
5190
|
+
fill: "none",
|
|
5191
|
+
}));
|
|
5192
|
+
}
|
|
5193
|
+
return els;
|
|
5130
5194
|
}
|
|
5131
5195
|
return [
|
|
5132
5196
|
rc.rectangle(n.x + 1, n.y + 1, n.w - 2, n.h - 2, {
|
|
@@ -5370,9 +5434,11 @@ function renderToSVG(sg, container, options = {}) {
|
|
|
5370
5434
|
: verticalAlign === "bottom"
|
|
5371
5435
|
? nodeBodyBottom - blockH / 2
|
|
5372
5436
|
: nodeBodyMid;
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5437
|
+
if (n.label) {
|
|
5438
|
+
ng.appendChild(lines.length > 1
|
|
5439
|
+
? mkMultilineText(lines, textX, textCY, fontSize, fontWeight, textColor, textAnchor, lineHeight, nodeFont, letterSpacing)
|
|
5440
|
+
: mkText(n.label, textX, textCY, fontSize, fontWeight, textColor, textAnchor, nodeFont, letterSpacing));
|
|
5441
|
+
}
|
|
5376
5442
|
if (options.interactive) {
|
|
5377
5443
|
ng.style.cursor = "pointer";
|
|
5378
5444
|
ng.addEventListener("click", () => options.onNodeClick?.(n.id));
|
|
@@ -5564,7 +5630,6 @@ function renderToSVG(sg, container, options = {}) {
|
|
|
5564
5630
|
NoteL.appendChild(ng);
|
|
5565
5631
|
}
|
|
5566
5632
|
svg.appendChild(NoteL);
|
|
5567
|
-
markdownMap(sg);
|
|
5568
5633
|
const MDL = mkGroup('markdown-layer');
|
|
5569
5634
|
for (const m of sg.markdowns) {
|
|
5570
5635
|
const mg = mkGroup(`markdown-${m.id}`, 'mdg');
|
|
@@ -6071,6 +6136,50 @@ function renderShape(rc, ctx, n, palette, R) {
|
|
|
6071
6136
|
break;
|
|
6072
6137
|
case 'text':
|
|
6073
6138
|
break; // no shape drawn
|
|
6139
|
+
case 'icon': {
|
|
6140
|
+
if (n.iconName) {
|
|
6141
|
+
const [prefix, name] = n.iconName.includes(':')
|
|
6142
|
+
? n.iconName.split(':', 2)
|
|
6143
|
+
: ['mdi', n.iconName];
|
|
6144
|
+
const iconColor = s.color
|
|
6145
|
+
? encodeURIComponent(String(s.color))
|
|
6146
|
+
: encodeURIComponent(String(palette.nodeStroke));
|
|
6147
|
+
const iconSize = Math.min(n.w, n.h) - 4;
|
|
6148
|
+
const iconUrl = `https://api.iconify.design/${prefix}/${name}.svg?color=${iconColor}&width=${iconSize}&height=${iconSize}`;
|
|
6149
|
+
const img = new Image();
|
|
6150
|
+
img.crossOrigin = 'anonymous';
|
|
6151
|
+
img.onload = () => {
|
|
6152
|
+
ctx.save();
|
|
6153
|
+
if (s.opacity != null)
|
|
6154
|
+
ctx.globalAlpha = Number(s.opacity);
|
|
6155
|
+
// clip-path for rounded corners (same as image)
|
|
6156
|
+
ctx.beginPath();
|
|
6157
|
+
const r = 6;
|
|
6158
|
+
ctx.moveTo(n.x + r, n.y);
|
|
6159
|
+
ctx.lineTo(n.x + n.w - r, n.y);
|
|
6160
|
+
ctx.quadraticCurveTo(n.x + n.w, n.y, n.x + n.w, n.y + r);
|
|
6161
|
+
ctx.lineTo(n.x + n.w, n.y + n.h - r);
|
|
6162
|
+
ctx.quadraticCurveTo(n.x + n.w, n.y + n.h, n.x + n.w - r, n.y + n.h);
|
|
6163
|
+
ctx.lineTo(n.x + r, n.y + n.h);
|
|
6164
|
+
ctx.quadraticCurveTo(n.x, n.y + n.h, n.x, n.y + n.h - r);
|
|
6165
|
+
ctx.lineTo(n.x, n.y + r);
|
|
6166
|
+
ctx.quadraticCurveTo(n.x, n.y, n.x + r, n.y);
|
|
6167
|
+
ctx.closePath();
|
|
6168
|
+
ctx.clip();
|
|
6169
|
+
ctx.drawImage(img, n.x + 1, n.y + 1, n.w - 2, n.h - 2);
|
|
6170
|
+
ctx.restore();
|
|
6171
|
+
// only draw border when stroke is explicitly set
|
|
6172
|
+
if (s.stroke) {
|
|
6173
|
+
rc.rectangle(n.x + 1, n.y + 1, n.w - 2, n.h - 2, { ...opts, fill: 'none' });
|
|
6174
|
+
}
|
|
6175
|
+
};
|
|
6176
|
+
img.src = iconUrl;
|
|
6177
|
+
}
|
|
6178
|
+
else {
|
|
6179
|
+
rc.rectangle(n.x + 1, n.y + 1, n.w - 2, n.h - 2, { ...opts, fill: '#e0e0e0', stroke: '#999999' });
|
|
6180
|
+
}
|
|
6181
|
+
return;
|
|
6182
|
+
}
|
|
6074
6183
|
case 'image': {
|
|
6075
6184
|
if (n.imageUrl) {
|
|
6076
6185
|
const img = new Image();
|
|
@@ -6092,7 +6201,10 @@ function renderShape(rc, ctx, n, palette, R) {
|
|
|
6092
6201
|
ctx.clip();
|
|
6093
6202
|
ctx.drawImage(img, n.x + 1, n.y + 1, n.w - 2, n.h - 2);
|
|
6094
6203
|
ctx.restore();
|
|
6095
|
-
|
|
6204
|
+
// only draw border when stroke is explicitly set
|
|
6205
|
+
if (s.stroke) {
|
|
6206
|
+
rc.rectangle(n.x + 1, n.y + 1, n.w - 2, n.h - 2, { ...opts, fill: 'none' });
|
|
6207
|
+
}
|
|
6096
6208
|
};
|
|
6097
6209
|
img.src = n.imageUrl;
|
|
6098
6210
|
}
|
|
@@ -6282,11 +6394,13 @@ function renderToCanvas(sg, canvas, options = {}) {
|
|
|
6282
6394
|
const textCY = vertAlign === 'top' ? nodeBodyTop + blockH / 2
|
|
6283
6395
|
: vertAlign === 'bottom' ? nodeBodyBottom - blockH / 2
|
|
6284
6396
|
: n.y + n.h / 2; // middle (default)
|
|
6285
|
-
if (
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6397
|
+
if (n.label) {
|
|
6398
|
+
if (lines.length > 1) {
|
|
6399
|
+
drawMultilineText(ctx, lines, textX, textCY, fontSize, fontWeight, textColor, textAlign, lineHeight, nodeFont, letterSpacing);
|
|
6400
|
+
}
|
|
6401
|
+
else {
|
|
6402
|
+
drawText(ctx, lines[0] ?? '', textX, textCY, fontSize, fontWeight, textColor, textAlign, nodeFont, letterSpacing);
|
|
6403
|
+
}
|
|
6290
6404
|
}
|
|
6291
6405
|
if (n.style?.opacity != null)
|
|
6292
6406
|
ctx.globalAlpha = 1;
|