euler314 commited on
Commit
b7d8ac9
·
verified ·
1 Parent(s): 208a7e8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +429 -0
app.py ADDED
@@ -0,0 +1,429 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import subprocess
3
+ import tempfile
4
+ import base64
5
+ from pathlib import Path
6
+ import os
7
+
8
+ # Set page configuration
9
+ st.set_page_config(page_title="LaTeX Editor & Compiler", page_icon="📝", layout="wide")
10
+
11
+ # Function to convert LaTeX to PDF
12
+ def latex_to_pdf(latex_code):
13
+ with tempfile.TemporaryDirectory() as temp_dir:
14
+ temp_path = Path(temp_dir)
15
+ tex_file = temp_path / "document.tex"
16
+ pdf_file = temp_path / "document.pdf"
17
+
18
+ # Write LaTeX code to file
19
+ with open(tex_file, "w") as f:
20
+ f.write(latex_code)
21
+
22
+ try:
23
+ # Run pdflatex to compile the LaTeX file
24
+ process = subprocess.run(
25
+ ["pdflatex", "-interaction=nonstopmode", "-output-directory", temp_dir, str(tex_file)],
26
+ capture_output=True,
27
+ text=True
28
+ )
29
+
30
+ # Check if PDF was created
31
+ if pdf_file.exists():
32
+ with open(pdf_file, "rb") as file:
33
+ pdf_data = file.read()
34
+ return pdf_data, process.stdout, process.stderr
35
+ else:
36
+ return None, process.stdout, process.stderr
37
+ except Exception as e:
38
+ return None, "", str(e)
39
+
40
+ # Function to display PDF
41
+ def display_pdf(pdf_data):
42
+ base64_pdf = base64.b64encode(pdf_data).decode('utf-8')
43
+ pdf_display = f"""
44
+ <iframe
45
+ src="data:application/pdf;base64,{base64_pdf}"
46
+ width="100%"
47
+ height="600"
48
+ style="border: none;"
49
+ ></iframe>
50
+ """
51
+ st.markdown(pdf_display, unsafe_allow_html=True)
52
+
53
+ # Function to create download link for PDF
54
+ def get_download_link(pdf_data, filename="document.pdf"):
55
+ b64_pdf = base64.b64encode(pdf_data).decode()
56
+ return f'<a href="data:application/pdf;base64,{b64_pdf}" download="{filename}" class="download-button">Download PDF</a>'
57
+
58
+ # LaTeX package reference
59
+ latex_packages = {
60
+ "Document": {
61
+ "\\usepackage{geometry}": "Page layout customization",
62
+ "\\usepackage{fancyhdr}": "Custom headers and footers",
63
+ "\\usepackage{titlesec}": "Title formatting",
64
+ "\\usepackage{hyperref}": "Hyperlinks and PDF metadata"
65
+ },
66
+ "Math": {
67
+ "\\usepackage{amsmath}": "Enhanced math formatting",
68
+ "\\usepackage{amssymb}": "Mathematical symbols",
69
+ "\\usepackage{mathtools}": "Extensions to amsmath",
70
+ "\\usepackage{physics}": "Physics notation"
71
+ },
72
+ "Graphics": {
73
+ "\\usepackage{graphicx}": "Include images",
74
+ "\\usepackage{tikz}": "Create vector graphics",
75
+ "\\usepackage{pgfplots}": "Create plots",
76
+ "\\usepackage{float}": "Better figure placement"
77
+ },
78
+ "Tables": {
79
+ "\\usepackage{tabularx}": "Flexible tables",
80
+ "\\usepackage{booktabs}": "Professional tables",
81
+ "\\usepackage{colortbl}": "Colored tables",
82
+ "\\usepackage{multirow}": "Multi-row cells"
83
+ },
84
+ "Content": {
85
+ "\\usepackage{listings}": "Code syntax highlighting",
86
+ "\\usepackage{minted}": "Advanced code highlighting",
87
+ "\\usepackage{biblatex}": "Bibliography management",
88
+ "\\usepackage{xcolor}": "Color support"
89
+ }
90
+ }
91
+
92
+ # LaTeX commands reference
93
+ latex_commands = {
94
+ "Document Structure": {
95
+ "\\documentclass{article}": "Specifies the type of document",
96
+ "\\begin{document}": "Starts the document content",
97
+ "\\end{document}": "Ends the document content",
98
+ "\\title{...}": "Sets the document title",
99
+ "\\author{...}": "Sets the document author",
100
+ "\\date{...}": "Sets the document date",
101
+ "\\maketitle": "Prints the title, author, and date"
102
+ },
103
+ "Sections": {
104
+ "\\section{...}": "Creates a section",
105
+ "\\subsection{...}": "Creates a subsection",
106
+ "\\subsubsection{...}": "Creates a subsubsection",
107
+ "\\paragraph{...}": "Creates a paragraph heading",
108
+ "\\tableofcontents": "Generates a table of contents"
109
+ },
110
+ "Text Formatting": {
111
+ "\\textbf{...}": "Bold text",
112
+ "\\textit{...}": "Italic text",
113
+ "\\underline{...}": "Underlined text",
114
+ "\\emph{...}": "Emphasized text",
115
+ "\\texttt{...}": "Typewriter text",
116
+ "\\textsc{...}": "Small caps text",
117
+ "\\textsf{...}": "Sans-serif text",
118
+ "\\color{red}{...}": "Colored text (requires xcolor)"
119
+ },
120
+ "Math": {
121
+ "$...$": "Inline math mode",
122
+ "$$...$$": "Display math mode",
123
+ "\\begin{equation}...\\end{equation}": "Numbered equation",
124
+ "\\begin{align}...\\end{align}": "Aligned equations",
125
+ "\\frac{num}{denom}": "Fraction",
126
+ "\\dfrac{num}{denom}": "Display fraction",
127
+ "\\sqrt{...}": "Square root",
128
+ "\\sqrt[n]{...}": "nth root",
129
+ "\\sum_{lower}^{upper}": "Summation",
130
+ "\\prod_{lower}^{upper}": "Product",
131
+ "\\int_{lower}^{upper}": "Integral",
132
+ "\\lim_{x \\to value}": "Limit",
133
+ "\\vec{...}": "Vector",
134
+ "\\overline{...}": "Overline",
135
+ "\\hat{...}": "Hat accent",
136
+ "\\partial": "Partial derivative"
137
+ },
138
+ "Lists": {
139
+ "\\begin{itemize}...\\end{itemize}": "Bulleted list",
140
+ "\\begin{enumerate}...\\end{enumerate}": "Numbered list",
141
+ "\\begin{description}...\\end{description}": "Description list",
142
+ "\\item": "List item",
143
+ "\\item[custom]": "Custom label item"
144
+ },
145
+ "Tables": {
146
+ "\\begin{table}...\\end{table}": "Table environment",
147
+ "\\begin{tabular}{cols}...\\end{tabular}": "Create a table",
148
+ "\\hline": "Horizontal line in table",
149
+ "\\cline{i-j}": "Partial horizontal line",
150
+ "cell1 & cell2 & cell3 \\\\": "Table row",
151
+ "\\multicolumn{n}{align}{content}": "Span multiple columns"
152
+ },
153
+ "Figures": {
154
+ "\\begin{figure}...\\end{figure}": "Figure environment",
155
+ "\\includegraphics[width=0.8\\textwidth]{filename}": "Include an image",
156
+ "\\caption{...}": "Add a caption to a figure or table",
157
+ "\\label{...}": "Add a label for cross-referencing",
158
+ "\\ref{...}": "Reference a labeled item"
159
+ },
160
+ "Citations": {
161
+ "\\cite{key}": "Citation",
162
+ "\\bibliography{file}": "Bibliography source",
163
+ "\\bibliographystyle{style}": "Bibliography style"
164
+ }
165
+ }
166
+
167
+ # Default LaTeX template
168
+ default_template = r"""\documentclass{article}
169
+ \usepackage[utf8]{inputenc}
170
+ \usepackage{amsmath}
171
+ \usepackage{amssymb}
172
+ \usepackage{graphicx}
173
+ \usepackage{hyperref}
174
+
175
+ \title{LaTeX Document}
176
+ \author{Your Name}
177
+ \date{\today}
178
+
179
+ \begin{document}
180
+
181
+ \maketitle
182
+
183
+ \section{Introduction}
184
+ Your introduction here. Insert some text to demonstrate LaTeX.
185
+
186
+ \section{Mathematical Expressions}
187
+ \subsection{Equations}
188
+ The famous Einstein's equation:
189
+ \begin{equation}
190
+ E = mc^2
191
+ \end{equation}
192
+
193
+ The quadratic formula:
194
+ \begin{equation}
195
+ x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
196
+ \end{equation}
197
+
198
+ \subsection{Calculus}
199
+ An integral example:
200
+ \begin{equation}
201
+ \int_{0}^{\pi} \sin(x) \, dx = 2
202
+ \end{equation}
203
+
204
+ \section{Lists and Items}
205
+ \subsection{Bullet Points}
206
+ \begin{itemize}
207
+ \item First item
208
+ \item Second item
209
+ \item Third item
210
+ \end{itemize}
211
+
212
+ \subsection{Numbered List}
213
+ \begin{enumerate}
214
+ \item First step
215
+ \item Second step
216
+ \item Third step
217
+ \end{enumerate}
218
+
219
+ \section{Tables}
220
+ \begin{table}[h]
221
+ \centering
222
+ \begin{tabular}{|c|c|c|}
223
+ \hline
224
+ Cell 1 & Cell 2 & Cell 3 \\
225
+ \hline
226
+ Data 1 & Data 2 & Data 3 \\
227
+ \hline
228
+ \end{tabular}
229
+ \caption{A simple table}
230
+ \label{tab:simple}
231
+ \end{table}
232
+
233
+ \section{Conclusion}
234
+ Your conclusion here.
235
+
236
+ \end{document}
237
+ """
238
+
239
+ # Add custom CSS
240
+ st.markdown("""
241
+ <style>
242
+ .editor-container {
243
+ border: 1px solid #ccc;
244
+ border-radius: 5px;
245
+ padding: 10px;
246
+ background-color: #f8f9fa;
247
+ }
248
+ .download-button {
249
+ display: inline-block;
250
+ padding: 0.5em 1em;
251
+ background-color: #4CAF50;
252
+ color: white !important;
253
+ text-align: center;
254
+ text-decoration: none;
255
+ font-size: 16px;
256
+ border-radius: 4px;
257
+ transition: background-color 0.3s;
258
+ margin-top: 10px;
259
+ }
260
+ .download-button:hover {
261
+ background-color: #45a049;
262
+ }
263
+ .stTextArea textarea {
264
+ font-family: 'Courier New', Courier, monospace !important;
265
+ font-size: 14px !important;
266
+ line-height: 1.5 !important;
267
+ }
268
+ .latex-command {
269
+ background-color: #f1f1f1;
270
+ padding: 2px 4px;
271
+ border-radius: 3px;
272
+ font-family: monospace;
273
+ cursor: pointer;
274
+ }
275
+ .reference-tabs .stTabs {
276
+ background-color: #f5f5f5;
277
+ border-radius: 5px;
278
+ padding: 10px;
279
+ }
280
+ .stMarkdown h4 {
281
+ margin-top: 0.5rem !important;
282
+ margin-bottom: 0.5rem !important;
283
+ }
284
+ .command-category {
285
+ margin-bottom: 15px !important;
286
+ }
287
+ </style>
288
+ """, unsafe_allow_html=True)
289
+
290
+ # JavaScript for copying commands to editor
291
+ st.markdown("""
292
+ <script>
293
+ function copyToEditor(text) {
294
+ const textareas = document.getElementsByTagName('textarea');
295
+ if (textareas.length > 0) {
296
+ const editor = textareas[0];
297
+ const start = editor.selectionStart;
298
+ const end = editor.selectionEnd;
299
+ const value = editor.value;
300
+ editor.value = value.substring(0, start) + text + value.substring(end);
301
+ editor.selectionStart = editor.selectionEnd = start + text.length;
302
+ editor.focus();
303
+ }
304
+ }
305
+ </script>
306
+ """, unsafe_allow_html=True)
307
+
308
+ # Main application
309
+ def main():
310
+ st.title("LaTeX Editor & PDF Compiler")
311
+
312
+ # Create layout with sidebar
313
+ col1, col2 = st.columns([3, 2])
314
+
315
+ with col1:
316
+ st.subheader("LaTeX Editor")
317
+
318
+ # Initialize session state
319
+ if 'latex_code' not in st.session_state:
320
+ st.session_state.latex_code = default_template
321
+
322
+ # LaTeX editor
323
+ latex_code = st.text_area(
324
+ "Edit your LaTeX document:",
325
+ value=st.session_state.latex_code,
326
+ height=500,
327
+ key="latex_editor"
328
+ )
329
+ st.session_state.latex_code = latex_code
330
+
331
+ # Control buttons
332
+ col1_1, col1_2, col1_3 = st.columns(3)
333
+
334
+ with col1_1:
335
+ if st.button("Compile PDF", use_container_width=True):
336
+ st.session_state.compile_clicked = True
337
+
338
+ with col1_2:
339
+ if st.button("Load Template", use_container_width=True):
340
+ st.session_state.latex_code = default_template
341
+ st.rerun()
342
+
343
+ with col1_3:
344
+ if st.button("Clear Editor", use_container_width=True):
345
+ st.session_state.latex_code = ""
346
+ st.rerun()
347
+
348
+ with col2:
349
+ st.subheader("PDF Preview")
350
+
351
+ # PDF preview
352
+ if 'compile_clicked' in st.session_state and st.session_state.compile_clicked:
353
+ with st.spinner("Compiling LaTeX to PDF..."):
354
+ pdf_data, stdout, stderr = latex_to_pdf(latex_code)
355
+
356
+ if pdf_data:
357
+ st.session_state.pdf_data = pdf_data
358
+ display_pdf(pdf_data)
359
+
360
+ # Download button
361
+ st.markdown(get_download_link(pdf_data), unsafe_allow_html=True)
362
+ st.session_state.compile_clicked = False
363
+ else:
364
+ st.error("Compilation Error")
365
+ with st.expander("Error Details"):
366
+ st.text(stdout)
367
+ st.text(stderr)
368
+ st.session_state.compile_clicked = False
369
+
370
+ # Display previous PDF if available
371
+ elif 'pdf_data' in st.session_state and st.session_state.pdf_data:
372
+ display_pdf(st.session_state.pdf_data)
373
+ st.markdown(get_download_link(st.session_state.pdf_data), unsafe_allow_html=True)
374
+ else:
375
+ st.info("Compile your LaTeX document to see the PDF preview")
376
+
377
+ # LaTeX Reference Sidebar
378
+ st.sidebar.title("LaTeX Reference")
379
+
380
+ # Search functionality
381
+ search_query = st.sidebar.text_input("Search commands or packages", "")
382
+
383
+ if search_query:
384
+ st.sidebar.subheader("Search Results")
385
+ found = False
386
+
387
+ # Search commands
388
+ for category, commands in latex_commands.items():
389
+ filtered_commands = {cmd: desc for cmd, desc in commands.items()
390
+ if search_query.lower() in cmd.lower() or search_query.lower() in desc.lower()}
391
+
392
+ if filtered_commands:
393
+ found = True
394
+ with st.sidebar.expander(f"{category} ({len(filtered_commands)} results)"):
395
+ for cmd, desc in filtered_commands.items():
396
+ st.markdown(f"<div class='latex-command' onclick=\"copyToEditor('{cmd}')\">{cmd}</div> - {desc}", unsafe_allow_html=True)
397
+
398
+ # Search packages
399
+ for category, packages in latex_packages.items():
400
+ filtered_packages = {pkg: desc for pkg, desc in packages.items()
401
+ if search_query.lower() in pkg.lower() or search_query.lower() in desc.lower()}
402
+
403
+ if filtered_packages:
404
+ found = True
405
+ with st.sidebar.expander(f"Packages: {category} ({len(filtered_packages)} results)"):
406
+ for pkg, desc in filtered_packages.items():
407
+ st.markdown(f"<div class='latex-command' onclick=\"copyToEditor('{pkg}')\">{pkg}</div> - {desc}", unsafe_allow_html=True)
408
+
409
+ if not found:
410
+ st.sidebar.info("No matching commands or packages found")
411
+
412
+ else:
413
+ # Display full reference when not searching
414
+ tabs = st.sidebar.tabs(["Commands", "Packages"])
415
+
416
+ with tabs[0]:
417
+ for category, commands in latex_commands.items():
418
+ with st.expander(category):
419
+ for cmd, desc in commands.items():
420
+ st.markdown(f"<div class='latex-command' onclick=\"copyToEditor('{cmd}')\">{cmd}</div> - {desc}", unsafe_allow_html=True)
421
+
422
+ with tabs[1]:
423
+ for category, packages in latex_packages.items():
424
+ with st.expander(category):
425
+ for pkg, desc in packages.items():
426
+ st.markdown(f"<div class='latex-command' onclick=\"copyToEditor('{pkg}')\">{pkg}</div> - {desc}", unsafe_allow_html=True)
427
+
428
+ if __name__ == "__main__":
429
+ main()