commit 92b3eb405bab86862f4b3f780ee3282d1094e53e Author: Adam Skotarczak (DEVELOP-WSL) Date: Mon Jul 7 23:25:12 2025 +0200 initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..906ef64 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.adoc text eol=lf +*.yml text eol=lf +*.sh text eol=lf +Makefile text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c8e2c90 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Custom + +# Files +*.zip +INHALT.md +.gitkeep +desktop.ini + +# Pandoc +missfont.log + +# Folders +#.vscode/** +build/** diff --git a/.vscode/cspell.json b/.vscode/cspell.json new file mode 100644 index 0000000..b807fd4 --- /dev/null +++ b/.vscode/cspell.json @@ -0,0 +1,66 @@ +{ + "version": "0.2", + "language": "en,de", + "languageSettings": [ + { + "languageId": "*", + "enabled": false + }, + { + "languageId": "plaintext", + "enabled": true + }, + { + "languageId": "markdown", + "enabled": true + }, + { + "languageId": "asciidoc", + "enabled": true + } + ], + "ignorePaths": [ + "node_modules", + "dist", + "build", + "output", + ".git" + ], + "words": [ + "abschranken", + "adoc", + "allpolig", + "arraybackslash", + "AsciiDoc", + "autochapter", + "Autorenrechtlich", + "Buildchain", + "Buildversion", + "codesys", + "Codesys", + "DGUV", + "Effizienzkritischen", + "Ethercat", + "Funkengefahr", + "gitcopy", + "kapitel", + "makefile", + "Neutralleiter", + "newpage", + "Pandoc", + "PDFTheme", + "Pneumatikventile", + "PNOZ", + "Pressenstempel", + "Printversion", + "Projektinterne", + "raggedright", + "realAscot", + "Schottky", + "Skotarczak", + "tabularx", + "textbf", + "textwidth", + "tocgen" + ] +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..5fe3cb0 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,11 @@ +{ + "recommendations": [ + "streetsidesoftware.code-spell-checker", + "streetsidesoftware.code-spell-checker-german", + "streetsidesoftware.code-spell-checker", + "streetsidesoftware.code-spell-checker-german", + "davidanson.vscode-markdownlint", + "yzane.markdown-pdf", + "yzhang.markdown-all-in-one" + ] +} diff --git a/.vscode/keybindings.json b/.vscode/keybindings.json new file mode 100644 index 0000000..9059fd1 --- /dev/null +++ b/.vscode/keybindings.json @@ -0,0 +1,8 @@ +[ + { + "key": "ctrl+alt+p", + "command": "workbench.action.tasks.runTask", + "args": "Markdown → PDF (Pandoc via WSL)", + "when": "editorLangId == markdown" + } +] diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8227123 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,65 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll.cSpell": "explicit" + }, + "asciidoc.preview.style": "styles/preview.css", + "files.associations": { + "*.adoc": "asciidoc" + }, + "files.eol": "\n", + "[yaml]": { + "files.eol": "\n" + }, + "[shellscript]": { + "files.eol": "\n" + }, + "[asciidoc]": { + "files.eol": "\n" + }, + "files.encoding": "utf8", + + "makefile.configureOnOpen": false, + + "cSpell.language": "de,de-DE,en", + "cSpell.dictionaries": ["de_DE", "en"], + "cSpell.enabled": true, + "[markdown]": { + "editor.wordWrap": "on", + "editor.quickSuggestions": { + "other": true, + "comments": true, + "strings": true + }, + "editor.renderWhitespace": "all", + }, + "markdownlint.config": { + "default": true, + "MD013": false, + "MD033": false, + "MD041": false + }, + "markdown-pdf.puppeteerLaunchOptions": { + "args": ["--no-sandbox", "--disable-setuid-sandbox"] + }, + "markdown-pdf.note": "Tastenkombi 'Ctrl+Alt+P' startet WSL-Build → PDF", + "cSpell.words": [ + "Betriebsystem", + "Buildchain", + "Buildversion", + "CLI", + "epub", + "GitHub", + "LaTeX", + "Markdown", + "newpage", + "pandoc", + "Pandoc", + "Printversion", + "Projektinterne", + "reintext", + "Rust", + "Skotarczak", + "Texlive", + "UTF" + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..8ddf6ca --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,19 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Markdown → PDF (Pandoc via WSL)", + "type": "shell", + "command": "wsl make pdf", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [], + "presentation": { + "reveal": "always", + "panel": "shared" + } + } + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a424584 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +# Changelog - Handbuch 1000T Presse - Codesys + +- **2025-07-07** - 0.1.0.alpha-1 + - [x] Initial Commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b392eb1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,56 @@ +# **LICENSE** + +*(Version 1.0 – April 2025)* + +--- + +**Buchlizenz – "Autorenrechtlich geschützt, freie Lesbarkeit – keine kommerzielle Nutzung"** + +Copyright © 2025 Adam Skotarczak +Alle Rechte vorbehalten. + +Dieses Buchprojekt ist urheberrechtlich geschützt. +Es darf **kostenfrei gelesen, geteilt und verlinkt** werden, solange folgende Bedingungen eingehalten werden: + +--- + +## 🔒 Rechte und Kontrolle + +- Das Urheberrecht am gesamten Inhalt liegt ausschließlich beim Autor. +- Beiträge (z. B. via GitHub Pull Requests) sind willkommen, werden jedoch nur mit Zustimmung des Autors übernommen. +- Mit der Einreichung eines Beitrags überträgt der Beitragende dem Autor ein einfaches Nutzungsrecht für die Veröffentlichung im Buch. + Es entsteht **kein Miturheberrecht** und keine Ansprüche auf spätere Verwendung. + +--- + +## ✅ Erlaubt + +- Nichtkommerzielle Nutzung (z. B. Lesen, Weitergeben, Zitieren) bei Namensnennung. +- Teilen des unveränderten Inhalts (z. B. als PDF, auf Webseiten, im Unterricht etc.). +- Verlinkung auf das GitHub-Repository oder andere offizielle Quellen. + +--- + +## ❌ Nicht erlaubt + +- Kommerzielle Nutzung (z. B. Verkauf, Druckexemplare gegen Entgelt, Verwendung in kostenpflichtigen Produkten oder Kursen). +- Veränderung oder Bearbeitung des Buchinhalts ohne ausdrückliche Genehmigung. +- Veröffentlichung abgewandelter Fassungen unter eigenem Namen. + +--- + +## ℹ️ Hinweis zur Lizenzform + +Diese Lizenz basiert inhaltlich auf der Creative Commons Lizenz +**CC BY-NC-ND 4.0 International**, jedoch mit zusätzlichen Klarstellungen zur Beitragspolitik und Urheberrolle. + +Für juristische Auslegung gilt deutsches Urheberrecht. + +--- + +**Kontakt:** +Adam Skotarczak +✉️ +🔗 + +--- diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ef23287 --- /dev/null +++ b/Makefile @@ -0,0 +1,180 @@ +# Makefile für Markdown-eBook Handbuch mit Pandoc +# (C) 2024-2025 - Adam Skotarczak - 30/06/2025 +# ORIGIN: https://local.ionivation.com/Lorenz-Industrietechnik-GmbH/1000T-Presse-Umbau-2024-Codesys + +# === load Configfile === +include config.mk + +# === Automatische Konfiguration === +VERSION := $(shell cat VERSION) +MASCHINEVERSION := $(shell cat ../../VERSION) +MASCHINEVERSION ?= '- nicht gefunden -' +PYTHON := $(shell command -v python3 || command -v python) + +# === Nur wsl oder Linux === # +ifeq ($(OS),Windows_NT) +set_codepage: + @if [ "$(OS)" = "Windows_NT" ]; then chcp 65001 >nul; fi + $(error [⚠] Windows wird nicht unterstützt. Bitte WSL oder Linux verwenden.) + exit(1) +endif + +# === Quelldateien (geordnet nach Nummerierung) === + +# Standard: prod, falls nicht durch CLI überschrieben +MODE ?= prod + +MD_ALL = $(wildcard $(MANUSCRIPT)/*.md) + +MD_FILES_prod := $(filter-out $(EXCLUDE_prod), $(MD_ALL)) +MD_FILES_dev = $(MD_ALL) + + +# Dynamische Auswahl je nach MODE +define set_md_files +$(eval MD_FILES := $(MD_FILES_$(MODE))) +$(eval MD_SORTED := $(sort $(MD_FILES))) +endef + + +# === Standardziel: Setze Codepage und führe alle Builds aus === +.DEFAULT_GOAL := all + + +# === Abhängigkeiten prüfen === +check-deps: check-python check-fonts +.PHONY: check-deps + + +# === Standardziel: Alles bauen === +all: clean plain epub pdf html docx toc + + +# === Hier ist geplant make zu missbrauchen, die notwendigen Abhängigkeiten zu installieren === +install: + @echo "\n⚠ - Noch nicht implementiert!\n" + + +# === EPUB-Ausgabe === +epub: $(OUTPUT) + $(call set_md_files) + pandoc $(MD_SORTED) \ + --metadata-file=$(METADATA) \ + --resource-path=media \ + --toc --toc-depth=$(TOCDEPTH) \ + --css=$(CSS) \ + --epub-chapter-level=1 \ + --epub-cover-image=$(LOGO) \ + -V toc-depth=$(TOCDEPTH) \ + -o $(OUTPUT)/$(TITLE).epub + + +# === PDF über LaTeX (Print-Version) === + +# --highlight-style= +#| Stilname | Beschreibung / Anmutung | +#| ------------ | --------------------------------------------- | +#| `pygments` | Klassischer Stil, angelehnt an Pygments | +#| `tango` | Kontrastreich, an das Tango-Theme angelehnt | +#| `kate` | Stil des Kate-Editors (KDE) | +#| `monochrome` | Schwarzweiß, ohne Farben (druckfreundlich) | +#| `espresso` | Dunkler Hintergrund, helles Code-Highlighting | +#| `zenburn` | Weicher, augenfreundlicher Dunkelstil | +#| `haddock` | Stil von Haddock-Dokumentation | +#| `breezedark` | KDE-Breeze-Dark-inspiriert (dunkel, modern) | + +# === PDF Generierung === +pdf: $(OUTPUT) + $(call set_md_files) + @echo "Verwende MODE=$(MODE)" + @echo "Dateien: $(MD_FILES)" + pandoc $(MD_SORTED) \ + --columns=1000 \ + --metadata-file=$(METADATA) \ + --metadata version="$(VERSION)" \ + --metadata buildmode="$(MODE)" \ + --metadata maschineversion="$(MASCHINEVERSION)" \ + --resource-path=media \ + --toc --number-sections --toc-depth=$(TOCDEPTH) \ + --template=$(TEX_PRINT) \ + --pdf-engine=xelatex \ + --highlight-style=tango \ + -V toc-depth=$(TOCDEPTH) \ + -V $(GEOMETRY) \ + -o $(OUTPUT)/$(TITLE).pdf + +# === HTML-Vorschau oder Export === +html: $(OUTPUT) + $(call set_md_files) + pandoc $(MD_SORTED) \ + --metadata-file=$(METADATA) \ + --resource-path=media \ + --toc --number-sections \ + --css=$(CSS) \ + -o $(OUTPUT)/$(TITLE).html + + +# === Word-Version (Lektorat etc.) === +docx: $(OUTPUT) + $(call set_md_files) + pandoc $(MD_SORTED) \ + --metadata-file=$(METADATA) \ + --resource-path=media \ + --toc --number-sections \ + -o $(OUTPUT)/$(TITLE).docx + + +plain: $(OUTPUT) + $(call set_md_files) + pandoc $(MD_SORTED) \ + --metadata-file=$(METADATA) \ + --resource-path=media \ + --wrap=none \ + -t plain \ + -o $(OUTPUT)/$(TITLE)_reintext.txt + + +# === Vorschau im Terminal (reines Markdown) === +preview: + cat $(MD_SORTED) | less + + +# === Sicherstellen, dass der Ausgabeordner existiert === +$(OUTPUT): + @mkdir -p $(OUTPUT) + @echo "[i] Verzeichnis $(OUTPUT) erstellt!" + + +# === Python-Check === +check-python: + @$(PYTHON) --version || (echo "❌ Python nicht gefunden, wsl gestartet?" && exit 1) + + +# === Fonts testen === +check-fonts: + @fc-match "$(FONT)" >/dev/null || (echo "❌ Schriftart $(FONT) nicht gefunden!" && exit 1) + + +# === Erstellt aus einem vordefinierten Verzeichnis mit Markdown-Dateien einen Inhaltsverzeichnis === +toc: + @echo "📚 Generiere Inhaltsverzeichnis in .\$(INDEXFILE).md ..." + @$(PYTHON) $(TOOLPATH)/tocgen.py -d $(MANUSCRIPT) -o $(INDEXFILE).md + @echo "📚 Inhaltsverzeichnis in .\$(INDEXFILE).md erstellt." + @echo "✅ Fertig." + + +# === Bereinigen der Ausgaben === +clean: + @rm -rf $(OUTPUT)/* + @echo "🧹 alle Builds unter $(OUTPUT)\ gelöscht." + @rm -f $(INDEXFILE).md + @echo "🧹 $(INDEXFILE).md gelöscht." + +clear: clean + +# === Hilfe === +help: + @echo "\n⚠ - Noch nicht implementiert!\n" + + +.PHONY: all toc epub check-python pdf html docx preview clean diff --git a/NOTES.md b/NOTES.md new file mode 100644 index 0000000..f586882 --- /dev/null +++ b/NOTES.md @@ -0,0 +1 @@ +# Notizen des Autors diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ca4fe8 --- /dev/null +++ b/README.md @@ -0,0 +1,256 @@ +# Codesys ST Handbuch + +![Buch-Logo](./media/logo/logo.png) + +**Version:** [VERSION](VERSION) + +## Inhalt + +- [Codesys ST Handbuch](#codesys-st-handbuch) + - [Inhalt](#inhalt) + - [Infos](#infos) + - [Struktur](#struktur) + - [Installation und Build](#installation-und-build) + - [Nötige Software für den Build](#nötige-software-für-den-build) + - [Schriftarten](#schriftarten) + - [Templates](#templates) + - [PDF](#pdf) + - [eBook (epub)](#ebook-epub) + - [DOCX (Office/ Word)](#docx-office-word) + - [Build](#build) + - [Erklärung zum Makefile](#erklärung-zum-makefile) + - [Struktur beim schreiben des Buchs](#struktur-beim-schreiben-des-buchs) + - [Schreiben mit VS-Code](#schreiben-mit-vs-code) + - [Projektinterne Tastenkombinationen mit `.vscode/keybindings.json`](#projektinterne-tastenkombinationen-mit-vscodekeybindingsjson) + - [Zweck](#zweck) + - [Einbindung in Visual Studio Code](#einbindung-in-visual-studio-code) + - [🔧 Vorgehen](#-vorgehen) + - [Empfehlung](#empfehlung) + - [Hinweis zur Konsistenz](#hinweis-zur-konsistenz) + - [Nützliche Links und Tipps für den Author](#nützliche-links-und-tipps-für-den-author) + - [Lizenz](#lizenz) + +--- + +## Infos + +--- + +## Struktur + +```plaintext + +📁 . # +├── 📁 build # Ausgabeordner (wird vom Build-Prozess befüllt) +├── 📁 manuscript # +│ ├── 📄 00_deckblatt.md # +│ ├── 📄 05_vorwort.md # +│ ├── 📄 10_kapitel1.md # +├── 📁 media # Bilder, Grafiken, Diagramme usw. NICHT im Manuskript enthalten sind. +│ ├── 📁 logo # +│ │ ├── 📄 logo.png # +│ └── 📄 favicon.ico # +├── 📁 metadata # Metadaten für eBook, Titelblatt, Author etc +│ ├── 📄 author.txt # +│ └── 📄 ebook.yaml # +├── 📁 styles # Pandoc-Templates, LaTeX-Vorlagen, CSS +│ ├── 📄 ebook-template.tex # +│ ├── 📄 ebook.css # +│ ├── 📄 print-template.tex # +│ └── 📄 reference.docx # +├── 📁 tools # +│ ├── 📄 bmp-emojis.md # +│ ├── 📄 cli-emojis.md # +│ ├── 📄 dev-setup.sh # +│ ├── 📄 gitcopy.bat # +│ └── 📄 tocgen.py # +├── 📄 .gitignore # +├── 📄 CHANGELOG.md # +├── 📄 desktop.ini # +├── 📄 LICENSE # Lizenz für das Buch (z. B. CC-BY) +├── 📄 Makefile # Automatisierter Build-Prozess mit Pandoc etc. +├── 📄 README.md # Diese Datei - Erklärung zum Build des Buchs +└── 📄 VERSION # Paketversion (ohne Zeilenumbruch einzeilig 0.0.0) + +``` + +--- + +## Installation und Build + +### Nötige Software für den Build + +**Hinweis: TeX unter Windows?** + +Obwohl es grundsätzlich möglich ist, TeX unter Windows zu installieren – und auch entsprechende Distributionen wie MiKTeX oder TeX Live für Windows existieren – rate ich dringend davon ab, auf diesem Weg zu starten. + +Für einen stabilen und reproduzierbaren Build-Prozess empfiehlt sich stattdessen der Einsatz eines Linux-Systems. Wenn du kein dediziertes Linux verwendest, ist das Windows Subsystem for Linux (`WSL`) eine ausgezeichnete Alternative. + +>Voraussetzung: +>Du solltest mit `apt` umgehen können und wissen, dass ein `update` vor dem `install` obligatorisch ist. + +Falls der Build trotzdem scheitert oder du dir den Aufwand sparen möchtest, lade dir einfach die fertige PDF-Version herunter – oder bestelle dir direkt ein gedrucktes Exemplar des Buchs. + +- **✅ Pandoc installieren:** + + ```sh + sudo apt install pandoc + ``` + +- **✅ Empfohlene Installation: TeX Live Full** (ca.8GB) + + ```sh + sudo apt install texlive-full + ``` + + Wenn NICHT `texlive-full`, dann aber: + + - Zusätzlich deutsche Sprache (falls babel fehlt): + + ```bash + sudo apt install texlive-lang-german + ``` + + Ich empfehle aber dringend `texlive-full` zu installieren da man erfahrungsgemäss am Anfang auf viele Fehler mit fehlenden Abhängigkeiten stößt wenn man Templates testet. + +- **✅ Make installieren:** + + Make oder besser die Anwendung `make` wird benötigt um die Erstellung der Ziele wie PDF zu automatisiern. + Dafür liegt auch das vorbereitete Skript `Makefile` im Hauptverzeichnis. Die ist nur optional und man kann es selbstverständlich auch manuell durchführen. + + ```sh + sudo apt install make + ``` + + Ich verwende Version: + + ```sh + > make -v + GNU Make 4.3 + Built for x86_64-pc-linux-gnu + ``` + +#### Schriftarten + +```sh +sudo apt install fonts-noto-color-emoji fonts-firacode +sudo apt install fonts-symbola +``` + +### Templates + +#### PDF + +#### eBook (epub) + +#### DOCX (Office/ Word) + +### Build + +Schau mal ins [`Makefile`](./Makefile), dort findest Du einige Kandidaten um aus dem vorliegenden Markdown Manuskript eine entsprechende Version zu konvertieren. Es stehen zum aktuellen Zeitpunkt folgende zur Verfügung: + + ```sh + make pdf + make epub + make docx + ``` + +Du musst im Kopfbereich der Datei zwingend ein paar Einstellungen vornehmen: + +| Parameter | Beschreibung | +|-------------------------------------------|-------------------------------------------------------------| +| `# === Allgemeine Konfiguration ===` | | +| `TITLE := rust-tutorial` | Dateiname ohne Erweiterung für die Ausgabe nach dem Build | +| `MANUSCRIPT := manuscript` | | +| `MANUSCRIPT := manuscript` | | +| `OUTPUT := build` | | +| `METADATA := metadata/ebook.yaml` | | +| `CSS := styles/ebook.css` | | +| `TEX_EBOOK := styles/ebook-template.tex` | | +| `TEX_PRINT := styles/print-template.tex` | | +| `LOGO := media/logo/logo.png` | Logo für den epub Build | + +--- + +#### Erklärung zum Makefile + +--- + +## Struktur beim schreiben des Buchs + +1. Kapitel sind in Dateien die jeweils von 00 aufsteigend sortiert sind. Pandoc baut sie aufsteigend ins Buch. + Kapitel 1 zB in `10_kapitel1.md`. Die vorstehende 10 steht für 1. Sollte zB Kapitel 1.1 hinzukommen, + dann man diese `11_kapitel1.md` benennen. Hoffe es ist verständlich. +2. Bilder sind nach Kapitel und fortlaufender Nummer sowie einem Hinweis benannt. + +--- + +## Schreiben mit VS-Code + +### Projektinterne Tastenkombinationen mit `.vscode/keybindings.json` + +Zur Vereinfachung und Vereinheitlichung der Bedienung ist in diesem Projekt eine Datei `.vscode/keybindings.json` enthalten. Diese Datei definiert projektweit gültige Tastenkombinationen, die bestimmte Aufgaben in Visual Studio Code auslösen – beispielsweise den PDF-Build aus Markdown heraus. + +> ⚠ Diese Datei ist **verpflichtender Bestandteil des Projekts** und muss bei jeder lokalen Arbeitskopie vorhanden sein. + +--- + +#### Zweck + +Die `keybindings.json` im Projektordner ermöglicht es, projektbezogene Aktionen wie das Erzeugen von PDF-Dokumenten über eine einfache Tastenkombination aufzurufen. Sie ergänzt die zentrale Datei `tasks.json`, in der die ausführbaren Aktionen definiert sind. + +Ein typischer Anwendungsfall ist die Kombination mit einem WSL-basierten Build-Befehl: + +```json +{ + "key": "ctrl+alt+p", + "command": "workbench.action.tasks.runTask", + "args": "Markdown → PDF (Pandoc via WSL)", + "when": "editorLangId == markdown" +} +``` + +Diese Tastenkombination führt den Build-Task `Markdown → PDF (Pandoc via WSL)` aus, der wiederum intern `wsl make pdf` ausführt. + +#### Einbindung in Visual Studio Code + +Visual Studio Code erlaubt von Haus aus keine automatische Nutzung Projektinterne `keybindings.json`-Dateien. Daher muss der Inhalt aus `.vscode/keybindings.json` **manuell** in das globale Benutzerprofil übernommen werden: + +#### 🔧 Vorgehen + +1. Öffne in VS Code die Tastenkombination `Strg + Shift + P` +2. Wähle: + `Preferences: Open Keyboard Shortcuts (JSON)` +3. Kopiere den Inhalt aus der Datei `.vscode/keybindings.json` ins geöffnete Profil +4. Speichern, fertig + +> 💬 Alternativ kann die Datei bei einer Neuinstallation auch einfach in den globalen Pfad kopiert werden. Unter Windows befindet sich dieser unter `%APPDATA%\Code\User\keybindings.json`. + +#### Empfehlung + +Es wird empfohlen, regelmäßig zu prüfen, ob die Projektinterne `keybindings.json` aktualisiert wurde (z. B. durch einen Pull). Neue Funktionen oder Workflows können dort neue Tastenkombinationen erhalten. + +#### Hinweis zur Konsistenz + +Um eine konsistente Bedienbarkeit zu gewährleisten, sollte **ausschließlich die im Projekt enthaltene `keybindings.json` verwendet werden**. Eigene globale Kürzel sollten nach Möglichkeit vermieden oder dokumentiert angepasst werden. + +--- + +## Nützliche Links und Tipps für den Author + +- **Zeichen Testen** + -> + +Oder `hexdump` aus: + +```sh +sudo apt install bsdmainutils +``` + +--- + +## Lizenz + +**(C) 2025 - Adam Skotarczak** + +--- diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..a6a2a26 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.0.alpha-1 diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..0d0316e --- /dev/null +++ b/config.mk @@ -0,0 +1,31 @@ +# === Allgemeine Konfiguration === + +# === Titel des eBooks OHNE Dateiendung === +TITLE := Handbuch-Codesys +# === Verzeichnis mit Markdown-Dateien === +MANUSCRIPT := manuscript +# === Ausgabeordner für Builds === +OUTPUT := build +# === Metadaten für das eBook === +METADATA := metadata/ebook.yaml +# === CSS-Datei für das eBook === +CSS := styles/ebook.css +# === LaTeX-Vorlage für das eBook === +TEX_EBOOK := styles/ebook-template.tex +# === LaTeX-Vorlage für den Druck === +TEX_PRINT := styles/print-template.tex +# === Logo für das eBook === +LOGO := media/logo/logo.png +# === Pfad zu Hilfswerkzeugen === +TOOLPATH := tools +# === LaTeX Geometrie-Einstellungen (z.B. A5-Papier) === +GEOMETRY := geometry:a4paper +# === Schriftart für LaTeX === +FONT := Noto Sans CJK SC +# === Python Index für make toc === +INDEXFILE := INHALT +# === Verzeichnistiefe im eBook === +TOCDEPTH := 3 +# Dateien auslassen im MODE prod +EXCLUDE_prod := \ + $(MANUSCRIPT)/0000_Deckblatt.md \ diff --git a/manuscript/0000_Deckblatt.md b/manuscript/0000_Deckblatt.md new file mode 100644 index 0000000..2cbdfd9 --- /dev/null +++ b/manuscript/0000_Deckblatt.md @@ -0,0 +1,80 @@ +# Informationen zu diesen Handbuch {-} + +**Deckblatt** + +Dieses Seite sollte nur vorhanden sein, wenn der Build mit dem Parameter `MODE=dev` erstellt wird. + +- **Dieses Buch hat digitale Anlagen zum Download** +- **Diese findest Du hier:** + + +--- + +- **Updates:** + + Auf dem Cover dieses Buchs im PDF-Format, findest Du eine `Buildversion`. + Diese gibt Dir Auskunft wie aktuell Deine Ausgabe ist. + Kleine Änderungen und Berichtigungen, werden in der Onlineversion sofort durchgeführt und Du kannst diese herunterladen. + Mit jeder vollen Versionsbezeichnung, gibt es eine neue Printversion des Buchs (1.0.0 ... 2.0.0 etc.). + +--- + +- **Information zur Buildversion des Buchs** + +```plaintext + v1.0.0 + │ │ └─ Fehlerkorrektur + │ └─── Inhaltliche Änderung + └───── Erweiterung z.B neues Kapitel +``` + +## LaTEx und Pandoc tests {-} + +Nachfolgend ein paar Tests, die eigentlich nur während der Entwicklung dieses Buchs hier vorhanden sein sollten. + +- **Fußnote - Test[^test]** + +[^test]: Diese Ausgabe sollte als Fussnote erscheinen. + +--- + +\newpage + +- **Codebeispiele** + Ich versuche Codebeispiele, die länger als 2-3 Zeilen sind stets auf einer neuen Seite zu beginnen. + + ```rust + let test: i16 = 4711; + + pub fn add(left: u64, right: u64) -> u64 { + left + right + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } + } + ``` + +--- + +- **Symboltest** + + - Symbole normal: + ✓ ✗ ⚠ ➤ ✎ ☑ + + - Symbole im Codeblock: + + ```text + ✓ ✗ ⚠ ➤ ✎ ☑ + ``` + +Es folgt ein Seitenumbruch: + +\newpage diff --git a/manuscript/0005_Vorwort.md b/manuscript/0005_Vorwort.md new file mode 100644 index 0000000..f927eee --- /dev/null +++ b/manuscript/0005_Vorwort.md @@ -0,0 +1,3 @@ +# Vorwort {-} + +\newpage diff --git a/manuscript/0050_Einleitung.md b/manuscript/0050_Einleitung.md new file mode 100644 index 0000000..0d11d34 --- /dev/null +++ b/manuscript/0050_Einleitung.md @@ -0,0 +1,104 @@ +# Einführung in ST und PLC-Programmierung mit CODESYS + +## Was ist ST (Structured Text)? + +**Structured Text (ST)** ist eine der fünf standardisierten Programmiersprachen nach IEC 61131-3 zur Programmierung von speicherprogrammierbaren Steuerungen (SPS). Es ist eine textbasierte Hochsprache, die an Pascal oder Ada erinnert. + +### Merkmale + +- Klare, strukturierte Syntax +- Unterstützt Kontrollstrukturen wie `IF`, `CASE`, `FOR`, `WHILE`, `REPEAT` +- Unterstützt Funktionen, Funktionsbausteine und Prozeduren +- Ideal für komplexe Berechnungen und Algorithmen +- Bessere Lesbarkeit für Entwickler mit klassischem Programmierhintergrund + +--- + +## Grundstruktur eines ST-Programms + +```pascal +VAR + x: BOOL; + counter: INT := 0; +END_VAR + +IF x THEN + counter := counter + 1; +END_IF; +``` + +--- + +## Was ist CODESYS? + +**CODESYS** ist eine IEC-61131-3-konforme, herstellerunabhängige Entwicklungsumgebung zur Programmierung von SPS. Es unterstützt mehrere Programmiersprachen und viele Zielsysteme (Controller unterschiedlicher Hersteller). + +### Hauptfunktionen + +- Unterstützung aller IEC-61131-3-Sprachen inkl. ST +- Grafische und textbasierte Editoren +- Integrierter Simulator +- Visualisierung und Debugging-Werkzeuge +- Unterstützung für Industrieprotokolle (CAN, Modbus, EtherCAT usw.) + +--- + +## Typische Elemente der ST-Programmierung in CODESYS + +| Element | Beschreibung | +| --------------------------------------- | ---------------------------------------------------- | +| `VAR`/`VAR_INPUT` | Definition von Variablen und Eingängen | +| `PROGRAM`, `FUNCTION_BLOCK`, `FUNCTION` | Kapselung von Logik in wiederverwendbaren Bausteinen | +| `IF`, `CASE`, `FOR` | Kontrollstrukturen | +| `TON`, `TP`, `CTU` | Standard-Funktionsbausteine für Timer und Zähler | +| `PLC_PRG` | Hauptprogramm eines CODESYS-Projekts | + +--- + +## Beispiel: Zähler mit ST in CODESYS + +```pascal +PROGRAM PLC_PRG +VAR + btnStart: BOOL; + counter: INT := 0; +END_VAR + +IF btnStart THEN + counter := counter + 1; +END_IF; +``` + +--- + +## Vorteile von ST in der Praxis + +- **Modularität**: Komplexe Funktionen lassen sich leicht kapseln und wiederverwenden. +- **Lesbarkeit**: Insbesondere für Entwickler mit Hintergrund in klassischen Sprachen. +- **Flexibilität**: Kombination mit grafischen Sprachen (FBD, LD) im selben Projekt möglich. + +--- + +## Typischer Ablauf bei der Entwicklung mit ST in CODESYS + +1. **Projekt erstellen** (z. B. „Standardprojekt“) +2. **Zielgerät auswählen** (Controller oder CODESYS Control Win) +3. **Programmstruktur erstellen** (`PLC_PRG`, Funktionsbausteine, etc.) +4. **Variablen definieren** +5. **Logik in ST schreiben** +6. **Simulation oder Download auf Steuerung** +7. **Test und Debugging** +8. **Visualisierung (optional)** + +--- + +## Literatur und Weiteres + +- **IEC 61131-3 Norm** +- **Offizielle CODESYS-Dokumentation** +- **ST-Referenzhandbuch** +- **OpenPLC Projekt (freies ST-Lernumfeld)** + +--- + +\newpage diff --git a/manuscript/0990_Glossar.md b/manuscript/0990_Glossar.md new file mode 100644 index 0000000..1b1715c --- /dev/null +++ b/manuscript/0990_Glossar.md @@ -0,0 +1,3 @@ +# Glossar {-} + +Glossar optional diff --git a/media/logo/icon-codesys.ico b/media/logo/icon-codesys.ico new file mode 100644 index 0000000..2a9ebce Binary files /dev/null and b/media/logo/icon-codesys.ico differ diff --git a/media/logo/logo-codesys.png b/media/logo/logo-codesys.png new file mode 100644 index 0000000..5ac9737 Binary files /dev/null and b/media/logo/logo-codesys.png differ diff --git a/media/logo/logo.png b/media/logo/logo.png new file mode 100644 index 0000000..095b71e Binary files /dev/null and b/media/logo/logo.png differ diff --git a/metadata/author.txt b/metadata/author.txt new file mode 100644 index 0000000..89b42db --- /dev/null +++ b/metadata/author.txt @@ -0,0 +1,8 @@ +Autor: Adam Skotarczak +Beschreibung: Elektroniker, CAD-Konstrukteur und FullStack Programmierer Node.js und Rust + +Kontakt: adam@skotarczak.net +Web: https://local.ionivation.com/realAscot/codesys-st-handbuch +GIT: ssh://git@local.ionivation.com:2222/realAscot/codesys-st-handbuch.git + +© 2024-2025 - Lorenz Industrietechnik GmbH. Alle Rechte vorbehalten. diff --git a/metadata/ebook.yaml b/metadata/ebook.yaml new file mode 100644 index 0000000..55c3da5 --- /dev/null +++ b/metadata/ebook.yaml @@ -0,0 +1,8 @@ +title: "Codesys ST Handbuch" +subtitle: "Programmieren mit Sturuktuierten Text" +author: "Adam Skotarczak" +lang: de-DE +rights: "© 2025 - Adam Skotarczak" +date: 2025-01-01 +description: | + Handbuch für die Programmierung mit ST in Codesys diff --git a/styles/ebook-template.tex b/styles/ebook-template.tex new file mode 100644 index 0000000..56998f0 --- /dev/null +++ b/styles/ebook-template.tex @@ -0,0 +1,53 @@ +\documentclass[11pt,a4paper]{article} + +\usepackage{fontspec} +\setmainfont{DejaVu Sans} + +\usepackage[ngerman]{babel} +\usepackage{parskip} +\usepackage{geometry} +\geometry{margin=2.5cm} +\usepackage{graphicx} +\usepackage{titlesec} +\usepackage{fancyhdr} +\usepackage{hyperref} +\usepackage{emptypage} + +% Kapitel auf neuer Seite +\newcommand{\sectionbreak}{\clearpage} +\titleformat{\section}{\normalfont\Large\bfseries}{\thesection}{1em}{} + +% Layout-Kopfzeile +\pagestyle{fancy} +\fancyhf{} +\rhead{$title$} +\lhead{$author$} +\rfoot{\thepage} + +% Titelseite +\title{ + \includegraphics[width=0.3\textwidth]{media/logo/logo.png} \\[2em] + {\Huge $title$} \\ + \vspace{1em} + \Large $subtitle$ +} + +\author{$for(author)$$author$$sep$ \and $endfor$} +\date{$date$} + +\begin{document} + +\thispagestyle{empty} +\maketitle +\clearpage + +\pagestyle{empty} +\tableofcontents +\clearpage + +\pagestyle{fancy} +\setcounter{page}{1} + +$body$ + +\end{document} diff --git a/styles/ebook.css b/styles/ebook.css new file mode 100644 index 0000000..4522363 --- /dev/null +++ b/styles/ebook.css @@ -0,0 +1,53 @@ +/* Basislayout für eBook-Reader & Browser */ +body { + font-family: "DejaVu Sans", sans-serif; + font-size: 1.05em; + line-height: 1.6; + color: #111; + background: #fff; + margin: 1em; + padding: 0; +} + +/* Kapitelüberschriften */ +h1, h2, h3 { + font-family: "DejaVu Sans", sans-serif; + font-weight: bold; + margin-top: 2em; + page-break-before: always; +} + +/* Inhaltsverzeichnis-Stil */ +nav.toc { + font-size: 0.95em; + margin-bottom: 2em; +} + +/* Bilder */ +img { + max-width: 100%; + height: auto; + display: block; + margin: 1.5em auto; + border: 0; +} + +/* Code und Inline-Code */ +code { + font-family: monospace; + background-color: #f4f4f4; + padding: 0.2em 0.4em; + border-radius: 3px; +} + +pre { + background-color: #f4f4f4; + padding: 1em; + overflow-x: auto; + border-radius: 4px; +} + +/* Seitenumbruch vor jedem Kapitel */ +h1 { + page-break-before: always; +} diff --git a/styles/print-template.tex b/styles/print-template.tex new file mode 100644 index 0000000..7441771 --- /dev/null +++ b/styles/print-template.tex @@ -0,0 +1,114 @@ +% Tex Template für Rust Handbuch +% © 2025 - Adam Skotarczak + +\documentclass[11pt,a4paper]{article} + +% Workaround für Pandoc: tightlist definieren +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} + +\usepackage{xfp} % <-- ganz nach oben! +\usepackage{expl3} % <-- optional, bei manchen TeX-Installationen nötig + +% Schriftarten +\usepackage{fontspec} +\setmainfont{DejaVu Sans} +\setmonofont{DejaVu Sans Mono} +%\setmonofont{Symbola} +%\setmonofont{Fira Code} +%\newfontfamily\emoji{Noto Color Emoji} + +\usepackage[ngerman]{babel} +\usepackage{parskip} +\usepackage{geometry} +\geometry{margin=2.5cm} +\usepackage{graphicx} +\usepackage[utf8]{inputenc} +\usepackage{xcolor} +\usepackage{titlesec} +\usepackage{fancyhdr} +\usepackage{hyperref} +\usepackage{emptypage} +\usepackage{longtable} +\usepackage{booktabs} +\usepackage{longtable} +\usepackage{array} +\usepackage{booktabs} +\usepackage{tabularx} + +\newcolumntype{L}[1]{>{\raggedright\arraybackslash}p{#1}} % optional +\newcolumntype{C}[1]{>{\centering\arraybackslash}p{#1}} % optional +\newcolumntype{R}[1]{>{\raggedleft\arraybackslash}p{#1}} % optional + +\usepackage{calc} +\usepackage{amssymb} % Mathematische Sonderzeichen wie \boxtimes, \triangle +\usepackage{pifont} % Dingbats (z. B. \ding, \XSolidBrush) +\usepackage{marvosym} % Zusätzliche Symbole wie \CircledR +\usepackage{wasysym} % Wetter-, Smileys und andere graphische Symbole + +% für Pandoc-Tabellen +$if(tables)$ +\usepackage{longtable,booktabs,array} +$endif$ + +% Verzeichnistiefe (aus Makefile TOCDEEP) +\setcounter{tocdepth}{$toc-depth$} + +% Fallback-Makros für Pandoc Highlighting +$if(highlighting-macros)$ +$highlighting-macros$ +$endif$ + +% Codeblöcke (Pandoc Highlighting) +\usepackage{color} +\usepackage{framed} +\usepackage{fancyvrb} + +% Kapitel auf neuer Seite +\newcommand{\sectionbreak}{\clearpage} +\titleformat{\section}{\normalfont\Large\bfseries}{\thesection}{1em}{} + +% Titel +\title{ + \includegraphics[width=0.3\textwidth]{media/logo/logo.png} \\[2em] + {\Huge $title$} \\ + \vspace{1em} + \Large $subtitle$ +} + +\author{$for(author)$$author$$sep$ \and $endfor$} +\date{ + $date$\\ + \vspace{5ex} + {\color{gray}\small Build: v$version$ ($buildmode$)}\\ % <-- Umbruch hinzugefügt + %{\color{gray}\small Anlagenversion: v$maschineversion$} +} + +% --- Schriftart für Codeblöcke verkleinern --- +\makeatletter +\def\verbatim@font{\scriptsize\ttfamily} +\makeatother + +\begin{document} + +% Titelseite OHNE Seitenzahl +\pagestyle{empty} +\maketitle +\thispagestyle{empty} +\clearpage + +% Inhaltsverzeichnis OHNE Seitenzahl +\tableofcontents +\clearpage + +% Seitenzahlen ab hier: fancy mit Kopf-/Fußzeile +\pagestyle{fancy} +\fancyhf{} +\rhead{$title$} +\lhead{$author$} +\rfoot{\thepage} +\setcounter{page}{1} + +$body$ + +\end{document} diff --git a/styles/reference.docx b/styles/reference.docx new file mode 100644 index 0000000..5867d60 Binary files /dev/null and b/styles/reference.docx differ diff --git a/tools/dev-setup.sh b/tools/dev-setup.sh new file mode 100644 index 0000000..c98db13 --- /dev/null +++ b/tools/dev-setup.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# dev-setup.sh +# Erstellt Git-Hook, der beim Branchwechsel eine Datei mit dem Branch-Namen erstellt + +HOOK_PATH=".git/hooks/post-checkout" + +echo "⚙️ Richte Git-Hook ein für Branch-Datei (z. B. BRANCH-MAIN)..." + +# Prüfe ob .git-Verzeichnis existiert +if [ ! -d .git ]; then + echo "❌ Dieses Skript muss im Root eines Git-Repositories ausgeführt werden." + exit 1 +fi + +# Hook-Inhalt +read -r -d '' HOOK_SCRIPT <<'EOF' +#!/bin/sh +branch=$(git rev-parse --abbrev-ref HEAD) + +# Entferne alte BRANCH-* Dateien +rm -f BRANCH-* + +# Erzeuge neue Datei mit aktuellem Branchnamen +touch "BRANCH-${branch}" +EOF + +# Hook schreiben +echo "$HOOK_SCRIPT" > "$HOOK_PATH" +chmod +x "$HOOK_PATH" + +echo "✅ Git-Hook erstellt: $HOOK_PATH" +echo "📄 Beispiel: BRANCH-main wird erstellt beim Wechsel auf 'main'" diff --git a/tools/gitcopy.bat b/tools/gitcopy.bat new file mode 100644 index 0000000..b1e4d84 --- /dev/null +++ b/tools/gitcopy.bat @@ -0,0 +1,161 @@ +@echo off +setlocal enabledelayedexpansion +chcp 65001 >nul + +REM Skript, um aus einem Projekt mit git-repo, ein portables .zip zu erstellen +REM +REM (C) 2025 MIT - Adam Skotarczak +REM +REM Version: v1.1.2 +REM Github: https://github.com/realAscot/gitcopy +REM ------------------------------------------------------------------- + + +rem --- Git-Verfügbarkeit prüfen --- +where git >nul 2>nul +if errorlevel 1 ( + echo. + echo [⚠️] Git ist nicht installiert oder nicht im PATH. + echo [📦] Bitte installiere Git von https://git-scm.com/download/win + call :show_help + echo. + exit /b 1 +) + +rem --- Git-Version anzeigen --- +for /f "tokens=*" %%i in ('git --version') do set "GIT_VERSION=%%i" + +if defined GIT_VERSION ( + echo. + echo [✅] Gefundene Git-Version: %GIT_VERSION% +) else ( + echo([⚠️] Konnte Git-Version nicht ermitteln. +) + +rem Prüfe auf optionalen Parameter "--debug" +set DEBUG=0 + +if NOT "%~1"=="" ( + if "%~1"=="--debug" ( + set DEBUG=1 + echo [⚠️] Debug-Modus aktiv: Ignoriere offene Commits. + exit /b 0 + ) else if "%~1"=="-d" ( + set DEBUG=1 + echo [⚠️] Debug-Modus aktiv: Ignoriere offene Commits. + exit /b 0 + ) else if "%~1"=="-h" ( + call :show_help + exit /b 0 + ) else if "%~1"=="--help" ( + call :show_help + exit /b 0 + ) else ( + rem Parameter vorhanden aber nicht erkannt. + call :kein_Parameter "%~1" + exit /b 1 + ) +) else ( + call :go "%~1" +) + +exit /b 0 + +:go + +call :generate_timestamp +set ZIP_NAME=projektarchiv-%TIMESTAMP%.zip + +rem ------------------------------------------------------------------- + +pushd %~dp0 + +if %DEBUG%==0 ( + echo [🔍] Prüfe auf uncommitted oder ungetrackte Änderungen... + set "hasChanges=" + for /f "delims=" %%i in ('git status --porcelain') do ( + set "hasChanges=1" + goto :has_changes + ) + echo [✅] Arbeitsverzeichnis ist sauber. +) else ( + echo [⚠️] Prüfschritt übersprungen. +) + +goto :create_zip + +:has_changes +echo. +echo [⚠️] Es sind uncommitted oder ungetrackte Änderungen vorhanden: +echo. +git status --short +echo. +echo [❌] Bitte committe oder stash diese Änderungen, bevor du ein ZIP erstellst. +echo [⚠️] versuche --debug um diese Prüfung zu umgehen aber dann wird das Archiv unvollständig. +echo. +endlocal +pause +exit /b 1 + +:create_zip +echo [💾] Erstelle ZIP-Archiv von HEAD... +git archive --format=zip --output="%ZIP_NAME%" HEAD +if errorlevel 1 ( + echo [⚠️] Fehler beim Erstellen des Archivs. + pause + exit /b 1 +) +echo [✅] Archiv erfolgreich erstellt: %CD%\%ZIP_NAME% +popd +endlocal +pause +exit /b 0 + +:generate_timestamp +rem Erzeugt einen Zeitstempel TTMMJJHHMM sicher und universell +for /f "tokens=1-4 delims=. " %%d in ('echo %DATE%') do ( + set "TAG=0%%d" + set "MONAT=0%%e" + set "JAHR=%%f" +) + +for /f "tokens=1-2 delims=: " %%g in ('echo %TIME%') do ( + set "STUNDE=0%%g" + set "MINUTE=0%%h" +) + +set "TAG=!TAG:~-2!" +set "MONAT=!MONAT:~-2!" +set "JAHR=!JAHR:~-2!" +set "STUNDE=!STUNDE:~-2!" +set "MINUTE=!MINUTE:~-2!" + +set "TIMESTAMP=!TAG!!MONAT!!JAHR!!STUNDE!!MINUTE!" +goto :eof + +:kein_Parameter +echo. +echo [⚠️] Unbekannter Parameter: "%~1" abbruch ... +echo. +call :show_help +exit /b 1 + +:show_help +echo. +echo ℹ️ GitCopy – Hilfe +echo ===================== +echo Erstellt ein ZIP-Archiv vom aktuellen HEAD-Stand des Git-Repositories. +echo (C) MIT 2025 - Adam Skotarczak +echo. +echo Verwendung: +echo gitcopy.bat [Option] +echo. +echo Optionen: +echo --debug / -d Überspringt die Prüfung auf uncommitted oder ungetrackte Änderungen. +echo -h / --help Zeigt diese Hilfe an. +echo. +endlocal +pause +goto :eof + +endlocal \ No newline at end of file diff --git a/tools/tocgen.py b/tools/tocgen.py new file mode 100644 index 0000000..07ea15d --- /dev/null +++ b/tools/tocgen.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import argparse + +"""tocgen.py + + Erstellt aus einem vordefinierten Verzeichnis mit Markdown-Dateien ein Inhaltsverzeichnis. + + (C) 2025 - Adam Skotarczak - Version: 1.0.0 - stand 20/05/2025 +""" + +MANUSKRIPT_DIR = "manuscript" +OUTPUT_PATH = "INHALT2.md" + +from pathlib import Path +import re + +def slugify(text): + return re.sub(r"[^\w\- ]", "", text.lower()).strip().replace(" ", "-") + +def parse_headings(md_file: Path, max_level=3): + lines = md_file.read_text(encoding="utf-8").splitlines() + headings = [] + in_codeblock = False + + for line in lines: + # Umschalten bei ```, egal ob mit oder ohne Sprache + if line.strip().startswith("```"): + in_codeblock = not in_codeblock + continue + if in_codeblock: + continue + + match = re.match(r"^(#{1,3})\s+(.*)", line) + if match: + level = len(match.group(1)) + if level <= max_level: + title = match.group(2).strip() + anchor = slugify(title) + headings.append((level, title, anchor)) + return headings + +def main(): + parser = argparse.ArgumentParser( + description="Erstellt aus einem Verzeichnis mit Markdown-Dateien ein Inhaltsverzeichnis." + ) + parser.add_argument( + "-d", "--dir", default=MANUSKRIPT_DIR, help="Verzeichnis mit Markdown-Dateien (Standard: manuscript)" + ) + parser.add_argument( + "-o", "--output", default=OUTPUT_PATH, help="Pfad für die Ausgabedatei (Standard: INHALT.md)" + ) + args = parser.parse_args() + + generate_toc(args.dir, args.output) + +def generate_toc(manuskript_dir=MANUSKRIPT_DIR, output_path=OUTPUT_PATH): + manuskript_dir = Path(manuskript_dir) + index_path = Path(output_path) + toc_lines = ["# **Inhalt**\n"] + + for md_file in sorted(manuskript_dir.glob("*.md")): + rel_path = md_file.as_posix() + headings = parse_headings(md_file) + for level, title, anchor in headings: + indent = " " * (level - 1) + link = f"{rel_path}#{anchor}" if level > 1 else rel_path + toc_lines.append(f"{indent}- [{title}]({link})") + + index_path.write_text("\n".join(toc_lines) + "\n", encoding="utf-8") + +if __name__ == "__main__": + main() +