Last active
March 28, 2023 09:33
Star
You must be signed in to star a gist
scope.sh for text preview of office documents in ranger file manager (similar to mailcap file)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# CUSTOM {{{ | |
shopt -s nocasematch | |
# }}} | |
set -o noclobber -o noglob -o nounset -o pipefail | |
IFS=$'\n' | |
# 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. | |
FILE_EXTENSION="${FILE_PATH##*.}" | |
FILE_EXTENSION_LOWER=$(echo ${FILE_EXTENSION} | tr '[:upper:]' '[:lower:]') | |
# Settings | |
HIGHLIGHT_SIZE_MAX=262143 # 256KiB | |
HIGHLIGHT_TABWIDTH=2 | |
# styles listed in /usr/share/highlight/themes | |
HIGHLIGHT_STYLE='solarized-light' | |
# squeeze repetivive empty used in plain output | |
squeeze() { head -n "$PV_HEIGHT" | cat -s; } | |
handle_extension() { | |
case "${FILE_EXTENSION_LOWER}" in | |
# Archive | |
jar) | |
deepjarlist "${FILE_PATH}" && exit 5 | |
;;& | |
rpm | rz | t7z | tar | tbz | tbz2 | tgz | tlz | txz | tZ | tzo | war | xpi | xz | Z | zip) | |
atool --list -- "${FILE_PATH}" && exit 5 | |
bsdtar --list --file "${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
rar) | |
# Avoid password prompt by providing empty password | |
unrar lt -p- -- "${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
7z) | |
# Avoid password prompt by providing empty password | |
7z l -p -- "${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
pdf) | |
# Preview as text conversion | |
pdftotext -l 10 -nopgbrk -q -- "${FILE_PATH}" - && exit 5 | |
exiftool "${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
# BitTorrent | |
torrent) | |
transmission-show -- "${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
# HTML | |
htm | html | xhtml) | |
# Preview as text conversion | |
w3m -dump "${FILE_PATH}" && exit 5 | |
lynx -dump -- "${FILE_PATH}" && exit 5 | |
elinks -dump "${FILE_PATH}" && exit 5 | |
;; # Continue with next handler on failure | |
# CUSTOM {{{ | |
# OpenDocument | |
odt) | |
# Preview as text conversion | |
odt2txt "${FILE_PATH}" | squeeze && exit 5 | |
pandoc --standalone --from odt --to plain -- "${FILE_PATH}" | squeeze && exit 5 | |
exit 1 | |
;; | |
ods | odp | sxw) | |
odt2txt "${FILE_PATH}" | squeeze && exit 5 | |
libreoffice --cat "${FILE_PATH}" | squeeze && exit 5 | |
exit 1 | |
;; | |
doc) | |
wvHtml --charset=utf-8 "${FILE_PATH}" - | w3m -dump -T text/html && exit 5 | |
antiword "${FILE_PATH}" | squeeze && exit 5 | |
catdoc "${FILE_PATH}" | squeeze && exit 5 | |
exit 1 | |
;; | |
docx) | |
docx2txt.pl "${FILE_PATH}" - | squeeze && exit 5 | |
pandoc --standalone --from docx --to plain -- "${FILE_PATH}" | squeeze && exit 5 | |
exit 1 | |
;; | |
epub) | |
pandoc --standalone --from epub --to plain "${FILE_PATH}" | squeeze && exit 5 | |
exit 1 | |
;; | |
xlsx) | |
xls2csv.py "${FILE_PATH}" | |
xlscat -a UTF-8 -b WINDOWS-1252 "${FILE_PATH}" | |
excel2csv "${FILE_PATH}" --trim && exit 5 | |
exit 1 | |
;; | |
xls) | |
xlscat -a UTF-8 -b WINDOWS-1252 "${FILE_PATH}" | |
# xls2csv -q -a UTF-8 -b WINDOWS-1252 -x "${FILE_PATH}" -c ~/.cache/ranger/excel.csv >/dev/null && cat -s ~/.cache/ranger/excel.csv && exit 5 | |
excel2csv "${FILE_PATH}" --trim && exit 5 | |
exit 1 | |
;; | |
rtf) | |
unrtf --html "${FILE_PATH}" | w3m -dump -T text/html && exit 5 | |
exit 1 | |
;; | |
pptx) | |
pptx2md --disable_image --disable_wmf "${FILE_PATH}" --output ~/.cache/ranger/presentation.md >/dev/null && | |
cat -s ~/.cache/ranger/presentation.md && | |
exit 5 | |
exit 1 | |
;; | |
ppt) | |
ppthtml "${FILE_PATH}" | w3m -dump -T text/html && exit 5 | |
exit 1 | |
;; | |
djvu) | |
# requires djvulibre | |
djvutxt --page=1-10 "${FILE_PATH}" | squeeze && exit 5 | |
exiftool "${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
log) | |
ccze -A <"${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
markdown | mdown | mkd | mkdn | mdwn | md) | |
mdcat "${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
json) | |
jq --color-output . "${FILE_PATH}" && exit 5 | |
python -m json.tool -- "${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
# }}} | |
esac | |
} | |
handle_image() { | |
local mimetype="${1}" | |
case "${mimetype}" in | |
# SVG | |
# image/svg+xml) | |
# convert "${FILE_PATH}" "${IMAGE_CACHE_PATH}" && exit 6 | |
# exit 1;; | |
# Image | |
image/*) | |
if [[ -n "$DISPLAY" ]]; then | |
local orientation | |
orientation="$(identify -format '%[EXIF:Orientation]\n' -- "${FILE_PATH}")" | |
# If orientation data is present and the image actually | |
# needs rotating ("1" means no rotation)... | |
if [[ -n "$orientation" && "$orientation" != 1 ]]; then | |
# ...auto-rotate the image according to the EXIF data. | |
convert -- "${FILE_PATH}" -auto-orient "${IMAGE_CACHE_PATH}" && exit 6 | |
fi | |
# w3mimgdisplay will be called for all images (unless overriden as above), | |
# but might fail for unsupported types. | |
exit 7 | |
elif command -v chafa; then | |
chafa --colors 240 --size "${PV_WIDTH}x${PV_HEIGHT}" "${FILE_PATH}" | |
exit 4 | |
fi | |
;; | |
# Video | |
video/*) | |
# Thumbnail | |
ffmpegthumbnailer -i "${FILE_PATH}" -o "${IMAGE_CACHE_PATH}" -s 0 && exit 6 | |
exit 1 | |
;; | |
# application/pdf) | |
# pdftoppm -f 1 -l 1 \ | |
# -scale-to-x 1920 \ | |
# -scale-to-y -1 \ | |
# -singlefile \ | |
# -jpeg -tiffcompression jpeg \ | |
# -- "${FILE_PATH}" "${IMAGE_CACHE_PATH%.*}" \ | |
# && exit 6 || exit 1;; | |
esac | |
} | |
handle_mime() { | |
local mimetype="${1}" | |
case "${mimetype}" in | |
# Text | |
text/* | */xml) | |
# Syntax highlight | |
if [[ "$(stat --printf='%s' -- "${FILE_PATH}")" -gt "${HIGHLIGHT_SIZE_MAX}" ]]; then | |
exit 2 | |
fi | |
if [[ "$(tput colors)" -ge 256 ]]; then | |
local highlight_format='xterm256' | |
else | |
local highlight_format='ansi' | |
fi | |
highlight --replace-tabs="${HIGHLIGHT_TABWIDTH}" --out-format="${highlight_format}" \ | |
--style="${HIGHLIGHT_STYLE}" --force -- "${FILE_PATH}" && exit 5 | |
exit 2 | |
;; | |
# Image | |
image/*) | |
# Preview as text conversion | |
# img2txt --gamma=0.6 --width="${PV_WIDTH}" -- "${FILE_PATH}" && exit 4 | |
exiftool "${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
# Video and audio | |
video/* | audio/*) | |
# CUSTOM {{{ | |
# let sed remove spaces to fit output into narrow column | |
mediainfo "${FILE_PATH}" && { | |
dump | sed 's/ \+:/: /;' | |
exit 5 | |
} | |
# }}} | |
exiftool "${FILE_PATH}" && exit 5 | |
exit 1 | |
;; | |
# CUSTOM {{{ | |
application/csv) | |
trim <"${FILE_PATH}" | |
exit 0 | |
;; | |
# }}} | |
esac | |
} | |
handle_fallback() { | |
echo '----- File Type Classification -----' && file --dereference --brief -- "${FILE_PATH}" && exit 5 | |
exit 1 | |
} | |
MIMETYPE="$(file --dereference --brief --mime-type -- "${FILE_PATH}")" | |
if [[ "${PV_IMAGE_ENABLED}" == 'True' ]]; then | |
handle_image "${MIMETYPE}" | |
fi | |
handle_extension | |
handle_mime "${MIMETYPE}" | |
handle_fallback | |
exit 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment