7ce3f3a8de8b6faa3c25a718768b2325a8d49611
[librarian.git] / src / librarian / elements / poetry / strofa.py
1 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
3 #
4 from copy import copy
5 import re
6 from ..base import WLElement
7 from .wers import Wers
8
9
10 class Strofa(WLElement):
11     SHOULD_HAVE_ID = True
12
13     TXT_TOP_MARGIN = 2
14     TXT_BOTTOM_MARGIN = 2
15     TXT_LEGACY_TOP_MARGIN = 1
16     TXT_LEGACY_BOTTOM_MARGIN = 0
17
18     EPUB_TAG = HTML_TAG = 'div'
19     EPUB_CLASS = HTML_CLASS = 'stanza'
20
21     def epub_build(self, builder):
22         super().epub_build(builder)
23         builder.start_element(
24             'div',
25             {
26                 'class': 'stanza-spacer'
27             }
28         )
29         builder.push_text('\u00a0');
30         builder.end_element()
31     
32     def get_verses(self):
33         from librarian.parser import parser
34
35         verses = [
36             parser.makeelement('wers')
37         ]
38         if self.text:
39             # Before any tags. These are text-only verses.
40             pieces = re.split(r"/\s+", self.text)
41             for piece in pieces[:-1]:
42                 verses[-1].text = piece
43                 verses.append(parser.makeelement('wers'))
44             verses[-1].text = pieces[-1]
45
46         for child in self:
47             if child.tail:
48                 pieces = re.split(r"/\s+", child.tail)
49                 child_copy = copy(child)
50                 child_copy.tail = pieces[0]
51                 verses[-1].append(child_copy)
52
53                 for piece in pieces[1:]:
54                     verses.append(parser.makeelement('wers'))
55                     verses[-1].text = piece
56                 
57             else:
58                 verses[-1].append(child)
59
60         for verse in verses:
61             verse.stanza = self
62             if len(verse) == 1 and isinstance(verse[0], Wers):
63                 assert not (verse.text or '').strip()
64                 assert not (verse[0].tail or '').strip()
65                 yield verse[0]
66             else:
67                 yield verse
68
69     def _build_inner(self, builder, build_method):
70         for child in self.get_verses():
71             getattr(child, build_method)(builder)