sreepathi-ravikumar commited on
Commit
6b0c3a0
·
verified ·
1 Parent(s): 4f3bedd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -41
app.py CHANGED
@@ -519,7 +519,6 @@ def create_manim_script(problem_data, script_path, audio_path, scale=1):
519
  title_size = settings.get("title_size", 48)
520
 
521
  manim_code = f"""from manim import *
522
-
523
  class GeneratedMathScene(Scene):
524
  def construct(self):
525
  # Scene settings
@@ -532,16 +531,46 @@ class GeneratedMathScene(Scene):
532
  equation_size = {equation_size}
533
  title_size = {title_size}
534
  wrap_width = {wrap_width}
535
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
  def make_wrapped_paragraph(content, color, font, font_size, line_spacing=0.2):
537
  lines = []
538
  words = content.split()
539
  current = ""
540
-
541
  for w in words:
542
  test = w if not current else current + " " + w
543
  test_obj = Text(test, color=color, font=font, font_size=font_size)
544
-
545
  if test_obj.width <= wrap_width * 0.9:
546
  current = test
547
  else:
@@ -549,25 +578,21 @@ class GeneratedMathScene(Scene):
549
  line_obj = Text(current, color=color, font=font, font_size=font_size)
550
  lines.append(line_obj)
551
  current = w
552
-
553
  if current:
554
  lines.append(Text(current, color=color, font=font, font_size=font_size))
555
-
556
  if not lines:
557
  return VGroup()
558
-
559
  first_line = lines[0]
560
  for ln in lines:
561
  ln.align_to(first_line, LEFT)
562
-
563
  para = VGroup(*lines).arrange(DOWN, aligned_edge=LEFT, buff=line_spacing)
564
  return para
565
-
566
  content_group = VGroup()
567
  current_y = 3.0
568
  line_spacing = 0.8
569
  slides = {slides_repr}
570
-
571
  for idx, slide in enumerate(slides):
572
  obj = None
573
  content = slide.get("content", "")
@@ -575,39 +600,35 @@ class GeneratedMathScene(Scene):
575
  scalelen = slide.get("duration", 1.0)
576
  duration = scalelen * {scale}
577
  slide_type = slide.get("type", "text")
578
-
579
  if slide_type == "title":
580
- title_text = content
581
- if title_text:
582
- lines_group = make_wrapped_paragraph(title_text, highlight_color, default_font, title_size, line_spacing=0.3)
583
- obj = lines_group if len(lines_group) > 0 else Text(title_text, color=highlight_color, font=default_font, font_size=title_size)
584
- else:
585
- obj = Text("", color=highlight_color, font=default_font, font_size=title_size)
586
-
587
  if obj.width > wrap_width:
588
  obj.scale_to_fit_width(wrap_width)
589
-
590
  obj.move_to(ORIGIN)
591
  self.play(FadeIn(obj), run_time=duration * 0.8)
592
  self.wait(duration * 0.3)
593
  self.play(FadeOut(obj), run_time=duration * 0.3)
594
  continue
595
-
596
  elif slide_type == "text":
597
- parts = content.split("#")
598
- inline_items = []
599
- for p in parts:
600
- if not p.strip():
601
- continue # ignore empty
602
-
603
- if p.startswith("%"):
604
- eq = p[1:] # remove %
605
- eq_obj = MathTex(eq, color=default_color, font_size=equation_size)
606
- inline_items.append(eq_obj)
607
- else:
608
- text_obj = make_wrapped_paragraph(p, default_color, default_font, text_size)
609
- inline_items.append(text_obj)
610
- obj = VGroup(*inline_items).arrange(RIGHT, aligned_edge=LEFT, buff=0.15)
611
  elif slide_type == "equation":
612
  eq_content = content
613
  test = MathTex(eq_content, color=default_color, font_size=equation_size)
@@ -616,26 +637,25 @@ class GeneratedMathScene(Scene):
616
  mid = len(parts) // 2
617
  line1 = " ".join(parts[:mid])
618
  line2 = " ".join(parts[mid:])
619
- wrapped_eq = f"{{{{line1}}}} \\\\ {{{{line2}}}}"
620
  obj = MathTex(wrapped_eq, color=default_color, font_size=equation_size)
621
  else:
622
  obj = MathTex(eq_content, color=default_color, font_size=equation_size)
623
-
624
  if obj.width > wrap_width:
625
  obj.scale_to_fit_width(wrap_width)
626
-
627
  if obj:
628
  obj.to_edge(LEFT, buff=0.3)
629
  obj.shift(UP * (current_y - obj.height / 2))
630
-
631
  obj_bottom = obj.get_bottom()[1]
 
632
  if obj_bottom < -3.5:
633
  scroll_amount = abs(obj_bottom - (-3.5)) + 0.3
634
  self.play(content_group.animate.shift(UP * scroll_amount), run_time=0.5)
635
  current_y += scroll_amount
636
  obj.shift(UP * scroll_amount)
637
  obj.to_edge(LEFT, buff=0.3)
638
-
639
  if animation == "write_left":
640
  self.play(Write(obj), run_time=duration)
641
  elif animation == "fade_in":
@@ -645,11 +665,11 @@ class GeneratedMathScene(Scene):
645
  self.play(obj.animate.set_color(highlight_color), run_time=duration * 0.4)
646
  else:
647
  self.play(Write(obj), run_time=duration)
648
-
649
  content_group.add(obj)
650
  current_y -= (getattr(obj, "height", 0) + line_spacing)
651
  self.wait(0.3)
652
-
653
  if len(content_group) > 0:
654
  final_box = SurroundingRectangle(content_group[-1], color=highlight_color, buff=0.2)
655
  self.play(Create(final_box), run_time=0.8)
 
519
  title_size = settings.get("title_size", 48)
520
 
521
  manim_code = f"""from manim import *
 
