--- student: name: "Max Mustermann" profession: "Fachinformatiker Fachrichtung Anwendungsentwicklung" company: "Musterfirma GmbH" supervisor: "Sabine Supervisor" project: title: "Entwicklung eines Markdown-zu-IHK-Konverters" subtitle: "Projektdokumentation zur Abschlussprüfung" period: "Sommer 2026" abbreviations: - abbr: "IHK" meaning: "Industrie- und Handelskammer" - abbr: "PDF" meaning: "Portable Document Format" - abbr: "API" meaning: "Application Programming Interface" - abbr: "AST" meaning: "Abstract Syntax Tree" - abbr: "DIN" meaning: "Deutsches Institut für Normung" - abbr: "YAML" meaning: "YAML Ain't Markup Language" glossary: - term: "Goldmark" definition: "Ein in Go geschriebener Markdown-Parser, der den CommonMark-Standard implementiert und durch Erweiterungen (Tabellen, YAML-Frontmatter) ergänzt werden kann." - term: "FPDF" definition: "Eine Go-Bibliothek zur Erzeugung von PDF-Dokumenten ohne externe Systemabhängigkeiten." - term: "Kroki" definition: "Ein Webdienst, der verschiedene Diagramm-Beschreibungssprachen (Mermaid, PlantUML u.a.) serverseitig in Bilder umwandelt." - term: "Zwei-Pass-Rendering" definition: "Verfahren, bei dem ein Dokument zweimal gerendert wird: Der erste Durchlauf ermittelt Seitenzahlen, der zweite nutzt diese für das Inhaltsverzeichnis." --- # Vorwort Dieses Projekt entstand im Rahmen der Abschlussprüfung zum Fachinformatiker Fachrichtung Anwendungsentwicklung. Es soll zeigen, dass technische Dokumentationen effizient und normgerecht erstellt werden können – ohne manuelle Nachbearbeitung in einer Textverarbeitung. # 1. Problemstellung ## 1.1 Ausgangslage Aktuell müssen IHK-Dokumentationen mühsam in Word formatiert werden, was fehleranfällig ist und viel Zeit kostet. Besonders die Einhaltung der Formvorgaben – Schriftgröße, Zeilenabstand und Seitenränder – erfordert manuelle Sorgfalt bei jedem Absatz. Änderungen am Inhalt erzwingen regelmäßig manuelle Korrekturen an der Formatierung. ## 1.2 Zielsetzung Ziel ist ein Go-Tool, das **Markdown** in PDF umwandelt und dabei alle formalen Anforderungen der IHK Chemnitz automatisch erfüllt. Das Tool soll: - die Prüfungsvorbereitung erleichtern, - die Qualität der Dokumente *einheitlich* sicherstellen und - den gesamten Formatierungsprozess vollständig automatisieren. Besondere Anforderung ist die Einhaltung der **DIN 5008**-Norm sowie der spezifischen Vorgaben der IHK Chemnitz (Korrekturrand 4 cm rechts, Schriftart Arial/Helvetica 12 pt, 1½-zeiliger Abstand). # 2. Projektablauf ## 2.1 Planung und Zeitrahmen Die Planung umfasst die Analyse der IHK-Vorgaben und das Design der Software-Architektur. Der Projektzeitraum beträgt maximal 80 Stunden gemäß Ausbildungsverordnung. @Tabelle: Projektphasen mit Zeitplanung | Phase | Aufgabe | Stunden | |-------|---------|---------| | 1 | Anforderungsanalyse und Recherche der IHK-Vorgaben sowie DIN 5008 Normen | 8 | | 2 | Architekturentwurf und Auswahl geeigneter Go-Bibliotheken (Goldmark, FPDF) | 10 | | 3 | Implementierung des Markdown-Parsers mit AST-Traversierung | 20 | | 4 | Implementierung des PDF-Renderers mit allen IHK-Elementen | 24 | | 5 | Tests, Fehlerkorrektur und Dokumentation | 12 | | 6 | Puffer und Abnahme | 6 | ## 2.2 Architektur Die Software ist in Go implementiert und folgt einer klaren Trennung zwischen Parsing und Rendering. Das Zwei-Pass-Verfahren ermöglicht ein korrektes Inhaltsverzeichnis mit Seitenzahlen. @DiagrammQuer: Systemarchitektur des Konverters – Zwei-Pass-Rendering ```mermaid graph LR subgraph Eingabe MD[report.md] CFG[YAML Frontmatter] end subgraph Parsing P(ParseMarkdown) AST[Goldmark AST] end subgraph Pass1[Pass 1 - Seitenzahlen ermitteln] R1[IHKRenderer] TOC[tocItems mit Seitenzahlen] end subgraph Pass2[Pass 2 - Finales PDF] R2[IHKRenderer] PDF[projektarbeit.pdf] end MD --> P CFG --> P P --> AST AST --> R1 R1 --> TOC TOC --> R2 AST --> R2 R2 --> PDF ``` ### Modulstruktur Der Konverter ist in neun fokussierte Go-Dateien aufgeteilt: - **`main.go`** – Einstiegspunkt, CLI-Flags, Zwei-Pass-Pipeline - **`config.go`** – YAML-Konfigurationsstruktur - **`markdown_parser.go`** – Goldmark-AST-Traversierung - **`pdf_renderer.go`** – Kern-Struct `IHKRenderer`, DIN-5008-Konstanten - **`pdf_content.go`** – Inhalts-Renderer (Absätze, Listen, Tabellen, Code, Bilder) - **`pdf_toc.go`** – Verzeichnis-Renderer (Inhalts-, Tabellen-, Abbildungsverzeichnis) - **`pdf_pages.go`** – Seiten-Renderer (Titelseite, Anhang, Erklärung, Glossar) - **`pdf_numbering.go`** – Seitennummerierung (Römisch / Arabisch) - **`diagram.go`** – Kroki-Diagramm-Rendering mit SHA-256-Cache ## 2.3 Realisierung Die Realisierung erfolgt in Go unter Verwendung von `goldmark` für das Markdown-Parsing und `fpdf` für die PDF-Erzeugung. @Tabelle: Eingesetzte Bibliotheken und Werkzeuge | Werkzeug | Zweck | Version | Lizenz | |----------|-------|---------|--------| | Go | Programmiersprache und Laufzeitumgebung | 1.22+ | BSD | | Goldmark | Markdown-Parser mit CommonMark-konformem AST | v1.8 | MIT | | goldmark-meta | YAML-Frontmatter-Erweiterung für Goldmark | v1.1 | MIT | | FPDF | PDF-Erzeugung ohne externe Systemabhängigkeiten | v0.9 | MIT | | Kroki | Diagramm-Rendering für Mermaid und PlantUML | online | Apache 2.0 | @Quelle: Goldmark Documentation, https://github.com/yuin/goldmark, 2024 @Quelle: Go-PDF/Fpdf Documentation, https://github.com/go-pdf/fpdf, 2025 ### Implementierungsbeispiel: Tabellen-Renderer Der folgende Ausschnitt zeigt die Kernlogik des mehrzeiligen Tabellen-Renderers. Jede Zelle wird mit `SplitLines` vorgemessen; anschließend werden alle Zellen einer Zeile auf einheitliche Höhe gebracht: ```go func (r *IHKRenderer) prepareRow(rawCells []string, numCols int, colW, lineHt float64, bold bool) tableRowData { r.pdf.SetFont("Helvetica", map[bool]string{true: "B", false: ""}[bold], dinFontCaption) cells := make([][]string, numCols) maxLines := 0 for j := 0; j < numCols; j++ { raw := "" if j < len(rawCells) { raw = rawCells[j] } split := r.pdf.SplitLines([]byte(r.tr(raw)), colW-2) lines := make([]string, len(split)) for k, b := range split { lines[k] = string(b) } if len(lines) == 0 { lines = []string{""} } cells[j] = lines if len(lines) > maxLines { maxLines = len(lines) } } return tableRowData{cells: cells, height: float64(maxLines) * lineHt} } ``` ## 2.4 Test und Qualitätssicherung Das Tool wurde anhand dieses Musterdokuments getestet. Folgende Kriterien wurden geprüft: 1. Korrekte Seitenränder gemäß DIN 5008 (links 3 cm, rechts 4 cm Korrekturrand) 2. Seitennummerierung – römisch im Vorspann (ab II), arabisch im Textteil (ab 1) 3. Schriftart Helvetica, 12 Punkt, 1½-zeiliger Abstand (6,35 mm Zeilenhöhe) 4. Automatisch generierte Verzeichnisse (Inhalt, Tabellen, Abbildungen) 5. Mehrzeilige Tabellenzellen mit einheitlicher Zeilenhöhe pro Tabellenzeile 6. Nummerierende Code-Blöcke mit Zeilennummern-Gutter 7. Listen mit korrektem hängendem Einzug (zweite Zeile bündig mit Text) 8. Tabellen als Anhang über die Direktive `@TabelleAnhang:` @Tabelle: Testergebnisse der Qualitätssicherung | Kriterium | Erwartet | Ergebnis | Status | |-----------|----------|----------|--------| | Linker Seitenrand | 30 mm | 30 mm | Bestanden | | Rechter Seitenrand (Korrekturrand) | 40 mm | 40 mm | Bestanden | | Schriftgröße Fließtext | 12 pt | 12 pt | Bestanden | | Zeilenabstand Fließtext | 6,35 mm (1,5-fach) | 6,35 mm | Bestanden | | Römische Nummerierung Vorspann | ab Seite II | ab Seite II | Bestanden | | Arabische Nummerierung Textteil | ab Seite 1 | ab Seite 1 | Bestanden | | Mehrzeilige Tabellenzellen | einheitliche Zeilenhöhe | einheitliche Zeilenhöhe | Bestanden | # 3. Verwendung der Direktiven ## 3.1 Quellenangaben und Bibliografie Quellenangaben werden mit der Direktive `@Quelle:` eingefügt und am Ende des Dokuments alphabetisch sortiert im Literaturverzeichnis ausgegeben. Die Direktive kann an beliebiger Stelle im Dokument stehen. ## 3.2 Benannte Tabellen Mit `@Tabelle: Tabellenname` unmittelbar vor einer Markdown-Tabelle wird der Tabelle ein Name gegeben. Dieser erscheint im Tabellenverzeichnis: ``` @Tabelle: Übersicht der Programmiersprachen | Sprache | Paradigma | Typsystem | |---------|-----------|-----------| | Go | Imperativ | Statisch | | Python | Multi | Dynamisch | ``` ## 3.3 Tabellen als Anhang Mit `@TabelleAnhang: Anlagenname` wird die folgende Tabelle nicht im Fließtext gerendert, sondern als eigene Anlage im Anhang platziert: ``` @TabelleAnhang: Vollständige Fehlerliste | Code | Beschreibung | Schwere | |------|--------------|---------| | E001 | Datei nicht gefunden | Kritisch | ``` ## 3.4 Diagramme als Anhang Mit `@AnhangUML:` gefolgt von einem Mermaid- oder PlantUML-Codeblock wird das Diagramm als Anlage eingebettet statt im Fließtext: ``` @AnhangUML: Datenbankschema \`\`\`plantuml @startuml entity User { ... } @enduml \`\`\` ``` # 4. Zusammenfassung Das Tool ermöglicht eine effiziente Erstellung von IHK-Dokumentationen unter Einhaltung **aller** Formatvorgaben. Durch die Trennung von Inhalt (Markdown) und Formatierung (Go-Renderer) ist eine konsistente Ausgabe garantiert. Künftige Erweiterungen könnten Fußnoten, Querverweise und eine konfigurierbare Spaltenbreite für Tabellen umfassen. @Quelle: IHK Chemnitz, Hinweise zur Erarbeitung der Dokumentation über die Projektarbeit, 2020 @Quelle: DIN 5008:2020-03, Schreib- und Gestaltungsregeln für die Textverarbeitung, Beuth Verlag @TabelleAnhang: Vollständige Liste der unterstützten Markdown-Direktiven | Direktive | Syntax | Beschreibung | |-----------|--------|--------------| | Quelle | @Quelle: Text | Fügt einen Literaturverweis hinzu, der alphabetisch im Literaturverzeichnis erscheint | | Tabelle | @Tabelle: Name | Gibt der folgenden Tabelle einen Namen für das Tabellenverzeichnis | | Tabellenanhang | @TabelleAnhang: Name | Sendet die folgende Tabelle als nummerierte Anlage in den Anhang | | Bildanhang | @Anhang: Titel \| Pfad | Fügt ein Bild als nummerierte Anlage in den Anhang ein | | Diagrammanhang | @AnhangUML: Titel | Rendert den folgenden Mermaid/PlantUML-Block als Anlage | @AnhangUML: Systemarchitektur – Datenflussdiagramm ```mermaid graph LR MD[report.md] -->|ParseMarkdown| AST[Goldmark AST] AST -->|Pass 1| R1[IHKRenderer Pass 1] R1 -->|tocItems| R2[IHKRenderer Pass 2] AST -->|Pass 2| R2 R2 -->|Save| OUT[projektarbeit.pdf] ``` @AnhangUMLQuer: Vollständige Modulübersicht – Querformat ```mermaid graph TD subgraph Eingabe MD[report.md] CFG[YAML Frontmatter] end subgraph Parser MP[markdown_parser.go] AST[Goldmark AST] end subgraph Renderer IR[pdf_renderer.go] IC[pdf_content.go] IT[pdf_toc.go] IP[pdf_pages.go] IN[pdf_numbering.go] end subgraph Diagramme DG[diagram.go] KR[Kroki API] end subgraph Ausgabe PDF[projektarbeit.pdf] end MD --> MP CFG --> MP MP --> AST AST --> IR IR --> IC IR --> IT IR --> IP IR --> IN IC --> DG DG --> KR KR --> DG IP --> PDF ``` @TabelleAnhangQuer: Vollständige Direktiven-Referenz im Querformat | Direktive | Syntax | Beschreibung | Querformat | |-----------|--------|--------------|------------| | Quelle | @Quelle: Text | Literaturverweis, alphabetisch sortiert im Literaturverzeichnis | – | | Tabelle | @Tabelle: Name | Gibt der nächsten Tabelle einen Namen für das Tabellenverzeichnis | – | | Tabellenanhang | @TabelleAnhang: Name | Sendet die nächste Tabelle als Anlage in den Anhang | – | | Tabellenanhang Quer | @TabelleAnhangQuer: Name | Tabelle als Anlage im Querformat (297×210 mm, 15 mm Rand) | Ja | | Bildanhang | @Anhang: Titel \| Pfad | Bild als nummerierte Anlage (Hochformat) | – | | Bildanhang Quer | @AnhangBildQuer: Titel \| Pfad | Bild als nummerierte Anlage im Querformat | Ja | | Diagrammanhang | @AnhangUML: Titel | Nächster Mermaid/PlantUML-Block als Anlage (Hochformat) | – | | Diagrammanhang Quer | @AnhangUMLQuer: Titel | Nächster Mermaid/PlantUML-Block als Anlage im Querformat | Ja | | Diagramm Querseite | @DiagrammQuer: Titel | Nächster Mermaid/PlantUML-Block inline als Querformat-Seite | – |