From 82c0860d1520489be56457829d49eb17f165b9cd Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 16 Oct 2024 15:56:57 +0200 Subject: [PATCH 1/1] Some prelim work on builder api. --- src/librarian/builders/epub.py | 1 + src/librarian/builders/html.py | 75 ++++++++++--------- src/librarian/builders/txt.py | 1 + src/librarian/elements/base.py | 21 +++--- src/librarian/elements/drama/lista_osob.py | 8 +- .../elements/headers/podtytul_czesc.py | 4 +- .../elements/headers/podtytul_podrozdzial.py | 4 +- .../elements/headers/podtytul_rozdzial.py | 4 +- src/librarian/elements/poetry/wers.py | 8 +- src/librarian/elements/poetry/wers_cd.py | 4 +- src/librarian/elements/poetry/wers_wciety.py | 8 +- .../elements/separators/sekcja_asterysk.py | 6 +- .../elements/separators/sekcja_swiatlo.py | 2 +- .../elements/separators/separator_linia.py | 2 +- 14 files changed, 77 insertions(+), 71 deletions(-) diff --git a/src/librarian/builders/epub.py b/src/librarian/builders/epub.py index e009d4a..3ef95f4 100644 --- a/src/librarian/builders/epub.py +++ b/src/librarian/builders/epub.py @@ -77,6 +77,7 @@ class Builder: class EpubBuilder(Builder): + build_method_fn = 'epub_build' file_extension = 'epub' isbn_field = 'isbn_epub' orphans = True diff --git a/src/librarian/builders/html.py b/src/librarian/builders/html.py index 0b063c6..66db675 100644 --- a/src/librarian/builders/html.py +++ b/src/librarian/builders/html.py @@ -9,7 +9,45 @@ from librarian.html import add_table_of_contents, add_table_of_themes, add_image from librarian import OutputFile -class HtmlBuilder: +class TreeBuilder: + @property + def cursor(self): + return self.current_cursors[-1] + + def enter_fragment(self, fragment): + cursor = self.cursors.get(fragment, self.cursor) + self.current_cursors.append(cursor) + + def exit_fragment(self): + self.current_cursors.pop() + + def create_fragment(self, name, element): + assert name not in self.cursors + self.cursors[name] = element + + def forget_fragment(self, name): + del self.cursors[name] + + def start_element(self, tag, attrib=None): + self.current_cursors.append(etree.SubElement( + self.cursor, + tag, + **(attrib or {}) + )) + + def end_element(self): + self.current_cursors.pop() + + def push_text(self, text): + cursor = self.cursor + if len(cursor): + cursor[-1].tail = (cursor[-1].tail or '') + text + else: + cursor.text = (cursor.text or '') + text + + +class HtmlBuilder(TreeBuilder): + build_method_fn = 'html_build' file_extension = "html" with_themes = True with_toc = True @@ -50,24 +88,6 @@ class HtmlBuilder: else: return 'https://wolnelektury.pl/media/book/pictures/{}/'.format(self.document.meta.url.slug) - @property - def cursor(self): - return self.current_cursors[-1] - - def enter_fragment(self, fragment): - cursor = self.cursors.get(fragment, self.cursor) - self.current_cursors.append(cursor) - - def exit_fragment(self): - self.current_cursors.pop() - - def create_fragment(self, name, element): - assert name not in self.cursors - self.cursors[name] = element - - def forget_fragment(self, name): - del self.cursors[name] - def build(self, document, element=None, **kwargs): self.document = document self.document.assign_ids() @@ -133,23 +153,6 @@ class HtmlBuilder: self.footnotes.insert(0, fnheader) self.tree.append(self.footnotes) - def start_element(self, tag, attrib=None): - self.current_cursors.append(etree.SubElement( - self.cursor, - tag, - **(attrib or {}) - )) - - def end_element(self): - self.current_cursors.pop() - - def push_text(self, text): - cursor = self.cursor - if len(cursor): - cursor[-1].tail = (cursor[-1].tail or '') + text - else: - cursor.text = (cursor.text or '') + text - def add_visible_number(self, element): assert '_id' in element.attrib, etree.tostring(element) self.start_element('a', { diff --git a/src/librarian/builders/txt.py b/src/librarian/builders/txt.py index 92ddb46..69ddbe2 100644 --- a/src/librarian/builders/txt.py +++ b/src/librarian/builders/txt.py @@ -37,6 +37,7 @@ class TxtFragment: class TxtBuilder: """ """ + build_method_fn = 'txt_build' file_extension = "txt" identifier = "txt" after_child_fn = 'txt_after_child' diff --git a/src/librarian/elements/base.py b/src/librarian/elements/base.py index 8f4acc5..1f22929 100644 --- a/src/librarian/elements/base.py +++ b/src/librarian/elements/base.py @@ -133,7 +133,8 @@ class WLElement(etree.ElementBase): return text - def _build_inner(self, builder, build_method): + def build_inner(self, builder): + build_method = builder.build_method_fn child_count = len(self) if self.CAN_HAVE_TEXT and self.text: text = self.normalize_text(self.text, builder) @@ -166,18 +167,18 @@ class WLElement(etree.ElementBase): def txt_after_child(self, builder, child_count): pass - def _txt_build_inner(self, builder): - self._build_inner(builder, 'txt_build') + def txt_build_inner(self, builder): + self.build_inner(builder) def txt_build(self, builder): builder.push_margin(self.TXT_TOP_MARGIN) builder.push_text(self.TXT_PREFIX, True) - self._txt_build_inner(builder) + self.txt_build_inner(builder) builder.push_text(self.TXT_SUFFIX, True) builder.push_margin(self.TXT_BOTTOM_MARGIN) - def _html_build_inner(self, builder): - self._build_inner(builder, 'html_build') + def html_build_inner(self, builder): + self.build_inner(builder) def get_html_attr(self, builder): attr = self.HTML_ATTR.copy() @@ -204,12 +205,12 @@ class WLElement(etree.ElementBase): self.get_html_attr(builder), ) - self._html_build_inner(builder) + self.html_build_inner(builder) if self.HTML_TAG: builder.end_element() - def _epub_build_inner(self, builder): - self._build_inner(builder, 'epub_build') + def epub_build_inner(self, builder): + self.build_inner(builder) def get_epub_attr(self, builder): attr = self.EPUB_ATTR.copy() @@ -255,7 +256,7 @@ class WLElement(etree.ElementBase): attr ) - self._epub_build_inner(builder) + self.epub_build_inner(builder) if self.EPUB_TAG: builder.end_element() diff --git a/src/librarian/elements/drama/lista_osob.py b/src/librarian/elements/drama/lista_osob.py index d8ea32a..45b52c8 100644 --- a/src/librarian/elements/drama/lista_osob.py +++ b/src/librarian/elements/drama/lista_osob.py @@ -15,16 +15,16 @@ class ListaOsob(WLElement): HTML_TAG = "div" HTML_CLASS = "person-list" - def _html_build_inner(self, builder): + def html_build_inner(self, builder): ol = etree.Element('ol') builder.create_fragment('list', ol) - super(ListaOsob, self)._html_build_inner(builder) + super().html_build_inner(builder) builder.cursor.append(ol) builder.forget_fragment('list') - def _epub_build_inner(self, builder): + def epub_build_inner(self, builder): ol = etree.Element('ol') builder.create_fragment('list', ol) - super(ListaOsob, self)._epub_build_inner(builder) + super().epub_build_inner(builder) builder.cursor.append(ol) builder.forget_fragment('list') diff --git a/src/librarian/elements/headers/podtytul_czesc.py b/src/librarian/elements/headers/podtytul_czesc.py index 14c6536..4111ade 100644 --- a/src/librarian/elements/headers/podtytul_czesc.py +++ b/src/librarian/elements/headers/podtytul_czesc.py @@ -16,7 +16,7 @@ class PodtytulCzesc(WLElement): EPUB_TAG = "h2" EPUB_CLASS = "h2" - def _epub_build_inner(self, builder): + def epub_build_inner(self, builder): builder.start_element('small', {}) - super()._epub_build_inner(builder) + super().epub_build_inner(builder) builder.end_element() diff --git a/src/librarian/elements/headers/podtytul_podrozdzial.py b/src/librarian/elements/headers/podtytul_podrozdzial.py index 239891e..e9d0208 100644 --- a/src/librarian/elements/headers/podtytul_podrozdzial.py +++ b/src/librarian/elements/headers/podtytul_podrozdzial.py @@ -16,7 +16,7 @@ class PodtytulPodrozdzial(WLElement): EPUB_TAG = "h2" EPUB_CLASS = "h4" - def _epub_build_inner(self, builder): + def epub_build_inner(self, builder): builder.start_element('small', {}) - super()._epub_build_inner(builder) + super().epub_build_inner(builder) builder.end_element() diff --git a/src/librarian/elements/headers/podtytul_rozdzial.py b/src/librarian/elements/headers/podtytul_rozdzial.py index f24fba7..3959007 100644 --- a/src/librarian/elements/headers/podtytul_rozdzial.py +++ b/src/librarian/elements/headers/podtytul_rozdzial.py @@ -16,7 +16,7 @@ class PodtytulRozdzial(WLElement): EPUB_TAG = "h2" EPUB_CLASS = "h3" - def _epub_build_inner(self, builder): + def epub_build_inner(self, builder): builder.start_element('small', {}) - super()._epub_build_inner(builder) + super().epub_build_inner(builder) builder.end_element() diff --git a/src/librarian/elements/poetry/wers.py b/src/librarian/elements/poetry/wers.py index cf2089c..f0f274c 100644 --- a/src/librarian/elements/poetry/wers.py +++ b/src/librarian/elements/poetry/wers.py @@ -22,8 +22,8 @@ class Wers(WLElement): return self.stanza.meta return super(Wers, self).meta - def _epub_build_inner(self, builder): - super()._epub_build_inner(builder) + def epub_build_inner(self, builder): + super().epub_build_inner(builder) builder.push_text('''\u00a0''') @property @@ -44,9 +44,9 @@ class Wers(WLElement): attr['class'] += ' verse-stretched' return attr - def _html_build_inner(self, builder): + def html_build_inner(self, builder): if self.is_stretched: builder.start_element('span') - super()._html_build_inner(builder) + super().html_build_inner(builder) if self.is_stretched: builder.end_element() diff --git a/src/librarian/elements/poetry/wers_cd.py b/src/librarian/elements/poetry/wers_cd.py index 2350c30..28d779f 100644 --- a/src/librarian/elements/poetry/wers_cd.py +++ b/src/librarian/elements/poetry/wers_cd.py @@ -6,9 +6,9 @@ from .wers import Wers class WersCd(Wers): HTML_CLASS = Wers.HTML_CLASS + ' verse-cont' - def _txt_build_inner(self, builder): + def txt_build_inner(self, builder): builder.push_text(' ' * 24, prepared=True) - super(WersCd, self)._txt_build_inner(builder) + super().txt_build_inner(builder) EPUB_ATTR = { "style": "margin-left: 12em", diff --git a/src/librarian/elements/poetry/wers_wciety.py b/src/librarian/elements/poetry/wers_wciety.py index 4a2744a..cb5f25e 100644 --- a/src/librarian/elements/poetry/wers_wciety.py +++ b/src/librarian/elements/poetry/wers_wciety.py @@ -12,19 +12,19 @@ class WersWciety(Wers): v = self.attrib.get('typ') return int(v) if v else 1 - def _txt_build_inner(self, builder): + def txt_build_inner(self, builder): ## Temporary legacy compatibility fix. typ = min(self.typ, 2) builder.push_text(' ' * self.typ, prepared=True) - super(WersWciety, self)._txt_build_inner(builder) + super().txt_build_inner(builder) def get_html_attr(self, builder): - attr = super(WersWciety, self).get_html_attr(builder) + attr = super().get_html_attr(builder) attr['class'] += f" verse-indent-{self.typ}" return attr def get_epub_attr(self, builder): - attr = super(WersWciety, self).get_html_attr(builder) + attr = super().get_html_attr(builder) attr['style'] = "margin-left: {}em".format(self.typ) return attr diff --git a/src/librarian/elements/separators/sekcja_asterysk.py b/src/librarian/elements/separators/sekcja_asterysk.py index 3ba8270..8cc2019 100644 --- a/src/librarian/elements/separators/sekcja_asterysk.py +++ b/src/librarian/elements/separators/sekcja_asterysk.py @@ -11,11 +11,11 @@ class SekcjaAsterysk(WLElement): EPUB_TAG = HTML_TAG = "p" HTML_CLASS = HTML_CLASS = "spacer-asterisk" - def _txt_build_inner(self, builder): + def txt_build_inner(self, builder): builder.push_text('*') - def _html_build_inner(self, builder): + def html_build_inner(self, builder): builder.push_text("*") - _epub_build_inner = _html_build_inner + epub_build_inner = html_build_inner diff --git a/src/librarian/elements/separators/sekcja_swiatlo.py b/src/librarian/elements/separators/sekcja_swiatlo.py index e3ab103..f7ea4a3 100644 --- a/src/librarian/elements/separators/sekcja_swiatlo.py +++ b/src/librarian/elements/separators/sekcja_swiatlo.py @@ -13,5 +13,5 @@ class SekcjaSwiatlo(WLElement): EPUB_TAG = 'p' EPUB_CLASS = 'spacer' - def _epub_build_inner(self, builder): + def epub_build_inner(self, builder): builder.push_text("\u00a0") diff --git a/src/librarian/elements/separators/separator_linia.py b/src/librarian/elements/separators/separator_linia.py index e5a5218..ac01f5d 100644 --- a/src/librarian/elements/separators/separator_linia.py +++ b/src/librarian/elements/separators/separator_linia.py @@ -11,7 +11,7 @@ class SeparatorLinia(WLElement): EPUB_TAG = HTML_TAG = "hr" EPUB_CLASS = HTML_CLASS = "spacer-line" - def _txt_build_inner(self, builder): + def txt_build_inner(self, builder): builder.push_text('-' * 48) -- 2.20.1