shukdevdattaEX commited on
Commit
5d082a5
Β·
verified Β·
1 Parent(s): b3c58e4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -117
app.py CHANGED
@@ -10,7 +10,7 @@ import io
10
  import markdown
11
  from datetime import datetime
12
  import tempfile
13
- import weasyprint
14
  from pathlib import Path
15
 
16
  # Function to convert markdown to HTML with styling
@@ -20,27 +20,23 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
20
  html_content = markdown.markdown(markdown_text, extensions=['tables', 'fenced_code'])
21
  # Get current timestamp
22
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
23
-
24
- # Build the optional problem section (as plain text to avoid f-string parsing issues)
25
  if include_problem and problem_text.strip():
26
- problem_section = (
27
- "<div class=\"problem-section\">\n"
28
- " <h2>πŸ“ Problem Statement</h2>\n"
29
- f" <p><strong>{problem_text}</strong></p>\n"
30
- "</div>\n"
31
- )
32
  else:
33
- problem_section = ""
34
-
35
- # Use plain triple-quoted string with placeholders to avoid f-string expression parsing issues
36
- template = """<!DOCTYPE html>
37
  <html lang="en">
38
  <head>
39
  <meta charset="UTF-8">
40
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
41
  <title>Math Solution - Advanced Math Tutor</title>
42
  <style>
43
- body {
44
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
45
  line-height: 1.6;
46
  color: #333;
@@ -48,75 +44,75 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
48
  margin: 0 auto;
49
  padding: 20px;
50
  background-color: #f9f9f9;
51
- }
52
- .container {
53
  background-color: white;
54
  padding: 40px;
55
  border-radius: 10px;
56
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
57
- }
58
- .header {
59
  text-align: center;
60
  border-bottom: 3px solid #4CAF50;
61
  padding-bottom: 20px;
62
  margin-bottom: 30px;
63
- }
64
- .header h1 {
65
  color: #2c3e50;
66
  margin: 0;
67
  font-size: 2.5em;
68
- }
69
- .header .subtitle {
70
  color: #7f8c8d;
71
  font-style: italic;
72
  margin-top: 10px;
73
- }
74
- .problem-section {
75
  background-color: #e8f5e8;
76
  padding: 20px;
77
  border-radius: 8px;
78
  margin-bottom: 30px;
79
  border-left: 5px solid #4CAF50;
80
- }
81
- .problem-section h2 {
82
  color: #2c3e50;
83
  margin-top: 0;
84
- }
85
- .solution-content {
86
  background-color: #f8f9fa;
87
  padding: 25px;
88
  border-radius: 8px;
89
  border-left: 5px solid #007bff;
90
- }
91
- h1, h2, h3, h4, h5, h6 {
92
  color: #2c3e50;
93
  margin-top: 25px;
94
  margin-bottom: 15px;
95
- }
96
- h2 {
97
  border-bottom: 2px solid #eee;
98
  padding-bottom: 10px;
99
- }
100
- code {
101
  background-color: #f1f1f1;
102
  padding: 2px 6px;
103
  border-radius: 3px;
104
  font-family: 'Courier New', monospace;
105
  color: #d63384;
106
- }
107
- pre {
108
  background-color: #f8f8f8;
109
  padding: 15px;
110
  border-radius: 5px;
111
  overflow-x: auto;
112
  border: 1px solid #ddd;
113
- }
114
- pre code {
115
  background-color: transparent;
116
  padding: 0;
117
  color: inherit;
118
- }
119
- .math-expression {
120
  background-color: #fff3cd;
121
  padding: 10px;
122
  border-radius: 5px;
@@ -124,15 +120,15 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
124
  margin: 10px 0;
125
  font-family: 'Times New Roman', serif;
126
  font-size: 1.1em;
127
- }
128
- .step {
129
  margin: 20px 0;
130
  padding: 15px;
131
  background-color: #ffffff;
132
  border-radius: 8px;
133
  border: 1px solid #dee2e6;
134
- }
135
- .final-answer {
136
  background-color: #d4edda;
137
  border: 2px solid #4CAF50;
138
  padding: 20px;
@@ -141,36 +137,36 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
141
  text-align: center;
142
  font-weight: bold;
143
  font-size: 1.2em;
144
- }
145
- .timestamp {
146
  text-align: right;
147
  color: #6c757d;
148
  font-size: 0.9em;
149
  margin-top: 30px;
150
  padding-top: 20px;
151
  border-top: 1px solid #eee;
152
- }
153
- ul, ol {
154
  padding-left: 25px;
155
- }
156
- li {
157
  margin: 8px 0;
158
- }
159
- table {
160
  border-collapse: collapse;
161
  width: 100%;
162
  margin: 20px 0;
163
- }
164
- th, td {
165
  border: 1px solid #ddd;
166
  padding: 12px;
167
  text-align: left;
168
- }
169
- th {
170
  background-color: #f8f9fa;
171
  font-weight: bold;
172
- }
173
- .print-button {
174
  background-color: #007bff;
175
  color: white;
176
  border: none;
@@ -181,53 +177,53 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
181
  margin: 10px 5px;
182
  display: inline-block;
183
  text-decoration: none;
184
- }
185
- .print-button:hover {
186
  background-color: #0056b3;
187
- }
188
- @media print {
189
- body {
190
  background-color: white;
191
- }
192
- .container {
193
  box-shadow: none;
194
  border: none;
195
- }
196
- .print-button {
197
  display: none;
198
- }
199
- }
200
  </style>
201
  <script>
202
- function printPage() {
203
  window.print();
204
- }
205
  </script>
206
  <!-- MathJax Configuration -->
207
  <script>
208
- window.MathJax = {
209
- tex: {
210
  inlineMath: [['$', '$'], ['\\\\(', '\\\\)']],
211
  displayMath: [['$$', '$$'], ['\\\\[', '\\\\]']],
212
  processEscapes: true,
213
  tags: 'ams',
214
- macros: {
215
  boxed: ['\\\\fbox{\\\\,#1}', 1]
216
- }
217
- },
218
- options: {
219
  skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
220
  ignoreHtmlClass: 'tex2jax_ignore',
221
  processHtmlClass: 'tex2jax_process'
222
- },
223
- loader: {load: ['[tex]/ams', '[tex]/bbox']},
224
- startup: {
225
- ready: () => {
226
  MathJax.startup.defaultReady();
227
  MathJax.typesetPromise();
228
- }
229
- }
230
- };
231
  </script>
232
  <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
233
  </head>
@@ -238,19 +234,15 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
238
  <div class="subtitle">Step-by-Step Mathematical Solution</div>
239
  </div>
240
  <button class="print-button" onclick="printPage()">πŸ–¨οΈ Print to PDF</button>
241
- __PROBLEM_SECTION__
242
  <div class="solution-content">
243
  <h2>πŸ” Solution</h2>
244
- __HTML_CONTENT__
245
  </div>
246
- <div class="timestamp">Generated on: __TIMESTAMP__</div>
247
  </div>
248
  </body>
249
  </html>"""
