euler314 commited on
Commit
72c62aa
·
verified ·
1 Parent(s): 04af6fe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +176 -373
app.py CHANGED
@@ -85,136 +85,6 @@ def render_pdf_preview(pdf_data):
85
  st.error(f"Error rendering PDF preview: {str(e)}")
86
  return None
87
 
88
- # LaTeX package reference
89
- latex_packages = {
90
- "Document": {
91
- "\\usepackage{geometry}": "Page layout customization",
92
- "\\usepackage{fancyhdr}": "Custom headers and footers",
93
- "\\usepackage{titlesec}": "Title formatting",
94
- "\\usepackage{hyperref}": "Hyperlinks and PDF metadata"
95
- },
96
- "Math": {
97
- "\\usepackage{amsmath}": "Enhanced math formatting",
98
- "\\usepackage{amssymb}": "Mathematical symbols",
99
- "\\usepackage{mathtools}": "Extensions to amsmath",
100
- "\\usepackage{physics}": "Physics notation"
101
- },
102
- "Graphics": {
103
- "\\usepackage{graphicx}": "Include images",
104
- "\\usepackage{tikz}": "Create vector graphics",
105
- "\\usepackage{pgfplots}": "Create plots",
106
- "\\usepackage{float}": "Better figure placement"
107
- },
108
- "Tables": {
109
- "\\usepackage{tabularx}": "Flexible tables",
110
- "\\usepackage{booktabs}": "Professional tables",
111
- "\\usepackage{colortbl}": "Colored tables",
112
- "\\usepackage{multirow}": "Multi-row cells"
113
- },
114
- "Content": {
115
- "\\usepackage{listings}": "Code syntax highlighting",
116
- "\\usepackage{minted}": "Advanced code highlighting",
117
- "\\usepackage{biblatex}": "Bibliography management",
118
- "\\usepackage{xcolor}": "Color support"
119
- }
120
- }
121
-
122
- # LaTeX commands reference
123
- latex_commands = {
124
- "Document Structure": {
125
- "\\documentclass{article}": "Specifies the type of document",
126
- "\\begin{document}": "Starts the document content",
127
- "\\end{document}": "Ends the document content",
128
- "\\title{...}": "Sets the document title",
129
- "\\author{...}": "Sets the document author",
130
- "\\date{...}": "Sets the document date",
131
- "\\maketitle": "Prints the title, author, and date"
132
- },
133
- "Sections": {
134
- "\\section{...}": "Creates a section",
135
- "\\subsection{...}": "Creates a subsection",
136
- "\\subsubsection{...}": "Creates a subsubsection",
137
- "\\paragraph{...}": "Creates a paragraph heading",
138
- "\\tableofcontents": "Generates a table of contents"
139
- },
140
- "Text Formatting": {
141
- "\\textbf{...}": "Bold text",
142
- "\\textit{...}": "Italic text",
143
- "\\underline{...}": "Underlined text",
144
- "\\emph{...}": "Emphasized text",
145
- "\\texttt{...}": "Typewriter text",
146
- "\\textsc{...}": "Small caps text",
147
- "\\textsf{...}": "Sans-serif text",
148
- "\\color{red}{...}": "Colored text (requires xcolor)"
149
- },
150
- "Math": {
151
- "$...$": "Inline math mode",
152
- "$$...$$": "Display math mode",
153
- "\\begin{equation}...\\end{equation}": "Numbered equation",
154
- "\\begin{align}...\\end{align}": "Aligned equations",
155
- "\\frac{num}{denom}": "Fraction",
156
- "\\dfrac{num}{denom}": "Display fraction",
157
- "\\sqrt{...}": "Square root",
158
- "\\sqrt[n]{...}": "nth root",
159
- "\\sum_{lower}^{upper}": "Summation",
160
- "\\prod_{lower}^{upper}": "Product",
161
- "\\int_{lower}^{upper}": "Integral",
162
- "\\lim_{x \\to value}": "Limit",
163
- "\\vec{...}": "Vector",
164
- "\\overline{...}": "Overline",
165
- "\\hat{...}": "Hat accent",
166
- "\\partial": "Partial derivative"
167
- },
168
- "Lists": {
169
- "\\begin{itemize}...\\end{itemize}": "Bulleted list",
170
- "\\begin{enumerate}...\\end{enumerate}": "Numbered list",
171
- "\\begin{description}...\\end{description}": "Description list",
172
- "\\item": "List item",
173
- "\\item[custom]": "Custom label item"
174
- },
175
- "Tables": {
176
- "\\begin{table}...\\end{table}": "Table environment",
177
- "\\begin{tabular}{cols}...\\end{tabular}": "Create a table",
178
- "\\hline": "Horizontal line in table",
179
- "\\cline{i-j}": "Partial horizontal line",
180
- "cell1 & cell2 & cell3 \\\\": "Table row",
181
- "\\multicolumn{n}{align}{content}": "Span multiple columns"
182
- },
183
- "Figures": {
184
- "\\begin{figure}...\\end{figure}": "Figure environment",
185
- "\\includegraphics[width=0.8\\textwidth]{filename}": "Include an image",
186
- "\\caption{...}": "Add a caption to a figure or table",
187
- "\\label{...}": "Add a label for cross-referencing",
188
- "\\ref{...}": "Reference a labeled item"
189
- },
190
- "Citations": {
191
- "\\cite{key}": "Citation",
192
- "\\bibliography{file}": "Bibliography source",
193
- "\\bibliographystyle{style}": "Bibliography style"
194
- }
195
- }
196
-
197
- # Flatten commands and shortcuts dictionary for autocomplete
198
- flat_commands = {}
199
- for category, commands in latex_commands.items():
200
- for cmd, desc in commands.items():
201
- cmd_parts = cmd.split("{")[0].strip() # Get just the command part
202
- flat_commands[cmd_parts] = {"full": cmd, "desc": desc, "category": category}
203
-
204
- # Add common math shortcuts
205
- math_shortcuts = {
206
- "\\fr": "\\frac{}{}",
207
- "\\eq": "\\begin{equation}\n\n\\end{equation}",
208
- "\\al": "\\begin{align}\n\n\\end{align}",
209
- "\\it": "\\item ",
210
- "\\bf": "\\textbf{}",
211
- "\\sq": "\\sqrt{}",
212
- "\\vec": "\\vec{}",
213
- "\\int": "\\int_{}^{}",
214
- "\\sum": "\\sum_{}^{}",
215
- "\\lim": "\\lim_{\\to }"
216
- }
217
-
218
  # Default LaTeX template
