Fonts in terminal emulators are always monospace.
Producing that output in a shell script is just a matter of entering it literally, for instance as:
#! /bin/sh -
cat << 'EOF'
╭─────────────────────────┤text title1├────────────────────────╮
│ │
│text, command, script, if else, echo, cat, sed, any command │
├──────────────────────────────────────────────────────────────┤
│text, command, script, if else, echo, ca t, sed, any command │
│text, command, script, if else, echo, cat , sed, any command │
│text, command, script, if else, echo, cat, sed, any command │
├──────────────────────────────────────────────────────────────┤
├─────────────────────────┤text title2├────────────────────────┤
│text, command, script, if else, echo, cat, sed, any command │
╰──────────────────────────────────────────────────────────────╯
EOF
In zsh
, using the l[width][text1][text2]
and r[width][text1][text2]
parameter expansion flags (combined with m
so they take into account the display width of characters), to do the padding and alignment:
#! /bin/zsh -
width=64
header() print -rC1 '╭'${(ml[width/2-1][─][┤]r[width/2-1][─][├])^@}'╮'
body() print -rC1 '|'${(ml[width/2-1]r[width/2-1])^@}'|'
ruler() print -rC1 "├${(ml[width-2][─])}┤"
midheader() print -rC1 '├'${(ml[width/2-1][─][┤]r[width/2-1][─][├])^@}'┤'
footer() print -rC1 "╰${(ml[width-2][─])}╯"
header 'text title1'
body '' some text ''
ruler
body '' 'more text' 'and more' ''
midheader 'text title2'
body '' 'some last text' ''
footer
Giving:
╭─────────────────────────┤text title1├────────────────────────╮
| |
| some |
| text |
| |
├──────────────────────────────────────────────────────────────┤
| |
| more text |
| and more |
| |
├─────────────────────────┤text title2├────────────────────────┤
| |
| some last text |
| |
╰──────────────────────────────────────────────────────────────╯
That assumes that you're in a locale whose charmap has those box drawing characters and that the script is encoded in that charmap and used in locales that use the same charmap.
Having the script encoded in UTF-8 and replace cat
with iconv -f UTF-8
would make sure the boxes are drawn correctly in the user's locale as long as its charmap has those box drawing characters.
In zsh, you could replace the literal ╭─╮├┤╰╯│
with the corresponding $'\uXXXX'
where XXXX
is the character's unicode code point in hexadecimal (\u256D\u2500\u256E\u251C\u2524\u2570\u256F\u2502
respectively) which zsh will expand to the corresponding encoding in the user's locale (and fail with a "character not in range" error in those locales where those characters are not present).
Before UTF-8 was common place, the usual method to draw boxes was to tell the terminal emulator to switch to an alternate charset.
After tput smacs
(s
et m
ode a
lternate c
har s
et; tput rmacs
to switch back, though you might need a tput enacs
to enable it first) in most terminals, characters such as `afgijklmnopqrstuvwxyz{|}~
become ◆▒°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·
, and for those that don't the acsc
terminfo capability give the translation. See the Line Graphics section in the terminfo(5) man page for details. Using those would make the output compatible with more terminals and locales don't use UTF-8, but is more complicated to do in a shell script without using dedicated applications that do box drawings such as dialog
or tbl
or terminal web browsers such as elinks
or w3m
which can dump a rendered form of an HTML table.
Again, using zsh makes it much easier than in bash as zsh has a builtin terminfo interface and more usable associative arrays.
The same header
, body
... functions in zsh
using those could be written:
#! /bin/zsh -
zmodload zsh/terminfo || exit
typeset -A c=( ${(s[])terminfo[acsc]} )
# ┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│
# jklmnopqrstuvwx
width=64
(( pad = width - 2 ))
(( lpad = pad / 2 + $#terminfo[rmacs] ))
(( rpad = pad / 2 + $#terminfo[smacs] ))
left=$terminfo[rmacs] right=$terminfo[smacs] line=$c[q]
hleft=$c[u]$terminfo[rmacs] hright=$terminfo[smacs]$c[t]
header() print -rC1 -- $terminfo[smacs]$c[l]${(mpl[lpad][$line][$hleft]r[rpad][$line][$hright])^@}$c[k]$terminfo[rmacs]
body() print -rC1 -- $terminfo[smacs]$c[x]${(mpl[lpad][ ][$left]r[rpad][ ][$right])^@}$c[x]$terminfo[rmacs]
ruler() print -rC1 -- "$terminfo[smacs]$c[t]${(mpl[pad][$line])}$c[u]$terminfo[rmacs]"
midheader() print -rC1 -- $terminfo[smacs]$c[t]${(mpl[lpad][$line][$hleft]r[rpad][$line][$hright])^@}$c[u]$terminfo[rmacs]
footer() print -rC1 -- "$terminfo[smacs]$c[m]${(mpl[pad][$line])}$c[j]$terminfo[rmacs]"
header 'text title1'
body '' some text ''
ruler
body '' 'more text' 'and more' ''
midheader 'text title2'
body '' 'some last text' ''
footer