What's the deal with the banner command?

2019-02-01 00:49发布

问题:

In some versions of UNIX and Linux there's a banner command (usually /usr/bin/banner) that prints great output like this:

 #####  #######    #     #####  #    #
#     #    #      # #   #     # #   #
#          #     #   #  #       #  #
 #####     #    #     # #       ###
      #    #    ####### #       #  #
#     #    #    #     # #     # #   #
 #####     #    #     #  #####  #    #

In other versions, the banner command (frequently /usr/games/banner) prints an ENORMOUS banner like you'd make in 1980 with Printshop that are suited for use at birthday parties and stuff.

I tend to love using banner for my scripts but it inherently non-portable because of this issue. Is "banner" part of UNIX and why isn't part of the POSIX standards? This is some BSD vs SysV difference but why hasn't it been resolved?

I know there's figlet which reproduces the banner that I like. But my issue with this command is portability. Banner should be part of UNIX, IMHO, even if they need to include both versions under different names (although ideally the behavior should be merged into one command with an option for the desired output).

Am I just crap out of luck when it comes to portability in scripts if I use banner?

回答1:

Because there were the two divergent behaviours when POSIX was standardized, back in the late 80s, banner was omitted from the standard. It was not essential and there wasn't a prevailing standard to select as 'the standard'.

And yes, you are out of luck if you use banner in your script; the behaviour is not reliable across platforms.



回答2:

Nothing is more portable across Unices as straight C.

You might find my rough draft here easier to modify and extend than one from a distribution (due to the implicit copyright if nothing else). This code was designed to be easy to read and understand without any comments.

