euler314 commited on
Commit
e6742d7
·
verified ·
1 Parent(s): f59c14c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -30
app.py CHANGED
@@ -5,6 +5,7 @@ import base64
5
  from pathlib import Path
6
  import os
7
  import shutil
 
8
 
9
  # Set page configuration
10
  st.set_page_config(page_title="LaTeX Editor & Compiler", page_icon="📝", layout="wide")
@@ -21,8 +22,6 @@ def latex_to_pdf(latex_code):
21
  st.code(f"PATH: {os.environ.get('PATH')}")
22
  result = subprocess.run(["which", "pdflatex"], capture_output=True, text=True)
23
  st.code(f"which pdflatex: {result.stdout} {result.stderr}")
24
- result = subprocess.run(["ls", "-la", "/usr/bin/pdflatex"], capture_output=True, text=True)
25
- st.code(f"ls -la /usr/bin/pdflatex: {result.stdout} {result.stderr}")
26
  return None, "", "Error: pdflatex is not installed or not in PATH."
27
 
28
  with tempfile.TemporaryDirectory() as temp_dir:
@@ -52,24 +51,30 @@ def latex_to_pdf(latex_code):
52
  except Exception as e:
53
  return None, "", str(e)
54
 
55
- # Function to display PDF
56
- def display_pdf(pdf_data):
57
- base64_pdf = base64.b64encode(pdf_data).decode('utf-8')
58
- pdf_display = f"""
59
- <iframe
60
- src="data:application/pdf;base64,{base64_pdf}"
61
- width="100%"
62
- height="600"
63
- style="border: none;"
64
- ></iframe>
65
- """
66
- st.markdown(pdf_display, unsafe_allow_html=True)
67
-
68
  # Function to create download link for PDF
69
  def get_download_link(pdf_data, filename="document.pdf"):
70
  b64_pdf = base64.b64encode(pdf_data).decode()
