Python - Create a text border with dynamic size

喜你入骨 提交于 2020-12-29 16:33:28

问题


I'm creating a command line script and I'd like there to be box...

+--------+
|        |
|        |
|        |
+--------+

... that will always fit its contents. I know how to do the top and bottom, but it's getting the ljust and rjust working correctly. There may be one string substitute per line, or 5, and the len of those strings could be anything between 0 and 80.

I have been doing things like:

print "|%s|" % (my_string.ljust(80-len(my_string)))

But holy dang is that messy... And that's just one hardcoded substitution. I have no idea how to make it dynamic with say 2 subs on line one, and 3 subs on line two and 1 sub on line three (all this in a column format).

So for a basic example, I need:

+--------+
| 1      |
| 1 2 3  |
| 1 2    |
+--------+

回答1:


I do it like this:

def bordered(text):
    lines = text.splitlines()
    width = max(len(s) for s in lines)
    res = ['┌' + '─' * width + '┐']
    for s in lines:
        res.append('│' + (s + ' ' * width)[:width] + '│')
    res.append('└' + '─' * width + '┘')
    return '\n'.join(res)

So you first format all your objects into text wariable, and then pass it throught bordered() function.




回答2:


You can do it with tabulate

from tabulate import tabulate

text = """
some words that
could be dynamic but 
are currently static
"""

table = [[text]]
output = tabulate(table, tablefmt='grid')

print(output)

Output:

+-----------------------+
| some words that       |
| could be dynamic but  |
| are currently static  |
+-----------------------+



回答3:


You can use '*' for width and precision fields of a string format, as described in this answer. Here is a sample:

text = """\
This is
a test of the
column formatting
system.""".splitlines()

maxlen = max(len(s) for s in text)
colwidth = maxlen + 2

print '+' + '-'*colwidth + '+'
for s in text:
    print '| %-*.*s |' % (maxlen, maxlen, s)
print '+' + '-'*colwidth + '+'

prints:

+-------------------+
| This is           |
| a test of the     |
| column formatting |
| system.           |
+-------------------+



回答4:


You can use curses module from python standard library for Linux and Mac. Also you can try pygcurse library for Mac, Linux and Windows. Also, you can read it. But for simple dialog you can use next code:

def my_text_frame(string_lst, width=20):
    g_line = "+{0}+".format("-"*(width-2))
    print g_line
    for line in string_lst:
        print "| {0:<{1}} |".format(line, width-4)
    print g_line
my_text_frame("""Some text
123456 789
123""".splitlines())

Output:

+------------------+
| Some text        |
| 123456 789       |
| 123              |
+------------------+



回答5:


I'm late to the party, but here is my version:

def breakLine(text, wrap=80):
    if len(text) > wrap:
        char = wrap
        while char > 0 and text[char] != ' ':
            char -= 1
        if char:
            text = [text[:char]] + breakLine(text[char + 1:], wrap)
        else:
            text = [text[:wrap - 1] + '-'] + breakLine(text[wrap - 1:], wrap)
        return text
    else:
        return [cleanLine(text)]

def cleanLine(text):
    if text[-1] == ' ':
        text = text[:-1]
    if text[0] == ' ':
        text = text[1:]
    return text

def boxPrint(text, wrap=0):
    line_style = '-'
    paragraph = text.split('\n')
    if wrap>0:
        index = 0
        while index < len(paragraph):
            paragraph[index] = cleanLine(paragraph[index])
            if len(paragraph[index]) > wrap:
                paragraph = paragraph[:index] + breakLine(paragraph[index]\
                    , wrap) + paragraph[index + 1:]
            index += 1

    length = (max([len(line) for line in paragraph]))
    print '+' + line_style * length + '+'
    for line in paragraph:
        print '|' + line + ' ' * (length - len(line)) + '|'
    print '+' + line_style * length + '+'

if __name__ == "__main__":
    text = "Some text comes here to be printed in a box!!!"
    boxPrint(text, 20)
    text = "Title:\nBody lorem ipsum something body\ncheers,"
    boxPrint(text, 20)
    boxPrint(text)
    text = "No Space:\nThisIsATextThatHasNoSpaceForWrappingWhichGetsBrokenUsingDashes"
    boxPrint(text, 20)

Which prints:

+--------------------+
|Some text comes here|
|to be printed in a  |
|box!!!              |
+--------------------+
+----------------+
|Title:          |
|Body lorem ipsum|
|something body  |
|cheers,         |
+----------------+
+-------------------------------+
|Title:                         |
|Body lorem ipsum something body|
|cheers,                        |
+-------------------------------+
+--------------------+
|No Space:           |
|ThisIsATextThatHasN-|
|oSpaceForWrappingWh-|
|ichGetsBrokenUsingD-|
|ashes               |
+--------------------+


来源:https://stackoverflow.com/questions/20756516/python-create-a-text-border-with-dynamic-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!