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()