mirror of
https://github.com/kuhyx/praca_magisterska.git
synced 2026-07-04 15:43:14 +02:00
269 lines
9.6 KiB
Bash
Executable File
269 lines
9.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# print_questions.sh — Convert and print exam questions from OBRONA_MAGISTERSKA_ODPOWIEDZI.md
|
|
#
|
|
# Usage:
|
|
# ./print_questions.sh [OPTIONS] [QUESTION_NUMBERS...]
|
|
#
|
|
# Examples:
|
|
# ./print_questions.sh # Generate PDF of ALL questions
|
|
# ./print_questions.sh 1 # Generate PDF of question 1
|
|
# ./print_questions.sh 1 3 7 # Generate PDF of questions 1, 3, 7
|
|
# ./print_questions.sh 1-5 # Generate PDF of questions 1 through 5
|
|
# ./print_questions.sh 1 3-5 8 # Mix of individual and ranges
|
|
# ./print_questions.sh --print 1 3 # Generate PDF AND print questions 1, 3
|
|
# ./print_questions.sh --print # Generate PDF AND print ALL questions
|
|
# ./print_questions.sh --list # List available questions
|
|
#
|
|
# Options:
|
|
# --print, -p Send to printer after generating PDF
|
|
# --printer NAME Printer name (default: Brother_HL-1110_series)
|
|
# --list, -l List available questions and exit
|
|
# --output, -o FILE Output PDF path (default: auto-generated in /tmp)
|
|
# --keep, -k Keep intermediate files (for debugging)
|
|
# --help, -h Show this help
|
|
#
|
|
|
|
set -euo pipefail
|
|
|
|
# ── Configuration ──────────────────────────────────────────────────────────────
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
SOURCE_MD="${SCRIPT_DIR}/OBRONA_MAGISTERSKA_ODPOWIEDZI.md"
|
|
PRINTER="Brother_HL-1110_series"
|
|
DO_PRINT=false
|
|
LIST_ONLY=false
|
|
KEEP_TMP=false
|
|
OUTPUT_PDF=""
|
|
QUESTIONS=()
|
|
|
|
# ── Parse arguments ───────────────────────────────────────────────────────────
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--print|-p)
|
|
DO_PRINT=true
|
|
shift
|
|
;;
|
|
--printer)
|
|
PRINTER="$2"
|
|
shift 2
|
|
;;
|
|
--list|-l)
|
|
LIST_ONLY=true
|
|
shift
|
|
;;
|
|
--output|-o)
|
|
OUTPUT_PDF="$2"
|
|
shift 2
|
|
;;
|
|
--keep|-k)
|
|
KEEP_TMP=true
|
|
shift
|
|
;;
|
|
--help|-h)
|
|
head -28 "$0" | tail -26
|
|
exit 0
|
|
;;
|
|
*)
|
|
# Parse question numbers and ranges (e.g., "1", "3-5", "13/27")
|
|
if [[ "$1" =~ ^[0-9]+(\/[0-9]+)?(-[0-9]+(\/[0-9]+)?)?$ ]]; then
|
|
if [[ "$1" == *-* ]]; then
|
|
# Range: extract start-end
|
|
range_start="${1%%-*}"
|
|
range_end="${1##*-}"
|
|
for ((i=range_start; i<=range_end; i++)); do
|
|
QUESTIONS+=("$i")
|
|
done
|
|
else
|
|
QUESTIONS+=("$1")
|
|
fi
|
|
else
|
|
echo "Error: Unknown argument '$1'. Use --help for usage." >&2
|
|
exit 1
|
|
fi
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# ── Verify source file ───────────────────────────────────────────────────────
|
|
if [[ ! -f "$SOURCE_MD" ]]; then
|
|
echo "Error: Source file not found: $SOURCE_MD" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ── List questions ────────────────────────────────────────────────────────────
|
|
list_questions() {
|
|
echo "Available questions in $(basename "$SOURCE_MD"):"
|
|
echo ""
|
|
grep "^## PYTANIE" "$SOURCE_MD" | while IFS= read -r line; do
|
|
# Extract question number and title
|
|
num=$(echo "$line" | sed 's/^## PYTANIE \([0-9/]*\):.*/\1/')
|
|
title=$(echo "$line" | sed 's/^## PYTANIE [0-9/]*: //')
|
|
printf " %6s %s\n" "$num" "$title"
|
|
done
|
|
echo ""
|
|
echo "Total: $(grep -c "^## PYTANIE" "$SOURCE_MD") questions"
|
|
}
|
|
|
|
if $LIST_ONLY; then
|
|
list_questions
|
|
exit 0
|
|
fi
|
|
|
|
# ── Extract questions ─────────────────────────────────────────────────────────
|
|
extract_questions() {
|
|
local md_file="$1"
|
|
shift
|
|
local selected=("$@")
|
|
|
|
if [[ ${#selected[@]} -eq 0 ]]; then
|
|
# All questions — output entire file
|
|
cat "$md_file"
|
|
return
|
|
fi
|
|
|
|
local tmpfile
|
|
tmpfile=$(mktemp)
|
|
local in_question=false
|
|
local current_num=""
|
|
local line_num=0
|
|
|
|
# Build a grep pattern to find question headers with their line numbers
|
|
# Then extract the relevant sections
|
|
local question_starts=()
|
|
local question_labels=()
|
|
|
|
while IFS= read -r line; do
|
|
((line_num++)) || true
|
|
if [[ "$line" =~ ^##\ PYTANIE\ ([0-9]+(/[0-9]+)?): ]]; then
|
|
question_starts+=("$line_num")
|
|
question_labels+=("${BASH_REMATCH[1]}")
|
|
fi
|
|
done < "$md_file"
|
|
|
|
# Total lines in file
|
|
local total_lines
|
|
total_lines=$(wc -l < "$md_file")
|
|
|
|
# For each selected question, find its start and end lines
|
|
local first=true
|
|
for sel in "${selected[@]}"; do
|
|
for i in "${!question_labels[@]}"; do
|
|
local label="${question_labels[$i]}"
|
|
# Match: exact number, or either side of a slash (e.g., "13" matches "13/27")
|
|
local match=false
|
|
if [[ "$label" == "$sel" ]]; then
|
|
match=true
|
|
elif [[ "$label" == */* ]]; then
|
|
local left="${label%%/*}"
|
|
local right="${label##*/}"
|
|
if [[ "$sel" == "$left" || "$sel" == "$right" ]]; then
|
|
match=true
|
|
fi
|
|
fi
|
|
|
|
if $match; then
|
|
local start="${question_starts[$i]}"
|
|
local end="$total_lines"
|
|
|
|
# End = next question start - 1, or EOF
|
|
local next=$((i + 1))
|
|
if [[ $next -lt ${#question_starts[@]} ]]; then
|
|
end=$(( ${question_starts[$next]} - 1 ))
|
|
fi
|
|
|
|
# Strip trailing blank lines and \newpage
|
|
if ! $first; then
|
|
echo ""
|
|
echo "\\newpage"
|
|
echo ""
|
|
fi
|
|
first=false
|
|
|
|
sed -n "${start},${end}p" "$md_file" | sed '/^\\newpage$/d' | sed -e :a -e '/^\s*$/{ $d; N; ba; }'
|
|
break
|
|
fi
|
|
done
|
|
done
|
|
|
|
rm -f "$tmpfile"
|
|
}
|
|
|
|
# ── Generate output filename ─────────────────────────────────────────────────
|
|
if [[ -z "$OUTPUT_PDF" ]]; then
|
|
if [[ ${#QUESTIONS[@]} -eq 0 ]]; then
|
|
OUTPUT_PDF="/tmp/obrona_all_questions.pdf"
|
|
elif [[ ${#QUESTIONS[@]} -eq 1 ]]; then
|
|
OUTPUT_PDF="/tmp/obrona_q${QUESTIONS[0]}.pdf"
|
|
else
|
|
joined=$(IFS=_; echo "${QUESTIONS[*]}")
|
|
joined="${joined//\//-}" # Replace / with - for safe filenames
|
|
OUTPUT_PDF="/tmp/obrona_q${joined}.pdf"
|
|
fi
|
|
fi
|
|
|
|
# ── Create temporary markdown ────────────────────────────────────────────────
|
|
TMP_DIR=$(mktemp -d)
|
|
TMP_MD="${TMP_DIR}/questions.md"
|
|
|
|
extract_questions "$SOURCE_MD" "${QUESTIONS[@]}" > "$TMP_MD"
|
|
|
|
# Count extracted questions
|
|
extracted=$(grep -c "^## PYTANIE" "$TMP_MD" || echo "0")
|
|
if [[ "$extracted" -eq 0 ]]; then
|
|
echo "Error: No matching questions found for: ${QUESTIONS[*]}" >&2
|
|
echo "Use --list to see available questions." >&2
|
|
rm -rf "$TMP_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
# ── Convert to PDF via pandoc + xelatex ───────────────────────────────────────
|
|
echo "Converting $extracted question(s) to PDF..."
|
|
|
|
pandoc "$TMP_MD" \
|
|
-o "$OUTPUT_PDF" \
|
|
--pdf-engine=xelatex \
|
|
-V geometry:a4paper \
|
|
-V geometry:margin=1.8cm \
|
|
-V fontsize=12pt \
|
|
-V mainfont="DejaVu Sans" \
|
|
-V sansfont="DejaVu Sans" \
|
|
-V monofont="DejaVu Sans Mono" \
|
|
-V linestretch=1.15 \
|
|
-V colorlinks=false \
|
|
--highlight-style=monochrome \
|
|
-V header-includes='\usepackage{fancyhdr}\pagestyle{fancy}\fancyhead[L]{\small Obrona magisterska}\fancyhead[R]{\small\thepage}\fancyfoot{}' \
|
|
-V header-includes='\usepackage{enumitem}\setlist{nosep,leftmargin=*}' \
|
|
-V header-includes='\renewcommand{\arraystretch}{1.3}' \
|
|
-V header-includes='\usepackage{booktabs}' \
|
|
2>/dev/null
|
|
|
|
echo "PDF generated: $OUTPUT_PDF"
|
|
echo " Pages: $(pdfinfo "$OUTPUT_PDF" 2>/dev/null | grep Pages | awk '{print $2}' || echo "?")"
|
|
|
|
# ── Print ─────────────────────────────────────────────────────────────────────
|
|
if $DO_PRINT; then
|
|
if ! lpstat -p "$PRINTER" &>/dev/null; then
|
|
echo "Error: Printer '$PRINTER' not found." >&2
|
|
echo "Available printers:" >&2
|
|
lpstat -p 2>/dev/null | awk '{print " " $2}' >&2
|
|
rm -rf "$TMP_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Printing to $PRINTER..."
|
|
lp -d "$PRINTER" \
|
|
-o media=A4 \
|
|
-o sides=one-sided \
|
|
-o fit-to-page \
|
|
"$OUTPUT_PDF"
|
|
echo "Print job submitted."
|
|
fi
|
|
|
|
# ── Cleanup ───────────────────────────────────────────────────────────────────
|
|
if $KEEP_TMP; then
|
|
echo "Temporary files kept in: $TMP_DIR"
|
|
else
|
|
rm -rf "$TMP_DIR"
|
|
fi
|