250
-
251
- # Replace placeholders with actual content
252
- styled_html = template.replace("__PROBLEM_SECTION__", problem_section).replace("__HTML_CONTENT__", html_content).replace("__TIMESTAMP__", timestamp)
253
-
254
  return styled_html
255
 
256
  # Function to save HTML to file
@@ -265,20 +257,36 @@ def save_html_to_file(html_content, filename_prefix="math_solution"):
265
  f.write(html_content)
266
  return file_path
267
 
268
- # Function to convert HTML to PDF
269
  def html_to_pdf(html_content, filename_prefix="math_solution"):
270
- """Convert HTML content to PDF and return the file path"""
271
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
272
  filename = f"{filename_prefix}_{timestamp}.pdf"
273
- # Create a temporary file for PDF
274
  temp_dir = tempfile.gettempdir()
 
 
 
275
  pdf_path = os.path.join(temp_dir, filename)
276
  try:
277
- # Convert HTML to PDF using WeasyPrint
278
- weasyprint.HTML(string=html_content).write_pdf(pdf_path)
 
 
 
 
 
 
 
 
 
 
 
279
  return pdf_path
280
  except Exception as e:
281
  print(f"Error converting to PDF: {str(e)}")
 
 
282
  return None
283
 
284
  # Enhanced function to generate math solution using OpenRouter with HTML output
