aboutsummaryrefslogtreecommitdiff
blob: d58036ae8b68cf9927f0b5d0e43dedb5bf32066e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# 	vim:fileencoding=utf-8
# Copyright 2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

from portage.output import colorize

try:  # newer python versions
    from itertools import zip_longest
except ImportError:  # older python naming
    from itertools import izip_longest as zip_longest

__all__ = [
    "string_rotator",
    "colorize_string",
    "align_string",
    "rotate_dash",
    "print_content",
    "display",
]


def display(
    plain_list, rotated_list, plain_width, rotated_height, cp, toplist="archlist"
):
    """Render defauld display to show the keywords listing"""
    # header
    output = []
    output.append("Keywords for %s:" % colorize("blue", cp))
    # data
    corner_image = ["".ljust(plain_width) for x in range(rotated_height)]
    if toplist != "archlist":
        corner_image.extend(plain_list)
    data_printout = [
        "%s%s" % (x, y)
        for x, y in zip_longest(corner_image, rotated_list, fillvalue=corner_image[0])
    ]
    if toplist == "archlist":
        data_printout.extend(plain_list)
    output.extend(data_printout)
    print(print_content(output))


def align_string(string, align, length):
    """Align string to the specified alignment (left or right, and after rotation it becomes top and bottom)"""
    if align == "top" or align == "left":
        string = string.ljust(length)
    else:
        string = string.rjust(length)
    return string


def colorize_string(color, string):
    """Add coloring for specified string. Due to rotation we need to do that per character rather than per-line"""
    tmp = []
    for char in list(string):
        # % is whitespace separator so we wont color that :)
        if char != "%":
            tmp.append(colorize(color, char))
        else:
            tmp.append(char)
    return "".join(tmp)


def rotate_dash(string):
    """Rotate special strings over 90 degrees for better readability."""
    chars = ["-", "|"]
    subs = ["|", "-"]
    out = string
    for x, y in zip(chars, subs):
        if string.find(x) != -1:
            out = out.replace(x, y)
    return out


def print_content(content):
    """Print out content (strip it out of the temporary %)"""
    return "\n".join(content).replace("%", "")


class string_rotator:
    __DASH_COUNT = 0

    def __getChar(self, string, position, line, bold_separator=False):
        """Return specified character from the string position"""

        # first figure out what character we want to work with
        # based on order and position in the string
        isdash = False
        if string.startswith("|") or string.startswith("-") or string.startswith("+"):
            split = list(string)
            isdash = True
            self.__DASH_COUNT += 1
        else:
            split = string.split("%")
        char = split[position]
        # bolding
        if (
            not isdash
            and bold_separator
            and (line - self.__DASH_COUNT) % 2 == 0
            and char != " "
        ):
            char = colorize("bold", char)
        return char

    def rotateContent(self, elements, length, bold_separator=False, strip=True):
        """
        Rotate string over 90 degrees:
        string -> s
                                t
                                r
                                i
                                n
                                g
        """
        # join used to have list of lines rather than list of chars
        tmp = []
        for position in range(length):
            x = ""
            for i, string in enumerate(elements):
                x += " " + self.__getChar(
                    rotate_dash(string), position, i, bold_separator
                )
            # spaces on dashed line should be dashed too
            if x.find("+ -") != -1:
                x = x.replace(" ", "-")
            # strip all chars and remove empty lines
            if not strip or len(x.strip(" |-")) > 0:
                tmp.append(x)
        return tmp