diff --git a/IHK_Projektdokumentation/IHK_Projektdokumentation_Final.docx b/IHK_Projektdokumentation/IHK_Projektdokumentation_Final.docx new file mode 100644 index 000000000..2b8eb0f31 Binary files /dev/null and b/IHK_Projektdokumentation/IHK_Projektdokumentation_Final.docx differ diff --git a/IHK_Projektdokumentation/convert_to_word.py b/IHK_Projektdokumentation/convert_to_word.py new file mode 100644 index 000000000..b98e66248 --- /dev/null +++ b/IHK_Projektdokumentation/convert_to_word.py @@ -0,0 +1,305 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Konvertiert die IHK-Projektdokumentation von Markdown nach Word (DOCX) +mit IHK-konformen Formatierungen. +""" + +import os +import re +from docx import Document +from docx.shared import Pt, Inches, RGBColor +from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING +from docx.enum.style import WD_STYLE_TYPE +from markdown import markdown +from bs4 import BeautifulSoup +import html2text + +def create_ihk_styles(doc): + """Erstellt IHK-konforme Formatvorlagen""" + + # Normaler Text + normal_style = doc.styles['Normal'] + normal_style.font.name = 'Arial' + normal_style.font.size = Pt(11) + normal_style.paragraph_format.line_spacing_rule = WD_LINE_SPACING.ONE_POINT_FIVE + normal_style.paragraph_format.space_after = Pt(6) + normal_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY + + # Überschrift 1 + h1_style = doc.styles['Heading 1'] + h1_style.font.name = 'Arial' + h1_style.font.size = Pt(16) + h1_style.font.bold = True + h1_style.paragraph_format.space_before = Pt(12) + h1_style.paragraph_format.space_after = Pt(12) + h1_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT + + # Überschrift 2 + h2_style = doc.styles['Heading 2'] + h2_style.font.name = 'Arial' + h2_style.font.size = Pt(14) + h2_style.font.bold = True + h2_style.paragraph_format.space_before = Pt(12) + h2_style.paragraph_format.space_after = Pt(6) + h2_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT + + # Überschrift 3 + h3_style = doc.styles['Heading 3'] + h3_style.font.name = 'Arial' + h3_style.font.size = Pt(12) + h3_style.font.bold = True + h3_style.paragraph_format.space_before = Pt(6) + h3_style.paragraph_format.space_after = Pt(6) + h3_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT + + # Code-Style + try: + code_style = doc.styles.add_style('Code', WD_STYLE_TYPE.CHARACTER) + code_style.font.name = 'Courier New' + code_style.font.size = Pt(10) + except: + code_style = doc.styles['Code'] + + return doc + +def setup_document_layout(doc): + """Richtet das Dokumentlayout nach IHK-Vorgaben ein""" + sections = doc.sections + for section in sections: + # Seitenränder (IHK-Standard) + section.top_margin = Inches(1.0) + section.bottom_margin = Inches(1.0) + section.left_margin = Inches(1.25) + section.right_margin = Inches(1.0) + + # Seitengröße A4 + section.page_height = Inches(11.69) + section.page_width = Inches(8.27) + +def add_title_page(doc): + """Fügt die Titelseite hinzu""" + # Titel + p = doc.add_paragraph() + p.alignment = WD_ALIGN_PARAGRAPH.CENTER + p.add_run('Abschlussprüfung - Sommer 2025\n').bold = True + p.add_run('\n') + + p = doc.add_paragraph() + p.alignment = WD_ALIGN_PARAGRAPH.CENTER + p.add_run('Fachinformatiker für digitale Vernetzung\n').font.size = Pt(14) + + doc.add_paragraph() + + p = doc.add_paragraph() + p.alignment = WD_ALIGN_PARAGRAPH.CENTER + p.add_run('Dokumentation der betrieblichen Projektarbeit\n').font.size = Pt(16) + + doc.add_paragraph() + + # Projekttitel + p = doc.add_paragraph() + p.alignment = WD_ALIGN_PARAGRAPH.CENTER + run = p.add_run('MYP – Manage Your Printer\n') + run.font.size = Pt(18) + run.font.bold = True + + p = doc.add_paragraph() + p.alignment = WD_ALIGN_PARAGRAPH.CENTER + p.add_run('Digitalisierung des 3D-Drucker-Reservierungsprozesses durch Etablierung\n') + p.add_run('der cyberphysischen Kommunikation mit relevanten Hardwarekomponenten') + + # Mehrere Leerzeilen + for _ in range(5): + doc.add_paragraph() + + # Abgabedatum + p = doc.add_paragraph() + p.alignment = WD_ALIGN_PARAGRAPH.CENTER + p.add_run('Abgabedatum: 5. Juni 2025').bold = True + + doc.add_paragraph() + doc.add_paragraph() + + # Ausbildungsbetrieb + p = doc.add_paragraph() + p.alignment = WD_ALIGN_PARAGRAPH.LEFT + p.add_run('Ausbildungsbetrieb\n').bold = True + p.add_run('\n') + p.add_run('Mercedes-Benz AG\n') + p.add_run('Daimlerstraße 143\n') + p.add_run('D-12277 Berlin') + + doc.add_paragraph() + + # Prüfungsbewerber + p = doc.add_paragraph() + p.alignment = WD_ALIGN_PARAGRAPH.LEFT + p.add_run('Prüfungsbewerber\n').bold = True + p.add_run('\n') + p.add_run('Till Tomczak\n') + p.add_run('Hainbuchenstraße 19\n') + p.add_run('D-16761 Hennigsdorf') + + # Seitenumbruch nach Titelseite + doc.add_page_break() + +def process_markdown_content(content): + """Verarbeitet Markdown-Inhalt und strukturiert ihn für Word""" + # Entferne Bilder vorerst + content = re.sub(r']*>', '', content) + + # Teile den Inhalt in Abschnitte + lines = content.split('\n') + processed_content = [] + + skip_until_content = False + for line in lines: + # Skip Titelbereich + if line.strip().startswith('# Inhaltsverzeichnis'): + skip_until_content = True + continue + + if skip_until_content and line.strip().startswith('# 1. Einleitung'): + skip_until_content = False + + if not skip_until_content and not line.strip().startswith('Mercedes-Benz') and \ + not line.strip().startswith('Till Tomczak') and \ + not line.strip().startswith('Abgabedatum:'): + processed_content.append(line) + + return '\n'.join(processed_content) + +def add_content_to_document(doc, content): + """Fügt den Inhalt zum Word-Dokument hinzu""" + lines = content.split('\n') + current_paragraph = None + in_code_block = False + + for line in lines: + # Überschrift 1 + if line.startswith('# '): + heading = line[2:].strip() + doc.add_heading(heading, level=1) + current_paragraph = None + + # Überschrift 2 + elif line.startswith('## '): + heading = line[3:].strip() + doc.add_heading(heading, level=2) + current_paragraph = None + + # Überschrift 3 + elif line.startswith('### '): + heading = line[4:].strip() + doc.add_heading(heading, level=3) + current_paragraph = None + + # Überschrift 4 + elif line.startswith('#### '): + heading = line[5:].strip() + # Word hat standardmäßig nur 3 Heading-Ebenen, nutze fetten Text + p = doc.add_paragraph() + p.add_run(heading).bold = True + current_paragraph = None + + # Aufzählungen + elif line.strip().startswith('- '): + text = line.strip()[2:] + p = doc.add_paragraph(text, style='List Bullet') + current_paragraph = None + + # Normaler Text + elif line.strip(): + if current_paragraph is None: + current_paragraph = doc.add_paragraph() + else: + current_paragraph.add_run(' ') + + # Verarbeite Inline-Formatierungen + process_inline_formatting(current_paragraph, line) + + # Leerzeile + else: + current_paragraph = None + +def process_inline_formatting(paragraph, text): + """Verarbeitet Inline-Formatierungen wie fett und kursiv""" + # Ersetze Markdown-Formatierungen + parts = re.split(r'(\*\*[^*]+\*\*|\*[^*]+\*|`[^`]+`)', text) + + for part in parts: + if part.startswith('**') and part.endswith('**'): + # Fett + paragraph.add_run(part[2:-2]).bold = True + elif part.startswith('*') and part.endswith('*') and not part.startswith('**'): + # Kursiv + paragraph.add_run(part[1:-1]).italic = True + elif part.startswith('`') and part.endswith('`'): + # Code + run = paragraph.add_run(part[1:-1]) + run.font.name = 'Courier New' + run.font.size = Pt(10) + else: + # Normaler Text + paragraph.add_run(part) + +def add_table_of_contents(doc): + """Fügt ein Inhaltsverzeichnis hinzu""" + doc.add_heading('Inhaltsverzeichnis', level=1) + + # Platzhalter für automatisches Inhaltsverzeichnis + p = doc.add_paragraph() + p.add_run('[Das Inhaltsverzeichnis wird in Word automatisch generiert.\n') + p.add_run('Verwenden Sie: Verweise → Inhaltsverzeichnis → Automatisches Verzeichnis]') + p.italic = True + + doc.add_page_break() + +def main(): + """Hauptfunktion""" + # Pfade + input_file = 'Dokumentation_Final_Markdown/Dokumentation.md' + output_file = 'IHK_Projektdokumentation_Final.docx' + + # Lese Markdown-Datei + print("Lese Markdown-Datei...") + with open(input_file, 'r', encoding='utf-8') as f: + content = f.read() + + # Erstelle Word-Dokument + print("Erstelle Word-Dokument...") + doc = Document() + + # Richte Styles und Layout ein + print("Konfiguriere IHK-konforme Formatierung...") + create_ihk_styles(doc) + setup_document_layout(doc) + + # Füge Titelseite hinzu + print("Erstelle Titelseite...") + add_title_page(doc) + + # Füge Inhaltsverzeichnis hinzu + print("Füge Inhaltsverzeichnis hinzu...") + add_table_of_contents(doc) + + # Verarbeite und füge Hauptinhalt hinzu + print("Verarbeite Dokumentinhalt...") + processed_content = process_markdown_content(content) + add_content_to_document(doc, processed_content) + + # Speichere Dokument + print(f"Speichere Dokument als {output_file}...") + doc.save(output_file) + + print("Konvertierung abgeschlossen!") + print("\nHinweise zur Nachbearbeitung:") + print("1. Überprüfen Sie die Formatierung und passen Sie sie ggf. an") + print("2. Generieren Sie das Inhaltsverzeichnis neu (Verweise → Inhaltsverzeichnis aktualisieren)") + print("3. Fügen Sie Kopf- und Fußzeilen mit Seitenzahlen hinzu") + print("4. Überprüfen Sie die Seitenumbrüche") + print("5. Fügen Sie ggf. Abbildungen und Diagramme ein") + +if __name__ == "__main__": + main() \ No newline at end of file