Track PDF generation failures and exit with non-zero code if any PDFs fail to build. This ensures CI properly detects build failures. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
316 lines
8.8 KiB
Bash
Executable File
316 lines
8.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# ClearGrow Documentation PDF Builder
|
|
# Requires: pandoc, texlive-xetex, texlive-fonts-recommended
|
|
|
|
# Don't exit on error - handle errors gracefully
|
|
set +e
|
|
|
|
DOCS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
OUTPUT_DIR="${DOCS_DIR}/pdf-output"
|
|
PANDOC_DIR="${DOCS_DIR}/pandoc"
|
|
|
|
# Track build failures
|
|
BUILD_FAILURES=0
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Pandoc options for XeLaTeX (supports Unicode box-drawing characters)
|
|
PANDOC_OPTS=(
|
|
--pdf-engine=xelatex
|
|
--from=markdown+yaml_metadata_block
|
|
-V geometry:margin=1in
|
|
-V mainfont="DejaVu Sans"
|
|
-V monofont="DejaVu Sans Mono"
|
|
-V fontsize=11pt
|
|
-V colorlinks=true
|
|
-V linkcolor=blue
|
|
-V urlcolor=blue
|
|
)
|
|
|
|
# Check dependencies
|
|
check_deps() {
|
|
echo "Checking dependencies..."
|
|
if ! command -v pandoc &> /dev/null; then
|
|
echo -e "${RED}Error: pandoc not found. Install with: apt-get install pandoc${NC}"
|
|
exit 1
|
|
fi
|
|
if ! command -v xelatex &> /dev/null; then
|
|
echo -e "${RED}Error: xelatex not found. Install with: apt-get install texlive-xetex${NC}"
|
|
exit 1
|
|
fi
|
|
echo -e "${GREEN}Dependencies OK${NC}"
|
|
}
|
|
|
|
# Strip YAML frontmatter from markdown files and concatenate
|
|
# Also converts --- horizontal rules to *** to avoid YAML confusion
|
|
concat_markdown_files() {
|
|
local output_file="$1"
|
|
shift
|
|
local files=("$@")
|
|
|
|
> "${output_file}" # Clear/create output file
|
|
|
|
for f in "${files[@]}"; do
|
|
# Use awk to:
|
|
# 1. Strip YAML frontmatter (content between --- markers at start of file)
|
|
# 2. Convert remaining --- to *** (horizontal rules)
|
|
awk '
|
|
BEGIN { in_frontmatter = 0; started = 0; past_frontmatter = 0 }
|
|
/^---$/ && !started {
|
|
in_frontmatter = 1
|
|
started = 1
|
|
next
|
|
}
|
|
/^---$/ && in_frontmatter {
|
|
in_frontmatter = 0
|
|
past_frontmatter = 1
|
|
next
|
|
}
|
|
/^---$/ && past_frontmatter {
|
|
print "***" # Convert horizontal rule to asterisks
|
|
next
|
|
}
|
|
!in_frontmatter { print }
|
|
' "$f" >> "${output_file}"
|
|
echo "" >> "${output_file}" # Add blank line between files
|
|
done
|
|
}
|
|
|
|
# Create output directory
|
|
setup_output() {
|
|
mkdir -p "${OUTPUT_DIR}"
|
|
echo "Output directory: ${OUTPUT_DIR}"
|
|
}
|
|
|
|
# Build User Quick Start Guide
|
|
build_user_quickstart() {
|
|
echo "Building User Quick Start Guide..."
|
|
|
|
local output="${OUTPUT_DIR}/ClearGrow_User_QuickStart.pdf"
|
|
local input_files=(
|
|
"${DOCS_DIR}/guides/user/getting-started/unboxing.md"
|
|
"${DOCS_DIR}/guides/user/getting-started/first-run.md"
|
|
"${DOCS_DIR}/guides/user/getting-started/pairing-probes.md"
|
|
)
|
|
|
|
# Check if files exist
|
|
local existing_files=()
|
|
for f in "${input_files[@]}"; do
|
|
if [[ -f "$f" ]]; then
|
|
existing_files+=("$f")
|
|
fi
|
|
done
|
|
|
|
if [[ ${#existing_files[@]} -eq 0 ]]; then
|
|
echo -e "${YELLOW} Skipped: No source files found${NC}"
|
|
return
|
|
fi
|
|
|
|
if pandoc "${existing_files[@]}" \
|
|
"${PANDOC_OPTS[@]}" \
|
|
--metadata title="ClearGrow User Quick Start" \
|
|
--metadata author="ClearGrow Documentation Team" \
|
|
--metadata date="$(date +%Y-%m)" \
|
|
--toc \
|
|
--toc-depth=2 \
|
|
-o "${output}" 2>&1; then
|
|
echo -e "${GREEN} Created: ${output}${NC}"
|
|
else
|
|
echo -e "${RED} Failed to create: ${output}${NC}"
|
|
((BUILD_FAILURES++))
|
|
fi
|
|
}
|
|
|
|
# Build Complete User Guide
|
|
build_user_complete() {
|
|
echo "Building Complete User Guide..."
|
|
|
|
local output="${OUTPUT_DIR}/ClearGrow_User_Guide.pdf"
|
|
|
|
# Find all user guide markdown files
|
|
local input_files=()
|
|
while IFS= read -r -d '' file; do
|
|
input_files+=("$file")
|
|
done < <(find "${DOCS_DIR}/guides/user" -name "*.md" -type f -print0 | sort -z)
|
|
|
|
if [[ ${#input_files[@]} -eq 0 ]]; then
|
|
echo -e "${YELLOW} Skipped: No source files found${NC}"
|
|
return
|
|
fi
|
|
|
|
if pandoc "${input_files[@]}" \
|
|
"${PANDOC_OPTS[@]}" \
|
|
--metadata title="ClearGrow User Guide" \
|
|
--metadata author="ClearGrow Documentation Team" \
|
|
--metadata date="$(date +%Y-%m)" \
|
|
--toc \
|
|
--toc-depth=3 \
|
|
-o "${output}" 2>&1; then
|
|
echo -e "${GREEN} Created: ${output}${NC}"
|
|
else
|
|
echo -e "${RED} Failed to create: ${output}${NC}"
|
|
((BUILD_FAILURES++))
|
|
fi
|
|
}
|
|
|
|
# Build Developer Guide
|
|
build_developer_guide() {
|
|
echo "Building Developer Guide..."
|
|
|
|
local output="${OUTPUT_DIR}/ClearGrow_Developer_Guide.pdf"
|
|
|
|
# Find all developer guide markdown files
|
|
local input_files=()
|
|
while IFS= read -r -d '' file; do
|
|
input_files+=("$file")
|
|
done < <(find "${DOCS_DIR}/guides/developer" -name "*.md" -type f -print0 | sort -z)
|
|
|
|
if [[ ${#input_files[@]} -eq 0 ]]; then
|
|
echo -e "${YELLOW} Skipped: No source files found${NC}"
|
|
return
|
|
fi
|
|
|
|
if pandoc "${input_files[@]}" \
|
|
"${PANDOC_OPTS[@]}" \
|
|
--metadata title="ClearGrow Developer Guide" \
|
|
--metadata author="ClearGrow Documentation Team" \
|
|
--metadata date="$(date +%Y-%m)" \
|
|
--toc \
|
|
--toc-depth=3 \
|
|
-o "${output}" 2>&1; then
|
|
echo -e "${GREEN} Created: ${output}${NC}"
|
|
else
|
|
echo -e "${RED} Failed to create: ${output}${NC}"
|
|
((BUILD_FAILURES++))
|
|
fi
|
|
}
|
|
|
|
# Build API Reference
|
|
build_api_reference() {
|
|
echo "Building API Reference..."
|
|
|
|
local output="${OUTPUT_DIR}/ClearGrow_API_Reference.pdf"
|
|
|
|
# Find all API reference markdown files
|
|
local input_files=()
|
|
while IFS= read -r -d '' file; do
|
|
input_files+=("$file")
|
|
done < <(find "${DOCS_DIR}/reference/api" -name "*.md" -type f -print0 | sort -z)
|
|
|
|
if [[ ${#input_files[@]} -eq 0 ]]; then
|
|
echo -e "${YELLOW} Skipped: No source files found${NC}"
|
|
return
|
|
fi
|
|
|
|
if pandoc "${input_files[@]}" \
|
|
"${PANDOC_OPTS[@]}" \
|
|
--metadata title="ClearGrow API Reference" \
|
|
--metadata author="ClearGrow Documentation Team" \
|
|
--metadata date="$(date +%Y-%m)" \
|
|
--toc \
|
|
--toc-depth=3 \
|
|
-o "${output}" 2>&1; then
|
|
echo -e "${GREEN} Created: ${output}${NC}"
|
|
else
|
|
echo -e "${RED} Failed to create: ${output}${NC}"
|
|
((BUILD_FAILURES++))
|
|
fi
|
|
}
|
|
|
|
# Build Full Technical Manual
|
|
build_technical_manual() {
|
|
echo "Building Full Technical Manual..."
|
|
|
|
local output="${OUTPUT_DIR}/ClearGrow_Technical_Manual.pdf"
|
|
local temp_combined="${OUTPUT_DIR}/.technical_manual_combined.md"
|
|
|
|
# Find all reference markdown files
|
|
local input_files=()
|
|
while IFS= read -r -d '' file; do
|
|
input_files+=("$file")
|
|
done < <(find "${DOCS_DIR}/reference" -name "*.md" -type f -print0 | sort -z)
|
|
|
|
if [[ ${#input_files[@]} -eq 0 ]]; then
|
|
echo -e "${YELLOW} Skipped: No source files found${NC}"
|
|
return
|
|
fi
|
|
|
|
# Concatenate files with YAML frontmatter stripped
|
|
concat_markdown_files "${temp_combined}" "${input_files[@]}"
|
|
|
|
if pandoc "${temp_combined}" \
|
|
"${PANDOC_OPTS[@]}" \
|
|
--metadata title="ClearGrow Technical Manual" \
|
|
--metadata author="ClearGrow Documentation Team" \
|
|
--metadata date="$(date +%Y-%m)" \
|
|
--toc \
|
|
--toc-depth=3 \
|
|
-o "${output}" 2>&1; then
|
|
echo -e "${GREEN} Created: ${output}${NC}"
|
|
else
|
|
echo -e "${RED} Failed to create: ${output}${NC}"
|
|
((BUILD_FAILURES++))
|
|
fi
|
|
|
|
rm -f "${temp_combined}"
|
|
}
|
|
|
|
# Main
|
|
main() {
|
|
echo "========================================"
|
|
echo "ClearGrow Documentation PDF Builder"
|
|
echo "========================================"
|
|
echo ""
|
|
|
|
check_deps
|
|
setup_output
|
|
echo ""
|
|
|
|
case "${1:-all}" in
|
|
user-quickstart)
|
|
build_user_quickstart
|
|
;;
|
|
user)
|
|
build_user_complete
|
|
;;
|
|
developer)
|
|
build_developer_guide
|
|
;;
|
|
api)
|
|
build_api_reference
|
|
;;
|
|
technical)
|
|
build_technical_manual
|
|
;;
|
|
all)
|
|
build_user_quickstart
|
|
build_user_complete
|
|
build_developer_guide
|
|
build_api_reference
|
|
build_technical_manual
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [user-quickstart|user|developer|api|technical|all]"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
echo ""
|
|
echo "========================================"
|
|
if [[ ${BUILD_FAILURES} -gt 0 ]]; then
|
|
echo -e "${RED}Build completed with ${BUILD_FAILURES} failure(s)${NC}"
|
|
echo "========================================"
|
|
exit 1
|
|
else
|
|
echo -e "${GREEN}Build complete. Output in: ${OUTPUT_DIR}${NC}"
|
|
echo "========================================"
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
main "$@"
|