all repos — shlide @ 3d0bcbbb1acf25cb6ef94556c5c8c366060188a7

slide deck presentation tool written in pure bash

shlide (view raw)

  1#!/usr/bin/env bash
  2# shellcheck disable=2154
  3#
  4# shlide - a slide deck presentation tool written in pure bash
  5# https://github.com/icyphox/shlide
  6#
  7# The MIT License (MIT)
  8#
  9# Copyright (c) 2020 Anirudh Oppiliappan <x@icyphox.sh>
 10
 11# Color definitions.
 12export BLK="\e[30m"
 13export RED="\e[31m"
 14export GRN="\e[32m"
 15export YLW="\e[33m"
 16export BLU="\e[34m"
 17export PUR="\e[35m"
 18export CYN="\e[36m"
 19export RST="\e[0m"
 20
 21# Other formatting.
 22export BLD="\e[1m"
 23export DIM="\e[2m"
 24export ITA="\e[3m"
 25export UND="\e[4m"
 26export FLS="\e[5m"
 27export REV="\e[7m"
 28export INV="\e[8m"
 29export STR="\e[9m"
 30
 31lines() {
 32    mapfile -tn 0 lines < "$1"
 33    printf '%s\n' "${#lines[@]}"
 34}
 35
 36longest_line() {
 37    max=0 
 38    local IFS=
 39    while read -r line; do
 40        l=$(ansi_filter "$(colorify "$line")")
 41        if [ "${#l}" -gt "$max" ]; then max="${#l}"; fi
 42    done < "$1"
 43    printf '%s\n' "$max"
 44}
 45
 46colorify() {
 47    # 'eval' hack to achieve substitution for colors.
 48    # Exclude SC2154.
 49    eval "declare dummy=\"$1\""
 50    printf '%b' "$dummy"
 51}
 52
 53# Filter out color sequences.
 54ansi_filter() {
 55    shopt -s extglob
 56    local IFS=
 57    printf '%s' "${1//$'\e'[\[(]*([0-9;])[@-n]/}"
 58    #" A little fix to prevent vim syntax highlighting from breaking.
 59    shopt -u extglob
 60}
 61
 62
 63display() {
 64    # 1 - slide contents
 65    # 2 - slide name
 66    # 3 - current slide nr.
 67    # 4 - total nr. of slides
 68
 69    slide_contents="$1"
 70
 71    # Hide the cursor.
 72    printf '\e[?25l'
 73
 74    # Clear the screen.
 75    printf '\e[2J'
 76
 77    # Get screen size.
 78    read -r LINES COLUMNS < <(stty -F /dev/tty size)
 79
 80    # Write slide number at bottom left.
 81    printf '\e[H'
 82    printf '\e[%sB%s/%s' "$LINES" "$(($3+1))" "$4"
 83
 84    # Custom calculations to center text.
 85    height=$(lines "$2")
 86    width=$(longest_line "$2")
 87
 88    # Rough estimates for the true center.
 89    ((l=LINES/2 - height/2))
 90    ((c=COLUMNS/2 - width/2))
 91
 92    printf '\e[%s;%sH' "$l" "$c"
 93
 94    while IFS= read -r line; do
 95        reduce=0
 96        # Print the contents of the slide file, 
 97        # line by line.
 98        l=$(colorify "$line")
 99        printf '%s' "$l"
100        case $line in
101            "" | "\n")
102                ((++reduce));;
103        esac
104        # Move down and back after each print.
105        l=$(ansi_filter "$l")
106        printf '\e[%sD\e[B' "$((${#l} - reduce))"
107    done <<< "$slide_contents"
108
109}
110
111die() {
112    printf '\e[2J'
113    printf '\e[?25h'
114    exit 0
115}
116
117display_end() {
118    ((l=LINES/2))
119    ((c=COLUMNS/2 - 8))
120    printf '\e[2J'
121    printf '\e[0;%sH' "$c"
122    printf 'END. Press q to quit.'
123}
124
125main() {
126
127    slides_dir="${1:-./}"
128    slides=("$slides_dir"/[0-9]*.txt)
129    total="${#slides[@]}"
130    i=0
131    while :; do
132        # Clear the screen.
133        printf '\e[2J'
134
135        # Capture Ctrl+C.
136        trap 'die' INT
137
138        # Don't go below 0.
139        [[ "$i" -lt 0 ]] && i=0
140
141        # Display END reached prompt, and then exit.
142        if [[ "$i" -eq "$total" ]]; then 
143            display_end
144        else
145            display "$(<"${slides[$i]}")" "${slides[$i]}" "$i" "$total"
146        fi
147
148        # Navigation
149        read -rsn1 input
150        case "$input" in
151            "j"|"n"|""|";")
152                [[ "$i" -eq "$total" ]] && die
153                ((++i))
154                ;;
155            "k"|"p"|""|",")
156                ((--i))
157                ;;
158            "0")
159                ((i=0))
160                ;;
161            "G")
162                ((i=total-1))
163                ;;
164            "q")
165                # Return the cursor on exit.
166                die
167                ;;
168        esac
169    done
170
171    # Return the cursor.
172    printf '\e[?25h'
173
174}
175
176main "$@"