comparison mrjunejune/test/snapshots/tools_latex_editor.snapshot @ 244:b8aa08503378

[tools] Add sandboxed online LaTeX editor Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Mon, 03 Aug 2026 16:56:25 -0700
parents
children 4f2b50bc78e7
comparison
equal deleted inserted replaced
243:823f2a8b16c8 244:b8aa08503378
1 <!doctype html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <meta name="theme-color" content="#544e43">
7 <link rel="icon" type="image/svg+xml" href="/public/epi_all_colors.svg">
8 <link rel="manifest" href="/public/manifest.json">
9 <link rel="apple-touch-icon" href="/public/epi_all_colors.svg">
10
11 <link rel="preload" href="/public/fonts/Roboto-Regular.ttf" as="font" crossorigin>
12 <link rel="preload" href="/public/fonts/Roboto-Thin.ttf"as="font" crossorigin>
13
14 <!-- <link rel="preload" href="/public/fonts/atkinson-regular.woff" as="font" type="font/woff" crossorigin> -->
15 <!-- <link rel="preload" href="/public/fonts/atkinson-bold.woff" as="font" type="font/woff" crossorigin> -->
16
17 <!-- <link rel="preload" href="/public/fonts/more-sugar.extras.otf" as="font" type="font/otf" crossorigin> -->
18 <link rel="preload" href="/public/fonts/more-sugar.regular.otf" as="font" type="font/otf" crossorigin>
19 <link rel="preload" href="/public/fonts/more-sugar.thin.otf" as="font" type="font/otf" crossorigin>
20 <link rel="preload" href="/public/epi_all_colors.svg" as="image">
21
22 <link rel="preload" href="/base.css" as="style" />
23 <link rel="stylesheet" href="/base.css" />
24
25 <script src="/public/pwa-register.js" defer></script>
26
27
28 <title>LaTeX Editor - MrJuneJune</title>
29 <link rel="stylesheet" href="/tools/latex_editor/index.css" />
30 <script src="/tools/latex_editor/index.js" defer></script>
31 </head>
32 <body>
33 <style>
34 :root {
35 --header-background: var(--white);
36 --header-color: rgb(var(--black));
37 --link-hover-accent: var(--awesome);
38 }
39
40 /* Fixed icon in top left corner */
41 #themeToggle {
42 position: fixed;
43 top: 20px;
44 left: 20px;
45 background: var(--header-background);
46 display: flex;
47 align-items: center;
48 border-radius: 50%;
49 cursor: pointer;
50 z-index: 1000;
51 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
52 transition: transform 0.2s ease;
53 }
54
55 #themeToggle:hover {
56 transform: scale(1.05);
57 }
58
59 /* Professional header */
60 header {
61 margin: auto;
62 padding: 1.5em 1em;
63 font-family: "More", sans-serif;
64 box-shadow: 0 2px 8px rgba(var(--black), 5%);
65 width: 720px;
66 max-width: calc(100% - 2em);
67 text-align: center;
68 }
69
70 header h1 {
71 margin: 0;
72 font-size: 1.8em;
73 font-weight: 700;
74 letter-spacing: -0.5px;
75 }
76
77 header h1 a {
78 text-decoration: none;
79 color: var(--header-color);
80 }
81
82 header h1 a::before {
83 display: none;
84 }
85
86 /* Mobile responsiveness */
87 @media (max-width: 720px) {
88 #themeToggle {
89 top: 15px;
90 left: 15px;
91 }
92
93 header {
94 padding: 1em;
95 }
96
97 header h1 {
98 font-size: 1.5em;
99 }
100 }
101
102 @media (max-width: 480px) {
103 #themeToggle {
104 top: 10px;
105 left: 10px;
106 }
107
108 #themeToggle img {
109 height: 40px;
110 width: 40px;
111 }
112
113 header h1 {
114 font-size: 1.3em;
115 }
116 }
117
118 #logo {
119 width: 300px;
120 }
121
122 /* 1. DEFINE THE DEFAULTS (Light Mode) */
123 :root {
124 --logo-invert: invert(0);
125 --epi-grayscale: grayscale(0) brightness(1);
126 }
127
128 /* 2. MANUAL DARK OVERRIDE */
129 html.dark {
130 --logo-invert: invert(1);
131 --epi-grayscale: grayscale(1);
132 }
133
134 /* 3. MANUAL LIGHT OVERRIDE */
135 html.light-mode {
136 --logo-invert: invert(0);
137 --epi-grayscale: brightness(2.9) grayscale(1);
138 }
139
140 /* 4. SYSTEM PREFERENCE */
141 @media (prefers-color-scheme: dark) {
142 :root:not(.light-mode) {
143 --logo-invert: invert(1);
144 }
145 }
146
147 /* 5. APPLY TO ELEMENTS */
148 #logo {
149 -webkit-filter: var(--logo-invert);
150 filter: var(--logo-invert);
151 transition: filter 0.3s ease;
152 }
153
154 .epi-logo {
155 -webkit-filter: var(--epi-grayscale);
156 filter: var(--epi-grayscale);
157 transition: filter 0.3s ease;
158 }
159 </style>
160
161 <div id="themeToggle">
162 <img id="epiChan" class="epi-logo" aria-label="Toggle dark mode" src="/public/epi_all_colors.svg" height="50" width="50">
163 </div>
164
165 <header>
166 <h1><a href="/">MrJuneJune</a></h1>
167 </header>
168 <script src="/index.js"></script>
169
170
171 <main class="latex-page">
172 <div class="latex-heading">
173 <div>
174 <h1>Online LaTeX Editor</h1>
175 <p>Write LaTeX here. My server compiles it inside a locked-down sandbox and sends the PDF back to this preview.</p>
176 </div>
177 <div class="latex-actions">
178 <label class="auto-compile">
179 <input id="autoCompile" type="checkbox" checked />
180 Auto compile
181 </label>
182 <button id="resetButton" type="button" class="secondary">Reset</button>
183 <button id="compileButton" type="button">Compile PDF</button>
184 <a id="downloadButton" class="button-link disabled" aria-disabled="true">Download</a>
185 </div>
186 </div>
187
188 <p id="latexStatus" class="latex-status" role="status" aria-live="polite">
189 Preparing your first PDF...
190 </p>
191
192 <div class="latex-workspace">
193 <section class="latex-panel editor-panel" aria-labelledby="sourceHeading">
194 <div class="panel-heading">
195 <h2 id="sourceHeading">document.tex</h2>
196 <span id="sourceSize">0 / 65,536 bytes</span>
197 </div>
198 <textarea id="latexSource" spellcheck="false" autocomplete="off" aria-label="LaTeX source">\documentclass[11pt]{article}
199 \usepackage[margin=1in]{geometry}
200 \usepackage{amsmath}
201 \usepackage{xcolor}
202
203 \title{Hello from my server}
204 \author{MrJuneJune}
205 \date{\today}
206
207 \begin{document}
208 \maketitle
209
210 This PDF was compiled by the custom C server behind this website.
211
212 \[
213 e^{i\pi} + 1 = 0
214 \]
215
216 \textcolor{blue}{Edit this document and watch the preview update.}
217
218 \end{document}
219 </textarea>
220 </section>
221
222 <section class="latex-panel preview-panel" aria-labelledby="previewHeading">
223 <div class="panel-heading">
224 <h2 id="previewHeading">PDF preview</h2>
225 <span>Server rendered</span>
226 </div>
227 <iframe
228 id="pdfPreview"
229 title="Compiled LaTeX PDF preview"
230 src="about:blank"
231 ></iframe>
232 <pre id="latexDiagnostics" class="latex-diagnostics" hidden></pre>
233 </section>
234 </div>
235
236 <section class="latex-notes">
237 <h2>Limits</h2>
238 <p>Source is capped at 64 KiB and compilation at 8 seconds. Shell commands, network access, and reads outside the isolated TeX workspace are blocked.</p>
239 </section>
240 </main>
241 <div style="display: flex; align-items: center; justify-content: center; margin: 30px 0px;">
242 <small>&copy; 2026 June Park</small>
243 </div>
244
245 </body>
246 </html>