522
  class GeneratedMathScene(Scene):
523
  def construct(self):
524
  # Scene settings
 
531
  equation_size = {equation_size}
532
  title_size = {title_size}
533
  wrap_width = {wrap_width}
534
+
535
+ def make_inline_segments(content, color, font, text_size, equation_size):
536
+
537
+ if not content:
538
+ return VGroup()
539
+
540
+ # Split by # separator
541
+ segments = content.split("#")
542
+ mobjects = []
543
+
544
+ for segment in segments:
545
+ segment = segment.strip()
546
+ if not segment:
547
+ continue
548
+
549
+ # Check if it's a LaTeX equation (starts with %$ and ends with $)
550
+ if segment.startswith("%$") and segment.endswith("$"):
551
+ # Remove %$ from start and $ from end
552
+ latex_content = segment[2:-1]
553
+ mob = MathTex(latex_content, color=color, font_size=equation_size)
554
+ else:
555
+ # Regular text
556
+ mob = Text(segment, color=color, font=font, font_size=text_size)
557
+
558
+ mobjects.append(mob)
559
+
560
+ if not mobjects:
561
+ return VGroup()
562
+
563
+ # Arrange horizontally with minimal spacing
564
+ inline_group = VGroup(*mobjects).arrange(RIGHT, buff=0.05)
565
+ return inline_group
566
+
567
  def make_wrapped_paragraph(content, color, font, font_size, line_spacing=0.2):
568
  lines = []
569
  words = content.split()
570
  current = ""
 
571
  for w in words:
572
  test = w if not current else current + " " + w
573
  test_obj = Text(test, color=color, font=font, font_size=font_size)
 
574
  if test_obj.width <= wrap_width * 0.9:
575
  current = test
576
  else:
 
578
  line_obj = Text(current, color=color, font=font, font_size=font_size)
579
  lines.append(line_obj)
580
  current = w
 
581
  if current:
582
  lines.append(Text(current, color=color, font=font, font_size=font_size))
 