219
  default_template = r"""\documentclass{article}
220
  \usepackage[utf8]{inputenc}
@@ -287,252 +157,239 @@ Your conclusion here.
287
  \end{document}
288
  """
289
 
290
- # Add custom CSS with improved sidebar styling
291
  st.markdown("""
292
  <style>
293
- /* Editor styling */
294
- .editor-container {
295
- border: 1px solid #ccc;
296
- border-radius: 5px;
297
- padding: 10px;
298
- background-color: #f8f9fa;
299
- }
300
- .stTextArea textarea {
301
- font-family: 'Courier New', Courier, monospace !important;
302
  font-size: 14px !important;
303
  line-height: 1.5 !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  }
305
 
306
  /* Download button styling */
307
  .download-button {
308
  display: inline-block;
309
  padding: 0.7em 1.4em;
310
- background-color: #4CAF50;
311
  color: white !important;
312
  text-align: center;
313
  text-decoration: none;
314
- font-size: 18px;
315
- border-radius: 4px;
316
  transition: background-color 0.3s;
317
  margin-top: 10px;
318
- font-weight: bold;
319
- box-shadow: 0 2px 5px rgba(0,0,0,0.2);
320
  }
321
  .download-button:hover {
322
- background-color: #45a049;
323
- box-shadow: 0 4px 8px rgba(0,0,0,0.3);
324
  }
325
 
326
- /* Sidebar styling */
327
- .sidebar .sidebar-content {
328
- background-color: #f0f2f6;
 
 
 
 
 
 
329
  }
330
 
331
- /* LaTeX command styling */
332
- .latex-command {
333
- background-color: #e9ecef;
334
- padding: 4px 8px;
335
- border-radius: 4px;
336
- font-family: 'Courier New', Courier, monospace;
337
- color: #1e1e1e;
338
- cursor: pointer;
339
- display: inline-block;
340
- margin-bottom: 4px;
341
- border: 1px solid #ced4da;
342
- }
343
- .latex-command:hover {
344
- background-color: #d0d7de;
345
- border-color: #adb5bd;
346
  }
347
 
348
- /* Command description styling */
349
- .command-description {
350
- color: #495057;
351
- padding-left: 8px;
352
- display: inline-block;
 
353
  }
354
 
355
- /* Category title styling */
356
- .category-title {
357
- font-weight: bold;
358
- color: #212529;
359
- margin-top: 15px;
360
- margin-bottom: 8px;
361
  }
362
 
363
- /* Expander styling */
364
- .streamlit-expanderHeader {
365
- font-weight: bold;
366
- color: #212529;
367
- background-color: #e9ecef;
368
- border-radius: 4px;
369
  }
370
 
371
- /* Command list container */
372
- .command-list {
373
- background-color: #f8f9fa;
374
- border-radius: 4px;
375
- padding: 8px;
376
- border: 1px solid #dee2e6;
377
  }
378
 
379
- /* Insert button styling */
380
- .insert-button {
381
- background-color: #007bff;
382
- color: white;
383
- border: none;
384
- border-radius: 4px;
385
- padding: 2px 8px;
386
- margin-left: 8px;
387
- cursor: pointer;
388
- font-size: 12px;
389
- }
390
- .insert-button:hover {
391
- background-color: #0069d9;
392
  }
393
 
394
- /* Hint box styling */
395
- .hint-box {
396
- background-color: #f8f9fa;
397
- border: 1px solid #dee2e6;
398
- border-radius: 4px;
399
- padding: 10px;
400
- margin-top: 5px;
401
  }
402
 
403
- /* Shortcut span */
404
- .shortcut-span {
405
- background-color: #e9ecef;
406
- padding: 2px 6px;
407
- border-radius: 3px;
408
- font-family: monospace;
409
- margin-right: 10px;
410
  }
411
 
412
- /* Shortcut tip */
413
- .shortcut-tip {
414
- font-style: italic;
415
- color: #6c757d;
416
- font-size: 0.85em;
417
  }
418
  </style>
419
  """, unsafe_allow_html=True)
