Files
MarkdownToIHKChemnits/report.md
T

349 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 | |