all repos — shlide @ a8db45dd0561a7f44d5e0f5b5264b0b1a40c1a1b

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    case "$OSTYPE" in
 79        "darwin"*) read -r LINES COLUMNS < <(stty -f /dev/tty size) ;;
 80        *) read -r LINES COLUMNS < <(stty -F /dev/tty size) ;;
 81    esac
 82
 83    # Write slide number at bottom left.
 84    printf '\e[H'
 85    printf '\e[%sB%s/%s' "$LINES" "$(($3+1))" "$4"
 86
 87    # Custom calculations to center text.
 88    height=$(lines "$2")
 89    width=$(longest_line "$2")
 90
 91    # Rough estimates for the true center.
 92    ((l=LINES/2 - height/2))
 93    ((c=COLUMNS/2 - width/2))
 94
 95    printf '\e[%s;%sH' "$l" "$c"
 96
 97    while IFS= read -r line; do
 98        reduce=0
 99        # Print the contents of the slide file, 
100        # line by line.
101        l=$(colorify "$line")
102        printf '%s' "$l"
103        case $line in
104            "" | "\n")
105                ((++reduce));;
106        esac
107        # Move down and back after each print.
108        l=$(ansi_filter "$l")
109        printf '\e[%sD\e[B' "$((${#l} - reduce))"
110    done <<< "$slide_contents"
111
112}
113
114die() {
115    printf '\e[2J'
116    printf '\e[?25h'
117    exit 0
118}
119
120display_end() {
121    ((l=LINES/2))
122    ((c=COLUMNS/2 - 8))
123    printf '\e[2J'
124    printf '\e[0;%sH' "$c"
125    printf 'END. Press q to quit.'
126}
127
128main() {
129
130    slides_dir="${1:-./}"
131    slides=("$slides_dir"/[0-9]*.txt)
132    total="${#slides[@]}"
133    i=0
134    while :; do
135        # Clear the screen.
136        printf '\e[2J'
137
138        # Capture Ctrl+C.
139        trap 'die' INT
140
141        # Don't go below 0.
142        [[ "$i" -lt 0 ]] && i=0
143
144        # Display END reached prompt, and then exit.
145        if [[ "$i" -eq "$total" ]]; then 
146            display_end
147        else
148            display "$(<"${slides[$i]}")" "${slides[$i]}" "$i" "$total"
149        fi
150
151        # Navigation
152        read -rsn1 input
153        case "$input" in
154            "j"|"n"|""|";")
155                [[ "$i" -eq "$total" ]] && die
156                ((++i))
157                ;;
158            "k"|"p"|""|",")
159                ((--i))
160                ;;
161            "0")
162                ((i=0))
163                ;;
164            "G")
165                ((i=total-1))
166                ;;
167            "q")
168                # Return the cursor on exit.
169                die
170                ;;
171            *)
172                # Reloads the slide
173                ;;
174        esac
175    done
176
177    # Return the cursor.
178    printf '\e[?25h'
179
180}
181
182main "$@"