shukdevdattaEX commited on
Commit
23ff77e
Β·
verified Β·
1 Parent(s): 1ec950d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +118 -94
app.py CHANGED
@@ -12,6 +12,7 @@ from datetime import datetime
12
  import tempfile
13
  import weasyprint
14
  from pathlib import Path
 
15
  # Function to convert markdown to HTML with styling
16
  def markdown_to_html(markdown_text, problem_text="", include_problem=True):
17
  """Convert markdown to styled HTML"""
@@ -19,23 +20,27 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
19
  html_content = markdown.markdown(markdown_text, extensions=['tables', 'fenced_code'])
20
  # Get current timestamp
21
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
22
- # Prepare problem section
 
23
  if include_problem and problem_text.strip():
24
- problem_section = f'''<div class="problem-section">
25
- <h2>πŸ“ Problem Statement</h2>
26
- <p><strong>{problem_text}</strong></p>
27
- </div>'''
 
 
28
  else:
29
- problem_section = ''
30
- # Create styled HTML document
31
- styled_html = f"""<!DOCTYPE html>
 
32
  <html lang="en">
33
  <head>
34
  <meta charset="UTF-8">
35
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
36
  <title>Math Solution - Advanced Math Tutor</title>
37
  <style>
38
- body {{
39
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
40
  line-height: 1.6;
41
  color: #333;
@@ -43,75 +48,75 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
43
  margin: 0 auto;
44
  padding: 20px;
45
  background-color: #f9f9f9;
46
- }}
47
- .container {{
48
  background-color: white;
49
  padding: 40px;
50
  border-radius: 10px;
51
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
52
- }}
53
- .header {{
54
  text-align: center;
55
  border-bottom: 3px solid #4CAF50;
56
  padding-bottom: 20px;
57
  margin-bottom: 30px;
58
- }}
59
- .header h1 {{
60
  color: #2c3e50;
61
  margin: 0;
62
  font-size: 2.5em;
63
- }}
64
- .header .subtitle {{
65
  color: #7f8c8d;
66
  font-style: italic;
67
  margin-top: 10px;
68
- }}
69
- .problem-section {{
70
  background-color: #e8f5e8;
71
  padding: 20px;
72
  border-radius: 8px;
73
  margin-bottom: 30px;
74
  border-left: 5px solid #4CAF50;
75
- }}
76
- .problem-section h2 {{
77
  color: #2c3e50;
78
  margin-top: 0;
79
- }}
80
- .solution-content {{
81
  background-color: #f8f9fa;
82
  padding: 25px;
83
  border-radius: 8px;
84
  border-left: 5px solid #007bff;
85
- }}
86
- h1, h2, h3, h4, h5, h6 {{
87
  color: #2c3e50;
88
  margin-top: 25px;
89
  margin-bottom: 15px;
90
- }}
91
- h2 {{
92
  border-bottom: 2px solid #eee;
93
  padding-bottom: 10px;
94
- }}
95
- code {{
96
  background-color: #f1f1f1;
97
  padding: 2px 6px;
98
  border-radius: 3px;
99
  font-family: 'Courier New', monospace;
100
  color: #d63384;
101
- }}
102
- pre {{
103
  background-color: #f8f8f8;
104
  padding: 15px;
105
  border-radius: 5px;
106
  overflow-x: auto;
107
  border: 1px solid #ddd;
108
- }}
109
- pre code {{
110
  background-color: transparent;
111
  padding: 0;
112
  color: inherit;
113
- }}
114
- .math-expression {{
115
  background-color: #fff3cd;
116
  padding: 10px;
117
  border-radius: 5px;
@@ -119,15 +124,15 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
119
  margin: 10px 0;
120
  font-family: 'Times New Roman', serif;
121
  font-size: 1.1em;
122
- }}
123
- .step {{
124
  margin: 20px 0;
125
  padding: 15px;
126
  background-color: #ffffff;
127
  border-radius: 8px;
128
  border: 1px solid #dee2e6;
129
- }}
130
- .final-answer {{
131
  background-color: #d4edda;
132
  border: 2px solid #4CAF50;
133
  padding: 20px;
@@ -136,36 +141,36 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
136
  text-align: center;
137
  font-weight: bold;
138
  font-size: 1.2em;
139
- }}
140
- .timestamp {{
141
  text-align: right;
142
  color: #6c757d;
143
  font-size: 0.9em;
144
  margin-top: 30px;
145
  padding-top: 20px;
146
  border-top: 1px solid #eee;
147
- }}
148
- ul, ol {{
149
  padding-left: 25px;
150
- }}
151
- li {{
152
  margin: 8px 0;
153
- }}
154
- table {{
155
  border-collapse: collapse;
156
  width: 100%;
157
  margin: 20px 0;
158
- }}
159
- th, td {{
160
  border: 1px solid #ddd;
161
  padding: 12px;
162
  text-align: left;
163
- }}
164
- th {{
165
  background-color: #f8f9fa;
166
  font-weight: bold;
167
- }}
168
- .print-button {{
169
  background-color: #007bff;
170
  color: white;
171
  border: none;
@@ -176,53 +181,53 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
176
  margin: 10px 5px;
177
  display: inline-block;
178
  text-decoration: none;
179
- }}
180
- .print-button:hover {{
181
  background-color: #0056b3;
182
- }}
183
- @media print {{
184
- body {{
185
  background-color: white;
186
- }}
187
- .container {{
188
  box-shadow: none;
189
  border: none;
190
- }}
191
- .print-button {{
192
  display: none;
193
- }}
194
- }}
195
  </style>
196
  <script>
197
- function printPage() {{
198
  window.print();
199
- }}
200
  </script>
201
  <!-- MathJax Configuration -->
202
  <script>
203
- window.MathJax = {{
204
- tex: {{
205
  inlineMath: [['$', '$'], ['\\\\(', '\\\\)']],
206
  displayMath: [['$$', '$$'], ['\\\\[', '\\\\]']],
207
  processEscapes: true,
208
  tags: 'ams',
209
- macros: {{
210
  boxed: ['\\\\fbox{\\\\,#1}', 1]
211
- }}
212
- }},
213
- options: {{
214
  skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
215
  ignoreHtmlClass: 'tex2jax_ignore',
216
  processHtmlClass: 'tex2jax_process'
217
- }},
218
- loader: {{load: ['[tex]/ams', '[tex]/bbox']}},
219
- startup: {{
220
- ready: () => {{
221
  MathJax.startup.defaultReady();
222
  MathJax.typesetPromise();
223
- }}
224
- }}
225
- }};
226
  </script>
227
  <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
228
  </head>
@@ -233,16 +238,21 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
233
  <div class="subtitle">Step-by-Step Mathematical Solution</div>
234
  </div>
235
  <button class="print-button" onclick="printPage()">πŸ–¨οΈ Print to PDF</button>
236
- {problem_section}
237
  <div class="solution-content">
238
  <h2>πŸ” Solution</h2>
239
- {html_content}
240
  </div>
241
- <div class="timestamp">Generated on: {timestamp}</div>
242
  </div>
243
  </body>
244
  </html>"""
 
 
 
 
