How To Make ASCII Diagrams Beautifuller

I've discovered an excellent tool in asciiflow.com.  The website makes it really easy to create ASCII box diagrams like this

They put these things in fruit machines you know!


This is ideal for source code banners, which I think should contain helpful documentation - but most programmers think it's a good place for the COPYRIGHT information and nothing else.

But wait! we can make it beautifuller... and easier to read... by replacing some of the ASCII characters with ones available in UTF-8:



There!  Isn't that better?  (Although some purists may object to non-ASCII characters in your code base.)

SOURCE CODE:
#!/usr/bin/python2
# coding: utf-8

# + gets converted in different ways depending on it's 4 neighbours
#
# . N .   { nsew(N,S,E,W) has bit 3 set if N in "+|<>"
# W + E   { nsew(N,S,E,W) has bit 2 set if S in "+|<>"
# . S .   { nsew(N,S,E,W) has bit 1 set if W in "+-^v"
#         { nsew(N,S,E,W) has bit 0 set if E in "+-^v"

def nsew(N,S,E,W):
    rv  = int(N in '+|<>') << 3
    rv += int(S in '+|<>') << 2
    rv += int(W in '+-^v') << 1
    rv += int(E in '+-^v')
    return rv

# lookup from nsew(N,S,E,W) to unicode replacement for +
# NSWE        NSWE        NSWE        NSWE 
# 0000 +      0100 ┬      1000 ┴      1100 │
# 0001 ├      0101 ╭      1001 ╰      1101 ├
# 0010 ┤      0110 ╮      1010 ╯      1110 ┤
# 0011 ─      0111 ┬      1011 ┴      1111 ┼

u=unicode('+├┤─┬╭╮┬┴╰╯┴│├┤┼','utf-8')

def x(s): # s is input string, x means convert
    out = []
    d={'-':'─','|':'│'}
    lines = s.splitlines(True)
    rows = map(lambda l: list(l), lines)
    m, n = len(lines), map(lambda l: len(l), lines)
    for i in range(m):
        for j in range(n[i]):
            ch = rows[i][j]
            if ch == '+':
                N = rows[i-1][j] if i and j < n[i-1] else ' '
                S = rows[i+1][j] if i < m-1 and j < n[i+1] else ' '
                W = rows[i][j-1] if j else ' '
                E = rows[i][j+1] if j < n[i]-1 else ' '
                mask = nsew(N,S,E,W)
                out += [u[mask]]
            else:
                out += [unicode(d.get(ch,ch),'utf-8')]
    return ''.join(out)


import sys
if __name__ == '__main__':
    sys.stdout.write(x(sys.stdin.read()).encode('utf-8'))

Comments

  1. That's kind of neat - I didn't know about that! I wonder if asciiflow.com are using that source code.

    ReplyDelete

Post a Comment

Popular posts from this blog

Why growth is falling in all developed countries (as a long term trend)

Three ways to look at the Bell/GHZ experiment