420
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  # Main application
422
  def main():
423
- st.title("LaTeX Editor & PDF Compiler")
 
424
 
425
  # Initialize session state
426
  if 'latex_code' not in st.session_state:
427
  st.session_state.latex_code = default_template
428
  if 'show_preview' not in st.session_state:
429
  st.session_state.show_preview = False
430
- if 'last_word' not in st.session_state:
431
- st.session_state.last_word = ""
432
 
433
  # Display installation status
434
  if not is_pdflatex_installed():
435
  st.warning("⚠️ LaTeX is not installed correctly. The PDF compilation feature will not work.")
436
- st.info("For Hugging Face Spaces, make sure you have a packages.txt file with the necessary LaTeX packages.")
437
 
438
- # Create layout
439
  col1, col2 = st.columns([3, 2])
440
 
441
  with col1:
442
- st.subheader("LaTeX Editor")
443
-
444
- # Setup autocompletion hints
445
- hint_container = st.empty()
446
-
447
- # Detect what's being typed for autocompletion
448
- current_text = st.session_state.latex_code
449
- if '\\' in current_text:
450
- # Find the last command being typed
451
- lines = current_text.split('\n')
452
- for line in reversed(lines):
453
- if '\\' in line:
454
- last_slash_pos = line.rfind('\\')
455
- command_start = line[last_slash_pos:]
456
- # Extract the command without arguments
457
- command_parts = command_start.split('{')[0].split(' ')[0].strip()
458
- if command_parts and command_parts != st.session_state.last_word:
459
- st.session_state.last_word = command_parts
460
-
461
- # Show hints for matching commands
462
- matching_commands = []
463
-
464
- # Check for shortcut matches
465
- shortcut_matches = []
466
- for shortcut, expansion in math_shortcuts.items():
467
- if shortcut.startswith(command_parts):
468
- shortcut_matches.append((shortcut, expansion))
469
-
470
- # Check for command matches
471
- command_matches = []
472
- for cmd, info in flat_commands.items():
473
- if cmd.startswith(command_parts):
474
- command_matches.append((cmd, info))
475
-
476
- # Combine shortcuts and commands
477
- matches = shortcut_matches + command_matches[:5] # Limit to top 5 commands
478
-
479
- if matches:
480
- hint_html = '<div class="hint-box"><p><strong>Suggestions:</strong></p>'
481
- for match, info in matches:
482
- if isinstance(info, dict):
483
- hint_html += f'<div><span class="shortcut-span">{match}</span> {info["desc"]}</div>'
484
- else:
485
- hint_html += f'<div><span class="shortcut-span">{match}</span> expands to <code>{info}</code></div>'
486
- hint_html += '<p class="shortcut-tip">Use the sidebar to insert full commands</p></div>'
487
- hint_container.markdown(hint_html, unsafe_allow_html=True)
488
- break
489
-
490
- # LaTeX editor
491
- latex_code = st.text_area(
492
- "Edit your LaTeX document:",
493
- value=st.session_state.latex_code,
494
- height=500,
495
- key="latex_editor"
496
- )
497
  st.session_state.latex_code = latex_code