583
  if not lines:
584
  return VGroup()
 
585
  first_line = lines[0]
586
  for ln in lines:
587
  ln.align_to(first_line, LEFT)
 
588
  para = VGroup(*lines).arrange(DOWN, aligned_edge=LEFT, buff=line_spacing)
589
  return para
590
+
591
  content_group = VGroup()
592
  current_y = 3.0
593
  line_spacing = 0.8
594
  slides = {slides_repr}
595
+
596
  for idx, slide in enumerate(slides):
597
  obj = None
598
  content = slide.get("content", "")
 
600
  scalelen = slide.get("duration", 1.0)
601
  duration = scalelen * {scale}
602
  slide_type = slide.get("type", "text")
603
+
604
  if slide_type == "title":
605
+ # Use inline segments for title
606
+ obj = make_inline_segments(content, highlight_color, default_font, title_size, equation_size)
607
+
608
+ # Fallback to simple text if no inline segments
609
+ if len(obj) == 0:
610
+ obj = Text(content, color=highlight_color, font=default_font, font_size=title_size)
611
+
612
  if obj.width > wrap_width:
613
  obj.scale_to_fit_width(wrap_width)
 
614
  obj.move_to(ORIGIN)
615
  self.play(FadeIn(obj), run_time=duration * 0.8)
616
  self.wait(duration * 0.3)
617
  self.play(FadeOut(obj), run_time=duration * 0.3)
618
  continue
619
+
620
  elif slide_type == "text":
621
+ # Use inline segments for text
622
+ obj = make_inline_segments(content, default_color, default_font, text_size, equation_size)
623
+
624
+ # Fallback if no inline segments detected
625
+ if len(obj) == 0:
626
+ obj = make_wrapped_paragraph(content, default_color, default_font, text_size, line_spacing=0.25)
627
+
628
+ # Handle width overflow
629
+ if obj.width > wrap_width:
630
+ obj.scale_to_fit_width(wrap_width)
631
+
 
 
 
632
  elif slide_type == "equation":
633
  eq_content = content
634
  test = MathTex(eq_content, color=default_color, font_size=equation_size)
 
637
  mid = len(parts) // 2
638
  line1 = " ".join(parts[:mid])
639
  line2 = " ".join(parts[mid:])
640
+ wrapped_eq = f"{{{line1}}} \\\\ {{{line2}}}"
641
  obj = MathTex(wrapped_eq, color=default_color, font_size=equation_size)
642
  else:
643
  obj = MathTex(eq_content, color=default_color, font_size=equation_size)
 
644
  if obj.width > wrap_width:
645
  obj.scale_to_fit_width(wrap_width)
646
+
647
  if obj:
648
  obj.to_edge(LEFT, buff=0.3)
649
  obj.shift(UP * (current_y - obj.height / 2))
 
650
  obj_bottom = obj.get_bottom()[1]
651
+
652
  if obj_bottom < -3.5:
653
  scroll_amount = abs(obj_bottom - (-3.5)) + 0.3
654
  self.play(content_group.animate.shift(UP * scroll_amount), run_time=0.5)
655
  current_y += scroll_amount
656
  obj.shift(UP * scroll_amount)
657
  obj.to_edge(LEFT, buff=0.3)
658
+
659
  if animation == "write_left":
660
  self.play(Write(obj), run_time=duration)
661
  elif animation == "fade_in":
 
665
  self.play(obj.animate.set_color(highlight_color), run_time=duration * 0.4)
666
  else:
667
  self.play(Write(obj), run_time=duration)
668
+
669
  content_group.add(obj)
670
  current_y -= (getattr(obj, "height", 0) + line_spacing)
671
  self.wait(0.3)
672
+
673
  if len(content_group) > 0:
674
  final_box = SurroundingRectangle(content_group[-1], color=highlight_color, buff=0.2)
675
  self.play(Create(final_box), run_time=0.8)