Create python_pptx.py
Browse files- python_pptx/python_pptx.py +95 -0
python_pptx/python_pptx.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# https://huggingface.co/spaces/MisterAI/GenDoc_05
|
| 3 |
+
# /home/user/python_pptx/python_pptx.py_02
|
| 4 |
+
|
| 5 |
+
from pptx import Presentation
|
| 6 |
+
from pptx.util import Inches, Pt
|
| 7 |
+
from pptx.enum.text import PP_ALIGN
|
| 8 |
+
|
| 9 |
+
class PresentationGenerator:
|
| 10 |
+
def __init__(self):
|
| 11 |
+
self.theme_colors = {
|
| 12 |
+
"title": "1F4E79", # Bleu foncé
|
| 13 |
+
"subtitle": "277BC0", # Bleu clair
|
| 14 |
+
"text": "2A2A2A", # Gris foncé
|
| 15 |
+
"background": "FFFFFF", # Blanc
|
| 16 |
+
"accent": "98C1D9" # Bleu pastel
|
| 17 |
+
}
|
| 18 |
+
self.default_font = "Calibri"
|
| 19 |
+
|
| 20 |
+
def parse_presentation_content(self, content):
|
| 21 |
+
slides = []
|
| 22 |
+
current_slide = None
|
| 23 |
+
lines = content.split('\n')
|
| 24 |
+
|
| 25 |
+
for line in lines:
|
| 26 |
+
line = line.strip()
|
| 27 |
+
if line == "#Debut Slide Titre#":
|
| 28 |
+
current_slide = {'type': 'title', 'title': ''}
|
| 29 |
+
elif line == "#Debut Slide Ressources Utiles#":
|
| 30 |
+
if current_slide:
|
| 31 |
+
slides.append(current_slide)
|
| 32 |
+
current_slide = {'type': 'resources', 'title': 'Ressources Utiles', 'points': []}
|
| 33 |
+
elif line.startswith("#Debut Slide"):
|
| 34 |
+
if current_slide:
|
| 35 |
+
slides.append(current_slide)
|
| 36 |
+
current_slide = {'type': 'content', 'title': '', 'points': []}
|
| 37 |
+
elif line.startswith("## Titre:"):
|
| 38 |
+
if current_slide:
|
| 39 |
+
current_slide['title'] = line[8:].strip()
|
| 40 |
+
elif line.startswith("### Points:"):
|
| 41 |
+
if current_slide:
|
| 42 |
+
current_slide['points'] = []
|
| 43 |
+
elif line.startswith("- ") and current_slide:
|
| 44 |
+
if current_slide:
|
| 45 |
+
current_slide['points'].append(line[2:].strip())
|
| 46 |
+
elif line == "#Fin Slide Ressources Utiles#" or line.startswith("#Fin Slide"):
|
| 47 |
+
if current_slide:
|
| 48 |
+
slides.append(current_slide)
|
| 49 |
+
current_slide = None
|
| 50 |
+
|
| 51 |
+
return slides
|
| 52 |
+
|
| 53 |
+
def create_presentation(self, slides):
|
| 54 |
+
prs = Presentation()
|
| 55 |
+
|
| 56 |
+
# Determine the maximum content slide for font size adjustment
|
| 57 |
+
max_content_length = max(len(" ".join(slide['points'])) for slide in slides if slide['type'] == 'content')
|
| 58 |
+
|
| 59 |
+
# Set font sizes based on the maximum content length
|
| 60 |
+
base_font_size = 32
|
| 61 |
+
title_font_size = 44
|
| 62 |
+
if max_content_length > 300: # Example threshold
|
| 63 |
+
base_font_size = 24
|
| 64 |
+
title_font_size = 36
|
| 65 |
+
|
| 66 |
+
# Title Slide
|
| 67 |
+
title_slide = prs.slides.add_slide(prs.slide_layouts[0])
|
| 68 |
+
title_slide.shapes.title.text = slides[0]['title']
|
| 69 |
+
title_slide.shapes.title.text_frame.paragraphs[0].font.size = Pt(title_font_size)
|
| 70 |
+
title_slide.shapes.title.text_frame.paragraphs[0].font.name = self.default_font
|
| 71 |
+
title_slide.shapes.title.text_frame.paragraphs[0].font.color.rgb = self.rgb_to_tuple(self.theme_colors["title"])
|
| 72 |
+
|
| 73 |
+
for slide in slides[1:]:
|
| 74 |
+
content_slide = prs.slides.add_slide(prs.slide_layouts[1])
|
| 75 |
+
content_slide.shapes.title.text = slide['title']
|
| 76 |
+
content_slide.shapes.title.text_frame.paragraphs[0].font.size = Pt(title_font_size)
|
| 77 |
+
content_slide.shapes.title.text_frame.paragraphs[0].font.name = self.default_font
|
| 78 |
+
content_slide.shapes.title.text_frame.paragraphs[0].font.color.rgb = self.rgb_to_tuple(self.theme_colors["subtitle"])
|
| 79 |
+
|
| 80 |
+
if slide['points']:
|
| 81 |
+
body = content_slide.shapes.placeholders[1].text_frame
|
| 82 |
+
body.clear()
|
| 83 |
+
for point in slide['points']:
|
| 84 |
+
p = body.add_paragraph()
|
| 85 |
+
p.text = point
|
| 86 |
+
p.font.size = Pt(base_font_size)
|
| 87 |
+
p.font.name = self.default_font
|
| 88 |
+
p.font.color.rgb = self.rgb_to_tuple(self.theme_colors["text"])
|
| 89 |
+
|
| 90 |
+
return prs
|
| 91 |
+
|
| 92 |
+
def rgb_to_tuple(self, hex_color):
|
| 93 |
+
# Convert hex color to RGB tuple
|
| 94 |
+
hex_color = hex_color.lstrip('#')
|
| 95 |
+
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
|