@@ -319,7 +327,7 @@ Do not use [ ] or code blocks for math expressions; use math delimiters instead.
319
  messages.append({"role": "user", "content": f"Solve this math problem step-by-step: {problem_text}"})
320
  # Create the completion
321
  completion = client.chat.completions.create(
322
- model="meta-llama/llama-3.3-70b-instruct:free",
323
  messages=messages,
324
  extra_headers={
325
  "HTTP-Referer": "https://advancedmathtutor.edu",
@@ -506,7 +514,6 @@ def create_demo():
506
  gr.update(value=html_file, visible=html_file is not None),
507
  gr.update(value=pdf_file, visible=pdf_file is not None)
508
  )
509
-
510
  openrouter_submit_btn.click(
511
  fn=handle_openrouter_submit,
512
  inputs=[openrouter_api_key, text_problem_input, openrouter_conversation_history],
@@ -517,7 +524,6 @@ def create_demo():
517
  openrouter_pdf_download
518
  ]
519
  )
520
-
521
  def clear_openrouter():
522
  return (
523
  "",
@@ -525,7 +531,6 @@ def create_demo():
525
  gr.update(value=None, visible=False),
526
  gr.update(value=None, visible=False)
527
  )
528
-
529
  openrouter_clear_btn.click(
530
  fn=clear_openrouter,
531
  inputs=[],
@@ -536,7 +541,6 @@ def create_demo():
536
  openrouter_pdf_download
537
  ]
538
  )
539
-
540
  # Image-based problem solver (Together AI)
541
  with gr.TabItem("Image Problem Solver (Together AI)"):
542
  with gr.Row():
@@ -583,7 +587,6 @@ def create_demo():
583
  gr.update(value=html_file, visible=html_file is not None),
584
  gr.update(value=pdf_file, visible=pdf_file is not None)
585
  )
586
-
587
  together_submit_btn.click(
588
  fn=handle_together_submit,
589
  inputs=[together_api_key, together_problem_input, together_image_input, together_conversation_history],
@@ -594,7 +597,6 @@ def create_demo():
594
  together_pdf_download
595
  ]
596
  )
597
-
598
  def clear_together():
599
  return (
600
  "",
@@ -602,7 +604,6 @@ def create_demo():
602
  gr.update(value=None, visible=False),
603
  gr.update(value=None, visible=False)
604
  )
605
-
606
  together_clear_btn.click(
607
  fn=clear_together,
608
  inputs=[],
@@ -613,7 +614,6 @@ def create_demo():
613
  together_pdf_download
614
  ]
615
  )
616
-
617
  # Help tab
618
  with gr.TabItem("Help"):