245
  return styled_html
 
246
  # Function to save HTML to file
247
  def save_html_to_file(html_content, filename_prefix="math_solution"):
248
  """Save HTML content to a temporary file and return the file path"""
@@ -254,6 +264,7 @@ def save_html_to_file(html_content, filename_prefix="math_solution"):
254
  with open(file_path, 'w', encoding='utf-8') as f:
255
  f.write(html_content)
256
  return file_path
 
257
  # Function to convert HTML to PDF
258
  def html_to_pdf(html_content, filename_prefix="math_solution"):
259
  """Convert HTML content to PDF and return the file path"""
@@ -269,6 +280,7 @@ def html_to_pdf(html_content, filename_prefix="math_solution"):
269
  except Exception as e:
270
  print(f"Error converting to PDF: {str(e)}")
271
  return None
 
272
  # Enhanced function to generate math solution using OpenRouter with HTML output
273
  def generate_math_solution_openrouter(api_key, problem_text, history=None):
274
  if not api_key.strip():
@@ -329,6 +341,7 @@ Do not use [ ] or code blocks for math expressions; use math delimiters instead.
329
  except Exception as e:
330
  error_message = f"Error: {str(e)}"
331
  return error_message, None, None, history
 
332
  # Enhanced function to generate math solution using Together AI with HTML output