498
 
499
- # Control buttons
500
- col1_1, col1_2, col1_3 = st.columns(3)
 
 
 
 
 
 
 
 
 
 
 
 
501
 
502
- with col1_1:
503
- if st.button("Compile PDF", use_container_width=True):
504
- st.session_state.compile_clicked = True
505
 
506
- with col1_2:
507
- if st.button("Load Template", use_container_width=True):
508
- st.session_state.latex_code = default_template
509
- st.rerun()
510
 
511
- with col1_3:
512
- if st.button("Clear Editor", use_container_width=True):
513
- st.session_state.latex_code = ""
514
- st.rerun()
515
-
516
- # Display available shortcuts
517
- with st.expander("LaTeX Shortcuts"):
518
- st.markdown("### Quick Shortcuts")
519
- for shortcut, expansion in math_shortcuts.items():
520
- st.markdown(f"<span class='shortcut-span'>{shortcut}</span> → <code>{expansion}</code>", unsafe_allow_html=True)
521
 
522
  with col2:
523
- st.subheader("PDF Output")
524
 
525
  # PDF compilation
526
  if 'compile_clicked' in st.session_state and st.session_state.compile_clicked:
527
- with st.spinner("Compiling LaTeX to PDF..."):
528
  pdf_data, stdout, stderr = latex_to_pdf(latex_code)
529
 
530
  if pdf_data:
531
  st.session_state.pdf_data = pdf_data
532
- st.success("PDF compiled successfully!")
533
 
534
  # Toggle button for preview
535
- if st.button("Show/Hide Preview", use_container_width=True):
536
  st.session_state.show_preview = not st.session_state.show_preview
537
 
538
  # Download button always available
@@ -540,25 +397,32 @@ def main():
540
 
541
  # Optional preview
