all repos — shlide @ c78c23a27544c78de1d39c08c44cac7687a62d2e

slide deck presentation tool written in pure bash

shlide (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
#!/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
        reduce=0
        # Print the contents of the slide file, 
        # line by line.
        printf "%s" "$line"
        case $line in
            "" | *"\n"*)
                ((++reduce));;
        esac
        # Move down and back after each print.
        printf '\e[%sD\e[B' "$((${#line} - $reduce))"
    done <<< "$slide_contents"

}

display_end() {
    read -r LINES COLUMNS < <(stty -F /dev/tty size)
    ((l=$LINES/2))
    ((c=$COLUMNS/2 - 8))
    printf '\e[2J'
    printf '\e[0;%sH' "$c"
    printf 'END. Press q to quit'
}

main() {

    slides_dir="${1:-./}"
    slides=("$slides_dir"/[0-9]*.txt)
    i=0
    while true; do

        # Display END reached prompt, and then exit
        [[ "$i" -eq "${#slides[@]}" ]] && {
            display_end
            read -rsn1 input
            case "$input" in
                "j"|"n"|"q")
                    printf '\e[2J'
                    printf '\e[?25h'
                    exit
                    ;;
                *)
                    ((--i))
                    ;;
            esac
        }

        # 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 "$@"