The banners on this page is generated from the output from figlet. I found a fun way to create terminal “slides” when figuring out how to center the banners.

To center something (a block of text) in relation to something else (a terminal) you need to know the width and height of the objects. A terminal window consist of cells ordered in columns (width) and lines (height).

The easiest and most reliable (maybe not the most efficient) way to get the dimensions of a terminal window is to use the commands: tput lines and tput cols

The dimensions of a block of text is the number of lines the block consist of (height) and the longest line in the block (width). We can use the wc(1) command to get both these metrics. wc -l prints the number of lines, wc -L prints the number of characters (columns) in the longest line.

#!/bin/bash

block=$(cat << EOB
 ██       ██                  ██    
░██      ░██                 ░██    
░██      ░██  ██████   █████ ░██  ██
░██████  ░██ ██░░░░██ ██░░░██░██ ██ 
░██░░░██ ░██░██   ░██░██  ░░ ░████  
░██  ░██ ░██░██   ░██░██   ██░██░██ 
░██████  ███░░██████ ░░█████ ░██░░██
░░░░░   ░░░  ░░░░░░   ░░░░░  ░░  ░░ 
EOB
)

block_width=$(wc -L <<< "$block")
block_height=$(wc -l <<< "$block")

terminal_width=$(tput cols)
terminal_height=$(tput lines)

echo "the block is $block_width columns wide"
echo "and $block_height lines high"

Running the script above will print:

the block is 36 columns wide  
and 8 lines high

To center the block horizontally we want an equal amount of blank columns to the left and to the right of the block. The total number of blank columns is: blank_columns=$((terminal_width - block_width))

So we want to indent each line of the block an amount of spaces equal to half of total number of blank columns.

First I like to create a string, that contains the indentation: indentation=$(printf "%$((blank_columns/2))s" " ")

Then use sed(1) to replace the beginning of each line in the block, with our indentation string: block=$(sed "s/^/${indentation}/g" <<< "$block")

To also center the block vertically centered, we do something similar:

blank_lines=$((terminal_height - block_height))
vpad=$(printf "%$((blank_lines/2))s" " ")
vpad=${vpad// /$'\n'}

First create a string ($vpad) containing a number of spaces equal to the number of blank lines we want to pad. Then replace the spaces with newline characters ($'\n').

clear
printf '%s' "$vpad" "$block" "$vpad"

This will clear the screen and print our block in the center.

#!/bin/bash

block=$(cat << EOB
 ██       ██                  ██    
░██      ░██                 ░██    
░██      ░██  ██████   █████ ░██  ██
░██████  ░██ ██░░░░██ ██░░░██░██ ██ 
░██░░░██ ░██░██   ░██░██  ░░ ░████  
░██  ░██ ░██░██   ░██░██   ██░██░██ 
░██████  ███░░██████ ░░█████ ░██░░██
░░░░░   ░░░  ░░░░░░   ░░░░░  ░░  ░░ 
EOB
)

block_width=$(wc -L <<< "$block")
block_height=$(wc -l <<< "$block")

terminal_width=$(tput cols)
terminal_height=$(tput lines)

blank_lines=$((terminal_height - block_height))
vpad=$(printf "%$((blank_lines/2))s" " ")
vpad=${vpad// /$'\n'}

blank_columns=$((terminal_width - block_width))
indentation=$(printf "%$((blank_columns/2))s" " ")

block=$(sed "s/^/${indentation}/g" <<< "$block")

clear
printf '%s' "$vpad" "$block" "$vpad"