542
  if st.session_state.show_preview:
 
543
  preview_images = render_pdf_preview(pdf_data)
544
  if preview_images:
545
- st.write("PDF Preview (First Pages):")
546
  for i, img in enumerate(preview_images):
547
  st.image(img, caption=f"Page {i+1}", use_container_width=True,
548
  output_format="PNG")
 
 
 
 
 
 
 
549
 
550
  st.session_state.compile_clicked = False
551
  else:
552
- st.error("Compilation Error")
553
- with st.expander("Error Details"):
554
- st.text(stdout)
555
- st.text(stderr)
556
  st.session_state.compile_clicked = False
557
 
558
  # Display previous PDF if available
559
  elif 'pdf_data' in st.session_state and st.session_state.pdf_data:
560
  # Toggle button for preview
561
- if st.button("Show/Hide Preview", use_container_width=True):
562
  st.session_state.show_preview = not st.session_state.show_preview
563
 
564
  # Download button always available
@@ -566,76 +430,15 @@ def main():
566
 
567
  # Optional preview
568
  if st.session_state.show_preview:
 
569
  preview_images = render_pdf_preview(st.session_state.pdf_data)
570
  if preview_images:
571
- st.write("PDF Preview (First Pages):")
572
  for i, img in enumerate(preview_images):
573
  st.image(img, caption=f"Page {i+1}", use_container_width=True,
574
  output_format="PNG")
575
- else:
576
- st.info("Compile your LaTeX document to generate a PDF for download")
577
-
578
- # LaTeX Reference Sidebar
579
- st.sidebar.title("LaTeX Reference")
580
-
581
- # Command search
582
- quick_search = st.sidebar.text_input("Find LaTeX Commands", "")
583
-
584
- if quick_search:
585
- # Find and display matching commands
586
- matching_cmds = []
587
- for category, commands in latex_commands.items():
588
- for cmd, desc in commands.items():
589
- cmd_without_backslash = cmd.replace("\\", "").lower()
590
- if quick_search.lower() in cmd_without_backslash:
591
- matching_cmds.append((cmd, desc, category))
592
-
593
- if matching_cmds:
594
- st.sidebar.markdown("### Matching Commands")
595
- for cmd, desc, category in matching_cmds[:15]: # Limit to 15 results
596
- col1, col2 = st.sidebar.columns([4, 1])
597
- with col1:
598
- st.markdown(f"<div><span class='latex-command'>{cmd}</span> <small>{category}</small></div>", unsafe_allow_html=True)
599
- with col2:
600
- if st.button("Insert", key=f"quick_{cmd}"):
601
- # Update LaTeX code with the inserted command
602
- st.session_state.latex_code += f"\n{cmd}"
603
- st.rerun()
604
- else:
605
- st.sidebar.info("No matching commands found")
606
-
607
- # Regular categories
608
- tab1, tab2 = st.sidebar.tabs(["Commands", "Packages"])
609
-
610
- with tab1:
611
- for category, commands in latex_commands.items():
612
- with st.expander(category, expanded=category=="Math"):
613
- st.markdown('<div class="command-list">', unsafe_allow_html=True)
614
- for cmd, desc in commands.items():
615
- col1, col2 = st.sidebar.columns([4, 1])
616
- with col1:
617
- st.markdown(f"<div><span class='latex-command'>{cmd}</span></div>", unsafe_allow_html=True)
618
- with col2:
619
- if st.button("Insert", key=f"btn_{cmd}"):
620
- # Update LaTeX code with the inserted command
621
- st.session_state.latex_code += f"\n{cmd}"
622
- st.rerun()
623
- st.markdown('</div>', unsafe_allow_html=True)
624
-
625
- with tab2:
626
- for category, packages in latex_packages.items():
627
- with st.expander(category):
628
- st.markdown('<div class="command-list">', unsafe_allow_html=True)
629
- for pkg, desc in packages.items():
630
- col1, col2 = st.sidebar.columns([4, 1])
631
- with col1:
632
- st.markdown(f"<div><span class='latex-command'>{pkg}</span></div>", unsafe_allow_html=True)
633
- with col2:
634
- if st.button("Insert", key=f"btn_{pkg}"):
635
- # Update LaTeX code with the inserted command
636
- st.session_state.latex_code += f"\n{pkg}"
637
- st.rerun()
638
  st.markdown('</div>', unsafe_allow_html=True)
 
 
