#!/usr/bin/env bash # # Usage: shlide path/to/slides/ # Each slide is a textfile under path/to/slides # Color definitions BLK="\e[30m" RED="\e[31m" GRN="\e[32m" YLW="\e[33m" BLU="\e[34m" PUR="\e[35m" CYN="\e[36m" RST="\e[0m" lines() { mapfile -tn 0 lines < "$1" printf '%s\n' "${#lines[@]}" } longest_line() { max=0 IFS= while read -r line; do if [ "${#line}" -gt "$max" ]; then max="${#line}"; fi done < "$1" printf '%s\n' "$max" } display() { # 1 - slide contents # 2 - slide name slide_contents="$1" # Hides the cursor. printf '\e[?25l' # Clear the screen. printf '\e[2J' # Move the cursor to the center. read -r LINES COLUMNS < <(stty -F /dev/tty size) height=$(lines "$2") width=$(longest_line "$2") # Rough estimates for the true center. ((l=$LINES/2 - $height/2)) ((c=$COLUMNS/2 - $width/2)) printf '\e[%s;%sH' "$l" "$c" while IFS= read -r line; do # Print the contents of the slide file, # line by line. printf "%s" "$line" # Move down and back after each print. printf '\e[%sD\e[B' "${#line}" done <<< "$slide_contents" } main() { slides_dir="${1:-./}" slides=("$slides_dir"/[0-9]*.txt) i=0 while true; do # Exit after last slide. [[ "$i" -gt "$((${#slides[@]} - 1))" ]] && { printf '\e[?25h' exit } # Don't go below 0. [[ "$i" -lt 0 ]] && i=0 # Navigate on j/k/n/p and quit on q. display "$(<${slides[$i]})" "${slides[$i]}" read -rsn1 input case "$input" in "j"|"n") ((++i)) ;; "k"|"p") ((--i)) ;; "q") # Return the cursor on exit. printf '\e[?25h' exit ;; esac done # Return the cursor. printf '\e[?25h' } main "$@"