1 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
5 from copy import deepcopy
8 from librarian import WLNS
13 Converts / verse endings into verse elements in a stanza.
15 Slashes may only occur directly in the stanza. Any slashes in subelements
16 will be ignored, and the subelements will be put inside verse elements.
18 >>> s = etree.fromstring(
19 ... "<strofa>a <b>c</b> <b>c</b>/\\nb<x>x/\\ny</x>c/ \\nd</strofa>"
21 >>> Stanza(s).versify()
22 >>> print(etree.tostring(s, encoding='unicode', pretty_print=True).strip())
24 <wers_normalny>a <b>c</b><b>c</b></wers_normalny>
26 y</x>c</wers_normalny>
27 <wers_normalny>d</wers_normalny>
31 def __init__(self, stanza_elem):
32 self.stanza = stanza_elem
34 self.open_verse = None
37 self.push_text(self.stanza.text)
38 for elem in self.stanza:
40 self.push_text(elem.tail)
41 tail = self.stanza.tail
43 self.stanza.tail = tail
45 verse for verse in self.verses
46 if verse.text or len(verse) > 0
49 def open_normal_verse(self):
50 self.open_verse = self.stanza.makeelement("wers_normalny")
51 self.verses.append(self.open_verse)
53 def get_open_verse(self):
54 if self.open_verse is None:
55 self.open_normal_verse()
56 return self.open_verse
58 def push_text(self, text):
61 for i, verse_text in enumerate(re.split(r"/\s*\n", text)):
63 self.open_normal_verse()
64 if not verse_text.strip():
66 verse = self.get_open_verse()
68 verse[-1].tail = (verse[-1].tail or "") + verse_text
70 verse.text = (verse.text or "") + verse_text
72 def push_elem(self, elem):
73 if elem.tag.startswith("wers"):
74 verse = deepcopy(elem)
76 self.verses.append(verse)
77 self.open_verse = verse
79 appended = deepcopy(elem)
81 self.get_open_verse().append(appended)
84 def replace_by_verse(tree):
85 """ Find stanzas and create new verses in place of a '/' character """
87 stanzas = tree.findall('.//' + WLNS('strofa'))
88 for stanza in stanzas:
89 Stanza(stanza).versify()