I've been working on a way to take a string, set a max character width then split the lines near or at the limit by words and then frame the whole thing.
I managed to do it with printf
an array and a for
loop, but it's horrible--as rudimentary as it gets*, and I have to do the whole thing each time.
I'd like to make a function and pass the string as an argument. I actually found an example on how to do it, but I wouldn't dare to use the code because I couldn't fully understand it to make it my own which is sort of a must because what I found couldn't be passed as an argument, it was a combination of process redirection and the fmt
command. I attempted endlessly without success, then I tried with fold
which I found referenced in fmt
's manpage.
I think I can do it using Here Documents, redirecting to file, then fmt
and printf
then later trap
to cleanup, but I want to avoid using the filesystem at all costs.
This is what I've got, it's the printMESSAGEBOX
function in the code:
#!/usr/bin/env bash # FORMATING: BOX DRAWING boxp=" " ; boxP=" " ; boxt=" ╭────────────────────────────────────────────────────────────────────────╮" ; boxb=" ╰────────────────────────────────────────────────────────────────────────╯" ; boxT="╭─────────────────────────────────────────────────────────────────────────────╮" ; boxB="╰─────────────────────────────────────────────────────────────────────────────╯" ; boxl=" │ " ; boxL="│ " ; boxr=" │" # FORMATING: FOREGROUND/TEXT ñbla () { tput setaf 0;} ; ñred () { tput setaf 1;} ; ñgre () { tput setaf 2;} ; ñyel () { tput setaf 3;} ; ñblu () { tput setaf 4;} ; ñmag () { tput setaf 5;} ; ñcya () { tput setaf 6;} ; ñwhi () { tput setaf 7;} # FORMATING: BACKGROUND/HIGHLIGHTING ññbla () { tput setab 0;} ; ññred () { tput setab 1;} ; ññgre () { tput setab 2;} ; ññyel () { tput setab 3;} ; ññblu () { tput setab 4;} ; ññmag () { tput setab 5;} ; ññcya () { tput setab 6;} ; ññwhi () { tput setab 7;} # FORMATING: MISC (HIGHLIGHT-STANDOUT-ON/HIGHLIGHT-STANDOUT-OFF/RM-STYLE-BOLD-OFF/BOLD-ON/UNDERLINE-ON/UNDERLINE-OFF) ñH () { tput smso;} ; ñh () { tput rmso;} ; ñ0 () { tput sgr0;} ; alias ñb="ñ0" ; ñB () { tput bold;} ; ñU () { tput smul;} ; ñu () { tput rmul;} # EXIT CLEANUP trap ñ0 SIGINT # MESSAGE PRINTING - REVISED CODE printBOXHEADER() { # SORT OUT INPUT while [ "$1" != "" ]; do case "$1" in --type) shift; type=$1 ;; --t0) type=0 ;; # don't print --t1) type=1 ;; # green checkmark --t2) type=2 ;; # red crossmark --t3) type=3 ;; # custom icon --t4) type=4 ;; # custom icon, custom color --ic) shift; ic=$1 ;; --ic-red) ic=red ;; # only obeyed with types 4 --ic-gre) ic=gre ;; # only obeyed with types 4 --ic-yel) ic=yel ;; # only obeyed with types 4 --ic-blu) ic=blu ;; # only obeyed with types 4 --ic-mag) ic=mag ;; # only obeyed with types 4 --ic-cya) ic=cya ;; # only obeyed with types 4 --ic-whi) ic=whi ;; # only obeyed with types 4 --icon) shift; icon=$1 ;; # single character/emoji, # only obeyed with types 3,4 --header) shift; header="$1" ;; # optional esac shift done # DO THAT THING YOU DO if [[ $type -eq 0 ]]; then return 0 elif [[ $type -eq 1 ]]; then echo "[$(ñgre) ✔︎ $(ñ0)] $header" elif [[ $type -eq 2 ]]; then echo "[$(ñred) ✖︎ $(ñ0)] $header" elif [[ $type -eq 3 ]]; then echo "[ $icon ] $header" elif [[ $type -eq 4 ]]; then echo "[$(ñ$ic) $icon $(ñ0)] $header" fi } # MESSAGE PRINTING - HAPHAZARD CODE msgprint() { printf "%s\n" "$boxt" for line in "${msg[@]}"; do printf "%s%s%s%s\n" "$boxl" "$line" "${boxp:${#line}}" "$boxr" done printf "%s\n" "$boxb" } msgprintw() { printf "%s\n" "$boxT" for line in "${msg[@]}"; do printf "%s%s%s%s\n" "$boxL" "$line" "${boxP:${#line}}" "$boxr" done printf "%s\n" "$boxB" } printMESSAGEBOX() { if [[ $widerbox =~ y ]]; then msgprintw elif [[ $widerbox =~ n ]]; then msgprint elif [[ $widerbox =~ x ]]; then return fi } widerbox=n msg=( "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do" "eiusmod tempor incididunt ut labore et dolore magna aliqua." "Pellentesque nec nam aliquam sem et." ) printBOXHEADER "$@" printMESSAGEBOX
Output:
zx9:Scripting v$ messageBOXREVISITING ╭────────────────────────────────────────────────────────────────────────╮ │ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do │ │ eiusmod tempor incididunt ut labore et dolore magna aliqua. │ │ Pellentesque nec nam aliquam sem et. │ ╰────────────────────────────────────────────────────────────────────────╯ zx9:Scripting v$
I want to make it similar like the printBOXHEADER
function in the code, it originally had the same mess up structure printMESSAGEBOX
has. The leading whitespace is there on purpose, it lines up with printBOXHEADER
when it's used, when it's not used, the white space is there to grab your attention. At least that's the intention.
Among the things I tried was trying to use fmt
split the lines into the array I've been using so far, then use printf
, but I think I got the quoting wrong because it would either pass the whole string or it would split every single word into its own line, framed and not framed in another try. I'm so close to getting it yet still… :(
Anything is welcome and hugely appreciated, even a whole departure from my method (as long as it's still done with with Bash and old commands commonly available on most systems, e.g; fmt
…the stuff in [/usr
]/bin
)
*: in my defense I just started making scripts :) but even with my lack of skills I can tell it's not good.