#!/usr/bin/env bash
# Get the directory where the script is locatedSCRIPT_DIR="$(cd"$(dirname "${BASH_SOURCE[0]}")"&&pwd)"LUA_FILTERS=("include-files.lua""preserve-ref.lua""citations.lua""pagebreak.lua""newline.lua""caption-code-blocks.lua""plantuml.lua""mermaid.lua""align-figures.lua""align-tables.lua""callouts.lua")TEMPLATE="$SCRIPT_DIR/template/bergfink.typst"FILTERS_DIR="$SCRIPT_DIR/filters"INPUT_FILES=()OUTPUT_FILE=""METADATA_FILE=""OUTPUT_TYP=falseCONFIG_FILE=""WATCH=false# Parse argumentswhile[[$# -gt 0]];docase$1 in
-o|--output)OUTPUT_FILE="$2"shift2;; -m|--metadata)METADATA_FILE="$2"shift2;; --typ)OUTPUT_TYP=trueif[[ -n "$2"&&"$2" != -* ]];thenOUTPUT_FILE="$2"shift2elseshift1fi;; -c|--config)CONFIG_FILE="$2"shift2;; -w|--watch)WATCH=trueshift;; -*)echo"Unknown option: $1"exit1;; *)INPUT_FILES+=("$1")shift;;esacdoneif[${#INPUT_FILES[@]} -eq 0];thenecho"Usage: $0 <input_files> [-o <output>] [-m <metadata>] [--typ [<output>]] [-w]"exit1fi# Resolve pathsABS_INPUT_FILES=()for f in "${INPUT_FILES[@]}";doABS_INPUT_FILES+=("$(realpath "$f")")doneFIRST_INPUT="${ABS_INPUT_FILES[0]}"INPUT_DIR="$(dirname "$FIRST_INPUT")"if["$OUTPUT_TYP"=true]&&[ -z "$OUTPUT_FILE"];then# Change extension to .typOUTPUT_FILE="${FIRST_INPUT%.*}.typ"elif[ -z "$OUTPUT_FILE"];then# Change extension to .pdfOUTPUT_FILE="${FIRST_INPUT%.*}.pdf"fi# If output file was provided as relative, resolve it relative to current CWDABS_OUTPUT_FILE="$(realpath -m "$OUTPUT_FILE")"if[ -n "$METADATA_FILE"];thenABS_METADATA_FILE="$(realpath "$METADATA_FILE")"fiif[ -n "$CONFIG_FILE"];thenABS_CONFIG_FILE="$(realpath "$CONFIG_FILE")"fi# Build pandoc commandrun_conversion(){echo"Running conversion..."localCMD=("pandoc""${ABS_INPUT_FILES[@]}""-o""$ABS_OUTPUT_FILE""--from""markdown""--template""$TEMPLATE")if[["$ABS_OUTPUT_FILE"== *.typ ]];thenCMD+=("--to""typst")elseCMD+=("--pdf-engine""typst")fifor f in "${LUA_FILTERS[@]}";doCMD+=("--lua-filter""$FILTERS_DIR/$f")doneif[ -n "$ABS_METADATA_FILE"];thenCMD+=("--metadata-file""$ABS_METADATA_FILE")fiif[ -n "$ABS_CONFIG_FILE"];then# Use relative path to avoid Typst root issues when include is used in templateREL_CONFIG_FILE=$(realpath --relative-to="$INPUT_DIR""$ABS_CONFIG_FILE")CMD+=("-V""user-config=$REL_CONFIG_FILE")fi# Change to input directory as in Python script: os.chdir(input_paths[0].parent)(cd"$INPUT_DIR"&&"${CMD[@]}")localEXIT_CODE=$?if[$EXIT_CODE -eq 0];thenecho"Done."return0elseecho"Error during conversion (Exit code: $EXIT_CODE)."return1fi}if["$WATCH"=false];then run_conversion ||exit1else run_conversion
FILES_TO_WATCH=("${ABS_INPUT_FILES[@]}")if[ -n "$ABS_METADATA_FILE"]&&[ -f "$ABS_METADATA_FILE"];thenFILES_TO_WATCH+=("$ABS_METADATA_FILE")fiif[ -n "$ABS_CONFIG_FILE"]&&[ -f "$ABS_CONFIG_FILE"];thenFILES_TO_WATCH+=("$ABS_CONFIG_FILE")fiecho"Watching for changes in ${INPUT_FILES[*]}... (Ctrl+C to stop)"# Get initial mtimesdeclare -A last_mtimes
for f in "${FILES_TO_WATCH[@]}";doif[ -f "$f"];then last_mtimes["$f"]=$(stat -c %Y "$f")fidone# Simple loop to check for changeswhile true;do sleep 1CHANGED=falsefor f in "${FILES_TO_WATCH[@]}";doif[ -f "$f"];thenMTIME=$(stat -c %Y "$f")if["${last_mtimes["$f"]}" !="$MTIME"];then last_mtimes["$f"]=$MTIMECHANGED=truefifidoneif["$CHANGED"=true];thenecho -e "\nChange detected, re-running conversion..." run_conversion
fidonefi