From 6aecff2eea33bba59735c3e4965181f1d553fb22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Tr=C3=B6ger?= Date: Wed, 22 Apr 2026 10:10:17 +0200 Subject: [PATCH] feat: Markdown-Hook mit Custom-Rule "no-hr" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Erzwingt Struktur über Überschriften statt horizontaler Trennlinien. - Custom Rule hooks/markdownlint-rules/no-hr.js erkennt --- / *** / ___ über das markdown-it-Token "hr" und liefert fixInfo zum Entfernen. - .markdownlint-cli2.jsonc aktiviert no-hr und deaktiviert MD013/MD040/MD041/MD060 (Begründung jeweils inline kommentiert). - hooks/auto-format.sh erweitert um md|markdown-Zweig mit zwei --fix-Pässen (zweiter Pass räumt MD012-Doppel-Leerzeilen auf, die nach HR-Entfernung entstehen). - bootstrap.sh installiert markdownlint-cli2 idempotent via npm -g. Verifiziert: - Custom Rule meldet --- und *** als Verstoß. - Zwei --fix-Pässe entfernen Trennlinien und überflüssige Leerzeilen, Endzustand 0 Fehler. - Bestehende README in /home/martin/Darktable/README.md ist nach Konfig-Anpassung 0 Fehler. Co-Authored-By: Claude Opus 4.7 --- .markdownlint-cli2.jsonc | 18 ++++++++++++++++++ bootstrap.sh | 12 ++++++++++++ hooks/auto-format.sh | 11 +++++++++++ hooks/markdownlint-rules/no-hr.js | 19 +++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 .markdownlint-cli2.jsonc create mode 100644 hooks/markdownlint-rules/no-hr.js diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc new file mode 100644 index 0000000..ada10d7 --- /dev/null +++ b/.markdownlint-cli2.jsonc @@ -0,0 +1,18 @@ +{ + "config": { + "default": true, + // Zeilenlänge: keine harte Grenze in Markdown. + "MD013": false, + // Sprache im Fenced Code Block: oft sinnvoll leer (ASCII-Diagramme, Pfade). + "MD040": false, + // Erste Zeile muss kein H1 sein. + "MD041": false, + // Tabellen-Spacing-Style: Geschmackssache, nicht auto-fixbar. + "MD060": false, + // Eigene Regel: keine horizontalen Trennlinien (Struktur über Überschriften). + "no-hr": true + }, + "customRules": [ + "./hooks/markdownlint-rules/no-hr.js" + ] +} diff --git a/bootstrap.sh b/bootstrap.sh index 8ed7c2a..ce49e66 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -75,6 +75,18 @@ else echo "✓ shellcheck installiert" fi +# --- markdownlint-cli2 (Markdown-Lint-Hook, custom rule no-hr) --- +if command -v markdownlint-cli2 &>/dev/null; then + echo "✓ markdownlint-cli2 $(markdownlint-cli2 --version 2>/dev/null | head -1)" +else + echo " markdownlint-cli2 fehlt – installiere via npm..." + if ! command -v npm &>/dev/null; then + sudo apt-get install -y npm + fi + sudo npm install -g markdownlint-cli2 + echo "✓ markdownlint-cli2 installiert" +fi + # --- gitea-mcp Binary --- if [[ -x ~/go/bin/gitea-mcp ]]; then echo "✓ gitea-mcp vorhanden" diff --git a/hooks/auto-format.sh b/hooks/auto-format.sh index 67cfdfa..0ba9fcd 100755 --- a/hooks/auto-format.sh +++ b/hooks/auto-format.sh @@ -33,6 +33,17 @@ case "$EXT" in shellcheck "$FILE" || true fi ;; + md|markdown) + if command -v markdownlint-cli2 &>/dev/null; then + # Erster Pass: entfernt Trennlinien und sonstige fixbare Verstöße. + # Zweiter Pass: räumt die nun verwaisten Mehrfach-Leerzeilen auf (MD012). + for _ in 1 2; do + markdownlint-cli2 \ + --config /mnt/projekte/claude-workflow/.markdownlint-cli2.jsonc \ + --fix "$FILE" >/dev/null 2>&1 || true + done + fi + ;; esac exit 0 diff --git a/hooks/markdownlint-rules/no-hr.js b/hooks/markdownlint-rules/no-hr.js new file mode 100644 index 0000000..2a46695 --- /dev/null +++ b/hooks/markdownlint-rules/no-hr.js @@ -0,0 +1,19 @@ +/** @type {import("markdownlint").Rule} */ +module.exports = { + names: ["no-hr", "no-horizontal-rules"], + description: "Horizontale Trennlinien sind nicht erlaubt", + tags: ["style"], + parser: "markdownit", + function: (params, onError) => { + for (const token of params.parsers.markdownit.tokens) { + if (token.type !== "hr") continue; + const startLine = token.map[0] + 1; + onError({ + lineNumber: startLine, + detail: "Struktur über Überschriften, nicht über Trennlinien.", + context: token.line, + fixInfo: { lineNumber: startLine, deleteCount: -1 } + }); + } + } +};