I wrote a function working quite fine using ANSI escape sequences for terminals like VT100 (normally managed by Linux/Unix terminal emulators). I reported below the Bash code.
#!/bin/bash
# Returns the line number if <= 255; otherwais 255.
function getCurPos() {
local CURPOS
local -i lineNumb
echo -e "\E[6n"; read -sdR CURPOS; CURPOS=${CURPOS#*[}
CURPOS=(${CURPOS//;/ })
#echo ${CURPOS[*]}
lineNumb=${CURPOS[0]}
if [ $lineNumb -gt 255 ]; then
return 255
fi
return $lineNumb
}
# $1: text with "echo -e" interpreted syntax ('\n' means "return")
function messagetBox() {
local oldIFS=IFS
unset IFS
if [ -z $1 ]; then exit 0; fi
local text=$1
local -i maxLineLenght=0
local -i lineLenght=0
local -i lineNumb=0
local -i count
local -i line
#echo -e "\033[1;31m"
echo
while read i; do
echo -e "| $i ";
lineLenght=${#i}
lineLenght+=4
if [ $lineLenght -gt $maxLineLenght ]; then
maxLineLenght=$lineLenght
fi
lineNumb+=1
done < <(echo -e $text)
count=$maxLineLenght
while [ $count -gt 0 ]; do
echo -en "-"
count+=-1
done
#echo -en "\033[u"
echo -en "\033[$((lineNumb+2))A\n"
count=$maxLineLenght
while [ $count -gt 0 ]; do
echo -en "-"
count+=-1
done
echo -en "\033[1B"
count=$lineNumb
while [ $count -gt 0 ]; do
getCurPos
line=$?
echo -e "\033[${line};${maxLineLenght}H|"
count+=-1
done
echo -en "\033[${lineNumb}B"
echo -e "\033[0m"
IFS=$localIFS
}
~$ source ./sample.sh
~$ messagetBox "Hello\nMy name is Lorenzo, I was born in Italy."
--------------------------------------------
| Hello |
| My name is Lorenzo, I was born in Italy. |
--------------------------------------------
~$
The problem is that for text lines longer than the screen column's number, new lines before the first side line unshape the box:
~$ messagetBox "Hello. My name is Lorenzo, I was born in Italy. Hello. My name is Lorenzo, I was born in Italy."
| Hello. My name is Lorenzo, I was born in Italy. Hello. My name is Loren------------------------------------------------------------
-----------------------------------------------------------------
-----------------------------------------------
There's a way to avoid it?
Here's a better way to draw the box:
$ cat ./messagetBox
#!/usr/bin/env bash
# `printf` will expand `\n` to newline and `\t` to tab
# `pr` will convert any tabs to the appropriate number
# of blanks to match the alignment seen in the input.
printf '%b\n' "$*" |
pr -e -t |
awk '
{
width = length($0)
maxWidth = ( width > maxWidth ? width : maxWidth )
lines[NR] = $0
}
END {
lineBeg = "| "
lineEnd = " |"
dashes = sprintf("%*s", maxWidth + length(lineBeg) + length(lineEnd), "")
gsub(/ /,"-",dashes)
print dashes
for ( lineNr=1; lineNr<=NR; lineNr++ ) {
line = sprintf("%-*s", maxWidth, lines[lineNr])
print lineBeg line lineEnd
}
print dashes
}
'
$ ./messagetBox "Hello\nMy name is Lorenzo, I was born in Italy."
--------------------------------------------
| Hello |
| My name is Lorenzo, I was born in Italy. |
--------------------------------------------
It isn't clear from your question what you're using all those escape sequences for but just add them to that output as you like if you need them. In particular I kept the populating of line
separate from printing so you could add escape sequences around that to change color or whatever inside the box if that's what you're trying to do.