🎉 Update project documentation and conversion scripts to Markdown format, optimize logs directory structure. 🐛
This commit is contained in:
Binary file not shown.
@ -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()
|
Reference in New Issue
Block a user