add tex export
This commit is contained in:
173
export_tex.sh
Executable file
173
export_tex.sh
Executable file
@@ -0,0 +1,173 @@
|
||||
#!/usr/bin/env bash
|
||||
# export_tex.sh — collect all files needed to compile a .tex file
|
||||
# Usage: ./export_tex.sh [manuscript.tex] [output_dir]
|
||||
# Defaults: first .tex in current dir; output_dir → ./export
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ── arguments ────────────────────────────────────────────────────────────────
|
||||
TEX_FILE="${1:-}"
|
||||
if [[ -z "$TEX_FILE" ]]; then
|
||||
TEX_FILE=$(ls *.tex 2>/dev/null | head -1)
|
||||
[[ -z "$TEX_FILE" ]] && { echo "No .tex file found."; exit 1; }
|
||||
fi
|
||||
[[ -f "$TEX_FILE" ]] || { echo "File not found: $TEX_FILE"; exit 1; }
|
||||
|
||||
EXPORT_DIR="${2:-export}"
|
||||
SRC_DIR="$(dirname "$(realpath "$TEX_FILE")")"
|
||||
TEX_BASE="$(basename "$TEX_FILE")"
|
||||
|
||||
mkdir -p "$EXPORT_DIR"
|
||||
|
||||
IMAGE_EXTS=(".pdf" ".png" ".jpg" ".jpeg" ".eps" ".svg" ".PNG" ".JPG" ".JPEG")
|
||||
|
||||
# Track already-processed tex files to avoid infinite loops
|
||||
declare -A VISITED_TEX
|
||||
|
||||
# ── helpers ──────────────────────────────────────────────────────────────────
|
||||
copy_rel() {
|
||||
# Copy a file to EXPORT_DIR preserving its path relative to SRC_DIR.
|
||||
local src="$1"
|
||||
[[ -f "$src" ]] || { echo " [missing] $src"; return; }
|
||||
local rel="${src#$SRC_DIR/}"
|
||||
local dest="$EXPORT_DIR/$rel"
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
cp -v "$src" "$dest"
|
||||
}
|
||||
|
||||
find_recursive() {
|
||||
# Find file by basename+ext under SRC_DIR; prefer shallower paths.
|
||||
local base="$1"; shift
|
||||
local found=""
|
||||
for ext in "$@"; do
|
||||
# Sort by path depth (fewer slashes = shallower) then alphabetically
|
||||
found=$(find "$SRC_DIR" -name "${base}${ext}" \
|
||||
| awk '{ print gsub(/\//,"/")" "$0 }' | sort -n | head -1 \
|
||||
| cut -d' ' -f2-)
|
||||
[[ -n "$found" ]] && break
|
||||
done
|
||||
echo "$found"
|
||||
}
|
||||
|
||||
copy_image() {
|
||||
local img="$1"
|
||||
# Normalise: strip leading ./ if present
|
||||
img="${img#./}"
|
||||
|
||||
# 1. Try path as written in .tex (relative to SRC_DIR), with/without ext
|
||||
if [[ "$img" == *.* ]]; then
|
||||
local f="$SRC_DIR/$img"
|
||||
if [[ -f "$f" ]]; then copy_rel "$f"; return; fi
|
||||
else
|
||||
for ext in "${IMAGE_EXTS[@]}"; do
|
||||
local f="$SRC_DIR/${img}${ext}"
|
||||
if [[ -f "$f" ]]; then copy_rel "$f"; return; fi
|
||||
done
|
||||
fi
|
||||
|
||||
# 2. Fallback: recursive search by basename only
|
||||
local base="${img##*/}"
|
||||
local f
|
||||
f=$(find_recursive "$base" "${IMAGE_EXTS[@]}")
|
||||
if [[ -n "$f" ]]; then
|
||||
copy_rel "$f"
|
||||
else
|
||||
echo " [missing] $img"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── recursive tex processor ───────────────────────────────────────────────────
|
||||
process_tex() {
|
||||
local tex_path
|
||||
tex_path="$(realpath "$1")"
|
||||
[[ -n "${VISITED_TEX[$tex_path]:-}" ]] && return
|
||||
VISITED_TEX["$tex_path"]=1
|
||||
|
||||
[[ -f "$tex_path" ]] || { echo " [missing tex] $tex_path"; return; }
|
||||
copy_rel "$tex_path"
|
||||
|
||||
# \input{file} or \include{file}
|
||||
while IFS= read -r inc; do
|
||||
# Try with and without .tex extension
|
||||
local candidate=""
|
||||
for try in "$SRC_DIR/${inc}.tex" "$SRC_DIR/${inc}"; do
|
||||
[[ -f "$try" ]] && { candidate="$try"; break; }
|
||||
done
|
||||
if [[ -n "$candidate" ]]; then
|
||||
process_tex "$candidate"
|
||||
else
|
||||
echo " [missing tex] $inc"
|
||||
fi
|
||||
done < <(grep -oP '\\(input|include)\{[^}]+\}' "$tex_path" \
|
||||
| grep -oP '(?<=\{)[^}]+' | tr -d '\r')
|
||||
|
||||
# \includegraphics
|
||||
while IFS= read -r img; do
|
||||
copy_image "$img"
|
||||
done < <(grep -oP '\\includegraphics(\[[^\]]*\])?\{[^}]+\}' "$tex_path" \
|
||||
| grep -oP '(?<=\{)[^}]+' | tr -d '\r')
|
||||
}
|
||||
|
||||
# ── 1. recurse through all .tex files ────────────────────────────────────────
|
||||
process_tex "$TEX_FILE"
|
||||
|
||||
# ── 2. document class (.cls) ──────────────────────────────────────────────────
|
||||
CLS=$(grep -oP '\\documentclass\[?[^\]]*\]?\{[^}]+\}' "$TEX_FILE" \
|
||||
| grep -oP '(?<=\{)[^}]+' | tr -d '\r' | head -1)
|
||||
if [[ -n "$CLS" ]]; then
|
||||
f=$(find_recursive "$CLS" ".cls")
|
||||
if [[ -n "$f" ]]; then
|
||||
copy_rel "$f"
|
||||
else
|
||||
echo " [system] ${CLS}.cls (not local, assumed installed)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Collect all files to search for bibliography settings: .tex + any local .cls/.sty
|
||||
mapfile -t SEARCH_FILES < <(
|
||||
printf '%s\n' "${!VISITED_TEX[@]}"
|
||||
find "$SRC_DIR" -maxdepth 1 \( -name "*.cls" -o -name "*.sty" \) 2>/dev/null
|
||||
)
|
||||
|
||||
# ── 3. bibliography style (.bst / .bbx) ──────────────────────────────────────
|
||||
BST=$(grep -rhP '\\bibliographystyle\{[^}]+\}' "${SEARCH_FILES[@]}" 2>/dev/null \
|
||||
| grep -oP '(?<=\{)[^}]+' | tr -d '\r' | head -1 || true)
|
||||
if [[ -n "$BST" ]]; then
|
||||
f=$(find_recursive "$BST" ".bst" ".bbx")
|
||||
if [[ -n "$f" ]]; then
|
||||
copy_rel "$f"
|
||||
else
|
||||
echo " [system] ${BST}.bst (not local, assumed installed)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# also copy any local .bbx / .cbx referenced by biblatex style option
|
||||
# matches both style= and bibstyle=
|
||||
grep -rhP '\\usepackage.*biblatex' "${SEARCH_FILES[@]}" 2>/dev/null \
|
||||
| grep -oP '(?:bib)?style\s*=\s*\{?[^},\]]+' | grep -oP '[^={} \r]+$' \
|
||||
| tr -d '\r' | sort -u \
|
||||
| while IFS= read -r sty; do
|
||||
for ext in ".bbx" ".cbx"; do
|
||||
f=$(find_recursive "$sty" "$ext")
|
||||
[[ -n "$f" ]] && copy_rel "$f"
|
||||
done
|
||||
done || true
|
||||
|
||||
# ── 4. bibliography database (.bib) ──────────────────────────────────────────
|
||||
# handles both \bibliography{} (BibTeX) and \addbibresource{} (biblatex)
|
||||
while IFS= read -r bib; do
|
||||
bib="${bib%.bib}" # strip .bib suffix if already present
|
||||
f=$(find_recursive "$bib" ".bib")
|
||||
[[ -n "$f" ]] && copy_rel "$f" || echo " [missing] ${bib}.bib"
|
||||
done < <({ grep -rhP '\\bibliography\{[^}]+\}' "${SEARCH_FILES[@]}" 2>/dev/null \
|
||||
| grep -oP '(?<=\{)[^}]+' | tr ',' '\n' | tr -d ' \r'
|
||||
grep -rhP '\\addbibresource\{[^}]+\}' "${SEARCH_FILES[@]}" 2>/dev/null \
|
||||
| grep -oP '(?<=\{)[^}]+' | tr -d '\r'; } \
|
||||
| sort -u || true)
|
||||
|
||||
# ── 5. .bbl (pre-built bibliography, if present) ─────────────────────────────
|
||||
BBL="$SRC_DIR/${TEX_BASE%.tex}.bbl"
|
||||
[[ -f "$BBL" ]] && copy_rel "$BBL"
|
||||
|
||||
echo ""
|
||||
echo "Done. Files exported to: $EXPORT_DIR/"
|
||||
Reference in New Issue
Block a user