sketchmark 1.1.1 → 1.1.2
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.
Potentially problematic release.
This version of sketchmark might be problematic. Click here for more details.
- package/dist/index.cjs +187 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +187 -10
- package/dist/index.js.map +1 -1
- package/dist/sketchmark.iife.js +187 -10
- package/dist/ui/editor.d.ts +4 -0
- package/dist/ui/editor.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/sketchmark.iife.js
CHANGED
|
@@ -10568,13 +10568,13 @@ var AIDiagram = (function (exports) {
|
|
|
10568
10568
|
</head>
|
|
10569
10569
|
<body>
|
|
10570
10570
|
<div class="diagram">${svgStr}</div>
|
|
10571
|
-
<details class="dsl"><summary style="cursor:pointer;color:#f0c96a">DSL source</summary><pre>${escapeHtml(dslSource)}</pre></details>
|
|
10571
|
+
<details class="dsl"><summary style="cursor:pointer;color:#f0c96a">DSL source</summary><pre>${escapeHtml$1(dslSource)}</pre></details>
|
|
10572
10572
|
</body>
|
|
10573
10573
|
</html>`;
|
|
10574
10574
|
const blob = new Blob([html], { type: 'text/html;charset=utf-8' });
|
|
10575
10575
|
download(blob, opts.filename ?? 'diagram.html');
|
|
10576
10576
|
}
|
|
10577
|
-
function escapeHtml(s) {
|
|
10577
|
+
function escapeHtml$1(s) {
|
|
10578
10578
|
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
10579
10579
|
}
|
|
10580
10580
|
// ── GIF stub (requires gifshot or gif.js at runtime) ──────
|
|
@@ -10800,7 +10800,7 @@ var AIDiagram = (function (exports) {
|
|
|
10800
10800
|
.skm-canvas__viewport.is-panning{cursor:grabbing}
|
|
10801
10801
|
.skm-canvas--dark .skm-canvas__viewport{background:#12100a}
|
|
10802
10802
|
.skm-canvas__grid{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
|
|
10803
|
-
.skm-canvas__world{position:absolute;top:0;left:0;transform-origin:0 0;
|
|
10803
|
+
.skm-canvas__world{position:absolute;top:0;left:0;transform-origin:0 0;}
|
|
10804
10804
|
.skm-canvas__controls{position:absolute;right:14px;bottom:14px;display:flex;flex-direction:column;align-items:center;gap:4px;z-index:2}
|
|
10805
10805
|
.skm-canvas__zoom{min-width:40px;text-align:center;color:#8a6040;font-size:10px}
|
|
10806
10806
|
.skm-canvas__minimap{position:absolute;left:14px;bottom:14px;width:120px;height:80px;background:rgba(255,248,234,.94);border:1px solid #caba98;border-radius:6px;overflow:hidden;z-index:2}
|
|
@@ -11450,20 +11450,44 @@ var AIDiagram = (function (exports) {
|
|
|
11450
11450
|
color: #fff;
|
|
11451
11451
|
}
|
|
11452
11452
|
|
|
11453
|
-
.skm-
|
|
11453
|
+
.skm-editor__surface {
|
|
11454
|
+
position: relative;
|
|
11454
11455
|
flex: 1;
|
|
11455
|
-
width: 100%;
|
|
11456
11456
|
min-height: 0;
|
|
11457
|
-
border: 0;
|
|
11458
|
-
outline: 0;
|
|
11459
|
-
resize: none;
|
|
11460
11457
|
background: #1c1608;
|
|
11461
|
-
|
|
11458
|
+
overflow: hidden;
|
|
11459
|
+
}
|
|
11460
|
+
|
|
11461
|
+
.skm-editor__highlight,
|
|
11462
|
+
.skm-editor__input {
|
|
11463
|
+
position: absolute;
|
|
11464
|
+
inset: 0;
|
|
11465
|
+
width: 100%;
|
|
11466
|
+
height: 100%;
|
|
11462
11467
|
padding: 12px 14px;
|
|
11463
11468
|
font: inherit;
|
|
11464
11469
|
font-size: 12px;
|
|
11465
11470
|
line-height: 1.7;
|
|
11466
11471
|
tab-size: 2;
|
|
11472
|
+
white-space: pre-wrap;
|
|
11473
|
+
overflow: auto;
|
|
11474
|
+
}
|
|
11475
|
+
|
|
11476
|
+
.skm-editor__highlight {
|
|
11477
|
+
margin: 0;
|
|
11478
|
+
border: 0;
|
|
11479
|
+
background: #1c1608;
|
|
11480
|
+
color: #e0c898;
|
|
11481
|
+
pointer-events: none;
|
|
11482
|
+
word-break: break-word;
|
|
11483
|
+
}
|
|
11484
|
+
|
|
11485
|
+
.skm-editor__input {
|
|
11486
|
+
border: 0;
|
|
11487
|
+
outline: 0;
|
|
11488
|
+
resize: none;
|
|
11489
|
+
background: transparent;
|
|
11490
|
+
color: transparent;
|
|
11467
11491
|
caret-color: #f0c96a;
|
|
11468
11492
|
}
|
|
11469
11493
|
|
|
@@ -11471,6 +11495,40 @@ var AIDiagram = (function (exports) {
|
|
|
11471
11495
|
color: #80633b;
|
|
11472
11496
|
}
|
|
11473
11497
|
|
|
11498
|
+
.skm-editor__input::selection {
|
|
11499
|
+
background: rgba(240, 201, 106, 0.22);
|
|
11500
|
+
}
|
|
11501
|
+
|
|
11502
|
+
.skm-editor__token--keyword {
|
|
11503
|
+
color: #e07040;
|
|
11504
|
+
}
|
|
11505
|
+
|
|
11506
|
+
.skm-editor__token--property {
|
|
11507
|
+
color: #70a8d0;
|
|
11508
|
+
}
|
|
11509
|
+
|
|
11510
|
+
.skm-editor__token--string {
|
|
11511
|
+
color: #8db870;
|
|
11512
|
+
}
|
|
11513
|
+
|
|
11514
|
+
.skm-editor__token--number {
|
|
11515
|
+
color: #d4a020;
|
|
11516
|
+
}
|
|
11517
|
+
|
|
11518
|
+
.skm-editor__token--comment {
|
|
11519
|
+
color: #6a5a3a;
|
|
11520
|
+
}
|
|
11521
|
+
|
|
11522
|
+
.skm-editor__token--connector {
|
|
11523
|
+
color: #c8b070;
|
|
11524
|
+
}
|
|
11525
|
+
|
|
11526
|
+
.skm-editor__token--color {
|
|
11527
|
+
color: var(--skm-editor-color, #f0c96a);
|
|
11528
|
+
box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.08);
|
|
11529
|
+
font-weight: 600;
|
|
11530
|
+
}
|
|
11531
|
+
|
|
11474
11532
|
.skm-editor__error {
|
|
11475
11533
|
display: none;
|
|
11476
11534
|
flex-shrink: 0;
|
|
@@ -11487,12 +11545,112 @@ var AIDiagram = (function (exports) {
|
|
|
11487
11545
|
display: block;
|
|
11488
11546
|
}
|
|
11489
11547
|
`;
|
|
11548
|
+
const CONNECTORS = ["<-->", "<->", "-->", "<--", "---", "--", "->", "<-"];
|
|
11549
|
+
const HEX_COLOR_RE = /#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b/g;
|
|
11490
11550
|
function defaultFormatter(value) {
|
|
11491
11551
|
return normalizeNewlines(value)
|
|
11492
11552
|
.split("\n")
|
|
11493
11553
|
.map((line) => line.replace(/[ \t]+$/g, ""))
|
|
11494
11554
|
.join("\n");
|
|
11495
11555
|
}
|
|
11556
|
+
function escapeHtml(value) {
|
|
11557
|
+
return value
|
|
11558
|
+
.replace(/&/g, "&")
|
|
11559
|
+
.replace(/</g, "<")
|
|
11560
|
+
.replace(/>/g, ">")
|
|
11561
|
+
.replace(/"/g, """);
|
|
11562
|
+
}
|
|
11563
|
+
function wrapToken(kind, value) {
|
|
11564
|
+
return `<span class="skm-editor__token skm-editor__token--${kind}">${escapeHtml(value)}</span>`;
|
|
11565
|
+
}
|
|
11566
|
+
function renderColorLiteral(value) {
|
|
11567
|
+
return `<span class="skm-editor__token skm-editor__token--color" style="--skm-editor-color:${value}">${escapeHtml(value)}</span>`;
|
|
11568
|
+
}
|
|
11569
|
+
function renderStringToken(value) {
|
|
11570
|
+
HEX_COLOR_RE.lastIndex = 0;
|
|
11571
|
+
if (!HEX_COLOR_RE.test(value)) {
|
|
11572
|
+
return wrapToken("string", value);
|
|
11573
|
+
}
|
|
11574
|
+
HEX_COLOR_RE.lastIndex = 0;
|
|
11575
|
+
let html = "";
|
|
11576
|
+
let lastIndex = 0;
|
|
11577
|
+
let match = null;
|
|
11578
|
+
while ((match = HEX_COLOR_RE.exec(value))) {
|
|
11579
|
+
if (match.index > lastIndex) {
|
|
11580
|
+
html += wrapToken("string", value.slice(lastIndex, match.index));
|
|
11581
|
+
}
|
|
11582
|
+
html += renderColorLiteral(match[0]);
|
|
11583
|
+
lastIndex = match.index + match[0].length;
|
|
11584
|
+
}
|
|
11585
|
+
if (lastIndex < value.length) {
|
|
11586
|
+
html += wrapToken("string", value.slice(lastIndex));
|
|
11587
|
+
}
|
|
11588
|
+
return html;
|
|
11589
|
+
}
|
|
11590
|
+
function renderPlainToken(value, nextChar) {
|
|
11591
|
+
if (/^-?\d/.test(value)) {
|
|
11592
|
+
return wrapToken("number", value);
|
|
11593
|
+
}
|
|
11594
|
+
if (nextChar === "=") {
|
|
11595
|
+
return wrapToken("property", value);
|
|
11596
|
+
}
|
|
11597
|
+
if (KEYWORDS.has(value)) {
|
|
11598
|
+
return wrapToken("keyword", value);
|
|
11599
|
+
}
|
|
11600
|
+
return escapeHtml(value);
|
|
11601
|
+
}
|
|
11602
|
+
function highlightLine(line) {
|
|
11603
|
+
let html = "";
|
|
11604
|
+
let index = 0;
|
|
11605
|
+
while (index < line.length) {
|
|
11606
|
+
const rest = line.slice(index);
|
|
11607
|
+
if (rest.startsWith("//") || rest.startsWith("#")) {
|
|
11608
|
+
html += wrapToken("comment", rest);
|
|
11609
|
+
break;
|
|
11610
|
+
}
|
|
11611
|
+
if (line[index] === "\"") {
|
|
11612
|
+
let end = index + 1;
|
|
11613
|
+
while (end < line.length) {
|
|
11614
|
+
if (line[end] === "\"" && line[end - 1] !== "\\") {
|
|
11615
|
+
end += 1;
|
|
11616
|
+
break;
|
|
11617
|
+
}
|
|
11618
|
+
end += 1;
|
|
11619
|
+
}
|
|
11620
|
+
html += renderStringToken(line.slice(index, end));
|
|
11621
|
+
index = end;
|
|
11622
|
+
continue;
|
|
11623
|
+
}
|
|
11624
|
+
const connector = CONNECTORS.find((candidate) => line.startsWith(candidate, index));
|
|
11625
|
+
if (connector) {
|
|
11626
|
+
html += wrapToken("connector", connector);
|
|
11627
|
+
index += connector.length;
|
|
11628
|
+
continue;
|
|
11629
|
+
}
|
|
11630
|
+
const wordMatch = /^[A-Za-z_][A-Za-z0-9_-]*/.exec(rest);
|
|
11631
|
+
if (wordMatch) {
|
|
11632
|
+
const word = wordMatch[0];
|
|
11633
|
+
const nextChar = line[index + word.length] ?? "";
|
|
11634
|
+
html += renderPlainToken(word, nextChar);
|
|
11635
|
+
index += word.length;
|
|
11636
|
+
continue;
|
|
11637
|
+
}
|
|
11638
|
+
const numberMatch = /^-?\d+(?:\.\d+)?/.exec(rest);
|
|
11639
|
+
if (numberMatch) {
|
|
11640
|
+
html += wrapToken("number", numberMatch[0]);
|
|
11641
|
+
index += numberMatch[0].length;
|
|
11642
|
+
continue;
|
|
11643
|
+
}
|
|
11644
|
+
html += escapeHtml(line[index]);
|
|
11645
|
+
index += 1;
|
|
11646
|
+
}
|
|
11647
|
+
return html;
|
|
11648
|
+
}
|
|
11649
|
+
function renderHighlightedValue(value) {
|
|
11650
|
+
const normalized = normalizeNewlines(value);
|
|
11651
|
+
const html = normalized.split("\n").map(highlightLine).join("\n");
|
|
11652
|
+
return html || " ";
|
|
11653
|
+
}
|
|
11496
11654
|
class SketchmarkEditor {
|
|
11497
11655
|
constructor(options) {
|
|
11498
11656
|
this.emitter = new EventEmitter();
|
|
@@ -11529,16 +11687,23 @@ var AIDiagram = (function (exports) {
|
|
|
11529
11687
|
if (options.showClearButton !== false)
|
|
11530
11688
|
this.toolbar.appendChild(clearButton);
|
|
11531
11689
|
this.toolbar.appendChild(hint);
|
|
11690
|
+
this.surface = document.createElement("div");
|
|
11691
|
+
this.surface.className = "skm-editor__surface";
|
|
11692
|
+
this.highlightElement = document.createElement("pre");
|
|
11693
|
+
this.highlightElement.className = "skm-editor__highlight";
|
|
11694
|
+
this.highlightElement.setAttribute("aria-hidden", "true");
|
|
11532
11695
|
this.textarea = document.createElement("textarea");
|
|
11533
11696
|
this.textarea.className = "skm-editor__input";
|
|
11534
11697
|
this.textarea.spellcheck = false;
|
|
11535
11698
|
this.textarea.placeholder = options.placeholder ?? "diagram\nbox a label=\"Hello\"\nend";
|
|
11536
11699
|
this.textarea.value = normalizeNewlines(options.value ?? DEFAULT_CLEAR_VALUE);
|
|
11537
11700
|
this.textarea.addEventListener("input", () => {
|
|
11701
|
+
this.syncHighlight();
|
|
11538
11702
|
const payload = { value: this.getValue(), editor: this };
|
|
11539
11703
|
options.onChange?.(payload.value, this);
|
|
11540
11704
|
this.emitter.emit("change", payload);
|
|
11541
11705
|
});
|
|
11706
|
+
this.textarea.addEventListener("scroll", () => this.syncScroll());
|
|
11542
11707
|
this.textarea.addEventListener("keydown", (event) => {
|
|
11543
11708
|
if ((event.ctrlKey || event.metaKey) && event.key === "Enter") {
|
|
11544
11709
|
event.preventDefault();
|
|
@@ -11550,9 +11715,12 @@ var AIDiagram = (function (exports) {
|
|
|
11550
11715
|
if (options.showToolbar !== false) {
|
|
11551
11716
|
this.root.appendChild(this.toolbar);
|
|
11552
11717
|
}
|
|
11553
|
-
this.
|
|
11718
|
+
this.surface.appendChild(this.highlightElement);
|
|
11719
|
+
this.surface.appendChild(this.textarea);
|
|
11720
|
+
this.root.appendChild(this.surface);
|
|
11554
11721
|
this.root.appendChild(this.errorElement);
|
|
11555
11722
|
host.appendChild(this.root);
|
|
11723
|
+
this.syncHighlight();
|
|
11556
11724
|
if (options.autoFocus) {
|
|
11557
11725
|
this.focus();
|
|
11558
11726
|
}
|
|
@@ -11562,6 +11730,7 @@ var AIDiagram = (function (exports) {
|
|
|
11562
11730
|
}
|
|
11563
11731
|
setValue(value, emitChange = false) {
|
|
11564
11732
|
this.textarea.value = normalizeNewlines(value);
|
|
11733
|
+
this.syncHighlight();
|
|
11565
11734
|
if (emitChange) {
|
|
11566
11735
|
const payload = { value: this.getValue(), editor: this };
|
|
11567
11736
|
this.options.onChange?.(payload.value, this);
|
|
@@ -11603,6 +11772,14 @@ var AIDiagram = (function (exports) {
|
|
|
11603
11772
|
destroy() {
|
|
11604
11773
|
this.root.remove();
|
|
11605
11774
|
}
|
|
11775
|
+
syncHighlight() {
|
|
11776
|
+
this.highlightElement.innerHTML = renderHighlightedValue(this.textarea.value);
|
|
11777
|
+
this.syncScroll();
|
|
11778
|
+
}
|
|
11779
|
+
syncScroll() {
|
|
11780
|
+
this.highlightElement.scrollTop = this.textarea.scrollTop;
|
|
11781
|
+
this.highlightElement.scrollLeft = this.textarea.scrollLeft;
|
|
11782
|
+
}
|
|
11606
11783
|
}
|
|
11607
11784
|
|
|
11608
11785
|
const EMBED_STYLE_ID = "sketchmark-embed-ui";
|
package/dist/ui/editor.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export interface SketchmarkEditorEvents extends Record<string, unknown> {
|
|
|
29
29
|
export declare class SketchmarkEditor {
|
|
30
30
|
readonly root: HTMLDivElement;
|
|
31
31
|
readonly toolbar: HTMLDivElement;
|
|
32
|
+
readonly surface: HTMLDivElement;
|
|
33
|
+
readonly highlightElement: HTMLPreElement;
|
|
32
34
|
readonly textarea: HTMLTextAreaElement;
|
|
33
35
|
readonly errorElement: HTMLDivElement;
|
|
34
36
|
private readonly emitter;
|
|
@@ -44,5 +46,7 @@ export declare class SketchmarkEditor {
|
|
|
44
46
|
clearError(): void;
|
|
45
47
|
on<K extends keyof SketchmarkEditorEvents>(event: K, listener: (payload: SketchmarkEditorEvents[K]) => void): () => void;
|
|
46
48
|
destroy(): void;
|
|
49
|
+
private syncHighlight;
|
|
50
|
+
private syncScroll;
|
|
47
51
|
}
|
|
48
52
|
//# sourceMappingURL=editor.d.ts.map
|
package/dist/ui/editor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/ui/editor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/ui/editor.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAiKlB,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7D,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAC3D;AAED,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAuB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACrE,MAAM,EAAE,4BAA4B,CAAC;IACrC,GAAG,EAAE,4BAA4B,CAAC;IAClC,KAAK,EAAE,4BAA4B,CAAC;IACpC,MAAM,EAAE,4BAA4B,CAAC;CACtC;AAiID,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,gBAAgB,EAAE,cAAc,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;IAEtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8C;IACtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;gBAEtC,OAAO,EAAE,uBAAuB;IAsF5C,QAAQ,IAAI,MAAM;IAIlB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,UAAQ,GAAG,IAAI;IAUjD,KAAK,IAAI,IAAI;IAIb,MAAM,IAAI,IAAI;IAOd,KAAK,IAAI,IAAI;IAOb,GAAG,IAAI,IAAI;IAMX,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKhC,UAAU,IAAI,IAAI;IAKlB,EAAE,CAAC,CAAC,SAAS,MAAM,sBAAsB,EACvC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,GACrD,MAAM,IAAI;IAKb,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,UAAU;CAInB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sketchmark",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "A plain-text DSL for hand-drawn diagrams. Write boxes, edges, and groups as code — renders sketchy SVG/Canvas via rough.js with a built-in step-by-step animation system.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"diagram",
|