#!/bin/sh
# Needs: util.sh
. util.sh
set -o noclobber -o noglob -o nounset
IFS=
# If the option `use_preview_script` is set to `true`,
# then this script will be called and its output will be displayed in ranger.
# ANSI color codes are supported.
# STDIN is disabled, so interactive scripts won't work properly
# This script is considered a configuration file and must be updated manually.
# It will be left untouched if you upgrade ranger.
# Meanings of exit codes:
# code | meaning | action of ranger
# -----+------------+-------------------------------------------
# 0 | success | Display stdout as preview
# 1 | no preview | Display no preview at all
# 2 | plain text | Display the plain content of the file
# 3 | fix width | Don't reload when width changes
# 4 | fix height | Don't reload when height changes
# 5 | fix both | Don't ever reload
# 6 | image | Display the image `$IMAGE_CACHE_PATH` points to as an image preview
# 7 | image | Display the file directly as an image
# Script arguments
FILE_PATH="$1" # Full path of the highlighted file
PV_WIDTH="$2" # Width of the preview pane (number of fitting characters)
PV_HEIGHT="$3" # Height of the preview pane (number of fitting characters)
IMAGE_CACHE_PATH="$4" # Full path that should be used to cache image preview
PV_IMAGE_ENABLED="$5" # 'True' if image previews are enabled, 'False' otherwise.
draw_line()
{
i=0
while [ $i -ne $PV_WIDTH ]
do
printf '-'
i=$((i+1))
done
echop
}
handle_video()
{
ffprobe -hide_banner -- "$1" 2>&1 | \
grep -v -e '^ *_' -e '^\[' -e 'Last message repeated' | \
attrfilter.sh '^[[:blank:]]+*Stream.*: (Audio|Video|Subtitle)' bold && \
exit 5
}
handle_image()
{
format=$(cat <<-EOF
Format: %m
Dimensions: %[width]x%[height] px
Colorspace: %[colorspace]
Bitdepth: %[bit-depth]
EOF
)
match "$MIMETYPE" 'image/jpeg' && \
format="$format$(printf '\nQuality: %%Q\n')"
magick identify -format "$format" -- "$1[0]" 2>&1
exit 5
}
handle_audio()
{
ffprobe -hide_banner -- "$1" 2>&1 | \
grep -v -e '^ *_' -e '^\[' -e 'Last message repeated' | \
attrfilter.sh '^[[:blank:]]+(ALBUM|TITLE|ARTIST|DATE|track)' bold && \
exit 5
}
handle_extension()
{
case "$1" in
*.7z|*.cb7|*.cbr|*.cbt|*.cbz|*.pk3|*.pk7|*.rar|*.tar|*.tar.bz2|\
*.tar.gz|*.tar.lz|*.tar.xz|*.tar.zst|*.zip|*.zpaq|*.tbz2|*.tgz|\
*.tlz|*.txz|*.tzst)
archive_list.sh "$FILE_PATH" | natsort && exit 5
exit 1
;;
*.epub)
mutool draw -F text "$FILE_PATH" 1-5 && exit 5
exit 1
;;
*.pdf)
dir=$(mktemp -d)
fifo=$dir/fifo
mkfifo -- "$fifo"
trap "rm -- '$fifo'; rmdir -- '$dir'" INT TERM HUP QUIT EXIT
{ pdfinfo -- "$FILE_PATH"
echop
draw_line
echop
pdftotext -layout -l 4 -- "$FILE_PATH" -
} >"$fifo" &
tr -d '\000-\010\016-\037\177' <"$fifo"
wait $!
[ $? -eq 0 ] && exit 5 || exit 1
;;
*.djvu)
{ djvudump "$FILE_PATH" | sed -n \
-e '/DIRM/{s#^[[:blank:]]*DIRM \[[0-9]*\][[:blank:]]*##p; q}' \
-e '/INFO/s#^[[:blank:]]*INFO \[[0-9]*\][[:blank:]]*##p'
echop
draw_line
echop
djvutxt --page=1-4 "$FILE_PATH"
} && exit 5
exit 1
;;
*.csv)
csv_view -t -- "$FILE_PATH" 2>&1
exit 5
;;
# Not (always) recognized by file
*.y4m|*.ts|*.ifo|*.mkv)
handle_video "$FILE_PATH"
exit 1
;;
*ppm)
handle_image "$FILE_PATH"
;;
*.wv|*.tta)
handle_audio "$FILE_PATH"
exit 1
;;
*.htm|*.html|*.xhtml)
w3m -dump "$FILE_PATH" && exit 5
;; # Continue with next handler on failure
esac
}
handle_mime()
{
case "$1" in
text/x-diff)
catdiff.sh "$FILE_PATH" && exit 5
;;
text/* | */xml)
exit 2
;;
image/*)
handle_image "$FILE_PATH"
;;
video/*)
handle_video "$FILE_PATH"
;;
audio/*)
handle_audio "$FILE_PATH"
;;
esac
}
handle_fallback()
{
printf -- '----- File Type Classification -----\n' &&
file --dereference --brief -- "$FILE_PATH" && exit 5
exit 1
}
MIMETYPE="$(mimetype "$FILE_PATH")"
handle_extension "$(tolower "$FILE_PATH")"
handle_mime "$MIMETYPE"
handle_fallback
exit 1