| |
| |
| |
|
|
| 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 |
|
|