[Don't be afraid of that big array, the actual code is very short. And at the very bottom there are "comments" which were used to visualize and construct the bitmaps. If you can understand why the space character works despite being coded as a backslash, then you understand the whole thing. The rest is just filling out the alphabet.]

#include <stdio.h>
#include <string.h>

enum {
    A = 1<<0,
    B = 1<<1,
    C = 1<<2,
    D = 1<<3,
    E = 1<<4,
    F = 1<<5,
    G = 1<<6,
    H = 1<<7,
};

char vec[] = " 0123456789"
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    ".,:!/\\|+-*=";

unsigned char map[sizeof(vec)][8] = {
    /* */ {A, B, C, D, E, F, G, H}, /* :) */
    /*0*/ {B|C|D|E|F, A|F|G, A|E|G, A|D|G, A|C|G, A|B|G, B|C|D|E|F, 0},
    /*1*/ {G, F|G, G, G, G, G, G, 0},
    /*2*/ {B|C|D|E|F, A|G, G, C|D|E|F, B, A, A|B|C|D|E|F|G, 0},
    /*3*/ {B|C|D|E|F, A|G, G, C|D|E|F, G, A|G, B|C|D|E|F, 0},
    /*4*/ {A|F, A|F, A|F, B|C|D|E|F|G, F, F, F, 0},
    /*5*/ {A|B|C|D|E|F|G, A, A, B|C|D|E|F, G, A|G, B|C|D|E|F, 0},
    /*6*/ {B|C|D|E|F, A, A, A|B|C|D|E|F, A|G, A|G, B|C|D|E|F, 0},
    /*7*/ {B|C|D|E|F|G, G, F, E, D, C, B, 0},
    /*8*/ {B|C|D|E|F, A|G, A|G, B|C|D|E|F, A|G, A|G, B|C|D|E|F, 0},
    /*9*/ {B|C|D|E|F, A|G, A|G, B|C|D|E|F|G, G, G, B|C|D|E|F, 0},
    /*a*/ {0, 0, B|C|D|E, F, B|C|D|E|F, A|F, B|C|D|E|G, 0},
    /*b*/ {B, B, B, B|C|D|E|F, B|G, B|G, A|C|D|E|F, 0},
    /*c*/ {0, 0, C|D|E, B|F, A, A, B|F, C|D|E},
    /*d*/ {F, F, F, B|C|D|E|F, A|F, A|F, B|C|D|E|G, 0},
    /*e*/ {0, 0, B|C|D|E, A|F, A|B|C|D|E|F, A, B|C|D|E, 0},
    /*f*/ {C|D|E, B, B, A|B|C|D, B, B, B, 0},
    /*g*/ {0, 0, B|C|D|E|G, A|F, A|F, B|C|D|E, F, B|C|D|E},
    /*h*/ {B, B, B, B|C|D|E, B|F, B|F, A|B|F, 0},
    /*i*/ {0, C, 0, B|C, C, C, A|B|C|D|E, 0},
    /*j*/ {0, D, 0, D, D, D, A|D, B|C},
    /*k*/ {B, B|E, B|D, B|C, B|D, B|E, A|B|E|F, 0},
    /*l*/ {A|B, B, B, B, B, B, A|B|C, 0},
    /*m*/ {0, 0, 0, A|C|E|F, A|B|D|G, A|D|G, A|D|G, 0},
    /*n*/ {0, 0, 0, B|D|E, B|C|F, B|F, B|F, 0},
    /*o*/ {0, 0, B|C|D|E, A|F, A|F, A|F, B|C|D|E, 0},
    /*p*/ {0, 0, A|B|C|D|E, B|F, B|F, B|C|D|E, B, A|B},
    /*q*/ {0, 0, B|C|D|E|G, A|F, A|F, B|C|D|E, F, F|G},
    /*r*/ {0, 0, A|B|D|E, B|C|F, B, B, A|B, 0},
    /*s*/ {0, 0, B|C|D|E, A, B|C|D|E, F, A|B|C|D|E, 0},
    /*t*/ {0, C, C, A|B|C|D|E, C, C, D|E, 0},
    /*u*/ {0, 0, A|F, A|F, A|F, A|F, B|C|D|E|G, 0},
    /*v*/ {0, 0, A|G, B|F, B|F, C|E, D, 0},
    /*w*/ {0, 0, A|G, A|G, A|D|G, A|D|G, B|C|E|F, 0},
    /*x*/ {0, 0, A|F, B|E, C|D, B|E, A|F, 0},
    /*y*/ {0, 0, B|F, B|F, B|F, C|F, A|D|E, B|C|D},
    /*z*/ {0, 0, A|B|C|D|E|F, E, D, C, B|C|D|E|F|G, 0},
    /*A*/ {D, C|E, B|F, A|G, A|B|C|D|E|F|G, A|G, A|G, 0},
    /*B*/ {A|B|C|D|E, A|F, A|F, A|B|C|D|E, A|F, A|F, A|B|C|D|E, 0},
    /*C*/ {C|D|E, B|F, A, A, A, B|F, C|D|E, 0},
    /*D*/ {A|B|C|D, A|E, A|F, A|F, A|F, A|E, A|B|C|D, 0},
    /*E*/ {A|B|C|D|E|F, A, A, A|B|C|D|E, A, A, A|B|C|D|E|F, 0},
    /*F*/ {A|B|C|D|E|F, A, A, A|B|C|D|E, A, A, A, 0},
    /*G*/ {C|D|E, B|F, A, A, A|E|F|G, B|F|G, C|D|E|G, 0},
    /*H*/ {A|G, A|G, A|G, A|B|C|D|E|F|G, A|G, A|G, A|G, 0},
    /*I*/ {A|B|C|D|E, C, C, C, C, C, A|B|C|D|E, 0},
    /*J*/ {A|B|C|D|E, C, C, C, C, C, A|C, B},
    /*K*/ {A|F, A|E, A|D, A|B|C, A|D, A|E, A|F, 0},
    /*L*/ {A, A, A, A, A, A, A|B|C|D|E|F, 0},
    /*M*/ {A|B|F|G, A|C|E|G, A|D|G, A|G, A|G, A|G, A|G, 0},
    /*N*/ {A|G, A|B|G, A|C|G, A|D|G, A|E|G, A|F|G, A|G, 0},
    /*O*/ {C|D|E, B|F, A|G, A|G, A|G, B|F, C|D|E, 0},
    /*P*/ {A|B|C|D, A|E, A|E, A|B|C|D, A, A, A, 0},
    /*Q*/ {C|D|E, B|F, A|G, A|G, A|C|G, B|D|F, C|D|E, F|G},
    /*R*/ {A|B|C|D, A|E, A|E, A|B|C|D, A|E, A|F, A|F, 0},
    /*S*/ {C|D|E, B|F, C, D, E, B|F, C|D|E, 0},
    /*T*/ {A|B|C|D|E|F|G, D, D, D, D, D, D, 0},
    /*U*/ {A|G, A|G, A|G, A|G, A|G, B|F, C|D|E, 0},
    /*V*/ {A|G, A|G, B|F, B|F, C|E, C|E, D, 0},
    /*W*/ {A|G, A|G, A|G, A|G, A|D|G, A|C|E|G, B|F, 0},
    /*X*/ {A|G, A|G, B|F, C|D|E, B|F, A|G, A|G, 0},
    /*Y*/ {A|G, A|G, B|F, C|E, D, D, D, 0},
    /*Z*/ {A|B|C|D|E|F|G, F, E, D, C, B, A|B|C|D|E|F|G, 0},
    /*.*/ {0, 0, 0, 0, 0, 0, D, 0},
    /*,*/ {0, 0, 0, 0, 0, E, E, D},
    /*:*/ {0, 0, 0, 0, D, 0, D, 0},
    /*!*/ {D, D, D, D, D, 0, D, 0},
    /*/ */ {G, F, E, D, C, B, A, 0},
    /*\\*/ {A, B, C, D, E, F, G, 0},
    /*|*/ {D, D, D, D, D, D, D, D},
    /*+*/ {0, D, D, B|C|D|E|F, D, D, 0, 0},
    /*-*/ {0, 0, 0, B|C|D|E|F, 0, 0, 0, 0},
    /***/ {0, B|D|F, C|D|E, D, C|D|E, B|D|F, 0, 0},
    /*=*/ {0, 0, B|C|D|E|F, 0, B|C|D|E|F, 0, 0, 0}
};

int enc(int c) { return strchr(vec,c)-vec; }

void show(char *s) {
    int row,col;
    char *sp;
    for (row=0; row<8; row++, putchar('\n'))
        for (sp = s; *sp; sp++)
            if (strchr(vec,*sp)!=NULL)
                for (col=0; col<8; col++)
                    putchar(map[enc(*sp)][row] & 1<<col ? *sp:' ');
}

int main(int c,char **v) {
    for (--c,++v;*v;v++,c--) show(*v);
    return 0;
}


/*
   01234567  01234567  01234567  01234567  01234567  01234567
0   #####               #           ###               #
1  #     #              #          #                  #
2  #     #    ####      #          #        #### #    #
3   #####         #     #####    #####     #    #     ####
4  #     #    #####     #    #     #       #    #     #   #
5  #     #   #    #     #    #     #        ####      #   #
6   #####     #### #   # ####      #            #    ##   #
7                                           ####
*/

/*
   01234567  01234567  01234567  01234567  01234567  01234567
0                       #
1    #          #       #  #
2                       # #      #         #####      #### #
3   ##          #       ##       ### ##     #   #    #    #
4    #          #       # #      #  #  #    #   #    #    #
5    #          #       #  #     #  #  #    ####      ####
6  #####     #  #      ##  ##    ## #  #    #             #
7             ##                           ##             ##
*/

/*
   01234567  01234567  01234567  01234567  01234567  01234567
0
1
2  ## ##      ####     #    #     #   #    ######    #     #
3   ##  #    #          #  #      #   #        #     #     #
4   #         ####       ##       #   #       #      #  #  #
5   #             #     #  #       #  #      #       #  #  #
6  ##        #####     #    #    #  ##      ######    ## ##
7                                 ###
*/

/*
   01234567  01234567  01234567  01234567  01234567  01234567
0     #      #####       ###     ####      #####     #     #
1    # #     #    #     #   #    #   #       #       #     #
2   #   #    #    #    #         #    #      #       #     #
3   #   #    #####     #         #    #      #       #     #
4   #####    #    #    #         #    #      #       #  #  #
5  #     #   #    #     #   #    #   #       #       # # # #
6  #     #   #####       ###     ####      # #        #   #
7                                           #
*/


回答3:

The desired banner is the System V banner, install the sysvbanner package to get it, at least on Ubuntu 11



回答4:

Here is a shell implementation inspired from @luser droog's code. It is not POSIX compliant but works with both ksh93 and bash, which make it portable enough for most current Unix implementations.

#!/bin/ksh93
# or #!/bin/bash

A=$((1<<0))
B=$((1<<1))
C=$((1<<2))
D=$((1<<3))
E=$((1<<4))
F=$((1<<5))
G=$((1<<6))
H=$((1<<7))

function outLine
{
  typeset r=0 scan
  for scan
  do
    typeset l=${#scan}
    typeset line=0
    for ((p=0; p<l; p++))
    do
      line="$((line+${scan:$p:1}))"
    done
    for ((column=0; column<8; column++))
      do
        [[ $((line & (1<<column))) == 0 ]] && n=" " || n="#"
        raw[r]="${raw[r]}$n"
      done
      r=$((r+1))
    done
}

function outChar
{
    case "$1" in
    (" ") outLine "" "" "" "" "" "" "" "" ;;
    ("0") outLine "BCDEF" "AFG" "AEG" "ADG" "ACG" "ABG" "BCDEF" "" ;;
    ("1") outLine "F" "EF" "F" "F" "F" "F" "F" "" ;;
    ("2") outLine "BCDEF" "AG" "G" "CDEF" "B" "A" "ABCDEFG" "" ;;
    ("3") outLine "BCDEF" "AG" "G" "CDEF" "G" "AG" "BCDEF" "" ;;
    ("4") outLine "AF" "AF" "AF" "BCDEFG" "F" "F" "F" "" ;;
    ("5") outLine "ABCDEFG" "A" "A" "ABCDEF" "G" "AG" "BCDEF" "" ;;
    ("6") outLine "BCDEF" "A" "A" "BCDEF" "AG" "AG" "BCDEF" "" ;;
    ("7") outLine "BCDEFG" "G" "F" "E" "D" "C" "B" "" ;;
    ("8") outLine "BCDEF" "AG" "AG" "BCDEF" "AG" "AG" "BCDEF" "" ;;
    ("9") outLine "BCDEF" "AG" "AG" "BCDEF" "G" "G" "BCDEF" "" ;;
    ("a") outLine "" "" "BCDE" "F" "BCDEF" "AF" "BCDEG" "" ;;
    ("b") outLine "B" "B" "BCDEF" "BG" "BG" "BG" "ACDEF" "" ;;
    ("c") outLine "" "" "CDE" "BF" "A" "BF" "CDE" "" ;;
    ("d") outLine "F" "F" "BCDEF" "AF" "AF" "AF" "BCDEG" "" ;;
    ("e") outLine "" "" "BCDE" "AF" "ABCDEF" "A" "BCDE" "" ;;
    ("f") outLine "CDE" "B" "B" "ABCD" "B" "B" "B" "" ;;
    ("g") outLine "" "" "BCDEG" "AF" "AF" "BCDE" "F" "BCDE" ;;
    ("h") outLine "B" "B" "BCDE" "BF" "BF" "BF" "ABF" "" ;;
    ("i") outLine "C" "" "BC" "C" "C" "C" "ABCDE" "" ;;
    ("j") outLine "D" "" "CD" "D" "D" "D" "AD" "BC" ;;
    ("k") outLine "B" "BE" "BD" "BC" "BD" "BE" "ABEF" "" ;;
    ("l") outLine "AB" "B" "B" "B" "B" "B" "ABC" "" ;;
    ("m") outLine "" "" "ACEF" "ABDG" "ADG" "ADG" "ADG" "" ;;
    ("n") outLine "" "" "BDE" "BCF" "BF" "BF" "BF" "" ;;
    ("o") outLine "" "" "BCDE" "AF" "AF" "AF" "BCDE" "" ;;
    ("p") outLine "" "" "ABCDE" "BF" "BF" "BCDE" "B" "AB" ;;
    ("q") outLine "" "" "BCDEG" "AF" "AF" "BCDE" "F" "FG" ;;
    ("r") outLine "" "" "ABDE" "BCF" "B" "B" "AB" "" ;;
    ("s") outLine "" "" "BCDE" "A" "BCDE" "F" "ABCDE" "" ;;
    ("t") outLine "C" "C" "ABCDE" "C" "C" "C" "DE" "" ;;
    ("u") outLine "" "" "AF" "AF" "AF" "AF" "BCDEG" "" ;;
    ("v") outLine "" "" "AG" "BF" "BF" "CE" "D" "" ;;
    ("w") outLine "" "" "AG" "AG" "ADG" "ADG" "BCEF" "" ;;
    ("x") outLine "" "" "AF" "BE" "CD" "BE" "AF" "" ;;
    ("y") outLine "" "" "BF" "BF" "BF" "CDE" "E" "BCD" ;;
    ("z") outLine "" "" "ABCDEF" "E" "D" "C" "BCDEFG" "" ;;
    ("A") outLine "D" "CE" "BF" "AG" "ABCDEFG" "AG" "AG" "" ;;
    ("B") outLine "ABCDE" "AF" "AF" "ABCDE" "AF" "AF" "ABCDE" "" ;;
    ("C") outLine "CDE" "BF" "A" "A" "A" "BF" "CDE" "" ;;
    ("D") outLine "ABCD" "AE" "AF" "AF" "AF" "AE" "ABCD" "" ;;
    ("E") outLine "ABCDEF" "A" "A" "ABCDE" "A" "A" "ABCDEF" "" ;;
    ("F") outLine "ABCDEF" "A" "A" "ABCDE" "A" "A" "A" "" ;;
    ("G") outLine "CDE" "BF" "A" "A" "AEFG" "BFG" "CDEG" "" ;;
    ("H") outLine "AG" "AG" "AG" "ABCDEFG" "AG" "AG" "AG" "" ;;
    ("I") outLine "ABCDE" "C" "C" "C" "C" "C" "ABCDE" "" ;;
    ("J") outLine "BCDEF" "D" "D" "D" "D" "BD" "C" "" ;;
    ("K") outLine "AF" "AE" "AD" "ABC" "AD" "AE" "AF" "" ;;
    ("L") outLine "A" "A" "A" "A" "A" "A" "ABCDEF" "" ;;
    ("M") outLine "ABFG" "ACEG" "ADG" "AG" "AG" "AG" "AG" "" ;;
    ("N") outLine "AG" "ABG" "ACG" "ADG" "AEG" "AFG" "AG" "" ;;
    ("O") outLine "CDE" "BF" "AG" "AG" "AG" "BF" "CDE" "" ;;
    ("P") outLine "ABCDE" "AF" "AF" "ABCDE" "A" "A" "A" "" ;;
    ("Q") outLine "CDE" "BF" "AG" "AG" "ACG" "BDF" "CDE" "FG" ;;
    ("R") outLine "ABCD" "AE" "AE" "ABCD" "AE" "AF" "AF" "" ;;
    ("S") outLine "CDE" "BF" "C" "D" "E" "BF" "CDE" "" ;;
    ("T") outLine "ABCDEFG" "D" "D" "D" "D" "D" "D" "" ;;
    ("U") outLine "AG" "AG" "AG" "AG" "AG" "BF" "CDE" "" ;;
    ("V") outLine "AG" "AG" "BF" "BF" "CE" "CE" "D" "" ;;
    ("W") outLine "AG" "AG" "AG" "AG" "ADG" "ACEG" "BF" "" ;;
    ("X") outLine "AG" "AG" "BF" "CDE" "BF" "AG" "AG" "" ;;
    ("Y") outLine "AG" "AG" "BF" "CE" "D" "D" "D" "" ;;
    ("Z") outLine "ABCDEFG" "F" "E" "D" "C" "B" "ABCDEFG" "" ;;
    (".") outLine "" "" "" "" "" "" "D" "" ;;
    (",") outLine "" "" "" "" "" "E" "E" "D" ;;
    (":") outLine "" "" "" "" "D" "" "D" "" ;;
    ("!") outLine "D" "D" "D" "D" "D" "" "D" "" ;;
    ("/") outLine "G" "F" "E" "D" "C" "B" "A" "" ;;
    ("\\") outLine "A" "B" "C" "D" "E" "F" "G" "" ;;
    ("|") outLine "D" "D" "D" "D" "D" "D" "D" "D" ;;
    ("+") outLine "" "D" "D" "BCDEF" "D" "D" "" "" ;;
    ("-") outLine "" "" "" "BCDEF" "" "" "" "" ;;
    ("*") outLine "" "BDF" "CDE" "D" "CDE" "BDF" "" "" ;;
    ("=") outLine "" "" "BCDEF" "" "BCDEF" "" "" "" ;;
    (*) outLine "ABCDEFGH" "AH" "AH" "AH" "AH" "AH" "AH" "ABCDEFGH" ;;
    esac
}

function outArg
{
  typeset l=${#1} c r
  for ((c=0; c<l; c++))
  do
    outChar "${1:$c:1}"
  done
  echo
  [ -z "$COLUMNS" ] && COLUMNS=$(tput cols 2>/dev/null)
  for ((r=0; r<8; r++))
  do
    printf "%-*.*s\n" "${COLUMNS:-80}" "${COLUMNS:-80}" "${raw[r]}"
    raw[r]=""
  done
}

for i
do
  outArg "$i"
  echo
done


回答5:

There's always FIGLet. Gives source for unix, windows, dos, mac etc. hope this points you in the right direction.

Also, there's TOIlet, which could be considered figlet++.



回答6:

It isn't really essential to a unix system, I am not sure why it would be part of the standard. There are a many other things that are arguably more important that the standard setting bodies should be focused on.

If it isn't available on the system you could simply install it or build a equivalent.

There is a banner clone on debian it has a single c file with 155 lines of code, and most of that is just the glyphs. The source can be found on the package page. http://packages.debian.org/testing/misc/sysvbanner

It shouldn't be too difficult to even build another clone in the scripting language of your choice.



回答7:

The banner command from bsdmainutils package version 8.0.13 is now called printerbanner and is located here /usr/bin/printerbanner.



回答8:

If anyone is interested, here's a Java version. It generates a String, and it's up to you whether you use System.out.println() or your Logging framework of choice.

public class Banner {
    public static String print(String s, char stdCh) {
        StringBuilder sb = new StringBuilder();
        for (int row = 0; row < 8; row++) {
            sb.append('\n');
            for (char ch : s.toCharArray()) {
                int enc = CHAR_LIST.indexOf(ch);
                if (enc < 0) continue;
                for (int col = 0; col < 8; col++) {
                    sb.append(isPresent(row, enc, col) ? charToPrint(ch, stdCh) : ' ');
                }
            }
        }
        return sb.append('\n').toString();
    }

    private static char charToPrint(char ch, char stdCh) {
        return ch != ' ' && stdCh != 0 ? stdCh : ch;
    }

    private static boolean isPresent(int row, int enc, int col) {
        return (map[enc][row] & 1 << col) != 0;
    }

    // @formatter:off
    private static final String CHAR_LIST = " 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.,:!/\\|+-*=";

    private static int        A = 1<<0;
    private static int        B = 1<<1;
    private static int        C = 1<<2;
    private static int        D = 1<<3;
    private static int        E = 1<<4;
    private static int        F = 1<<5;
    private static int        G = 1<<6;
    private static int        H = 1<<7;

    // define the 'font'
    private static int[][] map = new int[][] {
        /* */ {A, B, C, D, E, F, G, H},
        /*0*/ {B|C|D|E|F, A|F|G, A|E|G, A|D|G, A|C|G, A|B|G, B|C|D|E|F, 0},
        /*1*/ {G, F|G, G, G, G, G, G, 0},
        /*2*/ {B|C|D|E|F, A|G, G, C|D|E|F, B, A, A|B|C|D|E|F|G, 0},
        /*3*/ {B|C|D|E|F, A|G, G, C|D|E|F, G, A|G, B|C|D|E|F, 0},
        /*4*/ {A|F, A|F, A|F, B|C|D|E|F|G, F, F, F, 0},
        /*5*/ {A|B|C|D|E|F|G, A, A, B|C|D|E|F, G, A|G, B|C|D|E|F, 0},
        /*6*/ {B|C|D|E|F, A, A, A|B|C|D|E|F, A|G, A|G, B|C|D|E|F, 0},
        /*7*/ {B|C|D|E|F|G, G, F, E, D, C, B, 0},
        /*8*/ {B|C|D|E|F, A|G, A|G, B|C|D|E|F, A|G, A|G, B|C|D|E|F, 0},
        /*9*/ {B|C|D|E|F, A|G, A|G, B|C|D|E|F|G, G, G, B|C|D|E|F, 0},
        /*a*/ {0, 0, B|C|D|E, F, B|C|D|E|F, A|F, B|C|D|E|G, 0},
        /*b*/ {B, B, B, B|C|D|E|F, B|G, B|G, A|C|D|E|F, 0},
        /*c*/ {0, 0, C|D|E, B|F, A, A, B|F, C|D|E},
        /*d*/ {F, F, F, B|C|D|E|F, A|F, A|F, B|C|D|E|G, 0},
        /*e*/ {0, 0, B|C|D|E, A|F, A|B|C|D|E|F, A, B|C|D|E, 0},
        /*f*/ {C|D|E, B, B, A|B|C|D, B, B, B, 0},
        /*g*/ {0, 0, B|C|D|E|G, A|F, A|F, B|C|D|E, F, B|C|D|E},
        /*h*/ {B, B, B, B|C|D|E, B|F, B|F, A|B|F, 0},
        /*i*/ {0, C, 0, B|C, C, C, A|B|C|D|E, 0},
        /*j*/ {0, D, 0, D, D, D, A|D, B|C},
        /*k*/ {B, B|E, B|D, B|C, B|D, B|E, A|B|E|F, 0},
        /*l*/ {A|B, B, B, B, B, B, A|B|C, 0},
        /*m*/ {0, 0, 0, A|C|E|F, A|B|D|G, A|D|G, A|D|G, 0},
        /*n*/ {0, 0, 0, B|D|E, B|C|F, B|F, B|F, 0},
        /*o*/ {0, 0, B|C|D|E, A|F, A|F, A|F, B|C|D|E, 0},
        /*p*/ {0, 0, A|B|C|D|E, B|F, B|F, B|C|D|E, B, A|B},
        /*q*/ {0, 0, B|C|D|E|G, A|F, A|F, B|C|D|E, F, F|G},
        /*r*/ {0, 0, A|B|D|E, B|C|F, B, B, A|B, 0},
        /*s*/ {0, 0, B|C|D|E, A, B|C|D|E, F, A|B|C|D|E, 0},
        /*t*/ {0, C, C, A|B|C|D|E, C, C, D|E, 0},
        /*u*/ {0, 0, A|F, A|F, A|F, A|F, B|C|D|E|G, 0},
        /*v*/ {0, 0, A|G, B|F, B|F, C|E, D, 0},
        /*w*/ {0, 0, A|G, A|G, A|D|G, A|D|G, B|C|E|F, 0},
        /*x*/ {0, 0, A|F, B|E, C|D, B|E, A|F, 0},
        /*y*/ {0, 0, B|F, B|F, B|F, C|F, A|D|E, B|C|D},
        /*z*/ {0, 0, A|B|C|D|E|F, E, D, C, B|C|D|E|F|G, 0},
        /*A*/ {D, C|E, B|F, A|G, A|B|C|D|E|F|G, A|G, A|G, 0},
        /*B*/ {A|B|C|D|E, A|F, A|F, A|B|C|D|E, A|F, A|F, A|B|C|D|E, 0},
        /*C*/ {C|D|E, B|F, A, A, A, B|F, C|D|E, 0},
        /*D*/ {A|B|C|D, A|E, A|F, A|F, A|F, A|E, A|B|C|D, 0},
        /*E*/ {A|B|C|D|E|F, A, A, A|B|C|D|E, A, A, A|B|C|D|E|F, 0},
        /*F*/ {A|B|C|D|E|F, A, A, A|B|C|D|E, A, A, A, 0},
        /*G*/ {C|D|E, B|F, A, A, A|E|F|G, B|F|G, C|D|E|G, 0},
        /*H*/ {A|G, A|G, A|G, A|B|C|D|E|F|G, A|G, A|G, A|G, 0},
        /*I*/ {A|B|C|D|E, C, C, C, C, C, A|B|C|D|E, 0},
        /*J*/ {A|B|C|D|E, C, C, C, C, C, A|C, B},
        /*K*/ {A|F, A|E, A|D, A|B|C, A|D, A|E, A|F, 0},
        /*L*/ {A, A, A, A, A, A, A|B|C|D|E|F, 0},
        /*M*/ {A|B|F|G, A|C|E|G, A|D|G, A|G, A|G, A|G, A|G, 0},
        /*N*/ {A|G, A|B|G, A|C|G, A|D|G, A|E|G, A|F|G, A|G, 0},
        /*O*/ {C|D|E, B|F, A|G, A|G, A|G, B|F, C|D|E, 0},
        /*P*/ {A|B|C|D, A|E, A|E, A|B|C|D, A, A, A, 0},
        /*Q*/ {C|D|E, B|F, A|G, A|G, A|C|G, B|D|F, C|D|E, F|G},
        /*R*/ {A|B|C|D, A|E, A|E, A|B|C|D, A|E, A|F, A|F, 0},
        /*S*/ {C|D|E, B|F, C, D, E, B|F, C|D|E, 0},
        /*T*/ {A|B|C|D|E|F|G, D, D, D, D, D, D, 0},
        /*U*/ {A|G, A|G, A|G, A|G, A|G, B|F, C|D|E, 0},
        /*V*/ {A|G, A|G, B|F, B|F, C|E, C|E, D, 0},
        /*W*/ {A|G, A|G, A|G, A|G, A|D|G, A|C|E|G, B|F, 0},
        /*X*/ {A|G, A|G, B|F, C|D|E, B|F, A|G, A|G, 0},
        /*Y*/ {A|G, A|G, B|F, C|E, D, D, D, 0},
        /*Z*/ {A|B|C|D|E|F|G, F, E, D, C, B, A|B|C|D|E|F|G, 0},
        /*.*/ {0, 0, 0, 0, 0, 0, D, 0},
        /*,*/ {0, 0, 0, 0, 0, E, E, D},
        /*:*/ {0, 0, 0, 0, D, 0, D, 0},
        /*!*/ {D, D, D, D, D, 0, D, 0},
        /*/ */ {G, F, E, D, C, B, A, 0},
        /*\\*/ {A, B, C, D, E, F, G, 0},
        /*|*/ {D, D, D, D, D, D, D, D},
        /*+*/ {0, D, D, B|C|D|E|F, D, D, 0, 0},
        /*-*/ {0, 0, 0, B|C|D|E|F, 0, 0, 0, 0},
        /***/ {0, B|D|F, C|D|E, D, C|D|E, B|D|F, 0, 0},
        /*=*/ {0, 0, B|C|D|E|F, 0, B|C|D|E|F, 0, 0, 0}
    };

    /*
       01234567  01234567  01234567  01234567  01234567  01234567
    0   #####               #           ###               #
    1  #     #              #          #                  #
    2  #     #    ####      #          #        #### #    #
    3   #####         #     #####    #####     #    #     ####
    4  #     #    #####     #    #     #       #    #     #   #
    5  #     #   #    #     #    #     #        ####      #   #
    6   #####     #### #   # ####      #            #    ##   #
    7                                           ####
    */

    /*
       01234567  01234567  01234567  01234567  01234567  01234567
    0                       #
    1    #          #       #  #
    2                       # #      #         #####      #### #
    3   ##          #       ##       ### ##     #   #    #    #
    4    #          #       # #      #  #  #    #   #    #    #
    5    #          #       #  #     #  #  #    ####      ####
    6  #####     #  #      ##  ##    ## #  #    #             #
    7             ##                           ##             ##
    */

    /*
       01234567  01234567  01234567  01234567  01234567  01234567
    0
    1
    2  ## ##      ####     #    #     #   #    ######    #     #
    3   ##  #    #          #  #      #   #        #     #     #
    4   #         ####       ##       #   #       #      #  #  #
    5   #             #     #  #       #  #      #       #  #  #
    6  ##        #####     #    #    #  ##      ######    ## ##
    7                                 ###
    */

    /*
       01234567  01234567  01234567  01234567  01234567  01234567
    0     #      #####       ###     ####      #####     #     #
    1    # #     #    #     #   #    #   #       #       #     #
    2   #   #    #    #    #         #    #      #       #     #
    3   #   #    #####     #         #    #      #       #     #
    4   #####    #    #    #         #    #      #       #  #  #
    5  #     #   #    #     #   #    #   #       #       # # # #
    6  #     #   #####       ###     ####      # #        #   #
    7                                           #
    */

    // @formatter:on
}