Skip to content

text

SpacedText

Representation of text with newlines before or after.

Source code in mkreports/md/text.py
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
class SpacedText:
    """Representation of text with newlines before or after."""

    text: str
    req_nl: Tuple[int, int]

    def __init__(self, text: Text = "", req_nl: Tuple[int, int] = (0, 0)) -> None:
        """
        Initialize the object.

        Args:
            text (Text): The text to print.
            req_nl (Tuple[int, int]): Number of newlines before and after to ensure.
        """
        if isinstance(text, str):
            my_text = text
            my_req_nl = req_nl
        else:
            my_text = text.text
            my_req_nl = (
                max(req_nl[0], text.req_nl[0]),
                max(req_nl[1], text.req_nl[1]),
            )

        self.text = my_text
        self.req_nl = my_req_nl

    def __str__(self) -> str:
        """
        Return a formatted str.

        We assume that 3 newlines are before and after. That should be enough.
        """
        return self.format_text("\n\n\n", "\n\n\n")

    def __eq__(self, other: Any) -> bool:
        if type(self) != type(other):
            return False
        return self.text == other.text and self.req_nl == other.req_nl

    def __add__(self, follow: Text) -> "SpacedText":
        return _add_text(self, SpacedText(follow))

    def __radd__(self, precede: Text) -> "SpacedText":
        return _add_text(SpacedText(precede), self)

    def format_text(self, precede: Text = "", follow: Text = "") -> str:
        add_before = _needed_nl_between(SpacedText(precede), self)
        add_after = _needed_nl_between(self, SpacedText(follow))

        # return with the required additional newlines
        return ("\n" * add_before) + self.text + ("\n" * add_after)

__init__(text='', req_nl=(0, 0))

Initialize the object.

Parameters:

Name Type Description Default
text Text

The text to print.

''
req_nl Tuple[int, int]

Number of newlines before and after to ensure.

(0, 0)
Source code in mkreports/md/text.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def __init__(self, text: Text = "", req_nl: Tuple[int, int] = (0, 0)) -> None:
    """
    Initialize the object.

    Args:
        text (Text): The text to print.
        req_nl (Tuple[int, int]): Number of newlines before and after to ensure.
    """
    if isinstance(text, str):
        my_text = text
        my_req_nl = req_nl
    else:
        my_text = text.text
        my_req_nl = (
            max(req_nl[0], text.req_nl[0]),
            max(req_nl[1], text.req_nl[1]),
        )

    self.text = my_text
    self.req_nl = my_req_nl

__str__()

Return a formatted str.

We assume that 3 newlines are before and after. That should be enough.

Source code in mkreports/md/text.py
55
56
57
58
59
60
61
def __str__(self) -> str:
    """
    Return a formatted str.

    We assume that 3 newlines are before and after. That should be enough.
    """
    return self.format_text("\n\n\n", "\n\n\n")

_needed_nl_between(first, second)

Calculates the number of newlines needed between two text objects.

Source code in mkreports/md/text.py
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
def _needed_nl_between(first: SpacedText, second: SpacedText) -> int:
    """
    Calculates the number of newlines needed between two text objects.
    """
    if first.text == "" or second.text == "":
        return 0

    req_first_after = first.req_nl[1]
    num_first_after = count_newlines(first.text, before=False)

    req_second_before = second.req_nl[0]
    num_second_before = count_newlines(second.text, before=True)

    add_between = max(
        max(req_first_after, req_second_before) - num_second_before - num_first_after,
        0,
    )
    return add_between

count_newlines(x, before=True)

Count the number of newlines from front or back.

Here all newlines are counted while ignoring whitespace. Stop at first character that is not newline or whitespace. If there are no non-newline or whitespace characters, return infinite number of newlines.

Source code in mkreports/md/text.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def count_newlines(x: str, before=True) -> int:
    """
    Count the number of newlines from front or back.

    Here all newlines are counted while ignoring whitespace.
    Stop at first character that is not newline or whitespace.
    If there are no non-newline or whitespace characters, return
    infinite number of newlines.
    """
    num_nl = 0
    whitespace = [" ", "\r", "\t"]
    y = x if before else reversed(x)
    for ch in y:
        if ch == "\n":
            num_nl += 1
        elif ch in whitespace:
            continue
        else:
            return num_nl
    return num_nl