Skip to content

Commit 08a215b

Browse files
committed
image manager
1 parent 8a4c23a commit 08a215b

27 files changed

Lines changed: 9443 additions & 228587 deletions

package-lock.json

Lines changed: 615 additions & 507 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lemniscate",
3-
"version": "0.2.1",
3+
"version": "0.3.0",
44
"license": "MIT",
55
"scripts": {
66
"dev": "vite dev",
@@ -27,40 +27,40 @@
2727
},
2828
"devDependencies": {
2929
"@codemirror/lang-markdown": "^6.5.0",
30-
"@embedpdf/core": "^2.6.2",
31-
"@embedpdf/engines": "^2.6.2",
32-
"@embedpdf/plugin-document-manager": "^2.6.2",
33-
"@embedpdf/plugin-export": "^2.6.2",
34-
"@embedpdf/plugin-fullscreen": "^2.6.2",
35-
"@embedpdf/plugin-print": "^2.6.2",
36-
"@embedpdf/plugin-render": "^2.6.2",
37-
"@embedpdf/plugin-scroll": "^2.6.2",
38-
"@embedpdf/plugin-search": "^2.6.2",
39-
"@embedpdf/plugin-spread": "^2.6.2",
40-
"@embedpdf/plugin-tiling": "^2.6.2",
41-
"@embedpdf/plugin-viewport": "^2.6.2",
42-
"@embedpdf/plugin-zoom": "^2.6.2",
30+
"@embedpdf/core": "^2.10.1",
31+
"@embedpdf/engines": "^2.10.1",
32+
"@embedpdf/plugin-document-manager": "^2.10.1",
33+
"@embedpdf/plugin-export": "^2.10.1",
34+
"@embedpdf/plugin-fullscreen": "^2.10.1",
35+
"@embedpdf/plugin-print": "^2.10.1",
36+
"@embedpdf/plugin-render": "^2.10.1",
37+
"@embedpdf/plugin-scroll": "^2.10.1",
38+
"@embedpdf/plugin-search": "^2.10.1",
39+
"@embedpdf/plugin-spread": "^2.10.1",
40+
"@embedpdf/plugin-tiling": "^2.10.1",
41+
"@embedpdf/plugin-viewport": "^2.10.1",
42+
"@embedpdf/plugin-zoom": "^2.10.1",
4343
"@sveltejs/adapter-static": "^3.0.10",
4444
"@sveltejs/package": "^2.5.7",
4545
"@sveltejs/vite-plugin-svelte": "^6.2.4",
4646
"@types/file-saver": "^2.0.7",
47-
"@types/node": "^25.3.1",
48-
"carbon-components-svelte": "^0.101.3",
49-
"carbon-icons-svelte": "^13.8.0",
47+
"@types/node": "^25.5.0",
48+
"carbon-components-svelte": "^0.103.0",
49+
"carbon-icons-svelte": "^13.10.0",
5050
"cm6-theme-basic-dark": "^0.2.0",
5151
"cm6-theme-basic-light": "^0.2.0",
5252
"file-saver": "^2.0.5",
5353
"pandoc-wasm": "^1.0.1",
54-
"publint": "^0.3.17",
55-
"svelte": "^5.53.5",
56-
"svelte-check": "^4.4.3",
54+
"publint": "^0.3.18",
55+
"svelte": "^5.55.0",
56+
"svelte-check": "^4.4.5",
5757
"svelte-codemirror-editor": "^2.1.0",
5858
"svelte-idle": "^3.0.1",
59-
"texlyre-busytex": "^0.1.2-alpha",
59+
"texlyre-busytex": "^0.1.4-alpha",
6060
"typescript": "^5.9.3",
6161
"vite": "^7.3.1",
6262
"vite-plugin-top-level-await": "^1.6.0",
63-
"vite-plugin-wasm": "^3.5.0"
63+
"vite-plugin-wasm": "^3.6.0"
6464
},
6565
"keywords": [
6666
"svelte"

src/lib/ImageManagerModal.svelte

100644100755
Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<script lang='ts'>
22
import {
33
FileUploader,
4-
Modal
4+
Modal,
5+
Stack
56
} from 'carbon-components-svelte';
67
78
let {
@@ -19,13 +20,17 @@
1920
size='sm'
2021
modalHeading='Image Manager'
2122
>
22-
<FileUploader
23-
multiple
24-
bind:files={images}
25-
status='edit'
26-
labelTitle='Upload Images'
27-
buttonLabel='Add'
28-
labelDescription='Allowed files: .jpg, .png'
29-
accept={['.jpg', '.png']}
30-
/>
23+
<Stack gap={5}>
24+
<div>Note: image uploads are not saved when the tab/window is closed.</div>
25+
<div>Use Markdown or LaTeX to insert images.</div>
26+
<FileUploader
27+
multiple
28+
bind:files={images}
29+
status='edit'
30+
labelTitle='Upload Images'
31+
buttonLabel='Add'
32+
labelDescription='Allowed files: .jpg, .png'
33+
accept={['.jpg', '.png']}
34+
/>
35+
</Stack>
3136
</Modal>

src/routes/+page.svelte

100644100755
Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import { basicLight } from 'cm6-theme-basic-light';
4545
import FileSaver from 'file-saver';
4646
import { convert } from 'pandoc-wasm';
47-
import { BusyTexRunner, PdfLatex } from 'texlyre-busytex';
47+
import { BusyTexRunner, PdfLatex, type FileInput } from 'texlyre-busytex';
4848
import { listen, onIdle } from 'svelte-idle';
4949
5050
import AboutHelpModal from '$lib/AboutHelpModal.svelte';
@@ -113,12 +113,22 @@
113113
const blob = new Blob([editorInput], { type: 'text/plain;charset=utf-8' });
114114
FileSaver.saveAs(blob, `${$ConfigStore.title === '' ? 'lemniscate-editor' : $ConfigStore.title.toLowerCase().replaceAll(/[^a-z\d\s]/g, '').replaceAll(/\s/g, '-')}.md`);
115115
}
116-
116+
117117
const compile = async (): Promise<void> => {
118118
if (!runner.isInitialized()) {
119119
openNotification.set(true);
120120
return;
121121
}
122+
const reader = (file: File) => new Promise((resolve, reject) => {
123+
const fr = new FileReader();
124+
fr.onload = () => resolve(fr);
125+
fr.onerror = (err) => reject(err);
126+
fr.readAsArrayBuffer(file);
127+
});
128+
let preamble = $ConfigStore.preamble;
129+
if (images.length > 0 && !preamble.includes(`\\usepackage{graphicx}`)) {
130+
preamble += `\n\\usepackage{graphicx}`;
131+
}
122132
let metablock = `---\nlinkcolor: blue\n`;
123133
if ($ConfigStore.title !== '') metablock += `title: ${$ConfigStore.title}\n`;
124134
if ($ConfigStore.author !== '') metablock += `author: ${$ConfigStore.author}\n`;
@@ -128,14 +138,24 @@
128138
} else {
129139
metablock += `geometry:\n- paper=${$ConfigStore.paperSize}\n- top=${$ConfigStore.tmargin}\n- bottom=${$ConfigStore.bmargin}\n- left=${$ConfigStore.lmargin}\n- right=${$ConfigStore.rmargin}\n`
130140
}
131-
metablock += `header-includes:\n- |\n \`\`\`{=latex}\n ${$ConfigStore.preamble.replace(/\n/gm, `\n `)}\n \`\`\`\n...`;
141+
metablock += `header-includes:\n- |\n \`\`\`{=latex}\n ${preamble.replace(/\n/gm, `\n `)}\n \`\`\`\n...`;
132142
const pandocResult = await convert({
133143
from: `markdown${$ConfigStore.extensions !== '' ? `+${$ConfigStore.extensions}` : ''}`,
134144
to: $ConfigStore.formatSelect === 'article' ? 'latex' : 'beamer',
135145
standalone: true
136146
}, `${metablock}\n${editorInput}`, {});
137147
if (pandocResult.stderr === '') {
138-
const result = await engine.compile({ input: pandocResult.stdout });
148+
let additionalFiles: FileInput[] = [];
149+
const promises = images.map(reader);
150+
const filereaders = await Promise.all(promises);
151+
filereaders.forEach((fr, i) => additionalFiles.push({
152+
path: images[i].name,
153+
content: new Uint8Array((fr as FileReader).result as ArrayBuffer)
154+
}));
155+
const result = await engine.compile({
156+
input: pandocResult.stdout,
157+
additionalFiles: additionalFiles
158+
});
139159
if (result.success) {
140160
pdfview.openPdf(URL.createObjectURL(new Blob([ result.pdf! as Uint8Array<ArrayBuffer> ], { type: 'application/pdf' })));
141161
} else {
@@ -202,8 +222,8 @@
202222
<DocumentConfiguration />
203223
</TooltipDefinition>
204224
<TooltipDefinition
205-
tooltipText='Image Manager (Coming Soon)'
206-
on:click={() => {}}
225+
tooltipText='Image Manager'
226+
on:click={() => openImageManager = true}
207227
>
208228
<Image />
209229
</TooltipDefinition>

0 commit comments

Comments
 (0)