639
 
640
  if __name__ == "__main__":
641
  main()
 
85
  st.error(f"Error rendering PDF preview: {str(e)}")
86
  return None
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  # Default LaTeX template
89
  default_template = r"""\documentclass{article}
90
  \usepackage[utf8]{inputenc}
 
157
  \end{document}
158
  """
159
 
160
+ # Add VS Code-like styling
161
  st.markdown("""
162
  <style>
163
+ /* VS Code-like styling */
164
+ .vscode-editor textarea {
165
+ font-family: 'Consolas', 'Monaco', 'Courier New', monospace !important;
 
 
 
 
 
 
166
  font-size: 14px !important;
167
  line-height: 1.5 !important;
168
+ background-color: #1e1e1e !important;
169
+ color: #d4d4d4 !important;
170
+ padding: 10px !important;
171
+ border-radius: 4px !important;
172
+ border: 1px solid #252526 !important;
173
+ }
174
+
175
+ /* Editor container styling */
176
+ .vscode-container {
177
+ background-color: #1e1e1e;
178
+ border-radius: 6px;
179
+ padding: 8px;
180
+ border: 1px solid #333;
181
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
182
+ }
183
+
184
+ /* Make scrollbars VS Code style */
185
+ .vscode-editor textarea::-webkit-scrollbar {
186
+ width: 14px;
187
+ height: 14px;
188
+ }
189
+
190
+ .vscode-editor textarea::-webkit-scrollbar-thumb {
191
+ background-color: #424242;
192
+ border-radius: 7px;
193
+ border: 3px solid #1e1e1e;
194
+ }
195
+
196
+ .vscode-editor textarea::-webkit-scrollbar-track {
197
+ background-color: #1e1e1e;
198
+ }
199
+
200
+ /* Button styling */
201
+ .vscode-button {
202
+ background-color: #0e639c;
203
+ color: white;
204
+ border: none;
205
+ padding: 8px 12px;
206
+ border-radius: 2px;
207
+ cursor: pointer;
208
+ font-size: 13px;
209
+ margin-right: 10px;
210
+ margin-top: 10px;
211
+ transition: background-color 0.2s;
212
+ }
213
+
214
+ .vscode-button:hover {
215
+ background-color: #1177bb;
216
  }
217
 
218
  /* Download button styling */
219
  .download-button {
220
  display: inline-block;
221
  padding: 0.7em 1.4em;
222
+ background-color: #3d995e;
223
  color: white !important;
224
  text-align: center;
225
  text-decoration: none;
226
+ font-size: 14px;
227
+ border-radius: 2px;
228
  transition: background-color 0.3s;
229
  margin-top: 10px;
230
+ font-weight: normal;
 
231
  }
232
  .download-button:hover {
233
+ background-color: #4eb772;
 
234
  }
235
 
236
+ /* Status bar styling */
237
+ .status-bar {
238
+ background-color: #007acc;
239
+ color: white;
240
+ padding: 2px 8px;
241
+ font-size: 12px;
242
+ border-radius: 2px 2px 0 0;
243
+ display: flex;
244
+ justify-content: space-between;
245
  }
246
 
247
+ /* Terminal/output styling */
248
+ .terminal-output {
249
+ background-color: #1e1e1e;
250
+ color: #cccccc;
251
+ padding: 10px;
252
+ font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
253
+ font-size: 12px;
254
+ border-radius: 0 0 4px 4px;
255
+ border-top: 1px solid #333;
256
+ max-height: 200px;
257
+ overflow-y: auto;
 
 
 
 
258
  }
259
 
260
+ /* PDF preview container */
261
+ .pdf-preview-container {
262
+ border: 1px solid #333;
263
+ border-radius: 4px;
264
+ padding: 15px;
265
+ background-color: #252526;
266
  }
267
 
268
+ /* Info and error messages */
269
+ .stInfo {
270
+ background-color: #063b49;
271
+ color: #bbbbbb;
272
+ border: 1px solid #145b6c;
 
273
  }
274
 
275
+ .stError {
276
+ background-color: #5a1d1d;
277
+ color: #bbbbbb;
278
+ border: 1px solid #6c2b2b;
 
 
279
  }
280
 
281
+ .stSuccess {
282
+ background-color: #143d27;
283
+ color: #bbbbbb;
284
+ border: 1px solid #1e5a3a;
 
 
285
  }
286
 
287
+ /* Hide Streamlit elements */
288
+ #MainMenu {visibility: hidden;}
289
+ footer {visibility: hidden;}
290
+
291
+ /* Customize the rest of Streamlit UI */
292
+ .stApp {
293
+ background-color: #252526;
 
 
 
 
 
 
294
  }
295
 
296
+ h1, h2, h3, h4, h5, h6, p, div {
297
+ color: #cccccc;
 
 
 
 
 
298
  }
299
 
300
+ .stTabs [data-baseweb="tab-list"] {
301
+ background-color: #2d2d2d;
 
 
 
 
 
302
  }
303
 
304
+ .stTabs [data-baseweb="tab"] {
305
+ color: #cccccc;
 
 
 
306
  }
307
  </style>
308
  """, unsafe_allow_html=True)
