349 lines
12 KiB
Markdown
349 lines
12 KiB
Markdown
---
|
||
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 | – |
|