-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
335 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,335 @@ | ||
#!/bin/bash | ||
# | ||
# FlightGear Installer | ||
# libsay | ||
# Library that adds the command "say" to print nice looking messages. | ||
# | ||
# Author: Megaf - https://github.com/Megaf - mmegaf [at] gmail [dot] com | ||
# Date: 03/09/2022 | ||
# GitHub: https://github.com/Megaf/FlightGear-Installer | ||
# License: GPL V3 | ||
|
||
set_colour() | ||
{ | ||
local clrs=( | ||
black red green yellow blue magenta cyan | ||
white grey | ||
light_red light_green light_yellow light_blue light_magenta light_cyan | ||
bright_white bright_black | ||
) | ||
|
||
local chg_clr="tput" # Colour command to be used. | ||
local clr_arg="$2" | ||
|
||
[ "$1" = "fg" ] && local arg="setaf" # Colour command argument to set the foreground colour. | ||
[ "$1" = "bg" ] && local arg="setab" # Colour command argument to set the foreground colour. | ||
[ -z "$2" ] && [ "$1" != "fg" -o "$1" != "bg" ] && local arg="setaf" && local clr_arg="$1" # Foreground/cackground arg not passed. Assuming foreground. | ||
|
||
local clr_cmd=( | ||
"$chg_clr $arg 0" "$chg_clr $arg 1" "$chg_clr $arg 2" "$chg_clr $arg 3" "$chg_clr $arg 4" "$chg_clr $arg 5" "$chg_clr $arg 6" | ||
"$chg_clr $arg 7" "$chg_clr $arg 8" | ||
"$chg_clr $arg 9" "$chg_clr $arg 10" "$chg_clr $arg 11" "$chg_clr $arg 12" "$chg_clr $arg 13" "$chg_clr $arg 14" | ||
"$chg_clr $arg 15" "$chg_clr $arg 16" | ||
) | ||
|
||
for i in ${!clrs[@]}; do | ||
[[ "${clrs[$i]}" == "$clr_arg" ]] && ${clr_cmd[$i]} && break | ||
done | ||
|
||
unset clrs chg_clr clr_cmd clr_arg arg | ||
} | ||
|
||
# Turns underline on/off. | ||
underline_on() { tput smul; } | ||
underline_off() { tput rmul; } | ||
# Turns standout mode on/off. | ||
standout_on() { tput smso; } | ||
standout_off() { tput rmso; } | ||
|
||
bold_on() { tput bold; } # Turns mode on (use rst to reset). | ||
|
||
# Message type parse. Colour schemes for these types of message | ||
c_error() { tput smul; set_colour bg black; set_colour fg red; } # Set for Error. | ||
c_info() { set_colour bg black; set_colour fg green; } # Set for Information. | ||
c_warning() { set_colour bg black; tput smul; tput smso; set_colour fg yellow; } # Set for Warning. | ||
c_debug() { set_colour bg black; set_colour fg cyan; } # Set for Debug. | ||
|
||
# Resets the terminal to the default style. | ||
rst() { tput sgr0; } # Resets all colour and formating settings. | ||
|
||
draw() | ||
{ | ||
[ ! "$style" ] && local style="boxdoubleline" | ||
local prnt_args="%s" # Command args to use in the "print" command. | ||
prnt() { printf "$prnt_args" "$*"; } # "print" command the script uses. In theory it will be easy to use other things than "printf". | ||
|
||
local dynmc_cmd="do_" # Set this string as a "dynamic command", instead of printing a symbol in the array, it will execute an action. | ||
|
||
# Array with valid options for draw command. | ||
local parts_cmds=( | ||
topleftcorner top toprightcorner | ||
leftside rightside | ||
leftside_c rightside_c | ||
bottomleftcorner bottom bottomrightcorner | ||
line do_space do_godown do_save_pos do_go_pos | ||
do_linefill do_margin do_autofill | ||
do_topfill do_bottomfill | ||
) | ||
|
||
# Styles | ||
# BoxDoubleLine Style | ||
[ "$style" == "boxdoubleline" ] && local parts=( | ||
╔ ═ ╗ | ||
║ ║ | ||
╠ ╣ | ||
╚ ═ ╝ | ||
═ | ||
) | ||
|
||
[ "$style" == "boxverticalsinglehorizontaldouble" ] && local parts=( | ||
╒ ═ ╕ | ||
│ │ | ||
├ ┤ | ||
╘ ═ ╛ | ||
─ | ||
) | ||
|
||
[ "$style" == "boxverticaldoublehorizontalsingle" ] && local parts=( | ||
╓ ─ ╖ | ||
║ ║ | ||
╠ ╣ | ||
╙ ─ ╜ | ||
─ | ||
) | ||
|
||
[ "$style" == "boxsingleline" ] && local parts=( | ||
┌ ─ ┐ | ||
│ │ | ||
├ ┤ | ||
└ ─ ┘ | ||
─ | ||
) | ||
|
||
[ "$style" == "boxsolid" ] && local parts=( | ||
█ ▀ █ | ||
█ █ | ||
█ █ | ||
█ ▄ █ | ||
▄ | ||
) | ||
|
||
local prnt_clr="set_colour fg $colour;" | ||
local bordr_clr_cmds=( | ||
"prnt_clr ${parts[1]}" "0" "0" | ||
"0" "0" | ||
"0" "0" | ||
"0" "0" "0" | ||
"0" | ||
) | ||
|
||
do_linefill() { printf "%0.s${parts[10]}" $(seq 1 "$linesize"); } | ||
do_topfill() { printf "%0.s${parts[1]}" $(seq 1 "$linesize"); } | ||
do_bottomfill() { printf "%0.s${parts[8]}" $(seq 1 "$linesize"); } | ||
do_space() { printf "%0.s "; } | ||
do_margin() { printf "%0.s " $(seq 1 "$margin"); } | ||
do_autofill() { printf "%0.s " $(seq 1 "$bsize"); } | ||
do_save_pos() { tput sc; } | ||
do_go_pos() { tput rc; } | ||
do_godown() { printf "\n"; } | ||
|
||
# Array that contains the commands that are executed with "do_commands", like "do_margin" | ||
local dynmc_cmds=( | ||
"0" "0" "0" | ||
"0" "0" | ||
"0" "0" | ||
"0" "0" "0" | ||
"0" "do_space" "do_godown" "do_save_pos" "do_go_pos" | ||
"do_linefill" "do_margin" "do_autofill" | ||
"do_topfill" "do_bottomfill" | ||
) | ||
|
||
# 'for loop' to check if the required symbol is a static or a dynamic symbol. | ||
for i in "$@"; do | ||
local index=0 | ||
for n in "${parts_cmds[@]}"; do | ||
if [[ ! "$n" == "$i" ]]; then | ||
index="$((index+1))" | ||
elif [[ "$n" == "$i" ]]; then | ||
if [[ "${parts_cmds[$index]}" == "$dynmc_cmd"* ]]; then | ||
"${dynmc_cmds[$index]}" | ||
else | ||
prnt "${parts[$index]}" | ||
fi | ||
unset index | ||
break | ||
fi | ||
done | ||
done | ||
|
||
unset index prnt_args dynmc_cmd prnt parts_cmds parts prnt_clr bordr_clr_cmds do_linefill do_topfill do_bottomfill do_space do_margin do_autofill do_save_pos do_go_pos do_godown dynmc_cmds | ||
} | ||
|
||
draw_a_box() | ||
{ | ||
draw \ | ||
topleftcorner top top top toprightcorner do_godown \ | ||
leftside do_space do_space do_space rightside do_godown \ | ||
bottomleftcorner bottom bottom bottom bottomrightcorner do_godown | ||
} | ||
|
||
say() | ||
{ | ||
unset msg | ||
|
||
check_options() | ||
{ | ||
[ "$1" = "colour_command" ] && local options=( --colour --color ) | ||
[ "$1" = "alignment_command" ] && local options=( --align ) | ||
[ "$1" = "colour" ] && local options=(black red green yellow blue magenta cyan | ||
white grey light_red light_green light_yellow light_blue light_magenta light_cyan | ||
bright_white bright_black | ||
) | ||
[ "$1" = "alignment" ] && local options=( centre center left right ) | ||
|
||
for i in "${options[@]}"; do | ||
[ "$i" = "$2" ] && return 3 | ||
done | ||
unset options | ||
} | ||
|
||
validade_command() | ||
{ | ||
for i in "$*"; do | ||
check_options colour_command "$1" | ||
if [ "$?" = 3 ]; then | ||
check_options colour "$2" | ||
if [ "$?" = 3 ]; then | ||
colour="$2"; shift 2 | ||
else | ||
shift 2 | ||
fi | ||
fi | ||
|
||
check_options alignment_command "$1" | ||
if [ "$?" = 3 ]; then | ||
check_options alignment "$2" | ||
if [ "$?" = 3 ]; then | ||
align="$2"; shift 2 | ||
else | ||
shift 2 | ||
fi | ||
fi | ||
|
||
check_options colour_command "$1"; colour_result="$?" | ||
check_options alignment_command $1; align_result="$?" | ||
if [ "$colour_result" = 0 ] && [ "$align_result" = 0 ]; then | ||
if [[ "$1" == "--"* ]]; then | ||
shift 1 | ||
fi | ||
fi | ||
|
||
# If no command line arg was passed and the user doesn't want to open a txt file... | ||
if [[ ! "$1" == "--"* ]] && [[ ! "$1" == *".txt" ]]; then | ||
msg="$*" # ...Then grabs the whole input line as the text to use. | ||
fi | ||
done | ||
unset args | ||
} | ||
|
||
local args=( "$@" ) | ||
validade_command "${args[@]}" | ||
|
||
# Checks if input is coming from the standard input. | ||
if [ ! -t 0 ]; then | ||
msg="$(cat)" | ||
elif [[ "$1" == *".txt" ]]; then # Or if it's coming from a text file. | ||
msg="$(cat $1)" | ||
fi | ||
|
||
# Main print loop. It will do all calculations and printing. | ||
print_centre() | ||
{ | ||
local margin=1 # Default margin size between the side of the box and text. | ||
local spacesize=3 # Basically adjust the amount of space on both sides of the text to the box. | ||
local minimal_size=10 # Box will not be smaller than this, no matter how little the text is. | ||
local length=$(awk -S '{print length}' <<< $msg | sort -nr | head -1); # Finds the longest line in the text and sets the box size according to it. | ||
# local blength=$(awk -S '{print length}' <<< $msg | sort -nr | head -2 | tail -n 1); # Finds the second longest line. | ||
# Checking if the longest line is shorter than the minimal size wanted. | ||
[ "$length" -le "$minimal_size" ] && local linesize="$minimal_size" | ||
[ "$length" -ge "$minimal_size" ] && local linesize="$((length+spacesize))" | ||
# [ "$size" = "full" ] && local linesize="$(($(tput cols) - spacesize))" # For future use. Makes the box size "full screen". | ||
|
||
# Draws the top of the box | ||
draw topleftcorner do_topfill toprightcorner do_godown | ||
|
||
# While loop that brakes the whole text in individual lines for processing and printing. | ||
# Highly inneficient and slow, perhaps you can find a better way? :) | ||
while IFS= read -r a; do | ||
|
||
# Just do it loop, It runs per line calculations and printing. | ||
just_do_it() | ||
{ | ||
|
||
rst | ||
[ ! "$a" ] && draw leftside_c do_linefill || draw leftside | ||
|
||
# Checks if the line contain any of these works and apply colour code. | ||
if [[ "$a" == "ERROR:"* ]] || [[ "$a" == "ERR:"* ]]; then | ||
bold_on; set_colour fg red; set_colour bg white; local formatted="true" | ||
elif [[ "$a" == "INFO:"* ]]; then | ||
set_colour fg green; set_colour bg black; local formatted="true" | ||
elif [[ "$a" == "WARN:"* ]] || [[ "$a" == "WARNING:"* ]]; then | ||
standout_on; bold_on; set_colour fg yellow; set_colour bg black; local formatted="true" | ||
elif [[ "$a" == "DEBUG:"* ]] || [[ "$a" == "DBG:"* ]] || [[ "$a" == "ADV_DBG:"* ]]; then | ||
set_colour fg cyan; set_colour bg black; local formatted="true" | ||
elif [[ "$a" == "NOTICE:"* ]]; then | ||
bold_on; set_colour fg light_yellow; set_colour bg black; local formatted="true" | ||
elif [[ "$a" == "TITLE:"* ]]; then | ||
standout_on; bold_on; local formatted="true" | ||
fi | ||
|
||
# Final loop, calculates the line and spaces size and then prints the line. | ||
write_out() | ||
{ | ||
local txt_size="${#4}" | ||
local asize="$((txt_size+margin))" | ||
local bsize="$((linesize-asize))" | ||
local linesize_="$((linesize-1))" | ||
|
||
centre_txt() { sed -e :a -e "s/^.\{1,$linesize_\}$/ & /;ta" | tr -d '\n' | head -c $linesize; } | ||
|
||
[ "$weight" = "bold" -o "$2" = "bold" ] && bold_on | ||
[ ! "$formatted" = "true" ] && [ "$colour" ] && set_colour fg "$3" | ||
|
||
[ "$1" = "centre" -o "$1" = "center" ] && printf '%s' "$4" | centre_txt && rst | ||
[ "$1" = "left" ] || [ -z "$1" ] && draw do_margin && printf '%s' "$4" && draw do_autofill && rst | ||
[ "$1" = "right" ] && draw do_autofill && printf '%s' "$4" && draw do_margin && rst | ||
unset formatted centre_txt txt_size asize bsize linesize_ | ||
} | ||
|
||
[ "$a" ] && write_out "$align" "$weight" "$colour" "$a" | ||
rst | ||
[ ! "$a" ] && draw rightside_c do_godown || draw rightside do_godown | ||
} | ||
|
||
# Only prints a line, if either the line doesn't contain debug of if debug is enabled. | ||
[ ! "$debug" = "true" ] && [[ ! "$a" =~ "DEBUG:"* ]] && just_do_it | ||
[ "$debug" = "true" ] && just_do_it | ||
|
||
done <<< $msg | ||
|
||
# Draws the bottom of the box | ||
draw bottomleftcorner do_bottomfill bottomrightcorner do_godown | ||
|
||
unset margin spacesize minimal_size length linesize a just_do_it write_out weight | ||
} | ||
|
||
# Debug checker for single line messages. | ||
if [ "$msg" ] && [[ ! "$debug" == "true" ]] && [[ ! "$msg" == "DEBUG:"* ]] && [[ ! "$msg" == "DBG:"* ]]; then | ||
print_centre | ||
elif [ "$msg" ] && [[ "$debug" == "true" ]]; then | ||
print_centre | ||
fi | ||
|
||
unset msg print_centre colour_result align_result align colour | ||
} |