diff --git a/src/rebdhuhn/graphviz.py b/src/rebdhuhn/graphviz.py
index 8ed491b..51d3e41 100644
--- a/src/rebdhuhn/graphviz.py
+++ b/src/rebdhuhn/graphviz.py
@@ -10,16 +10,20 @@
from rebdhuhn.graph_utils import _mark_last_common_ancestors
from rebdhuhn.kroki import DotToSvgConverter
from rebdhuhn.models import DecisionNode, EbdGraph, EbdGraphEdge, EndNode, OutcomeNode, StartNode, ToNoEdge, ToYesEdge
+from rebdhuhn.utils import add_line_breaks
ADD_INDENT = " " #: This is just for style purposes to make the plantuml files human-readable.
+_LABEL_MAX_LINE_LENGTH = 80
+
def _format_label(label: str) -> str:
"""
Converts the given string e.g. a text for a node to a suitable output for dot. It replaces newlines (`\n`) with
the HTML-tag ` `.
"""
- return escape(label).replace("\n", ' ')
+ label_with_linebreaks = add_line_breaks(label, max_line_length=_LABEL_MAX_LINE_LENGTH, line_sep="\n")
+ return escape(label_with_linebreaks).replace("\n", ' ')
# escaped_str = re.sub(r"^(\d+): ", r"\1: ", label)
# escaped_str = label.replace("\n", ' ')
# return f'<{escaped_str} >'
diff --git a/src/rebdhuhn/utils.py b/src/rebdhuhn/utils.py
new file mode 100644
index 0000000..2062eb1
--- /dev/null
+++ b/src/rebdhuhn/utils.py
@@ -0,0 +1,58 @@
+"""utility functions"""
+
+
+def _split_string(input_string: str, max_length: int) -> list[str]:
+ """
+ Splits the input string into multiple parts, each with a maximum length of `max_length`.
+ The split occurs at the last space before reaching the limit.
+
+ :param input_string: The string to be split.
+ :param max_length: The maximum length for each part (default is 80).
+ :return: A list of strings, each of length up to `max_length`.
+ """
+ parts: list[str] = []
+ hurenkinder_length = int(0.125 * max_length)
+ grace_length = int(1.5 * max_length)
+ while len(input_string) > max_length:
+ # Find the last space before the max length
+ split_index_line_break = input_string.find("\n", 0, grace_length) # we prefer early line breaks
+ split_index_whitespace: int = input_string.rfind(" ", 0, max_length) # but late white spaces
+ split_index: int
+ # If no space is found, split at the max length
+ if split_index_line_break != -1: # prefer this one
+ split_index = split_index_line_break
+ elif split_index_whitespace != -1:
+ split_index = split_index_whitespace
+ else:
+ split_index = max_length
+ # Extract the part and append to the list
+ part: str = input_string[:split_index].rstrip()
+ if split_index_line_break != -1:
+ part = part.replace("\n", "")
+ parts.append(part)
+
+ # Update the input_string to the remaining part
+ input_string = input_string[split_index:].lstrip()
+ remaining_text_is_shorter_than_hurenkinder_threshold = len(input_string) <= hurenkinder_length
+ line_without_hurenkinder_within_grace_length = len(input_string) + len(part) <= grace_length
+ if remaining_text_is_shorter_than_hurenkinder_threshold and line_without_hurenkinder_within_grace_length:
+ parts[-1] += " " + input_string
+ input_string = ""
+ break
+ # Add the remaining string if any
+ if input_string:
+ parts.append(input_string)
+
+ return parts
+
+
+def add_line_breaks(text: str, max_line_length: int = 80, line_sep: str = "\n") -> str:
+ """
+ Adds line_sep lines breaks between words after max max_line_length characters.
+ If there already is a line break within the next max_line_length/2 after the max_line_length, we prefer to use that
+ one instead of adding a new one. This is because we cannot decide if an existing line break is just an artefact of
+ the .docx files (e.g. word break because the width of a column is limited) or if it has a functional meaning.
+ A line break with a meaning is e.g. "Cluster Ablehnung:\n ..." <- here the line break structures the text in a good
+ way, whereas `...Bilanzierungs-\nverantwortung...` is just an artefact.
+ """
+ return line_sep.join(_split_string(text, max_line_length))
diff --git a/unittests/__snapshots__/test_table_to_graph.ambr b/unittests/__snapshots__/test_table_to_graph.ambr
index d28804c..0ad1864 100644
--- a/unittests/__snapshots__/test_table_to_graph.ambr
+++ b/unittests/__snapshots__/test_table_to_graph.ambr
@@ -122,7 +122,7 @@
# ---
# name: TestEbdTableModels.test_table_to_digraph_dot_real_kroki_request[table1-DiGraph with 22 nodes and 21 edges][test_table_to_digraph_dot_real_kroki_request_E_0015_MaBiS-ZP Aktivierung prüfen]
'''
-
+
+ }'-->
D
- 7.17 AD: Aktivierung eines MaBiS-ZP für Bilanzierungsgebietssummenzeitreihen vom ÜNB an BIKO und NB
- 7.17.1 E_0015_MaBiS-ZP Aktivierung prüfen
+ 7.17 AD: Aktivierung eines MaBiS-ZP für Bilanzierungsgebietssummenzeitreihen vom ÜNB an BIKO und NB
+ 7.17.1 E_0015_MaBiS-ZP Aktivierung prüfen
Start
-
- E_0015
- Prüfende Rolle:
- BIKO
+
+ E_0015
+ Prüfende Rolle:
+ BIKO
1
-
- 1:
- Erfolgt die Aktivierung nach Ablauf der Clearingfrist für die KBKA?
+
+ 1:
+ Erfolgt die Aktivierung nach Ablauf der Clearingfrist für die KBKA?
Start->1
-
-
+
+
A01
-
- A01
- Hinweis:
- Cluster Ablehnung
- Fristüberschreitung
+
+ A01
+ Hinweis:
+ Cluster Ablehnung
+ Fristüberschreitung
1->A01
-
-
- Ja
+
+
+ Ja
2
-
- 2:
- Erfolgt die Aktivierung zum Monatsersten 00:00 Uhr?
+
+ 2:
+ Erfolgt die Aktivierung zum Monatsersten 00:00 Uhr?
1->2
-
-
- Nein
+
+
+ Nein
A02
-
- A02
- Hinweis:
- Cluster Ablehnung
- Gewählter Zeitpunkt nicht zulässig
+
+ A02
+ Hinweis:
+ Cluster Ablehnung
+ Gewählter Zeitpunkt nicht zulässig
2->A02
-
-
- Nein
+
+
+ Nein
3
-
- 3:
- Ist die richtige Regelzone angegeben
+
+ 3:
+ Ist die richtige Regelzone angegeben
2->3
-
-
- Ja
+
+
+ Ja
A03
-
- A03
- Hinweis:
- Cluster Ablehnung
- Regelzone falsch
+
+ A03
+ Hinweis:
+ Cluster Ablehnung
+ Regelzone falsch
3->A03
-
-
- Nein
+
+
+ Nein
4
-
- 4:
- Ist das Bilanzierungsgebiet zum Aktivierungsbeginn in der Regelzone des BIKO gültig?
+
+ 4:
+ Ist das Bilanzierungsgebiet zum Aktivierungsbeginn in der Regelzone des BIKO gültig?
3->4
-
-
- Ja
+
+
+ Ja
A04
-
- A04
- Hinweis:
- Cluster Ablehnung
- Bilanzierungsgebiet nicht gültig
+
+ A04
+ Hinweis:
+ Cluster Ablehnung
+ Bilanzierungsgebiet nicht gültig
4->A04
-
-
- Nein
+
+
+ Nein
5
-
- 5:
- Ist der ÜNB zum Aktivierungsbeginn für das Bilanzierungsgebiet zuständig?
+
+ 5:
+ Ist der ÜNB zum Aktivierungsbeginn für das Bilanzierungsgebiet zuständig?
4->5
-
-
- Ja
+
+
+ Ja
A05
-
- A05
- Hinweis:
- Cluster Ablehnung
- Keine Berechtigung
+
+ A05
+ Hinweis:
+ Cluster Ablehnung
+ Keine Berechtigung
5->A05
-
-
- Nein
+
+
+ Nein
6
-
- 6:
- Existiert bereits ein abweichendes Tupel unter der ID des MaBiS-ZP?
+
+ 6:
+ Existiert bereits ein abweichendes Tupel unter der ID des MaBiS-ZP?
5->6
-
-
- Ja
+
+
+ Ja
A06
-
- A06
- Hinweis:
- Cluster Ablehnung
- Abweichender MaBiS-ZP bereits vorhanden
+
+ A06
+ Hinweis:
+ Cluster Ablehnung
+ Abweichender MaBiS-ZP bereits vorhanden
6->A06
-
-
- Ja
+
+
+ Ja
7
-
- 7:
- Existiert bereits für das genannte Tupel aus Aggregations-verantwortlicher, Bilanzierungsgebiet, Spannungsebene und ZRT eine abweichende ID des MaBiS-ZP?
+
+ 7:
+ Existiert bereits für das genannte Tupel aus Aggregations-verantwortlicher,
+ Bilanzierungsgebiet, Spannungsebene und ZRT eine abweichende ID des MaBiS-ZP?
6->7
-
-
- Nein
+
+
+ Nein
A07
-
- A07
- Hinweis:
- Cluster Ablehnung
- Abweichende ID zum MaBiS-ZP bereits vorhanden
+
+ A07
+ Hinweis:
+ Cluster Ablehnung
+ Abweichende ID zum MaBiS-ZP bereits vorhanden
7->A07
-
-
- Ja
+
+
+ Ja
8
-
- 8:
- Ist der ÜNB zur Aktivierung des ZRT berechtigt?
+
+ 8:
+ Ist der ÜNB zur Aktivierung des ZRT berechtigt?
7->8
-
-
- Nein
+
+
+ Nein
A08
-
- A08
- Hinweis:
- Cluster Ablehnung
- ZRT Aktivierung nicht berechtigt
+
+ A08
+ Hinweis:
+ Cluster Ablehnung
+ ZRT Aktivierung nicht berechtigt
8->A08
-
-
- Nein
+
+
+ Nein
9
-
- 9:
- Passt die OBIS-Kennzahl zum ZRT?
+
+ 9:
+ Passt die OBIS-Kennzahl zum ZRT?
8->9
-
-
- Ja
+
+
+ Ja
A09
-
- A09
- Hinweis:
- Cluster Ablehnung
- OBIS nicht passend
+
+ A09
+ Hinweis:
+ Cluster Ablehnung
+ OBIS nicht passend
9->A09
-
-
- Nein
+
+
+ Nein
10
-
- 10:
- Ist der MaBiS-ZP zum Zeitpunkt der Aktivierung bereits aktiviert?
+
+ 10:
+ Ist der MaBiS-ZP zum Zeitpunkt der Aktivierung bereits aktiviert?
9->10
-
-
- Ja
+
+
+ Ja
A10
-
- A10
- Hinweis:
- Cluster Ablehnung
- MaBiS-ZP bereits aktiviert
+
+ A10
+ Hinweis:
+ Cluster Ablehnung
+ MaBiS-ZP bereits aktiviert
10->A10
-
-
- Ja
+
+
+ Ja
A11
-
- A11
- Hinweis:
- Cluster: Zustimmung
- Aktivierung durchgeführt
+
+ A11
+ Hinweis:
+ Cluster: Zustimmung
+ Aktivierung durchgeführt
10->A11
-
-
- Nein
+
+
+ Nein
diff --git a/unittests/output/E_0003.dot.svg b/unittests/output/E_0003.dot.svg
index e0e3a11..ef2314b 100644
--- a/unittests/output/E_0003.dot.svg
+++ b/unittests/output/E_0003.dot.svg
@@ -24,7 +24,30 @@
-
+
D
7.39 AD: Bestellung der Aggregationsebene der Bilanzkreissummenzeitreihe auf Ebene der Regelzone
7.39.1 E_0003_Bestellung der Aggregationsebene RZ prüfen
diff --git a/unittests/output/E_0003_with_watermark_background_is_False.dot.svg b/unittests/output/E_0003_with_watermark_background_is_False.dot.svg
index c757ef3..fa0d3a4 100644
--- a/unittests/output/E_0003_with_watermark_background_is_False.dot.svg
+++ b/unittests/output/E_0003_with_watermark_background_is_False.dot.svg
@@ -22,7 +22,30 @@
-
+
D
7.39 AD: Bestellung der Aggregationsebene der Bilanzkreissummenzeitreihe auf Ebene der Regelzone
7.39.1 E_0003_Bestellung der Aggregationsebene RZ prüfen
diff --git a/unittests/output/E_0003_with_watermark_background_is_True.dot.svg b/unittests/output/E_0003_with_watermark_background_is_True.dot.svg
index e0e3a11..ef2314b 100644
--- a/unittests/output/E_0003_with_watermark_background_is_True.dot.svg
+++ b/unittests/output/E_0003_with_watermark_background_is_True.dot.svg
@@ -24,7 +24,30 @@
-
+
D
7.39 AD: Bestellung der Aggregationsebene der Bilanzkreissummenzeitreihe auf Ebene der Regelzone
7.39.1 E_0003_Bestellung der Aggregationsebene RZ prüfen
diff --git a/unittests/output/E_0003_without_watermark.dot.svg b/unittests/output/E_0003_without_watermark.dot.svg
index 6c9fdeb..72c4ae7 100644
--- a/unittests/output/E_0003_without_watermark.dot.svg
+++ b/unittests/output/E_0003_without_watermark.dot.svg
@@ -1,22 +1,38 @@
-
-
-
-
-
-
+
+
D
7.39 AD: Bestellung der Aggregationsebene der Bilanzkreissummenzeitreihe auf Ebene der Regelzone
-7.39.1 E_0003_Bestellung der Aggregationsebene RZ prüfen
+7.39.1 E_0003_Bestellung der Aggregationsebene RZ prüfen
Start
E_0003
-Prüfende Rolle:
- ÜNB
+Prüfende Rolle:
+ ÜNB
@@ -27,7 +43,7 @@
-Start->1
+Start->1
@@ -37,11 +53,11 @@
A01
Hinweis:
-Fristüberschreitung
+Fristüberschreitung
-1->A01
+1->A01
Nein
@@ -55,7 +71,7 @@
-1->2
+1->2
Ja
@@ -66,11 +82,11 @@
A02
Hinweis:
-Gewählter Zeitpunkt nicht zulässig
+Gewählter Zeitpunkt nicht zulässig
-2->A02
+2->A02
Nein
@@ -83,10 +99,10 @@
-2->Ende
+2->Ende
Ja
-
+
\ No newline at end of file
diff --git a/unittests/output/E_0015.dot.svg b/unittests/output/E_0015.dot.svg
index f513cb1..717d02f 100644
--- a/unittests/output/E_0015.dot.svg
+++ b/unittests/output/E_0015.dot.svg
@@ -1,9 +1,9 @@
-
+
-
-
-
+
+
+
@@ -23,333 +23,389 @@
-
-
+
+
D
-7.17 AD: Aktivierung eines MaBiS-ZP für Bilanzierungsgebietssummenzeitreihen vom ÜNB an BIKO und NB
-7.17.1 E_0015_MaBiS-ZP Aktivierung prüfen
+7.17 AD: Aktivierung eines MaBiS-ZP für Bilanzierungsgebietssummenzeitreihen vom ÜNB an BIKO und NB
+7.17.1 E_0015_MaBiS-ZP Aktivierung prüfen
Start
-
-E_0015
-Prüfende Rolle:
- BIKO
+
+E_0015
+Prüfende Rolle:
+ BIKO
1
-
-1:
-Erfolgt die Aktivierung nach Ablauf der Clearingfrist für die KBKA?
+
+1:
+Erfolgt die Aktivierung nach Ablauf der Clearingfrist für die KBKA?
Start->1
-
-
+
+
A01
-
-A01
-Hinweis:
-Cluster Ablehnung
-Fristüberschreitung
+
+A01
+Hinweis:
+Cluster Ablehnung
+Fristüberschreitung
1->A01
-
-
-Ja
+
+
+Ja
2
-
-2:
-Erfolgt die Aktivierung zum Monatsersten 00:00 Uhr?
+
+2:
+Erfolgt die Aktivierung zum Monatsersten 00:00 Uhr?
1->2
-
-
-Nein
+
+
+Nein
A02
-
-A02
-Hinweis:
-Cluster Ablehnung
-Gewählter Zeitpunkt nicht zulässig
+
+A02
+Hinweis:
+Cluster Ablehnung
+Gewählter Zeitpunkt nicht zulässig
2->A02
-
-
-Nein
+
+
+Nein
3
-
-3:
-Ist die richtige Regelzone angegeben
+
+3:
+Ist die richtige Regelzone angegeben
2->3
-
-
-Ja
+
+
+Ja
A03
-
-A03
-Hinweis:
-Cluster Ablehnung
-Regelzone falsch
+
+A03
+Hinweis:
+Cluster Ablehnung
+Regelzone falsch
3->A03
-
-
-Nein
+
+
+Nein
4
-
-4:
-Ist das Bilanzierungsgebiet zum Aktivierungsbeginn in der Regelzone des BIKO gültig?
+
+4:
+Ist das Bilanzierungsgebiet zum Aktivierungsbeginn in der Regelzone des BIKO gültig?
3->4
-
-
-Ja
+
+
+Ja
A04
-
-A04
-Hinweis:
-Cluster Ablehnung
-Bilanzierungsgebiet nicht gültig
+
+A04
+Hinweis:
+Cluster Ablehnung
+Bilanzierungsgebiet nicht gültig
4->A04
-
-
-Nein
+
+
+Nein
5
-
-5:
-Ist der ÜNB zum Aktivierungsbeginn für das Bilanzierungsgebiet zuständig?
+
+5:
+Ist der ÜNB zum Aktivierungsbeginn für das Bilanzierungsgebiet zuständig?
4->5
-
-
-Ja
+
+
+Ja
A05
-
-A05
-Hinweis:
-Cluster Ablehnung
-Keine Berechtigung
+
+A05
+Hinweis:
+Cluster Ablehnung
+Keine Berechtigung
5->A05
-
-
-Nein
+
+
+Nein
6
-
-6:
-Existiert bereits ein abweichendes Tupel unter der ID des MaBiS-ZP?
+
+6:
+Existiert bereits ein abweichendes Tupel unter der ID des MaBiS-ZP?
5->6
-
-
-Ja
+
+
+Ja
A06
-
-A06
-Hinweis:
-Cluster Ablehnung
-Abweichender MaBiS-ZP bereits vorhanden
+
+A06
+Hinweis:
+Cluster Ablehnung
+Abweichender MaBiS-ZP bereits vorhanden
6->A06
-
-
-Ja
+
+
+Ja
7
-
-7:
-Existiert bereits für das genannte Tupel aus Aggregations-verantwortlicher, Bilanzierungsgebiet, Spannungsebene und ZRT eine abweichende ID des MaBiS-ZP?
+
+7:
+Existiert bereits für das genannte Tupel aus Aggregations-verantwortlicher,
+Bilanzierungsgebiet, Spannungsebene und ZRT eine abweichende ID des MaBiS-ZP?
6->7
-
-
-Nein
+
+
+Nein
A07
-
-A07
-Hinweis:
-Cluster Ablehnung
-Abweichende ID zum MaBiS-ZP bereits vorhanden
+
+A07
+Hinweis:
+Cluster Ablehnung
+Abweichende ID zum MaBiS-ZP bereits vorhanden
7->A07
-
-
-Ja
+
+
+Ja
8
-
-8:
-Ist der ÜNB zur Aktivierung des ZRT berechtigt?
+
+8:
+Ist der ÜNB zur Aktivierung des ZRT berechtigt?
7->8
-
-
-Nein
+
+
+Nein
A08
-
-A08
-Hinweis:
-Cluster Ablehnung
-ZRT Aktivierung nicht berechtigt
+
+A08
+Hinweis:
+Cluster Ablehnung
+ZRT Aktivierung nicht berechtigt
8->A08
-
-
-Nein
+
+
+Nein
9
-
-9:
-Passt die OBIS-Kennzahl zum ZRT?
+
+9:
+Passt die OBIS-Kennzahl zum ZRT?
8->9
-
-
-Ja
+
+
+Ja
A09
-
-A09
-Hinweis:
-Cluster Ablehnung
-OBIS nicht passend
+
+A09
+Hinweis:
+Cluster Ablehnung
+OBIS nicht passend
9->A09
-
-
-Nein
+
+
+Nein
10
-
-10:
-Ist der MaBiS-ZP zum Zeitpunkt der Aktivierung bereits aktiviert?
+
+10:
+Ist der MaBiS-ZP zum Zeitpunkt der Aktivierung bereits aktiviert?
9->10
-
-
-Ja
+
+
+Ja
A10
-
-A10
-Hinweis:
-Cluster Ablehnung
-MaBiS-ZP bereits aktiviert
+
+A10
+Hinweis:
+Cluster Ablehnung
+MaBiS-ZP bereits aktiviert
10->A10
-
-
-Ja
+
+
+Ja
A11
-
-A11
-Hinweis:
-Cluster: Zustimmung
-Aktivierung durchgeführt
+
+A11
+Hinweis:
+Cluster: Zustimmung
+Aktivierung durchgeführt
10->A11
-
-
-Nein
+
+
+Nein
diff --git a/unittests/output/E_0025.dot.svg b/unittests/output/E_0025.dot.svg
index 794359f..16b480a 100644
--- a/unittests/output/E_0025.dot.svg
+++ b/unittests/output/E_0025.dot.svg
@@ -24,7 +24,40 @@
-
+
D
7.41 AD: Übermittlung Prüfmitteilung für die Bilanzkreissummenzeitreihe vom BKV an BIKO und ÜNB
7.41.2 E_0025_Prüfmitteilung prüfen
diff --git a/unittests/output/E_0401.dot.svg b/unittests/output/E_0401.dot.svg
index 24b38e3..3011b4a 100644
--- a/unittests/output/E_0401.dot.svg
+++ b/unittests/output/E_0401.dot.svg
@@ -24,7 +24,69 @@
-
+
D
6.2 AD: Lieferende LF an NB
6.2.1 E_0401_Abmeldung prüfen
diff --git a/unittests/test_files/E_0015_kroki_response.dot.svg b/unittests/test_files/E_0015_kroki_response.dot.svg
index 8dd40e6..a15aab4 100644
--- a/unittests/test_files/E_0015_kroki_response.dot.svg
+++ b/unittests/test_files/E_0015_kroki_response.dot.svg
@@ -1,4 +1,4 @@
-
+
+}'-->
D
-7.17 AD: Aktivierung eines MaBiS-ZP für Bilanzierungsgebietssummenzeitreihen vom ÜNB an BIKO und NB
-7.17.1 E_0015_MaBiS-ZP Aktivierung prüfen
+7.17 AD: Aktivierung eines MaBiS-ZP für Bilanzierungsgebietssummenzeitreihen vom ÜNB an BIKO und NB
+7.17.1 E_0015_MaBiS-ZP Aktivierung prüfen
Start
-
-E_0015
-Prüfende Rolle:
- BIKO
+
+E_0015
+Prüfende Rolle:
+ BIKO
1
-
-1:
-Erfolgt die Aktivierung nach Ablauf der Clearingfrist für die KBKA?
+
+1:
+Erfolgt die Aktivierung nach Ablauf der Clearingfrist für die KBKA?
Start->1
-
-
+
+
A01
-
-A01
-Hinweis:
-Cluster Ablehnung
-Fristüberschreitung
+
+A01
+Hinweis:
+Cluster Ablehnung
+Fristüberschreitung
1->A01
-
-
-Ja
+
+
+Ja
2
-
-2:
-Erfolgt die Aktivierung zum Monatsersten 00:00 Uhr?
+
+2:
+Erfolgt die Aktivierung zum Monatsersten 00:00 Uhr?
1->2
-
-
-Nein
+
+
+Nein
A02
-
-A02
-Hinweis:
-Cluster Ablehnung
-Gewählter Zeitpunkt nicht zulässig
+
+A02
+Hinweis:
+Cluster Ablehnung
+Gewählter Zeitpunkt nicht zulässig
2->A02
-
-
-Nein
+
+
+Nein
3
-
-3:
-Ist die richtige Regelzone angegeben
+
+3:
+Ist die richtige Regelzone angegeben
2->3
-
-
-Ja
+
+
+Ja
A03
-
-A03
-Hinweis:
-Cluster Ablehnung
-Regelzone falsch
+
+A03
+Hinweis:
+Cluster Ablehnung
+Regelzone falsch
3->A03
-
-
-Nein
+
+
+Nein
4
-
-4:
-Ist das Bilanzierungsgebiet zum Aktivierungsbeginn in der Regelzone des BIKO gültig?
+
+4:
+Ist das Bilanzierungsgebiet zum Aktivierungsbeginn in der Regelzone des BIKO gültig?
3->4
-
-
-Ja
+
+
+Ja
A04
-
-A04
-Hinweis:
-Cluster Ablehnung
-Bilanzierungsgebiet nicht gültig
+
+A04
+Hinweis:
+Cluster Ablehnung
+Bilanzierungsgebiet nicht gültig
4->A04
-
-
-Nein
+
+
+Nein
5
-
-5:
-Ist der ÜNB zum Aktivierungsbeginn für das Bilanzierungsgebiet zuständig?
+
+5:
+Ist der ÜNB zum Aktivierungsbeginn für das Bilanzierungsgebiet zuständig?
4->5
-
-
-Ja
+
+
+Ja
A05
-
-A05
-Hinweis:
-Cluster Ablehnung
-Keine Berechtigung
+
+A05
+Hinweis:
+Cluster Ablehnung
+Keine Berechtigung
5->A05
-
-
-Nein
+
+
+Nein
6
-
-6:
-Existiert bereits ein abweichendes Tupel unter der ID des MaBiS-ZP?
+
+6:
+Existiert bereits ein abweichendes Tupel unter der ID des MaBiS-ZP?
5->6
-
-
-Ja
+
+
+Ja
A06
-
-A06
-Hinweis:
-Cluster Ablehnung
-Abweichender MaBiS-ZP bereits vorhanden
+
+A06
+Hinweis:
+Cluster Ablehnung
+Abweichender MaBiS-ZP bereits vorhanden
6->A06
-
-
-Ja
+
+
+Ja
7
-
-7:
-Existiert bereits für das genannte Tupel aus Aggregations-verantwortlicher, Bilanzierungsgebiet, Spannungsebene und ZRT eine abweichende ID des MaBiS-ZP?
+
+7:
+Existiert bereits für das genannte Tupel aus Aggregations-verantwortlicher,
+Bilanzierungsgebiet, Spannungsebene und ZRT eine abweichende ID des MaBiS-ZP?
6->7
-
-
-Nein
+
+
+Nein
A07
-
-A07
-Hinweis:
-Cluster Ablehnung
-Abweichende ID zum MaBiS-ZP bereits vorhanden
+
+A07
+Hinweis:
+Cluster Ablehnung
+Abweichende ID zum MaBiS-ZP bereits vorhanden
7->A07
-
-
-Ja
+
+
+Ja
8
-
-8:
-Ist der ÜNB zur Aktivierung des ZRT berechtigt?
+
+8:
+Ist der ÜNB zur Aktivierung des ZRT berechtigt?
7->8
-
-
-Nein
+
+
+Nein
A08
-
-A08
-Hinweis:
-Cluster Ablehnung
-ZRT Aktivierung nicht berechtigt
+
+A08
+Hinweis:
+Cluster Ablehnung
+ZRT Aktivierung nicht berechtigt
8->A08
-
-
-Nein
+
+
+Nein
9
-
-9:
-Passt die OBIS-Kennzahl zum ZRT?
+
+9:
+Passt die OBIS-Kennzahl zum ZRT?
8->9
-
-
-Ja
+
+
+Ja
A09
-
-A09
-Hinweis:
-Cluster Ablehnung
-OBIS nicht passend
+
+A09
+Hinweis:
+Cluster Ablehnung
+OBIS nicht passend
9->A09
-
-
-Nein
+
+
+Nein
10
-
-10:
-Ist der MaBiS-ZP zum Zeitpunkt der Aktivierung bereits aktiviert?
+
+10:
+Ist der MaBiS-ZP zum Zeitpunkt der Aktivierung bereits aktiviert?
9->10
-
-
-Ja
+
+
+Ja
A10
-
-A10
-Hinweis:
-Cluster Ablehnung
-MaBiS-ZP bereits aktiviert
+
+A10
+Hinweis:
+Cluster Ablehnung
+MaBiS-ZP bereits aktiviert
10->A10
-
-
-Ja
+
+
+Ja
A11
-
-A11
-Hinweis:
-Cluster: Zustimmung
-Aktivierung durchgeführt
+
+A11
+Hinweis:
+Cluster: Zustimmung
+Aktivierung durchgeführt
10->A11
-
-
-Nein
+
+
+Nein
\ No newline at end of file
diff --git a/unittests/test_utils.py b/unittests/test_utils.py
new file mode 100644
index 0000000..220110d
--- /dev/null
+++ b/unittests/test_utils.py
@@ -0,0 +1,49 @@
+# pylint:disable=line-too-long
+"""
+tests the utility functions
+"""
+
+import pytest
+
+from rebdhuhn.utils import add_line_breaks
+
+
+@pytest.mark.parametrize(
+ "original, length, line_break_char, expected",
+ [
+ pytest.param("text shorter than 80 chars", 80, "\n", "text shorter than 80 chars"),
+ pytest.param(
+ "Die Köchin der Frau Grubach, seiner Zimmervermieterin, die ihm jeden Tag gegen acht Uhr früh das Frühstück brachte, kam diesmal nicht.",
+ 80,
+ "\n",
+ "Die Köchin der Frau Grubach, seiner Zimmervermieterin, die ihm jeden Tag gegen\nacht Uhr früh das Frühstück brachte, kam diesmal nicht.",
+ ),
+ pytest.param(
+ "Er war schlank und doch fest gebaut, er trug ein anliegendes schwarzes Kleid, das, ähnlich den Reiseanzügen, mit verschiedenen Falten, Taschen, Schnallen, Knöpfen und einem Gürtel versehen war und infolgedessen, ohne daß man sich darüber klar wurde, wozu es dienen sollte, besonders praktisch erschien. »Wer sind Sie?« fragte K. und saß gleich halb aufrecht im Bett. Der Mann aber ging über die Frage hinweg, als müsse man seine Erscheinung hinnehmen, und sagte bloß seinerseits: »Sie haben geläutet?« »Anna soll mir das Frühstück bringen«, sagte K. und versuchte, zunächst stillschweigend, durch Aufmerksamkeit und Überlegung festzustellen, wer der Mann eigentlich war. Aber dieser setzte sich nicht allzulange seinen Blicken aus, sondern wandte sich zur Tür, die er ein wenig öffnete, um jemandem, der offenbar knapp hinter der Tür stand, zu sagen: »Er will, daß Anna ihm das Frühstück bringt.«",
+ 80,
+ " ",
+ "Er war schlank und doch fest gebaut, er trug ein anliegendes schwarzes Kleid, das, ähnlich den Reiseanzügen, mit verschiedenen Falten, Taschen, Schnallen, Knöpfen und einem Gürtel versehen war und infolgedessen, ohne daß man sich darüber klar wurde, wozu es dienen sollte, besonders praktisch erschien. »Wer sind Sie?« fragte K. und saß gleich halb aufrecht im Bett. Der Mann aber ging über die Frage hinweg, als müsse man seine Erscheinung hinnehmen, und sagte bloß seinerseits: »Sie haben geläutet?« »Anna soll mir das Frühstück bringen«, sagte K. und versuchte, zunächst stillschweigend, durch Aufmerksamkeit und Überlegung festzustellen, wer der Mann eigentlich war. Aber dieser setzte sich nicht allzulange seinen Blicken aus, sondern wandte sich zur Tür, die er ein wenig öffnete, um jemandem, der offenbar knapp hinter der Tür stand, zu sagen: »Er will, daß Anna ihm das Frühstück bringt.«",
+ ),
+ pytest.param(
+ "Der Mann aber ging über die Frage hinweg, als müsse man seine Erscheinung hinnehmen, und sagte bloß seinerseits:\n »Sie haben geläutet?« »Anna soll mir das Frühstück bringen«, sagte K. und versuchte, zunächst stillschweigend, durch Aufmerksamkeit und Überlegung festzustellen, wer der Mann eigentlich war.",
+ 80,
+ " ",
+ "Der Mann aber ging über die Frage hinweg, als müsse man seine Erscheinung hinnehmen, und sagte bloß seinerseits: »Sie haben geläutet?« »Anna soll mir das Frühstück bringen«, sagte K. und versuchte, zunächst stillschweigend, durch Aufmerksamkeit und Überlegung festzustellen, wer der Mann eigentlich war.",
+ ),
+ pytest.param(
+ 'Folgendes:\n * Wenn ein "früher" line break kommt, dann soll der bevorzugt werden.\n Außerdem wollen wir nach wie vor, dass ansonsten immer das späte Leerzeichen gewinnt, denn sonst wäre das blöd und ich muss hier noch ein paar Zeichen füllen.',
+ 80,
+ " ",
+ 'Folgendes: * Wenn ein "früher" line break kommt, dann soll der bevorzugt werden. Außerdem wollen wir nach wie vor, dass ansonsten immer das späte Leerzeichen gewinnt, denn sonst wäre das blöd und ich muss hier noch ein paar Zeichen füllen.',
+ ),
+ pytest.param(
+ "In jedem Fall wollen wir vermeiden, neue Hurenkinder einzuführen, denn die wären blöd",
+ 80,
+ " ",
+ "In jedem Fall wollen wir vermeiden, neue Hurenkinder einzuführen, denn die wären blöd", # no before "blöd"
+ ),
+ ],
+)
+def test_add_line_breaks(original: str, length: int, line_break_char: str, expected: str) -> None:
+ actual = add_line_breaks(original, max_line_length=length, line_sep=line_break_char)
+ assert actual == expected