619
  gr.Markdown(
@@ -621,38 +621,36 @@ def create_demo():
621
  ### New Features πŸŽ‰
622
  - **HTML-formatted solutions**: All responses are now generated in beautiful HTML format with MathJax for proper math rendering
623
  - **Download HTML**: Download the complete solution as an HTML file (math renders perfectly)
624
- - **Download PDF**: Convert and download solutions as PDF files (note: math may appear as raw LaTeX in server-generated PDF due to limitations; use browser print for best results)
625
  - **Print functionality**: Use the "Print to PDF" button in the HTML output to print directly (renders math via MathJax)
626
-
627
  ### Getting Started
628
  #### For Text-Based Problems (OpenRouter)
629
  1. You'll need an API key from OpenRouter
630
  2. Sign up at [OpenRouter](https://openrouter.ai/) to get your API key
631
  3. Enter your API key in the designated field in the "Text Problem Solver" tab
632
-
633
  #### For Image-Based Problems (Together AI)
634
  1. You'll need an API key from Together AI
635
  2. Sign up at [Together AI](https://www.together.ai/) to get your API key
636
  3. Enter your API key in the designated field in the "Image Problem Solver" tab
637
  4. Upload an image of your math problem
638
  5. Optionally add text to provide additional context
639
-
640
  ### Solving Math Problems
641
  - For text problems: Type or paste your math problem in the input field
642
  - For image problems: Upload a clear image of the math problem
643
  - Click "Solve Problem" to get a detailed step-by-step solution in HTML format
644
  - Use the download buttons to save HTML or PDF versions
645
  - Click "Print to PDF" within the solution to print directly from your browser
646
-
647
  ### HTML Output Features
648
  - **Professional styling**: Clean, readable format with proper typography
649
  - **Mathematical expressions**: Rendered with MathJax for beautiful LaTeX support
650
  - **Step-by-step sections**: Clearly organized solution steps
651
  - **Print-friendly**: Optimized for printing and PDF conversion
652
  - **Timestamps**: Each solution includes generation timestamp
653
-
654
- **Note**: For best math rendering in PDF, open the HTML in your browser and use "Print to PDF" – this executes MathJax for perfect equations. The server-generated PDF may show raw math delimiters.
655
-
656
  ### Tips for Best Results
657
  - Be specific in your problem description
658
  - Include all necessary information
@@ -660,7 +658,7 @@ def create_demo():
660
  - For algebraic expressions, describe clearly (AI will format math properly)
661
  - Use parentheses to group terms clearly
662
  - For images, ensure the math problem is clearly visible and well-lit
663
-
664
  ### Types of Problems You Can Solve
665
  - Algebra (equations, inequalities, systems of equations)
666
  - Calculus (derivatives, integrals, limits)
@@ -669,12 +667,11 @@ def create_demo():
669
  - Statistics and Probability
670
  - Number Theory
671
  - And many more!
672
-
673
  ### Required Dependencies
674
  To run this application, you'll need to install:
675
  ```bash
676
- pip install gradio openai together pillow markdown weasyprint
677
- MathJax is loaded via CDN – no additional install needed."""
678
  )
679
  return demo
680
 
 
10
  import markdown
11
  from datetime import datetime
12
  import tempfile
13
+ from playwright.sync_api import sync_playwright
14
  from pathlib import Path
15
 
16
  # Function to convert markdown to HTML with styling
 
20
  html_content = markdown.markdown(markdown_text, extensions=['tables', 'fenced_code'])
21
  # Get current timestamp
22
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
23
+ # Prepare problem section
 
24
  if include_problem and problem_text.strip():
25
+ problem_section = f'''<div class="problem-section">
26
+ <h2>πŸ“ Problem Statement</h2>
27
+ <p><strong>{problem_text}</strong></p>
28
+ </div>'''
 
 
29
  else:
30
+ problem_section = ''
31
+ # Create styled HTML document
32
+ styled_html = f"""<!DOCTYPE html>
 
33
  <html lang="en">
34
  <head>
35
  <meta charset="UTF-8">
36
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
37
  <title>Math Solution - Advanced Math Tutor</title>
38
  <style>
39
+ body {{
40
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
41
  line-height: 1.6;
42
  color: #333;
 
44
  margin: 0 auto;
45
  padding: 20px;
46
  background-color: #f9f9f9;
47
+ }}
48
+ .container {{
49
  background-color: white;
50
  padding: 40px;
51
  border-radius: 10px;
52
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
53
+ }}
54
+ .header {{
55
  text-align: center;
56
  border-bottom: 3px solid #4CAF50;
57
  padding-bottom: 20px;
58
  margin-bottom: 30px;
59
+ }}
60
+ .header h1 {{
61
  color: #2c3e50;
62
  margin: 0;
63
  font-size: 2.5em;
64
+ }}
65
+ .header .subtitle {{
66
  color: #7f8c8d;
67
  font-style: italic;
68
  margin-top: 10px;
69
+ }}
70
+ .problem-section {{
71
  background-color: #e8f5e8;
72
  padding: 20px;
73
  border-radius: 8px;
74
  margin-bottom: 30px;
75
  border-left: 5px solid #4CAF50;
76
+ }}
77
+ .problem-section h2 {{
78
  color: #2c3e50;
79
  margin-top: 0;
80
+ }}
81
+ .solution-content {{
82
  background-color: #f8f9fa;
83
  padding: 25px;
84
  border-radius: 8px;
85
  border-left: 5px solid #007bff;
86
+ }}
87
+ h1, h2, h3, h4, h5, h6 {{
88
  color: #2c3e50;
89
  margin-top: 25px;
90
  margin-bottom: 15px;
91
+ }}
92
+ h2 {{
93
  border-bottom: 2px solid #eee;
94
  padding-bottom: 10px;
95
+ }}
96
+ code {{
97
  background-color: #f1f1f1;
98
  padding: 2px 6px;
99
  border-radius: 3px;
100
  font-family: 'Courier New', monospace;
101
  color: #d63384;
102
+ }}
103
+ pre {{
104
  background-color: #f8f8f8;
105
  padding: 15px;
106
  border-radius: 5px;
107
  overflow-x: auto;
108
  border: 1px solid #ddd;
109
+ }}
110
+ pre code {{
111
  background-color: transparent;
112
  padding: 0;
113
  color: inherit;
114
+ }}
115
+ .math-expression {{
116
  background-color: #fff3cd;
117
  padding: 10px;
118
  border-radius: 5px;
 
120
  margin: 10px 0;
121
  font-family: 'Times New Roman', serif;
122
  font-size: 1.1em;
123
+ }}
124
+ .step {{
125
  margin: 20px 0;
126
  padding: 15px;
127
  background-color: #ffffff;
128
  border-radius: 8px;
129
  border: 1px solid #dee2e6;
130
+ }}
131
+ .final-answer {{
132
  background-color: #d4edda;
133
  border: 2px solid #4CAF50;
134
  padding: 20px;
 
137
  text-align: center;
138
  font-weight: bold;
139
  font-size: 1.2em;
140
+ }}
141
+ .timestamp {{
142
  text-align: right;
143
  color: #6c757d;
144
  font-size: 0.9em;
145
  margin-top: 30px;
146
  padding-top: 20px;
147
  border-top: 1px solid #eee;
148
+ }}
149
+ ul, ol {{
150
  padding-left: 25px;
151
+ }}
152
+ li {{
153
  margin: 8px 0;
154
+ }}
155
+ table {{
156
  border-collapse: collapse;
157
  width: 100%;
158
  margin: 20px 0;
159
+ }}
160
+ th, td {{
161
  border: 1px solid #ddd;
162
  padding: 12px;
163
  text-align: left;
164
+ }}
165
+ th {{
166
  background-color: #f8f9fa;
167
  font-weight: bold;
168
+ }}
169
+ .print-button {{
170
  background-color: #007bff;
171
  color: white;
172
  border: none;
 
177
  margin: 10px 5px;
178
  display: inline-block;
179
  text-decoration: none;
180
+ }}
181
+ .print-button:hover {{
182
  background-color: #0056b3;
183
+ }}
184
+ @media print {{
185
+ body {{
186
  background-color: white;
187
+ }}
188
+ .container {{
189
  box-shadow: none;
190
  border: none;
191
+ }}
192
+ .print-button {{
193
  display: none;
194
+ }}
195
+ }}
196
  </style>
197
  <script>
198
+ function printPage() {{
199
  window.print();
200
+ }}
201
  </script>
202
  <!-- MathJax Configuration -->
203
  <script>
204
+ window.MathJax = {{
205
+ tex: {{
206
  inlineMath: [['$', '$'], ['\\\\(', '\\\\)']],
207
  displayMath: [['$$', '$$'], ['\\\\[', '\\\\]']],
208
  processEscapes: true,
209
  tags: 'ams',
210
+ macros: {{
211
  boxed: ['\\\\fbox{\\\\,#1}', 1]
212
+ }}
213
+ }},
214
+ options: {{
215
  skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
216
  ignoreHtmlClass: 'tex2jax_ignore',
217
  processHtmlClass: 'tex2jax_process'
218
+ }},
219
+ loader: {{load: ['[tex]/ams', '[tex]/bbox']}},
220
+ startup: {{
221
+ ready: () => {{
222
  MathJax.startup.defaultReady();
223
  MathJax.typesetPromise();
224
+ }}
225
+ }}
226
+ }};
227
  </script>
228
  <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
229
  </head>
 
234
  <div class="subtitle">Step-by-Step Mathematical Solution</div>
235
  </div>
236
  <button class="print-button" onclick="printPage()">πŸ–¨οΈ Print to PDF</button>
237
+ {problem_section}
238
  <div class="solution-content">
239
  <h2>πŸ” Solution</h2>
240
+ {html_content}
241
  </div>
242
+ <div class="timestamp">Generated on: {timestamp}</div>
243
  </div>
244
  </body>
245
  </html>"""
 
 
 
 
246
  return styled_html
247
 
248
  # Function to save HTML to file
 
257
  f.write(html_content)
258
  return file_path
259
 
260
+ # Function to convert HTML to PDF using Playwright
261
  def html_to_pdf(html_content, filename_prefix="math_solution"):
262
+ """Convert HTML content to PDF using Playwright for MathJax rendering and return the file path"""
263
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
264
  filename = f"{filename_prefix}_{timestamp}.pdf"
265
+ # Create a temporary file for HTML
266
  temp_dir = tempfile.gettempdir()
267
+ html_path = os.path.join(temp_dir, f"{filename_prefix}_{timestamp}.html")
268
+ with open(html_path, 'w', encoding='utf-8') as f:
269
+ f.write(html_content)
270
  pdf_path = os.path.join(temp_dir, filename)
271
  try:
272
+ with sync_playwright() as p:
273
+ browser = p.chromium.launch(headless=True)
274
+ page = browser.new_page()
275
+ page.goto(f"file://{os.path.abspath(html_path)}")
276
+ # Wait for MathJax to fully render
277
+ page.wait_for_function(
278
+ "MathJax.tex2chtmlPromise ? MathJax.typesetPromise().then(() => true) : true",
279
+ timeout=30000
280
+ )
281
+ page.pdf(path=pdf_path, format='A4', print_background=True)
282
+ browser.close()
283
+ # Clean up HTML file
284
+ os.remove(html_path)
285
  return pdf_path
286
  except Exception as e:
287
  print(f"Error converting to PDF: {str(e)}")
288
+ if os.path.exists(html_path):
289
+ os.remove(html_path)
290
  return None
291
 
292
  # Enhanced function to generate math solution using OpenRouter with HTML output
 
327
  messages.append({"role": "user", "content": f"Solve this math problem step-by-step: {problem_text}"})
328
  # Create the completion
329
  completion = client.chat.completions.create(
330
+ model="deepseek/deepseek-r1-0528:free",
331
  messages=messages,
332
  extra_headers={
333
  "HTTP-Referer": "https://advancedmathtutor.edu",
 
514
  gr.update(value=html_file, visible=html_file is not None),
515
  gr.update(value=pdf_file, visible=pdf_file is not None)
516
  )
 
517
  openrouter_submit_btn.click(
518
  fn=handle_openrouter_submit,
519
  inputs=[openrouter_api_key, text_problem_input, openrouter_conversation_history],
 
524
  openrouter_pdf_download
525
  ]
526
  )
 
527
  def clear_openrouter():
528
  return (
529
  "",
 
531
  gr.update(value=None, visible=False),
532
  gr.update(value=None, visible=False)
533
  )
 
534
  openrouter_clear_btn.click(
535
  fn=clear_openrouter,
536
  inputs=[],
 
541
  openrouter_pdf_download
542
  ]
543
  )
 
544
  # Image-based problem solver (Together AI)
545
  with gr.TabItem("Image Problem Solver (Together AI)"):
546
  with gr.Row():
 
587
  gr.update(value=html_file, visible=html_file is not None),
588
  gr.update(value=pdf_file, visible=pdf_file is not None)
589
  )
 
590
  together_submit_btn.click(
591
  fn=handle_together_submit,
592
  inputs=[together_api_key, together_problem_input, together_image_input, together_conversation_history],
 
597
  together_pdf_download
598
  ]
599
  )
 
600
  def clear_together():
601
  return (
602
  "",
 
604
  gr.update(value=None, visible=False),
605
  gr.update(value=None, visible=False)
606
  )
 
607
  together_clear_btn.click(
608
  fn=clear_together,
609
  inputs=[],
 
614
  together_pdf_download
615
  ]
616
  )
 
617
  # Help tab
618
  with gr.TabItem("Help"):
619
  gr.Markdown(
 
621
  ### New Features πŸŽ‰
622
  - **HTML-formatted solutions**: All responses are now generated in beautiful HTML format with MathJax for proper math rendering
623
  - **Download HTML**: Download the complete solution as an HTML file (math renders perfectly)
624
+ - **Download PDF**: Convert and download solutions as PDF files (math rendered via browser for perfect equations)
625
  - **Print functionality**: Use the "Print to PDF" button in the HTML output to print directly (renders math via MathJax)
626
+
627
  ### Getting Started
628
  #### For Text-Based Problems (OpenRouter)
629
  1. You'll need an API key from OpenRouter
630
  2. Sign up at [OpenRouter](https://openrouter.ai/) to get your API key
631
  3. Enter your API key in the designated field in the "Text Problem Solver" tab
632
+
633
  #### For Image-Based Problems (Together AI)
634
  1. You'll need an API key from Together AI
635
  2. Sign up at [Together AI](https://www.together.ai/) to get your API key
636
  3. Enter your API key in the designated field in the "Image Problem Solver" tab
637
  4. Upload an image of your math problem
638
  5. Optionally add text to provide additional context
639
+
640
  ### Solving Math Problems
641
  - For text problems: Type or paste your math problem in the input field
642
  - For image problems: Upload a clear image of the math problem
643
  - Click "Solve Problem" to get a detailed step-by-step solution in HTML format
644
  - Use the download buttons to save HTML or PDF versions
645
  - Click "Print to PDF" within the solution to print directly from your browser
646
+
647
  ### HTML Output Features
648
  - **Professional styling**: Clean, readable format with proper typography
649
  - **Mathematical expressions**: Rendered with MathJax for beautiful LaTeX support
650
  - **Step-by-step sections**: Clearly organized solution steps
651
  - **Print-friendly**: Optimized for printing and PDF conversion
652
  - **Timestamps**: Each solution includes generation timestamp
653
+
 
 
654
  ### Tips for Best Results
655
  - Be specific in your problem description
656
  - Include all necessary information
 
658
  - For algebraic expressions, describe clearly (AI will format math properly)
659
  - Use parentheses to group terms clearly
660
  - For images, ensure the math problem is clearly visible and well-lit
661
+
662
  ### Types of Problems You Can Solve
663
  - Algebra (equations, inequalities, systems of equations)
664
  - Calculus (derivatives, integrals, limits)
 
667
  - Statistics and Probability
668
  - Number Theory
669
  - And many more!
670
+
671
  ### Required Dependencies
672
  To run this application, you'll need to install:
673
  ```bash
674
+ pip install gradio openai together pillow markdown playwright
 
675
  )
676
  return demo
677