From 9bb784e6f06ccd052e41da545c06c59100dd89c0 Mon Sep 17 00:00:00 2001
From: Myriad-Dreamin <35292584+Myriad-Dreamin@users.noreply.github.com>
Date: Wed, 9 Jul 2025 19:34:57 +0800
Subject: [PATCH] feat: run prettier correctly (#1893)
---
.prettierignore | 1 +
editors/vscode/scripts/check-version.mjs | 18 +--
editors/vscode/scripts/postinstall.cjs | 30 ++---
editors/vscode/src/features/preview-compat.ts | 2 +-
package.json | 2 +-
tools/editor-tools/src/components/modal.ts | 11 +-
.../editor-tools/src/features/diagnostics.ts | 20 +--
tools/editor-tools/src/features/docs.ts | 127 +++++++-----------
tools/editor-tools/src/features/font-view.ts | 121 +++++++----------
.../editor-tools/src/features/symbol-view.ts | 97 ++++++-------
.../src/features/template-gallery.ts | 104 ++++++--------
tools/editor-tools/src/utils.ts | 6 +-
tools/editor-tools/vite.config.js | 14 +-
tools/typst-dom/src/index.mts | 2 +-
tools/typst-dom/src/index.preview.mts | 4 +-
tools/typst-dom/src/typst-animation.mts | 2 +-
tools/typst-dom/src/typst-doc.canvas.mts | 80 ++++-------
tools/typst-dom/src/typst-doc.test.mts | 16 +--
tools/typst-dom/src/typst-outline.mts | 48 ++-----
tools/typst-dom/src/typst-patch.mts | 16 +--
tools/typst-dom/src/typst-patch.svg.mts | 25 ++--
tools/typst-dom/src/typst-patch.test.mts | 82 +++--------
tools/typst-preview-frontend/src/drag.ts | 89 ++++++------
23 files changed, 351 insertions(+), 566 deletions(-)
diff --git a/.prettierignore b/.prettierignore
index 8ffa0a072..cb2468c19 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -8,6 +8,7 @@ target/**
dist/**
icons/
node_modules/
+editors/vscode/test-dist/
editors/vscode/out/
editors/vscode/.vscode-test/**
*.toml
diff --git a/editors/vscode/scripts/check-version.mjs b/editors/vscode/scripts/check-version.mjs
index 428e0f4cf..c6e002d14 100644
--- a/editors/vscode/scripts/check-version.mjs
+++ b/editors/vscode/scripts/check-version.mjs
@@ -1,15 +1,15 @@
-
-import { readFileSync } from 'fs';
-
+import { readFileSync } from "fs";
function check() {
- const cargoToml = readFileSync('../../Cargo.toml', 'utf8');
- const cargoVersion = cargoToml.match(/version = "(.*?)"/)[1];
- const pkgVersion = JSON.parse(readFileSync('package.json', 'utf8')).version;
+ const cargoToml = readFileSync("../../Cargo.toml", "utf8");
+ const cargoVersion = cargoToml.match(/version = "(.*?)"/)[1];
+ const pkgVersion = JSON.parse(readFileSync("package.json", "utf8")).version;
- if (cargoVersion !== pkgVersion) {
- throw new Error(`Version mismatch: ${cargoVersion} (in Cargo.toml) !== ${pkgVersion} (in package.json)`);
- }
+ if (cargoVersion !== pkgVersion) {
+ throw new Error(
+ `Version mismatch: ${cargoVersion} (in Cargo.toml) !== ${pkgVersion} (in package.json)`,
+ );
+ }
}
check();
diff --git a/editors/vscode/scripts/postinstall.cjs b/editors/vscode/scripts/postinstall.cjs
index 01e808e50..4d81c6c47 100644
--- a/editors/vscode/scripts/postinstall.cjs
+++ b/editors/vscode/scripts/postinstall.cjs
@@ -1,28 +1,24 @@
+const path = require("path");
+const fs = require("fs");
+const rimraf = require("rimraf");
-const path = require('path');
-const fs = require('fs');
-const rimraf = require('rimraf');
+const vscodeDir = path.join(__dirname, "../");
+const editorToolsDir = path.join(vscodeDir, "../../tools/editor-tools/");
-const vscodeDir = path.join(__dirname, '../');
-const editorToolsDir = path.join(vscodeDir, '../../tools/editor-tools/');
-
-rimraf.sync(path.join(vscodeDir, 'out/editor-tools/'));
-fs.mkdirSync(path.join(vscodeDir, 'out/editor-tools/'), { recursive: true });
+rimraf.sync(path.join(vscodeDir, "out/editor-tools/"));
+fs.mkdirSync(path.join(vscodeDir, "out/editor-tools/"), { recursive: true });
function copyDir(src, dest) {
fs.readdirSync(src).forEach((item) => {
const srcPath = path.join(src, item);
const destPath = path.join(dest, item);
if (fs.lstatSync(srcPath).isDirectory()) {
- fs.mkdirSync(destPath,
- { recursive: true });
- copyDir(srcPath, destPath);
+ fs.mkdirSync(destPath, { recursive: true });
+ copyDir(srcPath, destPath);
+ } else {
+ fs.copyFileSync(srcPath, destPath);
}
- else {
- fs.copyFileSync(srcPath, destPath);
- }
-});
+ });
}
-copyDir(path.join(editorToolsDir, "dist"), path.join(vscodeDir, 'out/editor-tools/'));
-
+copyDir(path.join(editorToolsDir, "dist"), path.join(vscodeDir, "out/editor-tools/"));
diff --git a/editors/vscode/src/features/preview-compat.ts b/editors/vscode/src/features/preview-compat.ts
index 33fac54e3..0b0a6a8f5 100644
--- a/editors/vscode/src/features/preview-compat.ts
+++ b/editors/vscode/src/features/preview-compat.ts
@@ -681,4 +681,4 @@ export const revealDocumentCompat = async (args: any) => {
export const ejectPreviewPanelCompat = async () => {
vscode.window.showWarningMessage("Eject is not supported in compat mode");
-}
+};
diff --git a/package.json b/package.json
index 5077bbcab..293062db7 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
"tools/typst-preview-frontend"
],
"scripts": {
- "fmt": "cargo fmt --all && npx prettier tools/**/*.{js,mjs,cjs,ts,mts,cts} editors/vscode/**/*.{js,mjs,cjs,ts,mts,cts}",
+ "fmt": "cargo fmt --all && npx prettier --write tools/**/*.{js,mjs,cjs,ts,mts,cts} editors/vscode/**/*.{js,mjs,cjs,ts,mts,cts}",
"fmt:check": "cargo fmt --check --all && prettier --check tools/**/*.{js,mjs,cjs,ts,mts,cts} editors/vscode/**/*.{js,mjs,cjs,ts,mts,cts}",
"build:editor-tools": "cd tools/editor-tools/ && yarn run build",
"build:preview": "cd tools/typst-preview-frontend && yarn run build && rimraf ../../crates/tinymist-assets/src/typst-preview.html && cpr ./dist/index.html ../../crates/tinymist-assets/src/typst-preview.html",
diff --git a/tools/editor-tools/src/components/modal.ts b/tools/editor-tools/src/components/modal.ts
index 65f934851..25e901d9d 100644
--- a/tools/editor-tools/src/components/modal.ts
+++ b/tools/editor-tools/src/components/modal.ts
@@ -37,7 +37,7 @@ export function startModal(...contents: Node[]) {
{
class: "tinymist-button",
},
- "Close"
+ "Close",
);
const keydownHandler = (e: KeyboardEvent) => {
if (e.key === "Escape" || e.key === " " || e.key === "Enter") {
@@ -58,15 +58,12 @@ export function startModal(...contents: Node[]) {
{
class: "tinymist-button",
style: "margin-left: 0.5em",
- title:
- "Click the close button or press esc/space/enter to close this window",
+ title: "Click the close button or press esc/space/enter to close this window",
},
- "Help"
+ "Help",
);
help.onclick = () => {
- alert(
- "Click the close button or press esc/space/enter to close this window"
- );
+ alert("Click the close button or press esc/space/enter to close this window");
};
floatingWindow.appendChild(help);
diff --git a/tools/editor-tools/src/features/diagnostics.ts b/tools/editor-tools/src/features/diagnostics.ts
index ec4f2aeab..95edc4346 100644
--- a/tools/editor-tools/src/features/diagnostics.ts
+++ b/tools/editor-tools/src/features/diagnostics.ts
@@ -22,8 +22,8 @@ export const Diagnostics = () => {
`: error occurred in this call of function \`f\``,
br(),
a({ href: "javascript:void(0)" }, `test.typ(6, 2)`),
- `: error occurred in this call of function \`g\``
- )
+ `: error occurred in this call of function \`g\``,
+ ),
),
div(
{ class: `tinymist-card`, style: "flex: 1; width: 100%; padding: 10px" },
@@ -44,7 +44,7 @@ export const Diagnostics = () => {
},
`#let f(x, y) = `,
span({ style: "text-decoration: underline" }, `x + y`),
- `;`
+ `;`,
),
br(),
"where ",
@@ -61,7 +61,7 @@ export const Diagnostics = () => {
"2nd",
" function parameter of ",
code(a({ href: "javascript:void(0)" }, `f`)),
- "."
+ ".",
),
div(
{
@@ -82,7 +82,7 @@ export const Diagnostics = () => {
},
`#let g(x, y, z) = `,
span({ style: "text-decoration: underline" }, `f(x, y)`),
- ` + z;`
+ ` + z;`,
),
br(),
"where ",
@@ -99,7 +99,7 @@ export const Diagnostics = () => {
"2nd",
" function parameter of ",
code(a({ href: "javascript:void(0)" }, `g`)),
- "."
+ ".",
),
div(
{
@@ -120,9 +120,9 @@ export const Diagnostics = () => {
},
`#`,
span({ style: "text-decoration: underline" }, `g(1, left, red)`),
- `;`
- )
- )
- )
+ `;`,
+ ),
+ ),
+ ),
);
};
diff --git a/tools/editor-tools/src/features/docs.ts b/tools/editor-tools/src/features/docs.ts
index 597d4d0a2..7111a42be 100644
--- a/tools/editor-tools/src/features/docs.ts
+++ b/tools/editor-tools/src/features/docs.ts
@@ -40,8 +40,8 @@ export const Docs = () => {
const v = parsedDocs.val;
// console.log("updated", v);
return div(MakeDoc(v));
- }
- )
+ },
+ ),
);
};
@@ -89,9 +89,7 @@ async function recoverDocsStructure(content: string) {
let match;
let lastIndex = 0;
while ((match = reg.exec(content))) {
- tokenPromises.push(
- Promise.resolve([TokenKind.Text, content.slice(lastIndex, match.index)])
- );
+ tokenPromises.push(Promise.resolve([TokenKind.Text, content.slice(lastIndex, match.index)]));
tokenPromises.push(identifyCommentToken(match[1]));
lastIndex = reg.lastIndex;
}
@@ -157,8 +155,7 @@ async function recoverDocsStructure(content: string) {
};
if (sym) {
current.id = `${sym.id}-param-${token[1]}`;
- const renderedParams = (sym.data.renderedParams =
- sym.data.renderedParams || {});
+ const renderedParams = (sym.data.renderedParams = sym.data.renderedParams || {});
renderedParams[current.id] = current;
}
break;
@@ -240,19 +237,11 @@ async function identifyCommentToken(comment: string) {
case "end:errors":
return [TokenKind.ErrorEnd, cs[1]];
case "begin:module":
- return [
- TokenKind.ModuleStart,
- cs[1],
- JSON.parse(await base64ToUtf8(cs[2])),
- ];
+ return [TokenKind.ModuleStart, cs[1], JSON.parse(await base64ToUtf8(cs[2]))];
case "end:module":
return [TokenKind.ModuleEnd, cs[1]];
case "begin:symbol":
- return [
- TokenKind.SymbolStart,
- cs[1],
- JSON.parse(await base64ToUtf8(cs[2])),
- ];
+ return [TokenKind.SymbolStart, cs[1], JSON.parse(await base64ToUtf8(cs[2]))];
case "end:symbol":
return [TokenKind.SymbolEnd, cs[1]];
case "begin:sig":
@@ -312,7 +301,7 @@ function MakeDoc(root: DocElement) {
(e) =>
e.namespace === child.data.namespace &&
e.name === child.data.name &&
- e.version === child.data.version
+ e.version === child.data.version,
);
return;
}
@@ -494,9 +483,9 @@ function MakeDoc(root: DocElement) {
style: "text-decoration: underline",
title: `It is inaccessible by paths`,
},
- "Module"
+ "Module",
),
- code(" ", knownFiles[fileLoc]?.path || v.id)
+ code(" ", knownFiles[fileLoc]?.path || v.id),
);
} else {
title.push(span(`Module: ${v.id}`));
@@ -505,7 +494,7 @@ function MakeDoc(root: DocElement) {
return div(
{ class: "tinymist-module" },
h1({ id: v.id }, ...(fid ? [span({ id: fid }, ...title)] : title)),
- ModuleBody(v)
+ ModuleBody(v),
);
}
@@ -514,19 +503,14 @@ function MakeDoc(root: DocElement) {
return div(
h1(`@${v.data.namespace}/${v.data.name}:${v.data.version}`),
p(
- span(
- "This documentation is generated locally. Please submit issues to "
- ),
- a(
- { href: "https://github.com/Myriad-Dreamin/tinymist/issues" },
- "tinymist"
- ),
+ span("This documentation is generated locally. Please submit issues to "),
+ a({ href: "https://github.com/Myriad-Dreamin/tinymist/issues" }, "tinymist"),
span(" if you see "),
strong(i("incorrect")),
- span(" information in it.")
+ span(" information in it."),
),
// ModuleBody(v)
- ...v.children.map(Item)
+ ...v.children.map(Item),
);
}
@@ -546,16 +530,16 @@ function MakeDoc(root: DocElement) {
style: "text-decoration: underline",
title: `In external package @${extPkg.namespace}/${extPkg.name}:${extPkg.version}`,
},
- "external"
+ "external",
)
: span(
{
style: "text-decoration: underline",
title: `In local package @${extPkg.namespace}/${extPkg.name}:${extPkg.version}`,
},
- "external"
+ "external",
),
- code(" ", v.data.name)
+ code(" ", v.data.name),
);
} else {
const file = knownFiles[fileLoc?.[0]];
@@ -567,9 +551,9 @@ function MakeDoc(root: DocElement) {
style: "text-decoration: underline",
title: `This module is inaccessible by paths`,
},
- "internal"
+ "internal",
),
- code(" ")
+ code(" "),
)
: code();
@@ -579,8 +563,8 @@ function MakeDoc(root: DocElement) {
{
href: `#${fid}`,
},
- v.data.name
- )
+ v.data.name,
+ ),
);
}
@@ -598,8 +582,8 @@ function MakeDoc(root: DocElement) {
// View Source
//
},
- h3({ class: "doc-symbol-name" }, body)
- )
+ h3({ class: "doc-symbol-name" }, body),
+ ),
);
}
@@ -618,7 +602,7 @@ function MakeDoc(root: DocElement) {
{
id: v.id,
},
- code(v.data.name)
+ code(v.data.name),
);
let funcTitle = [...is_external, name];
if (sig) {
@@ -652,10 +636,10 @@ function MakeDoc(root: DocElement) {
{
class: `detail-header doc-symbol-${v.data.kind}`,
},
- h3({ class: "doc-symbol-name" }, code(...funcTitle))
+ h3({ class: "doc-symbol-name" }, code(...funcTitle)),
),
...SigPreview(v),
- ...(v.data.is_external ? ShortItemDoc(v) : [ItemDoc(v), ...SigDocs(v)])
+ ...(v.data.is_external ? ShortItemDoc(v) : [ItemDoc(v), ...SigDocs(v)]),
);
}
@@ -728,10 +712,10 @@ function MakeDoc(root: DocElement) {
{
class: "doc-param-title",
},
- strong(paramTitle)
- )
- )
- )
+ strong(paramTitle),
+ ),
+ ),
+ ),
);
}
@@ -751,7 +735,7 @@ function MakeDoc(root: DocElement) {
{
id: `param-${v.id}-${param.name}`,
},
- param.name
+ param.name,
),
];
if (param.cano_type) {
@@ -782,13 +766,13 @@ function MakeDoc(root: DocElement) {
{
class: "doc-param-title",
},
- strong(code(paramTitle))
+ strong(code(paramTitle)),
),
div({
style: "margin-left: 0.62em",
innerHTML: docsAll ? docsAll : "
-
",
- })
- )
+ }),
+ ),
);
}
@@ -826,19 +810,13 @@ function MakeDoc(root: DocElement) {
href: v.data.external_link,
title: "this symbol is re-exported from other modules",
},
- kwHl("external")
+ kwHl("external"),
),
code(" "),
]
: [];
- const sigTitle = [
- ...is_external,
- kwHl("let"),
- code(" "),
- code(fnHl(v.data.name)),
- code("("),
- ];
+ const sigTitle = [...is_external, kwHl("let"), code(" "), code(fnHl(v.data.name)), code("(")];
for (let i = 0; i < paramsAll.length; i++) {
if (i > 0) {
sigTitle.push(code(", "));
@@ -856,8 +834,8 @@ function MakeDoc(root: DocElement) {
{
href: `#param-${v.id}-${paramsAll[i].param.name}`,
},
- ...paramTitle
- )
+ ...paramTitle,
+ ),
);
}
sigTitle.push(code(")"));
@@ -877,9 +855,9 @@ function MakeDoc(root: DocElement) {
{
style: "margin: 0 1em",
},
- code(...sigTitle)
- )
- )
+ code(...sigTitle),
+ ),
+ ),
);
return res;
@@ -896,26 +874,23 @@ function MakeDoc(root: DocElement) {
},
h3(
{ class: "doc-symbol-name" },
- code(`${v.data.name}`)
+ code(`${v.data.name}`),
// code(
// {
// style: "float: right; line-height: 1em",
// },
// `${v.data.kind}`
// )
- )
+ ),
),
- ItemDoc(v)
+ ItemDoc(v),
);
}
return Item(root);
}
-function sigTypeHighlighted(
- inferred: [string, string] | undefined,
- target: ChildDom[]
-) {
+function sigTypeHighlighted(inferred: [string, string] | undefined, target: ChildDom[]) {
// todo: determine whether it is inferred
// if (types) {
// typeHighlighted(types, target);
@@ -925,24 +900,20 @@ function sigTypeHighlighted(
typeHighlighted(inferred[0], rendered, "|");
const infer = span(
{ class: "code-kw type-inferred", title: "inferred by type checker" },
- "infer"
+ "infer",
);
target.push(
code(
{ class: "type-inferred" },
infer,
code(" "),
- span({ class: "type-inferred-as", title: inferred[1] }, ...rendered)
- )
+ span({ class: "type-inferred-as", title: inferred[1] }, ...rendered),
+ ),
);
}
}
-function typeHighlighted(
- types: string,
- target: ChildDom[],
- by: RegExp | string = /[|,]/g
-) {
+function typeHighlighted(types: string, target: ChildDom[], by: RegExp | string = /[|,]/g) {
const type = types.split(by);
for (let i = 0; i < type.length; i++) {
if (i > 0) {
diff --git a/tools/editor-tools/src/features/font-view.ts b/tools/editor-tools/src/features/font-view.ts
index b9a8e08ed..670e3f37a 100644
--- a/tools/editor-tools/src/features/font-view.ts
+++ b/tools/editor-tools/src/features/font-view.ts
@@ -15,17 +15,13 @@ export const FontView = () => {
const FontResourcesData = `:[[preview:FontInformation]]:`;
const fontResources = van.state(
- FontResourcesData.startsWith(":")
- ? DOC_MOCK
- : JSON.parse(base64Decode(FontResourcesData))
+ FontResourcesData.startsWith(":") ? DOC_MOCK : JSON.parse(base64Decode(FontResourcesData)),
);
console.log("fontResources", fontResources);
const StyleAtCursorData = `:[[preview:StyleAtCursor]]:`;
const lastStylesAtCursor = van.state(
- StyleAtCursorData.startsWith(":")
- ? undefined
- : JSON.parse(base64Decode(StyleAtCursorData))
+ StyleAtCursorData.startsWith(":") ? undefined : JSON.parse(base64Decode(StyleAtCursorData)),
);
console.log("styleAtCursorBase", lastStylesAtCursor);
van.derive(() => {
@@ -72,12 +68,11 @@ export const FontView = () => {
icon: ChildDom,
title: string,
onclick: (this: HTMLDivElement) => void,
- opts?: PropsWithKnownKeys & { active?: State }
+ opts?: PropsWithKnownKeys & { active?: State },
) => {
const classProp = opts?.active
? van.derive(
- () =>
- `tinymist-button tinymist-font-action${opts?.active?.val ? " activated" : ""}`
+ () => `tinymist-button tinymist-font-action${opts?.active?.val ? " activated" : ""}`,
)
: "tinymist-button tinymist-font-action";
@@ -89,7 +84,7 @@ export const FontView = () => {
title,
onclick,
},
- icon
+ icon,
);
};
@@ -106,17 +101,15 @@ export const FontView = () => {
const machineTitle = `Weight ${font.weight || 400}, Stretch ${font.stretch || 1000}, at `;
const baseName = code(
- font.style === "normal" || !font.style
- ? ""
- : `${humanStyle(font.style)}, `,
+ font.style === "normal" || !font.style ? "" : `${humanStyle(font.style)}, `,
(_dom?: Element) => {
return span(
humanWeight(font.weight, showNumberOpt.val),
showNumber.val ? ", " : " ",
- humanStretch(font.stretch, showNumberOpt.val)
+ humanStretch(font.stretch, showNumberOpt.val),
);
},
- ` (${fileName})`
+ ` (${fileName})`,
);
let variantName;
@@ -127,8 +120,7 @@ export const FontView = () => {
title = machineTitle + w.path;
variantName = a(
{
- style:
- "font-size: 1.2em; text-decoration: underline; cursor: pointer;",
+ style: "font-size: 1.2em; text-decoration: underline; cursor: pointer;",
title,
onclick() {
if (w.kind === "fs") {
@@ -136,7 +128,7 @@ export const FontView = () => {
}
},
},
- baseName
+ baseName,
);
} else {
title = machineTitle + `Embedded: ${w.name}`;
@@ -145,7 +137,7 @@ export const FontView = () => {
style: "font-size: 1.2em",
title,
},
- baseName
+ baseName,
);
}
} else {
@@ -184,56 +176,44 @@ export const FontView = () => {
div(
{ style: "margin: 1.2em; margin-left: 0.5em" },
div(
- FontAction(
- "Copy",
- "Copy to clipboard",
- function (this: HTMLDivElement) {
- activeMe(this);
- copyToClipboard(`"${family.name || ""}"`);
- }
- ),
+ FontAction("Copy", "Copy to clipboard", function (this: HTMLDivElement) {
+ activeMe(this);
+ copyToClipboard(`"${family.name || ""}"`);
+ }),
" | ",
- FontAction(
- "Paste string",
- "Paste as String",
- function (this: HTMLDivElement) {
- activeMe(this);
- const rest = name;
- const markup = `#${rest}`;
- requestTextEdit({
- newText: {
- kind: "by-mode",
- markup,
- rest,
- },
- });
- }
- ),
+ FontAction("Paste string", "Paste as String", function (this: HTMLDivElement) {
+ activeMe(this);
+ const rest = name;
+ const markup = `#${rest}`;
+ requestTextEdit({
+ newText: {
+ kind: "by-mode",
+ markup,
+ rest,
+ },
+ });
+ }),
" ",
- FontAction(
- "#set",
- "Paste as Set Font Rule",
- function (this: HTMLDivElement) {
- activeMe(this);
- const rest = name;
- const markup = `#set text(font: ${rest})`;
- requestTextEdit({
- newText: {
- kind: "by-mode",
- markup,
- rest,
- },
- });
- }
- )
+ FontAction("#set", "Paste as Set Font Rule", function (this: HTMLDivElement) {
+ activeMe(this);
+ const rest = name;
+ const markup = `#set text(font: ${rest})`;
+ requestTextEdit({
+ newText: {
+ kind: "by-mode",
+ markup,
+ rest,
+ },
+ });
+ }),
),
span({ style: "font-size: 1.2em" }, family.name),
".",
br(),
code("Variant"),
": ",
- family.infos.map(FontSlot)
- )
+ family.infos.map(FontSlot),
+ ),
);
};
@@ -245,7 +225,7 @@ export const FontView = () => {
code(fontAtCursor),
br(),
"Checked at ",
- code(fontPosition)
+ code(fontPosition),
);
};
@@ -257,8 +237,7 @@ export const FontView = () => {
div(
{
class: "flex-col",
- style:
- "justify-content: center; align-items: center; gap: 10px; width: 100%;",
+ style: "justify-content: center; align-items: center; gap: 10px; width: 100%;",
},
div(
{
@@ -270,24 +249,22 @@ export const FontView = () => {
() => {
showNumber.val = !showNumber.val;
},
- { active: showNumber }
- )
+ { active: showNumber },
+ ),
),
div(
{
class: `tinymist-card`,
style: "flex: 1; width: 100%; padding: 10px; display: none",
},
- (_dom?: Element) => SelectingSlot()
+ (_dom?: Element) => SelectingSlot(),
),
- ...fontResources.val.families.map(FontFamilySlot)
- )
+ ...fontResources.val.families.map(FontFamilySlot),
+ ),
);
};
-export type fontLocation = FontSource extends { kind: infer Kind }
- ? Kind
- : never;
+export type fontLocation = FontSource extends { kind: infer Kind } ? Kind : never;
interface FontInfo {
name: string;
diff --git a/tools/editor-tools/src/features/symbol-view.ts b/tools/editor-tools/src/features/symbol-view.ts
index ee4edf262..a15a2a8ca 100644
--- a/tools/editor-tools/src/features/symbol-view.ts
+++ b/tools/editor-tools/src/features/symbol-view.ts
@@ -21,8 +21,7 @@ import { base64Decode } from "../utils";
// };
ortEnv.wasm.numThreads = 4;
-ortEnv.wasm.wasmPaths =
- "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.17.1/dist/";
+ortEnv.wasm.wasmPaths = "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.17.1/dist/";
type Point = [number, number];
type Stroke = Point[];
@@ -85,7 +84,7 @@ const SYMBOL_MOCK: SymbolInformation = {
const SearchBar = (
state: State,
- symbolSelected: State
+ symbolSelected: State,
) => {
const def = MiniSearch.getDefault("tokenize");
const search = van.derive(() => {
@@ -233,18 +232,15 @@ const CanvasPanel = (strokesState: State) => {
startModal(
p(
"The ",
- span(
- { style: "font-weight: bold; text-decoration: underline" },
- "offline"
- ),
+ span({ style: "font-weight: bold; text-decoration: underline" }, "offline"),
" handwritten stroke recognizer is powered by ",
a(
{
href: "https://github.com/QuarticCat/detypify",
},
- "Detypify"
+ "Detypify",
),
- ". Draw a symbol to search for it."
+ ". Draw a symbol to search for it.",
),
h4("Cannot find some symbols?"),
p(
@@ -253,9 +249,9 @@ const CanvasPanel = (strokesState: State) => {
{
href: "https://github.com/QuarticCat/detypify/blob/main/assets/supported-symbols.txt",
},
- "supported-symbols.txt"
+ "supported-symbols.txt",
),
- "."
+ ".",
),
p(
"❤️🔥: Click the ",
@@ -267,9 +263,9 @@ const CanvasPanel = (strokesState: State) => {
{
href: "https://detypify.quarticcat.com/",
},
- "Detypify"
+ "Detypify",
),
- "."
+ ".",
),
p(
"📝: Report the missing symbol to ",
@@ -277,9 +273,9 @@ const CanvasPanel = (strokesState: State) => {
{
href: "https://github.com/QuarticCat/detypify/issues/new",
},
- "GitHub Issues"
+ "GitHub Issues",
),
- "."
+ ".",
),
h4("Like it?"),
p(
@@ -288,16 +284,16 @@ const CanvasPanel = (strokesState: State) => {
{
href: "https://github.com/QuarticCat/detypify",
},
- "Detypify"
+ "Detypify",
),
- "!"
- )
+ "!",
+ ),
);
},
},
- HelpIcon()
+ HelpIcon(),
),
- srcCanvas
+ srcCanvas,
),
button(
{
@@ -305,8 +301,8 @@ const CanvasPanel = (strokesState: State) => {
title: "clear",
onclick: drawClear,
},
- "Clear"
- )
+ "Clear",
+ ),
);
};
@@ -441,16 +437,14 @@ const CATEGORY_INFO: SymbolCategory[] = [
},
];
// generate map from category value to category name
-const categoryIndex = new Map(
- CATEGORY_INFO.map((cat) => [cat.value, cat.name.toLowerCase()])
-);
+const categoryIndex = new Map(CATEGORY_INFO.map((cat) => [cat.value, cat.name.toLowerCase()]));
export const SymbolPicker = () => {
const symbolInformationData = `:[[preview:SymbolInformation]]:`;
const symInfo = van.state(
symbolInformationData.startsWith(":")
? SYMBOL_MOCK
- : JSON.parse(base64Decode(symbolInformationData))
+ : JSON.parse(base64Decode(symbolInformationData)),
);
console.log("symbolInformation", symInfo);
const detypifyPromise = Detypify.create();
@@ -473,7 +467,7 @@ export const SymbolPicker = () => {
() =>
``
+ `,
),
});
@@ -494,10 +488,7 @@ export const SymbolPicker = () => {
};
const bboxXWidth = diff(primaryGlyph.xMin, primaryGlyph.xMax);
- let xWidth = Math.max(
- bboxXWidth,
- primaryGlyph.xAdvance || fontSelected.unitsPerEm
- );
+ let xWidth = Math.max(bboxXWidth, primaryGlyph.xAdvance || fontSelected.unitsPerEm);
let yReal = diff(primaryGlyph.yMin, primaryGlyph.yMax);
let yGlobal = primaryGlyph.yAdvance || fontSelected.unitsPerEm;
@@ -527,7 +518,7 @@ export const SymbolPicker = () => {
// console.log(sym.typstCode, div({ innerHTML: imageData }));
maskInfo.setAttribute(
"style",
- `width: ${symWidth}; height: ${symHeight}; -webkit-mask-image: url('data:image/svg+xml;utf8,${encodeURIComponent(imageData)}'); -webkit-mask-size: auto ${symHeight}; -webkit-mask-repeat: no-repeat; transition: background-color 200ms; background-color: currentColor;`
+ `width: ${symWidth}; height: ${symHeight}; -webkit-mask-image: url('data:image/svg+xml;utf8,${encodeURIComponent(imageData)}'); -webkit-mask-size: auto ${symHeight}; -webkit-mask-repeat: no-repeat; transition: background-color 200ms; background-color: currentColor;`,
);
}, 1);
}
@@ -557,7 +548,7 @@ export const SymbolPicker = () => {
});
},
},
- maskInfo
+ maskInfo,
);
};
@@ -566,8 +557,8 @@ export const SymbolPicker = () => {
div({ style: "font-size: 14px; margin: 8px 0" }, cat.name),
div(
{ class: "flex-row", style: "flex-wrap: wrap; gap: 5px; width: 100%" },
- ...(cat.symbols || []).map((sym) => sym.elem)
- )
+ ...(cat.symbols || []).map((sym) => sym.elem),
+ ),
);
};
@@ -580,25 +571,21 @@ export const SymbolPicker = () => {
value,
elem: SymbolCell(value),
};
- })
- );
- const filteredPickers = van.state(
- undefined
+ }),
);
+ const filteredPickers = van.state(undefined);
function pickSymbolsBySearch(
pickers: { key: string; value: SymbolItem; elem: Element }[],
- filteredPickers: SelectedSymbolItem[] | undefined
+ filteredPickers: SelectedSymbolItem[] | undefined,
) {
if (!filteredPickers) return pickers;
- return pickers.filter((picker) =>
- filteredPickers.some((f) => f.typstCode === picker.key)
- );
+ return pickers.filter((picker) => filteredPickers.some((f) => f.typstCode === picker.key));
}
function pickSymbolsByDrawCandidates(
pickers: { key: string; value: SymbolItem; elem: Element }[],
- drawCandidates: DetypifySymbol[] | undefined
+ drawCandidates: DetypifySymbol[] | undefined,
) {
if (drawCandidates === undefined) return pickers;
if (!drawCandidates.length) return [];
@@ -623,7 +610,7 @@ export const SymbolPicker = () => {
style: "flex: 0 0 auto; gap: 5px",
},
SearchBar(symInfo, filteredPickers),
- CanvasPanel(strokes)
+ CanvasPanel(strokes),
),
div({ style: "flex: 1;" }, (_dom?: Element) =>
div(
@@ -631,27 +618,23 @@ export const SymbolPicker = () => {
CATEGORY_INFO,
pickSymbolsBySearch(
pickSymbolsByDrawCandidates(pickers.val, drawCandidates.val),
- filteredPickers.val
- )
+ filteredPickers.val,
+ ),
)
.filter((cat) => cat.symbols?.length)
- .map((info) => CategoryPicker(info))
- )
- )
+ .map((info) => CategoryPicker(info)),
+ ),
+ ),
);
};
function categorize(
catsRaw: SymbolCategory[],
- symInfo: InstantiatedSymbolItem[]
+ symInfo: InstantiatedSymbolItem[],
): InstantiatedSymbolCategory[] {
- let cats: InstantiatedSymbolCategory[] = [
- ...catsRaw.map((cat) => ({ ...cat })),
- ];
+ let cats: InstantiatedSymbolCategory[] = [...catsRaw.map((cat) => ({ ...cat }))];
// let misc
- let misc: InstantiatedSymbolCategory = cats.find(
- (cat) => cat.name === "Miscellaneous"
- )!;
+ let misc: InstantiatedSymbolCategory = cats.find((cat) => cat.name === "Miscellaneous")!;
// misc.symbols = symInfo.val.symbols;
for (let sym of symInfo) {
const { key, value } = sym;
diff --git a/tools/editor-tools/src/features/template-gallery.ts b/tools/editor-tools/src/features/template-gallery.ts
index 034d21c72..9b1040930 100644
--- a/tools/editor-tools/src/features/template-gallery.ts
+++ b/tools/editor-tools/src/features/template-gallery.ts
@@ -30,10 +30,7 @@ interface PackageMeta {
template: any;
}
-const TemplateList = (
- packages: State,
- catState: FilterState
-) => {
+const TemplateList = (packages: State, catState: FilterState) => {
const AuthorItem = (author: string) => {
// split by <
const [nameStart, emailRest] = author.split("<");
@@ -55,10 +52,7 @@ const TemplateList = (
const AuthorList = (authors: string[]) => {
if (authors.length <= 1) {
- return span(
- { class: `tinymist-author-container` },
- ...authors.map(AuthorItem)
- );
+ return span({ class: `tinymist-author-container` }, ...authors.map(AuthorItem));
}
return span(
@@ -70,57 +64,51 @@ const TemplateList = (
style: "text-decoration: underline",
title: authors.slice(1).join(", "),
},
- "et al."
- )
+ "et al.",
+ ),
);
};
const highlightMatches = (text: string, searchResults?: SearchResult[]): HTMLSpanElement => {
if (!searchResults || !text) return van.tags.span({}, text);
- const searchTerms = searchResults.flatMap(result => result.queryTerms);
- const regex = new RegExp(`(${searchTerms.join("|")})`, 'gi');
+ const searchTerms = searchResults.flatMap((result) => result.queryTerms);
+ const regex = new RegExp(`(${searchTerms.join("|")})`, "gi");
const parts = text.split(regex);
- return van.tags.span({}, ...parts.map(part =>
- regex.test(part)
- ? van.tags.span({ class: 'tinymist-highlight' }, part)
- : part
- ));
- }
+ return van.tags.span(
+ {},
+ ...parts.map((part) =>
+ regex.test(part) ? van.tags.span({ class: "tinymist-highlight" }, part) : part,
+ ),
+ );
+ };
const TemplateListItem = (item: PackageMeta) => {
- const TemplateAction = (
- icon: ChildDom,
- title: string,
- onclick: () => void
- ) =>
+ const TemplateAction = (icon: ChildDom, title: string, onclick: () => void) =>
button(
{
class: "tinymist-button tinymist-template-action",
title,
onclick,
},
- icon
+ icon,
);
return Card(
"template-card",
div(
- a({ href: item.repository, style: "font-size: 1.2em" },
- () => {
- return highlightMatches(item.name, catState.searchSelected.val);
- }
- ),
+ a({ href: item.repository, style: "font-size: 1.2em" }, () => {
+ return highlightMatches(item.name, catState.searchSelected.val);
+ }),
span(" "),
span({ style: "font-size: 0.8em" }, "v" + item.version),
span(" by "),
- AuthorList(item.authors)
+ AuthorList(item.authors),
),
div(
{
- style:
- "display: flex; align-items: center; gap: 0.25em; margin-top: 0.4em;",
+ style: "display: flex; align-items: center; gap: 0.25em; margin-top: 0.4em;",
class: "tinymist-template-actions",
},
button(
@@ -134,13 +122,13 @@ const TemplateList = (
title: van.derive(() =>
catState.getIsFavorite("preview", item.name)
? "Removes from favorite"
- : "Adds to favorite"
+ : "Adds to favorite",
),
onclick() {
catState.negIsFavorite("preview", item.name);
},
},
- HeartIcon(16)
+ HeartIcon(16),
),
TemplateAction(AddIcon(16), "Creates project", () => {
const packageSpec = `@preview/${item.name}:${item.version}`;
@@ -156,22 +144,22 @@ const TemplateList = (
}
return { value: cat };
})
- .map(CategoryButton(catState))
+ .map(CategoryButton(catState)),
),
div({ style: "clear: both" }),
- div({ style: "margin-top: 0.4em" },
+ div(
+ { style: "margin-top: 0.4em" },
div({}, () => {
return highlightMatches(item.description, catState.searchSelected.val);
- })
- )
+ }),
+ ),
);
};
function runFilterSearch(searchResult: SearchResult[] | undefined) {
// console.log("search", searchResult);
const searchResultMap = new Set(searchResult?.map((result) => result.id));
- return (value: PackageMeta) =>
- searchResult === undefined || searchResultMap.has(value.id);
+ return (value: PackageMeta) => searchResult === undefined || searchResultMap.has(value.id);
}
function runFilterCategory(categoryFilter: Set) {
@@ -197,8 +185,8 @@ const TemplateList = (
.filter(runFilterCategory(catState.categories.val))
.filter(runFilterFavorite)
.filter(runFilterSearch(catState.searchSelected.val))
- .map(TemplateListItem) || []
- )
+ .map(TemplateListItem) || [],
+ ),
);
};
@@ -280,8 +268,7 @@ const CategoryButton = (catState: FilterState) => (category: Category) => {
return button(
{
class: van.derive(() => {
- const activatingCls =
- category.value === catState.activating.val ? " activated" : "";
+ const activatingCls = category.value === catState.activating.val ? " activated" : "";
return "tinymist-button" + activatingCls;
}),
title: "Filter by category: " + category.value,
@@ -291,8 +278,8 @@ const CategoryButton = (catState: FilterState) => (category: Category) => {
{
style: "height: 16px;",
},
- category.display || category.value
- )
+ category.display || category.value,
+ ),
);
};
@@ -304,15 +291,14 @@ const FilterRow = (catState: FilterState) => {
return "tinymist-button" + activatingCls;
}),
title: "Filter by favorite state",
- onclick: () =>
- (catState.filterFavorite.val = !catState.filterFavorite.val),
+ onclick: () => (catState.filterFavorite.val = !catState.filterFavorite.val),
},
- HeartIcon(16)
+ HeartIcon(16),
);
return div(
{ class: "tinymist-category-filter" },
favButton,
- ...CATEGORIES.map(CategoryButton(catState))
+ ...CATEGORIES.map(CategoryButton(catState)),
);
};
@@ -322,15 +308,13 @@ export const TemplateGallery = () => {
const favoritePlaceholders = `:[[preview:FavoritePlaceholder]]:`;
const catState = new FilterState(
JSON.parse(
- favoritePlaceholders.startsWith(":")
- ? favoriteState
- : base64Decode(favoritePlaceholders)
- )
+ favoritePlaceholders.startsWith(":") ? favoriteState : base64Decode(favoritePlaceholders),
+ ),
);
van.derive(async () => {
- const rawPackages = await fetch(
- "https://packages.typst.org/preview/index.json"
- ).then((res) => res.json());
+ const rawPackages = await fetch("https://packages.typst.org/preview/index.json").then((res) =>
+ res.json(),
+ );
// collect packages by version
const packagesIndex = new Map();
@@ -355,9 +339,5 @@ export const TemplateGallery = () => {
packages.val = packagesList;
});
- return div(
- SearchBar(packages, catState),
- FilterRow(catState),
- TemplateList(packages, catState)
- );
+ return div(SearchBar(packages, catState), FilterRow(catState), TemplateList(packages, catState));
};
diff --git a/tools/editor-tools/src/utils.ts b/tools/editor-tools/src/utils.ts
index 024ca81ab..2893499e2 100644
--- a/tools/editor-tools/src/utils.ts
+++ b/tools/editor-tools/src/utils.ts
@@ -15,8 +15,4 @@ export const base64Decode = (encoded: string) =>
* @returns Base64 encoded string
*/
export const base64Encode = (utf8Str: string) =>
- btoa(
- Array.from(utf82bytes.encode(utf8Str), (c) => String.fromCharCode(c)).join(
- ""
- )
- );
+ btoa(Array.from(utf82bytes.encode(utf8Str), (c) => String.fromCharCode(c)).join(""));
diff --git a/tools/editor-tools/vite.config.js b/tools/editor-tools/vite.config.js
index f6f2e8e77..23eddced4 100644
--- a/tools/editor-tools/vite.config.js
+++ b/tools/editor-tools/vite.config.js
@@ -3,15 +3,15 @@ import { viteSingleFile } from "vite-plugin-singlefile";
// /src/main.ts
-const compPrefix = '--component=';
-const componentArgs = process.argv.find(arg => arg.startsWith(compPrefix));
-let output = 'dist/default';
+const compPrefix = "--component=";
+const componentArgs = process.argv.find((arg) => arg.startsWith(compPrefix));
+let output = "dist/default";
if (componentArgs) {
const component = componentArgs.substring(compPrefix.length);
process.env.VITE_ENTRY = `/src/main.${component}.ts`;
output = `dist/${component}`;
} else {
- process.env.VITE_ENTRY = '/src/main.ts';
+ process.env.VITE_ENTRY = "/src/main.ts";
}
export default defineConfig({
@@ -19,13 +19,13 @@ export default defineConfig({
assetsInclude: ["**/*.onnx"],
build: {
minify: false,
- outDir: output
+ outDir: output,
},
optimizeDeps: {
esbuildOptions: {
loader: {
".onnx": "dataurl",
},
- }
- }
+ },
+ },
});
diff --git a/tools/typst-dom/src/index.mts b/tools/typst-dom/src/index.mts
index bf04c72c1..551f2d23a 100644
--- a/tools/typst-dom/src/index.mts
+++ b/tools/typst-dom/src/index.mts
@@ -21,5 +21,5 @@ import { TypstDocumentContext, composeDoc, provideDoc } from "./typst-doc.mjs";
* ) {}
*/
export class TypstDocument extends provideDoc(
- composeDoc(TypstDocumentContext, provideCanvasDoc, provideSvgDoc)
+ composeDoc(TypstDocumentContext, provideCanvasDoc, provideSvgDoc),
) {}
diff --git a/tools/typst-dom/src/index.preview.mts b/tools/typst-dom/src/index.preview.mts
index 114ad52d8..091213163 100644
--- a/tools/typst-dom/src/index.preview.mts
+++ b/tools/typst-dom/src/index.preview.mts
@@ -11,6 +11,6 @@ export class TypstPreviewDocument extends provideDoc(
provideOutlineDoc,
provideCanvasDoc,
provideSvgDoc,
- provideDebugJumpDoc
- )
+ provideDebugJumpDoc,
+ ),
) {}
diff --git a/tools/typst-dom/src/typst-animation.mts b/tools/typst-dom/src/typst-animation.mts
index 6a4e83b6d..9a37a6623 100644
--- a/tools/typst-dom/src/typst-animation.mts
+++ b/tools/typst-dom/src/typst-animation.mts
@@ -4,7 +4,7 @@ export function triggerRipple(
top: number,
className: string,
animation: string,
- color?: string
+ color?: string,
) {
const ripple = document.createElement("div");
diff --git a/tools/typst-dom/src/typst-doc.canvas.mts b/tools/typst-dom/src/typst-doc.canvas.mts
index a32f9e348..ed1af4ce0 100644
--- a/tools/typst-dom/src/typst-doc.canvas.mts
+++ b/tools/typst-dom/src/typst-doc.canvas.mts
@@ -35,9 +35,7 @@ export interface TypstCanvasDocument {
}
export function provideCanvasDoc<
- TBase extends GConstructor<
- TypstDocumentContext & Partial
- >,
+ TBase extends GConstructor>,
>(Base: TBase): TBase & GConstructor {
return class CanvasDocument extends Base {
feat$canvas = true;
@@ -62,40 +60,28 @@ export function provideCanvasDoc<
pageInfo.elem = document.createElement("div");
pageInfo.elem.setAttribute("class", "typst-page-canvas");
pageInfo.elem.style.transformOrigin = "0 0";
- pageInfo.elem.setAttribute(
- "data-page-number",
- pageInfo.index.toString()
- );
+ pageInfo.elem.setAttribute("data-page-number", pageInfo.index.toString());
const canvas = document.createElement("canvas");
pageInfo.elem.appendChild(canvas);
pageInfo.container = document.createElement("div");
// todo: reuse by key
- pageInfo.container.setAttribute(
- TypstPatchAttrs.Tid,
- `canvas:` + pageInfo.index
- );
+ pageInfo.container.setAttribute(TypstPatchAttrs.Tid, `canvas:` + pageInfo.index);
pageInfo.container.setAttribute("class", "typst-page canvas-mode");
- pageInfo.container.setAttribute(
- "data-page-number",
- pageInfo.index.toString()
- );
+ pageInfo.container.setAttribute("data-page-number", pageInfo.index.toString());
pageInfo.container.appendChild(pageInfo.elem);
// do scaling early
this.prepareCanvas(pageInfo, canvas);
rescale(
pageInfo.container,
- this.isContentPreview || this.renderMode !== "canvas" || isFirst
+ this.isContentPreview || this.renderMode !== "canvas" || isFirst,
);
if (this.isContentPreview) {
const pageNumberIndicator = document.createElement("div");
- pageNumberIndicator.setAttribute(
- "class",
- "typst-preview-canvas-page-number"
- );
+ pageNumberIndicator.setAttribute("class", "typst-preview-canvas-page-number");
pageNumberIndicator.textContent = `${pageInfo.index + 1}`;
pageInfo.container.appendChild(pageNumberIndicator);
@@ -146,10 +132,7 @@ export function provideCanvasDoc<
return cached;
}
- async updateCanvas(
- pages: CanvasPage[],
- opts?: UpdateCanvasOptions
- ): Promise {
+ async updateCanvas(pages: CanvasPage[], opts?: UpdateCanvasOptions): Promise {
const tok = opts?.cancel || undefined;
const perf = performance.now();
console.log("updateCanvas start");
@@ -181,8 +164,7 @@ export function provideCanvasDoc<
let cached = this.prepareCanvas(pageInfo, canvas);
- const cacheKey =
- pageInfo.elem.getAttribute("data-cache-key") || undefined;
+ const cacheKey = pageInfo.elem.getAttribute("data-cache-key") || undefined;
const result = await this.kModule.renderCanvas({
canvas: canvas.getContext("2d")!,
pageOffset: pageInfo.index,
@@ -221,18 +203,12 @@ export function provideCanvasDoc<
if (noSpacingFromTop) {
canvasContainer.style.marginTop = `0px`;
} else {
- canvasContainer.style.marginTop = `${
- this.isContentPreview ? 6 : 5
- }px`;
+ canvasContainer.style.marginTop = `${this.isContentPreview ? 6 : 5}px`;
}
let elem = canvasContainer.firstElementChild as HTMLDivElement;
- const canvasWidth = Number.parseFloat(
- elem.getAttribute("data-page-width")!
- );
- const canvasHeight = Number.parseFloat(
- elem.getAttribute("data-page-height")!
- );
+ const canvasWidth = Number.parseFloat(elem.getAttribute("data-page-width")!);
+ const canvasHeight = Number.parseFloat(elem.getAttribute("data-page-height")!);
this.currentRealScale =
this.previewMode === PreviewMode.Slide
@@ -240,9 +216,7 @@ export function provideCanvasDoc<
: cw / canvasWidth;
const scale =
// The element in svg is already scaled by svg host
- this.renderMode === "svg"
- ? 1
- : this.currentRealScale * this.currentScaleRatio;
+ this.renderMode === "svg" ? 1 : this.currentRealScale * this.currentScaleRatio;
// apply scale
const appliedScale = (scale / this.pixelPerPt).toString();
@@ -309,18 +283,16 @@ export function provideCanvasDoc<
async rerender$canvas() {
// console.log('toggleCanvasViewportChange!!!!!!', this.id, this.isRendering);
- const pages: CanvasPage[] = this.kModule
- .retrievePagesInfo()
- .map((x, index) => {
- return {
- tag: "canvas",
- index,
- width: x.width,
- height: x.height,
- container: undefined as any as HTMLDivElement,
- elem: undefined as any as HTMLDivElement,
- };
- });
+ const pages: CanvasPage[] = this.kModule.retrievePagesInfo().map((x, index) => {
+ return {
+ tag: "canvas",
+ index,
+ width: x.width,
+ height: x.height,
+ container: undefined as any as HTMLDivElement,
+ elem: undefined as any as HTMLDivElement,
+ };
+ });
if (!this.hookedElem.firstElementChild) {
this.hookedElem.innerHTML = ``;
@@ -338,9 +310,7 @@ export function provideCanvasDoc<
checkChildren(canvasContainer);
}
if (canvasContainer.classList.contains("typst-page")) {
- const pageNumber = Number.parseInt(
- ch.getAttribute("data-page-number")!
- );
+ const pageNumber = Number.parseInt(ch.getAttribute("data-page-number")!);
if (pageNumber >= pages.length) {
// todo: cache key can shifted
elem.removeChild(ch);
@@ -358,9 +328,7 @@ export function provideCanvasDoc<
if (!ch.classList.contains("typst-page")) {
continue;
}
- const pageNumber = Number.parseInt(
- ch.getAttribute("data-page-number")!
- );
+ const pageNumber = Number.parseInt(ch.getAttribute("data-page-number")!);
if (pageNumber >= pages.length) {
// todo: cache key shifted
docDiv.removeChild(ch);
diff --git a/tools/typst-dom/src/typst-doc.test.mts b/tools/typst-dom/src/typst-doc.test.mts
index d700fbaa8..ceeb28b8c 100644
--- a/tools/typst-dom/src/typst-doc.test.mts
+++ b/tools/typst-dom/src/typst-doc.test.mts
@@ -14,9 +14,9 @@ interface TypstCanvasDocument {
renderCanvas(): number;
}
-function provideCanvas<
- TBase extends GConstructor
->(Base: TBase): TBase & GConstructor {
+function provideCanvas>(
+ Base: TBase,
+): TBase & GConstructor {
return class extends Base {
canvasFeat = 10;
renderCanvas() {
@@ -25,9 +25,9 @@ function provideCanvas<
};
}
-function provideSvg<
- TBase extends GConstructor
->(Base: TBase): TBase & GConstructor {
+function provideSvg>(
+ Base: TBase,
+): TBase & GConstructor {
return class extends Base {
feat = 100;
svgProp() {
@@ -42,9 +42,7 @@ function provideSvg<
describe("mixinClass", () => {
it("doMixin", () => {
const T = provideSvg(
- provideCanvas(
- TypstDocument as GConstructor
- )
+ provideCanvas(TypstDocument as GConstructor),
);
const t = new T();
expect(t.renderCanvas()).toBe(51);
diff --git a/tools/typst-dom/src/typst-outline.mts b/tools/typst-dom/src/typst-outline.mts
index 97d892a21..386297afc 100644
--- a/tools/typst-dom/src/typst-outline.mts
+++ b/tools/typst-dom/src/typst-outline.mts
@@ -42,7 +42,7 @@ class GenElem {
constructor(
public tag: string,
public container: HTMLElement,
- public additions?: Record
+ public additions?: Record,
) {}
push(child: GenNode) {
@@ -171,7 +171,7 @@ class GenContext {
export function patchOutlineEntry(
prev: HTMLDivElement,
pages: CanvasPage[],
- items: OutlineItemData[]
+ items: OutlineItemData[],
) {
const ctx = new GenContext(pages);
// the root element of the generated outline
@@ -190,8 +190,7 @@ export function patchOutlineEntry(
for (const elem of ctx.allElemList) {
// apply clickable behavior to node containing children
if (elem.children.some(isDataNode)) {
- const titleContentSpan = elem.additions!.title!.additions!
- .content as HTMLSpanElement;
+ const titleContentSpan = elem.additions!.title!.additions!.content as HTMLSpanElement;
titleContentSpan.style.textDecoration = "underline";
titleContentSpan.style.cursor = "pointer";
@@ -221,11 +220,7 @@ export function patchOutlineEntry(
/// Replace the `prev` element with `next` element.
/// Return true if the `prev` element is reused.
/// Return false if the `prev` element is replaced.
-function reuseOrPatchOutlineElem(
- ctx: GenContext,
- prev: Element,
- next: Element
-) {
+function reuseOrPatchOutlineElem(ctx: GenContext, prev: Element, next: Element) {
const canReuse = equalPatchElem(prev, next);
/// Even if the element is reused, we still need to replace its attributes.
@@ -237,9 +232,7 @@ function reuseOrPatchOutlineElem(
if (canReuse) {
if (isPageElem) {
- const pageNumber = Number.parseInt(
- next.getAttribute("data-page-number")!
- );
+ const pageNumber = Number.parseInt(next.getAttribute("data-page-number")!);
// console.log('reuse canvas', ctx.pages[pageNumber], prev, next);
const page = ctx.pages[pageNumber];
page.inserter = poisionCanvasMoved;
@@ -264,7 +257,7 @@ function patchOutlineChildren(ctx: GenContext, prev: Element, next: Element) {
prev.children as unknown as Element[],
next.children as unknown as Element[],
// todo: accurate calculation
- false
+ false,
);
// console.log("interpreted origin outline", targetView, toPatch);
@@ -275,10 +268,7 @@ function patchOutlineChildren(ctx: GenContext, prev: Element, next: Element) {
// console.log("interpreted target outline", targetView);
- const originView = changeViewPerspective(
- prev.children as unknown as Element[],
- targetView
- );
+ const originView = changeViewPerspective(prev.children as unknown as Element[], targetView);
runOriginViewInstructionsOnOutline(ctx, prev, originView);
}
@@ -286,7 +276,7 @@ function patchOutlineChildren(ctx: GenContext, prev: Element, next: Element) {
function runOriginViewInstructionsOnOutline(
ctx: GenContext,
prev: Element,
- originView: OriginViewInstruction[]
+ originView: OriginViewInstruction[],
) {
// console.log("interpreted origin view", originView);
for (const [op, off, fr] of originView) {
@@ -300,9 +290,7 @@ function runOriginViewInstructionsOnOutline(
break;
case "remove":
if (elem?.classList?.contains("typst-page")) {
- const pageNumber = Number.parseInt(
- elem.getAttribute("data-page-number")!
- );
+ const pageNumber = Number.parseInt(elem.getAttribute("data-page-number")!);
if (pageNumber < ctx.pages.length) {
const page = ctx.pages[pageNumber];
// console.log('recover canvas', page, pageNumber);
@@ -321,22 +309,14 @@ function runOriginViewInstructionsOnOutline(
}
export interface TypstOutlineDocument {
- patchOutlineEntry(
- prev: HTMLDivElement,
- pages: CanvasPage[],
- items: OutlineItemData[]
- ): void;
+ patchOutlineEntry(prev: HTMLDivElement, pages: CanvasPage[], items: OutlineItemData[]): void;
}
-export function provideOutlineDoc<
- TBase extends GConstructor,
->(Base: TBase): TBase & GConstructor {
+export function provideOutlineDoc>(
+ Base: TBase,
+): TBase & GConstructor {
return class DebugJumpDocument extends Base {
- patchOutlineEntry(
- prev: HTMLDivElement,
- pages: CanvasPage[],
- items: OutlineItemData[]
- ) {
+ patchOutlineEntry(prev: HTMLDivElement, pages: CanvasPage[], items: OutlineItemData[]) {
patchOutlineEntry(prev, pages, items);
}
};
diff --git a/tools/typst-dom/src/typst-patch.mts b/tools/typst-dom/src/typst-patch.mts
index f82a77da9..717ae7cc8 100644
--- a/tools/typst-dom/src/typst-patch.mts
+++ b/tools/typst-dom/src/typst-patch.mts
@@ -72,10 +72,7 @@ export function equalPatchElem(prev: ElementChildren, next: ElementChildren) {
/// To remove unused resources, An extra remove inst can remove a specify element
///
/// Example5: resource:[o1, o2] -> -> [o1, t1] and remove o2
-export type TargetViewInstruction =
- | ["append", T]
- | ["reuse", number]
- | ["remove", number];
+export type TargetViewInstruction = ["append", T] | ["reuse", number] | ["remove", number];
/// The recursive patch operation must be applied to this two element.
export type PatchPair = [T /* origin */, T /* target */];
@@ -89,7 +86,7 @@ export function interpretTargetView(
targetChildren: T[],
// todo: remove this tag
isPatchingSvg: boolean = true, // patch svg or outline
- tIsU = (x: T): x is U => !!x.getAttribute(TypstPatchAttrs.Tid)
+ tIsU = (x: T): x is U => !!x.getAttribute(TypstPatchAttrs.Tid),
): ViewTransform {
const availableOwnedResource = new Map();
const targetView: TargetViewInstruction[] = [];
@@ -187,13 +184,10 @@ export type OriginViewInstruction =
/// + Finally, it inserts the extra elements.
///
/// Some better strategy would help and be implemented in future.
-export function changeViewPerspective<
- T extends ElementChildren,
- U extends T = T
->(
+export function changeViewPerspective(
originChildren: T[],
targetView: TargetViewInstruction[],
- tIsU = (_x: T): _x is U => true
+ tIsU = (_x: T): _x is U => true,
): OriginViewInstruction[] {
const originView: OriginViewInstruction[] = [];
@@ -321,7 +315,7 @@ export function changeViewPerspective<
export function runOriginViewInstructions(
prev: Element,
- originView: OriginViewInstruction[]
+ originView: OriginViewInstruction[],
) {
// console.log("interpreted origin view", originView);
for (const [op, off, fr] of originView) {
diff --git a/tools/typst-dom/src/typst-patch.svg.mts b/tools/typst-dom/src/typst-patch.svg.mts
index 2ddc38b7d..5d65f383a 100644
--- a/tools/typst-dom/src/typst-patch.svg.mts
+++ b/tools/typst-dom/src/typst-patch.svg.mts
@@ -43,7 +43,7 @@ function patchChildren(prev: Element, next: Element) {
const originView = changeViewPerspective(
prev.children as unknown as SVGGElement[],
targetView,
- isGElem
+ isGElem,
);
runOriginViewInstructions(prev, originView);
@@ -76,10 +76,7 @@ interface FrozenReplacement {
debug?: string;
}
-function preReplaceNonSVGElements(
- prev: Element,
- next: Element
-): FrozenReplacement {
+function preReplaceNonSVGElements(prev: Element, next: Element): FrozenReplacement {
const removedIndices: number[] = [];
const frozenReplacement: FrozenReplacement = {
inserts: [],
@@ -118,9 +115,9 @@ function postReplaceNonSVGElements(prev: Element, frozen: FrozenReplacement) {
/// Retrieve the `` elements from the `prev` element.
const gElements = Array.from(prev.children).filter(isGElem);
if (gElements.length + 1 !== frozen.inserts.length) {
- throw new Error(`invalid frozen replacement: gElements.length (${gElements.length
- }) + 1 !=== frozen.inserts.length (${frozen.inserts.length}) ${frozen.debug || ""
- }
+ throw new Error(`invalid frozen replacement: gElements.length (${
+ gElements.length
+ }) + 1 !=== frozen.inserts.length (${frozen.inserts.length}) ${frozen.debug || ""}
current: ${prev.outerHTML}`);
}
@@ -156,10 +153,7 @@ function initOrPatchSvgHeader(svg: SVGElement) {
}
/// Create a global resource header
- const resourceHeader = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "svg"
- );
+ const resourceHeader = document.createElementNS("http://www.w3.org/2000/svg", "svg");
resourceHeader.id = "typst-svg-resources";
// set viewbox, width, and height
resourceHeader.setAttribute("viewBox", "0 0 0 0");
@@ -195,10 +189,7 @@ function patchSvgHeader(prev: SVGElement, next: SVGElement) {
// todo: gc
prevChild.append(...nextChild.children);
}
- } else if (
- prevChild.tagName === "style" &&
- nextChild.getAttribute("data-reuse") !== "1"
- ) {
+ } else if (prevChild.tagName === "style" && nextChild.getAttribute("data-reuse") !== "1") {
// console.log("replace extra style", prevChild, nextChild);
// todo: gc
@@ -240,7 +231,7 @@ function patchSvgHeader(prev: SVGElement, next: SVGElement) {
export function patchSvgToContainer(
hookedElem: Element,
patchStr: string,
- decorateSvgElement: (elem: SVGElement) => void = () => void 0
+ decorateSvgElement: (elem: SVGElement) => void = () => void 0,
) {
if (hookedElem.firstElementChild) {
const elem = document.createElement("div");
diff --git a/tools/typst-dom/src/typst-patch.test.mts b/tools/typst-dom/src/typst-patch.test.mts
index c9d04bd47..0c24de86a 100644
--- a/tools/typst-dom/src/typst-patch.test.mts
+++ b/tools/typst-dom/src/typst-patch.test.mts
@@ -1,9 +1,5 @@
import { describe, expect, it } from "vitest";
-import {
- PatchPair,
- interpretTargetView,
- changeViewPerspective,
-} from "./typst-patch.mjs";
+import { PatchPair, interpretTargetView, changeViewPerspective } from "./typst-patch.mjs";
interface Attributes {
[key: string]: string | null | undefined;
@@ -15,7 +11,7 @@ interface Attributes {
class MockElement {
tagName = "g";
- constructor(public attrs: Attributes) { }
+ constructor(public attrs: Attributes) {}
getAttribute(s: string): string | null {
return this.attrs[s] ?? null;
@@ -45,7 +41,7 @@ const repeatOrJust = (n: number | (number | null)[]): MockElement[] => {
(i) =>
new MockElement({
"data-tid": i !== null ? i.toString() : null,
- })
+ }),
);
}
@@ -64,7 +60,7 @@ const reuseStub = (n: number | null) =>
function toSnapshot([targetView, patchPair]: [
(MockElement | number | string)[][],
- PatchPair[]
+ PatchPair[],
]): string[] {
const repr = (elem: unknown) => {
if (elem instanceof MockElement) {
@@ -76,33 +72,24 @@ function toSnapshot([targetView, patchPair]: [
const instructions = targetView.map((i) => {
return i.map(repr).join(",");
});
- const patches = patchPair.length
- ? [patchPair.map((i) => i.map(repr).join("->")).join(",")]
- : [];
+ const patches = patchPair.length ? [patchPair.map((i) => i.map(repr).join("->")).join(",")] : [];
return [...instructions, ...patches];
}
-const hasTid = (elem: MockElement): elem is MockElement =>
- elem.getAttribute("data-tid") !== null;
+const hasTid = (elem: MockElement): elem is MockElement => elem.getAttribute("data-tid") !== null;
-const indexTargetView = (
- init: number | (number | null)[],
- rearrange: (number | null)[]
-) =>
+const indexTargetView = (init: number | (number | null)[], rearrange: (number | null)[]) =>
interpretTargetView(
injectOffsets("o", repeatOrJust(init)),
injectOffsets("t", rearrange.map(reuseStub)),
true,
- hasTid
+ hasTid,
);
-const indexOriginView = (
- init: number | (number | null)[],
- rearrange: (number | null)[]
-) =>
+const indexOriginView = (init: number | (number | null)[], rearrange: (number | null)[]) =>
changeViewPerspective(
injectOffsets("o", repeatOrJust(init)),
indexTargetView(init, rearrange)[0],
- hasTid
+ hasTid,
);
describe("interpretView", () => {
@@ -262,10 +249,7 @@ describe("interpretView", () => {
`);
});
it("handleReusePreserveOrder2", () => {
- const result = indexTargetView(
- [0, 1, 2, 1, 2, 3, 4, 3, 4],
- [1, 2, 3, 4, 3, 4, 1, 2]
- );
+ const result = indexTargetView([0, 1, 2, 1, 2, 3, 4, 3, 4], [1, 2, 3, 4, 3, 4, 1, 2]);
expect(toSnapshot(result)).toMatchInlineSnapshot(`
[
"reuse,1",
@@ -282,10 +266,7 @@ describe("interpretView", () => {
`);
});
it("handleReusePreserveOrder2_origin", () => {
- const result = indexOriginView(
- [0, 1, 2, 1, 2, 3, 4, 3, 4],
- [1, 2, 3, 4, 3, 4, 1, 2]
- );
+ const result = indexOriginView([0, 1, 2, 1, 2, 3, 4, 3, 4], [1, 2, 3, 4, 3, 4, 1, 2]);
expect(toSnapshot([result, []])).toMatchInlineSnapshot(`
[
"remove,0",
@@ -301,17 +282,8 @@ describe("interpretView", () => {
const target = injectOffsets("t", [0, null].map(reuseStub));
target[0].attrs["data-tid"] = "1";
target[1].attrs["data-tid"] = "0";
- const result = interpretTargetView(
- origin,
- target,
- true,
- hasTid
- );
- const result2 = changeViewPerspective(
- origin,
- result[0],
- hasTid
- );
+ const result = interpretTargetView(origin, target, true, hasTid);
+ const result2 = changeViewPerspective(origin, result[0], hasTid);
expect(toSnapshot(result)).toMatchInlineSnapshot(`
[
"reuse,3",
@@ -328,17 +300,8 @@ describe("interpretView", () => {
it("handleMasterproefThesisAffectedByEmptyPageAntiCase", () => {
const origin = injectOffsets("o", repeatOrJust([null, null, null, 0, 1]));
const target = injectOffsets("t", [0, 1].map(reuseStub));
- const result = interpretTargetView(
- origin,
- target,
- true,
- hasTid
- );
- const result2 = changeViewPerspective(
- origin,
- result[0],
- hasTid
- );
+ const result = interpretTargetView(origin, target, true, hasTid);
+ const result2 = changeViewPerspective(origin, result[0], hasTid);
expect(toSnapshot(result)).toMatchInlineSnapshot(`
[
"reuse,3",
@@ -354,17 +317,8 @@ describe("interpretView", () => {
it("handleReuseAppend", () => {
const origin = injectOffsets("o", repeatOrJust([null, null, null, 0, 1]));
const target = injectOffsets("t", [1, null, 0, null, 1].map(reuseStub));
- const result = interpretTargetView(
- origin,
- target,
- true,
- hasTid
- );
- const result2 = changeViewPerspective(
- origin,
- result[0],
- hasTid
- );
+ const result = interpretTargetView(origin, target, true, hasTid);
+ const result2 = changeViewPerspective(origin, result[0], hasTid);
expect(toSnapshot(result)).toMatchInlineSnapshot(`
[
"reuse,4",
diff --git a/tools/typst-preview-frontend/src/drag.ts b/tools/typst-preview-frontend/src/drag.ts
index 77fd4b7a9..e9906fbc1 100644
--- a/tools/typst-preview-frontend/src/drag.ts
+++ b/tools/typst-preview-frontend/src/drag.ts
@@ -1,50 +1,49 @@
export function setupDrag() {
- let lastPos = { x: 0, y: 0 };
- let moved = false;
- let containerElement: HTMLElement | null = null;
- const mouseMoveHandler = function (e: MouseEvent) {
- // How far the mouse has been moved
- const dx = e.clientX - lastPos.x;
- const dy = e.clientY - lastPos.y;
+ let lastPos = { x: 0, y: 0 };
+ let moved = false;
+ let containerElement: HTMLElement | null = null;
+ const mouseMoveHandler = function (e: MouseEvent) {
+ // How far the mouse has been moved
+ const dx = e.clientX - lastPos.x;
+ const dy = e.clientY - lastPos.y;
- window.scrollBy(-dx, -dy);
- lastPos = {
- x: e.clientX,
- y: e.clientY,
- };
- moved = true;
+ window.scrollBy(-dx, -dy);
+ lastPos = {
+ x: e.clientX,
+ y: e.clientY,
};
- const mouseUpHandler = function () {
- document.removeEventListener('mousemove', mouseMoveHandler);
- document.removeEventListener('mouseup', mouseUpHandler);
- if (!containerElement) return;
- if (!moved) {
- document.getSelection()?.removeAllRanges();
- }
- containerElement.style.cursor = 'grab';
- };
- const mouseDownHandler = function (e: MouseEvent) {
- lastPos = {
- // Get the current mouse position
- x: e.clientX,
- y: e.clientY,
- };
- if (!containerElement) return;
- const elementUnderMouse = e.target as HTMLElement | null;
- if (elementUnderMouse !== null && elementUnderMouse.classList.contains('tsel')) {
- return;
- }
- e.preventDefault();
- containerElement.style.cursor = 'grabbing';
- moved = false;
-
- document.addEventListener('mousemove', mouseMoveHandler);
- document.addEventListener('mouseup', mouseUpHandler);
- };
- document.addEventListener('DOMContentLoaded', () => {
- containerElement = document.getElementById('typst-container');
- if (!containerElement) return;
- containerElement.addEventListener('mousedown', mouseDownHandler);
+ moved = true;
+ };
+ const mouseUpHandler = function () {
+ document.removeEventListener("mousemove", mouseMoveHandler);
+ document.removeEventListener("mouseup", mouseUpHandler);
+ if (!containerElement) return;
+ if (!moved) {
+ document.getSelection()?.removeAllRanges();
}
- );
+ containerElement.style.cursor = "grab";
+ };
+ const mouseDownHandler = function (e: MouseEvent) {
+ lastPos = {
+ // Get the current mouse position
+ x: e.clientX,
+ y: e.clientY,
+ };
+ if (!containerElement) return;
+ const elementUnderMouse = e.target as HTMLElement | null;
+ if (elementUnderMouse !== null && elementUnderMouse.classList.contains("tsel")) {
+ return;
+ }
+ e.preventDefault();
+ containerElement.style.cursor = "grabbing";
+ moved = false;
+
+ document.addEventListener("mousemove", mouseMoveHandler);
+ document.addEventListener("mouseup", mouseUpHandler);
+ };
+ document.addEventListener("DOMContentLoaded", () => {
+ containerElement = document.getElementById("typst-container");
+ if (!containerElement) return;
+ containerElement.addEventListener("mousedown", mouseDownHandler);
+ });
}