| | |
| | |
| | |
| |
|
| | from pptx import Presentation |
| | from pptx.util import Inches, Pt |
| | from pptx.dml.color import RGBColor |
| | from pptx.enum.text import PP_ALIGN |
| | import re |
| |
|
| | class PresentationGenerator: |
| | def __init__(self): |
| | self.default_theme_colors = { |
| | "title": RGBColor(31, 78, 121), |
| | "subtitle": RGBColor(39, 123, 192), |
| | "text": RGBColor(42, 42, 42), |
| | "background": RGBColor(255, 255, 255), |
| | "accent": RGBColor(152, 193, 217) |
| | } |
| | self.default_font = "Calibri" |
| |
|
| | def parse_presentation_content(self, content): |
| | slides = [] |
| | current_slide = None |
| | lines = content.split('\n') |
| | for line in lines: |
| | line = line.strip() |
| | if line == "#Debut Slide Titre#": |
| | current_slide = {'type': 'title', 'title': ''} |
| | elif line == "#Debut Slide Ressources Utiles#": |
| | if current_slide: |
| | slides.append(current_slide) |
| | current_slide = {'type': 'resources', 'title': 'Ressources Utiles', 'points': []} |
| | elif line.startswith("#Debut Slide"): |
| | if current_slide: |
| | slides.append(current_slide) |
| | current_slide = {'type': 'content', 'title': '', 'points': []} |
| | elif line.startswith("## Titre:"): |
| | if current_slide: |
| | current_slide['title'] = line[8:].strip() |
| | elif line.startswith("###"): |
| | if current_slide: |
| | current_slide['points'].append((line[3:].strip(), 'subtitle')) |
| | elif line.startswith("- ") and current_slide: |
| | if current_slide: |
| | current_slide['points'].append((line[2:].strip(), 'text')) |
| | elif line == "#Fin Slide Ressources Utiles#" or line.startswith("#Fin Slide"): |
| | if current_slide: |
| | slides.append(current_slide) |
| | current_slide = None |
| |
|
| | return slides |
| |
|
| | def convert_markdown_links(self, text): |
| | |
| | pattern = r'\[([^\]]+)\]\((https?://[^\)]+)\)' |
| | repl = r'\1' |
| | text = re.sub(pattern, repl, text) |
| | return text |
| |
|
| | def create_presentation(self, slides): |
| | prs = Presentation() |
| |
|
| | |
| | max_content_length = max(len(" ".join([point[0] for point in slide['points']])) for slide in slides if slide['type'] == 'content') |
| |
|
| | |
| | base_font_size = 32 |
| | title_font_size = 44 |
| | if max_content_length > 300: |
| | base_font_size = 24 |
| | title_font_size = 36 |
| | if max_content_length > 400: |
| | base_font_size = 20 |
| | title_font_size = 32 |
| | if max_content_length > 500: |
| | base_font_size = 18 |
| | title_font_size = 28 |
| |
|
| | |
| | title_slide = prs.slides.add_slide(prs.slide_layouts[0]) |
| | title_slide.shapes.title.text = slides[0]['title'] |
| | title_slide.shapes.title.text_frame.paragraphs[0].font.size = Pt(title_font_size) |
| | title_slide.shapes.title.text_frame.paragraphs[0].font.name = self.default_font |
| | title_slide.shapes.title.text_frame.paragraphs[0].font.color.rgb = self.default_theme_colors["title"] |
| |
|
| | for slide in slides[1:]: |
| | content_slide = prs.slides.add_slide(prs.slide_layouts[1]) |
| | content_slide.shapes.title.text = slide['title'] |
| | content_slide.shapes.title.text_frame.paragraphs[0].font.size = Pt(title_font_size) |
| | content_slide.shapes.title.text_frame.paragraphs[0].font.name = self.default_font |
| | content_slide.shapes.title.text_frame.paragraphs[0].font.color.rgb = self.default_theme_colors["subtitle"] |
| |
|
| | if slide['points']: |
| | body = content_slide.shapes.placeholders[1].text_frame |
| | body.clear() |
| | for point, style in slide['points']: |
| | p = body.add_paragraph() |
| | p.text = self.convert_markdown_links(point) |
| | p.font.size = Pt(base_font_size if style == 'text' else title_font_size - 4) |
| | p.font.name = self.default_font |
| | p.font.color.rgb = self.default_theme_colors["text" if style == 'text' else 'subtitle'] |
| |
|
| | return prs |
| |
|