Add md-to-docx: markdown to DOCX converter using pandoc

Converts markdown files to DOCX with optional reference doc styling.
Supports front matter stripping and custom output paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul O'Reilly
2026-03-17 11:14:30 +13:00
parent cbde292dd7
commit 77af82c88c
3 changed files with 501 additions and 0 deletions

140
tests/test-md-to-docx.sh Executable file
View File

@@ -0,0 +1,140 @@
#!/usr/bin/env bash
# Test md-to-docx script via --dryrun mode
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
SCRIPT="$SCRIPT_DIR/scripts/md-to-docx"
PASS=0
FAIL=0
TMPDIR=$(mktemp -d)
cleanup() { rm -rf "$TMPDIR"; }
trap cleanup EXIT
green() { printf "\033[32m%s\033[0m\n" "$1"; }
red() { printf "\033[31m%s\033[0m\n" "$1"; }
assert_contains() {
local label="$1" output="$2" expected="$3"
if echo "$output" | grep -qF "$expected"; then
green " PASS: $label"
PASS=$((PASS + 1))
else
red " FAIL: $label"
red " Expected to contain: $expected"
red " Got: $output"
FAIL=$((FAIL + 1))
fi
}
assert_exit_code() {
local label="$1" actual="$2" expected="$3"
if [ "$actual" -eq "$expected" ]; then
green " PASS: $label"
PASS=$((PASS + 1))
else
red " FAIL: $label (expected exit $expected, got $actual)"
FAIL=$((FAIL + 1))
fi
}
# --- Setup test fixtures ---
cat > "$TMPDIR/test.md" << 'EOF'
# Test Document Title
## Introduction
This is a test document with a table.
| Column A | Column B |
|---|---|
| Value 1 | Value 2 |
## References
Some references here.
EOF
cat > "$TMPDIR/no-heading.md" << 'EOF'
This file has no headings at all.
Just plain text.
EOF
# ============================================================
echo "=== Test: dryrun with defaults ==="
output=$("$SCRIPT" --dryrun "$TMPDIR/test.md" 2>&1) || true
assert_contains "shows input path" "$output" "[dryrun] Input:"
assert_contains "shows output path" "$output" "[dryrun] Output:"
assert_contains "extracts title from heading" "$output" "Test Document Title"
assert_contains "shows TOC off" "$output" "TOC: no"
assert_contains "shows dependencies" "$output" "Dependencies OK: pandoc"
assert_contains "shows would generate" "$output" "Would generate styled .docx file"
# ============================================================
echo "=== Test: dryrun with --toc ==="
output=$("$SCRIPT" --dryrun --toc --toc-depth 3 "$TMPDIR/test.md" 2>&1) || true
assert_contains "shows TOC on with depth" "$output" "TOC: yes (depth: 3)"
# ============================================================
echo "=== Test: dryrun with --title override ==="
output=$("$SCRIPT" --dryrun -t "Custom Title" "$TMPDIR/test.md" 2>&1) || true
assert_contains "uses custom title" "$output" "Custom Title"
# ============================================================
echo "=== Test: dryrun with --output override ==="
output=$("$SCRIPT" --dryrun -o "$TMPDIR/custom.docx" "$TMPDIR/test.md" 2>&1) || true
assert_contains "uses custom output path" "$output" "custom.docx"
# ============================================================
echo "=== Test: dryrun with no-heading file ==="
output=$("$SCRIPT" --dryrun "$TMPDIR/no-heading.md" 2>&1) || true
assert_contains "falls back to filename" "$output" "no-heading"
# ============================================================
echo "=== Test: missing input file ==="
output=$("$SCRIPT" --dryrun "$TMPDIR/nonexistent.md" 2>&1) || rc=$?
# Capture exit code properly
set +e
"$SCRIPT" --dryrun "$TMPDIR/nonexistent.md" > /dev/null 2>&1
rc=$?
set -e
assert_exit_code "exits non-zero for missing file" "$rc" 1
output=$("$SCRIPT" --dryrun "$TMPDIR/nonexistent.md" 2>&1) || true
assert_contains "shows file not found error" "$output" "Error: file not found"
# ============================================================
echo "=== Test: --help flag ==="
output=$("$SCRIPT" --help 2>&1) || true
assert_contains "shows usage info" "$output" "Markdown"
# ============================================================
echo "=== Test: actual conversion (creates file) ==="
"$SCRIPT" "$TMPDIR/test.md" > /dev/null 2>&1 || true
if [ -f "$TMPDIR/test.docx" ]; then
green " PASS: docx file created"
PASS=$((PASS + 1))
# Check it's a valid zip (docx is a zip)
if file "$TMPDIR/test.docx" | grep -q "Zip\|Microsoft"; then
green " PASS: output is valid docx/zip format"
PASS=$((PASS + 1))
else
red " FAIL: output is not a valid docx file"
FAIL=$((FAIL + 1))
fi
else
red " FAIL: docx file not created"
FAIL=$((FAIL + 1))
FAIL=$((FAIL + 1)) # count the format check as failed too
fi
# ============================================================
echo ""
echo "==============================="
if [ "$FAIL" -eq 0 ]; then
green "All $PASS tests passed."
else
red "$FAIL tests failed, $PASS passed."
exit 1
fi