333
  def generate_math_solution_together(api_key, problem_text, image_path=None, history=None):
334
  if not api_key.strip():
@@ -420,6 +433,7 @@ Do not use [ ] or code blocks for math expressions; use math delimiters instead.
420
  except Exception as e:
421
  error_message = f"Error: {str(e)}"
422
  return error_message, None, None, history
 
423
  # Function to convert image to base64
424
  def image_to_base64(image_path):
425
  if image_path is None:
@@ -430,6 +444,7 @@ def image_to_base64(image_path):
430
  except Exception as e:
431
  print(f"Error converting image to base64: {str(e)}")
432
  return None
 
433
  # Define the Gradio interface
434
  def create_demo():
435
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as demo:
@@ -491,6 +506,7 @@ def create_demo():
491
  gr.update(value=html_file, visible=html_file is not None),
492
  gr.update(value=pdf_file, visible=pdf_file is not None)
493
  )
 
494
  openrouter_submit_btn.click(
495
  fn=handle_openrouter_submit,
496
  inputs=[openrouter_api_key, text_problem_input, openrouter_conversation_history],
@@ -501,6 +517,7 @@ def create_demo():
501
  openrouter_pdf_download
502
  ]
503
  )
 
504
  def clear_openrouter():
505
  return (
506
  "",
@@ -508,6 +525,7 @@ def create_demo():
508
  gr.update(value=None, visible=False),
509
  gr.update(value=None, visible=False)
510
  )
 
511
  openrouter_clear_btn.click(
512
  fn=clear_openrouter,
513
  inputs=[],
@@ -518,6 +536,7 @@ def create_demo():
518
  openrouter_pdf_download
519
  ]
520
  )
 
521
  # Image-based problem solver (Together AI)
522
  with gr.TabItem("Image Problem Solver (Together AI)"):
523
  with gr.Row():
@@ -564,6 +583,7 @@ def create_demo():
564
  gr.update(value=html_file, visible=html_file is not None),
565
  gr.update(value=pdf_file, visible=pdf_file is not None)
566
  )
 
567
  together_submit_btn.click(
568
  fn=handle_together_submit,
569
  inputs=[together_api_key, together_problem_input, together_image_input, together_conversation_history],
@@ -574,6 +594,7 @@ def create_demo():
574
  together_pdf_download
575
  ]
576
  )
 
577
  def clear_together():
578
  return (
579
  "",
@@ -581,6 +602,7 @@ def create_demo():
581
  gr.update(value=None, visible=False),
582
  gr.update(value=None, visible=False)
583
  )
 
584
  together_clear_btn.click(
585
  fn=clear_together,
586
  inputs=[],
@@ -591,6 +613,7 @@ def create_demo():
591
  together_pdf_download
592
  ]
593
  )
 
594
  # Help tab
595
  with gr.TabItem("Help"):
596
  gr.Markdown(
@@ -600,36 +623,36 @@ def create_demo():
600
  - **Download HTML**: Download the complete solution as an HTML file (math renders perfectly)
601
  - **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)
602
  - **Print functionality**: Use the "Print to PDF" button in the HTML output to print directly (renders math via MathJax)
603
-
604
  ### Getting Started
605
  #### For Text-Based Problems (OpenRouter)
606
  1. You'll need an API key from OpenRouter
