Skip to content

Commit 9f25666

Browse files
authored
Merge pull request #253 from pathsim/feature/dom2svg-export
Replace SVG export with dom2svg
2 parents ab9c373 + b48fcae commit 9f25666

8 files changed

Lines changed: 2992 additions & 695 deletions

File tree

package-lock.json

Lines changed: 17 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"@codemirror/theme-one-dark": "^6.0.0",
4545
"@xyflow/svelte": "^1.5.0",
4646
"codemirror": "^6.0.0",
47-
"katex": "^0.16.0",
47+
"katex": "^0.16.0",
4848
"pathfinding": "^0.4.18",
4949
"plotly.js-dist-min": "^2.35.0",
5050
"pyodide": "^0.26.0"

src/lib/export/dom2svg/index.d.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/** Configuration for a single font face */
2+
interface FontConfig {
3+
url: string;
4+
weight?: string | number;
5+
style?: string;
6+
}
7+
/** Font mapping: family name → URL string, single config, or array of configs for multiple weights/styles */
8+
type FontMapping = Record<string, string | FontConfig | FontConfig[]>;
9+
/** Options for domToSvg() */
10+
interface DomToSvgOptions {
11+
/** Map of font-family → URL or FontConfig for text-to-path conversion */
12+
fonts?: FontMapping;
13+
/** CSS selector or predicate to exclude elements */
14+
exclude?: string | ((element: Element) => boolean);
15+
/** Custom handler for specific elements — return SVGElement to use it, or null to fall through to default rendering */
16+
handler?: (element: Element, context: RenderContext) => SVGElement | null;
17+
/** Background color for the root SVG (default: transparent) */
18+
background?: string;
19+
/** Extra padding around the captured area in px */
20+
padding?: number;
21+
/** Whether to convert text to paths using opentype.js (default: false) */
22+
textToPath?: boolean;
23+
/** Skip applying CSS transforms as SVG attributes (default: false).
24+
* When true, element positions come solely from getBoundingClientRect
25+
* which already includes CSS transforms. Use this when capturing containers
26+
* with nested CSS transforms (e.g. SvelteFlow, React Flow) where
27+
* the default behaviour would double-apply transforms. */
28+
flattenTransforms?: boolean;
29+
}
30+
/** Internal render context passed through the tree */
31+
interface RenderContext {
32+
/** The output SVG document */
33+
svgDocument: Document;
34+
/** The <defs> element for shared definitions */
35+
defs: SVGDefsElement;
36+
/** ID generator for unique IDs */
37+
idGenerator: IdGenerator;
38+
/** Options from the caller */
39+
options: DomToSvgOptions;
40+
/** Font cache (available when textToPath is enabled) */
41+
fontCache?: FontCache;
42+
/** Current inherited opacity */
43+
opacity: number;
44+
}
45+
/** Interface for unique ID generation */
46+
interface IdGenerator {
47+
next(prefix?: string): string;
48+
}
49+
/** Interface for the font cache */
50+
interface FontCache {
51+
getFont(family: string, weight?: string | number, style?: string): Promise<any>;
52+
has(family: string): boolean;
53+
}
54+
/** Result of domToSvg() */
55+
interface DomToSvgResult {
56+
/** The generated SVG element */
57+
svg: SVGSVGElement;
58+
/** Serialize to SVG string */
59+
toString(): string;
60+
/** Serialize to a Blob */
61+
toBlob(): Blob;
62+
/** Trigger a download in the browser */
63+
download(filename?: string): void;
64+
}
65+
66+
/**
67+
* Convert a DOM element (including hybrid HTML/SVG) to a self-contained SVG.
68+
*
69+
* @param element - The root DOM element to convert
70+
* @param options - Configuration options
71+
* @returns A result object with the SVG and serialization helpers
72+
*/
73+
declare function domToSvg(element: Element, options?: DomToSvgOptions): Promise<DomToSvgResult>;
74+
75+
export { type DomToSvgOptions, type DomToSvgResult, type FontConfig, type FontMapping, domToSvg };

0 commit comments

Comments
 (0)