#!/usr/bin/env nu # Check for malformed closing code fences in markdown files # Malformed: ```plaintext (closing fence with language specifier) # Correct: ``` (just three backticks) # # Markdownlint does NOT catch this natively (MD040 only checks opening fences) # This is a CommonMark violation that must be checked separately # # Usage: # nu check-malformed-fences.nu # Check all markdown files # nu check-malformed-fences.nu file.md # Check specific file # nu check-malformed-fences.nu **/*.md # Check pattern def main [ ...files: string # Files to check (or empty for all) ] { let md_files = if ($files | is-empty) { glob **/*.md | where { |f| $f !~ "node_modules" } | where { |f| $f !~ "target" } | where { |f| $f !~ ".git" } | where { |f| $f !~ "build" } | where { |f| $f !~ "dist" } | where { |f| $f !~ ".coder" } | where { |f| $f !~ ".claude" } | where { |f| $f !~ "old_config" } } else { $files } mut errors = [] mut checked_count = 0 for file in $md_files { $checked_count = $checked_count + 1 let content = open $file | lines mut in_fence = false mut fence_lang = "" mut fence_start = 0 for line in ($content | enumerate) { let idx = $line.index let text = $line.item # Check if this is a code fence line if ($text =~ '^```') { if not $in_fence { # Opening fence if ($text =~ '^```\w+') { $in_fence = true $fence_lang = ($text | str substring 3..) $fence_start = $idx + 1 } } else { # We're inside a fence, so this must be a closing fence if ($text =~ '^```\w+\s*$') { # MALFORMED: closing fence has language $errors = ($errors | append { file: $file, line: ($idx + 1), fence_opened: $fence_start, opening_lang: $fence_lang, closing_text: $text, }) } # Reset fence state regardless $in_fence = false } } } } print $"🔍 Checked ($checked_count) markdown files" print "" if ($errors | is-empty) { print "✅ No malformed closing fences found" print "" print "All closing fences are correct: ``` (no language specifier)" exit 0 } else { print $"❌ Found ($errors | length) malformed closing fences" print "" print "Closing fences must NOT have language specifiers (CommonMark violation)" print "" for e in $errors { print $" ($e.file):($e.line)" print $" Opened at line ($e.fence_opened) with: ```($e.opening_lang)" print $" ❌ WRONG: ($e.closing_text | str trim)" print $" ✅ FIX TO: ```" print "" } print "How to fix:" print " Replace closing fences like ```plaintext with just ```" print "" exit 1 } }