607
  2. Sign up at [OpenRouter](https://openrouter.ai/) to get your API key
608
  3. Enter your API key in the designated field in the "Text Problem Solver" tab
609
-
610
  #### For Image-Based Problems (Together AI)
611
  1. You'll need an API key from Together AI
612
  2. Sign up at [Together AI](https://www.together.ai/) to get your API key
613
  3. Enter your API key in the designated field in the "Image Problem Solver" tab
614
  4. Upload an image of your math problem
615
  5. Optionally add text to provide additional context
616
-
617
  ### Solving Math Problems
618
  - For text problems: Type or paste your math problem in the input field
619
  - For image problems: Upload a clear image of the math problem
620
  - Click "Solve Problem" to get a detailed step-by-step solution in HTML format
621
  - Use the download buttons to save HTML or PDF versions
622
  - Click "Print to PDF" within the solution to print directly from your browser
623
-
624
  ### HTML Output Features
625
  - **Professional styling**: Clean, readable format with proper typography
626
  - **Mathematical expressions**: Rendered with MathJax for beautiful LaTeX support
627
  - **Step-by-step sections**: Clearly organized solution steps
628
  - **Print-friendly**: Optimized for printing and PDF conversion
629
  - **Timestamps**: Each solution includes generation timestamp
630
-
631
  **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.
632
-
633
  ### Tips for Best Results
634
  - Be specific in your problem description
635
  - Include all necessary information
@@ -637,7 +660,7 @@ def create_demo():
637
  - For algebraic expressions, describe clearly (AI will format math properly)
638
  - Use parentheses to group terms clearly
639
  - For images, ensure the math problem is clearly visible and well-lit
640
-
641
  ### Types of Problems You Can Solve
642
  - Algebra (equations, inequalities, systems of equations)
643
  - Calculus (derivatives, integrals, limits)
@@ -646,15 +669,16 @@ def create_demo():
646
  - Statistics and Probability
647
  - Number Theory
648
  - And many more!
649
-
650
  ### Required Dependencies
651
  To run this application, you'll need to install:
652
  ```bash
653
  pip install gradio openai together pillow markdown weasyprint
654
- MathJax is loaded via CDN – no additional install needed."""
655
- )
656
- return demo
 
657
  # Launch the app
658
  if __name__ == "__main__":
659
  demo = create_demo()
660
- demo.launch()
 
12
  import tempfile
13
  import weasyprint
14
  from pathlib import Path
15
+
16
  # Function to convert markdown to HTML with styling
17
  def markdown_to_html(markdown_text, problem_text="", include_problem=True):
18
  """Convert markdown to styled HTML"""
 
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
  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
  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
  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
  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
  <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
257
  def save_html_to_file(html_content, filename_prefix="math_solution"):
258
  """Save HTML content to a temporary file and return the file path"""
 
264
  with open(file_path, 'w', encoding='utf-8') as f:
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"""
 
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
285
  def generate_math_solution_openrouter(api_key, problem_text, history=None):
286
  if not api_key.strip():
 
341
  except Exception as e:
342
  error_message = f"Error: {str(e)}"
343
  return error_message, None, None, history
344
+
345
  # Enhanced function to generate math solution using Together AI with HTML output
346
  def generate_math_solution_together(api_key, problem_text, image_path=None, history=None):
347
  if not api_key.strip():
 
433
  except Exception as e:
434
  error_message = f"Error: {str(e)}"
435
  return error_message, None, None, history
436
+
437
  # Function to convert image to base64
438
  def image_to_base64(image_path):
439
  if image_path is None:
 
444
  except Exception as e:
445
  print(f"Error converting image to base64: {str(e)}")
446
  return None
447
+
448
  # Define the Gradio interface
449
  def create_demo():
450
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as 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
  openrouter_pdf_download
518
  ]
519
  )
520
+
521
  def clear_openrouter():
522
  return (
523
  "",
 
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
  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
  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
  together_pdf_download
595
  ]
596
  )
597
+
598
  def clear_together():
599
  return (
600
  "",
 
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
  together_pdf_download
614
  ]
615
  )
616
+
617
  # Help tab
618
  with gr.TabItem("Help"):
619
  gr.Markdown(
 
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
  - 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
  - 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
+
681
  # Launch the app
682
  if __name__ == "__main__":
683
  demo = create_demo()
684
+ demo.launch()