309
 
310
+ # Function to create a VS Code-like editor
311
+ def vs_code_editor(key, height=500):
312
+ editor_html = f"""
313
+ <div class="vscode-container">
314
+ <div class="status-bar">
315
+ <span>document.tex - LaTeX</span>
316
+ <span>UTF-8</span>
317
+ </div>
318
+ </div>
319
+ """
320
+ st.markdown(editor_html, unsafe_allow_html=True)
321
+
322
+ # Create the actual editor with VS Code styling
323
+ return st.text_area("", value=st.session_state.get(key, ""),
324
+ height=height, key=key, label_visibility="collapsed",
325
+ help="Type your LaTeX code here")
326
+
327
  # Main application
328
  def main():
329
+ # Set up a clean, dark theme
330
+ st.markdown("<h1 style='color: #cccccc; margin-bottom: 20px;'>LaTeX Editor</h1>", unsafe_allow_html=True)
331
 
332
  # Initialize session state
333
  if 'latex_code' not in st.session_state:
334
  st.session_state.latex_code = default_template
335
  if 'show_preview' not in st.session_state:
336
  st.session_state.show_preview = False
 
 
337
 
338
  # Display installation status
339
  if not is_pdflatex_installed():
340
  st.warning("⚠️ LaTeX is not installed correctly. The PDF compilation feature will not work.")
 
341
 
342
+ # Create layout - full width editor
343
  col1, col2 = st.columns([3, 2])
344
 
345
  with col1:
