diaposishell

Slides on the terminal
git clone git://git.meso-star.fr/diaposishell.git
Log | Files | Refs | README | LICENSE

diaposishell (3938B)


      1 #!/bin/sh -e
      2 
      3 # Copyright (C) 2023 |Méso|Star> (contact@meso-star.com)
      4 #
      5 # This program is free software: you can redistribute it and/or modify
      6 # it under the terms of the GNU General Public License as published by
      7 # the Free Software Foundation, either version 3 of the License, or
      8 # (at your option) any later version.
      9 #
     10 # This program is distributed in the hope that it will be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     13 # GNU General Public License for more details.
     14 #
     15 # You should have received a copy of the GNU General Public License
     16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
     17 
     18 islide=0  # Index of the current slide
     19 nslides=0 # Number of slides to display
     20 input="n"
     21 
     22 ################################################################################
     23 # Helper functions
     24 ################################################################################
     25 clear_screen()
     26 {
     27   printf "\e[2J" # Clear the screen
     28   printf "\e[0;0H" # Move cursor to the origin
     29 }
     30 
     31 init()
     32 {
     33   printf "\e[?1049h" # Switch to alternate buffer
     34   printf "\e[?25l" # Hide cursor
     35   printf "\e[0;0H" # Move cursor to the origin
     36 }
     37 
     38 cleanup()
     39 {
     40   printf "\e[?1049l" # Disable TUI mode
     41   printf "\e[?25h" # show cursor
     42 }
     43 
     44 cleanup_die()
     45 {
     46   cleanup
     47   exit
     48 }
     49 
     50 short_help()
     51 {
     52   printf "G         last\n"
     53   printf "g         first\n"
     54   printf "<i>gg     <i>th slide\n"
     55   printf "n         next\n"
     56   printf "p         previous\n"
     57   printf "q         quit\n"
     58   printf "Enter     repeat last action\n"
     59   printf "\n"
     60   printf "Enter to quit help\n"
     61 }
     62 
     63 next_slide()
     64 {
     65   [ "${islide}" -lt "${nslides}" ] && islide=$((islide+1))
     66   printf "%d\n" "${islide}"
     67 }
     68 
     69 prev_slide()
     70 {
     71   [ "${islide}" -gt 1 ] && islide=$((islide-1))
     72   printf "%d\n" "${islide}"
     73 }
     74 
     75 ################################################################################
     76 # The script
     77 ################################################################################
     78 if [ "$1" = "-x" ]; then
     79   run_script="1"
     80   shift 1
     81 fi
     82 [ "$#" -eq 0 ] && exit # Nothing to present
     83 
     84 # Save the input arguments in a temporary file. Each argument is a slide
     85 # content: a character string, a script to execute or a file to capture.
     86 printf "%s\n" "$@" > .slides
     87 islide=1 # Index of the current slide
     88 nslides=$(wc -l .slides | cut -d' ' -f1) # Number of slides
     89 
     90 # Setup the terminal user interface
     91 init
     92 
     93 # Let's be polite in the event of an [unexpected] shutdown:
     94 # restore the terminal as it was.
     95 trap cleanup_die INT TERM EXIT
     96 
     97 # main loop
     98 while true; do
     99   clear_screen
    100 
    101   if [ "${islide}" -le 0 ]; then # Apply for help
    102     short_help
    103 
    104   # Display the current slide
    105   else
    106     slide=$(sed -n "${islide}p" .slides)
    107 
    108     # The slide is not a file: simply print its character string
    109     if ! [ -f "${slide}" ]; then
    110       printf "%s\n" "${slide}"
    111 
    112     else
    113       shebang=$(sed -n '1s/^#!\(.\{0,\}\)$/\1/p' "${slide}")
    114 
    115       # The slide is executable
    116       if [ -n "${shebang}" ] && [ -n "${run_script}" ]; then
    117         cleanup
    118         ${shebang} "${slide}"
    119         init
    120       fi
    121       cat "${slide}" # Display slide content
    122     fi
    123   fi
    124 
    125   read -r c # User input
    126 
    127   # Disable short help mode whatever the user input
    128   if [ "${islide}" -le 0 ]; then
    129     islide=$((-islide))
    130 
    131   # Handle user action
    132   else
    133     save_input="${input}"
    134     [ -z "${c}" ] && c=${input} # Use previous action
    135     input="${c}"
    136 
    137     if echo "${c}" | grep -Eq "^[0-9]+gg$"; then
    138       islide="${c%gg}"
    139       [ "${islide}" -lt "1" ] && islide=1
    140       [ "${islide}" -gt "${nslides}" ] && islide="${nslides}"
    141 
    142     else
    143       case "${c}" in
    144         h|\?) islide=$((-islide));;
    145         g) islide=1;;
    146         G) islide="${nslides}";;
    147         n) islide=$(next_slide);;
    148         p) islide=$(prev_slide);;
    149         q) break;;
    150 
    151         # Invalid user input. Restore the input to the previous one
    152         *) input="${save_input}";;
    153       esac
    154     fi
    155   fi
    156 done