🎉 Update project documentation and conversion scripts to Markdown format, optimize logs directory structure. 🐛

This commit is contained in:
2025-06-03 23:04:37 +02:00
parent a27b978fc5
commit 31d1a3eaf6
25 changed files with 520 additions and 0 deletions

View File

@ -0,0 +1,442 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Erweiterte Konvertierung der IHK-Projektdokumentation von Markdown nach Word (DOCX)
mit vollständiger IHK-konformer Formatierung.
"""
import os
import re
from docx import Document
from docx.shared import Pt, Inches, RGBColor, Cm
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING
from docx.enum.style import WD_STYLE_TYPE
from docx.enum.section import WD_SECTION
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
def create_element(name):
"""Hilfsfunktion zum Erstellen von XML-Elementen"""
return OxmlElement(name)
def create_attribute(element, name, value):
"""Hilfsfunktion zum Setzen von XML-Attributen"""
element.set(qn(name), value)
def add_page_numbers(doc):
"""Fügt Seitenzahlen in die Fußzeile ein"""
for section in doc.sections:
footer = section.footer
footer_para = footer.paragraphs[0]
footer_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
# Füge Seitenzahl hinzu
fldChar1 = create_element('w:fldChar')
create_attribute(fldChar1, 'w:fldCharType', 'begin')
instrText = create_element('w:instrText')
instrText.text = " PAGE "
fldChar2 = create_element('w:fldChar')
create_attribute(fldChar2, 'w:fldCharType', 'end')
footer_para._p.append(fldChar1)
footer_para._p.append(instrText)
footer_para._p.append(fldChar2)
def add_header(doc):
"""Fügt Kopfzeile mit Projektinformationen hinzu"""
for section in doc.sections[1:]: # Skip erste Seite (Titelseite)
header = section.header
header_para = header.paragraphs[0]
header_para.text = "IHK-Projektdokumentation - MYP Manage Your Printer"
header_para.alignment = WD_ALIGN_PARAGRAPH.RIGHT
header_para.style.font.size = Pt(10)
header_para.style.font.italic = True
def create_ihk_styles(doc):
"""Erstellt erweiterte IHK-konforme Formatvorlagen"""
# Normaler Text mit IHK-Spezifikationen
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
normal_style.paragraph_format.first_line_indent = Cm(0.5) # Einzug erste Zeile
# Überschrift 1 - Hauptkapitel
h1_style = doc.styles['Heading 1']
h1_style.font.name = 'Arial'
h1_style.font.size = Pt(16)
h1_style.font.bold = True
h1_style.font.color.rgb = RGBColor(0, 0, 0)
h1_style.paragraph_format.space_before = Pt(24)
h1_style.paragraph_format.space_after = Pt(12)
h1_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT
h1_style.paragraph_format.keep_with_next = True
h1_style.paragraph_format.page_break_before = False # Kein automatischer Seitenumbruch
# Überschrift 2 - Unterkapitel
h2_style = doc.styles['Heading 2']
h2_style.font.name = 'Arial'
h2_style.font.size = Pt(14)
h2_style.font.bold = True
h2_style.font.color.rgb = RGBColor(0, 0, 0)
h2_style.paragraph_format.space_before = Pt(18)
h2_style.paragraph_format.space_after = Pt(6)
h2_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT
h2_style.paragraph_format.keep_with_next = True
# Überschrift 3 - Abschnitte
h3_style = doc.styles['Heading 3']
h3_style.font.name = 'Arial'
h3_style.font.size = Pt(12)
h3_style.font.bold = True
h3_style.font.color.rgb = RGBColor(0, 0, 0)
h3_style.paragraph_format.space_before = Pt(12)
h3_style.paragraph_format.space_after = Pt(6)
h3_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT
h3_style.paragraph_format.keep_with_next = True
# Aufzählungsstil
bullet_style = doc.styles['List Bullet']
bullet_style.font.name = 'Arial'
bullet_style.font.size = Pt(11)
bullet_style.paragraph_format.left_indent = Cm(1.0)
bullet_style.paragraph_format.first_line_indent = Cm(-0.5)
bullet_style.paragraph_format.space_after = Pt(3)
# Code-Style für technische Begriffe
try:
code_style = doc.styles.add_style('Code', WD_STYLE_TYPE.CHARACTER)
except:
code_style = doc.styles['Code']
code_style.font.name = 'Courier New'
code_style.font.size = Pt(10)
code_style.font.color.rgb = RGBColor(0, 0, 139) # Dunkelblau
# Zitat-Style
try:
quote_style = doc.styles.add_style('Quote', WD_STYLE_TYPE.PARAGRAPH)
except:
quote_style = doc.styles['Quote']
quote_style.font.name = 'Arial'
quote_style.font.size = Pt(10)
quote_style.font.italic = True
quote_style.paragraph_format.left_indent = Cm(1.0)
quote_style.paragraph_format.right_indent = Cm(1.0)
quote_style.paragraph_format.space_before = Pt(6)
quote_style.paragraph_format.space_after = Pt(6)
return doc
def setup_document_layout(doc):
"""Richtet das erweiterte Dokumentlayout nach IHK-Vorgaben ein"""
for section in doc.sections:
# IHK-Standard Seitenränder
section.top_margin = Cm(2.5)
section.bottom_margin = Cm(2.0)
section.left_margin = Cm(2.5)
section.right_margin = Cm(2.0)
# A4 Format
section.page_height = Cm(29.7)
section.page_width = Cm(21.0)
# Kopf- und Fußzeilenabstand
section.header_distance = Cm(1.25)
section.footer_distance = Cm(1.25)
def add_enhanced_title_page(doc):
"""Fügt eine erweiterte IHK-konforme Titelseite hinzu"""
# Logo-Platzhalter
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.RIGHT
p.add_run('[Mercedes-Benz Logo]').italic = True
# Leerzeilen
for _ in range(3):
doc.add_paragraph()
# Prüfungsinformationen
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('Abschlussprüfung Sommer 2025')
run.font.size = Pt(14)
run.font.bold = True
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('Industrie- und Handelskammer Berlin')
run.font.size = Pt(12)
doc.add_paragraph()
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('Fachinformatiker für digitale Vernetzung')
run.font.size = Pt(16)
run.font.bold = True
for _ in range(2):
doc.add_paragraph()
# Dokumenttyp
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('Dokumentation der betrieblichen Projektarbeit')
run.font.size = Pt(14)
for _ in range(2):
doc.add_paragraph()
# Projekttitel
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('MYP Manage Your Printer')
run.font.size = Pt(20)
run.font.bold = True
doc.add_paragraph()
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
p.add_run('Digitalisierung des 3D-Drucker-Reservierungsprozesses\n')
p.add_run('durch Etablierung der cyberphysischen Kommunikation\n')
p.add_run('mit relevanten Hardwarekomponenten')
# Füllung
for _ in range(6):
doc.add_paragraph()
# Informationsblock am Seitenende
table = doc.add_table(rows=2, cols=2)
table.alignment = WD_ALIGN_PARAGRAPH.CENTER
table.style = 'Table Grid'
# Ausbildungsbetrieb
cell = table.cell(0, 0)
p = cell.paragraphs[0]
p.add_run('Ausbildungsbetrieb:').bold = True
cell.add_paragraph('Mercedes-Benz AG')
cell.add_paragraph('Daimlerstraße 143')
cell.add_paragraph('12277 Berlin')
# Prüfungsbewerber
cell = table.cell(0, 1)
p = cell.paragraphs[0]
p.add_run('Prüfungsbewerber:').bold = True
cell.add_paragraph('Till Tomczak')
cell.add_paragraph('Hainbuchenstraße 19')
cell.add_paragraph('16761 Hennigsdorf')
# Abgabedatum
cell = table.cell(1, 0)
p = cell.paragraphs[0]
p.add_run('Abgabedatum:').bold = True
cell.add_paragraph('5. Juni 2025')
# Prüflingsnummer
cell = table.cell(1, 1)
p = cell.paragraphs[0]
p.add_run('Prüflingsnummer:').bold = True
cell.add_paragraph('[Wird von IHK vergeben]')
# Seitenumbruch
doc.add_page_break()
def process_enhanced_content(content):
"""Erweiterte Verarbeitung des Markdown-Inhalts"""
# Entferne den Header-Bereich
content = re.sub(r'^.*?(?=# 1\. Einleitung)', '', content, flags=re.DOTALL)
# Verbessere Formatierung
content = re.sub(r'', '', content) # Korrekter Gedankenstrich
content = re.sub(r'\.\.\.', '', content) # Auslassungspunkte
content = re.sub(r'"([^"]*)"', '\\1"', content) # Deutsche Anführungszeichen
return content
def add_enhanced_content(doc, content):
"""Fügt Inhalt mit erweiterter Formatierung hinzu"""
lines = content.split('\n')
current_paragraph = None
in_list = False
for i, line in enumerate(lines):
# Überschriften
if line.startswith('# '):
heading = line[2:].strip()
doc.add_heading(heading, level=1)
current_paragraph = None
in_list = False
elif line.startswith('## '):
heading = line[3:].strip()
doc.add_heading(heading, level=2)
current_paragraph = None
in_list = False
elif line.startswith('### '):
heading = line[4:].strip()
doc.add_heading(heading, level=3)
current_paragraph = None
in_list = False
elif line.startswith('#### '):
heading = line[5:].strip()
p = doc.add_paragraph()
p.add_run(heading + ':').bold = True
current_paragraph = None
in_list = False
# Listen
elif line.strip().startswith('- '):
text = line.strip()[2:]
p = doc.add_paragraph(text, style='List Bullet')
in_list = True
current_paragraph = None
# Normaler Text
elif line.strip():
if not in_list:
if current_paragraph is None:
current_paragraph = doc.add_paragraph()
else:
current_paragraph.add_run(' ')
process_enhanced_inline_formatting(current_paragraph, line.strip())
else:
in_list = False
current_paragraph = doc.add_paragraph()
process_enhanced_inline_formatting(current_paragraph, line.strip())
# Leerzeile
else:
current_paragraph = None
if not in_list:
in_list = False
def process_enhanced_inline_formatting(paragraph, text):
"""Erweiterte Inline-Formatierung mit besserer Erkennung"""
# Komplexere Regex für verschachtelte Formatierungen
pattern = r'(\*\*[^*]+\*\*|\*[^*]+\*|`[^`]+`|„[^"]+"|[^\']+\')'
parts = re.split(pattern, text)
for part in parts:
if not part:
continue
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/Technische Begriffe
run = paragraph.add_run(part[1:-1])
run.font.name = 'Courier New'
run.font.size = Pt(10)
run.font.color.rgb = RGBColor(0, 0, 139)
elif part.startswith('') or part.startswith('"'):
# Zitate
run = paragraph.add_run(part)
run.italic = True
else:
# Normaler Text
paragraph.add_run(part)
def add_appendix_placeholder(doc):
"""Fügt Platzhalter für Anhänge hinzu"""
doc.add_page_break()
doc.add_heading('Anlagen', level=1)
doc.add_heading('A. Netzwerkdiagramme und Systemarchitektur', level=2)
p = doc.add_paragraph('[Hier Netzwerkdiagramme einfügen]')
p.italic = True
doc.add_heading('B. API-Dokumentation', level=2)
p = doc.add_paragraph('[Hier API-Dokumentation einfügen]')
p.italic = True
doc.add_heading('C. Benutzerhandbuch', level=2)
p = doc.add_paragraph('[Hier Benutzerhandbuch einfügen]')
p.italic = True
doc.add_heading('D. Testprotokolle', level=2)
p = doc.add_paragraph('[Hier Testprotokolle einfügen]')
p.italic = True
doc.add_heading('E. Screenshots der Benutzeroberfläche', level=2)
p = doc.add_paragraph('[Hier Screenshots einfügen]')
p.italic = True
doc.add_heading('F. Konfigurationsdateien und Deployment-Skripte', level=2)
p = doc.add_paragraph('[Hier relevante Konfigurationsdateien einfügen]')
p.italic = True
def main():
"""Hauptfunktion"""
input_file = 'Dokumentation_Final_Markdown/Dokumentation.md'
output_file = 'IHK_Projektdokumentation_Final_Enhanced.docx'
print("Lese Markdown-Datei...")
with open(input_file, 'r', encoding='utf-8') as f:
content = f.read()
print("Erstelle Word-Dokument mit erweiterten IHK-Formatierungen...")
doc = Document()
# Konfiguration
print("Konfiguriere Dokumentlayout und Styles...")
create_ihk_styles(doc)
setup_document_layout(doc)
# Titelseite
print("Erstelle erweiterte Titelseite...")
add_enhanced_title_page(doc)
# Kopf- und Fußzeilen
print("Füge Kopf- und Fußzeilen hinzu...")
add_header(doc)
add_page_numbers(doc)
# Inhaltsverzeichnis
print("Füge Inhaltsverzeichnis-Platzhalter hinzu...")
doc.add_heading('Inhaltsverzeichnis', level=1)
p = doc.add_paragraph()
p.add_run('Bitte generieren Sie das Inhaltsverzeichnis über:\n')
p.add_run('Verweise → Inhaltsverzeichnis → Automatisches Verzeichnis 1\n\n')
p.add_run('Stellen Sie sicher, dass alle Überschriften korrekt als Überschrift 1-3 formatiert sind.')
p.italic = True
doc.add_page_break()
# Hauptinhalt
print("Verarbeite und füge Hauptinhalt hinzu...")
processed_content = process_enhanced_content(content)
add_enhanced_content(doc, processed_content)
# Anhänge
print("Füge Anhang-Platzhalter hinzu...")
add_appendix_placeholder(doc)
# Speichern
print(f"Speichere Dokument als {output_file}...")
doc.save(output_file)
print("\nKonvertierung erfolgreich abgeschlossen!")
print("\nWichtige Nachbearbeitungsschritte:")
print("1. Generieren Sie das Inhaltsverzeichnis (Verweise → Inhaltsverzeichnis)")
print("2. Überprüfen Sie alle Seitenumbrüche")
print("3. Fügen Sie fehlende Abbildungen und Diagramme ein")
print("4. Prüfen Sie die Seitennummerierung")
print("5. Ergänzen Sie die Anlagen mit den tatsächlichen Dokumenten")
print("6. Führen Sie eine finale Rechtschreibprüfung durch")
print("\nDie Datei entspricht nun den IHK-Formatvorgaben!")
if __name__ == "__main__":
main()