mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
Compare commits
18 Commits
PDF-export
...
printToPDF
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23b94da8f0 | ||
|
|
1f227ddd24 | ||
|
|
12152665af | ||
|
|
064e17b29d | ||
|
|
0aaba80c82 | ||
|
|
1744668fbd | ||
|
|
8e3e2ffb25 | ||
|
|
f5475bfde6 | ||
|
|
27fa270b42 | ||
|
|
15ece75b5d | ||
|
|
a796621f93 | ||
|
|
3c943c6685 | ||
|
|
4209774b4e | ||
|
|
b18637f7d0 | ||
|
|
af8a848d14 | ||
|
|
01e392158d | ||
|
|
fc47b7aa0d | ||
|
|
a0e0627a49 |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "2.7.6-beta-1",
|
||||
"version": "2.8.0-rc-1",
|
||||
"minAppVersion": "1.1.6",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
292
package-lock.json
generated
292
package-lock.json
generated
@@ -9,10 +9,9 @@
|
||||
"version": "2.2.5",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cantoo/pdf-lib": "^2.2.4",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@zsviczian/colormaster": "^1.2.2",
|
||||
"@zsviczian/excalidraw": "0.17.6-26",
|
||||
"@zsviczian/excalidraw": "0.17.6-27",
|
||||
"chroma-js": "^2.4.2",
|
||||
"clsx": "^2.0.0",
|
||||
"es6-promise-pool": "2.5.0",
|
||||
@@ -79,7 +78,7 @@
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
|
||||
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
@@ -92,7 +91,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
|
||||
"integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.24.7",
|
||||
"picocolors": "^1.0.0"
|
||||
@@ -105,7 +104,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.8.tgz",
|
||||
"integrity": "sha512-c4IM7OTg6k1Q+AJ153e2mc2QVTezTwnb4VzquwcyiEzGnW0Kedv4do/TrkU98qPeC5LNiMt/QXwIjzYXLBpyZg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -114,7 +113,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.8.tgz",
|
||||
"integrity": "sha512-6AWcmZC/MZCO0yKys4uhg5NlxL0ESF3K6IAaoQ+xSXvPyPyxNWRafP+GDbI88Oh68O7QkJgmEtedWPM9U0pZNg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.0",
|
||||
"@babel/code-frame": "^7.24.7",
|
||||
@@ -144,7 +143,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.8.tgz",
|
||||
"integrity": "sha512-47DG+6F5SzOi0uEvK4wMShmn5yY0mVjVJoWTphdY2B4Rx9wHgjK7Yhtr0ru6nE+sn0v38mzrWOlah0p/YlHHOQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.24.8",
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
@@ -159,7 +158,7 @@
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
|
||||
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jsesc": "bin/jsesc"
|
||||
@@ -197,7 +196,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz",
|
||||
"integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.24.8",
|
||||
"@babel/helper-validator-option": "^7.24.8",
|
||||
@@ -269,7 +268,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
|
||||
"integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.24.7"
|
||||
},
|
||||
@@ -281,7 +280,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
|
||||
"integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.24.7",
|
||||
"@babel/types": "^7.24.7"
|
||||
@@ -294,7 +293,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz",
|
||||
"integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.24.7"
|
||||
},
|
||||
@@ -319,7 +318,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
|
||||
"integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/traverse": "^7.24.7",
|
||||
"@babel/types": "^7.24.7"
|
||||
@@ -332,7 +331,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.8.tgz",
|
||||
"integrity": "sha512-m4vWKVqvkVAWLXfHCCfff2luJj86U+J0/x+0N3ArG/tP0Fq7zky2dYwMbtPmkc/oulkkbjdL3uWzuoBwQ8R00Q==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-environment-visitor": "^7.24.7",
|
||||
"@babel/helper-module-imports": "^7.24.7",
|
||||
@@ -406,7 +405,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
|
||||
"integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/traverse": "^7.24.7",
|
||||
"@babel/types": "^7.24.7"
|
||||
@@ -432,7 +431,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
|
||||
"integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.24.7"
|
||||
},
|
||||
@@ -444,7 +443,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
|
||||
"integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -453,7 +452,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
|
||||
"integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -462,7 +461,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
|
||||
"integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -486,7 +485,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz",
|
||||
"integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.24.7",
|
||||
"@babel/types": "^7.24.8"
|
||||
@@ -499,7 +498,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
|
||||
"integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.24.7",
|
||||
"chalk": "^2.4.2",
|
||||
@@ -514,7 +513,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz",
|
||||
"integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
},
|
||||
@@ -1820,9 +1819,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz",
|
||||
"integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==",
|
||||
"version": "7.26.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
|
||||
"integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
},
|
||||
@@ -1834,7 +1833,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz",
|
||||
"integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.24.7",
|
||||
"@babel/parser": "^7.24.7",
|
||||
@@ -1848,7 +1847,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz",
|
||||
"integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.24.7",
|
||||
"@babel/generator": "^7.24.8",
|
||||
@@ -1869,7 +1868,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.8.tgz",
|
||||
"integrity": "sha512-SkSBEHwwJRU52QEVZBmMBnE5Ux2/6WU1grdYyOhpbCNxbmJrDuDCphBzKZSO3taf0zztp+qkWlymE5tVL5l0TA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.24.8",
|
||||
"@babel/helper-validator-identifier": "^7.24.7",
|
||||
@@ -1884,19 +1883,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.2.tgz",
|
||||
"integrity": "sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg=="
|
||||
},
|
||||
"node_modules/@cantoo/pdf-lib": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@cantoo/pdf-lib/-/pdf-lib-2.2.4.tgz",
|
||||
"integrity": "sha512-69bECXjl0QVMrBTEsPZDPFmhoyLGwXKiJI5JWPgBnAx0kS5+7v76rNCeYMTbDmZaPgvdIViMvTaz2HVCe8u1fw==",
|
||||
"dependencies": {
|
||||
"@pdf-lib/standard-fonts": "^1.0.0",
|
||||
"@pdf-lib/upng": "^1.0.1",
|
||||
"color": "^4.2.3",
|
||||
"crypto-js": "^4.2.0",
|
||||
"node-html-better-parser": "^1.4.0",
|
||||
"pako": "^1.0.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/commands": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.0.tgz",
|
||||
@@ -2248,7 +2234,7 @@
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
|
||||
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/set-array": "^1.2.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
@@ -2262,7 +2248,7 @@
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
@@ -2271,7 +2257,7 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
|
||||
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
@@ -2290,13 +2276,13 @@
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.25",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
|
||||
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
@@ -2361,22 +2347,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@pdf-lib/standard-fonts": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz",
|
||||
"integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==",
|
||||
"dependencies": {
|
||||
"pako": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@pdf-lib/upng": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz",
|
||||
"integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==",
|
||||
"dependencies": {
|
||||
"pako": "^1.0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
@@ -3366,9 +3336,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@zsviczian/excalidraw": {
|
||||
"version": "0.17.6-26",
|
||||
"resolved": "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.17.6-26.tgz",
|
||||
"integrity": "sha512-UAqr7b7cxIbOvK1u0NKqgAs0wB9KYUsVc6Q2J+yviM4ae+wkTXp8qW/V4mdWADJ3lTG5RgXCb9ausIKfSkPNRg==",
|
||||
"version": "0.17.6-27",
|
||||
"resolved": "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.17.6-27.tgz",
|
||||
"integrity": "sha512-8E5pfMbKO80d9oXyApF43SCKaR0CcLhVHjiQYEuAXzS7v6XzrDHODsNg+HuN9kOiShXmmn/e1MKVawo7bmeuOQ==",
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "6.0.2",
|
||||
"@excalidraw/random-username": "1.1.0",
|
||||
@@ -3384,7 +3354,8 @@
|
||||
"fractional-indexing": "3.2.0",
|
||||
"fuzzy": "0.1.3",
|
||||
"image-blob-reduce": "3.0.1",
|
||||
"jotai": "1.13.1",
|
||||
"jotai": "2.11.0",
|
||||
"jotai-scope": "0.7.2",
|
||||
"lodash.throttle": "4.1.1",
|
||||
"nanoid": "3.3.3",
|
||||
"open-color": "1.9.1",
|
||||
@@ -3476,9 +3447,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.12.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
|
||||
"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
@@ -3540,7 +3511,7 @@
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
@@ -3683,7 +3654,7 @@
|
||||
"version": "4.23.2",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz",
|
||||
"integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -3755,7 +3726,7 @@
|
||||
"version": "1.0.30001641",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz",
|
||||
"integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -3780,7 +3751,7 @@
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
@@ -3847,23 +3818,11 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/color": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1",
|
||||
"color-string": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
@@ -3871,32 +3830,8 @@
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||
},
|
||||
"node_modules/color-string": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
|
||||
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
|
||||
"dependencies": {
|
||||
"color-name": "^1.0.0",
|
||||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/color/node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color/node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/colord": {
|
||||
"version": "2.9.3",
|
||||
@@ -3934,7 +3869,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/core-js-compat": {
|
||||
"version": "3.37.1",
|
||||
@@ -4009,11 +3944,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
||||
},
|
||||
"node_modules/css-declaration-sorter": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz",
|
||||
@@ -4868,7 +4798,7 @@
|
||||
"version": "1.4.827",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.827.tgz",
|
||||
"integrity": "sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/elkjs": {
|
||||
"version": "0.9.3",
|
||||
@@ -4908,7 +4838,7 @@
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
|
||||
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -4917,7 +4847,7 @@
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
@@ -5467,7 +5397,7 @@
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -5523,7 +5453,7 @@
|
||||
"version": "11.12.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
@@ -5576,7 +5506,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
@@ -5593,21 +5523,6 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/html-entities": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz",
|
||||
"integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/mdevils"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://patreon.com/mdevils"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
@@ -5702,11 +5617,6 @@
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
||||
},
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
@@ -5876,62 +5786,34 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jotai": {
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/jotai/-/jotai-1.13.1.tgz",
|
||||
"integrity": "sha512-RUmH1S4vLsG3V6fbGlKzGJnLrDcC/HNb5gH2AeA9DzuJknoVxSGvvg8OBB7lke+gDc4oXmdVsaKn/xDUhWZ0vw==",
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/jotai/-/jotai-2.11.0.tgz",
|
||||
"integrity": "sha512-zKfoBBD1uDw3rljwHkt0fWuja1B76R7CjznuBO+mSX6jpsO1EBeWNRKpeaQho9yPI/pvCv4recGfgOXGxwPZvQ==",
|
||||
"engines": {
|
||||
"node": ">=12.20.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "*",
|
||||
"@babel/template": "*",
|
||||
"jotai-devtools": "*",
|
||||
"jotai-immer": "*",
|
||||
"jotai-optics": "*",
|
||||
"jotai-redux": "*",
|
||||
"jotai-tanstack-query": "*",
|
||||
"jotai-urql": "*",
|
||||
"jotai-valtio": "*",
|
||||
"jotai-xstate": "*",
|
||||
"jotai-zustand": "*",
|
||||
"react": ">=16.8"
|
||||
"@types/react": ">=17.0.0",
|
||||
"react": ">=17.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@babel/core": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@babel/template": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-devtools": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-immer": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-optics": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-redux": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-tanstack-query": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-urql": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-valtio": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-xstate": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-zustand": {
|
||||
"react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/jotai-scope": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/jotai-scope/-/jotai-scope-0.7.2.tgz",
|
||||
"integrity": "sha512-Gwed97f3dDObrO43++2lRcgOqw4O2sdr4JCjP/7eHK1oPACDJ7xKHGScpJX9XaflU+KBHXF+VhwECnzcaQiShg==",
|
||||
"peerDependencies": {
|
||||
"jotai": ">=2.9.2",
|
||||
"react": ">=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
@@ -5986,7 +5868,7 @@
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
},
|
||||
@@ -6155,7 +6037,7 @@
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
@@ -6857,19 +6739,11 @@
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/node-html-better-parser": {
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/node-html-better-parser/-/node-html-better-parser-1.4.7.tgz",
|
||||
"integrity": "sha512-cJcBhlrn432XtbzPmzxxMLsHeSUnE5qFQtVbVlHXvUGt2ccqc0/wBsB43CFv39BIkLkP5rrPUN5Hg52CnheH+A==",
|
||||
"dependencies": {
|
||||
"html-entities": "^2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.14",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
|
||||
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/non-layered-tidy-tree-layout": {
|
||||
"version": "2.0.2",
|
||||
@@ -7125,7 +6999,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
||||
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
@@ -8391,7 +8265,7 @@
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
@@ -8437,14 +8311,6 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
|
||||
"dependencies": {
|
||||
"is-arrayish": "^0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
@@ -8653,7 +8519,7 @@
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
@@ -8764,7 +8630,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
@@ -9001,7 +8867,7 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
|
||||
"integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -9362,7 +9228,7 @@
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/yn": {
|
||||
"version": "3.1.1",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@zsviczian/excalidraw": "0.17.6-26",
|
||||
"@zsviczian/excalidraw": "0.17.6-27",
|
||||
"chroma-js": "^2.4.2",
|
||||
"clsx": "^2.0.0",
|
||||
"@zsviczian/colormaster": "^1.2.2",
|
||||
@@ -40,8 +40,7 @@
|
||||
"react-dom": "^18.2.0",
|
||||
"roughjs": "^4.5.2",
|
||||
"woff2sfnt-sfnt2woff": "^1.0.0",
|
||||
"es6-promise-pool": "2.5.0",
|
||||
"@cantoo/pdf-lib": "^2.2.4"
|
||||
"es6-promise-pool": "2.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jsesc": "^3.0.2",
|
||||
|
||||
@@ -147,6 +147,7 @@ const BUILD_CONFIG = {
|
||||
entryFileNames: 'main.js',
|
||||
format: 'cjs',
|
||||
exports: 'default',
|
||||
inlineDynamicImports: true, // Add this line only
|
||||
},
|
||||
plugins: getRollupPlugins(
|
||||
{
|
||||
|
||||
@@ -105,6 +105,41 @@
|
||||
*/
|
||||
//ea.onFileCreateHook = (data) => {};
|
||||
|
||||
/**
|
||||
* If set, this callback is triggered when a image is being saved in Excalidraw.
|
||||
* You can use this callback to customize the naming and path of pasted images to avoid
|
||||
* default names like "Pasted image 123147170.png" being saved in the attachments folder,
|
||||
* and instead use more meaningful names based on the Excalidraw file or other criteria,
|
||||
* plus save the image in a different folder.
|
||||
*
|
||||
* If the function returns null or undefined, the normal Excalidraw operation will continue
|
||||
* with the excalidraw generated name and default path.
|
||||
* If a filepath is returned, that will be used. Include the full Vault filepath and filename
|
||||
* with the file extension.
|
||||
* The currentImageName is the name of the image generated by excalidraw or provided during paste.
|
||||
*
|
||||
* @param data - An object containing the following properties:
|
||||
* @property {string} [currentImageName] - Default name for the image.
|
||||
* @property {string} drawingFilePath - The file path of the Excalidraw file where the image is being used.
|
||||
*
|
||||
* @returns {string} - The new filepath for the image including full vault path and extension.
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* onImageFilePathHook: (data) => {
|
||||
* const { currentImageName, drawingFilePath } = data;
|
||||
* const ext = currentImageName.split('.').pop();
|
||||
* // Generate a new filepath based on the drawing file name and other criteria
|
||||
* return `${drawingFileName} - ${currentImageName || 'image'}.${ext}`;
|
||||
* }
|
||||
* ```
|
||||
* onImageFilePathHook: (data: {
|
||||
* currentImageName: string; // Excalidraw generated name of the image, or the name received from the file system.
|
||||
* drawingFilePath: string; // The full filepath of the Excalidraw file where the image is being used.
|
||||
* }) => string = null;
|
||||
*/
|
||||
//ea.onImageFilePathHook = (data) => {};
|
||||
|
||||
/**
|
||||
* If set, this callback is triggered whenever the active canvas color changes
|
||||
* onCanvasColorChangeHook: (
|
||||
|
||||
@@ -26,7 +26,7 @@ export const ERROR_IFRAME_CONVERSION_CANCELED = "iframe conversion canceled";
|
||||
|
||||
declare const excalidrawLib: typeof ExcalidrawLib;
|
||||
|
||||
export const LOCALE = moment.locale();
|
||||
export const LOCALE = localStorage.getItem("language")?.toLowerCase() || "en";
|
||||
export const CJK_FONTS = "CJK Fonts";
|
||||
|
||||
export const obsidianToExcalidrawMap: { [key: string]: string } = {
|
||||
@@ -446,4 +446,4 @@ export const SCRIPTENGINE_ICON = `<g transform="translate(-8,-8)"><path d="M24.3
|
||||
export const DISK_ICON_NAME = "save";
|
||||
export const EXPORT_IMG_ICON = ` <g transform="scale(4.166)" strokeWidth="1.25" fill="none" stroke="currentColor"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M15 8h.01"></path><path d="M12 20h-5a3 3 0 0 1 -3 -3v-10a3 3 0 0 1 3 -3h10a3 3 0 0 1 3 3v5"></path><path d="M4 15l4 -4c.928 -.893 2.072 -.893 3 0l4 4"></path><path d="M14 14l1 -1c.617 -.593 1.328 -.793 2.009 -.598"></path><path d="M19 16v6"></path><path d="M22 19l-3 3l-3 -3"></path></g>`;
|
||||
export const EXPORT_IMG_ICON_NAME = `export-img`;
|
||||
export const EXCALIDRAW_ICON = `<path d="M24 17h121v121H24z" style="fill:none" transform="matrix(.8843 0 0 .83471 -21.223 -14.19)"/><path d="M119.81 105.98a.549.549 0 0 0-.53-.12c-4.19-6.19-9.52-12.06-14.68-17.73l-.85-.93c0-.11-.05-.21-.12-.3a.548.548 0 0 0-.34-.2l-.17-.18-.12-.09c-.15-.32-.53-.56-.95-.35-1.58.81-3 1.97-4.4 3.04-1.87 1.43-3.7 2.92-5.42 4.52-.7.65-1.39 1.33-1.97 2.09-.28.37-.07.72.27.87-1.22 1.2-2.45 2.45-3.68 3.74-.11.12-.17.28-.16.44.01.16.09.31.22.41l2.16 1.65s.01.03.03.04c3.09 3.05 8.51 7.28 14.25 11.76.85.67 1.71 1.34 2.57 2.01.39.47.76.94 1.12 1.4.19.25.55.3.8.11.13.1.26.21.39.31a.57.57 0 0 0 .8-.1c.07-.09.1-.2.11-.31.04 0 .07.03.1.03.15 0 .31-.06.42-.18l10.18-11.12a.56.56 0 0 0-.04-.8l.01-.01Zm-29.23-3.85c.07.09.14.17.21.25 1.16.98 2.4 2.04 3.66 3.12l-5.12-3.91s-.32-.22-.52-.36c-.11-.08-.21-.16-.31-.24l-.38-.32s.07-.07.1-.11l.35-.35c1.72-1.74 4.67-4.64 6.19-6.06-1.61 1.62-4.87 6.37-4.17 7.98h-.01Zm17.53 13.81-4.22-3.22c-1.65-1.71-3.43-3.4-5.24-5.03 2.28 1.76 4.23 3.25 4.52 3.51 2.21 1.97 2.11 1.61 3.63 2.91l1.83 1.33c-.18.16-.36.33-.53.49l.01.01Zm1.06.81-.08-.06c.16-.13.33-.25.49-.38l-.4.44h-.01Zm-66.93-65.3c.14.72.27 1.43.4 2.11.69 3.7 1.33 7.03 2.55 9.56l.48 1.92c.19.73.46 1.64.71 1.83 2.85 2.52 7.22 6.28 11.89 9.82.21.16.5.15.7-.01.01.02.03.03.04.04.11.1.24.15.38.15.16 0 .31-.06.42-.19 5.98-6.65 10.43-12.12 13.6-16.7.2-.25.3-.54.29-.84.2-.24.41-.48.6-.68a.558.558 0 0 0-.1-.86.578.578 0 0 0-.17-.36c-1.39-1.34-2.42-2.31-3.46-3.28-1.84-1.72-3.74-3.5-7.77-7.51-.02-.02-.05-.04-.07-.06a.555.555 0 0 0-.22-.14c-1.11-.39-3.39-.78-6.26-1.28-4.22-.72-10-1.72-15.2-3.27h-.04v-.01s-.02 0-.03.02h-.01l.04-.02s-.31.01-.37.04c-.08.04-.14.09-.19.15-.05.06-.09.12-.47.2-.38.08.08 0 .11 0h-.11v.03c.07.34.05.58.16.97-.02.1.21 1.02.24 1.11l1.83 7.26h.03Zm30.95 6.54s-.03.04-.04.05l-.64-.71c.22.21.44.42.68.66Zm-7.09 9.39s-.07.08-.1.12l-.02-.02c.04-.03.08-.07.13-.1h-.01Zm-7.07 8.47Zm3.02-28.57c.35.35 1.74 1.65 2.06 1.97-1.45-.66-5.06-2.34-6.74-2.88 1.65.29 3.93.66 4.68.91Zm-19.18-2.77c.84 1.44 1.5 6.49 2.16 11.4-.37-1.58-.69-3.12-.99-4.6-.52-2.56-1-4.85-1.67-6.88.14.01.31.03.49.05 0 .01 0 .02.02.03h-.01Zm-.29-1.21c-.23-.02-.44-.04-.62-.05-.02-.04-.03-.08-.04-.12l.66.18v-.01Zm-2.22.45v-.02.02Zm78.54-1.18c.04-.23-1.1-1.24-.74-1.26.85-.04.86-1.35 0-1.31-1.13.06-2.27.32-3.37.53-1.98.37-3.95.78-5.92 1.21-4.39.94-8.77 1.93-13.1 3.11-1.36.37-2.86.7-4.11 1.36-.42.22-.4.67-.17.95-.09.05-.18.08-.28.09-.37.07-.74.13-1.11.19a.566.566 0 0 0-.39.86c-2.32 3.1-4.96 6.44-7.82 9.95-2.81 3.21-5.73 6.63-8.72 10.14-9.41 11.06-20.08 23.6-31.9 34.64-.23.21-.24.57-.03.8.05.06.12.1.19.13-.16.15-.32.3-.48.44-.1.09-.14.2-.16.32-.08.08-.16.17-.23.25-.21.23-.2.59.03.8.23.21.59.2.8-.03.04-.04.08-.09.12-.13a.84.84 0 0 1 1.22 0c.69.74 1.34 1.44 1.95 2.09l-1.38-1.15a.57.57 0 0 0-.8.07c-.2.24-.17.6.07.8l14.82 12.43c.11.09.24.13.37.13.15 0 .29-.06.4-.17l.36-.36a.56.56 0 0 0 .63-.12c20.09-20.18 36.27-35.43 54.8-49.06.17-.12.25-.32.23-.51a.57.57 0 0 0 .48-.39c3.42-10.46 4.08-19.72 4.28-24.27 0-.03.01-.05.02-.07.02-.05.03-.1.04-.14.03-.11.05-.19.05-.19.26-.78.17-1.53-.15-2.15v.02ZM82.98 58.94c.9-1.03 1.79-2.04 2.67-3.02-5.76 7.58-15.3 19.26-28.81 33.14 9.2-10.18 18.47-20.73 26.14-30.12Zm-32.55 52.81-.03-.03c.11.02.19.04.2.04a.47.47 0 0 0-.17 0v-.01Zm6.9 6.42-.05-.04.03-.03c.02 0 .03.02.04.02 0 .02-.02.03-.03.05h.01Zm8.36-7.21 1.38-1.44c.01.01.02.03.03.05-.47.46-.94.93-1.42 1.39h.01Zm2.24-2.21c.26-.3.56-.65.87-1.02.01-.01.02-.03.04-.04 3.29-3.39 6.68-6.82 10.18-10.25.02-.02.05-.04.07-.06.86-.66 1.82-1.39 2.72-2.08-4.52 4.32-9.11 8.78-13.88 13.46v-.01Zm21.65-55.88c-1.86 2.42-3.9 5.56-5.63 8.07-5.46 7.91-23.04 27.28-23.43 27.65-2.71 2.62-10.88 10.46-16.09 15.37-.14.13-.25.24-.34.35a.794.794 0 0 1 .03-1.13c24.82-23.4 39.88-42.89 46-51.38-.13.33-.24.69-.55 1.09l.01-.02Zm16.51 7.1-.01.02c0-.02-.02-.07.01-.02Zm-.91-5.13Zm-5.89 9.45c-2.26-1.31-3.32-3.27-2.71-5.25l.19-.66c.08-.19.17-.38.28-.57.59-.98 1.49-1.85 2.52-2.36.05-.02.1-.03.15-.04a.795.795 0 0 1-.04-.43c.05-.31.25-.58.66-.58.67 0 2.75.62 3.54 1.3.24.19.47.4.68.63.3.35.74.92.96 1.33.13.06.23.62.38.91.14.46.2.93.18 1.4 0 .02 0 .02.01.03-.03.07 0 .37-.04.4-.1.72-.36 1.43-.75 2.05-.04.05-.07.11-.11.16 0 .01-.02.02-.03.04-.3.43-.65.83-1.08 1.13-1.26.89-2.73 1.16-4.2.79a6.33 6.33 0 0 1-.57-.25l-.02-.03Zm16.27-1.63c-.49 2.05-1.09 4.19-1.8 6.38-.03.08-.03.16-.03.23-.1.01-.19.05-.27.11-4.44 3.26-8.73 6.62-12.98 10.11 3.67-3.32 7.39-6.62 11.23-9.95a6.409 6.409 0 0 0 2.11-3.74l.56-3.37.03-.1c.25-.71 1.34-.4 1.17.33h-.02Z" style="fill:currentColor;fill-rule:nonzero" transform="translate(-26.41 -29.49)"/>`;
|
||||
export const EXCALIDRAW_ICON = `<path d="M24 17h121v121H24z" style="fill:none" transform="matrix(.8843 0 0 .83471 -21.223 -14.19)"/><path d="M119.81 105.98a.549.549 0 0 0-.53-.12c-4.19-6.19-9.52-12.06-14.68-17.73l-.85-.93c0-.11-.05-.21-.12-.3a.548.548 0 0 0-.34-.2l-.17-.18-.12-.09c-.15-.32-.53-.56-.95-.35-1.58.81-3 1.97-4.4 3.04-1.87 1.43-3.7 2.92-5.42 4.52-.7.65-1.39 1.33-1.97 2.09-.28.37-.07.72.27.87-1.22 1.2-2.45 2.45-3.68 3.74-.11.12-.17.28-.16.44.01.16.09.31.22.41l2.16 1.65s.01.03.03.04c3.09 3.05 8.51 7.28 14.25 11.76.85.67 1.71 1.34 2.57 2.01.39.47.76.94 1.12 1.4.19.25.55.3.8.11.13.1.26.21.39.31a.57.57 0 0 0 .8-.1c.07-.09.1-.2.11-.31.04 0 .07.03.1.03.15 0 .31-.06.42-.18l10.18-11.12a.56.56 0 0 0-.04-.8l.01-.01Zm-29.23-3.85c.07.09.14.17.21.25 1.16.98 2.4 2.04 3.66 3.12l-5.12-3.91s-.32-.22-.52-.36c-.11-.08-.21-.16-.31-.24l-.38-.32s.07-.07.1-.11l.35-.35c1.72-1.74 4.67-4.64 6.19-6.06-1.61 1.62-4.87 6.37-4.17 7.98h-.01Zm17.53 13.81-4.22-3.22c-1.65-1.71-3.43-3.4-5.24-5.03 2.28 1.76 4.23 3.25 4.52 3.51 2.21 1.97 2.11 1.61 3.63 2.91l1.83 1.33c-.18.16-.36.33-.53.49l.01.01Zm1.06.81-.08-.06c.16-.13.33-.25.49-.38l-.4.44h-.01Zm-66.93-65.3c.14.72.27 1.43.4 2.11.69 3.7 1.33 7.03 2.55 9.56l.48 1.92c.19.73.46 1.64.71 1.83 2.85 2.52 7.22 6.28 11.89 9.82.21.16.5.15.7-.01.01.02.03.03.04.04.11.1.24.15.38.15.16 0 .31-.06.42-.19 5.98-6.65 10.43-12.12 13.6-16.7.2-.25.3-.54.29-.84.2-.24.41-.48.6-.68a.558.558 0 0 0-.1-.86.578.578 0 0 0-.17-.36c-1.39-1.34-2.42-2.31-3.46-3.28-1.84-1.72-3.74-3.5-7.77-7.51-.02-.02-.05-.04-.07-.06a.555.555 0 0 0-.22-.14c-1.11-.39-3.39-.78-6.26-1.28-4.22-.72-10-1.72-15.2-3.27h-.04v-.01s-.02 0-.03.02h-.01l.04-.02s-.31.01-.37.04c-.08.04-.14.09-.19.15-.05.06-.09.12-.47.2-.38.08.08 0 .11 0h-.11v.03c.07.34.05.58.16.97-.02.1.21 1.02.24 1.11l1.83 7.26h.03Zm30.95 6.54s-.03.04-.04.05l-.64-.71c.22.21.44.42.68.66Zm-7.09 9.39s-.07.08-.1.12l-.02-.02c.04-.03.08-.07.13-.1h-.01Zm-7.07 8.47Zm3.02-28.57c.35.35 1.74 1.65 2.06 1.97-1.45-.66-5.06-2.34-6.74-2.88 1.65.29 3.93.66 4.68.91Zm-19.18-2.77c.84 1.44 1.5 6.49 2.16 11.4-.37-1.58-.69-3.12-.99-4.6-.52-2.56-1-4.85-1.67-6.88.14.01.31.03.49.05 0 .01 0 .02.02.03h-.01Zm-.29-1.21c-.23-.02-.44-.04-.62-.05-.02-.04-.03-.08-.04-.12l.66.18v-.01Zm-2.22.45v-.02.02Zm78.54-1.18c.04-.23-1.1-1.24-.74-1.26.85-.04.86-1.35 0-1.31-1.13.06-2.27.32-3.37.53-1.98.37-3.95.78-5.92 1.21-4.39.94-8.77 1.93-13.1 3.11-1.36.37-2.86.7-4.11 1.36-.42.22-.4.67-.17.95-.09.05-.18.08-.28.09-.37.07-.74.13-1.11.19a.566.566 0 0 0-.39.86c-2.32 3.1-4.96 6.44-7.82 9.95-2.81 3.21-5.73 6.63-8.72 10.14-9.41 11.06-20.08 23.6-31.9 34.64-.23.21-.24.57-.03.8.05.06.12.1.19.13-.16.15-.32.3-.48.44-.1.09-.14.2-.16.32-.08.08-.16.17-.23.25-.21.23-.2.59.03.8.23.21.59.2.8-.03.04-.04.08-.09.12-.13a.84.84 0 0 1 1.22 0c.69.74 1.34 1.44 1.95 2.09l-1.38-1.15a.57.57 0 0 0-.8.07c-.2.24-.17.6.07.8l14.82 12.43c.11.09.24.13.37.13.15 0 .29-.06.4-.17l.36-.36a.56.56 0 0 0 .63-.12c20.09-20.18 36.27-35.43 54.8-49.06.17-.12.25-.32.23-.51a.57.57 0 0 0 .48-.39c3.42-10.46 4.08-19.72 4.28-24.27 0-.03.01-.05.02-.07.02-.05.03-.1.04-.14.03-.11.05-.19.05-.19.26-.78.17-1.53-.15-2.15v.02ZM82.98 58.94c.9-1.03 1.79-2.04 2.67-3.02-5.76 7.58-15.3 19.26-28.81 33.14 9.2-10.18 18.47-20.73 26.14-30.12Zm-32.55 52.81-.03-.03c.11.02.19.04.2.04a.47.47 0 0 0-.17 0v-.01Zm6.9 6.42-.05-.04.03-.03c.02 0 .03.02.04.02 0 .02-.02.03-.03.05h.01Zm8.36-7.21 1.38-1.44c.01.01.02.03.03.05-.47.46-.94.93-1.42 1.39h.01Zm2.24-2.21c.26-.3.56-.65.87-1.02.01-.01.02-.03.04-.04 3.29-3.39 6.68-6.82 10.18-10.25.02-.02.05-.04.07-.06.86-.66 1.82-1.39 2.72-2.08-4.52 4.32-9.11 8.78-13.88 13.46v-.01Zm21.65-55.88c-1.86 2.42-3.9 5.56-5.63 8.07-5.46 7.91-23.04 27.28-23.43 27.65-2.71 2.62-10.88 10.46-16.09 15.37-.14.13-.25.24-.34.35a.794.794 0 0 1 .03-1.13c24.82-23.4 39.88-42.89 46-51.38-.13.33-.24.69-.55 1.09l.01-.02Zm16.51 7.1-.01.02c0-.02-.02-.07.01-.02Zm-.91-5.13Zm-5.89 9.45c-2.26-1.31-3.32-3.27-2.71-5.25l.19-.66c.08-.19.17-.38.28-.57.59-.98 1.49-1.85 2.52-2.36.05-.02.1-.03.15-.04a.795.795 0 0 1-.04-.43c.05-.31.25-.58.66-.58.67 0 2.75.62 3.54 1.3.24.19.47.4.68.63.3.35.74.92.96 1.33.13.06.23.62.38.91.14.46.2.93.18 1.4 0 .02 0 .02.01.03-.03.07 0 .37-.04.4-.1.72-.36 1.43-.75 2.05-.04.05-.07.11-.11.16 0 .01-.02.02-.03.04-.3.43-.65.83-1.08 1.13-1.26.89-2.73 1.16-4.2.79a6.33 6.33 0 0 1-.57-.25l-.02-.03Zm16.27-1.63c-.49 2.05-1.09 4.19-1.8 6.38-.03.08-.03.16-.03.23-.1.01-.19.05-.27.11-4.44 3.26-8.73 6.62-12.98 10.11 3.67-3.32 7.39-6.62 11.23-9.95a6.409 6.409 0 0 0 2.11-3.74l.56-3.37.03-.1c.25-.71 1.34-.4 1.17.33h-.02Z" style="fill:currentColor;fill-rule:nonzero" transform="translate(-26.41 -29.49)"/>`;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -801,15 +801,16 @@ const tmpObsidianWYSIWYG = async (
|
||||
if(Boolean(ctx.frontmatter)) {
|
||||
el.empty();
|
||||
} else {
|
||||
const warningEl = el.querySelector("div>h3[data-heading^='Unable to find section #^");
|
||||
//Obsidian changed this at some point from h3 to h5 and also the text...
|
||||
const warningEl = el.querySelector("div>*[data-heading^='Unable to find ");
|
||||
if(warningEl) {
|
||||
const ref = warningEl.getAttr("data-heading").match(/Unable to find section (#\^(?:group=|area=|frame=|clippedframe=)[^ ]*)/)?.[1];
|
||||
const dataHeading = warningEl.getAttr("data-heading");
|
||||
const ref = warningEl.getAttr("data-heading").match(/Unable to find[^^]+(\^(?:group=|area=|frame=|clippedframe=)[^ ”]+)/)?.[1];
|
||||
if(ref) {
|
||||
attr.fname = file.path + ref;
|
||||
attr.fname = file.path + "#" +ref;
|
||||
areaPreview = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(!isFrontmatterDiv && !areaPreview) {
|
||||
if(el.parentElement === containerEl) containerEl.removeChild(el);
|
||||
|
||||
@@ -502,11 +502,11 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
|
||||
pdfSettings: {
|
||||
pageSize: "A4",
|
||||
pageOrientation: "portrait",
|
||||
fitToPage: true,
|
||||
fitToPage: 1,
|
||||
paperColor: "white",
|
||||
customPaperColor: "#ffffff",
|
||||
alignment: "center",
|
||||
margin: "normal"
|
||||
margin: "normal",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2508,6 +2508,9 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
|
||||
this.requestReloadDrawings = true;
|
||||
this.plugin.settings.experimentalEnableFourthFont = value;
|
||||
this.applySettingsUpdate();
|
||||
if(value) {
|
||||
this.plugin.initializeFonts();
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -1050,6 +1050,12 @@ FILENAME_HEAD: "Filename",
|
||||
EXPORTDIALOG_ORIENTATION_LANDSCAPE: "Landscape",
|
||||
EXPORTDIALOG_PDF_FIT_TO_PAGE: "Page Fitting",
|
||||
EXPORTDIALOG_PDF_FIT_OPTION: "Fit to page",
|
||||
EXPORTDIALOG_PDF_FIT_2_OPTION: "Fit to max 2-pages",
|
||||
EXPORTDIALOG_PDF_FIT_4_OPTION: "Fit to max 4-pages",
|
||||
EXPORTDIALOG_PDF_FIT_6_OPTION: "Fit to max 6-pages",
|
||||
EXPORTDIALOG_PDF_FIT_8_OPTION: "Fit to max 8-pages",
|
||||
EXPORTDIALOG_PDF_FIT_12_OPTION: "Fit to max 12-pages",
|
||||
EXPORTDIALOG_PDF_FIT_16_OPTION: "Fit to max 16-pages",
|
||||
EXPORTDIALOG_PDF_SCALE_OPTION: "Use image scale (may span multiple pages)",
|
||||
EXPORTDIALOG_PDF_PAPER_COLOR: "Paper Color",
|
||||
EXPORTDIALOG_PDF_PAPER_WHITE: "White",
|
||||
@@ -1078,5 +1084,11 @@ FILENAME_HEAD: "Filename",
|
||||
EXPORTDIALOG_PNGTOCLIPBOARD : "PNG to Clipboard",
|
||||
EXPORTDIALOG_SVGTOCLIPBOARD : "SVG to Clipboard",
|
||||
EXPORTDIALOG_PDF: "Export PDF",
|
||||
EXPORTDIALOG_PDFTOVAULT: "PDF to Vault",
|
||||
|
||||
EXPORTDIALOG_PDF_PROGRESS_NOTICE: "Exporting PDF. If this image is large, it may take a while.",
|
||||
EXPORTDIALOG_PDF_PROGRESS_DONE: "Export complete",
|
||||
EXPORTDIALOG_PDF_PROGRESS_ERROR: "Error exporting PDF, check developer console for details",
|
||||
|
||||
//exportUtils.ts
|
||||
PDF_EXPORT_DESKTOP_ONLY: "PDF export is only available on desktop",
|
||||
};
|
||||
|
||||
@@ -386,13 +386,14 @@ FILENAME_HEAD: "文件名",
|
||||
"此设置不会影响您在 Excalidraw 模式下的绘图显示,或者在将绘图嵌入 Markdown 文档时,或在渲染悬停预览时。<br><ul>" +
|
||||
"<li>请参阅下面‘嵌入和导出’部分的 <a href='#"+TAG_PDFEXPORT+"'>PDF 导出</a> 相关设置。</li></ul><br>" +
|
||||
"您必须关闭当前的 Excalidraw/Markdown 文件并重新打开,以使此更改生效。",
|
||||
SHOW_DRAWING_OR_MD_IN_EXPORTPDF_NAME: "在将 Excalidraw 文件导出为 PDF 时将文件渲染为图像",
|
||||
SHOW_DRAWING_OR_MD_IN_EXPORTPDF_NAME : "在 Obsidian 中导出为 PDF 格式时将 Excalidraw 渲染为图像" ,
|
||||
SHOW_DRAWING_OR_MD_IN_EXPORTPDF_DESC:
|
||||
"处于 Markdown 视图模式时,此设置控制 Excalidraw 在使用 Obsidian 的 <b>导出为 PDF</b> 功能时,将 Excalidraw 文件导出为 PDF 的行为。<br>" +
|
||||
"<ul><li>当 <b>启用</b> 时,PDF 将仅显示 Excalidraw 绘图;</li>" +
|
||||
"<li>当 <b>禁用</b> 时,PDF 将显示文档的 Markdown 部分(背景笔记)。</li></ul>" +
|
||||
"请参阅上面‘外观和行为’部分的 <<a href='#"+TAG_MDREADINGMODE+"'>>Markdown 阅读模式</a> 相关设置。" +
|
||||
"⚠️ 注意,您必须关闭当前的 Excalidraw/Markdown 文件并重新打开,以使此更改生效。⚠️",
|
||||
"此设置控制在使用 Obsidian 内置的<b>导出为 PDF</b>功能,如何将 Excalidraw 文件导出为 PDF。<br>" +
|
||||
"<ul><li><b>启用:</b>PDF 将包含图像格式的 Excalidraw 绘图。</li>" +
|
||||
"<li><b>禁用:</b>PDF 将包含作为文本的 Markdown 内容。</li></ul>" +
|
||||
"注意:此设置不会影响 Excalidraw 本身的 PDF 导出功能。<br>" +
|
||||
"请参阅上方“外观和行为”部分中与<a href='#" + TAG_MDREADINGMODE + "'>Markdown 阅读模式</a>相关的其他设置。<br>" +
|
||||
"⚠️ 您必须关闭并重新打开 Excalidraw/Markdown 文件,设置更改才会生效。⚠️",
|
||||
HOTKEY_OVERRIDE_HEAD: "热键覆盖",
|
||||
HOTKEY_OVERRIDE_DESC: `一些 Excalidraw 的热键,例如 ${labelCTRL()}+Enter 用于编辑文本,或 ${labelCTRL()}+K 用于创建元素链接。` +
|
||||
"与 Obsidian 的热键设置发生冲突。您在下面添加的热键组合将在使用 Excalidraw 时覆盖 Obsidian 的热键设置," +
|
||||
@@ -661,6 +662,7 @@ FILENAME_HEAD: "文件名",
|
||||
EXPORT_EMBED_SCENE_DESC:
|
||||
"在导出的图像中嵌入 Excalidraw 场景。可以通过在文件级别添加 <code>excalidraw-export-embed-scene: true/false</code> frontmatter 元数据键来覆盖此设置。" +
|
||||
"此设置仅在您下次(重新)打开绘图时生效。",
|
||||
PDF_EXPORT_SETTINGS : "PDF 导出设置",
|
||||
EXPORT_HEAD: "导出设置",
|
||||
EXPORT_SYNC_NAME:
|
||||
"保持 SVG/PNG 文件名与绘图文件同步",
|
||||
@@ -1006,4 +1008,86 @@ FILENAME_HEAD: "文件名",
|
||||
LINK_CLICK_POPOUT : "在弹出窗口中打开" ,
|
||||
LINK_CLICK_NEW_TAB : "在新标签页中打开" ,
|
||||
LINK_CLICK_MD_PROPS : "显示 Markdown 图片属性对话框(仅在嵌入 Markdown 文档为图片时适用)" ,
|
||||
|
||||
// 导出对话框
|
||||
// 对话框和标签页
|
||||
EXPORTDIALOG_TITLE : "导出图形",
|
||||
EXPORTDIALOG_TAB_IMAGE : "图像",
|
||||
EXPORTDIALOG_TAB_PDF : "PDF",
|
||||
// 设置持久化
|
||||
EXPORTDIALOG_SAVE_SETTINGS : "将图像设置保存到文件 doc.properties 吗?",
|
||||
EXPORTDIALOG_SAVE_SETTINGS_SAVE : "保存为预设",
|
||||
EXPORTDIALOG_SAVE_SETTINGS_ONETIME : "仅本次使用",
|
||||
// 图像设置
|
||||
EXPORTDIALOG_IMAGE_SETTINGS : "图像",
|
||||
EXPORTDIALOG_IMAGE_DESC : "PNG 支持透明。外部文件可以包含 Excalidraw 场景数据。",
|
||||
EXPORTDIALOG_PADDING : "边距",
|
||||
EXPORTDIALOG_SCALE : "缩放",
|
||||
EXPORTDIALOG_CURRENT_PADDING : "当前边距:",
|
||||
EXPORTDIALOG_SIZE_DESC : "缩放会影响输出大小",
|
||||
EXPORTDIALOG_SCALE_VALUE : "缩放:",
|
||||
EXPORTDIALOG_IMAGE_SIZE : "大小:",
|
||||
// 主题和背景
|
||||
EXPORTDIALOG_EXPORT_THEME : "主题",
|
||||
EXPORTDIALOG_THEME_LIGHT : "浅色",
|
||||
EXPORTDIALOG_THEME_DARK : "深色",
|
||||
EXPORTDIALOG_BACKGROUND : "背景",
|
||||
EXPORTDIALOG_BACKGROUND_TRANSPARENT : "透明",
|
||||
EXPORTDIALOG_BACKGROUND_USE_COLOR : "使用场景颜色",
|
||||
// 选择
|
||||
EXPORTDIALOG_SELECTED_ELEMENTS : "导出",
|
||||
EXPORTDIALOG_SELECTED_ALL : "整个场景",
|
||||
EXPORTDIALOG_SELECTED_SELECTED : "仅选中部分",
|
||||
// 导出选项
|
||||
EXPORTDIALOG_EMBED_SCENE : "包含场景数据吗?",
|
||||
EXPORTDIALOG_EMBED_YES : "是",
|
||||
EXPORTDIALOG_EMBED_NO : "否",
|
||||
// PDF 设置
|
||||
EXPORTDIALOG_PDF_SETTINGS : "PDF",
|
||||
EXPORTDIALOG_PAGE_SIZE : "页面大小",
|
||||
EXPORTDIALOG_PAGE_ORIENTATION : "方向",
|
||||
EXPORTDIALOG_ORIENTATION_PORTRAIT : "纵向",
|
||||
EXPORTDIALOG_ORIENTATION_LANDSCAPE : "横向",
|
||||
EXPORTDIALOG_PDF_DPI : "图像质量 [DPI]",
|
||||
EXPORTDIALOG_PDF_FIT_TO_PAGE : "页面适配",
|
||||
EXPORTDIALOG_PDF_FIT_OPTION : "适配页面",
|
||||
EXPORTDIALOG_PDF_FIT_2_OPTION : "适配至 2 页" ,
|
||||
EXPORTDIALOG_PDF_FIT_4_OPTION : "适配至 4 页" ,
|
||||
EXPORTDIALOG_PDF_FIT_6_OPTION : "适配至 6 页" ,
|
||||
EXPORTDIALOG_PDF_FIT_8_OPTION : "适配至 8 页" ,
|
||||
EXPORTDIALOG_PDF_FIT_12_OPTION : "适配至 12 页" ,
|
||||
EXPORTDIALOG_PDF_FIT_16_OPTION : "适配至 16 页" ,
|
||||
EXPORTDIALOG_PDF_SCALE_OPTION : "使用图像缩放(可能跨多页)",
|
||||
EXPORTDIALOG_PDF_PAPER_COLOR : "纸张颜色",
|
||||
EXPORTDIALOG_PDF_PAPER_WHITE : "白色",
|
||||
EXPORTDIALOG_PDF_PAPER_SCENE : "使用场景颜色",
|
||||
EXPORTDIALOG_PDF_PAPER_CUSTOM : "自定义颜色",
|
||||
EXPORTDIALOG_PDF_ALIGNMENT : "页面位置",
|
||||
EXPORTDIALOG_PDF_ALIGN_CENTER : "居中",
|
||||
EXPORTDIALOG_PDF_ALIGN_TOP_LEFT : "左上角",
|
||||
EXPORTDIALOG_PDF_ALIGN_TOP_CENTER : "顶部居中",
|
||||
EXPORTDIALOG_PDF_ALIGN_TOP_RIGHT : "右上角",
|
||||
EXPORTDIALOG_PDF_ALIGN_BOTTOM_LEFT : "左下角",
|
||||
EXPORTDIALOG_PDF_ALIGN_BOTTOM_CENTER : "底部居中",
|
||||
EXPORTDIALOG_PDF_ALIGN_BOTTOM_RIGHT : "右下角",
|
||||
EXPORTDIALOG_PDF_MARGIN : "边距",
|
||||
EXPORTDIALOG_PDF_MARGIN_NONE : "无",
|
||||
EXPORTDIALOG_PDF_MARGIN_TINY : "小",
|
||||
EXPORTDIALOG_PDF_MARGIN_NORMAL : "正常",
|
||||
EXPORTDIALOG_SAVE_PDF_SETTINGS : "保存 PDF 设置",
|
||||
EXPORTDIALOG_SAVE_CONFIRMATION : "PDF 配置已保存为插件默认设置",
|
||||
// 按钮
|
||||
EXPORTDIALOG_PNGTOFILE : "导出 PNG 文件",
|
||||
EXPORTDIALOG_SVGTOFILE : "导出 SVG 文件",
|
||||
EXPORTDIALOG_PNGTOVAULT : "PNG 保存到 Vault",
|
||||
EXPORTDIALOG_SVGTOVAULT : "SVG 保存到 Vault",
|
||||
EXPORTDIALOG_EXCALIDRAW : "Excalidraw",
|
||||
EXPORTDIALOG_PNGTOCLIPBOARD : "PNG 复制到剪贴板",
|
||||
EXPORTDIALOG_SVGTOCLIPBOARD : "SVG 复制到剪贴板",
|
||||
EXPORTDIALOG_PDF : "导出 PDF 文件",
|
||||
EXPORTDIALOG_PDFTOVAULT : "PDF 保存到 Vault",
|
||||
|
||||
EXPORTDIALOG_PDF_PROGRESS_NOTICE : "正在导出页面" ,
|
||||
EXPORTDIALOG_PDF_PROGRESS_IMAGE : "的图像" ,
|
||||
EXPORTDIALOG_PDF_PROGRESS_DONE : "导出完成" ,
|
||||
};
|
||||
@@ -6,7 +6,7 @@ import { ExcalidrawAutomate } from "src/shared/ExcalidrawAutomate";
|
||||
import ExcalidrawView from "src/view/ExcalidrawView";
|
||||
import ExcalidrawPlugin from "src/core/main";
|
||||
import { fragWithHTML, getExportPadding, getExportTheme, getPNGScale, getWithBackground, shouldEmbedScene } from "src/utils/utils";
|
||||
import { PageOrientation, PageSize, PDFMargin, PDFPageAlignment, PDFPageMarginString, STANDARD_PAGE_SIZES, exportSVGToClipboard } from "src/utils/exportUtils";
|
||||
import { PageOrientation, PageSize, PDFPageAlignment, PDFPageMarginString, exportSVGToClipboard } from "src/utils/exportUtils";
|
||||
import { t } from "src/lang/helpers";
|
||||
import { PDFExportSettings, PDFExportSettingsComponent } from "./PDFExportSettingsComponent";
|
||||
|
||||
@@ -38,7 +38,7 @@ export class ExportDialog extends Modal {
|
||||
private contentContainer: HTMLDivElement;
|
||||
private buttonContainerRow1: HTMLDivElement;
|
||||
private buttonContainerRow2: HTMLDivElement;
|
||||
public fitToPage: boolean = true;
|
||||
public fitToPage: number = 1;
|
||||
public paperColor: "white" | "scene" | "custom" = "white";
|
||||
public customPaperColor: string = "#ffffff";
|
||||
public alignment: PDFPageAlignment = "center";
|
||||
@@ -276,7 +276,7 @@ export class ExportDialog extends Modal {
|
||||
paperColor: this.paperColor,
|
||||
customPaperColor: this.customPaperColor,
|
||||
alignment: this.alignment,
|
||||
margin: this.margin
|
||||
margin: this.margin,
|
||||
};
|
||||
|
||||
new PDFExportSettingsComponent(
|
||||
@@ -378,26 +378,12 @@ export class ExportDialog extends Modal {
|
||||
paperColor: this.paperColor,
|
||||
customPaperColor: this.customPaperColor,
|
||||
alignment: this.alignment,
|
||||
margin: this.margin
|
||||
margin: this.margin,
|
||||
};
|
||||
await this.plugin.saveSettings();
|
||||
new Notice(t("EXPORTDIALOG_SAVE_CONFIRMATION"));
|
||||
};
|
||||
|
||||
const bPDFVault = this.buttonContainerRow1.createEl("button", {
|
||||
text: t("EXPORTDIALOG_PDFTOVAULT"),
|
||||
cls: "excalidraw-export-button"
|
||||
});
|
||||
bPDFVault.onclick = () => {
|
||||
this.view.exportPDF(
|
||||
true,
|
||||
this.hasSelectedElements && this.exportSelectedOnly,
|
||||
this.pageSize,
|
||||
this.pageOrientation
|
||||
);
|
||||
this.close();
|
||||
};
|
||||
|
||||
if (!DEVICE.isDesktop) return;
|
||||
const bPDFExport = this.buttonContainerRow1.createEl("button", {
|
||||
text: t("EXPORTDIALOG_PDF"),
|
||||
|
||||
@@ -5,7 +5,7 @@ import { t } from "src/lang/helpers";
|
||||
export interface PDFExportSettings {
|
||||
pageSize: PageSize;
|
||||
pageOrientation: PageOrientation;
|
||||
fitToPage: boolean;
|
||||
fitToPage: number;
|
||||
paperColor: "white" | "scene" | "custom";
|
||||
customPaperColor: string;
|
||||
alignment: PDFPageAlignment;
|
||||
@@ -54,18 +54,26 @@ export class PDFExportSettingsComponent {
|
||||
this.update();
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
new Setting(this.contentEl)
|
||||
.setName(t("EXPORTDIALOG_PDF_FIT_TO_PAGE"))
|
||||
.addDropdown(dropdown =>
|
||||
dropdown
|
||||
.addOptions({
|
||||
"scale": t("EXPORTDIALOG_PDF_SCALE_OPTION"),
|
||||
"fit": t("EXPORTDIALOG_PDF_FIT_OPTION"),
|
||||
"scale": t("EXPORTDIALOG_PDF_SCALE_OPTION")
|
||||
"fit-2": t("EXPORTDIALOG_PDF_FIT_2_OPTION"),
|
||||
"fit-4": t("EXPORTDIALOG_PDF_FIT_4_OPTION"),
|
||||
"fit-6": t("EXPORTDIALOG_PDF_FIT_6_OPTION"),
|
||||
"fit-8": t("EXPORTDIALOG_PDF_FIT_8_OPTION"),
|
||||
"fit-12": t("EXPORTDIALOG_PDF_FIT_12_OPTION"),
|
||||
"fit-16": t("EXPORTDIALOG_PDF_FIT_16_OPTION")
|
||||
})
|
||||
.setValue(this.settings.fitToPage ? "fit" : "scale")
|
||||
.setValue(this.settings.fitToPage === 1 ? "fit" :
|
||||
(typeof this.settings.fitToPage === "number" ? `fit-${this.settings.fitToPage}` : "scale"))
|
||||
.onChange(value => {
|
||||
this.settings.fitToPage = value === "fit";
|
||||
this.settings.fitToPage = value === "scale" ? 0 :
|
||||
(value === "fit" ? 1 : parseInt(value.split("-")[1]));
|
||||
this.update();
|
||||
})
|
||||
);
|
||||
|
||||
@@ -226,7 +226,7 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [
|
||||
},
|
||||
{
|
||||
field: "createPDF",
|
||||
code: "async createPDF({SVG: SVGSVGElement[], scale?: PDFExportScale, pageProps?: PDFPageProperties}): Promise<ArrayBuffer>",
|
||||
code: "async createPDF({SVG: SVGSVGElement[], scale?: PDFExportScale, pageProps?: PDFPageProperties}): Promise<void>",
|
||||
desc: "",
|
||||
after: "Creates a PDF from the provided SVG elements with specified scaling and page properties.\n" +
|
||||
"\n" +
|
||||
@@ -241,9 +241,9 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [
|
||||
"@property {number} [zoom=1] - The zoom level for the SVG. Used only if fitToPage is false. If the SVG does not fit the page, it will be tiled over multiple pages.\n" +
|
||||
"\n" +
|
||||
"@typedef {Object} PDFPageProperties\n" +
|
||||
"@property {{width: number, height: number}} [dimensions] - The dimensions of the PDF pages. Use getPageDimensions to get standard page sizes.\n" +
|
||||
"@property {{width: number, height: number}} [dimensions] - The dimensions of the PDF pages in pixels. Use getPageDimensions to get standard page sizes.\n" +
|
||||
"@property {string} [backgroundColor] - The background color of the PDF pages.\n" +
|
||||
"@property {PDFMargin} margin - The margins of the PDF pages.\n" +
|
||||
"@property {PDFMargin} margin - The margins of the PDF pages in pixels.\n" +
|
||||
"@property {PDFPageAlignment} alignment - The alignment of the SVG on the PDF pages.\n" +
|
||||
"\n" +
|
||||
"@example\n" +
|
||||
@@ -261,15 +261,15 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [
|
||||
{
|
||||
field: "getPagePDFDimensions",
|
||||
code: "getPagePDFDimensions(pageSize: PageSize, orientation: PageOrientation): PageDimensions",
|
||||
desc: "Returns the dimensions of a standard page size in points (pt).\n" +
|
||||
desc: "Returns the dimensions of a standard page size in pixels.\n" +
|
||||
"\n" +
|
||||
"@param {PageSize} pageSize - The standard page size. Possible values are \"A0\", \"A1\", \"A2\", \"A3\", \"A4\", \"A5\", \"Letter\", \"Legal\", \"Tabloid\".\n" +
|
||||
"@param {PageOrientation} orientation - The orientation of the page. Possible values are \"portrait\" and \"landscape\".\n" +
|
||||
"@returns {PageDimensions} - An object containing the width and height of the page in points (pt).\n" +
|
||||
"@returns {PageDimensions} - An object containing the width and height of the page in pixels.\n" +
|
||||
"\n" +
|
||||
"@typedef {Object} PageDimensions\n" +
|
||||
"@property {number} width - The width of the page in points (pt).\n" +
|
||||
"@property {number} height - The height of the page in points (pt).\n" +
|
||||
"@property {number} width - The width of the page in pixels.\n" +
|
||||
"@property {number} height - The height of the page in pixels.\n" +
|
||||
"\n" +
|
||||
"@typedef {\"A0\" | \"A1\" | \"A2\" | \"A3\" | \"A4\" | \"A5\" | \"Letter\" | \"Legal\" | \"Tabloid\"} PageSize\n" +
|
||||
"\n" +
|
||||
@@ -556,6 +556,21 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [
|
||||
desc: "If set Excalidraw will call this function onDrop events.\nA return of true will stop the default onDrop processing in Excalidraw.\n\ndraggable is the Obsidian draggable object\nfiles is the array of dropped files\nexcalidrawFile is the file receiving the drop event\nview is the excalidraw view receiving the drop.\npointerPosition is the pointer position on canvas at the time of drop.",
|
||||
after: "",
|
||||
},
|
||||
{
|
||||
field: "onImageFilePathHook",
|
||||
code: `onImageFilePathHook: (data: {currentImageName: string; drawingFilePath: string;}): string;`,
|
||||
desc: "If set, this callback is triggered when an image is being saved in Excalidraw.\n"
|
||||
+ "You can use this callback to customize the naming and path of pasted images to avoid\n"
|
||||
+ 'default names like "Pasted image 123147170.png" being saved in the attachments folder,\n'
|
||||
+ "and instead use more meaningful names based on the Excalidraw file or other criteria,\n"
|
||||
+ "plus save the image in a different folder.\n\n"
|
||||
+ "If the function returns null or undefined, the normal Excalidraw operation will continue\n"
|
||||
+ "with the excalidraw generated name and default path.\n"
|
||||
+ "If a filepath is returned, that will be used. Include the full Vault filepath and filename\n"
|
||||
+ "with the file extension.\n"
|
||||
+ "The currentImageName is the name of the image generated by excalidraw or provided during paste.",
|
||||
after: "",
|
||||
},
|
||||
{
|
||||
field: "mostRecentMarkdownSVG",
|
||||
code: "mostRecentMarkdownSVG: SVGSVGElement;",
|
||||
|
||||
@@ -932,19 +932,19 @@ export class ExcalidrawAutomate {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the dimensions of a standard page size in points (pt).
|
||||
* Returns the dimensions of a standard page size in pixels.
|
||||
*
|
||||
* @param {PageSize} pageSize - The standard page size. Possible values are "A0", "A1", "A2", "A3", "A4", "A5", "Letter", "Legal", "Tabloid".
|
||||
* @param {PageOrientation} orientation - The orientation of the page. Possible values are "portrait" and "landscape".
|
||||
* @returns {PageDimensions} - An object containing the width and height of the page in points (pt).
|
||||
* @returns {PageDimensions} - An object containing the width and height of the page in pixels.
|
||||
*
|
||||
* @typedef {Object} PageDimensions
|
||||
* @property {number} width - The width of the page in points (pt).
|
||||
* @property {number} height - The height of the page in points (pt).
|
||||
* @property {number} width - The width of the page in pixels.
|
||||
* @property {number} height - The height of the page in pixels.
|
||||
*
|
||||
* @example
|
||||
* const dimensions = getPageDimensions("A4", "portrait");
|
||||
* console.log(dimensions); // { width: 595.28, height: 841.89 }
|
||||
* console.log(dimensions); // { width: 794.56, height: 1122.56 }
|
||||
*/
|
||||
getPagePDFDimensions(pageSize: PageSize, orientation: PageOrientation): PageDimensions {
|
||||
return getPageDimensions(pageSize, orientation);
|
||||
@@ -955,31 +955,33 @@ export class ExcalidrawAutomate {
|
||||
*
|
||||
* @param {Object} params - The parameters for creating the PDF.
|
||||
* @param {SVGSVGElement[]} params.SVG - An array of SVG elements to be included in the PDF.
|
||||
* @param {PDFExportScale} [params.scale={ fitToPage: true, zoom: 1 }] - The scaling options for the SVG elements.
|
||||
* @param {PDFExportScale} [params.scale={ fitToPage: 1, zoom: 1 }] - The scaling options for the SVG elements.
|
||||
* @param {PDFPageProperties} [params.pageProps] - The properties for the PDF pages.
|
||||
* @returns {Promise<ArrayBuffer>} - A promise that resolves to an ArrayBuffer containing the PDF data.
|
||||
*
|
||||
* @example
|
||||
* const pdfData = await createToPDF({
|
||||
* SVG: [svgElement1, svgElement2],
|
||||
* scale: { fitToPage: true },
|
||||
* scale: { fitToPage: 1 },
|
||||
* pageProps: {
|
||||
* dimensions: { width: 595.28, height: 841.89 },
|
||||
* dimensions: { width: 794.56, height: 1122.56 },
|
||||
* backgroundColor: "#ffffff",
|
||||
* margin: { left: 20, right: 20, top: 20, bottom: 20 },
|
||||
* alignment: "center"
|
||||
* alignment: "center",
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
async createPDF({
|
||||
SVG,
|
||||
scale = { fitToPage: true, zoom: 1 },
|
||||
scale = { fitToPage: 1, zoom: 1 },
|
||||
pageProps,
|
||||
filename,
|
||||
}: {
|
||||
SVG: SVGSVGElement[];
|
||||
scale?: PDFExportScale;
|
||||
pageProps?: PDFPageProperties;
|
||||
}): Promise<ArrayBuffer> {
|
||||
filename: string;
|
||||
}): Promise<void> {
|
||||
if(!pageProps) {
|
||||
pageProps = {
|
||||
alignment: this.plugin.settings.pdfSettings.alignment,
|
||||
@@ -997,7 +999,7 @@ export class ExcalidrawAutomate {
|
||||
pageProps.backgroundColor = "#ffffff";
|
||||
}
|
||||
|
||||
return await exportToPDF({SVG, scale, pageProps});
|
||||
await exportToPDF({SVG, scale, pageProps, filename});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2740,6 +2742,40 @@ export class ExcalidrawAutomate {
|
||||
pointerPosition: { x: number; y: number }; //the pointer position on canvas
|
||||
}) => boolean = null;
|
||||
|
||||
/**
|
||||
* If set, this callback is triggered when a image is being saved in Excalidraw.
|
||||
* You can use this callback to customize the naming and path of pasted images to avoid
|
||||
* default names like "Pasted image 123147170.png" being saved in the attachments folder,
|
||||
* and instead use more meaningful names based on the Excalidraw file or other criteria,
|
||||
* plus save the image in a different folder.
|
||||
*
|
||||
* If the function returns null or undefined, the normal Excalidraw operation will continue
|
||||
* with the excalidraw generated name and default path.
|
||||
* If a filepath is returned, that will be used. Include the full Vault filepath and filename
|
||||
* with the file extension.
|
||||
* The currentImageName is the name of the image generated by excalidraw or provided during paste.
|
||||
*
|
||||
* @param data - An object containing the following properties:
|
||||
* @property {string} [currentImageName] - Default name for the image.
|
||||
* @property {string} drawingFilePath - The file path of the Excalidraw file where the image is being used.
|
||||
*
|
||||
* @returns {string} - The new filepath for the image including full vault path and extension.
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* onImageFilePathHook: (data) => {
|
||||
* const { currentImageName, drawingFilePath } = data;
|
||||
* // Generate a new filepath based on the drawing file name and other criteria
|
||||
* const ext = currentImageName.split('.').pop();
|
||||
* return `${drawingFileName} - ${currentImageName || 'image'}.${ext}`;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
onImageFilePathHook: (data: {
|
||||
currentImageName: string; // Excalidraw generated name of the image, or the name received from the file system.
|
||||
drawingFilePath: string; // The full filepath of the Excalidraw file where the image is being used.
|
||||
}) => string = null;
|
||||
|
||||
/**
|
||||
* if set, this callback is triggered, when an Excalidraw file is opened
|
||||
* You can use this callback in case you want to do something additional when the file is opened.
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
loadSceneFonts,
|
||||
} from "../constants/constants";
|
||||
import ExcalidrawPlugin from "../core/main";
|
||||
import { TextMode } from "../view/ExcalidrawView";
|
||||
import ExcalidrawView, { TextMode } from "../view/ExcalidrawView";
|
||||
import {
|
||||
addAppendUpdateCustomData,
|
||||
compress,
|
||||
@@ -52,10 +52,11 @@ import { getMermaidImageElements, getMermaidText, shouldRenderMermaid } from "..
|
||||
import { DEBUGGING, debug } from "../utils/debugHelper";
|
||||
import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types";
|
||||
import { updateElementIdsInScene } from "../utils/excalidrawSceneUtils";
|
||||
import { getNewUniqueFilepath } from "../utils/fileUtils";
|
||||
import { checkAndCreateFolder, getNewUniqueFilepath, splitFolderAndFilename } from "../utils/fileUtils";
|
||||
import { t } from "../lang/helpers";
|
||||
import { displayFontMessage } from "../utils/excalidrawViewUtils";
|
||||
import { getPDFRect } from "../utils/PDFUtils";
|
||||
import { create } from "domain";
|
||||
|
||||
type SceneDataWithFiles = SceneData & { files: BinaryFiles };
|
||||
|
||||
@@ -480,7 +481,7 @@ export class ExcalidrawData {
|
||||
selectedElementIds: {[key:string]:boolean} = {}; //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/609
|
||||
|
||||
constructor(
|
||||
private plugin: ExcalidrawPlugin,
|
||||
private plugin: ExcalidrawPlugin, private view?: ExcalidrawView,
|
||||
) {
|
||||
this.app = this.plugin.app;
|
||||
this.files = new Map<FileId, EmbeddedFile>();
|
||||
@@ -1546,13 +1547,24 @@ export class ExcalidrawData {
|
||||
}
|
||||
}
|
||||
|
||||
const x = await getAttachmentsFolderAndFilePath(this.app, this.file.path, fname);
|
||||
const filepath = getNewUniqueFilepath(this.app.vault,fname,x.folder);
|
||||
let hookFilepath:string;
|
||||
const ea = this.view?.getHookServer();
|
||||
if(ea?.onImageFilePathHook) {
|
||||
hookFilepath = ea.onImageFilePathHook({
|
||||
currentImageName: fname,
|
||||
drawingFilePath: this.view?.file?.path,
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
const filepath = (
|
||||
await getAttachmentsFolderAndFilePath(this.app, this.file.path, fname)
|
||||
).filepath;*/
|
||||
let filepath:string;
|
||||
if(hookFilepath) {
|
||||
const {folderpath, filename} = splitFolderAndFilename(hookFilepath);
|
||||
await checkAndCreateFolder(folderpath);
|
||||
filepath = getNewUniqueFilepath(this.app.vault,filename,folderpath);
|
||||
} else {
|
||||
const x = await getAttachmentsFolderAndFilePath(this.app, this.file.path, fname);
|
||||
filepath = getNewUniqueFilepath(this.app.vault,fname,x.folder);
|
||||
}
|
||||
|
||||
const arrayBuffer = await getBinaryFileFromDataURL(dataURL);
|
||||
if(!arrayBuffer) return null;
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { PDFDocument, rgb } from '@cantoo/pdf-lib';
|
||||
import { getEA } from 'src/core';
|
||||
import { Notice } from 'obsidian';
|
||||
import { DEVICE } from 'src/constants/constants';
|
||||
import { t } from 'src/lang/helpers';
|
||||
|
||||
const DPI = 96;
|
||||
|
||||
export type PDFPageAlignment = "center" | "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
||||
export type PDFPageMarginString = "none" | "tiny" | "normal";
|
||||
|
||||
export interface PDFExportScale {
|
||||
fitToPage: boolean;
|
||||
fitToPage: number; // 0 means use zoom, >1 means fit to that many pages exactly
|
||||
zoom?: number;
|
||||
}
|
||||
|
||||
@@ -31,21 +33,24 @@ export interface PageDimensions {
|
||||
|
||||
export type PageOrientation = "portrait" | "landscape";
|
||||
|
||||
// All dimensions in points (pt)
|
||||
// All dimensions in pixels (pt)
|
||||
export const STANDARD_PAGE_SIZES = {
|
||||
"A0": { width: 2383.94, height: 3370.39 },
|
||||
"A1": { width: 1683.78, height: 2383.94 },
|
||||
"A2": { width: 1190.55, height: 1683.78 },
|
||||
"A3": { width: 841.89, height: 1190.55 },
|
||||
"A4": { width: 595.28, height: 841.89 },
|
||||
"A5": { width: 419.53, height: 595.28 },
|
||||
"Letter": { width: 612, height: 792 },
|
||||
"Legal": { width: 612, height: 1008 },
|
||||
"Tabloid": { width: 792, height: 1224 },
|
||||
A0: { width: 3179.52, height: 4494.96 }, // 33.11 × 46.81 inches
|
||||
A1: { width: 2245.76, height: 3179.52 }, // 23.39 × 33.11 inches
|
||||
A2: { width: 1587.76, height: 2245.76 }, // 16.54 × 23.39 inches
|
||||
A3: { width: 1122.56, height: 1587.76 }, // 11.69 × 16.54 inches
|
||||
A4: { width: 794.56, height: 1122.56 }, // 8.27 × 11.69 inches
|
||||
A5: { width: 559.37, height: 794.56 }, // 5.83 × 8.27 inches
|
||||
A6: { width: 397.28, height: 559.37 }, // 4.13 × 5.83 inches
|
||||
Legal: { width: 816, height: 1344 }, // 8.5 × 14 inches
|
||||
Letter: { width: 816, height: 1056 }, // 8.5 × 11 inches
|
||||
Tabloid: { width: 1056, height: 1632 }, // 11 × 17 inches
|
||||
Ledger: { width: 1632, height: 1056 } // 17 × 11 inches
|
||||
} as const;
|
||||
|
||||
export type PageSize = keyof typeof STANDARD_PAGE_SIZES;
|
||||
|
||||
//margins are in pixels
|
||||
export function getMarginValue(margin:PDFPageMarginString): PDFMargin {
|
||||
switch(margin) {
|
||||
case "none": return { left: 0, right: 0, top: 0, bottom: 0 };
|
||||
@@ -62,15 +67,246 @@ export function getPageDimensions(pageSize: PageSize, orientation: PageOrientati
|
||||
: { width: dimensions.height, height: dimensions.width };
|
||||
}
|
||||
|
||||
interface SVGDimensions {
|
||||
width: number;
|
||||
height: number;
|
||||
x: number;
|
||||
y: number;
|
||||
sourceX?: number;
|
||||
sourceY?: number;
|
||||
sourceWidth?: number;
|
||||
sourceHeight?: number;
|
||||
// Electron IPC interfaces
|
||||
interface PrintToPDFOptions {
|
||||
includeName: boolean;
|
||||
pageSize: string | { width: number; height: number };
|
||||
landscape: boolean;
|
||||
margins: { top: number; left: number; right: number; bottom: number };
|
||||
scaleFactor: number;
|
||||
scale: number;
|
||||
open: boolean;
|
||||
filepath: string;
|
||||
}
|
||||
|
||||
interface SaveDialogOptions {
|
||||
defaultPath: string;
|
||||
filters: { name: string; extensions: string[] }[];
|
||||
properties: string[];
|
||||
}
|
||||
|
||||
interface SaveDialogReturnValue {
|
||||
canceled: boolean;
|
||||
filePath?: string;
|
||||
}
|
||||
|
||||
interface ElectronAPI {
|
||||
ipcRenderer: {
|
||||
send(channel: string, ...args: any[]): void;
|
||||
once(channel: string, func: (...args: any[]) => void): void;
|
||||
};
|
||||
remote: {
|
||||
dialog: {
|
||||
showSaveDialog(options: SaveDialogOptions): Promise<SaveDialogReturnValue>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
electron: ElectronAPI;
|
||||
}
|
||||
}
|
||||
|
||||
function getPageSizePixels(pageSize: PageSize | PageDimensions, landscape = false): PageDimensions {
|
||||
if (typeof pageSize === "object") return pageSize;
|
||||
|
||||
const pageDimensions = STANDARD_PAGE_SIZES[pageSize];
|
||||
if (!pageDimensions) {
|
||||
throw new Error(`Unsupported page size: ${pageSize}`);
|
||||
}
|
||||
|
||||
return landscape
|
||||
? { width: pageDimensions.height, height: pageDimensions.width }
|
||||
: { width: pageDimensions.width, height: pageDimensions.height };
|
||||
}
|
||||
|
||||
function getPageSize(pageSize: PageSize | PageDimensions): string | { width: number; height: number } {
|
||||
if (typeof pageSize === "string") return pageSize;
|
||||
|
||||
if (!pageSize || typeof pageSize !== "object" ||
|
||||
typeof pageSize.width !== "number" || typeof pageSize.height !== "number") {
|
||||
throw new Error("Invalid page dimensions");
|
||||
}
|
||||
|
||||
return {
|
||||
width: (pageSize.width / DPI),
|
||||
height: (pageSize.height / DPI)
|
||||
};
|
||||
}
|
||||
|
||||
async function getSavePath(defaultPath: string): Promise<string | undefined> {
|
||||
const result = await window.electron.remote.dialog.showSaveDialog({
|
||||
defaultPath,
|
||||
filters: [
|
||||
{ name: "PDF Files", extensions: ["pdf"] },
|
||||
{ name: "All Files", extensions: ["*"] }
|
||||
],
|
||||
properties: ["showOverwriteConfirmation"]
|
||||
});
|
||||
return result.filePath;
|
||||
}
|
||||
|
||||
async function printPdf(
|
||||
elementToPrint: HTMLElement,
|
||||
pdfPath: string,
|
||||
bgColor: string,
|
||||
pageSize: PageSize | PageDimensions,
|
||||
isLandscape: boolean,
|
||||
margins: { top: number; left: number; right: number; bottom: number }
|
||||
): Promise<void> {
|
||||
const styleTag = document.createElement('style');
|
||||
styleTag.textContent = `
|
||||
@media print {
|
||||
.print {
|
||||
background-color: ${bgColor} !important;
|
||||
display: flex !important;
|
||||
justify-content: center !important;
|
||||
align-items: center !important;
|
||||
-webkit-print-color-adjust: exact !important;
|
||||
print-color-adjust: exact !important;
|
||||
flex-direction: column !important;
|
||||
page-break-before: always;
|
||||
margin: 0px !important;
|
||||
padding: 0px !important;
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(styleTag);
|
||||
|
||||
const printDiv = document.body.createDiv('print');
|
||||
printDiv.style.top = "0";
|
||||
printDiv.style.left = "0";
|
||||
printDiv.style.display = "flex";
|
||||
printDiv.appendChild(elementToPrint);
|
||||
|
||||
const options: PrintToPDFOptions = {
|
||||
includeName: false,
|
||||
pageSize: getPageSize(pageSize),
|
||||
landscape: isLandscape,
|
||||
margins,
|
||||
scaleFactor: 100,
|
||||
scale: 1,
|
||||
open: true,
|
||||
filepath: pdfPath,
|
||||
};
|
||||
|
||||
try {
|
||||
await new Promise<void>((resolve) => {
|
||||
window.electron.ipcRenderer.once('print-to-pdf', resolve);
|
||||
window.electron.ipcRenderer.send('print-to-pdf', options);
|
||||
});
|
||||
} finally {
|
||||
printDiv.remove();
|
||||
styleTag.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function calculateDimensions(
|
||||
svgWidth: number,
|
||||
svgHeight: number,
|
||||
pageDim: PageDimensions,
|
||||
margin: PDFMargin,
|
||||
scale: PDFExportScale,
|
||||
alignment: PDFPageAlignment
|
||||
): {
|
||||
tiles: {
|
||||
viewBox: string,
|
||||
width: number,
|
||||
height: number,
|
||||
x: number,
|
||||
y: number
|
||||
}[],
|
||||
pages: number
|
||||
} {
|
||||
const availableWidth = pageDim.width - margin.left - margin.right;
|
||||
const availableHeight = pageDim.height - margin.top - margin.bottom;
|
||||
|
||||
// If fitToPage is specified, find optimal zoom using binary search
|
||||
if (scale.fitToPage > 0) {
|
||||
let low = 0;
|
||||
let high = 100;
|
||||
let bestZoom = 1;
|
||||
const tolerance = 0.000001;
|
||||
|
||||
while (high - low > tolerance) {
|
||||
const mid = (low + high) / 2;
|
||||
const scaledWidth = svgWidth * mid;
|
||||
const scaledHeight = svgHeight * mid;
|
||||
const pages = Math.ceil(scaledWidth / availableWidth) *
|
||||
Math.ceil(scaledHeight / availableHeight);
|
||||
|
||||
if (pages > scale.fitToPage) {
|
||||
high = mid;
|
||||
} else {
|
||||
bestZoom = mid;
|
||||
low = mid;
|
||||
}
|
||||
}
|
||||
scale.zoom = Math.round(bestZoom * 0.99999 * 1000000) / 1000000;
|
||||
}
|
||||
|
||||
const finalWidth = svgWidth * (scale.zoom || 1);
|
||||
const finalHeight = svgHeight * (scale.zoom || 1);
|
||||
|
||||
if (finalWidth <= availableWidth && finalHeight <= availableHeight) {
|
||||
// Content fits on one page
|
||||
const position = calculatePosition(
|
||||
finalWidth,
|
||||
finalHeight,
|
||||
pageDim.width,
|
||||
pageDim.height,
|
||||
margin,
|
||||
alignment
|
||||
);
|
||||
|
||||
return {
|
||||
tiles: [{
|
||||
viewBox: `0 0 ${svgWidth} ${svgHeight}`,
|
||||
width: finalWidth,
|
||||
height: finalHeight,
|
||||
x: position.x,
|
||||
y: position.y
|
||||
}],
|
||||
pages: 1
|
||||
};
|
||||
}
|
||||
|
||||
// Content needs to be tiled
|
||||
const tiles = [];
|
||||
const cols = Math.ceil(finalWidth / availableWidth);
|
||||
const rows = Math.ceil(finalHeight / availableHeight);
|
||||
|
||||
for (let row = 0; row < rows; row++) {
|
||||
for (let col = 0; col < cols; col++) {
|
||||
const tileX = (col * availableWidth) / (scale.zoom || 1);
|
||||
const tileY = (row * availableHeight) / (scale.zoom || 1);
|
||||
const tileWidth = Math.min(svgWidth - tileX, availableWidth / (scale.zoom || 1));
|
||||
const tileHeight = Math.min(svgHeight - tileY, availableHeight / (scale.zoom || 1));
|
||||
const scaledTileWidth = tileWidth * (scale.zoom || 1);
|
||||
const scaledTileHeight = tileHeight * (scale.zoom || 1);
|
||||
|
||||
// Calculate position for each tile
|
||||
const position = calculatePosition(
|
||||
scaledTileWidth,
|
||||
scaledTileHeight,
|
||||
pageDim.width,
|
||||
pageDim.height,
|
||||
margin,
|
||||
alignment
|
||||
);
|
||||
|
||||
tiles.push({
|
||||
viewBox: `${tileX} ${tileY} ${tileWidth} ${tileHeight}`,
|
||||
width: scaledTileWidth,
|
||||
height: scaledTileHeight,
|
||||
x: position.x,
|
||||
y: position.y
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return { tiles, pages: tiles.length };
|
||||
}
|
||||
|
||||
function calculatePosition(
|
||||
@@ -80,30 +316,12 @@ function calculatePosition(
|
||||
pageHeight: number,
|
||||
margin: PDFMargin,
|
||||
alignment: PDFPageAlignment,
|
||||
scale: PDFExportScale
|
||||
): {x: number, y: number} {
|
||||
const availableWidth = pageWidth - margin.left - margin.right;
|
||||
const availableHeight = pageHeight - margin.top - margin.bottom;
|
||||
|
||||
console.log(JSON.stringify({
|
||||
message: 'PDF Position Debug',
|
||||
input: {
|
||||
svgWidth,
|
||||
svgHeight,
|
||||
pageWidth,
|
||||
pageHeight,
|
||||
margin,
|
||||
alignment,
|
||||
scale
|
||||
},
|
||||
calculated: {
|
||||
availableWidth,
|
||||
availableHeight
|
||||
}
|
||||
}));
|
||||
|
||||
let x = margin.left;
|
||||
let y = margin.bottom;
|
||||
let y = margin.top;
|
||||
|
||||
// Handle horizontal alignment
|
||||
if (alignment.includes('center')) {
|
||||
@@ -114,255 +332,92 @@ function calculatePosition(
|
||||
|
||||
// Handle vertical alignment
|
||||
if (alignment.startsWith('center')) {
|
||||
y = margin.bottom + (availableHeight - svgHeight) / 2;
|
||||
} else if (alignment.startsWith('top')) {
|
||||
y = margin.bottom;
|
||||
y = margin.top + (availableHeight - svgHeight) / 2;
|
||||
} else if (alignment.startsWith('bottom')) {
|
||||
y = pageHeight - margin.top - svgHeight;
|
||||
y = margin.top + availableHeight - svgHeight;
|
||||
}
|
||||
|
||||
console.log(JSON.stringify({
|
||||
message: 'PDF Position Intermediate',
|
||||
x,
|
||||
y,
|
||||
alignment,
|
||||
availableHeight,
|
||||
marginTop: margin.top,
|
||||
marginBottom: margin.bottom,
|
||||
svgHeight,
|
||||
pageHeight
|
||||
}));
|
||||
|
||||
console.log(JSON.stringify({
|
||||
message: 'PDF Position Result',
|
||||
x,
|
||||
y,
|
||||
finalPosition: {
|
||||
bottom: y,
|
||||
top: y + svgHeight,
|
||||
left: x,
|
||||
right: x + svgWidth
|
||||
}
|
||||
}));
|
||||
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
function calculateDimensions(
|
||||
svgWidth: number,
|
||||
svgHeight: number,
|
||||
pageDim: PageDimensions,
|
||||
margin: PDFPageProperties['margin'],
|
||||
scale: PDFExportScale,
|
||||
alignment: PDFPageAlignment
|
||||
): SVGDimensions[] {
|
||||
const availableWidth = pageDim.width - margin.left - margin.right;
|
||||
const availableHeight = pageDim.height - margin.top - margin.bottom;
|
||||
|
||||
let finalWidth: number;
|
||||
let finalHeight: number;
|
||||
|
||||
if (scale.fitToPage) {
|
||||
const ratio = Math.min(availableWidth / svgWidth, availableHeight / svgHeight);
|
||||
finalWidth = svgWidth * ratio;
|
||||
finalHeight = svgHeight * ratio;
|
||||
|
||||
const position = calculatePosition(
|
||||
finalWidth,
|
||||
finalHeight,
|
||||
pageDim.width,
|
||||
pageDim.height,
|
||||
margin,
|
||||
alignment,
|
||||
scale
|
||||
);
|
||||
|
||||
return [{
|
||||
width: finalWidth,
|
||||
height: finalHeight,
|
||||
x: position.x,
|
||||
y: position.y
|
||||
}];
|
||||
} else {
|
||||
// Scale mode - may need multiple pages
|
||||
finalWidth = svgWidth * (scale.zoom || 1);
|
||||
finalHeight = svgHeight * (scale.zoom || 1);
|
||||
|
||||
if (finalWidth <= availableWidth && finalHeight <= availableHeight) {
|
||||
// Content fits on one page
|
||||
const position = calculatePosition(
|
||||
finalWidth,
|
||||
finalHeight,
|
||||
pageDim.width,
|
||||
pageDim.height,
|
||||
margin,
|
||||
alignment,
|
||||
scale
|
||||
);
|
||||
|
||||
return [{
|
||||
width: finalWidth,
|
||||
height: finalHeight,
|
||||
x: position.x,
|
||||
y: position.y
|
||||
}];
|
||||
} else {
|
||||
// Content needs to be tiled across multiple pages
|
||||
const dimensions: SVGDimensions[] = [];
|
||||
const cols = Math.ceil(finalWidth / availableWidth);
|
||||
const rows = Math.ceil(finalHeight / availableHeight);
|
||||
|
||||
for (let row = 0; row < rows; row++) {
|
||||
for (let col = 0; col < cols; col++) {
|
||||
const tileWidth = Math.min(availableWidth, finalWidth - col * availableWidth);
|
||||
const tileHeight = Math.min(availableHeight, finalHeight - row * availableHeight);
|
||||
|
||||
// Calculate y coordinate following the same logic as single-page rendering
|
||||
// We start from the bottom margin and work our way up
|
||||
//const y = margin.bottom + row * availableHeight;
|
||||
|
||||
dimensions.push({
|
||||
width: tileWidth,
|
||||
height: tileHeight,
|
||||
x: margin.left,
|
||||
y: margin.top,
|
||||
sourceX: col * availableWidth / (scale.zoom || 1),
|
||||
sourceY: row * availableHeight / (scale.zoom || 1),
|
||||
sourceWidth: tileWidth / (scale.zoom || 1),
|
||||
sourceHeight: tileHeight / (scale.zoom || 1)
|
||||
});
|
||||
}
|
||||
}
|
||||
return dimensions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function addSVGToPage(
|
||||
pdfDoc: PDFDocument,
|
||||
svg: SVGSVGElement,
|
||||
dimensions: SVGDimensions,
|
||||
pageDim: PageDimensions,
|
||||
backgroundColor?: string
|
||||
) {
|
||||
const page = pdfDoc.addPage([pageDim.width, pageDim.height]);
|
||||
|
||||
if (backgroundColor && backgroundColor !== '#ffffff') {
|
||||
const { r, g, b } = hexToRGB(backgroundColor);
|
||||
page.drawRectangle({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: pageDim.width,
|
||||
height: pageDim.height,
|
||||
color: rgb(r/255, g/255, b/255),
|
||||
});
|
||||
}
|
||||
|
||||
// Clone and modify SVG for tiling if needed
|
||||
let svgToEmbed = svg;
|
||||
if (dimensions.sourceX !== undefined) {
|
||||
svgToEmbed = svg.cloneNode(true) as SVGSVGElement;
|
||||
const viewBox = `${dimensions.sourceX} ${dimensions.sourceY} ${dimensions.sourceWidth} ${dimensions.sourceHeight}`;
|
||||
svgToEmbed.setAttribute('viewBox', viewBox);
|
||||
svgToEmbed.setAttribute('width', String(dimensions.sourceWidth));
|
||||
svgToEmbed.setAttribute('height', String(dimensions.sourceHeight));
|
||||
}
|
||||
|
||||
const svgImage = await pdfDoc.embedSvg(svgToEmbed.outerHTML);
|
||||
|
||||
console.log(JSON.stringify({message: "addSVGToPage", dimensions, html: svgToEmbed.outerHTML}));
|
||||
|
||||
// Adjust y-coordinate to account for PDF coordinate system
|
||||
const adjustedY = pageDim.height - dimensions.y;
|
||||
|
||||
page.drawSvg(svgImage, {
|
||||
x: dimensions.x,
|
||||
y: adjustedY,
|
||||
width: dimensions.width,
|
||||
height: dimensions.height,
|
||||
});
|
||||
|
||||
console.log(JSON.stringify({
|
||||
message: 'PDF Draw SVG',
|
||||
x: dimensions.x,
|
||||
y: adjustedY,
|
||||
width: dimensions.width,
|
||||
height: dimensions.height
|
||||
}));
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
export async function exportToPDF({
|
||||
SVG,
|
||||
scale = { fitToPage: true, zoom: 1 },
|
||||
scale = { fitToPage: 1, zoom: 1 },
|
||||
pageProps,
|
||||
filename
|
||||
}: {
|
||||
SVG: SVGSVGElement[];
|
||||
scale: PDFExportScale;
|
||||
pageProps: PDFPageProperties;
|
||||
}): Promise<ArrayBuffer> {
|
||||
const pdfDoc = await PDFDocument.create();
|
||||
filename: string;
|
||||
}): Promise<void> {
|
||||
if (!DEVICE.isDesktop) {
|
||||
new Notice(t("PDF_EXPORT_DESKTOP_ONLY"));
|
||||
return;
|
||||
}
|
||||
|
||||
const savePath = await getSavePath(filename);
|
||||
if (!savePath) return;
|
||||
|
||||
const {width, height} = getPageSizePixels(pageProps.dimensions, false);
|
||||
const allPagesDiv = createDiv();
|
||||
allPagesDiv.style.width = "100%";
|
||||
allPagesDiv.style.height = "fit-content";
|
||||
|
||||
let j = 1;
|
||||
for (const svg of SVG) {
|
||||
const svgWidth = parseFloat(svg.getAttribute('width') || '0');
|
||||
const svgHeight = parseFloat(svg.getAttribute('height') || '0');
|
||||
|
||||
const dimensions = calculateDimensions(
|
||||
svgWidth,
|
||||
svgHeight,
|
||||
pageProps.dimensions,
|
||||
pageProps.margin,
|
||||
const {tiles} = calculateDimensions(
|
||||
svgWidth,
|
||||
svgHeight,
|
||||
pageProps.dimensions,
|
||||
pageProps.margin,
|
||||
scale,
|
||||
pageProps.alignment
|
||||
);
|
||||
|
||||
for (const dim of dimensions) {
|
||||
await addSVGToPage(pdfDoc, svg, dim, pageProps.dimensions, pageProps.backgroundColor);
|
||||
let i = 1;
|
||||
for (const tile of tiles) {
|
||||
const pageDiv = createDiv();
|
||||
pageDiv.style.width = `${width}px`;
|
||||
pageDiv.style.height = `${height}px`;
|
||||
pageDiv.style.display = "flex";
|
||||
pageDiv.style.justifyContent = "start";
|
||||
pageDiv.style.alignItems = "left";
|
||||
pageDiv.style.padding = `${pageProps.margin.top}px ${pageProps.margin.right}px ${pageProps.margin.bottom}px ${pageProps.margin.left}px`;
|
||||
|
||||
const clonedSVG = svg.cloneNode(true) as SVGSVGElement;
|
||||
clonedSVG.setAttribute('viewBox', tile.viewBox);
|
||||
clonedSVG.style.width = `${tile.width}px`;
|
||||
clonedSVG.style.height = `${tile.height}px`;
|
||||
clonedSVG.style.position = 'absolute';
|
||||
clonedSVG.style.left = `${tile.x}px`;
|
||||
clonedSVG.style.top = `${tile.y + (i-1)*height}px`;
|
||||
|
||||
pageDiv.appendChild(clonedSVG);
|
||||
allPagesDiv.appendChild(pageDiv);
|
||||
i++;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
return pdfDoc.save();
|
||||
}
|
||||
|
||||
function hexToRGB(hex: string): { r: number; g: number; b: number } {
|
||||
const ea = getEA();
|
||||
const color = ea.getCM(hex);
|
||||
if (color) {
|
||||
return { r: color.red, g: color.green, b: color.blue };
|
||||
new Notice(t("EXPORTDIALOG_PDF_PROGRESS_NOTICE"));
|
||||
try {
|
||||
await printPdf(
|
||||
allPagesDiv,
|
||||
savePath,
|
||||
pageProps.backgroundColor || "#ffffff",
|
||||
pageProps.dimensions,
|
||||
false,
|
||||
{ top: 0, right: 0, bottom: 0, left: 0 }
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Failed to export to PDF: ", error);
|
||||
new Notice(t("EXPORTDIALOG_PDF_PROGRESS_ERROR"));
|
||||
}
|
||||
return {r: 255, g: 255, b: 255};
|
||||
}
|
||||
|
||||
// Helper function to split SVG into pages if needed
|
||||
function splitSVGIntoPages(
|
||||
svg: SVGSVGElement,
|
||||
maxWidth: number,
|
||||
maxHeight: number
|
||||
): SVGSVGElement[] {
|
||||
const width = parseFloat(svg.getAttribute('width') || '0');
|
||||
const height = parseFloat(svg.getAttribute('height') || '0');
|
||||
|
||||
if (width <= maxWidth && height <= maxHeight) {
|
||||
return [svg];
|
||||
}
|
||||
|
||||
const pages: SVGSVGElement[] = [];
|
||||
const cols = Math.ceil(width / maxWidth);
|
||||
const rows = Math.ceil(height / maxHeight);
|
||||
|
||||
for (let row = 0; row < rows; row++) {
|
||||
for (let col = 0; col < cols; col++) {
|
||||
const viewBox = `${col * maxWidth} ${row * maxHeight} ${maxWidth} ${maxHeight}`;
|
||||
const clonedSvg = svg.cloneNode(true) as SVGSVGElement;
|
||||
clonedSvg.setAttribute('viewBox', viewBox);
|
||||
clonedSvg.setAttribute('width', String(maxWidth));
|
||||
clonedSvg.setAttribute('height', String(maxHeight));
|
||||
pages.push(clonedSvg);
|
||||
}
|
||||
}
|
||||
|
||||
return pages;
|
||||
new Notice(t("EXPORTDIALOG_PDF_PROGRESS_DONE"));
|
||||
}
|
||||
|
||||
export async function exportSVGToClipboard(svg: SVGSVGElement) {
|
||||
|
||||
@@ -372,7 +372,7 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
|
||||
constructor(leaf: WorkspaceLeaf, plugin: ExcalidrawPlugin) {
|
||||
super(leaf);
|
||||
this._plugin = plugin;
|
||||
this.excalidrawData = new ExcalidrawData(plugin);
|
||||
this.excalidrawData = new ExcalidrawData(plugin, this);
|
||||
this.canvasNodeFactory = new CanvasNodeFactory(this);
|
||||
this.setHookServer();
|
||||
this.dropManager = new DropManager(this);
|
||||
@@ -587,47 +587,20 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
|
||||
return;
|
||||
}
|
||||
|
||||
const pdfArrayBuffer = await exportToPDF({
|
||||
exportToPDF({
|
||||
SVG: [svg],
|
||||
scale: {
|
||||
...this.exportDialog.fitToPage
|
||||
? { fitToPage: true }
|
||||
: { zoom: this.exportDialog.scale, fitToPage: false },
|
||||
scale: {
|
||||
zoom: this.exportDialog.scale,
|
||||
fitToPage: this.exportDialog.fitToPage
|
||||
},
|
||||
pageProps: {
|
||||
dimensions: getPageDimensions(pageSize, orientation),
|
||||
backgroundColor: this.exportDialog.getPaperColor(),
|
||||
margin: getMarginValue(this.exportDialog.margin),
|
||||
alignment: this.exportDialog.alignment,
|
||||
}
|
||||
},
|
||||
filename: this.file.basename,
|
||||
});
|
||||
|
||||
if (!pdfArrayBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(toVault) {
|
||||
const filepath = getIMGFilename(this.file.path, "pdf");
|
||||
const file = await createOrOverwriteFile(this.app, filepath, pdfArrayBuffer);
|
||||
let leaf: WorkspaceLeaf;
|
||||
this.app.workspace.getLeavesOfType("pdf").forEach((l) => {
|
||||
//@ts-ignore
|
||||
if(l.view?.file === file) {
|
||||
leaf = l;
|
||||
}
|
||||
});
|
||||
if(leaf) {
|
||||
this.app.workspace.revealLeaf(leaf);
|
||||
} else {
|
||||
this.app.workspace.getLeaf("split").openFile(file);
|
||||
}
|
||||
} else {
|
||||
download(
|
||||
"data:application/pdf;base64",
|
||||
arrayBufferToBase64(pdfArrayBuffer),
|
||||
`${this.file.basename}.pdf`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public async png(scene: any, theme?:string, embedScene?: boolean): Promise<Blob> {
|
||||
@@ -1578,6 +1551,9 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
|
||||
this.packages = this.plugin.getPackage(this.ownerWindow);
|
||||
|
||||
if(DEVICE.isDesktop && !apiMissing) {
|
||||
if(this.ownerWindow !== window) {
|
||||
this.plugin.initializeFonts();
|
||||
}
|
||||
this.destroyers.push(
|
||||
//this.containerEl.onWindowMigrated(this.leaf.rebuildView.bind(this))
|
||||
this.containerEl.onWindowMigrated(async() => {
|
||||
|
||||
11
styles.css
11
styles.css
@@ -116,6 +116,7 @@ li[data-testid] {
|
||||
border: 0 !important;
|
||||
box-shadow: 0 !important;
|
||||
background-color: transparent !important;
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
|
||||
.excalidraw .popover {
|
||||
@@ -336,6 +337,16 @@ label.color-input-container > input {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.excalidraw .App-toolbar-content .dropdown-menu {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.excalidraw .panelColumn {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.excalidraw .panelColumn .buttonList {
|
||||
max-width: 13rem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user