71
  return f'<a href="data:application/pdf;base64,{b64_pdf}" download="{filename}" class="download-button">Download PDF</a>'
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  # LaTeX package reference
74
  latex_packages = {
75
  "Document": {
@@ -262,18 +267,21 @@ st.markdown("""
262
  }
263
  .download-button {
264
  display: inline-block;
265
- padding: 0.5em 1em;
266
  background-color: #4CAF50;
267
  color: white !important;
268
  text-align: center;
269
  text-decoration: none;
270
- font-size: 16px;
271
  border-radius: 4px;
272
  transition: background-color 0.3s;
273
  margin-top: 10px;
 
 
274
  }
275
  .download-button:hover {
276
  background-color: #45a049;
 
277
  }
278
  .stTextArea textarea {
279
  font-family: 'Courier New', Courier, monospace !important;
@@ -302,6 +310,29 @@ st.markdown("""
302
  </style>
303
  """, unsafe_allow_html=True)
304
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  # Main application
306
  def main():
307
  st.title("LaTeX Editor & PDF Compiler")
@@ -310,8 +341,13 @@ def main():
310
  if not is_pdflatex_installed():
311
  st.warning("⚠️ LaTeX is not installed correctly. The PDF compilation feature will not work.")
312
  st.info("For Hugging Face Spaces, make sure you have a packages.txt file with the necessary LaTeX packages.")
313
- else:
314
- st.success("✅ LaTeX is installed and ready to use!")
 
 
 
 
 
315
 
316
  # Create layout with sidebar
317
  col1, col2 = st.columns([3, 2])
@@ -350,19 +386,17 @@ def main():
350
  st.rerun()
351
 
352
  with col2:
353
- st.subheader("PDF Preview")
354
 
355
- # PDF preview
356
  if 'compile_clicked' in st.session_state and st.session_state.compile_clicked:
357
  with st.spinner("Compiling LaTeX to PDF..."):
358
  pdf_data, stdout, stderr = latex_to_pdf(latex_code)
359
 
360
  if pdf_data:
361
  st.session_state.pdf_data = pdf_data
362
- display_pdf(pdf_data)
363
-
364
- # Download button
365
- st.markdown(get_download_link(pdf_data), unsafe_allow_html=True)
366
  st.session_state.compile_clicked = False
367
  else:
368
  st.error("Compilation Error")
@@ -373,10 +407,9 @@ def main():
373
 
374
  # Display previous PDF if available
375
  elif 'pdf_data' in st.session_state and st.session_state.pdf_data:
376
- display_pdf(st.session_state.pdf_data)
377
- st.markdown(get_download_link(st.session_state.pdf_data), unsafe_allow_html=True)
378
  else:
379
- st.info("Compile your LaTeX document to see the PDF preview")
380
 
381
  # LaTeX Reference Sidebar
382
  st.sidebar.title("LaTeX Reference")
@@ -397,7 +430,12 @@ def main():
397
  found = True
398
  with st.sidebar.expander(f"{category} ({len(filtered_commands)} results)"):
399
  for cmd, desc in filtered_commands.items():
400
- st.markdown(f"<div class='latex-command' onclick=\"copyToEditor('{cmd}')\">{cmd}</div> - {desc}", unsafe_allow_html=True)
 
 
 
 
 
401
 
402
  # Search packages
403
  for category, packages in latex_packages.items():
@@ -408,7 +446,11 @@ def main():
408
  found = True
409
  with st.sidebar.expander(f"Packages: {category} ({len(filtered_packages)} results)"):
410
  for pkg, desc in filtered_packages.items():
411
- st.markdown(f"<div class='latex-command' onclick=\"copyToEditor('{pkg}')\">{pkg}</div> - {desc}", unsafe_allow_html=True)
 
 
 
 
412
 
413
  if not found:
414
  st.sidebar.info("No matching commands or packages found")
@@ -422,12 +464,18 @@ def main():
422
  with st.expander(category):
423
  for cmd, desc in commands.items():
424
  st.markdown(f"<div class='latex-command'>{cmd}</div> - {desc}", unsafe_allow_html=True)
 
 
 
425
 
426
  with tabs[1]:
427
  for category, packages in latex_packages.items():
428
  with st.expander(category):
429
  for pkg, desc in packages.items():
430
  st.markdown(f"<div class='latex-command'>{pkg}</div> - {desc}", unsafe_allow_html=True)
 
 
 
431
 
432
  if __name__ == "__main__":
433
  main()
 
5
  from pathlib import Path
6
  import os
7
  import shutil
8
+ import time
9
 
10
  # Set page configuration
11
  st.set_page_config(page_title="LaTeX Editor & Compiler", page_icon="📝", layout="wide")
 
22
  st.code(f"PATH: {os.environ.get('PATH')}")
23
  result = subprocess.run(["which", "pdflatex"], capture_output=True, text=True)
24
  st.code(f"which pdflatex: {result.stdout} {result.stderr}")
 
 
25
  return None, "", "Error: pdflatex is not installed or not in PATH."
26
 
27
  with tempfile.TemporaryDirectory() as temp_dir:
 
51
  except Exception as e:
52
  return None, "", str(e)
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  # Function to create download link for PDF
55
  def get_download_link(pdf_data, filename="document.pdf"):
56
  b64_pdf = base64.b64encode(pdf_data).decode()
57
  return f'<a href="data:application/pdf;base64,{b64_pdf}" download="{filename}" class="download-button">Download PDF</a>'
58
 
59
+ # Convert PDF to images for preview (safer than embedding PDF)
60
+ def pdf_preview(pdf_data):
61
+ # Save PDF to a temporary file
62
+ if not pdf_data:
63
+ return st.error("No PDF data to preview")
64
+
65
+ st.warning("PDF preview is not available due to browser security restrictions.")
66
+ st.info("Please download the PDF using the button below to view it.")
67
+
68
+ # Provide download button with more prominent styling
69
+ st.markdown(
70
+ f"""
71
+ <div style="text-align: center; margin: 30px 0;">
72
+ {get_download_link(pdf_data)}
73
+ </div>
74
+ """,
75
+ unsafe_allow_html=True
76
+ )
77
+
78
  # LaTeX package reference
79
  latex_packages = {
80
  "Document": {
 
267
  }
268
  .download-button {
269
  display: inline-block;
270
+ padding: 0.7em 1.4em;
271
  background-color: #4CAF50;
272
  color: white !important;
273
  text-align: center;
274
  text-decoration: none;
275
+ font-size: 18px;
276
  border-radius: 4px;
277
  transition: background-color 0.3s;
278
  margin-top: 10px;
279
+ font-weight: bold;
280
+ box-shadow: 0 2px 5px rgba(0,0,0,0.2);
281
  }
282
  .download-button:hover {
283
  background-color: #45a049;
284
+ box-shadow: 0 4px 8px rgba(0,0,0,0.3);
285
  }
286
  .stTextArea textarea {
287
  font-family: 'Courier New', Courier, monospace !important;
 
310
  </style>
311
  """, unsafe_allow_html=True)
312
 
313
+ # JavaScript for copying commands (optional, may not work in all environments)
314
+ st.markdown("""
315
+ <script>
316
+ document.addEventListener('DOMContentLoaded', (event) => {
317
+ // Add click handlers to copy LaTeX commands
318
+ document.querySelectorAll('.latex-command').forEach(element => {
319
+ element.addEventListener('click', function() {
320
+ const textToCopy = this.textContent;
321
+ const textArea = document.querySelector('.stTextArea textarea');
322
+ if (textArea) {
323
+ const start = textArea.selectionStart;
324
+ const end = textArea.selectionEnd;
325
+ const value = textArea.value;
326
+ textArea.value = value.substring(0, start) + textToCopy + value.substring(end);
327
+ textArea.selectionStart = textArea.selectionEnd = start + textToCopy.length;
328
+ textArea.focus();
329
+ }
330
+ });
331
+ });
332
+ });
333
+ </script>
334
+ """, unsafe_allow_html=True)
335
+
336
  # Main application
337
  def main():
338
  st.title("LaTeX Editor & PDF Compiler")
 
341
  if not is_pdflatex_installed():
342
  st.warning("⚠️ LaTeX is not installed correctly. The PDF compilation feature will not work.")
343
  st.info("For Hugging Face Spaces, make sure you have a packages.txt file with the necessary LaTeX packages.")
344
+
345
+ # Show packages.txt content suggestion
346
+ with st.expander("Required packages.txt content"):
347
+ st.code("""texlive
348
+ texlive-latex-extra
349
+ texlive-fonts-recommended
350
+ texlive-science""", language="text")
351
 
352
  # Create layout with sidebar
353
  col1, col2 = st.columns([3, 2])
 
386
  st.rerun()
387
 
388
  with col2:
389
+ st.subheader("PDF Output")
390
 
391
+ # PDF compilation and download
392
  if 'compile_clicked' in st.session_state and st.session_state.compile_clicked:
393
  with st.spinner("Compiling LaTeX to PDF..."):
394
  pdf_data, stdout, stderr = latex_to_pdf(latex_code)
395
 
396
  if pdf_data:
397
  st.session_state.pdf_data = pdf_data
398
+ st.success("PDF compiled successfully!")
399
+ pdf_preview(pdf_data)
 
 
400
  st.session_state.compile_clicked = False
401
  else:
402
  st.error("Compilation Error")
 
407
 
408
  # Display previous PDF if available
409
  elif 'pdf_data' in st.session_state and st.session_state.pdf_data:
410
+ pdf_preview(st.session_state.pdf_data)
 
411
  else:
412
+ st.info("Compile your LaTeX document to generate a PDF for download")
413
 
414
  # LaTeX Reference Sidebar
415
  st.sidebar.title("LaTeX Reference")
 
430
  found = True
431
  with st.sidebar.expander(f"{category} ({len(filtered_commands)} results)"):
432
  for cmd, desc in filtered_commands.items():
433
+ cmd_display = cmd.replace("\\", "\\\\") # Escape backslashes for display
434
+ st.markdown(f"<div class='latex-command' title='Click to copy'>{cmd}</div> - {desc}", unsafe_allow_html=True)
435
+ if st.button(f"Insert '{cmd}'", key=f"btn_{cmd}"):
436
+ # Insert at cursor not supported directly, but we can append
437
+ st.session_state.latex_code += f"\n{cmd}"
438
+ st.rerun()
439
 
440
  # Search packages
441
  for category, packages in latex_packages.items():
 
446
  found = True
447
  with st.sidebar.expander(f"Packages: {category} ({len(filtered_packages)} results)"):
448
  for pkg, desc in filtered_packages.items():
449
+ pkg_display = pkg.replace("\\", "\\\\") # Escape backslashes for display
450
+ st.markdown(f"<div class='latex-command' title='Click to copy'>{pkg}</div> - {desc}", unsafe_allow_html=True)
451
+ if st.button(f"Insert '{pkg}'", key=f"btn_{pkg}"):
452
+ st.session_state.latex_code += f"\n{pkg}"
453
+ st.rerun()
454
 
455
  if not found:
456
  st.sidebar.info("No matching commands or packages found")
 
464
  with st.expander(category):
465
  for cmd, desc in commands.items():
466
  st.markdown(f"<div class='latex-command'>{cmd}</div> - {desc}", unsafe_allow_html=True)
467
+ if st.button(f"Insert '{cmd}'", key=f"btn_{cmd}"):
468
+ st.session_state.latex_code += f"\n{cmd}"
469
+ st.rerun()
470
 
471
  with tabs[1]:
472
  for category, packages in latex_packages.items():
473
  with st.expander(category):
474
  for pkg, desc in packages.items():
475
  st.markdown(f"<div class='latex-command'>{pkg}</div> - {desc}", unsafe_allow_html=True)
476
+ if st.button(f"Insert '{pkg}'", key=f"btn_{pkg}"):
477
+ st.session_state.latex_code += f"\n{pkg}"
478
+ st.rerun()
479
 
480
  if __name__ == "__main__":
481
  main()