My bash functions for compression, file name handling, delimiters matching, LaTeX, multimedia processing etc. in .bashrc
__pv() {
if command -v pv >/dev/null 2>&1; then
pv
else
cat
fi
}
compress_single() {
local msg='Usage: compress_single [-h|--help]
compress_single [-t|--tar] [-n|--no-tar] [-p|--pad PAD] COMMAND SOURCE [TARGET]
If TARGET is not provided and PAD is provided, SOURCE concatenating PAD is used.
No tar is used by default.'
local tar=0
local pad=''
local target=''
while [ "$#" -gt 0 ]; do
case "$1" in
-h | --help)
echo "$msg"
return 0
;;
-t | --tar)
tar=1
shift
;;
-n | --no-tar)
tar=0
shift
;;
-p | --pad)
if [ "$#" -lt 2 ]; then
echo "$msg" >&2
return 1
fi
pad="$2"
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
if [ "$#" -eq 3 ]; then
target="$3"
elif [ "$#" -eq 2 ] && [ -n "$pad" ]; then
target="${2}${pad}"
else
echo "$msg" >&2
return 1
fi
if [ "$tar" -eq 1 ]; then
(
set -o pipefail
tar -cf - "$2" | __pv | $1 | __pv >"$target"
)
else
(
set -o pipefail
$1 "$2" | __pv >"$target"
)
fi
}
split_file() {
local bytes
if [ -n "${SPLIT_SIZE:-}" ]; then
bytes="$SPLIT_SIZE"
else
bytes="4000M"
fi
split -b "$bytes" -d -a 3 "$1" "$1.part."
}
compress_split() {
# shellcheck disable=2016
local msg='Usage: compress_split [-h|--help]
compress_split [-t|--tar] [-n|--no-tar] [-p|--pad PAD] [-b BYTES|--bytes BYTES] COMMAND SOURCE [TARGET]
If TARGET is not provided and PAD is provided, SOURCE concatenating PAD is used.
No tar is used by default.
If BYTES is not provided, $SPLIT_SIZE is used if set and 4000M is used otherwise.'
local bytes
local pad=''
local target=''
if [ -n "${SPLIT_SIZE:-}" ]; then
bytes="$SPLIT_SIZE"
else
bytes="4000M"
fi
local tar=0
while [ "$#" -gt 0 ]; do
case "$1" in
-h | --help)
echo "$msg"
return 0
;;
-t | --tar)
tar=1
shift
;;
-n | --no-tar)
tar=0
shift
;;
-p | --pad)
if [ "$#" -lt 2 ]; then
echo "$msg" >&2
return 1
fi
pad="$2"
shift 2
;;
-b | --bytes)
if [ "$#" -lt 2 ]; then
echo "$msg" >&2
return 1
fi
bytes="$2"
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
if [ "$#" -eq 3 ]; then
target="$3"
elif [ "$#" -eq 2 ] && [ -n "$pad" ]; then
target="${2}${pad}"
else
echo "$msg" >&2
return 1
fi
if [ "$tar" -eq 1 ]; then
(
set -o pipefail
tar -cf - "$2" | __pv | $1 | __pv | split -b "$bytes" -d -a 3 - "$target.part."
)
else
(
set -o pipefail
$1 "$2" | __pv | split -b "$bytes" -d -a 3 - "$target.part."
)
fi
}
bz2_single() {
compress_single --tar --pad '.tar.bz2' 'bzip2 -9' "$@"
}
gz_single() {
compress_single --tar --pad '.tar.gz' 'gzip -9' "$@"
}
xz_single() {
compress_single --tar --pad '.tar.xz' 'xz -9' "$@"
}
tar_single() {
compress_single --no-tar --pad '.tar' 'tar -cf -' "$@"
}
zip_single() {
compress_single --no-tar --pad '.zip' 'zip -r -9 -' "$@"
}
bz2_split() {
compress_split --tar --pad '.tar.bz2' 'bzip2 -9' "$@"
}
gz_split() {
compress_split --tar --pad '.tar.gz' 'gzip -9' "$@"
}
xz_split() {
compress_split --tar --pad '.tar.xz' 'xz -9' "$@"
}
tar_split() {
compress_split --no-tar --pad '.tar' 'tar -cf -' "$@"
}
zip_split() {
compress_split --no-tar --pad '.zip' 'zip -r -9 -' "$@"
}
bz2_single_all() {
(
shopt -s nullglob
for f in *; do
compress_single --tar --pad '.tar.bz2' 'bzip2 -9' "$f" "$@" && rm -- "$f"
done
)
}
gz_single_all() {
(
shopt -s nullglob
for f in *; do
compress_single --tar --pad '.tar.gz' 'gzip -9' "$f" "$@" && rm -- "$f"
done
)
}
xz_single_all() {
(
shopt -s nullglob
for f in *; do
compress_single --tar --pad '.tar.xz' 'xz -9' "$f" "$@" && rm -- "$f"
done
)
}
tar_single_all() {
(
shopt -s nullglob
for f in *; do
compress_single --no-tar --pad '.tar' 'tar -cf -' "$f" "$@" && rm -- "$f"
done
)
}
zip_single_all() {
(
shopt -s nullglob
for f in *; do
compress_single --no-tar --pad '.zip' 'zip -r -9 -' "$f" "$@" && rm -- "$f"
done
)
}
bz2_split_all() {
(
shopt -s nullglob
for f in *; do
compress_split --tar --pad '.tar.bz2' 'bzip2 -9' "$f" "$@" && rm -- "$f"
done
)
}
gz_split_all() {
(
shopt -s nullglob
for f in *; do
compress_split --tar --pad '.tar.gz' 'gzip -9' "$f" "$@" && rm -- "$f"
done
)
}
xz_split_all() {
(
shopt -s nullglob
for f in *; do
compress_split --tar --pad '.tar.xz' 'xz -9' "$f" "$@" && rm -- "$f"
done
)
}
tar_split_all() {
(
shopt -s nullglob
for f in *; do
compress_split --no-tar --pad '.tar' 'tar -cf -' "$f" "$@" && rm -- "$f"
done
)
}
zip_split_all() {
(
shopt -s nullglob
for f in *; do
compress_split --no-tar --pad '.zip' 'zip -r -9 -' "$f" "$@" && rm -- "$f"
done
)
}
extract_all_and() {
local erar=0
local ezip=0
local etargz=0
local etgz=0
local egz=0
local etarbz2=0
local etbz2=0
local ebz2=0
local etarxz=0
local etxz=0
local exz=0
while [ "$#" -gt 0 ]; do
case "$1" in
--erar | --exclude-rar)
erar=1
shift
;;
--ezip | --exclude-zip)
ezip=1
shift
;;
--etargz | --exclude-targz)
etargz=1
shift
;;
--etgz | --exclude-tgz)
etgz=1
shift
;;
--egz | --exclude-gz)
egz=1
shift
;;
--etarbz2 | --exclude-tarbz2)
etarbz2=1
shift
;;
--etbz2 | --exclude-tbz2)
etbz2=1
shift
;;
--ebz2 | --exclude-bz2)
ebz2=1
shift
;;
--etarxz | --exclude-tarxz)
etarxz=1
shift
;;
--etxz | --exclude-txz)
etxz=1
shift
;;
--exz | --exclude-xz)
exz=1
shift
;;
--)
shift
break
;;
*)
break
;;
esac
done
[ "$#" -lt 2 ] && return 1
(
shopt -s globstar nullglob
for f in "$1" "$1"/**/*; do
[[ -f $f ]] || continue
local file=${f##*/}
local dir=${f%/*}
[[ $dir == "$f" ]] && dir=.
local un=''
local -a cmd=()
case $file in
*.rar)
[ "$erar" -eq 1 ] && continue
un=${file%.rar}
cmd=(unrar x)
;;
*.zip)
[ "$ezip" -eq 1 ] && continue
un=${file%.zip}
cmd=(unzip)
;;
*.tar.gz)
[ "$etargz" -eq 1 ] && continue
un=${file%.tar.gz}
cmd=(tar -xzf)
;;
*.tgz)
[ "$etgz" -eq 1 ] && continue
un=${file%.tgz}
cmd=(tar -xzf)
;;
*.gz)
[ "$egz" -eq 1 ] && continue
un=${file%.gz}
cmd=(gzip -d)
;;
*.tar.bz2)
[ "$etarbz2" -eq 1 ] && continue
un=${file%.tar.bz2}
cmd=(tar -xjf)
;;
*.tbz2)
[ "$etbz2" -eq 1 ] && continue
un=${file%.tbz2}
cmd=(tar -xjf)
;;
*.bz2)
[ "$ebz2" -eq 1 ] && continue
un=${file%.bz2}
cmd=(bzip2 -d)
;;
*.tar.xz)
[ "$etarxz" -eq 1 ] && continue
un=${file%.tar.xz}
cmd=(tar -xJf)
;;
*.txz)
[ "$etxz" -eq 1 ] && continue
un=${file%.txz}
cmd=(tar -xJf)
;;
*.xz)
[ "$exz" -eq 1 ] && continue
un=${file%.xz}
cmd=(xz -d)
;;
*)
continue
;;
esac
(
cd "$dir" &&
"${cmd[@]}" "$file" &&
rm -- "$file" &&
"${@:2}" "$un" &&
rm -rf -- "$un"
)
done
)
}
extract_all() {
extract_all_and "$@" false
}
extract_all_and_bz2() {
local -a args=()
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --pad)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
extract_all_and "$@" bz2_single "${args[@]}"
}
extract_all_and_gz() {
local -a args=()
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --pad)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
extract_all_and "$@" gz_single "${args[@]}"
}
extract_all_and_xz() {
local -a args=()
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --pad)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
extract_all_and "$@" xz_single "${args[@]}"
}
extract_all_and_tar() {
local -a args=()
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --pad)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
extract_all_and "$@" tar_single "${args[@]}"
}
extract_all_and_zip() {
local -a args=()
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --pad)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
extract_all_and "$@" zip_single "${args[@]}"
}
extract_all_and_bz2_split() {
local -a args=()
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --pad)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
-b | --bytes)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
extract_all_and "$@" bz2_split "${args[@]}"
}
extract_all_and_gz_split() {
local -a args=()
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --pad)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
-b | --bytes)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
extract_all_and "$@" gz_split "${args[@]}"
}
extract_all_and_xz_split() {
local -a args=()
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --pad)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
-b | --bytes)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
extract_all_and "$@" xz_split "${args[@]}"
}
extract_all_and_tar_split() {
local -a args=()
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --pad)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
-b | --bytes)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
extract_all_and "$@" tar_split "${args[@]}"
}
extract_all_and_zip_split() {
local -a args=()
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --pad)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
-b | --bytes)
if [ "$#" -lt 2 ]; then
return 1
fi
args+=("$1" "$2")
shift 2
;;
--)
shift
break
;;
*)
break
;;
esac
done
extract_all_and "$@" zip_split "${args[@]}"
}
remove_extension() {
sed -E 's/^(.+)\.[^.]+$/\1/'
}
get_extension() {
sed -E '/^\.?[^.]+$/d; s/^.+\.([^.]*)$/\1/'
}
ls_extension() {
find . -type f | sed -n 's/.*\(\.[^.\/]*\)$/\1/p' | sort -u
}
ffmpeg_av1_opus() {
if [ "$#" -lt 4 ]; then
return
fi
local new="${5:-"$(echo "$4" | remove_extension)_ffmpeg_av1_$1_$2_opus_$3.mkv"}"
if ! ffmpeg -n -i "$4" -c:v libsvtav1 -preset "$1" -crf "$2" -c:a libopus -vbr:a 1 -b:a "$3" "$new"; then
rm -f -- "$new"
return 1
fi
}
ffmpeg_av1_lossless_flac() {
if [ "$#" -eq 0 ]; then
return
fi
local new="${2:-"$(echo "$1" | remove_extension)_ffmpeg_av1_lossless_flac.mkv"}"
if ! ffmpeg -n -i "$1" -c:v libsvtav1 -svtav1-params lossless=1 -preset -2 -c:a flac "$new"; then
rm -f -- "$new"
return 1
fi
}
ffmpeg_opus() {
if [ "$#" -lt 2 ]; then
return
fi
local new="${3:-"$(echo "$2" | remove_extension)_ffmpeg_opus_$1.opus"}"
if ! ffmpeg -n -i "$2" -c:a libopus -vbr:a 1 -b:a "$1" "$new"; then
rm -f -- "$new"
return 1
fi
}
ffmpeg_flac() {
if [ "$#" -eq 0 ]; then
return
fi
local new="${2:-"$(echo "$1" | remove_extension)_ffmpeg_flac.flac"}"
if ! ffmpeg -n -i "$1" -c:a flac "$new"; then
rm -f -- "$new"
return 1
fi
}
ffmpeg_segment() {
if [ "$#" -lt 2 ]; then
return
fi
ffmpeg -n -i "$2" -c copy -map 0 -segment_time "$1" -f segment -reset_timestamps 1 "${3:-"$(echo "$2" | remove_extension)_ffmpeg_%04d.$(echo "$2" | get_extension)"}"
}
ffmpeg_concat_auto() {
local -a files=()
if [ "$#" -eq 0 ]; then
for f in *; do
test -f "$f" && files+=("$f")
done
else
files=("$@")
fi
ffmpeg -n -f concat -safe 0 -i <(printf "file '$PWD/%s'\n" "${files[@]}") -c copy "$(echo "${files[0]}" | remove_extension | sed -E 's/_ffmpeg_[0-9]+$//').$(echo "${files[0]}" | get_extension)"
}
ffmpeg_concat() {
if [ "$#" -lt 2 ]; then
return
fi
ffmpeg -n -f concat -safe 0 -i <(printf "file '$PWD/%s'\n" "${@:2}") -c copy "$1"
}
echo_non_ffmpeg() {
while IFS= read -r -d '' f; do
case "$f" in
*ffmpeg_*) ;;
*)
echo "$f"
;;
esac
done < <(find . -type f -print0)
}
remove_non_ffmpeg() {
while IFS= read -r -d '' f; do
case "$f" in
*ffmpeg_*) ;;
*)
rm -f -- "$f"
;;
esac
done < <(find . -type f -print0)
}
echo_ffmpeg() {
while IFS= read -r -d '' f; do
case "$f" in
*ffmpeg_*)
echo "$f"
;;
*) ;;
esac
done < <(find . -type f -print0)
}
remove_ffmpeg() {
while IFS= read -r -d '' f; do
case "$f" in
*ffmpeg_*)
rm -f -- "$f"
;;
*) ;;
esac
done < <(find . -type f -print0)
}
jxl_lossy() {
if [ "$#" -lt 2 ]; then
return
fi
local new="${3:-"$(echo "$2" | remove_extension).jxl"}"
if ! cjxl -j 0 -e 10 -d "$1" "$2" "$new"; then
rm -f -- "$new"
return 1
fi
}
jxl_lossless() {
if [ "$#" -eq 0 ]; then
return
fi
local new="${2:-"$(echo "$1" | remove_extension).jxl"}"
if ! cjxl -j 1 -e 10 -d 0 "$1" "$new"; then
rm -f -- "$new"
return 1
fi
}
multimedia_convert() {
(
shopt -s globstar nullglob
for f in **/*; do
[[ -f $f ]] || continue
local file=${f##*/}
local dir=${f%/*}
[[ $dir == "$f" ]] && dir=.
case ${file,,} in
*_ffmpeg_av1_*_*_opus_*.mkv | *_ffmpeg_av1_lossless_flac*.mkv)
continue
;;
*.ico | *.flac | *.gif | *.opus)
local ext="${file##*.}"
ext="${ext,,}"
if [[ ${file##*.} != "$ext" ]]; then
if [[ -e "${f%.*}.${ext}" ]]; then
printf 'Skipping: output exists: %s\n' "$f" >&2
continue
fi
mv -- "$f" "${f%.*}.${ext}"
fi
;;
*.jpg | *.jpeg | *.png)
local jxl="${file%.*}.jxl"
if [[ -e "$dir/$jxl" ]]; then
printf 'Skipping: output exists: %s\n' "$f" >&2
continue
fi
(
cd "$dir" &&
jxl_lossy 1 "./$file" "./$jxl" &&
rm -- "$file"
)
;;
*.avif | *.bmp | *.heic | *.heif | *.jp2 | *.tif | *.webp)
local png="${file%.*}.png"
if [[ -e "$dir/$png" ]]; then
printf 'Skipping: intermediate png exists: %s\n' "$f" >&2
continue
fi
local jxl="${file%.*}.jxl"
if [[ -e "$dir/$jxl" ]]; then
printf 'Skipping: output exists: %s\n' "$f" >&2
continue
fi
(
if cd "$dir"; then
magick "./$file" "./$png" &&
jxl_lossy 1 "./$png" "./$jxl" &&
rm -- "$file"
rm -f -- "$png"
fi
)
;;
*.3gp | *.mov | *.vob | *.wmv)
(
cd "$dir" &&
ffmpeg_av1_opus 4 40 24k "./$file" &&
rm -- "$file"
)
;;
*.avi | *.mkv | *.mp4 | *.mts | *.webm)
(
cd "$dir" &&
ffmpeg_av1_opus 4 32 72k "./$file" &&
rm -- "$file"
)
;;
*.aac | *.mp3 | *.m4a | *.ogg)
(
cd "$dir" &&
ffmpeg_opus 96k "./$file" &&
rm -- "$file"
)
;;
*.wav)
(
cd "$dir" &&
ffmpeg_flac "./$file" &&
rm -- "$file"
)
;;
*)
continue
;;
esac
done
)
}
clean_file() {
if [ $# -ne 0 ]; then
files=("$@")
else
files=(*)
fi
for f in "${files[@]}"; do
test -f "$f" && perl -i -pe 's/\x{FEFF}//g; s/\x{200B}//g; s/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]//g' -- "$f"
done
}
latexmkc() {
if command -v latexmk >/dev/null 2>&1; then
latexmk -c
else
rm -f -- *.acn *.acr *.alg *.aux *.bbl *.blg *.fdb_latexmk *.fls *.glg *.glo *.gls *.idx *.ilg *.ind *.ist *.lof *.log *.lot *.maf *.mp *.mtc *.mtc1 *.nav *.nlo *.out *.pdfsync *.snm *.tmp *.toc *.top *.tui *.vrb
fi
}
latexmkC() {
if command -v latexmk >/dev/null 2>&1; then
latexmk -C
else
latexmkc
rm -f -- *.dvi *.hnt *.pdf *.ps *.synctex *.synctex.gz
fi
}
latexci() {
# shellcheck disable=2016
local msg='latexci [-h|--help] [-m|--latexmk] [-n|--no-latexmk] [-o|--auto-latexmk] [-r|--reproducible] [-s|--no-reproducible] [-t|--auto-reproducible] [-l|--log log_file] [-c|--clean] [-d|--no-clean] [-e|--engine-times engine-times] engine [files]
--latexmk (default): Use latexmk -"$engine".
--no-latexmk: Use "$engine".
--auto-latexmk: Prefer latexmk -"$engine" and fallback to "$engine".
--reproducible (default): Compile reproducibly.
--no-reproducible: Compile normally.
--auto-reproducible: Prefer to compile reproducibly and fallback to compile normally.
--clean: Clean auxiliary files of each file after successful compilation and remove latexci_${engine}_*_log.txt if the whole run succeeds.
engine-times (default: 2): times to run "$engine" when not using latexmk.
log_file (default: latexci_${engine}_$(date +%s)_log.txt): name of log file. It is only used when there are warnings or errors. If file of the same name has existed, it will be deleted.
files (default: all **/*.tex): LaTeX files to compile.'
# mk (latexmk), rp (reproducible): 0 auto, 1 must, 2 no
local mk=1
local rp=1
local times=2
local clean=1
local log=''
local -a args=()
local -a files=()
while [ $# -gt 0 ]; do
case "$1" in
-h | --help)
echo "$msg"
return 0
;;
-m | --latexmk)
mk=1
shift
;;
-n | --no-latexmk)
mk=2
shift
;;
-o | --auto-latexmk)
mk=0
shift
;;
-r | --reproducible)
rp=1
shift
;;
-s | --no-reproducible)
rp=2
shift
;;
-t | --auto-reproducible)
rp=0
shift
;;
-l | --log)
log="$2"
shift 2
;;
-e | --engine-times)
if [[ ! $2 =~ ^[0-9]+$ ]] || (($2 < 1)); then
echo "latexci error: engine-times must be a positive integer." >&2
return 1
fi
times="$2"
shift 2
;;
-c | --clean)
clean=1
shift
;;
-d | --no-clean)
clean=0
shift
;;
--)
shift
args+=("$@")
break
;;
*)
args+=("$1")
shift
;;
esac
done
local engine
if [ "${#args[@]}" -eq 0 ]; then
echo 'latexci error: engine required.' >&2
return 1
else
engine="${args[0]}"
fi
local cwd
cwd="$(pwd)"
if [ "${#args[@]}" -ne 1 ]; then
files=("${args[@]:1}")
else
mapfile -d '' -t files < <(
find "$cwd" -type f -name '*.tex' -print0
)
fi
if [ "${#files[@]}" -eq 0 ]; then
echo "latexci warning: no .tex file found." >&2
return 0
fi
[ -z "$log" ] && log="latexci_${engine}_$(date +%s)_log.txt"
rm -f -- "$log"
for f in "${files[@]}"; do
local dir
dir="$(dirname "$f")"
if ! cd "$dir"; then
echo "$f: can't cd $dir" >>"$cwd/$log"
continue
fi
local file
file="$(basename "$f")"
local -a env_args=()
local epoch=''
if [ "$rp" -eq 1 ]; then
epoch=$(command -v git >/dev/null 2>&1 && git log -1 --format=%ct -- "$file" 2>/dev/null)
if [ -n "$epoch" ]; then
env_args=(SOURCE_DATE_EPOCH="$epoch")
else
echo "$f: git log failed for and reproducible required" >>"$cwd/$log"
fi
elif [ "$rp" -eq 0 ]; then
epoch=$(command -v git >/dev/null 2>&1 && git log -1 --format=%ct -- "$file" 2>/dev/null)
if [ -n "$epoch" ]; then
env_args=(SOURCE_DATE_EPOCH="$epoch")
fi
fi
if [ "$mk" -ne 2 ] && command -v latexmk >/dev/null 2>&1; then
if env "${env_args[@]}" latexmk -"$engine" -latexoption='-interaction=nonstopmode -halt-on-error' "$file"; then
[ "$clean" -eq 1 ] && latexmkc
else
echo "$f: latexmk $engine failed" >>"$cwd/$log"
fi
elif [ "$mk" -ne 1 ] && command -v "$engine" >/dev/null 2>&1; then
local fail=0
local et="$times"
while ((et > 0)); do
if ! env "${env_args[@]}" "$engine" -interaction=nonstopmode -halt-on-error "$file"; then
echo "$f: $engine failed" >>"$cwd/$log"
fail=1
break
fi
((et--))
done
if [ "$fail" -eq 0 ]; then
[ "$clean" -eq 1 ] && latexmkc
fi
else
echo "$f: all allowed methods not executable" >>"$cwd/$log"
fi
done
if [ "$mk" -eq 0 ] && ! command -v latexmk >/dev/null 2>&1; then
echo "latexci warning: latexmk not executable, $engine used" >&2
fi
if [ -f "$cwd/$log" ]; then
{
echo "latexci log"
echo "$cwd"
date -uIs
} >>"$cwd/$log"
cat "$cwd/$log" >&2
echo "latexci warning: failures logged to $cwd/${log}." >&2
# shellcheck disable=2164
cd "$cwd"
return 1
else
[ "$clean" -eq 1 ] && rm -f -- "$cwd/latexci_${engine}"_*_log.txt
# shellcheck disable=2164
cd "$cwd"
fi
}
xelatexci() {
latexci xelatex "$@"
}
lualatexci() {
latexci lualatex "$@"
}
match_round() {
awk '{ n = gsub(/\(/, "("); m = gsub(/\)/, ")"); balance += n - m; printf "%2d %5d %s\n", balance, NR, $0
}' "$1"
}
match_square() {
awk '{ n = gsub(/\[/, "["); m = gsub(/\]/, "]"); balance += n - m; printf "%2d %5d %s\n", balance, NR, $0
}' "$1"
}
match_curly() {
awk '{ n = gsub(/\{/, "{"); m = gsub(/\}/, "}"); balance += n - m; printf "%2d %5d %s\n", balance, NR, $0
}' "$1"
}
No replies yet