346
+ # VS Code-like editor with custom class for styling
347
+ st.markdown('<div class="vscode-editor">', unsafe_allow_html=True)
348
+ latex_code = vs_code_editor("latex_editor", height=500)
349
+ st.markdown('</div>', unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  st.session_state.latex_code = latex_code
351
 
352
+ # Control buttons with VS Code styling
353
+ st.markdown("""
354
+ <div style="display: flex; gap: 10px;">
355
+ <button class="vscode-button" onclick="document.querySelector('[data-testid=\\\"stFormSubmitButton\\\"]').click()">
356
+ Compile PDF
357
+ </button>
358
+ <button class="vscode-button" onclick="document.querySelector('[key=\\\"load_template\\\"]').click()">
359
+ Load Template
360
+ </button>
361
+ <button class="vscode-button" onclick="document.querySelector('[key=\\\"clear_editor\\\"]').click()">
362
+ Clear Editor
363
+ </button>
364
+ </div>
365
+ """, unsafe_allow_html=True)
366
 
367
+ # Hidden buttons to handle the clicks
368
+ if st.button("Compile PDF", key="compile", help="Compile LaTeX to PDF"):
369
+ st.session_state.compile_clicked = True
370
 
371
+ if st.button("Load Template", key="load_template", help="Load default template"):
372
+ st.session_state.latex_code = default_template
373
+ st.rerun()
 
374
 
375
+ if st.button("Clear Editor", key="clear_editor", help="Clear editor content"):
376
+ st.session_state.latex_code = ""
377
+ st.rerun()
 
 
 
 
 
 
 
378
 
379
  with col2:
380
+ st.markdown("<h3 style='color: #cccccc; margin-bottom: 10px;'>Output</h3>", unsafe_allow_html=True)
381
 
382
  # PDF compilation
383
  if 'compile_clicked' in st.session_state and st.session_state.compile_clicked:
384
+ with st.spinner("Compiling..."):
385
  pdf_data, stdout, stderr = latex_to_pdf(latex_code)
386
 
387
  if pdf_data:
388
  st.session_state.pdf_data = pdf_data
389
+ st.success("Compilation successful")
390
 
391
  # Toggle button for preview
392
+ if st.button("Toggle Preview", help="Show or hide the PDF preview"):
393
  st.session_state.show_preview = not st.session_state.show_preview
394
 
395
  # Download button always available
 
397
 
398
  # Optional preview
399
  if st.session_state.show_preview:
400
+ st.markdown('<div class="pdf-preview-container">', unsafe_allow_html=True)
401
  preview_images = render_pdf_preview(pdf_data)
402
  if preview_images:
 
403
  for i, img in enumerate(preview_images):
404
  st.image(img, caption=f"Page {i+1}", use_container_width=True,
405
  output_format="PNG")
406
+ st.markdown('</div>', unsafe_allow_html=True)
407
+
408
+ # Terminal output in collapsible section
409
+ with st.expander("Terminal Output"):
410
+ st.markdown('<div class="terminal-output">', unsafe_allow_html=True)
411
+ st.text(stdout)
412
+ st.markdown('</div>', unsafe_allow_html=True)
413
 
414
  st.session_state.compile_clicked = False
415
  else:
416
+ st.error("Compilation failed")
417
+ st.markdown('<div class="terminal-output">', unsafe_allow_html=True)
418
+ st.text(stderr)
419
+ st.markdown('</div>', unsafe_allow_html=True)
420
  st.session_state.compile_clicked = False
421
 
422
  # Display previous PDF if available
423
  elif 'pdf_data' in st.session_state and st.session_state.pdf_data:
424
  # Toggle button for preview
425
+ if st.button("Toggle Preview", help="Show or hide the PDF preview"):
426
  st.session_state.show_preview = not st.session_state.show_preview
427
 
428
  # Download button always available
 
430
 
431
  # Optional preview
432
  if st.session_state.show_preview:
433
+ st.markdown('<div class="pdf-preview-container">', unsafe_allow_html=True)
434
  preview_images = render_pdf_preview(st.session_state.pdf_data)
435
  if preview_images:
 
436
  for i, img in enumerate(preview_images):
437
  st.image(img, caption=f"Page {i+1}", use_container_width=True,
438
  output_format="PNG")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  st.markdown('</div>', unsafe_allow_html=True)
440
+ else:
441
+ st.info("Click 'Compile PDF' to generate output")
442
 
443
  if __name__ == "__main__":
444
  main()