dotfiles

My collection of dotfiles
git clone git://git.stellar-nexus.ru/dotfiles
Log | Files | Refs

scope.sh (13758B)


      1 #!/usr/bin/env bash
      2 
      3 set -o noclobber -o noglob -o nounset -o pipefail
      4 IFS=$'\n'
      5 
      6 ## If the option `use_preview_script` is set to `true`,
      7 ## then this script will be called and its output will be displayed in ranger.
      8 ## ANSI color codes are supported.
      9 ## STDIN is disabled, so interactive scripts won't work properly
     10 
     11 ## This script is considered a configuration file and must be updated manually.
     12 ## It will be left untouched if you upgrade ranger.
     13 
     14 ## Because of some automated testing we do on the script #'s for comments need
     15 ## to be doubled up. Code that is commented out, because it's an alternative for
     16 ## example, gets only one #.
     17 
     18 ## Meanings of exit codes:
     19 ## code | meaning    | action of ranger
     20 ## -----+------------+-------------------------------------------
     21 ## 0    | success    | Display stdout as preview
     22 ## 1    | no preview | Display no preview at all
     23 ## 2    | plain text | Display the plain content of the file
     24 ## 3    | fix width  | Don't reload when width changes
     25 ## 4    | fix height | Don't reload when height changes
     26 ## 5    | fix both   | Don't ever reload
     27 ## 6    | image      | Display the image `$IMAGE_CACHE_PATH` points to as an image preview
     28 ## 7    | image      | Display the file directly as an image
     29 
     30 ## Script arguments
     31 FILE_PATH="${1}"         # Full path of the highlighted file
     32 PV_WIDTH="${2}"          # Width of the preview pane (number of fitting characters)
     33 ## shellcheck disable=SC2034 # PV_HEIGHT is provided for convenience and unused
     34 PV_HEIGHT="${3}"         # Height of the preview pane (number of fitting characters)
     35 IMAGE_CACHE_PATH="${4}"  # Full path that should be used to cache image preview
     36 PV_IMAGE_ENABLED="${5}"  # 'True' if image previews are enabled, 'False' otherwise.
     37 
     38 FILE_EXTENSION="${FILE_PATH##*.}"
     39 FILE_EXTENSION_LOWER="$(printf "%s" "${FILE_EXTENSION}" | tr '[:upper:]' '[:lower:]')"
     40 
     41 ## Settings
     42 HIGHLIGHT_SIZE_MAX=262143  # 256KiB
     43 HIGHLIGHT_TABWIDTH=${HIGHLIGHT_TABWIDTH:-8}
     44 HIGHLIGHT_STYLE=${HIGHLIGHT_STYLE:-pablo}
     45 HIGHLIGHT_OPTIONS="--replace-tabs=${HIGHLIGHT_TABWIDTH} --style=${HIGHLIGHT_STYLE} ${HIGHLIGHT_OPTIONS:-}"
     46 PYGMENTIZE_STYLE=${PYGMENTIZE_STYLE:-autumn}
     47 OPENSCAD_IMGSIZE=${RNGR_OPENSCAD_IMGSIZE:-1000,1000}
     48 OPENSCAD_COLORSCHEME=${RNGR_OPENSCAD_COLORSCHEME:-Tomorrow Night}
     49 
     50 handle_extension() {
     51     case "${FILE_EXTENSION_LOWER}" in
     52         ## Archive
     53         a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\
     54         rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip)
     55             atool --list -- "${FILE_PATH}" && exit 5
     56             bsdtar --list --file "${FILE_PATH}" && exit 5
     57             exit 1;;
     58         rar)
     59             ## Avoid password prompt by providing empty password
     60             unrar lt -p- -- "${FILE_PATH}" && exit 5
     61             exit 1;;
     62         7z)
     63             ## Avoid password prompt by providing empty password
     64             7z l -p -- "${FILE_PATH}" && exit 5
     65             exit 1;;
     66 
     67         ## PDF
     68         pdf)
     69             ## Preview as text conversion
     70             pdftotext -l 10 -nopgbrk -q -- "${FILE_PATH}" - | \
     71               fmt -w "${PV_WIDTH}" && exit 5
     72             mutool draw -F txt -i -- "${FILE_PATH}" 1-10 | \
     73               fmt -w "${PV_WIDTH}" && exit 5
     74             exiftool "${FILE_PATH}" && exit 5
     75             exit 1;;
     76 
     77         ## BitTorrent
     78         torrent)
     79             transmission-show -- "${FILE_PATH}" && exit 5
     80             exit 1;;
     81 
     82         ## OpenDocument
     83         odt|ods|odp|sxw)
     84             ## Preview as text conversion
     85             odt2txt "${FILE_PATH}" && exit 5
     86             ## Preview as markdown conversion
     87             pandoc -s -t markdown -- "${FILE_PATH}" && exit 5
     88             exit 1;;
     89 
     90         ## XLSX
     91         xlsx)
     92             ## Preview as csv conversion
     93             ## Uses: https://github.com/dilshod/xlsx2csv
     94             xlsx2csv -- "${FILE_PATH}" && exit 5
     95             exit 1;;
     96 
     97         ## HTML
     98         htm|html|xhtml)
     99             ## Preview as text conversion
    100             w3m -dump "${FILE_PATH}" && exit 5
    101             lynx -dump -- "${FILE_PATH}" && exit 5
    102             elinks -dump "${FILE_PATH}" && exit 5
    103             pandoc -s -t markdown -- "${FILE_PATH}" && exit 5
    104             ;;
    105 
    106         ## JSON
    107         json)
    108             jq --color-output . "${FILE_PATH}" && exit 5
    109             python -m json.tool -- "${FILE_PATH}" && exit 5
    110             ;;
    111 
    112         ## Direct Stream Digital/Transfer (DSDIFF) and wavpack aren't detected
    113         ## by file(1).
    114         dff|dsf|wv|wvc)
    115             mediainfo "${FILE_PATH}" && exit 5
    116             exiftool "${FILE_PATH}" && exit 5
    117             ;; # Continue with next handler on failure
    118     esac
    119 }
    120 
    121 handle_image() {
    122     ## Size of the preview if there are multiple options or it has to be
    123     ## rendered from vector graphics. If the conversion program allows
    124     ## specifying only one dimension while keeping the aspect ratio, the width
    125     ## will be used.
    126     local DEFAULT_SIZE="1920x1080"
    127 
    128     local mimetype="${1}"
    129     case "${mimetype}" in
    130         ## SVG
    131         # image/svg+xml|image/svg)
    132         #     convert -- "${FILE_PATH}" "${IMAGE_CACHE_PATH}" && exit 6
    133         #     exit 1;;
    134 
    135         ## DjVu
    136         # image/vnd.djvu)
    137         #     ddjvu -format=tiff -quality=90 -page=1 -size="${DEFAULT_SIZE}" \
    138         #           - "${IMAGE_CACHE_PATH}" < "${FILE_PATH}" \
    139         #           && exit 6 || exit 1;;
    140 
    141         ## Image
    142         image/*)
    143             local orientation
    144             orientation="$( identify -format '%[EXIF:Orientation]\n' -- "${FILE_PATH}" )"
    145             ## If orientation data is present and the image actually
    146             ## needs rotating ("1" means no rotation)...
    147             if [[ -n "$orientation" && "$orientation" != 1 ]]; then
    148                 ## ...auto-rotate the image according to the EXIF data.
    149                 convert -- "${FILE_PATH}" -auto-orient "${IMAGE_CACHE_PATH}" && exit 6
    150             fi
    151 
    152             ## `w3mimgdisplay` will be called for all images (unless overriden
    153             ## as above), but might fail for unsupported types.
    154             exit 7;;
    155 
    156         ## Video
    157         # video/*)
    158         #     # Thumbnail
    159         #     ffmpegthumbnailer -i "${FILE_PATH}" -o "${IMAGE_CACHE_PATH}" -s 0 && exit 6
    160         #     exit 1;;
    161 
    162         ## PDF
    163         # application/pdf)
    164         #     pdftoppm -f 1 -l 1 \
    165         #              -scale-to-x "${DEFAULT_SIZE%x*}" \
    166         #              -scale-to-y -1 \
    167         #              -singlefile \
    168         #              -jpeg -tiffcompression jpeg \
    169         #              -- "${FILE_PATH}" "${IMAGE_CACHE_PATH%.*}" \
    170         #         && exit 6 || exit 1;;
    171 
    172 
    173         ## ePub, MOBI, FB2 (using Calibre)
    174         # application/epub+zip|application/x-mobipocket-ebook|\
    175         # application/x-fictionbook+xml)
    176         #     # ePub (using https://github.com/marianosimone/epub-thumbnailer)
    177         #     epub-thumbnailer "${FILE_PATH}" "${IMAGE_CACHE_PATH}" \
    178         #         "${DEFAULT_SIZE%x*}" && exit 6
    179         #     ebook-meta --get-cover="${IMAGE_CACHE_PATH}" -- "${FILE_PATH}" \
    180         #         >/dev/null && exit 6
    181         #     exit 1;;
    182 
    183         ## Font
    184         application/font*|application/*opentype)
    185             preview_png="/tmp/$(basename "${IMAGE_CACHE_PATH%.*}").png"
    186             if fontimage -o "${preview_png}" \
    187                          --pixelsize "120" \
    188                          --fontname \
    189                          --pixelsize "80" \
    190                          --text "  ABCDEFGHIJKLMNOPQRSTUVWXYZ  " \
    191                          --text "  abcdefghijklmnopqrstuvwxyz  " \
    192                          --text "  0123456789.:,;(*!?') ff fl fi ffi ffl  " \
    193                          --text "  The quick brown fox jumps over the lazy dog.  " \
    194                          "${FILE_PATH}";
    195             then
    196                 convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \
    197                     && rm "${preview_png}" \
    198                     && exit 6
    199             else
    200                 exit 1
    201             fi
    202             ;;
    203 
    204         ## Preview archives using the first image inside.
    205         ## (Very useful for comic book collections for example.)
    206         # application/zip|application/x-rar|application/x-7z-compressed|\
    207         #     application/x-xz|application/x-bzip2|application/x-gzip|application/x-tar)
    208         #     local fn=""; local fe=""
    209         #     local zip=""; local rar=""; local tar=""; local bsd=""
    210         #     case "${mimetype}" in
    211         #         application/zip) zip=1 ;;
    212         #         application/x-rar) rar=1 ;;
    213         #         application/x-7z-compressed) ;;
    214         #         *) tar=1 ;;
    215         #     esac
    216         #     { [ "$tar" ] && fn=$(tar --list --file "${FILE_PATH}"); } || \
    217         #     { fn=$(bsdtar --list --file "${FILE_PATH}") && bsd=1 && tar=""; } || \
    218         #     { [ "$rar" ] && fn=$(unrar lb -p- -- "${FILE_PATH}"); } || \
    219         #     { [ "$zip" ] && fn=$(zipinfo -1 -- "${FILE_PATH}"); } || return
    220         #
    221         #     fn=$(echo "$fn" | python -c "import sys; import mimetypes as m; \
    222         #             [ print(l, end='') for l in sys.stdin if \
    223         #               (m.guess_type(l[:-1])[0] or '').startswith('image/') ]" |\
    224         #         sort -V | head -n 1)
    225         #     [ "$fn" = "" ] && return
    226         #     [ "$bsd" ] && fn=$(printf '%b' "$fn")
    227         #
    228         #     [ "$tar" ] && tar --extract --to-stdout \
    229         #         --file "${FILE_PATH}" -- "$fn" > "${IMAGE_CACHE_PATH}" && exit 6
    230         #     fe=$(echo -n "$fn" | sed 's/[][*?\]/\\\0/g')
    231         #     [ "$bsd" ] && bsdtar --extract --to-stdout \
    232         #         --file "${FILE_PATH}" -- "$fe" > "${IMAGE_CACHE_PATH}" && exit 6
    233         #     [ "$bsd" ] || [ "$tar" ] && rm -- "${IMAGE_CACHE_PATH}"
    234         #     [ "$rar" ] && unrar p -p- -inul -- "${FILE_PATH}" "$fn" > \
    235         #         "${IMAGE_CACHE_PATH}" && exit 6
    236         #     [ "$zip" ] && unzip -pP "" -- "${FILE_PATH}" "$fe" > \
    237         #         "${IMAGE_CACHE_PATH}" && exit 6
    238         #     [ "$rar" ] || [ "$zip" ] && rm -- "${IMAGE_CACHE_PATH}"
    239         #     ;;
    240     esac
    241 
    242     # openscad_image() {
    243     #     TMPPNG="$(mktemp -t XXXXXX.png)"
    244     #     openscad --colorscheme="${OPENSCAD_COLORSCHEME}" \
    245     #         --imgsize="${OPENSCAD_IMGSIZE/x/,}" \
    246     #         -o "${TMPPNG}" "${1}"
    247     #     mv "${TMPPNG}" "${IMAGE_CACHE_PATH}"
    248     # }
    249 
    250     # case "${FILE_EXTENSION_LOWER}" in
    251     #     ## 3D models
    252     #     ## OpenSCAD only supports png image output, and ${IMAGE_CACHE_PATH}
    253     #     ## is hardcoded as jpeg. So we make a tempfile.png and just
    254     #     ## move/rename it to jpg. This works because image libraries are
    255     #     ## smart enough to handle it.
    256     #     csg|scad)
    257     #         openscad_image "${FILE_PATH}" && exit 6
    258     #         ;;
    259     #     3mf|amf|dxf|off|stl)
    260     #         openscad_image <(echo "import(\"${FILE_PATH}\");") && exit 6
    261     #         ;;
    262     # esac
    263 }
    264 
    265 handle_mime() {
    266     local mimetype="${1}"
    267     case "${mimetype}" in
    268         ## RTF and DOC
    269         text/rtf|*msword)
    270             ## Preview as text conversion
    271             ## note: catdoc does not always work for .doc files
    272             ## catdoc: http://www.wagner.pp.ru/~vitus/software/catdoc/
    273             catdoc -- "${FILE_PATH}" && exit 5
    274             exit 1;;
    275 
    276         ## DOCX, ePub, FB2 (using markdown)
    277         ## You might want to remove "|epub" and/or "|fb2" below if you have
    278         ## uncommented other methods to preview those formats
    279         *wordprocessingml.document|*/epub+zip|*/x-fictionbook+xml)
    280             ## Preview as markdown conversion
    281             pandoc -s -t markdown -- "${FILE_PATH}" && exit 5
    282             exit 1;;
    283 
    284         ## XLS
    285         *ms-excel)
    286             ## Preview as csv conversion
    287             ## xls2csv comes with catdoc:
    288             ##   http://www.wagner.pp.ru/~vitus/software/catdoc/
    289             xls2csv -- "${FILE_PATH}" && exit 5
    290             exit 1;;
    291 
    292         ## Text
    293         text/* | */xml)
    294             ## Syntax highlight
    295             if [[ "$( stat --printf='%s' -- "${FILE_PATH}" )" -gt "${HIGHLIGHT_SIZE_MAX}" ]]; then
    296                 exit 2
    297             fi
    298             if [[ "$( tput colors )" -ge 256 ]]; then
    299                 local pygmentize_format='terminal256'
    300                 local highlight_format='xterm256'
    301             else
    302                 local pygmentize_format='terminal'
    303                 local highlight_format='ansi'
    304             fi
    305             env HIGHLIGHT_OPTIONS="${HIGHLIGHT_OPTIONS}" highlight \
    306                 --out-format="${highlight_format}" \
    307                 --force -- "${FILE_PATH}" && exit 5
    308             env COLORTERM=8bit bat --color=always --style="plain" \
    309                 -- "${FILE_PATH}" && exit 5
    310             pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}"\
    311                 -- "${FILE_PATH}" && exit 5
    312             exit 2;;
    313 
    314         ## DjVu
    315         image/vnd.djvu)
    316             ## Preview as text conversion (requires djvulibre)
    317             djvutxt "${FILE_PATH}" | fmt -w "${PV_WIDTH}" && exit 5
    318             exiftool "${FILE_PATH}" && exit 5
    319             exit 1;;
    320 
    321         ## Image
    322         image/*)
    323             ## Preview as text conversion
    324             # img2txt --gamma=0.6 --width="${PV_WIDTH}" -- "${FILE_PATH}" && exit 4
    325             exiftool "${FILE_PATH}" && exit 5
    326             exit 1;;
    327 
    328         ## Video and audio
    329         video/* | audio/*)
    330             mediainfo "${FILE_PATH}" && exit 5
    331             exiftool "${FILE_PATH}" && exit 5
    332             exit 1;;
    333     esac
    334 }
    335 
    336 handle_fallback() {
    337     echo '----- File Type Classification -----' && file --dereference --brief -- "${FILE_PATH}" && exit 5
    338     exit 1
    339 }
    340 
    341 
    342 MIMETYPE="$( file --dereference --brief --mime-type -- "${FILE_PATH}" )"
    343 if [[ "${PV_IMAGE_ENABLED}" == 'True' ]]; then
    344     handle_image "${MIMETYPE}"
    345 fi
    346 handle_extension
    347 handle_mime "${MIMETYPE}"
    348 handle_fallback
    349 
    350 exit 1