Search code examples
pythonpretty-printword-wrapclint

Printing columns of an equal custom set spacing while not letting long strings flow over other columns. (using clint perhaps?)


Suppose I have these two lists:

column1 = ["Attribute:","Virtual machine:","Troll:"]
column2 = ["A value associated with an object which is referenced by name using dotted expressions. For example, if an object o has an attribute a it would be referenced as o.a.", 
           "A computer defined entirely in software. Python's virtual machine executes the bytecode emitted by the bytecode compiler.",
           "Someone who posts inflammatory, extraneous, or off-topic messages in an online community, such as a forum, chat room, or blog, with the primary intent of provoking readers into an emotional response or of otherwise disrupting normal on-topic discussion."]

This code:

for c1, c2 in zip(column1, column2):
    print "%-16s %s" % (c1, c2)

Ouputs this text:

Attribute:       A value associated with an object which is referenced by name u
sing dotted expressions. For example, if an object o has an attribute a it would
be referenced as o.a.
Virtual machine: A computer defined entirely in software. Python's virtual machi
ne executes the bytecode emitted by the bytecode compiler.
Troll:           Someone who posts inflammatory, extraneous, or off-topic messag
es in an online community, such as a forum, chat room, or blog, with the primary
 intent of provoking readers into an emotional response or of otherwise disrupti
ng normal on-topic discussion.

While I would like this:

Attribute:       A value associated with an object which is referenced by name 
                 using dotted expressions. For example, if an object o has an 
                 attribute a it would be referenced as o.a.
Virtual machine: A computer defined entirely in software. Python's virtual 
                 machine executes the bytecode emitted by the bytecode compiler.
Troll:           Someone who posts inflammatory, extraneous, or off-topic 
                 messages in an online community, such as a forum, chat room, or 
                 blog, with the primary intent of provoking readers into an 
                 emotional response or of otherwise disrupting normal on-topic
                 discussion.

How do I get this result for any terminal size? (Someone advised me that Clint might be able to achieve this quite easily, has anyone done this yet?)

Note: The requirement that a word is not chopped in pieces by the end of a line is only secondary for me. The most important requirement is letting each string element of the column2 list continue with the same horizontal spacing as where the string of each element in that list started.


Solution

  • from clint.textui import puts, columns
    
    width = 20
    
    for term, definition in zip(column1, column2):
        puts(columns([term, width], [definition, None]))
    

    ...prefix with this to choose column width based on content:

    #derive 1st column width from longest term
    width = 0
    for s in column1:
        if len(s) > width :
            width = len(s) + 1
    

    Adapted from clint\examples\text_width.py. Thanks for the question; I didn't know how to do this before, and it's something I'll use.