From 4b0833f222da430d31356b6f065e56073b849d0f Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 10 Apr 2024 13:31:22 +0200 Subject: [PATCH 01/13] bugfix --- setup.py | 2 +- src/librarian/pdf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 1368375..a11c86e 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def whole_tree(prefix, path): setup( name='librarian', - version='24.4', + version='24.4.1', description='Converter from WolneLektury.pl XML-based language to XHTML, TXT and other formats', author="Marek Stępniowski", author_email='marek@stepniowski.com', diff --git a/src/librarian/pdf.py b/src/librarian/pdf.py index e5cf5bd..de09755 100644 --- a/src/librarian/pdf.py +++ b/src/librarian/pdf.py @@ -196,7 +196,7 @@ def add_fundraising(doc, fundraising): naglowek.addprevious(spot) spots.append(spot) spot = etree.Element('f_spot') - doc.getroot()[-1][-1].append(spot) + doc.getroot()[-1].append(spot) spots.append(spot) e = len(spots) nfunds = len(fundraising) -- 2.20.1 From 9c9a55d7dda5595a236f11977d7f21f804d37872 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 22 May 2024 11:44:56 +0200 Subject: [PATCH 02/13] Fix for comments. --- src/librarian/document.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librarian/document.py b/src/librarian/document.py index 2e9a4a5..7780b61 100644 --- a/src/librarian/document.py +++ b/src/librarian/document.py @@ -81,6 +81,7 @@ class WLDocument: """ EXPR = re.compile(r'/\s', re.MULTILINE | re.UNICODE) def _compat_assign_ordered_ids_in_elem(elem, i): + if isinstance(elem, etree._Comment): return i elem.attrib['_compat_ordered_id'] = str(i) i += 1 if getattr(elem, 'HTML_CLASS', None) == 'stanza': -- 2.20.1 From 88f39c4f90a67164b2c3da7c7a41df420f3b17ab Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 22 May 2024 11:47:40 +0200 Subject: [PATCH 03/13] Limit image size, fixes #4464. --- CHANGELOG.md | 5 +++++ setup.py | 2 +- src/librarian/elements/figures/ilustr.py | 18 +++++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 171bb9b..13a3341 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ This document records all notable changes to Librarian. +## 24.5 + +- Smaller images in EPUB (600px width instead of 1200px). +- Convert PNG to JPEGs if too large in EPUBs. + ## 24.4 - Add fundraising inserts in PDF. diff --git a/setup.py b/setup.py index a11c86e..494b3f2 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def whole_tree(prefix, path): setup( name='librarian', - version='24.4.1', + version='24.5', description='Converter from WolneLektury.pl XML-based language to XHTML, TXT and other formats', author="Marek Stępniowski", author_email='marek@stepniowski.com', diff --git a/src/librarian/elements/figures/ilustr.py b/src/librarian/elements/figures/ilustr.py index 33099f6..4e848ac 100644 --- a/src/librarian/elements/figures/ilustr.py +++ b/src/librarian/elements/figures/ilustr.py @@ -8,6 +8,9 @@ from PIL import Image from ..base import WLElement +MAX_PNG_WEIGHT = 200000 + + class Ilustr(WLElement): SHOULD_HAVE_ID = True @@ -28,7 +31,7 @@ class Ilustr(WLElement): 'PNG': ('PNG', 'png', 'image/png'), }.get(img.format, ('JPEG', 'jpg', 'image/jpeg')) - width = 1200 + width = 600 if img.size[0] < width: th = img else: @@ -36,6 +39,19 @@ class Ilustr(WLElement): buffer = io.BytesIO() th.save(buffer, format=th_format) + + # Limit PNG to 200K. If larger, convert to JPEG. + if th_format == 'PNG' and buffer.tell() > MAX_PNG_WEIGHT: + th_format, ext, media_type = 'JPEG', 'jpg', 'image/jpeg' + if th.mode != 'RGB': + buffer = io.BytesIO() + th = Image.alpha_composite( + Image.new('RGBA', th.size, '#fff'), + th.convert('RGBA') + ) + th = th.convert('RGB') + th.save(buffer, format=th_format) + imgfile.close() file_name = 'image%d.%s' % ( builder.assign_image_number(), -- 2.20.1 From 011b98a4661b754a0789ae78e145437b5b86e5fe Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 11 Sep 2024 15:56:58 +0200 Subject: [PATCH 04/13] Move HTML from the old transform sheet. --- scripts/book2html | 33 - setup.py | 1 - src/librarian/builders/daisy.py | 70 +- src/librarian/builders/html.py | 91 ++- src/librarian/covers/marquise.py | 1 + src/librarian/dcparser.py | 105 ++- src/librarian/document.py | 78 +- src/librarian/elements/base.py | 69 +- src/librarian/elements/blocks/dedykacja.py | 2 +- src/librarian/elements/blocks/nota.py | 2 + src/librarian/elements/comments/abstrakt.py | 4 +- src/librarian/elements/drama/didaskalia.py | 4 +- src/librarian/elements/drama/lista_osob.py | 2 +- src/librarian/elements/drama/lista_osoba.py | 3 + src/librarian/elements/drama/miejsce_czas.py | 7 +- .../elements/drama/naglowek_listy.py | 3 +- .../elements/drama/naglowek_osoba.py | 2 +- src/librarian/elements/figures/animacja.py | 2 +- src/librarian/elements/figures/ilustr.py | 29 +- src/librarian/elements/figures/tabela.py | 2 +- src/librarian/elements/footnotes/__init__.py | 9 +- src/librarian/elements/front/autor_utworu.py | 2 +- src/librarian/elements/front/base.py | 2 +- .../elements/front/dzielo_nadrzedne.py | 2 +- src/librarian/elements/front/motto.py | 2 +- src/librarian/elements/front/motto_podpis.py | 7 +- src/librarian/elements/front/nazwa_utworu.py | 2 +- src/librarian/elements/front/podtytul.py | 2 +- .../elements/headers/naglowek_czesc.py | 3 +- .../elements/headers/naglowek_podrozdzial.py | 2 +- .../elements/headers/naglowek_rozdzial.py | 3 +- .../elements/headers/naglowek_scena.py | 2 +- .../elements/headers/podtytul_czesc.py | 2 +- .../elements/headers/podtytul_podrozdzial.py | 2 +- .../elements/headers/podtytul_rozdzial.py | 2 +- src/librarian/elements/paragraphs/akap.py | 8 +- src/librarian/elements/poetry/strofa.py | 28 +- src/librarian/elements/poetry/wers.py | 29 +- src/librarian/elements/poetry/wers_akap.py | 4 +- src/librarian/elements/poetry/wers_cd.py | 6 +- .../elements/poetry/wers_do_prawej.py | 4 +- src/librarian/elements/poetry/wers_srodek.py | 4 +- src/librarian/elements/poetry/wers_wciety.py | 4 +- src/librarian/elements/styles/www.py | 7 +- src/librarian/elements/tools/__init__.py | 44 +- src/librarian/html.py | 177 +---- .../locale/pl/LC_MESSAGES/messages.po | 12 +- src/librarian/picture.py | 238 ------ src/librarian/xslt/book2html.xslt | 677 ------------------ tests/files/picture/angelus-novus.jpeg | Bin 23365 -> 0 bytes tests/files/picture/angelus-novus.xml | 42 -- tests/files/tags/akap/1.expected.html | 7 + tests/files/tags/akap/1.xml | 6 + tests/files/tags/akap_cd/1.expected.html | 3 + tests/files/tags/akap_cd/1.xml | 1 + tests/files/tags/akap_dialog/1.expected.html | 9 + tests/files/tags/akap_dialog/1.xml | 12 + tests/files/tags/animacja/1.expected.html | 4 + tests/files/tags/animacja/1.xml | 4 + tests/files/tags/autor_utworu/1.expected.html | 1 + tests/files/tags/autor_utworu/1.xml | 1 + tests/files/tags/base.xml | 7 + tests/files/tags/dedykacja/1.expected.html | 11 + tests/files/tags/dedykacja/1.xml | 10 + tests/files/tags/didask_tekst/1.expected.html | 7 + tests/files/tags/didask_tekst/1.xml | 5 + tests/files/tags/didaskalia/1.expected.html | 27 + tests/files/tags/didaskalia/1.xml | 34 + tests/files/tags/dlugi_cytat/1.expected.html | 3 + tests/files/tags/dlugi_cytat/1.xml | 1 + .../tags/dzielo_nadrzedne/1.expected.html | 3 + tests/files/tags/dzielo_nadrzedne/1.xml | 3 + tests/files/tags/ilustr/1.expected.html | 1 + tests/files/tags/ilustr/1.xml | 1 + tests/files/tags/indeks_dolny/1.expected.html | 3 + tests/files/tags/indeks_dolny/1.xml | 3 + tests/files/tags/kwestia/1.expected.html | 15 + tests/files/tags/kwestia/1.xml | 16 + tests/files/tags/kwestia/2.expected.html | 11 + tests/files/tags/kwestia/2.xml | 16 + tests/files/tags/lista_osob/1.expected.html | 21 + tests/files/tags/lista_osob/1.xml | 21 + tests/files/tags/mat/1.expected.html | 42 ++ tests/files/tags/mat/1.xml | 41 ++ tests/files/tags/motto/1.expected.html | 11 + tests/files/tags/motto/1.xml | 10 + tests/files/tags/motto_podpis/1.expected.html | 13 + tests/files/tags/motto_podpis/1.xml | 14 + tests/files/tags/naglowek_akt/1.expected.html | 12 + tests/files/tags/naglowek_akt/1.xml | 4 + .../files/tags/naglowek_czesc/1.expected.html | 22 + tests/files/tags/naglowek_czesc/1.xml | 15 + .../files/tags/naglowek_osoba/1.expected.html | 13 + tests/files/tags/naglowek_osoba/1.xml | 12 + .../tags/naglowek_podrozdzial/1.expected.html | 1 + tests/files/tags/naglowek_podrozdzial/1.xml | 1 + .../tags/naglowek_rozdzial/1.expected.html | 12 + tests/files/tags/naglowek_rozdzial/1.xml | 6 + tests/files/tags/nazwa_utworu/1.expected.html | 1 + tests/files/tags/nazwa_utworu/1.xml | 1 + tests/files/tags/nota/1.expected.html | 7 + tests/files/tags/nota/1.xml | 5 + tests/files/tags/nota/2.expected.html | 18 + tests/files/tags/nota/2.xml | 14 + tests/files/tags/nota/3.expected.html | 8 + tests/files/tags/nota/3.xml | 9 + tests/files/tags/nota/4.expected.html | 12 + tests/files/tags/nota/4.xml | 7 + tests/files/tags/nota/5.expected.html | 5 + tests/files/tags/nota/5.xml | 4 + tests/files/tags/nota/6.expected.html | 8 + tests/files/tags/nota/6.xml | 9 + tests/files/tags/numeracja/1.expected.html | 30 + tests/files/tags/numeracja/1.xml | 32 + tests/files/tags/osoba/1.expected.html | 23 + tests/files/tags/osoba/1.xml | 16 + tests/files/tags/pa/1.expected.html | 9 + tests/files/tags/pa/1.xml | 3 + tests/files/tags/pe/1.expected.html | 9 + tests/files/tags/pe/1.xml | 3 + tests/files/tags/pe/2.expected.html | 12 + tests/files/tags/pe/2.xml | 6 + tests/files/tags/podtytul/1.expected.html | 3 + tests/files/tags/podtytul/1.xml | 4 + tests/files/tags/poezja_cyt/1.expected.html | 4 + tests/files/tags/poezja_cyt/1.xml | 6 + tests/files/tags/pr/1.expected.html | 9 + tests/files/tags/pr/1.xml | 3 + tests/files/tags/pt/1.expected.html | 9 + tests/files/tags/pt/1.xml | 3 + tests/files/tags/ref/1.expected.html | 3 + tests/files/tags/ref/1.xml | 1 + tests/files/tags/rownolegle/1.expected.html | 13 + tests/files/tags/rownolegle/1.xml | 16 + .../tags/sekcja_asterysk/1.expected.html | 5 + tests/files/tags/sekcja_asterysk/1.xml | 5 + .../files/tags/sekcja_swiatlo/1.expected.html | 5 + tests/files/tags/sekcja_swiatlo/1.xml | 5 + .../tags/separator_linia/1.expected.html | 5 + tests/files/tags/separator_linia/1.xml | 5 + tests/files/tags/slowo_obce/1.expected.html | 3 + tests/files/tags/slowo_obce/1.xml | 3 + tests/files/tags/srodtytul/1.expected.html | 9 + tests/files/tags/srodtytul/1.xml | 1 + tests/files/tags/strofa/1.expected.html | 13 + tests/files/tags/strofa/1.xml | 10 + tests/files/tags/tab/1.expected.html | 21 + tests/files/tags/tab/1.xml | 17 + tests/files/tags/tabela/1.expected.html | 22 + tests/files/tags/tabela/1.xml | 21 + tests/files/tags/tytul_dziela/1.expected.html | 8 + tests/files/tags/tytul_dziela/1.xml | 9 + tests/files/tags/tytul_dziela/2.expected.html | 3 + tests/files/tags/tytul_dziela/2.xml | 3 + tests/files/tags/wers_cd/1.expected.html | 17 + tests/files/tags/wers_cd/1.xml | 23 + .../files/tags/wers_do_prawej/1.expected.html | 8 + tests/files/tags/wers_do_prawej/1.xml | 7 + tests/files/tags/wers_wciety/1.expected.html | 13 + tests/files/tags/wers_wciety/1.xml | 13 + tests/files/tags/wers_wciety/2.expected.html | 8 + tests/files/tags/wers_wciety/2.xml | 10 + .../tags/wieksze_odstepy/1.expected.html | 3 + tests/files/tags/wieksze_odstepy/1.xml | 3 + tests/files/tags/www/1.expected.html | 4 + tests/files/tags/www/1.xml | 4 + tests/files/tags/wyroznienie/1.expected.html | 9 + tests/files/tags/wyroznienie/1.xml | 9 + tests/files/tags/wywiad_pyt/1.expected.html | 4 + tests/files/tags/wywiad_pyt/1.xml | 3 + .../tags/zastepnik_wersu/1.expected.html | 8 + tests/files/tags/zastepnik_wersu/1.xml | 10 + tests/files/text/abstrakt.expected.html | 3 + tests/files/text/abstrakt.xml | 9 +- .../text/asnyk_miedzy_nami_expected.html | 48 +- .../asnyk_miedzy_nami_expected.legacy.html | 47 -- .../text/asnyk_miedzy_nami_fragments.html | 62 +- tests/files/text/asnyk_miedzy_nami_refs.html | 10 +- tests/test_html.py | 35 +- tests/test_html_annotations.py | 20 +- tests/test_html_examples.py | 49 ++ tests/test_html_fragments.py | 2 +- tests/test_html_transform_abstrakt.py | 19 +- tests/test_picture.py | 56 -- tests/test_ref.py | 6 +- tox.ini | 6 +- 186 files changed, 1685 insertions(+), 1675 deletions(-) delete mode 100755 scripts/book2html delete mode 100644 src/librarian/picture.py delete mode 100644 src/librarian/xslt/book2html.xslt delete mode 100644 tests/files/picture/angelus-novus.jpeg delete mode 100644 tests/files/picture/angelus-novus.xml create mode 100644 tests/files/tags/akap/1.expected.html create mode 100644 tests/files/tags/akap/1.xml create mode 100644 tests/files/tags/akap_cd/1.expected.html create mode 100644 tests/files/tags/akap_cd/1.xml create mode 100644 tests/files/tags/akap_dialog/1.expected.html create mode 100644 tests/files/tags/akap_dialog/1.xml create mode 100644 tests/files/tags/animacja/1.expected.html create mode 100644 tests/files/tags/animacja/1.xml create mode 100644 tests/files/tags/autor_utworu/1.expected.html create mode 100644 tests/files/tags/autor_utworu/1.xml create mode 100644 tests/files/tags/base.xml create mode 100644 tests/files/tags/dedykacja/1.expected.html create mode 100644 tests/files/tags/dedykacja/1.xml create mode 100644 tests/files/tags/didask_tekst/1.expected.html create mode 100644 tests/files/tags/didask_tekst/1.xml create mode 100644 tests/files/tags/didaskalia/1.expected.html create mode 100644 tests/files/tags/didaskalia/1.xml create mode 100644 tests/files/tags/dlugi_cytat/1.expected.html create mode 100644 tests/files/tags/dlugi_cytat/1.xml create mode 100644 tests/files/tags/dzielo_nadrzedne/1.expected.html create mode 100644 tests/files/tags/dzielo_nadrzedne/1.xml create mode 100644 tests/files/tags/ilustr/1.expected.html create mode 100644 tests/files/tags/ilustr/1.xml create mode 100644 tests/files/tags/indeks_dolny/1.expected.html create mode 100644 tests/files/tags/indeks_dolny/1.xml create mode 100644 tests/files/tags/kwestia/1.expected.html create mode 100644 tests/files/tags/kwestia/1.xml create mode 100644 tests/files/tags/kwestia/2.expected.html create mode 100644 tests/files/tags/kwestia/2.xml create mode 100644 tests/files/tags/lista_osob/1.expected.html create mode 100644 tests/files/tags/lista_osob/1.xml create mode 100644 tests/files/tags/mat/1.expected.html create mode 100644 tests/files/tags/mat/1.xml create mode 100644 tests/files/tags/motto/1.expected.html create mode 100644 tests/files/tags/motto/1.xml create mode 100644 tests/files/tags/motto_podpis/1.expected.html create mode 100644 tests/files/tags/motto_podpis/1.xml create mode 100644 tests/files/tags/naglowek_akt/1.expected.html create mode 100644 tests/files/tags/naglowek_akt/1.xml create mode 100644 tests/files/tags/naglowek_czesc/1.expected.html create mode 100644 tests/files/tags/naglowek_czesc/1.xml create mode 100644 tests/files/tags/naglowek_osoba/1.expected.html create mode 100644 tests/files/tags/naglowek_osoba/1.xml create mode 100644 tests/files/tags/naglowek_podrozdzial/1.expected.html create mode 100644 tests/files/tags/naglowek_podrozdzial/1.xml create mode 100644 tests/files/tags/naglowek_rozdzial/1.expected.html create mode 100644 tests/files/tags/naglowek_rozdzial/1.xml create mode 100644 tests/files/tags/nazwa_utworu/1.expected.html create mode 100644 tests/files/tags/nazwa_utworu/1.xml create mode 100644 tests/files/tags/nota/1.expected.html create mode 100644 tests/files/tags/nota/1.xml create mode 100644 tests/files/tags/nota/2.expected.html create mode 100644 tests/files/tags/nota/2.xml create mode 100644 tests/files/tags/nota/3.expected.html create mode 100644 tests/files/tags/nota/3.xml create mode 100644 tests/files/tags/nota/4.expected.html create mode 100644 tests/files/tags/nota/4.xml create mode 100644 tests/files/tags/nota/5.expected.html create mode 100644 tests/files/tags/nota/5.xml create mode 100644 tests/files/tags/nota/6.expected.html create mode 100644 tests/files/tags/nota/6.xml create mode 100644 tests/files/tags/numeracja/1.expected.html create mode 100644 tests/files/tags/numeracja/1.xml create mode 100644 tests/files/tags/osoba/1.expected.html create mode 100644 tests/files/tags/osoba/1.xml create mode 100644 tests/files/tags/pa/1.expected.html create mode 100644 tests/files/tags/pa/1.xml create mode 100644 tests/files/tags/pe/1.expected.html create mode 100644 tests/files/tags/pe/1.xml create mode 100644 tests/files/tags/pe/2.expected.html create mode 100644 tests/files/tags/pe/2.xml create mode 100644 tests/files/tags/podtytul/1.expected.html create mode 100644 tests/files/tags/podtytul/1.xml create mode 100644 tests/files/tags/poezja_cyt/1.expected.html create mode 100644 tests/files/tags/poezja_cyt/1.xml create mode 100644 tests/files/tags/pr/1.expected.html create mode 100644 tests/files/tags/pr/1.xml create mode 100644 tests/files/tags/pt/1.expected.html create mode 100644 tests/files/tags/pt/1.xml create mode 100644 tests/files/tags/ref/1.expected.html create mode 100644 tests/files/tags/ref/1.xml create mode 100644 tests/files/tags/rownolegle/1.expected.html create mode 100644 tests/files/tags/rownolegle/1.xml create mode 100644 tests/files/tags/sekcja_asterysk/1.expected.html create mode 100644 tests/files/tags/sekcja_asterysk/1.xml create mode 100644 tests/files/tags/sekcja_swiatlo/1.expected.html create mode 100644 tests/files/tags/sekcja_swiatlo/1.xml create mode 100644 tests/files/tags/separator_linia/1.expected.html create mode 100644 tests/files/tags/separator_linia/1.xml create mode 100644 tests/files/tags/slowo_obce/1.expected.html create mode 100644 tests/files/tags/slowo_obce/1.xml create mode 100644 tests/files/tags/srodtytul/1.expected.html create mode 100644 tests/files/tags/srodtytul/1.xml create mode 100644 tests/files/tags/strofa/1.expected.html create mode 100644 tests/files/tags/strofa/1.xml create mode 100644 tests/files/tags/tab/1.expected.html create mode 100644 tests/files/tags/tab/1.xml create mode 100644 tests/files/tags/tabela/1.expected.html create mode 100644 tests/files/tags/tabela/1.xml create mode 100644 tests/files/tags/tytul_dziela/1.expected.html create mode 100644 tests/files/tags/tytul_dziela/1.xml create mode 100644 tests/files/tags/tytul_dziela/2.expected.html create mode 100644 tests/files/tags/tytul_dziela/2.xml create mode 100644 tests/files/tags/wers_cd/1.expected.html create mode 100644 tests/files/tags/wers_cd/1.xml create mode 100644 tests/files/tags/wers_do_prawej/1.expected.html create mode 100644 tests/files/tags/wers_do_prawej/1.xml create mode 100644 tests/files/tags/wers_wciety/1.expected.html create mode 100644 tests/files/tags/wers_wciety/1.xml create mode 100644 tests/files/tags/wers_wciety/2.expected.html create mode 100644 tests/files/tags/wers_wciety/2.xml create mode 100644 tests/files/tags/wieksze_odstepy/1.expected.html create mode 100644 tests/files/tags/wieksze_odstepy/1.xml create mode 100644 tests/files/tags/www/1.expected.html create mode 100644 tests/files/tags/www/1.xml create mode 100644 tests/files/tags/wyroznienie/1.expected.html create mode 100644 tests/files/tags/wyroznienie/1.xml create mode 100644 tests/files/tags/wywiad_pyt/1.expected.html create mode 100644 tests/files/tags/wywiad_pyt/1.xml create mode 100644 tests/files/tags/zastepnik_wersu/1.expected.html create mode 100644 tests/files/tags/zastepnik_wersu/1.xml create mode 100644 tests/files/text/abstrakt.expected.html delete mode 100644 tests/files/text/asnyk_miedzy_nami_expected.legacy.html create mode 100644 tests/test_html_examples.py delete mode 100644 tests/test_picture.py diff --git a/scripts/book2html b/scripts/book2html deleted file mode 100755 index 8eadb04..0000000 --- a/scripts/book2html +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -# This file is part of Librarian, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from librarian.book2anything import Book2Anything, Option - - -class Book2Html(Book2Anything): - format_name = "HTML" - ext = "html" - uses_cover = False - uses_provider = False - transform_flags = [ - Option('-r', '--raw', dest='full-page', - action='store_false', default=True, - help='output raw text for use in templates') - ] - transform_options = [ - Option('--css', dest='css'), - Option( - '-b', '--base-url', dest='base_url', metavar='URL', - help='specifies the base URL for relative image references' - ), - ] - parser_options = [ - Option('-i', '--ignore-dublin-core', dest='parse_dublincore', - action='store_false', default=True, - help='don\'t try to parse dublin core metadata') - ] - - -if __name__ == '__main__': - Book2Html.run() diff --git a/setup.py b/setup.py index 494b3f2..184db52 100755 --- a/setup.py +++ b/setup.py @@ -40,7 +40,6 @@ setup( 'Pillow>=9.1.0', 'texml', 'ebooklib', - 'aeneas', 'mutagen', 'qrcode', 'requests', diff --git a/src/librarian/builders/daisy.py b/src/librarian/builders/daisy.py index c706cbd..4949879 100644 --- a/src/librarian/builders/daisy.py +++ b/src/librarian/builders/daisy.py @@ -5,8 +5,6 @@ from copy import deepcopy import subprocess import tempfile import zipfile -from aeneas.executetask import ExecuteTask -from aeneas.task import Task from lxml import etree import mutagen from librarian import OutputFile, get_resource @@ -117,75 +115,11 @@ class DaisyBuilder: directory + "book%d.mp3" % i, ) - config_string = "task_language=pol|is_text_type=unparsed|is_text_unparsed_id_regex=sec\d+$|is_text_unparsed_id_sort=numeric|os_task_file_format=tab" - task = Task(config_string=config_string) - - with tempfile.TemporaryDirectory() as temp: - syncfile = temp + "/sync" - task.audio_file_path_absolute = mp3[i] - task.text_file_path_absolute = html.get_filename() - task.sync_map_file_path_absolute = syncfile - - ExecuteTask(task).execute() - task.output_sync_map_file() - - sync = [] - with open(syncfile) as f: - for line in f: - start, end, sec = line.strip().split('\t') - start = float(start) - end = float(end) - sync.append([start, end, sec]) - - hms = format_hms(durations[i]) - elapsed_hms = format_hms(sum(durations[:i])) - - context = { - "VERSION": "1.10", - - "HHMMSSmmm": hms, - "HHMMSS": hms.split('.')[0], - "Sd": "%.1f" % durations[i], - "ELAPSED": elapsed_hms, - - "TITLE": document.meta.title, - "PUBLISHER": document.meta.publisher[0], - "YEAR": document.meta.created_at[:4], - "MONTH": document.meta.created_at[5:7], - "AUTHOR": document.meta.author.readable(), - - "NARRATOR": narrator, - } - - with open(get_resource('res/daisy/content.smil')) as f: - tree = etree.parse(f) populate(tree.getroot(), context) - seq = tree.find('//seq') - for si, item in enumerate(sync): - par = etree.SubElement(seq, 'par', id="par%06d" % (si + 1), endsync="last") - etree.SubElement( - par, - "text", - src="book%d.html#%s" % (i, item[2])) - - audio = etree.SubElement( - par, - "audio", - src="book%d.mp3" % i, - **{ - "clip-begin": "npt=%.3fs" % item[0], - "clip-end": "npt=%.3fs" % item[1], - } - ) - - zipf.writestr( + zipf.write( + syncfiles[i], directory + 'content%d.smil' % i, - etree.tostring( - tree, - xml_declaration=True, - pretty_print=True, - ), ) for fname in ('smil10.dtd', 'xhtml1-transitional.dtd', 'xhtml-lat1.ent', 'xhtml-special.ent', 'xhtml-symbol.ent'): diff --git a/src/librarian/builders/html.py b/src/librarian/builders/html.py index 0499d43..f2177ae 100644 --- a/src/librarian/builders/html.py +++ b/src/librarian/builders/html.py @@ -1,30 +1,38 @@ # This file is part of Librarian, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Wolne Lektury. See NOTICE for more information. # +from collections import defaultdict +import os from urllib.request import urlopen from lxml import etree -from librarian.html import add_anchors, add_table_of_contents, add_table_of_themes +from librarian.html import add_table_of_contents, add_table_of_themes, add_image_sizes from librarian import OutputFile class HtmlBuilder: file_extension = "html" - with_anchors = True with_themes = True with_toc = True with_footnotes = True with_nota_red = True + with_ids = True + with_numbering = True no_externalities = False orphans = True - def __init__(self, base_url=None): + root_tag = 'div' + root_attrib = {'id': 'book-text'} + + def __init__(self, gallery_path=None, gallery_url=None, base_url=None): self._base_url = base_url + self.gallery_path = gallery_path + self.gallery_url = gallery_url - self.tree = text = etree.Element('div', **{'id': 'book-text'}) + self.tree = text = etree.Element(self.root_tag, **self.root_attrib) self.header = etree.Element('h1') self.footnotes = etree.Element('div', id='footnotes') - self.footnote_counter = 0 + self.counters = defaultdict(lambda: 1) self.nota_red = etree.Element('div', id='nota_red') @@ -61,19 +69,38 @@ class HtmlBuilder: def forget_fragment(self, name): del self.cursors[name] - def preprocess(self, document): - document._compat_assign_ordered_ids() - document._compat_assign_section_ids() - - def build(self, document, **kwargs): + def build(self, document, element=None, **kwargs): self.document = document - self.preprocess(document) - document.tree.getroot().html_build(self) + self.assign_ids(self.document.tree) + self.prepare_images() + + if element is None: + element = document.tree.getroot() + + element.html_build(self) self.postprocess(document) return self.output() + def assign_ids(self, tree): + # Assign IDs depth-first, to account for any inside. + for _e, elem in etree.iterwalk(tree, events=('end',)): + if getattr(elem, 'NUMBERING', None): + elem.assign_id(self) + + def prepare_images(self): + # Temporarily use the legacy method, before transitioning to external generators. + if self.gallery_path is None: + return + try: + os.makedirs(self.gallery_path) + except OSError: + pass + add_image_sizes(self.document.tree, self.gallery_path, self.gallery_url, self.base_url) + def output(self): + if not len(self.tree): + return None return OutputFile.from_bytes( etree.tostring( self.tree, @@ -84,7 +111,7 @@ class HtmlBuilder: ) def postprocess(self, document): - _ = document.tree.getroot().master.gettext + _ = document.tree.getroot().gettext if document.meta.translators: self.enter_fragment('header') @@ -101,8 +128,6 @@ class HtmlBuilder: if len(self.header): self.tree.insert(0, self.header) - if self.with_anchors: - add_anchors(self.tree) if self.with_nota_red and len(self.nota_red): self.tree.append(self.nota_red) if self.with_themes: @@ -110,7 +135,7 @@ class HtmlBuilder: if self.with_toc: add_table_of_contents(self.tree) - if self.footnote_counter: + if self.counters['fn'] > 1: fnheader = etree.Element("h3") fnheader.text = _("Footnotes") self.footnotes.insert(0, fnheader) @@ -133,6 +158,15 @@ class HtmlBuilder: 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', { + 'href': f'#{element.attrib["_id"]}', + 'class': 'wl-num', + }) + self.push_text(element.attrib['_visible_numbering']) + self.end_element() + class StandaloneHtmlBuilder(HtmlBuilder): css_url = "https://static.wolnelektury.pl/css/compressed/book_text.css" @@ -148,7 +182,6 @@ class StandaloneHtmlBuilder(HtmlBuilder): head = etree.Element('head') tree.insert(0, head) - etree.SubElement(head, 'meta', charset='utf-8') etree.SubElement(head, 'title').text = document.meta.title @@ -185,23 +218,41 @@ class StandaloneHtmlBuilder(HtmlBuilder): class SnippetHtmlBuilder(HtmlBuilder): - with_anchors = False with_themes = False with_toc = False with_footnotes = False with_nota_red = False - with_refs = False + with_ids = False + with_numbering = False + + +class AbstraktHtmlBuilder(HtmlBuilder): + with_themes = False + with_toc = False + with_footnotes = False + with_nota_red = False + with_ids = False + with_numbering = False + + root_tag = 'blockquote' + root_attrib = {} + + def build(self, document, element=None, **kwargs): + if element is None: + element = document.tree.find('//abstrakt') + element.attrib['_force'] = '1' + return super().build(document, element, **kwargs) class DaisyHtmlBuilder(StandaloneHtmlBuilder): file_extension = 'xhtml' - with_anchors = False with_themes = False with_toc = False with_footnotes = False with_nota_red = False with_deep_identifiers = False no_externalities = True + with_numbering = False def output(self): tree = etree.ElementTree(self.tree) diff --git a/src/librarian/covers/marquise.py b/src/librarian/covers/marquise.py index 0b2349a..c56ae7a 100644 --- a/src/librarian/covers/marquise.py +++ b/src/librarian/covers/marquise.py @@ -16,6 +16,7 @@ class MarquiseCover(Cover): additional_logos = [] square_variant = False + background_color = '#000' width = 2100 height = 2970 margin = 100 diff --git a/src/librarian/dcparser.py b/src/librarian/dcparser.py index 910f5e1..ce03be2 100644 --- a/src/librarian/dcparser.py +++ b/src/librarian/dcparser.py @@ -87,23 +87,7 @@ class Field: return False -class DCInfo(type): - def __new__(mcs, classname, bases, class_dict): - fields = list(class_dict['FIELDS']) - - for base in bases[::-1]: - if hasattr(base, 'FIELDS'): - for field in base.FIELDS[::-1]: - try: - fields.index(field) - except ValueError: - fields.insert(0, field) - - class_dict['FIELDS'] = tuple(fields) - return super(DCInfo, mcs).__new__(mcs, classname, bases, class_dict) - - -class WorkInfo(metaclass=DCInfo): +class BookInfo: FIELDS = ( Field(DCNS('creator'), 'authors', Person, salias='author', multiple=True), @@ -140,6 +124,48 @@ class WorkInfo(metaclass=DCInfo): Field(WLNS('contentWarning'), 'content_warnings', multiple=True, required=False), Field(WLNS('developmentStage'), 'stage', required=False), + + Field(DCNS('audience'), 'audiences', text.Audience, salias='audience', multiple=True, + required=False), + + Field(DCNS('subject.period'), 'epochs', text.Epoch, salias='epoch', multiple=True, + required=False), + Field(DCNS('subject.type'), 'kinds', text.Kind, salias='kind', multiple=True, + required=False), + Field(DCNS('subject.genre'), 'genres', text.Genre, salias='genre', multiple=True, + required=False), + Field('category.legimi', 'legimi', text.LegimiCategory, required=False), + Field('category.thema.main', 'thema_main', text.MainThemaCategory, required=False), + Field('category.thema', 'thema', text.ThemaCategory, required=False, multiple=True), + Field(DCNS('subject.location'), 'location', required=False), + + Field(DCNS('contributor.translator'), 'translators', + Person, salias='translator', multiple=True, required=False), + Field(DCNS('relation.hasPart'), 'parts', WLURI, + multiple=True, required=False), + Field(DCNS('relation.isVariantOf'), 'variant_of', WLURI, + required=False), + + Field(DCNS('relation.coverImage.url'), 'cover_url', required=False), + Field(DCNS('relation.coverImage.attribution'), 'cover_by', + required=False), + Field(DCNS('relation.coverImage.source'), 'cover_source', + required=False), + # WLCover-specific. + Field(WLNS('coverBarColor'), 'cover_bar_color', required=False), + Field(WLNS('coverBoxPosition'), 'cover_box_position', required=False), + Field(WLNS('coverClass'), 'cover_class', default=['default']), + Field(WLNS('coverLogoUrl'), 'cover_logo_urls', multiple=True, + required=False), + Field(WLNS('endnotes'), 'endnotes', BoolValue, + required=False), + + Field('pdf-id', 'isbn_pdf', required=False), + Field('epub-id', 'isbn_epub', required=False), + Field('mobi-id', 'isbn_mobi', required=False), + Field('txt-id', 'isbn_txt', required=False), + Field('html-id', 'isbn_html', required=False), + ) @classmethod @@ -350,50 +376,5 @@ class WorkInfo(metaclass=DCInfo): return result -class BookInfo(WorkInfo): - FIELDS = ( - Field(DCNS('audience'), 'audiences', text.Audience, salias='audience', multiple=True, - required=False), - - Field(DCNS('subject.period'), 'epochs', text.Epoch, salias='epoch', multiple=True, - required=False), - Field(DCNS('subject.type'), 'kinds', text.Kind, salias='kind', multiple=True, - required=False), - Field(DCNS('subject.genre'), 'genres', text.Genre, salias='genre', multiple=True, - required=False), - Field('category.legimi', 'legimi', text.LegimiCategory, required=False), - Field('category.thema.main', 'thema_main', text.MainThemaCategory, required=False), - Field('category.thema', 'thema', text.ThemaCategory, required=False, multiple=True), - Field(DCNS('subject.location'), 'location', required=False), - - Field(DCNS('contributor.translator'), 'translators', - Person, salias='translator', multiple=True, required=False), - Field(DCNS('relation.hasPart'), 'parts', WLURI, - multiple=True, required=False), - Field(DCNS('relation.isVariantOf'), 'variant_of', WLURI, - required=False), - - Field(DCNS('relation.coverImage.url'), 'cover_url', required=False), - Field(DCNS('relation.coverImage.attribution'), 'cover_by', - required=False), - Field(DCNS('relation.coverImage.source'), 'cover_source', - required=False), - # WLCover-specific. - Field(WLNS('coverBarColor'), 'cover_bar_color', required=False), - Field(WLNS('coverBoxPosition'), 'cover_box_position', required=False), - Field(WLNS('coverClass'), 'cover_class', default=['default']), - Field(WLNS('coverLogoUrl'), 'cover_logo_urls', multiple=True, - required=False), - Field(WLNS('endnotes'), 'endnotes', BoolValue, - required=False), - - Field('pdf-id', 'isbn_pdf', required=False), - Field('epub-id', 'isbn_epub', required=False), - Field('mobi-id', 'isbn_mobi', required=False), - Field('txt-id', 'isbn_txt', required=False), - Field('html-id', 'isbn_html', required=False), - ) - - def parse(file_name, cls=BookInfo): return cls.from_file(file_name) diff --git a/src/librarian/document.py b/src/librarian/document.py index 7780b61..d61abb4 100644 --- a/src/librarian/document.py +++ b/src/librarian/document.py @@ -18,6 +18,9 @@ class WLDocument: tree = etree.parse(source, parser=parser) self.tree = tree tree.getroot().document = self + + self.preprocess() + self.base_meta = dcparser.BookInfo({}, { DCNS('language'): ["pol"], }, validate_required=False) @@ -33,6 +36,11 @@ class WLDocument: return self.tree.getroot().meta return master.meta + def preprocess(self): + # Change slash-verses into real verses. + for _e, elem in etree.iterwalk(self.tree, ('start',), 'strofa'): + elem.preprocess() + @property def children(self): for part_uri in self.meta.parts or []: @@ -46,76 +54,6 @@ class WLDocument: def build(self, builder, base_url=None, **kwargs): return builder(base_url=base_url).build(self, **kwargs) - def assign_ids(self, existing=None): - # Find all existing IDs. - existing = existing or set() - que = [self.tree.getroot()] - while que: - item = que.pop(0) - try: - item.normalize_insides() - except AttributeError: - pass - existing.add(item.attrib.get('id')) - que.extend(item) - - i = 1 - que = [self.tree.getroot()] - while que: - item = que.pop(0) - que.extend(item) - if item.attrib.get('id'): - continue - if not getattr(item, 'SHOULD_HAVE_ID', False): - continue - while f'e{i}' in existing: - i += 1 - item.attrib['id'] = f'e{i}' - i += 1 - - def _compat_assign_ordered_ids(self): - """ - Compatibility: ids in document order, to be roughly compatible with legacy - footnote ids. Just for testing consistency, change to some sane identifiers - at convenience. - """ - EXPR = re.compile(r'/\s', re.MULTILINE | re.UNICODE) - def _compat_assign_ordered_ids_in_elem(elem, i): - if isinstance(elem, etree._Comment): return i - elem.attrib['_compat_ordered_id'] = str(i) - i += 1 - if getattr(elem, 'HTML_CLASS', None) == 'stanza': - if elem.text: - i += len(EXPR.split(elem.text)) - 1 - for sub in elem: - i = _compat_assign_ordered_ids_in_elem(sub, i) - if sub.tail: - i += len(EXPR.split(sub.tail)) - 1 - else: - if elem.tag in ('uwaga', 'extra'): - return i - for sub in elem: - i = _compat_assign_ordered_ids_in_elem(sub, i) - return i - - _compat_assign_ordered_ids_in_elem(self.tree.getroot(), 4) - - def _compat_assign_section_ids(self): - """ - Ids in master-section order. These need to be compatible with the - #secN anchors used by WL search results page to link to fragments. - """ - def _compat_assigns_section_ids_in_elem(elem, prefix='sec'): - for i, child in enumerate(elem): - idfier = '{}{}'.format(prefix, i + 1) - try: - child.attrib['_compat_section_id'] = idfier - except: - pass - _compat_assigns_section_ids_in_elem(child, idfier + '-') - _compat_assigns_section_ids_in_elem(self.tree.getroot().master) - - def editors(self): persons = set(self.meta.editors + self.meta.technical_editors) diff --git a/src/librarian/elements/base.py b/src/librarian/elements/base.py index b0d16ed..2349f16 100644 --- a/src/librarian/elements/base.py +++ b/src/librarian/elements/base.py @@ -40,6 +40,7 @@ class WLElement(etree.ElementBase): CAN_HAVE_TEXT = True STRIP = False + NUMBERING = None text_substitutions = [ ('---', '—'), @@ -85,6 +86,15 @@ class WLElement(etree.ElementBase): except AttributeError: return parent.in_context_of(setting) + def get_context_map(self, setting, key, default=None): + parent = self.getparent() + if parent is None: + return default + try: + return getattr(parent, setting)[key] + except AttributeError: + return parent.get_context_map(setting, key, default) + def signal(self, signal): parent = self.getparent() if parent is not None: @@ -136,7 +146,8 @@ class WLElement(etree.ElementBase): for i, child in enumerate(self): if isinstance(child, WLElement): getattr(child, build_method)(builder) - elif getattr(builder, 'debug') and child.tag is etree.Comment: + # FIXME base builder api + elif getattr(builder, 'debug', False) and child.tag is etree.Comment: builder.process_comment(child) if self.CAN_HAVE_TEXT and child.tail: text = self.normalize_text(child.tail, builder) @@ -167,14 +178,21 @@ class WLElement(etree.ElementBase): attr = self.HTML_ATTR.copy() if self.HTML_CLASS: attr['class'] = self.HTML_CLASS - # always copy the id attribute (?) - if self.attrib.get('id'): - attr['id'] = self.attrib['id'] - elif getattr(self, 'SHOULD_HAVE_ID', False) and '_compat_section_id' in self.attrib: - attr['id'] = self.attrib['_compat_section_id'] + if builder.with_ids: + # always copy the id attribute (?) + if self.attrib.get('id'): + attr['id'] = self.attrib['id'] + if self.attrib.get('_id'): + attr['id'] = self.attrib['_id'] return attr def html_build(self, builder): + # Do we need a number? + numbering = self.numbering + if numbering == 'main': + if builder.with_numbering and self.has_visible_numbering: + builder.add_visible_number(self) + if self.HTML_TAG: builder.start_element( self.HTML_TAG, @@ -315,15 +333,38 @@ class WLElement(etree.ElementBase): return snipelem + @property + def numbering(self): + numbering = self.NUMBERING + if numbering is None or self.in_context_of('DISABLE_NUMBERING'): + return None + numbering = self.get_context_map('SUPPRESS_NUMBERING', numbering, numbering) + return numbering + + @property + def id_prefix(self): + prefix = self.numbering + if prefix == 'main': + # TODO: self.context.main_numbering_prefix + prefix = 'f' # default numbering prefix + return prefix + + def assign_id(self, builder): + numbering = self.numbering + if numbering: + number = str(builder.counters[numbering]) + self.attrib['_id'] = self.id_prefix + number + builder.counters[numbering] += 1 + + if numbering == 'main': + self.attrib['_visible_numbering'] = str(builder.counters['_visible']) + builder.counters['_visible'] += 1 + + if numbering == 'fn': + self.attrib['_visible_numbering'] = number + def get_link(self): - sec = getattr(self, 'SHOULD_HAVE_ID', False) and self.attrib.get('_compat_section_id') - if sec: - return sec - parent_index = self.getparent().index(self) - if parent_index: - return self.getparent()[parent_index - 1].get_link() - else: - return self.getparent().get_link() + return self.attrib.get('_id') or self.getparent().get_link() class Snippet(WLElement): diff --git a/src/librarian/elements/blocks/dedykacja.py b/src/librarian/elements/blocks/dedykacja.py index 4076541..265b268 100644 --- a/src/librarian/elements/blocks/dedykacja.py +++ b/src/librarian/elements/blocks/dedykacja.py @@ -5,7 +5,7 @@ from ..base import WLElement class Dedykacja(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' TXT_LEGACY_TOP_MARGIN = 2 diff --git a/src/librarian/elements/blocks/nota.py b/src/librarian/elements/blocks/nota.py index 8a8d8bd..dbba883 100644 --- a/src/librarian/elements/blocks/nota.py +++ b/src/librarian/elements/blocks/nota.py @@ -9,3 +9,5 @@ class Nota(WLElement): EPUB_TAG = HTML_TAG = "div" EPUB_CLASS = HTML_CLASS = "note" + + SUPPRESS_NUMBERING = {'main': 'i'} diff --git a/src/librarian/elements/comments/abstrakt.py b/src/librarian/elements/comments/abstrakt.py index 09be8ae..f54a455 100644 --- a/src/librarian/elements/comments/abstrakt.py +++ b/src/librarian/elements/comments/abstrakt.py @@ -9,7 +9,9 @@ class Abstrakt(WLElement): pass def html_build(self, builder): - pass + if not self.attrib['_force']: + return + return super().html_build(builder) def epub_build(self, builder): pass diff --git a/src/librarian/elements/drama/didaskalia.py b/src/librarian/elements/drama/didaskalia.py index ed43cae..8f461dd 100644 --- a/src/librarian/elements/drama/didaskalia.py +++ b/src/librarian/elements/drama/didaskalia.py @@ -5,7 +5,7 @@ from ..base import WLElement class Didaskalia(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' TXT_TOP_PARGIN = 2 TXT_BOTTOM_MARGIN = 2 @@ -14,5 +14,5 @@ class Didaskalia(WLElement): TXT_PREFIX = "/ " TXT_SUFFIX = " /" - EPUB_TAG =_HTML_TAG = "div" + EPUB_TAG = HTML_TAG = "div" EPUB_CLASS = HTML_CLASS = "didaskalia" diff --git a/src/librarian/elements/drama/lista_osob.py b/src/librarian/elements/drama/lista_osob.py index 0727698..f9e210d 100644 --- a/src/librarian/elements/drama/lista_osob.py +++ b/src/librarian/elements/drama/lista_osob.py @@ -6,8 +6,8 @@ from ..base import WLElement class ListaOsob(WLElement): + NUMBERING = 'i' CAN_HAVE_TEXT = False - SHOULD_HAVE_ID = True TXT_TOP_MARGIN = 3 TXT_BOTTOM_MARGIN = 3 diff --git a/src/librarian/elements/drama/lista_osoba.py b/src/librarian/elements/drama/lista_osoba.py index e4243df..2341918 100644 --- a/src/librarian/elements/drama/lista_osoba.py +++ b/src/librarian/elements/drama/lista_osoba.py @@ -5,6 +5,8 @@ from ..base import WLElement class ListaOsoba(WLElement): + NUMBERING = "i" + TXT_TOP_MARGIN = 1 TXT_BOTTOM_MARGIN = 1 TXT_LEGACY_TOP_MARGIN = 1 @@ -12,6 +14,7 @@ class ListaOsoba(WLElement): TXT_PREFIX = " * " EPUB_TAG = HTML_TAG = "li" + HTML_CLASS = "wl" def html_build(self, builder): builder.enter_fragment('list') diff --git a/src/librarian/elements/drama/miejsce_czas.py b/src/librarian/elements/drama/miejsce_czas.py index 313109c..48e748e 100644 --- a/src/librarian/elements/drama/miejsce_czas.py +++ b/src/librarian/elements/drama/miejsce_czas.py @@ -5,8 +5,9 @@ from ..paragraphs import Akap class MiejsceCzas(Akap): - SHOULD_HAVE_ID = True + NUMBERING = 'i' + + HTML_CLASS = 'wl place-and-time' EPUB_TAG = "div" - EPUB_CLASS = HTML_CLASS = 'place-and-time' - + EPUB_CLASS = 'place-and-time' diff --git a/src/librarian/elements/drama/naglowek_listy.py b/src/librarian/elements/drama/naglowek_listy.py index 646833c..0918ba8 100644 --- a/src/librarian/elements/drama/naglowek_listy.py +++ b/src/librarian/elements/drama/naglowek_listy.py @@ -5,9 +5,10 @@ from ..base import WLElement class NaglowekListy(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' HTML_TAG = "h3" + HTML_CLASS = "wl" EPUB_TAG = "div" EPUB_CLASS = "h3" diff --git a/src/librarian/elements/drama/naglowek_osoba.py b/src/librarian/elements/drama/naglowek_osoba.py index dde0c0c..43aa1d3 100644 --- a/src/librarian/elements/drama/naglowek_osoba.py +++ b/src/librarian/elements/drama/naglowek_osoba.py @@ -5,7 +5,7 @@ from ..base import WLElement class NaglowekOsoba(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' TXT_TOP_MARGIN = 3 TXT_BOTTOM_MARGIN = 2 diff --git a/src/librarian/elements/figures/animacja.py b/src/librarian/elements/figures/animacja.py index 3479a02..6b0619a 100644 --- a/src/librarian/elements/figures/animacja.py +++ b/src/librarian/elements/figures/animacja.py @@ -5,7 +5,7 @@ from ..base import WLElement class Animacja(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' HTML_TAG = 'div' HTML_CLASS = "animacja cycle-slideshow" diff --git a/src/librarian/elements/figures/ilustr.py b/src/librarian/elements/figures/ilustr.py index 4e848ac..51bae4e 100644 --- a/src/librarian/elements/figures/ilustr.py +++ b/src/librarian/elements/figures/ilustr.py @@ -12,13 +12,36 @@ MAX_PNG_WEIGHT = 200000 class Ilustr(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' EPUB_TAG = HTML_TAG = 'img' def get_html_attr(self, builder): - ## TODO: thumbnail. + cls = 'ilustr' + if self.attrib.get('wyrownanie'): + cls += ' ' + self.attrib['wyrownanie'] + if self.attrib.get('oblew'): + cls += ' oblew' + attr = { + 'class': cls, + 'alt': self.attrib.get('alt', ''), + 'title': self.attrib.get('alt', ''), + 'src': self.attrib.get('src', ''), + } + if self.attrib.get('srcset'): + attr['srcset'] = self.attrib['srcset'] + attr['sizes'] = ''' + (min-width: 718px) 600px, + (min-width: 600px) calc(100vw - 118px), + (min-width: 320px) calc(100vw - 75px), + (min-width: 15em) calc(100wv - 60px), + calc(100wv - 40px) + ''' + if self.attrib.get('szer'): + attr['style'] = 'width: ' + self.attrib['szer'] + return attr + def get_epub_attr(self, builder): url = urllib.parse.urljoin( builder.base_url, self.get('src') @@ -69,5 +92,3 @@ class Ilustr(WLElement): 'alt': self.attrib.get('alt', ''), 'title': self.attrib.get('alt', ''), } - - get_epub_attr = get_html_attr diff --git a/src/librarian/elements/figures/tabela.py b/src/librarian/elements/figures/tabela.py index 737166f..783fcb6 100644 --- a/src/librarian/elements/figures/tabela.py +++ b/src/librarian/elements/figures/tabela.py @@ -5,7 +5,7 @@ from ..base import WLElement class Tabela(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' EPUB_TAG = HTML_TAG = 'table' diff --git a/src/librarian/elements/footnotes/__init__.py b/src/librarian/elements/footnotes/__init__.py index 76be8e8..a94b968 100644 --- a/src/librarian/elements/footnotes/__init__.py +++ b/src/librarian/elements/footnotes/__init__.py @@ -6,8 +6,10 @@ from ..base import WLElement class Footnote(WLElement): NO_TOC = True + DISABLE_NUMBERING = True START_INLINE = True ASIDE = True + NUMBERING = 'fn' def signal(self, signal): if signal == 'INLINE': @@ -22,10 +24,9 @@ class Footnote(WLElement): if not builder.with_footnotes: return - builder.footnote_counter += 1 - fn_no = builder.footnote_counter - footnote_id = 'footnote-idm{}'.format(self.attrib['_compat_ordered_id']) - anchor_id = 'anchor-idm{}'.format(self.attrib['_compat_ordered_id']) + fn_no = self.attrib.get('_visible_numbering') + footnote_id = 'footnote-id{}'.format(fn_no) + anchor_id = 'anchor-id{}'.format(fn_no) # Add anchor. builder.start_element( diff --git a/src/librarian/elements/front/autor_utworu.py b/src/librarian/elements/front/autor_utworu.py index 555cb92..3e35b0b 100644 --- a/src/librarian/elements/front/autor_utworu.py +++ b/src/librarian/elements/front/autor_utworu.py @@ -8,7 +8,7 @@ class AutorUtworu(HeaderElement): TXT_BOTTOM_MARGIN = 2 TXT_LEGACY_BOTTOM_MARGIN = 2 - HTML_CLASS = 'author' + HTML_CLASS = 'wl author' def epub_build(self, builder): return diff --git a/src/librarian/elements/front/base.py b/src/librarian/elements/front/base.py index 04d286e..ad16ca3 100644 --- a/src/librarian/elements/front/base.py +++ b/src/librarian/elements/front/base.py @@ -5,8 +5,8 @@ from ..base import WLElement class HeaderElement(WLElement): + NUMBERING = 'i' HTML_TAG = 'span' - SHOULD_HAVE_ID = True def txt_build(self, builder): builder.enter_fragment('header') diff --git a/src/librarian/elements/front/dzielo_nadrzedne.py b/src/librarian/elements/front/dzielo_nadrzedne.py index bbc30b1..cc70164 100644 --- a/src/librarian/elements/front/dzielo_nadrzedne.py +++ b/src/librarian/elements/front/dzielo_nadrzedne.py @@ -8,7 +8,7 @@ class DzieloNadrzedne(HeaderElement): TXT_BOTTOM_MARGIN = 1 TXT_LEGACY_BOTTOM_MARGIN = 1 - HTML_CLASS = "collection" + HTML_CLASS = "wl collection" def epub_build(self, builder): return diff --git a/src/librarian/elements/front/motto.py b/src/librarian/elements/front/motto.py index ab6d13c..a6769b8 100644 --- a/src/librarian/elements/front/motto.py +++ b/src/librarian/elements/front/motto.py @@ -5,7 +5,7 @@ from ..base import WLElement class Motto(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' TXT_LEGACY_TOP_MARGIN = 4 TXT_LEGACY_BOTTOM_MARGIN = 2 diff --git a/src/librarian/elements/front/motto_podpis.py b/src/librarian/elements/front/motto_podpis.py index 3441263..199da84 100644 --- a/src/librarian/elements/front/motto_podpis.py +++ b/src/librarian/elements/front/motto_podpis.py @@ -5,9 +5,10 @@ from ..base import WLElement class MottoPodpis(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' + HTML_TAG = "p" - EPUB_CLASS = HTML_CLASS = "motto_podpis" + HTML_CLASS = "wl motto_podpis" EPUB_TAG = "div" - + EPUB_CLASS = "motto_podpis" diff --git a/src/librarian/elements/front/nazwa_utworu.py b/src/librarian/elements/front/nazwa_utworu.py index 376b932..dd40266 100644 --- a/src/librarian/elements/front/nazwa_utworu.py +++ b/src/librarian/elements/front/nazwa_utworu.py @@ -8,7 +8,7 @@ class NazwaUtworu(HeaderElement): TXT_BOTTOM_MARGIN = 1 TXT_LEGACY_BOTTOM_MARGIN = 1 - HTML_CLASS = 'title' + HTML_CLASS = 'wl title' EPUB_TAG = 'h2' EPUB_CLASS = 'intitle' diff --git a/src/librarian/elements/front/podtytul.py b/src/librarian/elements/front/podtytul.py index e602571..711b3fa 100644 --- a/src/librarian/elements/front/podtytul.py +++ b/src/librarian/elements/front/podtytul.py @@ -8,7 +8,7 @@ class Podtytul(HeaderElement): TXT_BOTTOM_MARGIN = 1 TXT_LEGACY_BOTTOM_MARGIN = 1 - HTML_CLASS = 'subtitle' + HTML_CLASS = 'wl subtitle' EPUB_TAG = 'h2' EPUB_CLASS = 'insubtitle' diff --git a/src/librarian/elements/headers/naglowek_czesc.py b/src/librarian/elements/headers/naglowek_czesc.py index 9ce9ebb..11991ae 100644 --- a/src/librarian/elements/headers/naglowek_czesc.py +++ b/src/librarian/elements/headers/naglowek_czesc.py @@ -5,8 +5,8 @@ from ..base import WLElement class NaglowekCzesc(WLElement): + NUMBERING = 's' SECTION_PRECEDENCE = 1 - SHOULD_HAVE_ID = True TXT_TOP_MARGIN = 5 TXT_BOTTOM_MARGIN = 2 @@ -14,6 +14,7 @@ class NaglowekCzesc(WLElement): TXT_LEGACY_BOTTOM_MARGIN = 0 EPUB_TAG = HTML_TAG = "h2" + HTML_CLASS = "wl" EPUB_CLASS = "h2" EPUB_START_CHUNK = True diff --git a/src/librarian/elements/headers/naglowek_podrozdzial.py b/src/librarian/elements/headers/naglowek_podrozdzial.py index 26c8049..213ec00 100644 --- a/src/librarian/elements/headers/naglowek_podrozdzial.py +++ b/src/librarian/elements/headers/naglowek_podrozdzial.py @@ -5,8 +5,8 @@ from ..base import WLElement class NaglowekPodrozdzial(WLElement): + NUMBERING = 's' SECTION_PRECEDENCE = 3 - SHOULD_HAVE_ID = True TXT_TOP_MARGIN = 3 TXT_BOTTOM_MARGIN = 2 diff --git a/src/librarian/elements/headers/naglowek_rozdzial.py b/src/librarian/elements/headers/naglowek_rozdzial.py index 65194d3..502dea1 100644 --- a/src/librarian/elements/headers/naglowek_rozdzial.py +++ b/src/librarian/elements/headers/naglowek_rozdzial.py @@ -5,8 +5,8 @@ from ..base import WLElement class NaglowekRozdzial(WLElement): + NUMBERING = 's' SECTION_PRECEDENCE = 2 - SHOULD_HAVE_ID = True TXT_TOP_MARGIN = 4 TXT_BOTTOM_MARGIN = 2 @@ -14,6 +14,7 @@ class NaglowekRozdzial(WLElement): TXT_LEGACY_BOTTOM_MARGIN = 0 HTML_TAG = 'h3' + HTML_CLASS = 'wl' EPUB_TAG = 'h2' EPUB_CLASS = 'h3' diff --git a/src/librarian/elements/headers/naglowek_scena.py b/src/librarian/elements/headers/naglowek_scena.py index eb2c356..e9ea5c7 100644 --- a/src/librarian/elements/headers/naglowek_scena.py +++ b/src/librarian/elements/headers/naglowek_scena.py @@ -5,8 +5,8 @@ from ..base import WLElement class NaglowekScena(WLElement): + NUMBERING = 's' SECTION_PRECEDENCE = 2 - SHOULD_HAVE_ID = True TXT_TOP_MARGIN = 4 TXT_BOTTOM_MARGIN = 2 diff --git a/src/librarian/elements/headers/podtytul_czesc.py b/src/librarian/elements/headers/podtytul_czesc.py index 6b8ed75..14c6536 100644 --- a/src/librarian/elements/headers/podtytul_czesc.py +++ b/src/librarian/elements/headers/podtytul_czesc.py @@ -5,7 +5,7 @@ from ..base import WLElement class PodtytulCzesc(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' TXT_TOP_MARGIN = 2 TXT_BOTTOM_MARGIN = 2 diff --git a/src/librarian/elements/headers/podtytul_podrozdzial.py b/src/librarian/elements/headers/podtytul_podrozdzial.py index bf3fcfe..239891e 100644 --- a/src/librarian/elements/headers/podtytul_podrozdzial.py +++ b/src/librarian/elements/headers/podtytul_podrozdzial.py @@ -5,7 +5,7 @@ from ..base import WLElement class PodtytulPodrozdzial(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' TXT_TOP_MARGIN = 2 TXT_BOTTOM_MARGIN = 2 diff --git a/src/librarian/elements/headers/podtytul_rozdzial.py b/src/librarian/elements/headers/podtytul_rozdzial.py index ac455c3..f24fba7 100644 --- a/src/librarian/elements/headers/podtytul_rozdzial.py +++ b/src/librarian/elements/headers/podtytul_rozdzial.py @@ -5,7 +5,7 @@ from ..base import WLElement class PodtytulRozdzial(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' TXT_TOP_MARGIN = 2 TXT_BOTTOM_MARGIN = 2 diff --git a/src/librarian/elements/paragraphs/akap.py b/src/librarian/elements/paragraphs/akap.py index 9df8492..63f74b5 100644 --- a/src/librarian/elements/paragraphs/akap.py +++ b/src/librarian/elements/paragraphs/akap.py @@ -6,15 +6,19 @@ from ..base import WLElement class Akap(WLElement): STRIP = True - SHOULD_HAVE_ID = True + NUMBERING = 'main' TXT_TOP_MARGIN = 2 TXT_BOTTOM_MARGIN = 2 TXT_LEGACY_TOP_MARGIN = 2 TXT_LEGACY_BOTTOM_MARGIN = 0 + EPUB_CLASS = 'paragraph' + HTML_TAG = 'p' - EPUB_CLASS = HTML_CLASS = 'paragraph' + HTML_CLASS = 'wl paragraph' + + has_visible_numbering = True @property def EPUB_TAG(self): diff --git a/src/librarian/elements/poetry/strofa.py b/src/librarian/elements/poetry/strofa.py index 7ce3f3a..bccb01b 100644 --- a/src/librarian/elements/poetry/strofa.py +++ b/src/librarian/elements/poetry/strofa.py @@ -8,7 +8,7 @@ from .wers import Wers class Strofa(WLElement): - SHOULD_HAVE_ID = True + NUMBERING = 'i' TXT_TOP_MARGIN = 2 TXT_BOTTOM_MARGIN = 2 @@ -28,8 +28,8 @@ class Strofa(WLElement): ) builder.push_text('\u00a0'); builder.end_element() - - def get_verses(self): + + def preprocess(self): from librarian.parser import parser verses = [ @@ -57,15 +57,15 @@ class Strofa(WLElement): else: verses[-1].append(child) - for verse in verses: - verse.stanza = self - if len(verse) == 1 and isinstance(verse[0], Wers): - assert not (verse.text or '').strip() - assert not (verse[0].tail or '').strip() - yield verse[0] - else: - yield verse + verses = [ + verse[0] if len(verse) == 1 and isinstance(verse[0], Wers) + else verse + for verse in verses + ] + + while len(self): + self.remove(self[0]) + self.text = None - def _build_inner(self, builder, build_method): - for child in self.get_verses(): - getattr(child, build_method)(builder) + for verse in verses: + self.append(verse) diff --git a/src/librarian/elements/poetry/wers.py b/src/librarian/elements/poetry/wers.py index edc4c7c..127d5bd 100644 --- a/src/librarian/elements/poetry/wers.py +++ b/src/librarian/elements/poetry/wers.py @@ -13,7 +13,10 @@ class Wers(WLElement): TXT_LEGACY_BOTTOM_MARGIN = 0 EPUB_TAG = HTML_TAG = 'div' - EPUB_CLASS = HTML_CLASS = 'verse' + EPUB_CLASS = 'verse' + HTML_CLASS = 'wl verse' + + NUMBERING = 'main' @property def meta(self): @@ -25,3 +28,27 @@ class Wers(WLElement): super()._epub_build_inner(builder) builder.push_text('''\u00a0''') + @property + def has_visible_numbering(self): + try: + number = int(self.attrib['_visible_numbering']) + except: + return False + return number == 1 or not(number % 5) + + @property + def is_stretched(self): + return self.find('.//tab[@szer="*"]') is not None + + def get_html_attr(self, builder): + attr = super().get_html_attr(builder) + if self.is_stretched: + attr['class'] += ' verse-stretched' + return attr + + def _html_build_inner(self, builder): + if self.is_stretched: + builder.start_element('span') + super()._html_build_inner(builder) + if self.is_stretched: + builder.end_element() diff --git a/src/librarian/elements/poetry/wers_akap.py b/src/librarian/elements/poetry/wers_akap.py index 394684c..8d0a9dc 100644 --- a/src/librarian/elements/poetry/wers_akap.py +++ b/src/librarian/elements/poetry/wers_akap.py @@ -7,9 +7,7 @@ from .wers import Wers class WersAkap(Wers): TXT_PREFIX = ' ' - HTML_ATTR = { - "style": "padding-left: 1em" - } + HTML_CLASS = Wers.HTML_CLASS + ' verse-p' EPUB_ATTR = { "style": "margin-left: 1em" diff --git a/src/librarian/elements/poetry/wers_cd.py b/src/librarian/elements/poetry/wers_cd.py index 49d5a6b..2350c30 100644 --- a/src/librarian/elements/poetry/wers_cd.py +++ b/src/librarian/elements/poetry/wers_cd.py @@ -4,14 +4,12 @@ from .wers import Wers class WersCd(Wers): + HTML_CLASS = Wers.HTML_CLASS + ' verse-cont' + def _txt_build_inner(self, builder): builder.push_text(' ' * 24, prepared=True) super(WersCd, self)._txt_build_inner(builder) - HTML_ATTR = { - "style": "padding-left: 12em", - } - EPUB_ATTR = { "style": "margin-left: 12em", } diff --git a/src/librarian/elements/poetry/wers_do_prawej.py b/src/librarian/elements/poetry/wers_do_prawej.py index b3c8ae9..59e639c 100644 --- a/src/librarian/elements/poetry/wers_do_prawej.py +++ b/src/librarian/elements/poetry/wers_do_prawej.py @@ -7,6 +7,8 @@ from .wers import Wers class WersDoPrawej(Wers): TXT_PREFIX = ' ' - EPUB_ATTR = HTML_ATTR = { + HTML_CLASS = Wers.HTML_CLASS + ' verse-right' + + EPUB_ATTR = { "style": "text-align: right", } diff --git a/src/librarian/elements/poetry/wers_srodek.py b/src/librarian/elements/poetry/wers_srodek.py index b8088c5..eaef5c9 100644 --- a/src/librarian/elements/poetry/wers_srodek.py +++ b/src/librarian/elements/poetry/wers_srodek.py @@ -7,6 +7,8 @@ from .wers import Wers class WersSrodek(Wers): TXT_PREFIX = ' ' - EPUB_ATTR = HTML_ATTR = { + HTML_CLASS = Wers.HTML_CLASS + ' verse-center' + + EPUB_ATTR = { "style": "text-align: center", } diff --git a/src/librarian/elements/poetry/wers_wciety.py b/src/librarian/elements/poetry/wers_wciety.py index 8fbd175..4a2744a 100644 --- a/src/librarian/elements/poetry/wers_wciety.py +++ b/src/librarian/elements/poetry/wers_wciety.py @@ -5,6 +5,8 @@ from .wers import Wers class WersWciety(Wers): + HTML_CLASS = Wers.HTML_CLASS + ' verse-indent' + @property def typ(self): v = self.attrib.get('typ') @@ -19,7 +21,7 @@ class WersWciety(Wers): def get_html_attr(self, builder): attr = super(WersWciety, self).get_html_attr(builder) - attr['style'] = "padding-left: {}em".format(self.typ) + attr['class'] += f" verse-indent-{self.typ}" return attr def get_epub_attr(self, builder): diff --git a/src/librarian/elements/styles/www.py b/src/librarian/elements/styles/www.py index 7022d1f..4655829 100644 --- a/src/librarian/elements/styles/www.py +++ b/src/librarian/elements/styles/www.py @@ -5,10 +5,15 @@ from ..base import WLElement class WWW(WLElement): - EPUB_TAG = 'a' + HTML_TAG = EPUB_TAG = 'a' def get_epub_attr(self, builder): attr = super().get_epub_attr(builder) attr['href'] = self.text return attr + def get_html_attr(self, builder): + attr = super().get_epub_attr(builder) + attr['target'] = '_blank' + attr['href'] = self.text + return attr diff --git a/src/librarian/elements/tools/__init__.py b/src/librarian/elements/tools/__init__.py index 99f81d9..c4820b1 100644 --- a/src/librarian/elements/tools/__init__.py +++ b/src/librarian/elements/tools/__init__.py @@ -5,11 +5,13 @@ from ..base import WLElement class Numeracja(WLElement): - pass + NUMBERING = True + def assign_id(self, builder): + builder.counters['_visible'] = int(self.get('start', 1)) class Rownolegle(WLElement): - def build_epub(self, builder): + def epub_build(self, builder): for i, block in enumerate(self): attr = {"class": "rownolegly-blok"} if not i: @@ -17,16 +19,49 @@ class Rownolegle(WLElement): if i == len(self) - 1: attr['class'] += ' last' builder.start_element('div', attr) - self.build_epub(block, builder) + block.epub_build(builder) builder.end_element() + def html_build(self, builder): + for i, block in enumerate(self): + attr = {"class": "paralell-block"} + if not i: + attr['class'] += ' paralell-block-first' + if i == len(self) - 1: + attr['class'] += ' paralell-block-last' + builder.start_element('div', attr) + block.html_build(builder) + builder.end_element() + + class Tab(WLElement): EPUB_TAG = HTML_TAG = 'span' + def html_build(self, builder): + szer = self.get('szer', '1') + if szer == '*': + reopen = [] + from lxml import etree + p = builder.cursor + while 'verse' not in p.attrib.get('class', ''): + reopen.append(p) + p = p.getparent() + builder.end_element() + builder.start_element('span', {'class': 'verse-stretched-space'}) + builder.end_element() + while reopen: + p = reopen.pop() + builder.start_element(p.tag, p.attrib) + else: + super().html_build(builder) + def get_html_attr(self, builder): + szer = self.get('szer', '1').strip() + if szer.endswith('em'): + szer = szer[:-2] try: - szer = int(self.get('szer', 1)) + szer = int(szer) except: szer = 1 return { @@ -35,4 +70,3 @@ class Tab(WLElement): } get_epub_attr = get_html_attr - diff --git a/src/librarian/html.py b/src/librarian/html.py index 2919498..a96e975 100644 --- a/src/librarian/html.py +++ b/src/librarian/html.py @@ -9,43 +9,9 @@ import urllib.parse import urllib.request from lxml import etree -from librarian import XHTMLNS, ParseError, OutputFile from librarian import functions from PIL import Image -from lxml.etree import XMLSyntaxError, XSLTApplyError - - -functions.reg_substitute_entities() -functions.reg_person_name() - -STYLESHEETS = { - 'legacy': 'xslt/book2html.xslt', -} - - -def get_stylesheet(name): - return os.path.join(os.path.dirname(__file__), STYLESHEETS[name]) - - -def html_has_content(text): - return etree.ETXPath( - '//p|//{%(ns)s}p|//h1|//{%(ns)s}h1' % {'ns': str(XHTMLNS)} - )(text) - - -def transform_abstrakt(abstrakt_element): - style_filename = get_stylesheet('legacy') - style = etree.parse(style_filename) - xml = etree.tostring(abstrakt_element, encoding='unicode') - document = etree.parse(io.StringIO( - xml.replace('', '', - etree.tostring(result, encoding='unicode')) - return re.sub(']*>', '', html) - def add_image_sizes(tree, gallery_path, gallery_url, base_url): widths = [360, 600, 1200, 1800, 2400] @@ -92,65 +58,6 @@ def add_image_sizes(tree, gallery_path, gallery_url, base_url): f.close() -def transform(wldoc, stylesheet='legacy', options=None, flags=None, css=None, gallery_path='img/', gallery_url='img/', base_url='file://./'): - """Transforms the WL document to XHTML. - - If output_filename is None, returns an XML, - otherwise returns True if file has been written,False if it hasn't. - File won't be written if it has no content. - """ - # Parse XSLT - try: - style_filename = get_stylesheet(stylesheet) - style = etree.parse(style_filename) - - document = copy.deepcopy(wldoc) - del wldoc - document.swap_endlines() - - if flags: - for flag in flags: - document.edoc.getroot().set(flag, 'yes') - - document.clean_ed_note() - document.clean_ed_note('abstrakt') - document.fix_pa_akap() - - if not options: - options = {} - - try: - os.makedirs(gallery_path) - except OSError: - pass - - add_image_sizes(document.edoc, gallery_path, gallery_url, base_url) - - css = ( - css - or 'https://static.wolnelektury.pl/css/compressed/book_text.css' - ) - css = "'%s'" % css - result = document.transform(style, css=css, **options) - del document # no longer needed large object :) - - if html_has_content(result): - add_anchors(result.getroot()) - add_table_of_themes(result.getroot()) - add_table_of_contents(result.getroot()) - - return OutputFile.from_bytes(etree.tostring( - result, method='html', xml_declaration=False, - pretty_print=True, encoding='utf-8' - )) - else: - return None - except KeyError: - raise ValueError("'%s' is not a valid stylesheet.") - except (XMLSyntaxError, XSLTApplyError) as e: - raise ParseError(e) - - class Fragment: def __init__(self, id, themes): super(Fragment, self).__init__() @@ -265,7 +172,7 @@ def extract_fragments(input_filename): else: # Omit annotation tags if (len(element.get('name', '')) or - element.get('class', '') in ('annotation', 'anchor')): + element.get('class', '') in ('annotation-anchor', 'anchor', 'wl-num', 'reference')): if event == 'end' and element.tail: for fragment_id in open_fragments: open_fragments[fragment_id].append( @@ -283,24 +190,16 @@ def extract_fragments(input_filename): return closed_fragments, open_fragments -def add_anchor(element, prefix, with_link=True, with_target=True, - link_text=None): +def add_anchor(element, prefix, link_text=None): parent = element.getparent() index = parent.index(element) - if with_link: - if link_text is None: - link_text = prefix - anchor = etree.Element('a', href='#%s' % prefix) - anchor.set('class', 'anchor') - anchor.text = str(link_text) - parent.insert(index, anchor) - - if with_target: - anchor_target = etree.Element('a', name='%s' % prefix) - anchor_target.set('class', 'target') - anchor_target.text = ' ' - parent.insert(index, anchor_target) + if link_text is None: + link_text = prefix + anchor = etree.Element('a', href='#%s' % prefix) + anchor.set('class', 'anchor') + anchor.text = str(link_text) + parent.insert(index, anchor) def any_ancestor(element, test): @@ -310,43 +209,9 @@ def any_ancestor(element, test): return False -def add_anchors(root): - counter = 1 - visible_counter = 1 - for element in root.iterdescendants(): - def f(e): - return ( - e.get('class') in ( - 'note', 'motto', 'motto_podpis', 'dedication', 'frame' - ) - or e.get('id') == 'nota_red' - or e.tag == 'blockquote' - or e.get('id') == 'footnotes' - ) - - if element.get('class') == 'numeracja': - try: - visible_counter = int(element.get('data-start')) - except ValueError: - visible_counter = 1 - - if any_ancestor(element, f): - continue - - if element.tag == 'div' and 'verse' in element.get('class', ''): - if visible_counter == 1 or visible_counter % 5 == 0: - add_anchor(element, "f%d" % counter, link_text=visible_counter) - counter += 1 - visible_counter += 1 - elif 'paragraph' in element.get('class', ''): - add_anchor(element, "f%d" % counter, link_text=visible_counter) - counter += 1 - visible_counter += 1 - - def raw_printable_text(element): working = copy.deepcopy(element) - for e in working.findall('a'): + for e in working.findall('.//a'): if e.get('class') in ('annotation', 'theme-begin'): e.text = '' return etree.tostring(working, method='text', encoding='unicode').strip() @@ -354,7 +219,6 @@ def raw_printable_text(element): def add_table_of_contents(root): sections = [] - counter = 1 for element in root.iterdescendants(): if element.tag in ('h2', 'h3'): if any_ancestor( @@ -368,12 +232,13 @@ def add_table_of_contents(root): if (element.tag == 'h3' and len(sections) and sections[-1][1] == 'h2'): sections[-1][3].append( - (counter, element.tag, element_text, []) + (element.attrib['id'], element.tag, element_text, []) ) else: - sections.append((counter, element.tag, element_text, [])) - add_anchor(element, "s%d" % counter, with_link=False) - counter += 1 + sections.append((element.attrib['id'], element.tag, element_text, [])) + + if not sections: + return toc = etree.Element('div') toc.set('id', 'toc') @@ -383,14 +248,14 @@ def add_table_of_contents(root): for n, section, text, subsections in sections: section_element = etree.SubElement(toc_list, 'li') - add_anchor(section_element, "s%d" % n, with_target=False, + add_anchor(section_element, n, link_text=text) if len(subsections): subsection_list = etree.SubElement(section_element, 'ol') for n1, subsection, subtext, _ in subsections: subsection_element = etree.SubElement(subsection_list, 'li') - add_anchor(subsection_element, "s%d" % n1, with_target=False, + add_anchor(subsection_element, n1, link_text=subtext) root.insert(0, toc) @@ -421,7 +286,13 @@ def add_table_of_themes(root): item = etree.SubElement(themes_li, 'a', href="#%s" % fragment) item.text = str(i + 1) item.tail = ' ' + + if not len(themes_ol): + return + root.insert(0, themes_div) + themes_div.tail = root.text + root.text = None def extract_annotations(html_path): @@ -458,8 +329,8 @@ def extract_annotations(html_path): candidate = candidate.strip() if candidate in FN_QUALIFIERS: qualifiers.append(candidate) - elif candidate.startswith('z '): - subcandidate = candidate.split()[1] + elif candidate.startswith('z\u00A0'): + subcandidate = candidate.split('\u00A0')[1].split()[0] if subcandidate in FN_QUALIFIERS: qualifiers.append(subcandidate) else: diff --git a/src/librarian/locale/pl/LC_MESSAGES/messages.po b/src/librarian/locale/pl/LC_MESSAGES/messages.po index c81c458..3c60fe2 100644 --- a/src/librarian/locale/pl/LC_MESSAGES/messages.po +++ b/src/librarian/locale/pl/LC_MESSAGES/messages.po @@ -17,26 +17,26 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.3\n" -#: src/librarian/builders/html.py:84 +#: src/librarian/builders/html.py:94 msgid "translated by" msgstr "tłum." -#: src/librarian/builders/html.py:104 +#: src/librarian/builders/html.py:118 msgid "Footnotes" msgstr "Przypisy" -#: src/librarian/elements/footnotes/__init__.py:55 +#: src/librarian/elements/footnotes/__init__.py:111 msgid "author's footnote" msgstr "przypis autorski" -#: src/librarian/elements/footnotes/__init__.py:63 +#: src/librarian/elements/footnotes/__init__.py:119 msgid "translator's footnote" msgstr "przypis tłumacza" -#: src/librarian/elements/footnotes/__init__.py:71 +#: src/librarian/elements/footnotes/__init__.py:127 msgid "editor's footnote" msgstr "przypis redakcyjny" -#: src/librarian/elements/footnotes/__init__.py:79 +#: src/librarian/elements/footnotes/__init__.py:135 msgid "source editor's footnote" msgstr "przypis edytorski" diff --git a/src/librarian/picture.py b/src/librarian/picture.py deleted file mode 100644 index 8b2c882..0000000 --- a/src/librarian/picture.py +++ /dev/null @@ -1,238 +0,0 @@ -# This file is part of Librarian, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Wolne Lektury. See NOTICE for more information. -# -from operator import and_ -import functools -import io -from .dcparser import Field, WorkInfo, DCNS -from librarian import (RDFNS, ValidationError, NoDublinCore, ParseError, WLURI) -from xml.parsers.expat import ExpatError -from os import path -from lxml import etree -from lxml.etree import (XMLSyntaxError, XSLTApplyError, Element) -import re - - -class WLPictureURI(WLURI): - _re_wl_uri = re.compile( - 'http://wolnelektury.pl/katalog/obraz/(?P[-a-z0-9]+)/?$' - ) - template = 'http://wolnelektury.pl/katalog/obraz/%s/' - - -def as_wlpictureuri_strict(text): - return WLPictureURI.strict(text) - - -class PictureInfo(WorkInfo): - """ - Dublin core metadata for a picture - """ - FIELDS = ( - Field(DCNS('language'), 'language', required=False), - Field(DCNS('subject.period'), 'epochs', salias='epoch', multiple=True), - Field(DCNS('subject.type'), 'kinds', salias='kind', multiple=True), - Field(DCNS('subject.genre'), 'genres', salias='genre', multiple=True, - required=False), - Field(DCNS('subject.style'), 'styles', salias='style', multiple=True, - required=False), - - Field(DCNS('format.dimensions'), 'dimensions', required=False), - Field(DCNS('format.checksum.sha1'), 'sha1', required=True), - Field(DCNS('description.medium'), 'medium', required=False), - Field(DCNS('description.dimensions'), 'original_dimensions', - required=False), - Field(DCNS('format'), 'mime_type', required=False), - Field(DCNS('identifier.url'), 'url', WLPictureURI, - strict=as_wlpictureuri_strict) - ) - - -class ImageStore: - EXT = ['gif', 'jpeg', 'png', 'swf', 'psd', 'bmp' - 'tiff', 'tiff', 'jpc', 'jp2', 'jpf', 'jb2', 'swc', - 'aiff', 'wbmp', 'xbm'] - MIME = ['image/gif', 'image/jpeg', 'image/png', - 'application/x-shockwave-flash', 'image/psd', 'image/bmp', - 'image/tiff', 'image/tiff', 'application/octet-stream', - 'image/jp2', 'application/octet-stream', - 'application/octet-stream', 'application/x-shockwave-flash', - 'image/iff', 'image/vnd.wap.wbmp', 'image/xbm'] - - def __init__(self, dir_): - super(ImageStore, self).__init__() - self.dir = dir_ - - def path(self, slug, mime_type): - """ - Finds file by slug and mime type in our iamge store. - Returns a file objects (perhaps should return a filename?) - """ - try: - i = self.MIME.index(mime_type) - except ValueError: - err = ValueError( - "Picture %s has unknown mime type: %s" - % (slug, mime_type) - ) - err.slug = slug - err.mime_type = mime_type - raise err - ext = self.EXT[i] - # add some common extensions tiff->tif, jpeg->jpg - return path.join(self.dir, slug + '.' + ext) - - -class WLPicture: - def __init__(self, edoc, parse_dublincore=True, image_store=None): - self.edoc = edoc - self.image_store = image_store - - root_elem = edoc.getroot() - - dc_path = './/' + RDFNS('RDF') - - if root_elem.tag != 'picture': - raise ValidationError( - "Invalid root element. Found '%s', should be 'picture'" - % root_elem.tag - ) - - if parse_dublincore: - self.rdf_elem = root_elem.find(dc_path) - - if self.rdf_elem is None: - raise NoDublinCore( - "Document has no DublinCore - which is required." - ) - - self.picture_info = PictureInfo.from_element(self.rdf_elem) - else: - self.picture_info = None - self.frame = None - - @classmethod - def from_bytes(cls, xml, *args, **kwargs): - return cls.from_file(io.BytesIO(xml), *args, **kwargs) - - @classmethod - def from_file(cls, xmlfile, parse_dublincore=True, image_store=None): - - # first, prepare for parsing - if isinstance(xmlfile, str): - file = open(xmlfile, 'rb') - try: - data = file.read() - finally: - file.close() - else: - data = xmlfile.read() - - if not isinstance(data, str): - data = data.decode('utf-8') - - data = data.replace('\ufeff', '') - - # assume images are in the same directory - if image_store is None and getattr(xmlfile, 'name', None): - image_store = ImageStore(path.dirname(xmlfile.name)) - - try: - parser = etree.XMLParser(remove_blank_text=False) - tree = etree.parse(io.BytesIO(data.encode('utf-8')), parser) - - me = cls(tree, parse_dublincore=parse_dublincore, - image_store=image_store) - me.load_frame_info() - return me - except (ExpatError, XMLSyntaxError, XSLTApplyError) as e: - raise ParseError(e) - - @property - def mime_type(self): - if self.picture_info is None: - raise ValueError( - "DC is not loaded, hence we don't know the image type." - ) - return self.picture_info.mime_type - - @property - def slug(self): - return self.picture_info.url.slug - - @property - def image_path(self): - if self.image_store is None: - raise ValueError("No image store associated with whis WLPicture.") - - return self.image_store.path(self.slug, self.mime_type) - - def image_file(self, *args, **kwargs): - return open(self.image_path, 'rb', *args, **kwargs) - - def get_sem_coords(self, sem): - area = sem.find("div[@type='rect']") - if area is None: - area = sem.find("div[@type='whole']") - return [[0, 0], [-1, -1]] - - def has_all_props(node, props): - return functools.reduce( - and_, map(lambda prop: prop in node.attrib, props) - ) - - if not has_all_props(area, ['x1', 'x2', 'y1', 'y2']): - return None - - def n(prop): return int(area.get(prop)) - return [[n('x1'), n('y1')], [n('x2'), n('y2')]] - - def partiter(self): - """ - Iterates the parts of this picture and returns them - and their metadata. - """ - # omg no support for //sem[(@type='theme') or (@type='object')] ? - for part in list(self.edoc.iterfind("//sem[@type='theme']")) +\ - list(self.edoc.iterfind("//sem[@type='object']")): - pd = {'type': part.get('type')} - - coords = self.get_sem_coords(part) - if coords is None: - continue - pd['coords'] = coords - - def want_unicode(x): - if not isinstance(x, str): - return x.decode('utf-8') - else: - return x - pd['object'] = ( - part.attrib['type'] == 'object' - and want_unicode(part.attrib.get('object', '')) - or None - ) - pd['themes'] = ( - part.attrib['type'] == 'theme' - and [part.attrib.get('theme', '')] - or [] - ) - yield pd - - def load_frame_info(self): - k = self.edoc.find("//sem[@object='kadr']") - - if k is not None: - clip = self.get_sem_coords(k) - self.frame = clip - frm = Element("sem", {"type": "frame"}) - frm.append(next(k.iter("div"))) - self.edoc.getroot().append(frm) - k.getparent().remove(k) - else: - frm = self.edoc.find("//sem[@type='frame']") - if frm: - self.frame = self.get_sem_coords(frm) - else: - self.frame = None - return self diff --git a/src/librarian/xslt/book2html.xslt b/src/librarian/xslt/book2html.xslt deleted file mode 100644 index b009345..0000000 --- a/src/librarian/xslt/book2html.xslt +++ /dev/null @@ -1,677 +0,0 @@ - - - - - - - - - - - - Książka z serwisu WolneLektury.pl - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
-

Przypisy

- -
- fn- - - [] - - -

- [przypis autorski] - [przypis tłumacza] - [przypis redakcyjny] - [przypis edytorski] -

-
- - -

- [przypis autorski] - [przypis tłumacza] - [przypis redakcyjny] - [przypis edytorski] -

-
-
-
-
-
-
-
-
- - - - - - - - - -

- - -

-
- -
- - - - - - - -
-
- - - -
-

-
    - -
-
-
- - -
-
- - -
-
- - -
- -
-
- - -
-
- - - -
- - -
-
- - - - - - -
- - - - ilustr - - - oblew - - - - - - - - - - - - (min-width: 718px) 600px, - (min-width: 600px) calc(100vw - 118px), - (min-width: 320px) calc(100vw - 75px), - (min-width: 15em) calc(100wv - 60px), - calc(100wv - 40px) - - - - - - - - - - - width: - - - - - -
-
-
- - -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - -

-
- - -
- - -
-
- - - -

- - -

-
- - -
- - -
-
- - - -

- - -

-
- - -
- - -
-
- - - - -

- - -

-
- - - -
- - -
-
- - -
  • -
    - - -

    - - - -

    -
    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - - - -
    - - verse - - - verse-p - - - verse-indent - - verse-indent- - - - - - verse-cont - - - verse-right - - - verse-center - - - - -
    -
    - - - -

    - - -

    -
    - - - - - - - - -
    -
    - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - [] - - - - - - - - - - - - - - - - - - - - - - - - - - „” - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - -

    *

    -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    - - - - - - tłum. - - , - - - - - - - - - - - - - - - -
    - - rownolegly-blok - - last - - - first - - - - border-left: 2px solid red; padding-left: .5em; - - border-radius: 0 0 0 .75em; - - - border-radius: .75em 0 0 0; - - - -
    -
    - - - - - - display: inline-block; width: em - - - display: inline-block; width: 1em - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wl- - - - - - - - - - - - - - -
    diff --git a/tests/files/picture/angelus-novus.jpeg b/tests/files/picture/angelus-novus.jpeg deleted file mode 100644 index fd0394fb342880b9fef27f1ad6d2055b06061ae2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23365 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 diff --git a/tests/files/picture/angelus-novus.xml b/tests/files/picture/angelus-novus.xml deleted file mode 100644 index 1e70828..0000000 --- a/tests/files/picture/angelus-novus.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - Klee, Paul - Angelus Novus - Fundacja Wolne Lektury - Sekuła, Aleksandra - Kwiatkowska, Katarzyna - Trzeciak, Weronika - Modernizm - Obraz - Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl). Reprodukcja cyfrowa wykonana przez Bibliotekę Narodową z egzemplarza pochodzącego ze zbiorów BN. - 31.8 × 24.2 cm - Akwarela na papierze - http://wolnelektury.pl/katalog/obraz/angelus-novus - http://katilifox.files.wordpress.com/2011/04/1190051611_angelus-novus.jpg - Muzeum Narodowe, inw. 00000000. - Domena publiczna - Paul Klee zm. 1940 - 1940 - Image - image/jpeg - 329 x 400 px - 5ed8e8d24d92017c6341c0b8cfcc414dec55b8bf - 1920 - lat - - - -
    - - -
    - - -
    - - -
    - - - - diff --git a/tests/files/tags/akap/1.expected.html b/tests/files/tags/akap/1.expected.html new file mode 100644 index 0000000..12fce96 --- /dev/null +++ b/tests/files/tags/akap/1.expected.html @@ -0,0 +1,7 @@ +
    +1

    Kali opowiedział, co zaszło, i ze słów jego pokazało się, że przyczyną wydarzenia była tylko zawziętość Fumby, gdy bowiem bitwa +już ustała, chciał jeszcze dobić dwóch Samburów i od jednego z nich otrzymał cios włócznią.

    +2

    Wiadomość rozbiegła się w mgnieniu oka między wszystkimi Wa-himami i naokół Kalego uczyniło się zbiegowisko. +W chwilę później sześciu wojowników przyniosło na włóczniach starego króla, który nie był zabity, ale ciężko ranny i przed śmiercią chciał +jeszcze zobaczyć potężnego, siedzącego na słoniu pana, prawdziwego zwycięzcę Samburu.

    +
    diff --git a/tests/files/tags/akap/1.xml b/tests/files/tags/akap/1.xml new file mode 100644 index 0000000..6cac9b6 --- /dev/null +++ b/tests/files/tags/akap/1.xml @@ -0,0 +1,6 @@ +Kali opowiedział, co zaszło, i ze słów jego pokazało się, że przyczyną wydarzenia była tylko zawziętość Fumby, gdy bowiem bitwa +już ustała, chciał jeszcze dobić dwóch Samburów i od jednego z nich otrzymał cios włócznią. + +Wiadomość rozbiegła się w mgnieniu oka między wszystkimi Wa-himami i naokół Kalego uczyniło się zbiegowisko. +W chwilę później sześciu wojowników przyniosło na włóczniach starego króla, który nie był zabity, ale ciężko ranny i przed śmiercią chciał +jeszcze zobaczyć potężnego, siedzącego na słoniu pana, prawdziwego zwycięzcę Samburu. diff --git a/tests/files/tags/akap_cd/1.expected.html b/tests/files/tags/akap_cd/1.expected.html new file mode 100644 index 0000000..00861ef --- /dev/null +++ b/tests/files/tags/akap_cd/1.expected.html @@ -0,0 +1,3 @@ +
    +1

    dalszy-ciąg-akapitu

    +
    diff --git a/tests/files/tags/akap_cd/1.xml b/tests/files/tags/akap_cd/1.xml new file mode 100644 index 0000000..2b818c4 --- /dev/null +++ b/tests/files/tags/akap_cd/1.xml @@ -0,0 +1 @@ + dalszy-ciąg-akapitu diff --git a/tests/files/tags/akap_dialog/1.expected.html b/tests/files/tags/akap_dialog/1.expected.html new file mode 100644 index 0000000..a8d3556 --- /dev/null +++ b/tests/files/tags/akap_dialog/1.expected.html @@ -0,0 +1,9 @@ +
    +1

    — Nel, potrafisz wyliczyć nasze podróże od Fajumu? — pytał Staś.

    +2

    — Potrafię.

    +3

    To mówiąc dziewczynka podniosła w górę brwi i zaczęła rachować na paluszkach.

    +4

    — Zaraz. Od Fajumu do Chartumu — to jedna; od Chartumu do Faszody — to druga; od Faszody do tego wąwozu, w którym znaleźliśmy +Kinga — to trzecia; a od Góry Lindego do jeziora — to czwarta.

    +5

    — Tak. Chyba nie ma na świecie drugiej muchy, która by przeleciała taki kawał Afryki.

    +6

    — Ładnie by ta mucha wyglądała bez ciebie!

    +
    diff --git a/tests/files/tags/akap_dialog/1.xml b/tests/files/tags/akap_dialog/1.xml new file mode 100644 index 0000000..5c05965 --- /dev/null +++ b/tests/files/tags/akap_dialog/1.xml @@ -0,0 +1,12 @@ +--- Nel, potrafisz wyliczyć nasze podróże od Fajumu? --- pytał Staś. + +--- Potrafię. + +To mówiąc dziewczynka podniosła w górę brwi i zaczęła rachować na paluszkach. + +--- Zaraz. Od Fajumu do Chartumu --- to jedna; od Chartumu do Faszody --- to druga; od Faszody do tego wąwozu, w którym znaleźliśmy +Kinga --- to trzecia; a od Góry Lindego do jeziora --- to czwarta. + +--- Tak. Chyba nie ma na świecie drugiej muchy, która by przeleciała taki kawał Afryki. + +--- Ładnie by ta mucha wyglądała bez ciebie! diff --git a/tests/files/tags/animacja/1.expected.html b/tests/files/tags/animacja/1.expected.html new file mode 100644 index 0000000..b38a92e --- /dev/null +++ b/tests/files/tags/animacja/1.expected.html @@ -0,0 +1,4 @@ +
    + Wieloryb + Kot +
    diff --git a/tests/files/tags/animacja/1.xml b/tests/files/tags/animacja/1.xml new file mode 100644 index 0000000..f97c6a0 --- /dev/null +++ b/tests/files/tags/animacja/1.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/files/tags/autor_utworu/1.expected.html b/tests/files/tags/autor_utworu/1.expected.html new file mode 100644 index 0000000..bd35ca0 --- /dev/null +++ b/tests/files/tags/autor_utworu/1.expected.html @@ -0,0 +1 @@ +

    Hans Christian Andersen

    diff --git a/tests/files/tags/autor_utworu/1.xml b/tests/files/tags/autor_utworu/1.xml new file mode 100644 index 0000000..d6a7534 --- /dev/null +++ b/tests/files/tags/autor_utworu/1.xml @@ -0,0 +1 @@ +Hans Christian Andersen diff --git a/tests/files/tags/base.xml b/tests/files/tags/base.xml new file mode 100644 index 0000000..cf6f61f --- /dev/null +++ b/tests/files/tags/base.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/files/tags/dedykacja/1.expected.html b/tests/files/tags/dedykacja/1.expected.html new file mode 100644 index 0000000..83995b5 --- /dev/null +++ b/tests/files/tags/dedykacja/1.expected.html @@ -0,0 +1,11 @@ +
    +

    +Władysław Stanisław ReymontChłopiCzęść pierwsza — Jesień +

    +
    +
    +1
    Miriamowi
    +
    (Zenonowi Przesmyckiemu)
    +
    +
    +
    diff --git a/tests/files/tags/dedykacja/1.xml b/tests/files/tags/dedykacja/1.xml new file mode 100644 index 0000000..c4a4da6 --- /dev/null +++ b/tests/files/tags/dedykacja/1.xml @@ -0,0 +1,10 @@ +Władysław Stanisław Reymont +Chłopi +Część pierwsza --- Jesień + + + +Miriamowi/ +(Zenonowi Przesmyckiemu) + + diff --git a/tests/files/tags/didask_tekst/1.expected.html b/tests/files/tags/didask_tekst/1.expected.html new file mode 100644 index 0000000..33b94f3 --- /dev/null +++ b/tests/files/tags/didask_tekst/1.expected.html @@ -0,0 +1,7 @@ +
    +1
    Oto, co może mówić kochające serce.
    +
    Do Filinta, który się śmieje
    +
    Och, śmiejcie się do syta, panowie szyderce,
    +
    A ja cenię to wyżej niż te sztuczne kwiatki,
    +5
    Te fałszywe brylanty waszej muzy gładkiej.
    +
    diff --git a/tests/files/tags/didask_tekst/1.xml b/tests/files/tags/didask_tekst/1.xml new file mode 100644 index 0000000..cdbb022 --- /dev/null +++ b/tests/files/tags/didask_tekst/1.xml @@ -0,0 +1,5 @@ +Oto, co może mówić kochające serce./ +Do Filinta, który się śmieje/ +Och, śmiejcie się do syta, panowie szyderce,/ +A ja cenię to wyżej niż te sztuczne kwiatki,/ +Te fałszywe brylanty waszej muzy gładkiej. diff --git a/tests/files/tags/didaskalia/1.expected.html b/tests/files/tags/didaskalia/1.expected.html new file mode 100644 index 0000000..efefbab --- /dev/null +++ b/tests/files/tags/didaskalia/1.expected.html @@ -0,0 +1,27 @@ +
    +

    CZEŚNIK

    +
    +
    obracając się ku niemu
    +
    +1
    Tu sęk właśnie!
    +Na toż bym się, mocium panie,
    Kawalerstwa dziś wyrzekał,
    +
    +
    uderzając w stół
    +
    +
    By kto... niech go piorun trzaśnie!
    +
    Długo będzie na to czekał,
    +
    +
    po krótkim milczeniu, biorąc talerz
    +
    +5
    Ma dochody wprawdzie znaczne —
    +
    Podstolina ma znaczniejsze;
    +
    Z wdówką zatem działać zacznę.
    +
    +
    po krótkim milczeniu
    +
    +
    Bawi z nami — w domu Klary,
    +
    Bo krewniaczka jej daleka,
    +10
    Ale mnie się wszystko zdaje...
    +
    +
    +
    diff --git a/tests/files/tags/didaskalia/1.xml b/tests/files/tags/didaskalia/1.xml new file mode 100644 index 0000000..466d912 --- /dev/null +++ b/tests/files/tags/didaskalia/1.xml @@ -0,0 +1,34 @@ +CZEŚNIK + + +obracając się ku niemu + + +Tu sęk właśnie! +Na toż bym się, mocium panie,/ +Kawalerstwa dziś wyrzekał, + + +uderzając w stół + + +By kto... niech go piorun trzaśnie!/ +Długo będzie na to czekał, + + +po krótkim milczeniu, biorąc talerz + + +Ma dochody wprawdzie znaczne ---/ +Podstolina ma znaczniejsze;/ +Z wdówką zatem działać zacznę. + + +po krótkim milczeniu + + +Bawi z nami --- w domu Klary,/ +Bo krewniaczka jej daleka,/ +Ale mnie się wszystko zdaje... + + diff --git a/tests/files/tags/dlugi_cytat/1.expected.html b/tests/files/tags/dlugi_cytat/1.expected.html new file mode 100644 index 0000000..6872c0b --- /dev/null +++ b/tests/files/tags/dlugi_cytat/1.expected.html @@ -0,0 +1,3 @@ +
    +1

    blok-akapitow-cytatu

    +
    diff --git a/tests/files/tags/dlugi_cytat/1.xml b/tests/files/tags/dlugi_cytat/1.xml new file mode 100644 index 0000000..1c38349 --- /dev/null +++ b/tests/files/tags/dlugi_cytat/1.xml @@ -0,0 +1 @@ + blok-akapitow-cytatu diff --git a/tests/files/tags/dzielo_nadrzedne/1.expected.html b/tests/files/tags/dzielo_nadrzedne/1.expected.html new file mode 100644 index 0000000..e1a18ac --- /dev/null +++ b/tests/files/tags/dzielo_nadrzedne/1.expected.html @@ -0,0 +1,3 @@ +

    +Bruno JasieńskiBut w butonierceDeszcz +

    diff --git a/tests/files/tags/dzielo_nadrzedne/1.xml b/tests/files/tags/dzielo_nadrzedne/1.xml new file mode 100644 index 0000000..6327806 --- /dev/null +++ b/tests/files/tags/dzielo_nadrzedne/1.xml @@ -0,0 +1,3 @@ +Bruno Jasieński +But w butonierce +Deszcz diff --git a/tests/files/tags/ilustr/1.expected.html b/tests/files/tags/ilustr/1.expected.html new file mode 100644 index 0000000..3b8fc76 --- /dev/null +++ b/tests/files/tags/ilustr/1.expected.html @@ -0,0 +1 @@ +
    Kot
    diff --git a/tests/files/tags/ilustr/1.xml b/tests/files/tags/ilustr/1.xml new file mode 100644 index 0000000..ec62695 --- /dev/null +++ b/tests/files/tags/ilustr/1.xml @@ -0,0 +1 @@ + diff --git a/tests/files/tags/indeks_dolny/1.expected.html b/tests/files/tags/indeks_dolny/1.expected.html new file mode 100644 index 0000000..a42c881 --- /dev/null +++ b/tests/files/tags/indeks_dolny/1.expected.html @@ -0,0 +1,3 @@ +
    +1

    H2O.

    +
    diff --git a/tests/files/tags/indeks_dolny/1.xml b/tests/files/tags/indeks_dolny/1.xml new file mode 100644 index 0000000..fd8a247 --- /dev/null +++ b/tests/files/tags/indeks_dolny/1.xml @@ -0,0 +1,3 @@ + + H2O. + diff --git a/tests/files/tags/kwestia/1.expected.html b/tests/files/tags/kwestia/1.expected.html new file mode 100644 index 0000000..2fe9773 --- /dev/null +++ b/tests/files/tags/kwestia/1.expected.html @@ -0,0 +1,15 @@ +
    +

    PUSTELNIK

    +
    +1
    Więc jako dawniej czynili mocarze,
    +
    Z Lechem się mieniał Scyta na obrączki;
    +
    A pokochawszy mocniej sercem, w darze
    +
    Dał mu koronę... stąd nasza korona.
    +5
    Zbawiciel niegdyś wyciągając rączki
    +
    Szedł do niej z matki zadumanej łona
    +
    I ku rubinom podawał się cały
    +
    Jako różyczka z liści wychylona,
    +
    I wołał: caca! i na brylant biały
    +10
    Różanych ustek perełkami świecił.
    +
    +
    diff --git a/tests/files/tags/kwestia/1.xml b/tests/files/tags/kwestia/1.xml new file mode 100644 index 0000000..a8fc460 --- /dev/null +++ b/tests/files/tags/kwestia/1.xml @@ -0,0 +1,16 @@ +PUSTELNIK + + + +Więc jako dawniej czynili mocarze,/ +Z Lechem się mieniał Scyta na obrączki;/ +A pokochawszy mocniej sercem, w darze/ +Dał mu koronę... stąd nasza korona./ +Zbawiciel niegdyś wyciągając rączki/ +Szedł do niej z matki zadumanej łona/ +I ku rubinom podawał się cały/ +Jako różyczka z liści wychylona,/ +I wołał: caca! i na brylant biały/ +Różanych ustek perełkami świecił. + + diff --git a/tests/files/tags/kwestia/2.expected.html b/tests/files/tags/kwestia/2.expected.html new file mode 100644 index 0000000..5783d97 --- /dev/null +++ b/tests/files/tags/kwestia/2.expected.html @@ -0,0 +1,11 @@ +
    +

    GŁOS HESI

    +
    +1

    Mamuńciu, tak zimno! troszkę ciepłej wody...

    +
    +

    DULSKA

    +
    +2

    Jeszcze czego? Hartujcie się... Felicjan! wstajesz? Wiesz? ten błazen, twój syn, nie wrócił jeszcze do domu! Co? nic nie mówisz? naturalnie. +Ojciec toleruje. Niedaleko padło jabłko od jabłoni. Ale jak będą dłużki małe — nie zapłacę.

    +
    +
    diff --git a/tests/files/tags/kwestia/2.xml b/tests/files/tags/kwestia/2.xml new file mode 100644 index 0000000..f4f053d --- /dev/null +++ b/tests/files/tags/kwestia/2.xml @@ -0,0 +1,16 @@ +GŁOS HESI + + + +Mamuńciu, tak zimno! troszkę ciepłej wody... + + + +DULSKA + + + +Jeszcze czego? Hartujcie się... Felicjan! wstajesz? Wiesz? ten błazen, twój syn, nie wrócił jeszcze do domu! Co? nic nie mówisz? naturalnie. +Ojciec toleruje. Niedaleko padło jabłko od jabłoni. Ale jak będą dłużki małe --- nie zapłacę. + + diff --git a/tests/files/tags/lista_osob/1.expected.html b/tests/files/tags/lista_osob/1.expected.html new file mode 100644 index 0000000..01617a4 --- /dev/null +++ b/tests/files/tags/lista_osob/1.expected.html @@ -0,0 +1,21 @@ +
    +

    +SofoklesAntygona +

    +
    +

    OSOBY DRAMATU

    +
      +
    1. ANTYGONA, córka Edypa
    2. +
    3. ISMENA, jej siostra
    4. +
    5. CHÓR TEBANSKICH STARCÓW
    6. +
    7. KREON, król Teb
    8. +
    9. STRAŻNIK
    10. +
    11. HAJMON, syn Kreona
    12. +
    13. TYREZJASZ, wróżbita
    14. +
    15. POSŁANIEC.
    16. +
    17. EURYDYKA, żona Kreona
    18. +
    19. POSŁANIEC drugi
    20. +
    +
    +

    Rzecz dzieje się przed dworcem królewskim w Tebach

    +
    diff --git a/tests/files/tags/lista_osob/1.xml b/tests/files/tags/lista_osob/1.xml new file mode 100644 index 0000000..c6f4e24 --- /dev/null +++ b/tests/files/tags/lista_osob/1.xml @@ -0,0 +1,21 @@ +Sofokles +Antygona + + + +OSOBY DRAMATU + +ANTYGONA, córka Edypa +ISMENA, jej siostra +CHÓR TEBANSKICH STARCÓW +KREON, król Teb +STRAŻNIK +HAJMON, syn Kreona +TYREZJASZ, wróżbita +POSŁANIEC. +EURYDYKA, żona Kreona +POSŁANIEC drugi + + + +Rzecz dzieje się przed dworcem królewskim w Tebach diff --git a/tests/files/tags/mat/1.expected.html b/tests/files/tags/mat/1.expected.html new file mode 100644 index 0000000..1a9163a --- /dev/null +++ b/tests/files/tags/mat/1.expected.html @@ -0,0 +1,42 @@ +
    +1

    Oznaczmy odległość tych miejsc przez δ, + dalej odległość kliszy od kondensatora przez h, + długość płyt metalowych kondensatora przez l, + natężenie pola elektryczności przez F, + masę elektronu przez m, + jego ładunek przez e, + a prędkość przez v. + Możemy wyprowadzić wzór następujący + + δ + = + + + e + ⁢ + F + ⁢ + l + × + + + l + 2 + + + + h + + + + + m + ⁢ + + v + 2 + + + + +

    +
    diff --git a/tests/files/tags/mat/1.xml b/tests/files/tags/mat/1.xml new file mode 100644 index 0000000..8c60418 --- /dev/null +++ b/tests/files/tags/mat/1.xml @@ -0,0 +1,41 @@ + + Oznaczmy odległość tych miejsc przez δ, + dalej odległość kliszy od kondensatora przez h, + długość płyt metalowych kondensatora przez l, + natężenie pola elektryczności przez F, + masę elektronu przez m, + jego ładunek przez e, + a prędkość przez v. + Możemy wyprowadzić wzór następujący + + δ + = + + + e + ⁢ + F + ⁢ + l + × + + + l + 2 + + + + h + + + + + m + ⁢ + + v + 2 + + + + + diff --git a/tests/files/tags/motto/1.expected.html b/tests/files/tags/motto/1.expected.html new file mode 100644 index 0000000..6f71f42 --- /dev/null +++ b/tests/files/tags/motto/1.expected.html @@ -0,0 +1,11 @@ +
    +

    +Aleksander FredroZemsta +

    +
    +1

    Nie masz nic tak złego, żeby się na dobre nie przydało. Bywa z węża dryjakiew, złe często dobremu okazyją daje.

    +
    +

    +And. Maks. Fredro +

    +
    diff --git a/tests/files/tags/motto/1.xml b/tests/files/tags/motto/1.xml new file mode 100644 index 0000000..e3aec09 --- /dev/null +++ b/tests/files/tags/motto/1.xml @@ -0,0 +1,10 @@ +Aleksander Fredro +Zemsta + + +Nie masz nic tak złego, żeby się na dobre nie przydało. Bywa z węża dryjakiew, złe często dobremu okazyją daje. + + + +And. Maks. Fredro + diff --git a/tests/files/tags/motto_podpis/1.expected.html b/tests/files/tags/motto_podpis/1.expected.html new file mode 100644 index 0000000..1ff589b --- /dev/null +++ b/tests/files/tags/motto_podpis/1.expected.html @@ -0,0 +1,13 @@ +
    +

    +Adam MickiewiczKonrad WallenrodPowieść historyczna(Z dziejów litewskich i pruskich) +

    +
    +
    +1
    Dovete adunque sapere come sono/ +due generazioni da combattere...../ +bisogna essere volpe e leone.
    +
    +
    +

    MACCHIAVELLI

    +
    diff --git a/tests/files/tags/motto_podpis/1.xml b/tests/files/tags/motto_podpis/1.xml new file mode 100644 index 0000000..709b324 --- /dev/null +++ b/tests/files/tags/motto_podpis/1.xml @@ -0,0 +1,14 @@ +Adam Mickiewicz +Konrad Wallenrod +Powieść historyczna +(Z dziejów litewskich i pruskich) + + + +Dovete adunque sapere come sono/ +due generazioni da combattere...../ +bisogna essere volpe e leone. + + + +MACCHIAVELLI diff --git a/tests/files/tags/naglowek_akt/1.expected.html b/tests/files/tags/naglowek_akt/1.expected.html new file mode 100644 index 0000000..f5c0f26 --- /dev/null +++ b/tests/files/tags/naglowek_akt/1.expected.html @@ -0,0 +1,12 @@ +
    +
    +

    Spis treści

    +
      +AKT PIERWSZY
      1. +SCENA PIERWSZA
      2. +
    1. +
    +
    +

    AKT PIERWSZY

    +

    SCENA PIERWSZA

    +
    diff --git a/tests/files/tags/naglowek_akt/1.xml b/tests/files/tags/naglowek_akt/1.xml new file mode 100644 index 0000000..85d24ec --- /dev/null +++ b/tests/files/tags/naglowek_akt/1.xml @@ -0,0 +1,4 @@ +AKT PIERWSZY + +Pokój w zamku Cześnika, drzwi na prawo, lewo i w środku, stoły, krzesła etc., gitara angielska na ścianie. +SCENA PIERWSZA diff --git a/tests/files/tags/naglowek_czesc/1.expected.html b/tests/files/tags/naglowek_czesc/1.expected.html new file mode 100644 index 0000000..d59489e --- /dev/null +++ b/tests/files/tags/naglowek_czesc/1.expected.html @@ -0,0 +1,22 @@ +
    +
    +

    Spis treści

    +
      +PIEŚŃ I
    1. +
    +
    +

    +Juliusz SłowackiBeniowski +

    +

    PIEŚŃ I

    +
    +1
    Za panowania króla Stanisława
    +
    Mieszkał ubogi szlachcic na Podolu,
    +
    Wysoko potem go wyniosła sława;
    +
    Szczęścia miał mało w życiu, więcej bolu;
    +5
    Albowiem była to epoka krwawa,
    +
    I kraj był cały na rumaku, w polu;
    +
    Łany, ogrody leżały odłogiem,
    +
    Zaraza stała u domu za progiem.
    +
    +
    diff --git a/tests/files/tags/naglowek_czesc/1.xml b/tests/files/tags/naglowek_czesc/1.xml new file mode 100644 index 0000000..3859aad --- /dev/null +++ b/tests/files/tags/naglowek_czesc/1.xml @@ -0,0 +1,15 @@ +Juliusz Słowacki +Beniowski + +PIEŚŃ I + + +Za panowania króla Stanisława/ +Mieszkał ubogi szlachcic na Podolu,/ +Wysoko potem go wyniosła sława;/ +Szczęścia miał mało w życiu, więcej bolu;/ +Albowiem była to epoka krwawa,/ +I kraj był cały na rumaku, w polu;/ +Łany, ogrody leżały odłogiem,/ +Zaraza stała u domu za progiem. + diff --git a/tests/files/tags/naglowek_osoba/1.expected.html b/tests/files/tags/naglowek_osoba/1.expected.html new file mode 100644 index 0000000..4903bb3 --- /dev/null +++ b/tests/files/tags/naglowek_osoba/1.expected.html @@ -0,0 +1,13 @@ +
    +

    CZEŚNIK

    +
    +
    jakby do siebie
    +
    +1
    Piękne dobra w każdym względzie —
    +
    Lasy — gleba wyśmienita —
    +
    Dobrą żoną pewnie będzie —
    +
    Co za czynsze! — To kobiéta!...
    +5
    Trzy folwarki!
    +
    +
    +
    diff --git a/tests/files/tags/naglowek_osoba/1.xml b/tests/files/tags/naglowek_osoba/1.xml new file mode 100644 index 0000000..2aa172a --- /dev/null +++ b/tests/files/tags/naglowek_osoba/1.xml @@ -0,0 +1,12 @@ +CZEŚNIK + + +jakby do siebie + +Piękne dobra w każdym względzie ---/ +Lasy --- gleba wyśmienita ---/ +Dobrą żoną pewnie będzie ---/ +Co za czynsze! --- To kobiéta!.../ +Trzy folwarki! +... + diff --git a/tests/files/tags/naglowek_podrozdzial/1.expected.html b/tests/files/tags/naglowek_podrozdzial/1.expected.html new file mode 100644 index 0000000..1194ffb --- /dev/null +++ b/tests/files/tags/naglowek_podrozdzial/1.expected.html @@ -0,0 +1 @@ +

    numer-i/lub-tytuł-podrozdziału

    diff --git a/tests/files/tags/naglowek_podrozdzial/1.xml b/tests/files/tags/naglowek_podrozdzial/1.xml new file mode 100644 index 0000000..f0e14fd --- /dev/null +++ b/tests/files/tags/naglowek_podrozdzial/1.xml @@ -0,0 +1 @@ + numer-i/lub-tytuł-podrozdziału diff --git a/tests/files/tags/naglowek_rozdzial/1.expected.html b/tests/files/tags/naglowek_rozdzial/1.expected.html new file mode 100644 index 0000000..578edc1 --- /dev/null +++ b/tests/files/tags/naglowek_rozdzial/1.expected.html @@ -0,0 +1,12 @@ +
    + +

    +Bolesław PrusLalkaTom pierwszy +

    +

    I. Jak wygląda firma J. Mincel i S. Wokulski przez szkło butelek?

    +
    diff --git a/tests/files/tags/naglowek_rozdzial/1.xml b/tests/files/tags/naglowek_rozdzial/1.xml new file mode 100644 index 0000000..4ee02e5 --- /dev/null +++ b/tests/files/tags/naglowek_rozdzial/1.xml @@ -0,0 +1,6 @@ +Bolesław Prus +Lalka +Tom pierwszy + +I. Jak wygląda firma J. Mincel i S. Wokulski przez szkło butelek? + diff --git a/tests/files/tags/nazwa_utworu/1.expected.html b/tests/files/tags/nazwa_utworu/1.expected.html new file mode 100644 index 0000000..b89798a --- /dev/null +++ b/tests/files/tags/nazwa_utworu/1.expected.html @@ -0,0 +1 @@ +

    Anioł

    diff --git a/tests/files/tags/nazwa_utworu/1.xml b/tests/files/tags/nazwa_utworu/1.xml new file mode 100644 index 0000000..0627acf --- /dev/null +++ b/tests/files/tags/nazwa_utworu/1.xml @@ -0,0 +1 @@ +Anioł diff --git a/tests/files/tags/nota/1.expected.html b/tests/files/tags/nota/1.expected.html new file mode 100644 index 0000000..e68a4bc --- /dev/null +++ b/tests/files/tags/nota/1.expected.html @@ -0,0 +1,7 @@ +
    +

    +Henryk SienkiewiczLatarnik +

    +

    Opowiadanie to osnute jest na wypadku rzeczywistym, o którym w swoim czasie pisał J. Horain + w jednej ze swoich korespondencyj z Ameryki.

    +
    diff --git a/tests/files/tags/nota/1.xml b/tests/files/tags/nota/1.xml new file mode 100644 index 0000000..57991c6 --- /dev/null +++ b/tests/files/tags/nota/1.xml @@ -0,0 +1,5 @@ +Henryk Sienkiewicz +Latarnik + +Opowiadanie to osnute jest na wypadku rzeczywistym, o którym w swoim czasie pisał J. Horain + w jednej ze swoich korespondencyj z Ameryki. diff --git a/tests/files/tags/nota/2.expected.html b/tests/files/tags/nota/2.expected.html new file mode 100644 index 0000000..6006ef6 --- /dev/null +++ b/tests/files/tags/nota/2.expected.html @@ -0,0 +1,18 @@ +
    +
    +

    Spis treści

    +
      +III
    1. +
    +
    +

    III

    +
    +1
    Każdego z takich, jak ty, świat nie może
    +
    Od razu przyjąć na spokojne łoże,
    +
    I nie przyjmował nigdy, jak wiek wiekiem.
    +
    Bo glina w glinę wtapia się bez przerwy,
    +5
    Gdy sprzeczne ciała zbija się aż ćwiekiem
    +
    Później... lub pierwéj...
    +
    +

    Pisałem w Paryżu 1856 w styczniu.

    +
    diff --git a/tests/files/tags/nota/2.xml b/tests/files/tags/nota/2.xml new file mode 100644 index 0000000..efa9504 --- /dev/null +++ b/tests/files/tags/nota/2.xml @@ -0,0 +1,14 @@ + + +III + + +Każdego z takich, jak ty, świat nie może/ +Od razu przyjąć na spokojne łoże,/ +I nie przyjmował nigdy, jak wiek wiekiem./ +Bo glina w glinę wtapia się bez przerwy,/ +Gdy sprzeczne ciała zbija się aż ćwiekiem/ +Później... lub pierwéj... + + +Pisałem w Paryżu 1856 w styczniu. diff --git a/tests/files/tags/nota/3.expected.html b/tests/files/tags/nota/3.expected.html new file mode 100644 index 0000000..b7d62b4 --- /dev/null +++ b/tests/files/tags/nota/3.expected.html @@ -0,0 +1,8 @@ +
    +1

    Jego marzenie się nie spełniło: nie ożenił się, choć był już na to zupełnie zdecydowany, +gdy skończono oporządzać jego mieszkanie. [...] Rzecz dziwna, czym jest mundur dla takich ludzi.

    +

    Uwaga tłumacza. Drukowane obecnie w „Nowej Reformie” +Wspomnienia Sybiraka (pamiętniki Józefa Bogusławskiego) pozwalają +szczęśliwym trafem podać w całości nazwiska Polaków, o których mówi Dostojewski w swoich pamiętnikach, +oznaczając te nazwiska tylko pierwszymi literami, z dodaniem czasami końcówek. [...]

    +
    diff --git a/tests/files/tags/nota/3.xml b/tests/files/tags/nota/3.xml new file mode 100644 index 0000000..92e7980 --- /dev/null +++ b/tests/files/tags/nota/3.xml @@ -0,0 +1,9 @@ + + +Jego marzenie się nie spełniło: nie ożenił się, choć był już na to zupełnie zdecydowany, +gdy skończono oporządzać jego mieszkanie. [...] Rzecz dziwna, czym jest mundur dla takich ludzi. + +Uwaga tłumacza. Drukowane obecnie w ,,Nowej Reformie" +Wspomnienia Sybiraka (pamiętniki Józefa Bogusławskiego) pozwalają +szczęśliwym trafem podać w całości nazwiska Polaków, o których mówi Dostojewski w swoich pamiętnikach, +oznaczając te nazwiska tylko pierwszymi literami, z dodaniem czasami końcówek. [...] diff --git a/tests/files/tags/nota/4.expected.html b/tests/files/tags/nota/4.expected.html new file mode 100644 index 0000000..ec32394 --- /dev/null +++ b/tests/files/tags/nota/4.expected.html @@ -0,0 +1,12 @@ +
    +
    +

    Spis treści

    +
      +Gospodarstwo
    1. +
    +
    +

    Gospodarstwo

    +

    Powrót panicza — Spotkanie się pierwsze w pokoiku, drugie u stołu — Ważna Sędziego +nauka o grzeczności — Podkomorzego uwagi polityczne nad modami — Początek sporu o Kusego i Sokoła +— Żale Wojskiego — Ostatni Woźny Trybunału — Rzut oka na ówczesny stan polityczny Litwy i Europy

    +
    diff --git a/tests/files/tags/nota/4.xml b/tests/files/tags/nota/4.xml new file mode 100644 index 0000000..56ab06f --- /dev/null +++ b/tests/files/tags/nota/4.xml @@ -0,0 +1,7 @@ + + +Gospodarstwo + +Powrót panicza --- Spotkanie się pierwsze w pokoiku, drugie u stołu --- Ważna Sędziego +nauka o grzeczności --- Podkomorzego uwagi polityczne nad modami --- Początek sporu o Kusego i Sokoła +--- Żale Wojskiego --- Ostatni Woźny Trybunału --- Rzut oka na ówczesny stan polityczny Litwy i Europy diff --git a/tests/files/tags/nota/5.expected.html b/tests/files/tags/nota/5.expected.html new file mode 100644 index 0000000..dadf5f6 --- /dev/null +++ b/tests/files/tags/nota/5.expected.html @@ -0,0 +1,5 @@ +
    +

    II

    +

    Moje wypadki • Ognisko w wąwozie • Uczta • Opowiadania skwatera • Nocleg • Głosy nocne +• Niespokojne sny • Ranek • Polowanie z zasadzki • Pierwszy jeleń

    +
    diff --git a/tests/files/tags/nota/5.xml b/tests/files/tags/nota/5.xml new file mode 100644 index 0000000..94747d3 --- /dev/null +++ b/tests/files/tags/nota/5.xml @@ -0,0 +1,4 @@ +II + +Moje wypadki • Ognisko w wąwozie • Uczta • Opowiadania skwatera • Nocleg • Głosy nocne +• Niespokojne sny • Ranek • Polowanie z zasadzki • Pierwszy jeleń diff --git a/tests/files/tags/nota/6.expected.html b/tests/files/tags/nota/6.expected.html new file mode 100644 index 0000000..b0465e4 --- /dev/null +++ b/tests/files/tags/nota/6.expected.html @@ -0,0 +1,8 @@ +
    +1

    Oto rozdziały dwudziesty piąty, szósty i siódmy przygotowują nadchodzącą chwilę.

    +

    Idea dobra zaczyna świecić

    +2

    Już Arystofanes tłumaczy Erosa, który dwie płci wiąże, stwarzając mit, dając koncepcję +„dążenia do jedności”. Dopiero teraz popęd płciowy wystąpi w jasnym, boskim świetle, jako +nieświadome dążenie do nieśmiertelności. Pokaże się, że istoty żywe dlatego tylko zapłodnienia +pragną, że zapłodnienie uczestniczy jakoś w wielkiej idei „nieśmiertelnego dobra”.

    +
    diff --git a/tests/files/tags/nota/6.xml b/tests/files/tags/nota/6.xml new file mode 100644 index 0000000..63c88ae --- /dev/null +++ b/tests/files/tags/nota/6.xml @@ -0,0 +1,9 @@ + + +Oto rozdziały dwudziesty piąty, szósty i siódmy przygotowują nadchodzącą chwilę. + +Idea dobra zaczyna świecić +Już Arystofanes tłumaczy Erosa, który dwie płci wiąże, stwarzając mit, dając koncepcję +,,dążenia do jedności". Dopiero teraz popęd płciowy wystąpi w jasnym, boskim świetle, jako +nieświadome dążenie do nieśmiertelności. Pokaże się, że istoty żywe dlatego tylko zapłodnienia +pragną, że zapłodnienie uczestniczy jakoś w wielkiej idei ,,nieśmiertelnego dobra". diff --git a/tests/files/tags/numeracja/1.expected.html b/tests/files/tags/numeracja/1.expected.html new file mode 100644 index 0000000..7ae68bb --- /dev/null +++ b/tests/files/tags/numeracja/1.expected.html @@ -0,0 +1,30 @@ +
    +
    +1
    Jednych tam śmierć porwała kres życiu znacząca,
    +
    Drugim z dala od ludzi Zeus życie rozkoszy
    +
    Dał pełne i umieścił ich u ziemi końca,
    +
    Gdzie żadna troska w sercu spokoju nie płoszy,
    +5
    W Krainie Szczęścia nad pienistym Oceanem,
    +100
    Z dala od bogów; Kronos jest nad nimi panem,
    +
    [Zwolniony z pęt przez bogów i ludzi rodzica.
    +
    Zeus im udzielił wielkiej czci, chwałą zaszczyca
    +
    I wyniósł ich jak żadne w porównaniu z niemi
    +
    Plemię z tych, które żyły na wszechpłodnej ziemi.]
    +105
    Cni bohaterzy! Trzykroć w roku owoc wszelki,
    +
    Jak miód słodki, od ziemi biorą żywicielki.
    +
    +
    +
    Gdy masz przejść w bród przez piękne fale wiecznej rzeki,
    +
    Módl się wprzód, umyj ręce i spójrz w prąd daleki.
    +740
    Tym, co wchodzą do rzeki, nie mocząc rąk, prości,
    +
    Bogowie odpłacają cierpieniem w przyszłości.
    +
    Gdy bogom uroczyste obiaty się palą,
    +
    +
    +1
    Pilnie strzeż się na bliźnich mieść potwarzy brzemię.
    +
    Mały zachód, trud lekki popuścić jej wodze,
    +
    Lecz ciężko dźwigać, trudno ją zrzucić na ziemię.
    +
    Nigdy potwarz, jeżeli ją uprawia mnóstwo,
    +5
    Nie ginie całkiem; to też w swym rodzaju bóstwo.
    +
    +
    diff --git a/tests/files/tags/numeracja/1.xml b/tests/files/tags/numeracja/1.xml new file mode 100644 index 0000000..14d29c4 --- /dev/null +++ b/tests/files/tags/numeracja/1.xml @@ -0,0 +1,32 @@ + +Jednych tam śmierć porwała kres życiu znacząca,/ +Drugim z dala od ludzi Zeus życie rozkoszy/ +Dał pełne i umieścił ich u ziemi końca,/ +Gdzie żadna troska w sercu spokoju nie płoszy,/ +W Krainie Szczęścia nad pienistym Oceanem,/ +Z dala od bogów; Kronos jest nad nimi panem,/ +[Zwolniony z pęt przez bogów i ludzi rodzica./ +Zeus im udzielił wielkiej czci, chwałą zaszczyca/ +I wyniósł ich jak żadne w porównaniu z niemi/ +Plemię z tych, które żyły na wszechpłodnej ziemi.]/ +Cni bohaterzy! Trzykroć w roku owoc wszelki,/ +Jak miód słodki, od ziemi biorą żywicielki. + + + + + +Gdy masz przejść w bród przez piękne fale wiecznej rzeki,/ +Módl się wprzód, umyj ręce i spójrz w prąd daleki./ +Tym, co wchodzą do rzeki, nie mocząc rąk, prości,/ +Bogowie odpłacają cierpieniem w przyszłości./ +Gdy bogom uroczyste obiaty się palą, + + + + +Pilnie strzeż się na bliźnich mieść potwarzy brzemię./ +Mały zachód, trud lekki popuścić jej wodze,/ +Lecz ciężko dźwigać, trudno ją zrzucić na ziemię./ +Nigdy potwarz, jeżeli ją uprawia mnóstwo,/ +Nie ginie całkiem; to też w swym rodzaju bóstwo. diff --git a/tests/files/tags/osoba/1.expected.html b/tests/files/tags/osoba/1.expected.html new file mode 100644 index 0000000..50a9b9c --- /dev/null +++ b/tests/files/tags/osoba/1.expected.html @@ -0,0 +1,23 @@ +
    +
    +

    Spis treści

    +
      +AKT PIERWSZY
      1. +SCENA PIERWSZA
      2. +
    1. +
    +
    +

    AKT PIERWSZY

    +
    +Pokój w zamku +Cześnika, +drzwi na prawo, lewo i w środku, stoły, krzesła etc., gitara angielska na ścianie. +
    +

    SCENA PIERWSZA

    +
    + +Cześnik, +Dyndalski + +
    +
    diff --git a/tests/files/tags/osoba/1.xml b/tests/files/tags/osoba/1.xml new file mode 100644 index 0000000..98bf0e0 --- /dev/null +++ b/tests/files/tags/osoba/1.xml @@ -0,0 +1,16 @@ +AKT PIERWSZY + + +Pokój w zamku +Cześnika, +drzwi na prawo, lewo i w środku, stoły, krzesła etc., gitara angielska na ścianie. + + +SCENA PIERWSZA + + + +Cześnik, +Dyndalski + + diff --git a/tests/files/tags/pa/1.expected.html b/tests/files/tags/pa/1.expected.html new file mode 100644 index 0000000..f74cb3f --- /dev/null +++ b/tests/files/tags/pa/1.expected.html @@ -0,0 +1,9 @@ +
    +1

    Bieży[1].

    +
    +

    Przypisy

    +
    +[1]

    bieży — biegnie. [przypis autorski]

    +
    +
    +
    diff --git a/tests/files/tags/pa/1.xml b/tests/files/tags/pa/1.xml new file mode 100644 index 0000000..ebe4b29 --- /dev/null +++ b/tests/files/tags/pa/1.xml @@ -0,0 +1,3 @@ + + Bieżybieży --- biegnie.. + diff --git a/tests/files/tags/pe/1.expected.html b/tests/files/tags/pe/1.expected.html new file mode 100644 index 0000000..777d900 --- /dev/null +++ b/tests/files/tags/pe/1.expected.html @@ -0,0 +1,9 @@ +
    +1

    Bieży[1].

    +
    +

    Przypisy

    +
    +[1]

    bieży — biegnie. [przypis edytorski]

    +
    +
    +
    diff --git a/tests/files/tags/pe/1.xml b/tests/files/tags/pe/1.xml new file mode 100644 index 0000000..f28f30e --- /dev/null +++ b/tests/files/tags/pe/1.xml @@ -0,0 +1,3 @@ + + Bieżybieży --- biegnie.. + diff --git a/tests/files/tags/pe/2.expected.html b/tests/files/tags/pe/2.expected.html new file mode 100644 index 0000000..e30725e --- /dev/null +++ b/tests/files/tags/pe/2.expected.html @@ -0,0 +1,12 @@ +
    +1

    Bieży[1].

    +
    +

    Przypisy

    +
    +[1]

    +

    bieży — biegnie.

    +

    Drugi akapit przypisu.

    + [przypis edytorski]

    +
    +
    +
    diff --git a/tests/files/tags/pe/2.xml b/tests/files/tags/pe/2.xml new file mode 100644 index 0000000..ab00e06 --- /dev/null +++ b/tests/files/tags/pe/2.xml @@ -0,0 +1,6 @@ + + Bieży + bieży --- biegnie. + Drugi akapit przypisu. + . + diff --git a/tests/files/tags/podtytul/1.expected.html b/tests/files/tags/podtytul/1.expected.html new file mode 100644 index 0000000..2fdf222 --- /dev/null +++ b/tests/files/tags/podtytul/1.expected.html @@ -0,0 +1,3 @@ +

    +Daniel DefoeRobinson CrusoeJego życia losy, doświadczenia i przypadki +

    diff --git a/tests/files/tags/podtytul/1.xml b/tests/files/tags/podtytul/1.xml new file mode 100644 index 0000000..55415f3 --- /dev/null +++ b/tests/files/tags/podtytul/1.xml @@ -0,0 +1,4 @@ +Daniel Defoe +Robinson Crusoe + +Jego życia losy, doświadczenia i przypadki diff --git a/tests/files/tags/poezja_cyt/1.expected.html b/tests/files/tags/poezja_cyt/1.expected.html new file mode 100644 index 0000000..b0d195b --- /dev/null +++ b/tests/files/tags/poezja_cyt/1.expected.html @@ -0,0 +1,4 @@ +
    +1
    Tymczasem przenoś duszę moją utęsknioną
    +
    Do tych pagórków leśnych, do tych łąk zielonych...
    +
    diff --git a/tests/files/tags/poezja_cyt/1.xml b/tests/files/tags/poezja_cyt/1.xml new file mode 100644 index 0000000..e003954 --- /dev/null +++ b/tests/files/tags/poezja_cyt/1.xml @@ -0,0 +1,6 @@ + + +Tymczasem przenoś duszę moją utęsknioną/ +Do tych pagórków leśnych, do tych łąk zielonych... + + diff --git a/tests/files/tags/pr/1.expected.html b/tests/files/tags/pr/1.expected.html new file mode 100644 index 0000000..72ec98a --- /dev/null +++ b/tests/files/tags/pr/1.expected.html @@ -0,0 +1,9 @@ +
    +1

    Bieży[1].

    +
    +

    Przypisy

    +
    +[1]

    bieży — biegnie. [przypis redakcyjny]

    +
    +
    +
    diff --git a/tests/files/tags/pr/1.xml b/tests/files/tags/pr/1.xml new file mode 100644 index 0000000..f111c8b --- /dev/null +++ b/tests/files/tags/pr/1.xml @@ -0,0 +1,3 @@ + + Bieżybieży --- biegnie.. + diff --git a/tests/files/tags/pt/1.expected.html b/tests/files/tags/pt/1.expected.html new file mode 100644 index 0000000..0cbd428 --- /dev/null +++ b/tests/files/tags/pt/1.expected.html @@ -0,0 +1,9 @@ +
    +1

    Bieży[1].

    +
    +

    Przypisy

    +
    +[1]

    bieży — biegnie. [przypis tłumacza]

    +
    +
    +
    diff --git a/tests/files/tags/pt/1.xml b/tests/files/tags/pt/1.xml new file mode 100644 index 0000000..c832b38 --- /dev/null +++ b/tests/files/tags/pt/1.xml @@ -0,0 +1,3 @@ + + Bieżybieży --- biegnie.. + diff --git a/tests/files/tags/ref/1.expected.html b/tests/files/tags/ref/1.expected.html new file mode 100644 index 0000000..85c374a --- /dev/null +++ b/tests/files/tags/ref/1.expected.html @@ -0,0 +1,3 @@ +
    +1

    W roku 1872 dom pod numerem 7 przy Saville Row, Burlington Gardens, w którym w roku 1814 zmarł Sheridan, był zamieszkany przez Phileasa Fogga, członka londyńskiego klubu „Reforma”, osobistość wybitną i wielce oryginalną.

    +
    diff --git a/tests/files/tags/ref/1.xml b/tests/files/tags/ref/1.xml new file mode 100644 index 0000000..6d46efe --- /dev/null +++ b/tests/files/tags/ref/1.xml @@ -0,0 +1 @@ +W roku 1872 dom pod numerem 7 przy Saville Row, Burlington Gardens, w którym w roku 1814 zmarł Sheridan, był zamieszkany przez Phileasa Fogga, członka londyńskiego klubu ,,Reforma", osobistość wybitną i wielce oryginalną. diff --git a/tests/files/tags/rownolegle/1.expected.html b/tests/files/tags/rownolegle/1.expected.html new file mode 100644 index 0000000..36d9021 --- /dev/null +++ b/tests/files/tags/rownolegle/1.expected.html @@ -0,0 +1,13 @@ +
    +
    +1

    Treść

    +
    +
    +
    +2

    Treść

    +
    +
    +3

    Treść

    +
    +
    +
    diff --git a/tests/files/tags/rownolegle/1.xml b/tests/files/tags/rownolegle/1.xml new file mode 100644 index 0000000..8775145 --- /dev/null +++ b/tests/files/tags/rownolegle/1.xml @@ -0,0 +1,16 @@ + + + + Treść + + + + + Treść + + + Treść + + + + diff --git a/tests/files/tags/sekcja_asterysk/1.expected.html b/tests/files/tags/sekcja_asterysk/1.expected.html new file mode 100644 index 0000000..d1d86b7 --- /dev/null +++ b/tests/files/tags/sekcja_asterysk/1.expected.html @@ -0,0 +1,5 @@ +
    +1

    Tekst

    +

    *

    +2

    Tekst

    +
    diff --git a/tests/files/tags/sekcja_asterysk/1.xml b/tests/files/tags/sekcja_asterysk/1.xml new file mode 100644 index 0000000..c7b34ae --- /dev/null +++ b/tests/files/tags/sekcja_asterysk/1.xml @@ -0,0 +1,5 @@ +Tekst + + + +Tekst diff --git a/tests/files/tags/sekcja_swiatlo/1.expected.html b/tests/files/tags/sekcja_swiatlo/1.expected.html new file mode 100644 index 0000000..6985524 --- /dev/null +++ b/tests/files/tags/sekcja_swiatlo/1.expected.html @@ -0,0 +1,5 @@ +
    +1

    Tekst

    +
    +2

    Tekst

    +
    diff --git a/tests/files/tags/sekcja_swiatlo/1.xml b/tests/files/tags/sekcja_swiatlo/1.xml new file mode 100644 index 0000000..34ac256 --- /dev/null +++ b/tests/files/tags/sekcja_swiatlo/1.xml @@ -0,0 +1,5 @@ +Tekst + + + +Tekst diff --git a/tests/files/tags/separator_linia/1.expected.html b/tests/files/tags/separator_linia/1.expected.html new file mode 100644 index 0000000..4f54cff --- /dev/null +++ b/tests/files/tags/separator_linia/1.expected.html @@ -0,0 +1,5 @@ +
    +1

    Tekst

    +
    +2

    Tekst

    +
    diff --git a/tests/files/tags/separator_linia/1.xml b/tests/files/tags/separator_linia/1.xml new file mode 100644 index 0000000..4c05f5e --- /dev/null +++ b/tests/files/tags/separator_linia/1.xml @@ -0,0 +1,5 @@ +Tekst + + + +Tekst diff --git a/tests/files/tags/slowo_obce/1.expected.html b/tests/files/tags/slowo_obce/1.expected.html new file mode 100644 index 0000000..8fa6808 --- /dev/null +++ b/tests/files/tags/slowo_obce/1.expected.html @@ -0,0 +1,3 @@ +
    +1

    Na czwarty dzień przywiózł mu stójka z osłowickiej apteki diachylum; Zołzikiewicz rozsmarował na płatek...

    +
    diff --git a/tests/files/tags/slowo_obce/1.xml b/tests/files/tags/slowo_obce/1.xml new file mode 100644 index 0000000..8e99a29 --- /dev/null +++ b/tests/files/tags/slowo_obce/1.xml @@ -0,0 +1,3 @@ + +Na czwarty dzień przywiózł mu stójka z osłowickiej apteki diachylum; Zołzikiewicz rozsmarował na płatek... + diff --git a/tests/files/tags/srodtytul/1.expected.html b/tests/files/tags/srodtytul/1.expected.html new file mode 100644 index 0000000..291f17f --- /dev/null +++ b/tests/files/tags/srodtytul/1.expected.html @@ -0,0 +1,9 @@ +
    +
    +

    Spis treści

    +
      +śródtytuł
    1. +
    +
    +

    śródtytuł

    +
    diff --git a/tests/files/tags/srodtytul/1.xml b/tests/files/tags/srodtytul/1.xml new file mode 100644 index 0000000..8132adf --- /dev/null +++ b/tests/files/tags/srodtytul/1.xml @@ -0,0 +1 @@ + śródtytuł diff --git a/tests/files/tags/strofa/1.expected.html b/tests/files/tags/strofa/1.expected.html new file mode 100644 index 0000000..fb5cb9a --- /dev/null +++ b/tests/files/tags/strofa/1.expected.html @@ -0,0 +1,13 @@ +
    +

    +Mikołaj Sęp SzarzyńskiDo Zosie +

    +
    +1
    Będę się zawsze dziwował twojej pikności:
    +
    Nie szkodzi wiernej dalekość miłości;
    +
    Bo, gdzie ciałem nie mogę być, tam myślą będę,
    +
    A pierwej siebie, niż ciebie zabędę;
    +5
    A dotąd się serce me smęcić nie przestanie,
    +
    Aż cię oglądam, me wdzięczne kochanie.
    +
    +
    diff --git a/tests/files/tags/strofa/1.xml b/tests/files/tags/strofa/1.xml new file mode 100644 index 0000000..9310b33 --- /dev/null +++ b/tests/files/tags/strofa/1.xml @@ -0,0 +1,10 @@ +Mikołaj Sęp Szarzyński +Do Zosie + +Będę się zawsze dziwował twojej pikności:/ +Nie szkodzi wiernej dalekość miłości;/ +Bo, gdzie ciałem nie mogę być, tam myślą będę,/ +A pierwej siebie, niż ciebie zabędę;/ +A dotąd się serce me smęcić nie przestanie,/ +Aż cię oglądam, me wdzięczne kochanie. + diff --git a/tests/files/tags/tab/1.expected.html b/tests/files/tags/tab/1.expected.html new file mode 100644 index 0000000..e2afe7d --- /dev/null +++ b/tests/files/tags/tab/1.expected.html @@ -0,0 +1,21 @@ +
    +1
    AB
    +
    A1
    +
    A2
    +
    A3
    +5
    A4
    +
    A5
    +
    A6
    +
    A1em
    +
    A2em
    +10
    A3em
    +
    A4em
    +
    A5em
    +
    A6em
    +
    +A* +
    +15
    +Rozszerzony tabulator wewnątrzwyróżnienia +
    +
    diff --git a/tests/files/tags/tab/1.xml b/tests/files/tags/tab/1.xml new file mode 100644 index 0000000..bd2dc46 --- /dev/null +++ b/tests/files/tags/tab/1.xml @@ -0,0 +1,17 @@ + + AB/ + A1/ + A2/ + A3/ + A4/ + A5/ + A6/ + A1em/ + A2em/ + A3em/ + A4em/ + A5em/ + A6em/ + A*/ + Rozszerzony tabulator wewnątrzwyróżnienia + diff --git a/tests/files/tags/tabela/1.expected.html b/tests/files/tags/tabela/1.expected.html new file mode 100644 index 0000000..fe9ef5f --- /dev/null +++ b/tests/files/tags/tabela/1.expected.html @@ -0,0 +1,22 @@ +
    + + + + + + + + + +
    ab
    cd
    + + + + + + + + + +
    ab
    cd
    +
    diff --git a/tests/files/tags/tabela/1.xml b/tests/files/tags/tabela/1.xml new file mode 100644 index 0000000..5e8f12b --- /dev/null +++ b/tests/files/tags/tabela/1.xml @@ -0,0 +1,21 @@ + + + a + b + + + c + d + + + + + + a + b + + + c + d + + diff --git a/tests/files/tags/tytul_dziela/1.expected.html b/tests/files/tags/tytul_dziela/1.expected.html new file mode 100644 index 0000000..364942d --- /dev/null +++ b/tests/files/tags/tytul_dziela/1.expected.html @@ -0,0 +1,8 @@ +
    +1

    Przeczytałem wczoraj + + Kilka uwag o „Hamlecie” + Szekspira + + pióra...

    +
    diff --git a/tests/files/tags/tytul_dziela/1.xml b/tests/files/tags/tytul_dziela/1.xml new file mode 100644 index 0000000..3b79afd --- /dev/null +++ b/tests/files/tags/tytul_dziela/1.xml @@ -0,0 +1,9 @@ + + Przeczytałem wczoraj + + Kilka uwag o + Hamlecie + Szekspira + + pióra... + diff --git a/tests/files/tags/tytul_dziela/2.expected.html b/tests/files/tags/tytul_dziela/2.expected.html new file mode 100644 index 0000000..b744afd --- /dev/null +++ b/tests/files/tags/tytul_dziela/2.expected.html @@ -0,0 +1,3 @@ +
    +1

    Belzebub (z hebr.) — w Nowym Testamencie pan piekieł i przywódca złych duchów. W utworze Krasińskiego ma on być twórcą „spróchniałego obrazu” raju, który to obraz — niby dekorację teatralną — złe duchy przechowują w sklepach, czyli podziemiach (staropolskie: sklep — piwnica, loch, podziemie). Wokół interpretacji obrazu Edenu rozwinęła się polemika między A. Łuckim a Z. Niemojewską–Gruszczyńską (A. Łucki, Obraz Edenu w „Nie–Boskiej komedii”, „Ruch literacki”, nr 3, s.65–67; Z. Niemojewska–Gruszczyńska, W sprawie obrazu Edenu w „Nie–Boskiej komedii”, tamże, nr 5, s. 133–135; A. Łucki, Jeszcze w sprawie obrazu Edenu w „Nie–Boskiej komedii”, tamże, nr 6, s.191–192). Kleiner sądzi, że obraz Edenu to przyroda „zespolona z jakimiś utopijnymi marzeniami”, „że plan pierwotny był odmienny”, przyroda „miała być narzędziem szatana”, kuszącego wyobraźnię poety. Za tą interpretacją idzie też wyd. Libery i Sawrymowicza. Według M. Janion interpretacja Edenu jako jednej z trzech wizji–kuszeń może być dwojaka. Po pierwsze można uznać, że Eden stanowi tu synonim natury, tak jak rozumieli ją romantycy: to raj utracony, stan naturalnej szczęśliwości, przeciwieństwo życia w cywilizacji, prosty i harmonijny żywot. Ale można rozumieć ów symboliczny Eden jako oświeceniowy „stan naturalny” człowieka związany z filozoficzną utopią XVIII–wiecznych racjonalistów. Wtedy pokusę szatańską łączyć należy z obrazem przyszłego szczęścia ludzkości, jaką roztacza Pankracy w rozmowie z hrabią Henrykiem.

    +
    diff --git a/tests/files/tags/tytul_dziela/2.xml b/tests/files/tags/tytul_dziela/2.xml new file mode 100644 index 0000000..ce17d5c --- /dev/null +++ b/tests/files/tags/tytul_dziela/2.xml @@ -0,0 +1,3 @@ + + Belzebub (z hebr.) --- w Nowym Testamencie pan piekieł i przywódca złych duchów. W utworze Krasińskiego ma on być twórcą ,,spróchniałego obrazu" raju, który to obraz --- niby dekorację teatralną --- złe duchy przechowują w sklepach, czyli podziemiach (staropolskie: sklep --- piwnica, loch, podziemie). Wokół interpretacji obrazu Edenu rozwinęła się polemika między A. Łuckim a Z. Niemojewską--Gruszczyńską (A. Łucki, Obraz Edenu w Nie--Boskiej komedii, ,,Ruch literacki", nr 3, s.65--67; Z. Niemojewska--Gruszczyńska, W sprawie obrazu Edenu w Nie--Boskiej komedii, tamże, nr 5, s. 133--135; A. Łucki, Jeszcze w sprawie obrazu Edenu w Nie--Boskiej komedii, tamże, nr 6, s.191--192). Kleiner sądzi, że obraz Edenu to przyroda ,,zespolona z jakimiś utopijnymi marzeniami", ,,że plan pierwotny był odmienny", przyroda ,,miała być narzędziem szatana", kuszącego wyobraźnię poety. Za tą interpretacją idzie też wyd. Libery i Sawrymowicza. Według M. Janion interpretacja Edenu jako jednej z trzech wizji--kuszeń może być dwojaka. Po pierwsze można uznać, że Eden stanowi tu synonim natury, tak jak rozumieli ją romantycy: to raj utracony, stan naturalnej szczęśliwości, przeciwieństwo życia w cywilizacji, prosty i harmonijny żywot. Ale można rozumieć ów symboliczny Eden jako oświeceniowy ,,stan naturalny" człowieka związany z filozoficzną utopią XVIII--wiecznych racjonalistów. Wtedy pokusę szatańską łączyć należy z obrazem przyszłego szczęścia ludzkości, jaką roztacza Pankracy w rozmowie z hrabią Henrykiem. + diff --git a/tests/files/tags/wers_cd/1.expected.html b/tests/files/tags/wers_cd/1.expected.html new file mode 100644 index 0000000..c0aea62 --- /dev/null +++ b/tests/files/tags/wers_cd/1.expected.html @@ -0,0 +1,17 @@ +
    +

    MARYNA

    +
    +1
    Więc?
    + +
    +

    POETA

    +
    +
    Sztuka dla sztuki.
    +
    +

    MARYNA

    +
    +
    Zawrót głowy, wielka chwała;
    +
    niech pan sztuki płata różne,
    +5
    bylebym ja spokój miała.
    +
    +
    diff --git a/tests/files/tags/wers_cd/1.xml b/tests/files/tags/wers_cd/1.xml new file mode 100644 index 0000000..c64c14c --- /dev/null +++ b/tests/files/tags/wers_cd/1.xml @@ -0,0 +1,23 @@ +MARYNA + + + + Więc? + + + + +POETA + + + Sztuka dla sztuki. + + + +MARYNA + +Zawrót głowy, wielka chwała;/ +niech pan sztuki płata różne,/ +bylebym ja spokój miała. + + diff --git a/tests/files/tags/wers_do_prawej/1.expected.html b/tests/files/tags/wers_do_prawej/1.expected.html new file mode 100644 index 0000000..922ce4a --- /dev/null +++ b/tests/files/tags/wers_do_prawej/1.expected.html @@ -0,0 +1,8 @@ +
    +1
    Anioł ognisty — mój anioł lewy
    +
    Poruszył dawną miłości strunę.
    +
    Z tobą! o! z tobą, gdzie białe mewy,
    +
    Z tobą w podśnieżną sybirską trunę,
    +5
    Gdzie wiatry wyją tak jak hyjeny,
    +
    Tam, gdzie ty pasasz na grobach reny.
    +
    diff --git a/tests/files/tags/wers_do_prawej/1.xml b/tests/files/tags/wers_do_prawej/1.xml new file mode 100644 index 0000000..0a32e1e --- /dev/null +++ b/tests/files/tags/wers_do_prawej/1.xml @@ -0,0 +1,7 @@ +Anioł ognisty --- mój anioł lewy/ +Poruszył dawną miłości strunę./ +Z tobą! o! z tobą, gdzie białe mewy,/ +Z tobą w podśnieżną sybirską trunę,/ +Gdzie wiatry wyją tak jak hyjeny,/ +Tam, gdzie ty pasasz na grobach reny. + diff --git a/tests/files/tags/wers_wciety/1.expected.html b/tests/files/tags/wers_wciety/1.expected.html new file mode 100644 index 0000000..0ee7c74 --- /dev/null +++ b/tests/files/tags/wers_wciety/1.expected.html @@ -0,0 +1,13 @@ +
    +

    +Julisz SłowackiAnioł ognisty — mój anioł lewy... +

    +
    +1
    Anioł ognisty — mój anioł lewy
    +
    Poruszył dawną miłości strunę.
    +
    Z tobą! o! z tobą, gdzie białe mewy,
    +
    Z tobą w podśnieżną sybirską trunę,
    +5
    Gdzie wiatry wyją tak jak hyjeny,
    +
    Tam, gdzie ty pasasz na grobach reny.
    +
    +
    diff --git a/tests/files/tags/wers_wciety/1.xml b/tests/files/tags/wers_wciety/1.xml new file mode 100644 index 0000000..db6c80d --- /dev/null +++ b/tests/files/tags/wers_wciety/1.xml @@ -0,0 +1,13 @@ +Julisz Słowacki +Anioł ognisty --- mój anioł lewy... +Anioł ognisty --- mój anioł lewy/ + +Poruszył dawną miłości strunę./ + +Z tobą! o! z tobą, gdzie białe mewy,/ + +Z tobą w podśnieżną sybirską trunę,/ + +Gdzie wiatry wyją tak jak hyjeny,/ +Tam, gdzie ty pasasz na grobach reny. + diff --git a/tests/files/tags/wers_wciety/2.expected.html b/tests/files/tags/wers_wciety/2.expected.html new file mode 100644 index 0000000..85b8e22 --- /dev/null +++ b/tests/files/tags/wers_wciety/2.expected.html @@ -0,0 +1,8 @@ +
    1
    zwykły
    +
    wcięty
    +
    wcięty 1
    +
    wcięty 2
    + 5
    wcięty 25
    +
    akapitowy
    +
    środek
    +
    do prawej
    diff --git a/tests/files/tags/wers_wciety/2.xml b/tests/files/tags/wers_wciety/2.xml new file mode 100644 index 0000000..c31d2cb --- /dev/null +++ b/tests/files/tags/wers_wciety/2.xml @@ -0,0 +1,10 @@ + + zwykły + wcięty + wcięty 1 + wcięty 2 + wcięty 25 + akapitowy + środek + do prawej + diff --git a/tests/files/tags/wieksze_odstepy/1.expected.html b/tests/files/tags/wieksze_odstepy/1.expected.html new file mode 100644 index 0000000..0ad94e4 --- /dev/null +++ b/tests/files/tags/wieksze_odstepy/1.expected.html @@ -0,0 +1,3 @@ +
    +1

    tekst tekst tekst

    +
    diff --git a/tests/files/tags/wieksze_odstepy/1.xml b/tests/files/tags/wieksze_odstepy/1.xml new file mode 100644 index 0000000..c647957 --- /dev/null +++ b/tests/files/tags/wieksze_odstepy/1.xml @@ -0,0 +1,3 @@ + + tekst tekst tekst + diff --git a/tests/files/tags/www/1.expected.html b/tests/files/tags/www/1.expected.html new file mode 100644 index 0000000..9b44ed6 --- /dev/null +++ b/tests/files/tags/www/1.expected.html @@ -0,0 +1,4 @@ + diff --git a/tests/files/tags/www/1.xml b/tests/files/tags/www/1.xml new file mode 100644 index 0000000..36c0360 --- /dev/null +++ b/tests/files/tags/www/1.xml @@ -0,0 +1,4 @@ + + Adres: + https://wolnelektury.pl + diff --git a/tests/files/tags/wyroznienie/1.expected.html b/tests/files/tags/wyroznienie/1.expected.html new file mode 100644 index 0000000..65cffe3 --- /dev/null +++ b/tests/files/tags/wyroznienie/1.expected.html @@ -0,0 +1,9 @@ +
    +1
    Byłem u Ciebie w te dni przedostatnie
    +
    Niedocieczonego wątku — —
    +
    — Pełne jak mit,
    +
    Blade jak świt,
    +5
    — Gdy życia koniec szepce do początku:
    +
    +„Nie stargam cię ja — nie! — Ja, u-wydatnię!...”
    +
    diff --git a/tests/files/tags/wyroznienie/1.xml b/tests/files/tags/wyroznienie/1.xml new file mode 100644 index 0000000..243ae6a --- /dev/null +++ b/tests/files/tags/wyroznienie/1.xml @@ -0,0 +1,9 @@ + +Byłem u Ciebie w te dni przedostatnie/ +Niedocieczonego wątku --- ---/ +--- Pełne jak mit,/ +Blade jak świt,/ +--- Gdy życia koniec szepce do początku:/ + +,,Nie stargam cię ja --- nie! --- Ja, u-wydatnię!..." + diff --git a/tests/files/tags/wywiad_pyt/1.expected.html b/tests/files/tags/wywiad_pyt/1.expected.html new file mode 100644 index 0000000..e8b700d --- /dev/null +++ b/tests/files/tags/wywiad_pyt/1.expected.html @@ -0,0 +1,4 @@ +
    +1

    blok akapitów pytania

    +2

    blok akapitów odpowiedzi

    +
    diff --git a/tests/files/tags/wywiad_pyt/1.xml b/tests/files/tags/wywiad_pyt/1.xml new file mode 100644 index 0000000..aa74999 --- /dev/null +++ b/tests/files/tags/wywiad_pyt/1.xml @@ -0,0 +1,3 @@ +blok akapitów pytania + +blok akapitów odpowiedzi diff --git a/tests/files/tags/zastepnik_wersu/1.expected.html b/tests/files/tags/zastepnik_wersu/1.expected.html new file mode 100644 index 0000000..cd767f2 --- /dev/null +++ b/tests/files/tags/zastepnik_wersu/1.expected.html @@ -0,0 +1,8 @@ +
    +1
    I powleczem korowód, smęcąc ujęte snem grody,
    +
    W bramy bijąc urnami, gwizdając w szczerby toporów,
    +
    Aż się mury Jerycha porozwalają jak kłody,
    +
    Serca zmdlałe ocucą, pleśń z oczu zgarną narody.
    +5
    . . . . . . . . . . . . . . . .
    +
    Dalej — dalej — —
    +
    diff --git a/tests/files/tags/zastepnik_wersu/1.xml b/tests/files/tags/zastepnik_wersu/1.xml new file mode 100644 index 0000000..716699a --- /dev/null +++ b/tests/files/tags/zastepnik_wersu/1.xml @@ -0,0 +1,10 @@ + +I powleczem korowód, smęcąc ujęte snem grody,/ +W bramy bijąc urnami, gwizdając w szczerby toporów,/ +Aż się mury Jerycha porozwalają jak kłody,/ +Serca zmdlałe ocucą, pleśń z oczu zgarną narody./ + +. . . . . . . . . . . . . . . ./ + +Dalej --- dalej --- --- + diff --git a/tests/files/text/abstrakt.expected.html b/tests/files/text/abstrakt.expected.html new file mode 100644 index 0000000..94c33b6 --- /dev/null +++ b/tests/files/text/abstrakt.expected.html @@ -0,0 +1,3 @@ +
    +

    Przygody Tomka Sawyera to najsłynniejsza powieść dla młodzieży autorstwa amerykańskiego pisarza Marka Twaina.

    +
    diff --git a/tests/files/text/abstrakt.xml b/tests/files/text/abstrakt.xml index 7a468a1..27d3cd5 100644 --- a/tests/files/text/abstrakt.xml +++ b/tests/files/text/abstrakt.xml @@ -1,6 +1,7 @@ - - - - + + + Przygody Tomka Sawyera to najsłynniejsza powieść dla młodzieży autorstwa amerykańskiego pisarza Marka Twaina. + + diff --git a/tests/files/text/asnyk_miedzy_nami_expected.html b/tests/files/text/asnyk_miedzy_nami_expected.html index 34fccdd..2450c02 100644 --- a/tests/files/text/asnyk_miedzy_nami_expected.html +++ b/tests/files/text/asnyk_miedzy_nami_expected.html @@ -1,47 +1,43 @@
    -
    -

    Spis treści

    -
      -
      1. Miłość platoniczna: 1
      2. Natura: 1
      3. Nicość: 1

      -Adam AsnykMiłość platonicznaMiędzy nami nic nie było +Adam AsnykMiłość platonicznaMiędzy nami nic nie było

      -
      - 1
      Między nami Nicośćnic nie było! +
      +1
      Między nami Nicośćnic nie było!
      -
      Żadnych zwierzeń, wyznań żadnych!
      -
      Nic nas z sobą nie łączyło —
      -
      Prócz wiosennych marzeń zdradnych;
      +
      Żadnych zwierzeń, wyznań żadnych!
      +
      Nic nas z sobą nie łączyło —
      +
      Prócz wiosennych marzeń zdradnych;
      -
      - 5
      +
      +5
      NaturaPrócz tych woni, barw i blasków,
      -
      Unoszących się w przestrzeni;
      -
      Prócz szumiących śpiewem lasków
      -
      I tej świeżej łąk zieleni;
      +
      Unoszących się w przestrzeni;
      +
      Prócz szumiących śpiewem lasków
      +
      I tej świeżej łąk zieleni;
      -
      -
      Prócz tych kaskad i potoków,
      - 10
      Zraszających każdy parów,
      -
      Prócz girlandy tęcz, obłoków,
      -
      Prócz natury słodkich czarów;
      +
      +
      Prócz tych kaskad i potoków,
      +10
      Zraszających każdy parów,
      +
      Prócz girlandy tęcz, obłoków,
      +
      Prócz natury słodkich czarów;
      -
      -
      Prócz tych wspólnych, jasnych zdrojów,
      -
      Z których serce zachwyt piło;
      - 15
      Prócz pierwiosnków[1] i powojów,—
      -
      Między nami nic nie było! +
      +
      Prócz tych wspólnych, jasnych zdrojów,
      +
      Z których serce zachwyt piło;
      +15
      Prócz pierwiosnków[1] i powojów,—
      +
      Między nami nic nie było!

      Przypisy

      -[1]

      pierwiosnek — taki kwiatek [przypis edytorski]

      +[1]

      pierwiosnek — taki kwiatek [przypis edytorski]

      diff --git a/tests/files/text/asnyk_miedzy_nami_expected.legacy.html b/tests/files/text/asnyk_miedzy_nami_expected.legacy.html deleted file mode 100644 index 7004f5a..0000000 --- a/tests/files/text/asnyk_miedzy_nami_expected.legacy.html +++ /dev/null @@ -1,47 +0,0 @@ -
      -
      -

      Spis treści

      -
        -
        -
          -
        1. Miłość platoniczna: 1 2
        2. -
        3. Natura: 1
        4. -
        5. Nicość: 1
        6. -
        -

        -Adam AsnykMiłość platonicznaMiędzy nami nic nie było -

        -Miłość platoniczna
        - 1
        Między nami Nicośćnic nie było! -
        -
        Żadnych zwierzeń, wyznań żadnych!
        -
        Nic nas z sobą nie łączyło —
        -
        Prócz wiosennych marzeń zdradnych;
        -
        -
        - 5
        -NaturaPrócz tych woni, barw i blasków,
        -
        Unoszących się w przestrzeni;
        -
        Prócz szumiących śpiewem lasków
        -
        I tej świeżej łąk zieleni;
        -
        -
        -
        Prócz tych kaskad i potoków,
        - 10
        Zraszających każdy parów,
        -
        Prócz girlandy tęcz, obłoków,
        -
        Prócz natury słodkich czarów;
        -
        -
        -
        Prócz tych wspólnych, jasnych zdrojów,
        -
        Z których serce zachwyt piło;
        - 15
        Prócz pierwiosnków[1] i powojów,—
        -
        Między nami nic nie było! -
        -
        -
        -

        Przypisy

        -
        -[1]

        pierwiosnek — taki kwiatek [przypis edytorski]

        -
        -
        -
        diff --git a/tests/files/text/asnyk_miedzy_nami_fragments.html b/tests/files/text/asnyk_miedzy_nami_fragments.html index eeeaee6..9fd6a25 100644 --- a/tests/files/text/asnyk_miedzy_nami_fragments.html +++ b/tests/files/text/asnyk_miedzy_nami_fragments.html @@ -1,54 +1,54 @@ 1: Nicość -
        nic nie było!
        +
        nic nie było!
        1189062500041: Miłość platoniczna -

        Między nami nic nie było +

        Między nami nic nie było

        -
        Między nami nic nie było! +
        Między nami nic nie było!
        -
        Żadnych zwierzeń, wyznań żadnych!
        -
        Nic nas z sobą nie łączyło —
        -
        Prócz wiosennych marzeń zdradnych;
        +
        Żadnych zwierzeń, wyznań żadnych!
        +
        Nic nas z sobą nie łączyło —
        +
        Prócz wiosennych marzeń zdradnych;
        -
        -Prócz tych woni, barw i blasków,
        -
        Unoszących się w przestrzeni;
        -
        Prócz szumiących śpiewem lasków
        -
        I tej świeżej łąk zieleni;
        +
        +Prócz tych woni, barw i blasków,
        +
        Unoszących się w przestrzeni;
        +
        Prócz szumiących śpiewem lasków
        +
        I tej świeżej łąk zieleni;
        -
        Prócz tych kaskad i potoków,
        -
        Zraszających każdy parów,
        -
        Prócz girlandy tęcz, obłoków,
        -
        Prócz natury słodkich czarów;
        +
        Prócz tych kaskad i potoków,
        +
        Zraszających każdy parów,
        +
        Prócz girlandy tęcz, obłoków,
        +
        Prócz natury słodkich czarów;
        -
        Prócz tych wspólnych, jasnych zdrojów,
        -
        Z których serce zachwyt piło;
        -
        Prócz pierwiosnków i powojów,—
        -
        Między nami nic nie było!
        +
        Prócz tych wspólnych, jasnych zdrojów,
        +
        Z których serce zachwyt piło;
        +
        Prócz pierwiosnków i powojów,—
        +
        Między nami nic nie było!
        1189062528872: Natura -
        Prócz tych woni, barw i blasków,
        -
        Unoszących się w przestrzeni;
        -
        Prócz szumiących śpiewem lasków
        -
        I tej świeżej łąk zieleni;
        +
        Prócz tych woni, barw i blasków,
        +
        Unoszących się w przestrzeni;
        +
        Prócz szumiących śpiewem lasków
        +
        I tej świeżej łąk zieleni;
        -
        Prócz tych kaskad i potoków,
        -
        Zraszających każdy parów,
        -
        Prócz girlandy tęcz, obłoków,
        -
        Prócz natury słodkich czarów;
        +
        Prócz tych kaskad i potoków,
        +
        Zraszających każdy parów,
        +
        Prócz girlandy tęcz, obłoków,
        +
        Prócz natury słodkich czarów;
        -
        Prócz tych wspólnych, jasnych zdrojów,
        -
        Z których serce zachwyt piło;
        -
        Prócz pierwiosnków i powojów,—
        -
        Między nami nic nie było!
        +
        Prócz tych wspólnych, jasnych zdrojów,
        +
        Z których serce zachwyt piło;
        +
        Prócz pierwiosnków i powojów,—
        +
        Między nami nic nie było!
        diff --git a/tests/files/text/asnyk_miedzy_nami_refs.html b/tests/files/text/asnyk_miedzy_nami_refs.html index 703d79c..8bd2327 100644 --- a/tests/files/text/asnyk_miedzy_nami_refs.html +++ b/tests/files/text/asnyk_miedzy_nami_refs.html @@ -1,6 +1,6 @@ -sec7 -
        -
        Prócz tych wspólnych, jasnych zdrojów,
        -
        Z których serce zachwyt piło;
        -
        Prócz pierwiosnków
        +f15 +
        +
        Prócz tych wspólnych, jasnych zdrojów,
        +
        Z których serce zachwyt piło;
        +
        Prócz pierwiosnków
        diff --git a/tests/test_html.py b/tests/test_html.py index 1d698fd..5e5ee30 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -1,29 +1,16 @@ # This file is part of Librarian, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Wolne Lektury. See NOTICE for more information. # -import re +import io from unittest import TestCase -from librarian import NoDublinCore from librarian.builders import builders from librarian.document import WLDocument -from librarian.parser import WLDocument as LegacyWLDocument from .utils import get_fixture class TransformTest(TestCase): maxDiff = None - def test_transform_legacy(self): - expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected.legacy.html') - - html = LegacyWLDocument.from_file( - get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml') - ).as_html().get_bytes().decode('utf-8') - - html = re.sub(r'idm\d+', 'idmNNN', html) - with open(expected_output_file_path) as f: - self.assertEqual(f.read(), html) - def test_transform(self): expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected.html') html = WLDocument( @@ -33,23 +20,9 @@ class TransformTest(TestCase): with open(expected_output_file_path) as f: self.assertEqual(html, f.read()) - def test_no_dublincore(self): - with self.assertRaises(NoDublinCore): - LegacyWLDocument.from_file( - get_fixture('text', 'asnyk_miedzy_nami_nodc.xml') - ).as_html() - - def test_passing_parse_dublincore_to_transform(self): - """Passing parse_dublincore=False to transform omits DublinCore parsing.""" - LegacyWLDocument.from_file( - get_fixture('text', 'asnyk_miedzy_nami_nodc.xml'), - parse_dublincore=False, - ).as_html() - def test_empty(self): self.assertIsNone( - LegacyWLDocument.from_bytes( - b'', - parse_dublincore=False, - ).as_html() + WLDocument( + filename=io.BytesIO(b''), + ).build(builders['html'], base_url='/') ) diff --git a/tests/test_html_annotations.py b/tests/test_html_annotations.py index bdbe4fb..ccf8030 100644 --- a/tests/test_html_annotations.py +++ b/tests/test_html_annotations.py @@ -1,12 +1,16 @@ # This file is part of Librarian, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Wolne Lektury. See NOTICE for more information. # +import io import unittest -from librarian.parser import WLDocument +from librarian.builders import HtmlBuilder +from librarian.document import WLDocument from librarian.html import extract_annotations class AnnotationsTests(unittest.TestCase): + maxDiff = None + def _test_annotation(self, expected, got, name): self.assertTrue( got[0].startswith('anchor-'), @@ -108,19 +112,19 @@ class AnnotationsTests(unittest.TestCase): 'częściej: gemajn, szeregowiec w wojsku polskim cudzoziemskiego autoramentu.', ( 'pe', ['daw.', 'niem.'], - 'gemajna (daw., z niem. gemein: zwykły) \u2014 częściej: gemajn, ' - 'szeregowiec w wojsku polskim cudzoziemskiego autoramentu. [przypis edytorski]', - '

        gemajna (daw., z niem. gemein: zwykły) ' - '\u2014 częściej: gemajn, szeregowiec w wojsku polskim cudzoziemskiego autoramentu. [przypis edytorski]

        ' + 'gemajna (daw., z\u00A0niem. gemein: zwykły) \u2014 częściej: gemajn, ' + 'szeregowiec w\u00A0wojsku polskim cudzoziemskiego autoramentu. [przypis edytorski]', + '

        gemajna (daw., z\u00A0niem. gemein: zwykły) ' + '\u2014 częściej: gemajn, szeregowiec w\u00A0wojsku polskim cudzoziemskiego autoramentu. [przypis edytorski]

        ' ), 'Footnote with multiple and qualifiers and emphasis.'), ) xml_src = ''' %s ''' % "".join( t[0] for t in annotations) - html = WLDocument.from_bytes( - xml_src.encode('utf-8'), - parse_dublincore=False).as_html().get_file() + html = WLDocument( + filename=io.BytesIO(xml_src.encode('utf-8')) + ).build(HtmlBuilder, base_url='/').get_file() res_annotations = list(extract_annotations(html)) for i, (src, expected, name) in enumerate(annotations): diff --git a/tests/test_html_examples.py b/tests/test_html_examples.py new file mode 100644 index 0000000..582123c --- /dev/null +++ b/tests/test_html_examples.py @@ -0,0 +1,49 @@ +import io +import os +from unittest import TestCase +from librarian.builders import HtmlBuilder +from librarian.document import WLDocument +from librarian.elements import WL_ELEMENTS +from .utils import get_fixture, get_all_fixtures + + +class HtmlExamplesTests(TestCase): + maxDiff = None + + @classmethod + def setUpClass(cls): + with open(get_fixture('tags', 'base.xml'), 'rb') as f: + cls.base_xml = f.read() + + def test_examples(self): + for tag in WL_ELEMENTS: + with self.subTest(tag): + self.tag_test(tag) + for path in get_all_fixtures('tags'): + if os.path.isdir(path): + name = path.rsplit('/', 1)[1] + self.assertIn(name, WL_ELEMENTS) + + def tag_test(self, tag): + for fixture in get_all_fixtures(f'tags/{tag}', '*.xml'): + with self.subTest(tag=tag, n=fixture.rsplit('/', 1)[-1].rsplit('.', 1)[0]): + with open(fixture, 'rb') as f: + xml_input = f.read() + xml_file = io.BytesIO(self.base_xml.replace(b'', xml_input)) + doc = WLDocument(filename=xml_file) + html = HtmlBuilder(base_url='/').build(doc).get_bytes().decode('utf-8') + + with open(fixture.rsplit('.', 1)[0] + '.expected.html', 'r') as f: + expected_html = f.read() + try: + with open(fixture.rsplit('.', 1)[0] + '.expected.toc.html', 'r') as f: + expected_toc = f.read() + except: + expected_toc = '' + try: + with open(fixture.rsplit('.', 1)[0] + '.expected.themes.html', 'r') as f: + expected_themes = f.read() + except: + expected_themes = '' + + self.assertEqual(html, expected_html) diff --git a/tests/test_html_fragments.py b/tests/test_html_fragments.py index 2d55362..a89e94f 100644 --- a/tests/test_html_fragments.py +++ b/tests/test_html_fragments.py @@ -13,7 +13,7 @@ class FragmentsTest(unittest.TestCase): expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_fragments.html') closed_fragments, open_fragments = extract_fragments( - get_fixture('text', 'asnyk_miedzy_nami_expected.legacy.html')) + get_fixture('text', 'asnyk_miedzy_nami_expected.html')) assert not open_fragments fragments_text = "\n\n".join("%s: %s\n%s" % (f.id, f.themes, f) for f in sorted(closed_fragments.values(), key=lambda f: f.id)) with open(expected_output_file_path, 'rb') as f: diff --git a/tests/test_html_transform_abstrakt.py b/tests/test_html_transform_abstrakt.py index 4f36b80..ae7fbe5 100644 --- a/tests/test_html_transform_abstrakt.py +++ b/tests/test_html_transform_abstrakt.py @@ -2,16 +2,19 @@ # Copyright © Fundacja Wolne Lektury. See NOTICE for more information. # import unittest -from librarian.parser import WLDocument -from librarian.html import transform_abstrakt +from librarian.document import WLDocument +from librarian.builders.html import AbstraktHtmlBuilder from .utils import get_fixture class AbstractTests(unittest.TestCase): def test_abstrakt(self): - transform_abstrakt( - WLDocument.from_file( - get_fixture('text', 'abstrakt.xml'), - parse_dublincore=False - ).edoc.getroot().find('.//abstrakt') - ) + builder = AbstraktHtmlBuilder() + got = builder.build( + WLDocument( + filename=get_fixture('text', 'abstrakt.xml'), + ) + ).get_bytes().decode('utf-8') + with open(get_fixture('text', 'abstrakt.expected.html')) as f: + expected = f.read() + self.assertEqual(expected, got) diff --git a/tests/test_picture.py b/tests/test_picture.py deleted file mode 100644 index afa4da8..0000000 --- a/tests/test_picture.py +++ /dev/null @@ -1,56 +0,0 @@ -# This file is part of Librarian, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Wolne Lektury. See NOTICE for more information. -# -from os import path -import unittest -from librarian import picture, dcparser -from tests.utils import get_all_fixtures, get_fixture - - -class PictureTests(unittest.TestCase): - def test_wlpictureuri(self): - uri = picture.WLPictureURI('http://wolnelektury.pl/katalog/obraz/angelus-novus') - - def check_load(self, xml_file): - pi = dcparser.parse(xml_file, picture.PictureInfo) - self.assertIsNotNone(pi) - self.assertIsInstance(pi, picture.PictureInfo) - - def test_load(self): - for fixture in get_all_fixtures('picture', '*.xml'): - with self.subTest(fixture=fixture): - self.check_load(fixture) - - def test_wlpicture(self): - with open(get_fixture('picture', 'angelus-novus.xml')) as f: - wlp = picture.WLPicture.from_file(f) - pi = wlp.picture_info - - self.assertEqual(pi.type[0], "Image") - self.assertEqual(pi.mime_type, 'image/jpeg') - self.assertEqual(wlp.mime_type, 'image/jpeg') - self.assertEqual(wlp.slug, 'angelus-novus') - self.assertTrue(path.exists(wlp.image_path)) - - f = wlp.image_file() - f.close() - - - def test_picture_parts(self): - with open(get_fixture('picture', 'angelus-novus.xml')) as f: - wlp = picture.WLPicture.from_file(f) - parts = list(wlp.partiter()) - expect_parts = 4 - self.assertEqual(len(parts), expect_parts, "there should be %d parts of the picture" % expect_parts) - motifs = set() - names = set() - - for p in parts: - for m in p['themes']: - motifs.add(m) - for p in parts: - if p['object']: - names.add(p['object']) - - self.assertEqual(motifs, {'anioł historii', 'spojrzenie'}, "missing motifs, got: %s" % motifs) - self.assertEqual(names, {'obraz cały', 'skrzydło'}, 'missing objects, got: %s' % names) diff --git a/tests/test_ref.py b/tests/test_ref.py index 2383866..d75228e 100644 --- a/tests/test_ref.py +++ b/tests/test_ref.py @@ -11,12 +11,14 @@ from lxml import etree class RefTests(TestCase): def test_snippet(self): doc = WLDocument(filename=get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml')) - doc._compat_assign_section_ids() + + hb = builders['html']() + hb.assign_ids(doc.tree) refs = [] for ref in doc.references(): snippet = ref.get_snippet() - b = builders['html']() + b = builders['html-snippet']() for s in snippet: s.html_build(b) diff --git a/tox.ini b/tox.ini index ecf3ecc..5797049 100644 --- a/tox.ini +++ b/tox.ini @@ -1,17 +1,17 @@ [tox] envlist = clean, - py{37,38,39,310,311}, + py{38,39,310,311}, stats [testenv] deps = coverage -passenv = HOME ; Needed to find locally installed fonts when testing PDF production. +passenv = HOME # Needed to find locally installed fonts when testing PDF production. download = true commands = coverage run -install_command = pip install numpy; pip install --extra-index-url https://py.mdrn.pl/simple {packages} +install_command = pip install --extra-index-url https://py.mdrn.pl/simple {packages} [testenv:clean] basepython = python3 -- 2.20.1 From 55fbc767e5592cad565cff0d16b9638d01b6706f Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Mon, 16 Sep 2024 12:33:02 +0200 Subject: [PATCH 05/13] Text converter updated. --- setup.py | 2 +- src/librarian/builders/txt.py | 27 +++++---------- src/librarian/elements/__init__.py | 14 ++++---- src/librarian/elements/base.py | 33 +++++++++++-------- src/librarian/elements/blocks/dedykacja.py | 3 +- src/librarian/elements/blocks/dlugi_cytat.py | 4 +-- src/librarian/elements/blocks/poezja_cyt.py | 2 -- src/librarian/elements/drama/didaskalia.py | 2 -- src/librarian/elements/drama/lista_osob.py | 2 -- src/librarian/elements/drama/lista_osoba.py | 2 -- .../elements/drama/naglowek_osoba.py | 2 -- src/librarian/elements/figures/kol.py | 1 + src/librarian/elements/figures/tabela.py | 4 +++ src/librarian/elements/figures/wiersz.py | 3 ++ src/librarian/elements/front/autor_utworu.py | 1 - .../elements/front/dzielo_nadrzedne.py | 1 - src/librarian/elements/front/motto.py | 4 +-- src/librarian/elements/front/nazwa_utworu.py | 1 - src/librarian/elements/front/podtytul.py | 1 - .../elements/headers/naglowek_czesc.py | 2 -- .../elements/headers/naglowek_podrozdzial.py | 2 -- .../elements/headers/naglowek_rozdzial.py | 2 -- .../elements/headers/naglowek_scena.py | 2 -- src/librarian/elements/masters/__init__.py | 2 +- src/librarian/elements/paragraphs/akap.py | 2 -- src/librarian/elements/poetry/strofa.py | 2 -- src/librarian/elements/poetry/wers.py | 2 -- .../elements/separators/sekcja_asterysk.py | 2 -- .../elements/separators/sekcja_swiatlo.py | 1 - .../elements/separators/separator_linia.py | 2 -- src/librarian/elements/styles/__init__.py | 2 +- src/librarian/elements/styles/mat.py | 30 +++++++++++++++++ src/librarian/elements/tools/__init__.py | 10 ++++++ tests/files/tags/didaskalia/1.expected.html | 4 +-- tests/files/tags/kwestia/1.expected.html | 2 +- tests/files/tags/kwestia/2.expected.html | 4 +-- tests/files/tags/motto_podpis/1.expected.html | 2 +- .../files/tags/naglowek_osoba/1.expected.html | 2 +- tests/files/tags/nota/2.expected.html | 2 +- tests/files/tags/nota/3.expected.html | 4 +-- tests/files/tags/poezja_cyt/1.expected.html | 2 +- tests/files/tags/slowo_obce/1.expected.html | 2 +- tests/files/tags/tabela/1.expected.html | 32 +++++++++--------- tests/files/tags/tytul_dziela/1.expected.html | 2 +- tests/files/tags/wers_wciety/1.expected.html | 2 +- tests/files/tags/wers_wciety/2.expected.html | 18 +++++----- tests/files/tags/wers_wciety/2.xml | 14 ++++---- tests/files/tags/wyroznienie/1.expected.html | 2 +- .../text/asnyk_miedzy_nami_expected_raw.txt | 2 -- tests/test_text.py | 31 ++--------------- 50 files changed, 142 insertions(+), 157 deletions(-) diff --git a/setup.py b/setup.py index 184db52..2af0a05 100755 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ setup( "librarian=librarian.command_line:main" ] }, - scripts=['scripts/book2html', + scripts=[ 'scripts/book2txt', 'scripts/book2pdf', 'scripts/book2fb2', diff --git a/src/librarian/builders/txt.py b/src/librarian/builders/txt.py index 8302de5..28fe709 100644 --- a/src/librarian/builders/txt.py +++ b/src/librarian/builders/txt.py @@ -15,14 +15,6 @@ class TxtFragment: self.current_margin = 0 self.starting_block = True - def push_legacy_margin(self, margin): - if margin: - if self.pieces: - self.pieces[-1] = self.pieces[-1].rstrip(' ') - self.pieces.append('\r\n' * margin) - self.current_margin += margin - self.starting_block = True - def push_margin(self, margin): if margin: if self.pieces: @@ -47,8 +39,11 @@ class TxtBuilder: """ file_extension = "txt" identifier = "txt" + after_child_fn = 'txt_after_child' + debug = False orphans = False + normalize_whitespace = True default_license_description = { "pol": ( @@ -107,9 +102,6 @@ class TxtBuilder: def push_margin(self, margin): self.current_fragments[-1].push_margin(margin) - def push_legacy_margin(self, margin, where=None): - self.current_fragments[-1].push_legacy_margin(margin) - def build(self, document, raw_text=False, **kwargs): document.tree.getroot().txt_build(self) meta = document.meta @@ -123,27 +115,26 @@ class TxtBuilder: for translator in meta.translators ) ) - #builder.push_margin(2) - self.push_legacy_margin(1) + builder.push_margin(2) if meta.isbn_txt: - #builder.push_margin(2) - self.push_legacy_margin(1) + self.push_margin(2) isbn = meta.isbn_txt if isbn.startswith(('ISBN-' , 'ISBN ')): isbn = isbn[5:] self.push_text('ISBN {isbn}'.format(isbn=isbn)) #builder.push_margin(5) - #builder.push_margin(4) - self.push_legacy_margin(1) + self.push_margin(4) self.exit_fragment() - text = ''.join(self.fragments['header'].pieces) + ''.join(self.fragments[None].pieces) + text = ''.join(self.fragments[None].pieces).lstrip() if raw_text: result = text else: + text = ''.join(self.fragments['header'].pieces) + text + if meta.license: license_description = self.license_description['pol'].format(meta=meta) else: diff --git a/src/librarian/elements/__init__.py b/src/librarian/elements/__init__.py index b08c3e1..0191ae5 100644 --- a/src/librarian/elements/__init__.py +++ b/src/librarian/elements/__init__.py @@ -132,11 +132,11 @@ WL_ELEMENTS = { "wywiad_odp": blocks.WywiadOdp, # Inline MathML, should really be namespaced. - "mrow": etree.ElementBase, - "mi": etree.ElementBase, - "mo": etree.ElementBase, - "msup": etree.ElementBase, - "mn": etree.ElementBase, - "mfrac": etree.ElementBase, - "mfenced": etree.ElementBase, + "mrow": styles.MRow, + "mi": styles.M, + "mo": styles.M, + "msup": styles.MSup, + "mn": styles.M, + "mfrac": styles.MFrac, + "mfenced": styles.MFenced, } diff --git a/src/librarian/elements/base.py b/src/librarian/elements/base.py index 2349f16..060449c 100644 --- a/src/librarian/elements/base.py +++ b/src/librarian/elements/base.py @@ -45,12 +45,11 @@ class WLElement(etree.ElementBase): text_substitutions = [ ('---', '—'), ('--', '–'), - #('...', '…'), # Temporary turnoff for epub + ('...', '…'), (',,', '„'), ('"', '”'), ('\ufeff', ''), - - ("'", "\u2019"), # This was enabled for epub. + ("'", "\u2019"), ] @property @@ -118,9 +117,9 @@ class WLElement(etree.ElementBase): text = text or '' for e, s in self.text_substitutions: text = text.replace(e, s) - # FIXME: TEmporary turnoff -# text = re.sub(r'\s+', ' ', text) -### TODO: Added now for epub + + if getattr(builder, 'normalize_whitespace', False): + text = re.sub(r'\s+', ' ', text) if getattr(builder, 'hyphenator', None) is not None: newt = '' @@ -144,8 +143,12 @@ class WLElement(etree.ElementBase): text = text.rstrip() builder.push_text(text) for i, child in enumerate(self): + real_child_count = 0 if isinstance(child, WLElement): getattr(child, build_method)(builder) + self.after_child(builder, real_child_count) + real_child_count += 1 + # FIXME base builder api elif getattr(builder, 'debug', False) and child.tag is etree.Comment: builder.process_comment(child) @@ -155,21 +158,23 @@ class WLElement(etree.ElementBase): text = text.rstrip() builder.push_text(text) + def after_child(self, builder, child_count): + fn = getattr(builder, 'after_child_fn', None) + if fn: + getattr(self, builder.after_child_fn)(builder, child_count) + + def txt_after_child(self, builder, child_count): + pass + def _txt_build_inner(self, builder): self._build_inner(builder, 'txt_build') def txt_build(self, builder): - if hasattr(self, 'TXT_LEGACY_TOP_MARGIN'): - builder.push_legacy_margin(self.TXT_LEGACY_TOP_MARGIN) - else: - builder.push_margin(self.TXT_TOP_MARGIN) + builder.push_margin(self.TXT_TOP_MARGIN) builder.push_text(self.TXT_PREFIX, True) self._txt_build_inner(builder) builder.push_text(self.TXT_SUFFIX, True) - if hasattr(self, 'TXT_LEGACY_BOTTOM_MARGIN'): - builder.push_legacy_margin(self.TXT_LEGACY_BOTTOM_MARGIN) - else: - builder.push_margin(self.TXT_BOTTOM_MARGIN) + builder.push_margin(self.TXT_BOTTOM_MARGIN) def _html_build_inner(self, builder): self._build_inner(builder, 'html_build') diff --git a/src/librarian/elements/blocks/dedykacja.py b/src/librarian/elements/blocks/dedykacja.py index 265b268..ae00b72 100644 --- a/src/librarian/elements/blocks/dedykacja.py +++ b/src/librarian/elements/blocks/dedykacja.py @@ -7,7 +7,8 @@ from ..base import WLElement class Dedykacja(WLElement): NUMBERING = 'i' - TXT_LEGACY_TOP_MARGIN = 2 + TXT_TOP_MARGIN = 2 + TXT_BOTTOM_MARGIN = 4 EPUB_TAG = HTML_TAG = "div" EPUB_CLASS = HTML_CLASS = "dedication" diff --git a/src/librarian/elements/blocks/dlugi_cytat.py b/src/librarian/elements/blocks/dlugi_cytat.py index 0a55833..bdac225 100644 --- a/src/librarian/elements/blocks/dlugi_cytat.py +++ b/src/librarian/elements/blocks/dlugi_cytat.py @@ -8,9 +8,7 @@ class DlugiCytat(WLElement): CAN_HAVE_TEXT = False TXT_TOP_MARGIN = 3 - TXT_BOTTOM_MARGIN = 2 - TXT_LEGACY_TOP_MARGIN = 1 - TXT_LEGACY_BOTTOM_MARGIN = 0 + TXT_BOTTOM_MARGIN = 3 HTML_TAG = 'blockquote' diff --git a/src/librarian/elements/blocks/poezja_cyt.py b/src/librarian/elements/blocks/poezja_cyt.py index 2b351ca..dd26d13 100644 --- a/src/librarian/elements/blocks/poezja_cyt.py +++ b/src/librarian/elements/blocks/poezja_cyt.py @@ -9,8 +9,6 @@ class PoezjaCyt(WLElement): TXT_TOP_MARGIN = 3 TXT_BOTTOM_MARGIN = 3 - TXT_LEGACY_TOP_MARGIN = 1 - TXT_LEGACY_BOTTOM_MARGIN = 0 HTML_TAG = 'blockquote' diff --git a/src/librarian/elements/drama/didaskalia.py b/src/librarian/elements/drama/didaskalia.py index 8f461dd..b6b53f9 100644 --- a/src/librarian/elements/drama/didaskalia.py +++ b/src/librarian/elements/drama/didaskalia.py @@ -9,8 +9,6 @@ class Didaskalia(WLElement): TXT_TOP_PARGIN = 2 TXT_BOTTOM_MARGIN = 2 - TXT_LEGACY_TOP_MARGIN = 2 - TXT_LEGACY_BOTTOM_MARGIN = 0 TXT_PREFIX = "/ " TXT_SUFFIX = " /" diff --git a/src/librarian/elements/drama/lista_osob.py b/src/librarian/elements/drama/lista_osob.py index f9e210d..d8ea32a 100644 --- a/src/librarian/elements/drama/lista_osob.py +++ b/src/librarian/elements/drama/lista_osob.py @@ -11,8 +11,6 @@ class ListaOsob(WLElement): TXT_TOP_MARGIN = 3 TXT_BOTTOM_MARGIN = 3 - TXT_LEGACY_TOP_MARGIN = 3 - TXT_LEGACY_BOTTOM_MARGIN = 1 HTML_TAG = "div" HTML_CLASS = "person-list" diff --git a/src/librarian/elements/drama/lista_osoba.py b/src/librarian/elements/drama/lista_osoba.py index 2341918..7319321 100644 --- a/src/librarian/elements/drama/lista_osoba.py +++ b/src/librarian/elements/drama/lista_osoba.py @@ -9,8 +9,6 @@ class ListaOsoba(WLElement): TXT_TOP_MARGIN = 1 TXT_BOTTOM_MARGIN = 1 - TXT_LEGACY_TOP_MARGIN = 1 - TXT_LEGACY_BOTTOM_MARGIN = 0 TXT_PREFIX = " * " EPUB_TAG = HTML_TAG = "li" diff --git a/src/librarian/elements/drama/naglowek_osoba.py b/src/librarian/elements/drama/naglowek_osoba.py index 43aa1d3..6ff6761 100644 --- a/src/librarian/elements/drama/naglowek_osoba.py +++ b/src/librarian/elements/drama/naglowek_osoba.py @@ -9,8 +9,6 @@ class NaglowekOsoba(WLElement): TXT_TOP_MARGIN = 3 TXT_BOTTOM_MARGIN = 2 - TXT_LEGACY_TOP_MARGIN = 3 - TXT_LEGACY_BOTTOM_MARGIN = 0 HTML_TAG = "h4" diff --git a/src/librarian/elements/figures/kol.py b/src/librarian/elements/figures/kol.py index 9b425de..fa09fc7 100644 --- a/src/librarian/elements/figures/kol.py +++ b/src/librarian/elements/figures/kol.py @@ -6,3 +6,4 @@ from ..base import WLElement class Kol(WLElement): EPUB_TAG = HTML_TAG = 'td' + TXT_PREFIX = ' ' * 4 diff --git a/src/librarian/elements/figures/tabela.py b/src/librarian/elements/figures/tabela.py index 783fcb6..5ab04e0 100644 --- a/src/librarian/elements/figures/tabela.py +++ b/src/librarian/elements/figures/tabela.py @@ -6,6 +6,10 @@ from ..base import WLElement class Tabela(WLElement): NUMBERING = 'i' + CAN_HAVE_TEXT = False + + TXT_TOP_MARGIN = 3 + TXT_BOTTOM_MARGIN = 3 EPUB_TAG = HTML_TAG = 'table' diff --git a/src/librarian/elements/figures/wiersz.py b/src/librarian/elements/figures/wiersz.py index c5d355a..c013558 100644 --- a/src/librarian/elements/figures/wiersz.py +++ b/src/librarian/elements/figures/wiersz.py @@ -5,4 +5,7 @@ from ..base import WLElement class Wiersz(WLElement): + CAN_HAVE_TEXT = False EPUB_TAG = HTML_TAG = 'tr' + TXT_TOP_MARGIN = 1 + TXT_BOTTOM_MARGIN = 1 diff --git a/src/librarian/elements/front/autor_utworu.py b/src/librarian/elements/front/autor_utworu.py index 3e35b0b..0f71cb5 100644 --- a/src/librarian/elements/front/autor_utworu.py +++ b/src/librarian/elements/front/autor_utworu.py @@ -6,7 +6,6 @@ from .base import HeaderElement class AutorUtworu(HeaderElement): TXT_BOTTOM_MARGIN = 2 - TXT_LEGACY_BOTTOM_MARGIN = 2 HTML_CLASS = 'wl author' diff --git a/src/librarian/elements/front/dzielo_nadrzedne.py b/src/librarian/elements/front/dzielo_nadrzedne.py index cc70164..cc16a81 100644 --- a/src/librarian/elements/front/dzielo_nadrzedne.py +++ b/src/librarian/elements/front/dzielo_nadrzedne.py @@ -6,7 +6,6 @@ from .base import HeaderElement class DzieloNadrzedne(HeaderElement): TXT_BOTTOM_MARGIN = 1 - TXT_LEGACY_BOTTOM_MARGIN = 1 HTML_CLASS = "wl collection" diff --git a/src/librarian/elements/front/motto.py b/src/librarian/elements/front/motto.py index a6769b8..ac9f209 100644 --- a/src/librarian/elements/front/motto.py +++ b/src/librarian/elements/front/motto.py @@ -7,8 +7,8 @@ from ..base import WLElement class Motto(WLElement): NUMBERING = 'i' - TXT_LEGACY_TOP_MARGIN = 4 - TXT_LEGACY_BOTTOM_MARGIN = 2 + TXT_TOP_MARGIN = 4 + TXT_BOTTOM_MARGIN = 2 EPUB_TAG = HTML_TAG = "div" EPUB_CLASS = HTML_CLASS = "motto" diff --git a/src/librarian/elements/front/nazwa_utworu.py b/src/librarian/elements/front/nazwa_utworu.py index dd40266..9e3bd51 100644 --- a/src/librarian/elements/front/nazwa_utworu.py +++ b/src/librarian/elements/front/nazwa_utworu.py @@ -6,7 +6,6 @@ from .base import HeaderElement class NazwaUtworu(HeaderElement): TXT_BOTTOM_MARGIN = 1 - TXT_LEGACY_BOTTOM_MARGIN = 1 HTML_CLASS = 'wl title' diff --git a/src/librarian/elements/front/podtytul.py b/src/librarian/elements/front/podtytul.py index 711b3fa..01991d5 100644 --- a/src/librarian/elements/front/podtytul.py +++ b/src/librarian/elements/front/podtytul.py @@ -6,7 +6,6 @@ from .base import HeaderElement class Podtytul(HeaderElement): TXT_BOTTOM_MARGIN = 1 - TXT_LEGACY_BOTTOM_MARGIN = 1 HTML_CLASS = 'wl subtitle' diff --git a/src/librarian/elements/headers/naglowek_czesc.py b/src/librarian/elements/headers/naglowek_czesc.py index 11991ae..7d2fa0d 100644 --- a/src/librarian/elements/headers/naglowek_czesc.py +++ b/src/librarian/elements/headers/naglowek_czesc.py @@ -10,8 +10,6 @@ class NaglowekCzesc(WLElement): TXT_TOP_MARGIN = 5 TXT_BOTTOM_MARGIN = 2 - TXT_LEGACY_TOP_MARGIN = 5 - TXT_LEGACY_BOTTOM_MARGIN = 0 EPUB_TAG = HTML_TAG = "h2" HTML_CLASS = "wl" diff --git a/src/librarian/elements/headers/naglowek_podrozdzial.py b/src/librarian/elements/headers/naglowek_podrozdzial.py index 213ec00..6865362 100644 --- a/src/librarian/elements/headers/naglowek_podrozdzial.py +++ b/src/librarian/elements/headers/naglowek_podrozdzial.py @@ -10,8 +10,6 @@ class NaglowekPodrozdzial(WLElement): TXT_TOP_MARGIN = 3 TXT_BOTTOM_MARGIN = 2 - TXT_LEGACY_TOP_MARGIN = 3 - TXT_LEGACY_BOTTOM_MARGIN = 0 HTML_TAG = "h4" diff --git a/src/librarian/elements/headers/naglowek_rozdzial.py b/src/librarian/elements/headers/naglowek_rozdzial.py index 502dea1..e61f6a7 100644 --- a/src/librarian/elements/headers/naglowek_rozdzial.py +++ b/src/librarian/elements/headers/naglowek_rozdzial.py @@ -10,8 +10,6 @@ class NaglowekRozdzial(WLElement): TXT_TOP_MARGIN = 4 TXT_BOTTOM_MARGIN = 2 - TXT_LEGACY_TOP_MARGIN = 4 - TXT_LEGACY_BOTTOM_MARGIN = 0 HTML_TAG = 'h3' HTML_CLASS = 'wl' diff --git a/src/librarian/elements/headers/naglowek_scena.py b/src/librarian/elements/headers/naglowek_scena.py index e9ea5c7..a0ae5be 100644 --- a/src/librarian/elements/headers/naglowek_scena.py +++ b/src/librarian/elements/headers/naglowek_scena.py @@ -10,8 +10,6 @@ class NaglowekScena(WLElement): TXT_TOP_MARGIN = 4 TXT_BOTTOM_MARGIN = 2 - TXT_LEGACY_TOP_MARGIN = 4 - TXT_LEGACY_BOTTOM_MARGIN = 0 HTML_TAG = 'h3' diff --git a/src/librarian/elements/masters/__init__.py b/src/librarian/elements/masters/__init__.py index d4f3cf0..54f5ba1 100644 --- a/src/librarian/elements/masters/__init__.py +++ b/src/librarian/elements/masters/__init__.py @@ -7,4 +7,4 @@ from ..base import WLElement class Master(WLElement): CAN_HAVE_TEXT = False - TXT_LEGACY_BOTTOM_MARGIN = 2 + TXT_BOTTOM_MARGIN = 2 diff --git a/src/librarian/elements/paragraphs/akap.py b/src/librarian/elements/paragraphs/akap.py index 63f74b5..6ee10d7 100644 --- a/src/librarian/elements/paragraphs/akap.py +++ b/src/librarian/elements/paragraphs/akap.py @@ -10,8 +10,6 @@ class Akap(WLElement): TXT_TOP_MARGIN = 2 TXT_BOTTOM_MARGIN = 2 - TXT_LEGACY_TOP_MARGIN = 2 - TXT_LEGACY_BOTTOM_MARGIN = 0 EPUB_CLASS = 'paragraph' diff --git a/src/librarian/elements/poetry/strofa.py b/src/librarian/elements/poetry/strofa.py index bccb01b..f698bc3 100644 --- a/src/librarian/elements/poetry/strofa.py +++ b/src/librarian/elements/poetry/strofa.py @@ -12,8 +12,6 @@ class Strofa(WLElement): TXT_TOP_MARGIN = 2 TXT_BOTTOM_MARGIN = 2 - TXT_LEGACY_TOP_MARGIN = 1 - TXT_LEGACY_BOTTOM_MARGIN = 0 EPUB_TAG = HTML_TAG = 'div' EPUB_CLASS = HTML_CLASS = 'stanza' diff --git a/src/librarian/elements/poetry/wers.py b/src/librarian/elements/poetry/wers.py index 127d5bd..cf2089c 100644 --- a/src/librarian/elements/poetry/wers.py +++ b/src/librarian/elements/poetry/wers.py @@ -9,8 +9,6 @@ class Wers(WLElement): TXT_TOP_MARGIN = 1 TXT_BOTTOM_MARGIN = 1 - TXT_LEGACY_TOP_MARGIN = 1 - TXT_LEGACY_BOTTOM_MARGIN = 0 EPUB_TAG = HTML_TAG = 'div' EPUB_CLASS = 'verse' diff --git a/src/librarian/elements/separators/sekcja_asterysk.py b/src/librarian/elements/separators/sekcja_asterysk.py index 35bd7a7..3ba8270 100644 --- a/src/librarian/elements/separators/sekcja_asterysk.py +++ b/src/librarian/elements/separators/sekcja_asterysk.py @@ -7,8 +7,6 @@ from ..base import WLElement class SekcjaAsterysk(WLElement): TXT_TOP_MARGIN = 2 TXT_BOTTOM_MARGIN = 4 - TXT_LEGACY_TOP_MARGIN = 2 - TXT_LEGACY_BOTTOM_MARGIN = 2 EPUB_TAG = HTML_TAG = "p" HTML_CLASS = HTML_CLASS = "spacer-asterisk" diff --git a/src/librarian/elements/separators/sekcja_swiatlo.py b/src/librarian/elements/separators/sekcja_swiatlo.py index 805078e..e3ab103 100644 --- a/src/librarian/elements/separators/sekcja_swiatlo.py +++ b/src/librarian/elements/separators/sekcja_swiatlo.py @@ -6,7 +6,6 @@ from ..base import WLElement class SekcjaSwiatlo(WLElement): TXT_BOTTOM_MARGIN = 6 - TXT_LEGACY_BOTTOM_MARGIN = 4 HTML_TAG = "hr" HTML_CLASS = "spacer" diff --git a/src/librarian/elements/separators/separator_linia.py b/src/librarian/elements/separators/separator_linia.py index 8874967..e5a5218 100644 --- a/src/librarian/elements/separators/separator_linia.py +++ b/src/librarian/elements/separators/separator_linia.py @@ -7,8 +7,6 @@ from ..base import WLElement class SeparatorLinia(WLElement): TXT_TOP_MARGIN = 4 TXT_BOTTOM_MARGIN = 4 - TXT_LEGACY_TOP_MARGIN = 2 - TXT_LEGACY_BOTTOM_MARGIN = 2 EPUB_TAG = HTML_TAG = "hr" EPUB_CLASS = HTML_CLASS = "spacer-line" diff --git a/src/librarian/elements/styles/__init__.py b/src/librarian/elements/styles/__init__.py index 4453490..dd35dfc 100644 --- a/src/librarian/elements/styles/__init__.py +++ b/src/librarian/elements/styles/__init__.py @@ -2,7 +2,7 @@ # Copyright © Fundacja Wolne Lektury. See NOTICE for more information. # from .indeks_dolny import IndeksDolny -from .mat import Mat +from .mat import Mat, M, MRow, MFenced, MFrac, MSup from .slowo_obce import SlowoObce from .tytul_dziela import TytulDziela from .wieksze_odstepy import WiekszeOdstepy diff --git a/src/librarian/elements/styles/mat.py b/src/librarian/elements/styles/mat.py index 68fcc3f..1512c32 100644 --- a/src/librarian/elements/styles/mat.py +++ b/src/librarian/elements/styles/mat.py @@ -6,6 +6,8 @@ from ..base import WLElement class Mat(WLElement): + STRIP = True + def html_build(self, builder): e = copy(self) e.tag = 'math' @@ -15,3 +17,31 @@ class Mat(WLElement): def epub_build(self, builder): builder.start_element('img', {"src": builder.mathml(self)}) builder.end_element() + + +class M(WLElement): + STRIP = True + + +class MRow(M): + pass + + +class MFenced(M): + TXT_PREFIX = '(' + TXT_SUFFIX = ')' + + +class MFrac(M): + TXT_PREFIX = '(' + TXT_SUFFIX = ')' + + def txt_after_child(self, builder, child_count): + if child_count: + builder.push_text(') / (') + + +class MSup(M): + def txt_after_child(self, builder, child_count): + if child_count: + builder.push_text(' ^ ') diff --git a/src/librarian/elements/tools/__init__.py b/src/librarian/elements/tools/__init__.py index c4820b1..69a26ea 100644 --- a/src/librarian/elements/tools/__init__.py +++ b/src/librarian/elements/tools/__init__.py @@ -70,3 +70,13 @@ class Tab(WLElement): } get_epub_attr = get_html_attr + + def txt_build(self, builder): + szer = self.get('szer', '1').strip() + if szer.endswith('em'): + szer = szer[:-2] + try: + szer = int(szer) + except: + szer = 1 + builder.push_text(' ' * 4 * szer) diff --git a/tests/files/tags/didaskalia/1.expected.html b/tests/files/tags/didaskalia/1.expected.html index efefbab..88137d5 100644 --- a/tests/files/tags/didaskalia/1.expected.html +++ b/tests/files/tags/didaskalia/1.expected.html @@ -8,7 +8,7 @@ Na toż bym się, mocium panie,
        Kawalerstwa dziś w
        uderzając w stół
        -
        By kto... niech go piorun trzaśnie!
        +
        By kto… niech go piorun trzaśnie!
        Długo będzie na to czekał,
        po krótkim milczeniu, biorąc talerz
        @@ -21,7 +21,7 @@ Na toż bym się, mocium panie,
        Kawalerstwa dziś w
        Bawi z nami — w domu Klary,
        Bo krewniaczka jej daleka,
        -10
        Ale mnie się wszystko zdaje...
        +10
        Ale mnie się wszystko zdaje…
        diff --git a/tests/files/tags/kwestia/1.expected.html b/tests/files/tags/kwestia/1.expected.html index 2fe9773..54109b5 100644 --- a/tests/files/tags/kwestia/1.expected.html +++ b/tests/files/tags/kwestia/1.expected.html @@ -4,7 +4,7 @@ 1
        Więc jako dawniej czynili mocarze,
        Z Lechem się mieniał Scyta na obrączki;
        A pokochawszy mocniej sercem, w darze
        -
        Dał mu koronę... stąd nasza korona.
        +
        Dał mu koronę… stąd nasza korona.
        5
        Zbawiciel niegdyś wyciągając rączki
        Szedł do niej z matki zadumanej łona
        I ku rubinom podawał się cały
        diff --git a/tests/files/tags/kwestia/2.expected.html b/tests/files/tags/kwestia/2.expected.html index 5783d97..b73287a 100644 --- a/tests/files/tags/kwestia/2.expected.html +++ b/tests/files/tags/kwestia/2.expected.html @@ -1,11 +1,11 @@

        GŁOS HESI

        -1

        Mamuńciu, tak zimno! troszkę ciepłej wody...

        +1

        Mamuńciu, tak zimno! troszkę ciepłej wody…

        DULSKA

        -2

        Jeszcze czego? Hartujcie się... Felicjan! wstajesz? Wiesz? ten błazen, twój syn, nie wrócił jeszcze do domu! Co? nic nie mówisz? naturalnie. +2

        Jeszcze czego? Hartujcie się… Felicjan! wstajesz? Wiesz? ten błazen, twój syn, nie wrócił jeszcze do domu! Co? nic nie mówisz? naturalnie. Ojciec toleruje. Niedaleko padło jabłko od jabłoni. Ale jak będą dłużki małe — nie zapłacę.

        diff --git a/tests/files/tags/motto_podpis/1.expected.html b/tests/files/tags/motto_podpis/1.expected.html index 1ff589b..ec6cecb 100644 --- a/tests/files/tags/motto_podpis/1.expected.html +++ b/tests/files/tags/motto_podpis/1.expected.html @@ -5,7 +5,7 @@
        1
        Dovete adunque sapere come sono/ -due generazioni da combattere...../ +due generazioni da combattere…../ bisogna essere volpe e leone.
        diff --git a/tests/files/tags/naglowek_osoba/1.expected.html b/tests/files/tags/naglowek_osoba/1.expected.html index 4903bb3..1bbd782 100644 --- a/tests/files/tags/naglowek_osoba/1.expected.html +++ b/tests/files/tags/naglowek_osoba/1.expected.html @@ -6,7 +6,7 @@ 1
        Piękne dobra w każdym względzie —
        Lasy — gleba wyśmienita —
        Dobrą żoną pewnie będzie —
        -
        Co za czynsze! — To kobiéta!...
        +
        Co za czynsze! — To kobiéta!…
        5
        Trzy folwarki!
        diff --git a/tests/files/tags/nota/2.expected.html b/tests/files/tags/nota/2.expected.html index 6006ef6..d78347f 100644 --- a/tests/files/tags/nota/2.expected.html +++ b/tests/files/tags/nota/2.expected.html @@ -12,7 +12,7 @@
        I nie przyjmował nigdy, jak wiek wiekiem.
        Bo glina w glinę wtapia się bez przerwy,
        5
        Gdy sprzeczne ciała zbija się aż ćwiekiem
        -
        Później... lub pierwéj...
        +
        Później… lub pierwéj…

        Pisałem w Paryżu 1856 w styczniu.

        diff --git a/tests/files/tags/nota/3.expected.html b/tests/files/tags/nota/3.expected.html index b7d62b4..243db4a 100644 --- a/tests/files/tags/nota/3.expected.html +++ b/tests/files/tags/nota/3.expected.html @@ -1,8 +1,8 @@
        1

        Jego marzenie się nie spełniło: nie ożenił się, choć był już na to zupełnie zdecydowany, -gdy skończono oporządzać jego mieszkanie. [...] Rzecz dziwna, czym jest mundur dla takich ludzi.

        +gdy skończono oporządzać jego mieszkanie. […] Rzecz dziwna, czym jest mundur dla takich ludzi.

        Uwaga tłumacza. Drukowane obecnie w „Nowej Reformie” Wspomnienia Sybiraka (pamiętniki Józefa Bogusławskiego) pozwalają szczęśliwym trafem podać w całości nazwiska Polaków, o których mówi Dostojewski w swoich pamiętnikach, -oznaczając te nazwiska tylko pierwszymi literami, z dodaniem czasami końcówek. [...]

        +oznaczając te nazwiska tylko pierwszymi literami, z dodaniem czasami końcówek. […]

        diff --git a/tests/files/tags/poezja_cyt/1.expected.html b/tests/files/tags/poezja_cyt/1.expected.html index b0d195b..17e1d92 100644 --- a/tests/files/tags/poezja_cyt/1.expected.html +++ b/tests/files/tags/poezja_cyt/1.expected.html @@ -1,4 +1,4 @@
        1
        Tymczasem przenoś duszę moją utęsknioną
        -
        Do tych pagórków leśnych, do tych łąk zielonych...
        +
        Do tych pagórków leśnych, do tych łąk zielonych…
        diff --git a/tests/files/tags/slowo_obce/1.expected.html b/tests/files/tags/slowo_obce/1.expected.html index 8fa6808..5c8ce78 100644 --- a/tests/files/tags/slowo_obce/1.expected.html +++ b/tests/files/tags/slowo_obce/1.expected.html @@ -1,3 +1,3 @@
        -1

        Na czwarty dzień przywiózł mu stójka z osłowickiej apteki diachylum; Zołzikiewicz rozsmarował na płatek...

        +1

        Na czwarty dzień przywiózł mu stójka z osłowickiej apteki diachylum; Zołzikiewicz rozsmarował na płatek…

        diff --git a/tests/files/tags/tabela/1.expected.html b/tests/files/tags/tabela/1.expected.html index fe9ef5f..f839494 100644 --- a/tests/files/tags/tabela/1.expected.html +++ b/tests/files/tags/tabela/1.expected.html @@ -1,22 +1,22 @@
        - - - - - - - - + + + + + + + +
        ab
        cd
        ab
        cd
        - - - - - - - - + + + + + + + +
        ab
        cd
        ab
        cd
        diff --git a/tests/files/tags/tytul_dziela/1.expected.html b/tests/files/tags/tytul_dziela/1.expected.html index 364942d..f246117 100644 --- a/tests/files/tags/tytul_dziela/1.expected.html +++ b/tests/files/tags/tytul_dziela/1.expected.html @@ -4,5 +4,5 @@ Kilka uwag o „Hamlecie” Szekspira - pióra...

        + pióra…

        diff --git a/tests/files/tags/wers_wciety/1.expected.html b/tests/files/tags/wers_wciety/1.expected.html index 0ee7c74..b2254fb 100644 --- a/tests/files/tags/wers_wciety/1.expected.html +++ b/tests/files/tags/wers_wciety/1.expected.html @@ -1,6 +1,6 @@

        -Julisz SłowackiAnioł ognisty — mój anioł lewy... +Julisz SłowackiAnioł ognisty — mój anioł lewy…

        1
        Anioł ognisty — mój anioł lewy
        diff --git a/tests/files/tags/wers_wciety/2.expected.html b/tests/files/tags/wers_wciety/2.expected.html index 85b8e22..f502985 100644 --- a/tests/files/tags/wers_wciety/2.expected.html +++ b/tests/files/tags/wers_wciety/2.expected.html @@ -1,8 +1,10 @@ -
        1
        zwykły
        -
        wcięty
        -
        wcięty 1
        -
        wcięty 2
        - 5
        wcięty 25
        -
        akapitowy
        -
        środek
        -
        do prawej
        +
        +1
        zwykły
        +
        wcięty
        +
        wcięty 1
        +
        wcięty 2
        +5
        wcięty 25
        +
        akapitowy
        +
        środek
        +
        do prawej
        +
        diff --git a/tests/files/tags/wers_wciety/2.xml b/tests/files/tags/wers_wciety/2.xml index c31d2cb..9ce9f6a 100644 --- a/tests/files/tags/wers_wciety/2.xml +++ b/tests/files/tags/wers_wciety/2.xml @@ -1,10 +1,10 @@ - zwykły - wcięty - wcięty 1 - wcięty 2 - wcięty 25 - akapitowy - środek + zwykły/ + wcięty/ + wcięty 1/ + wcięty 2/ + wcięty 25/ + akapitowy/ + środek/ do prawej diff --git a/tests/files/tags/wyroznienie/1.expected.html b/tests/files/tags/wyroznienie/1.expected.html index 65cffe3..d160084 100644 --- a/tests/files/tags/wyroznienie/1.expected.html +++ b/tests/files/tags/wyroznienie/1.expected.html @@ -5,5 +5,5 @@
        Blade jak świt,
        5
        — Gdy życia koniec szepce do początku:
        -„Nie stargam cię ja — nie! — Ja, u-wydatnię!...”
        +„Nie stargam cię ja — nie! — Ja, u-wydatnię!…”
        diff --git a/tests/files/text/asnyk_miedzy_nami_expected_raw.txt b/tests/files/text/asnyk_miedzy_nami_expected_raw.txt index cac61d8..29e243a 100644 --- a/tests/files/text/asnyk_miedzy_nami_expected_raw.txt +++ b/tests/files/text/asnyk_miedzy_nami_expected_raw.txt @@ -1,5 +1,3 @@ - - Między nami nic nie było! Żadnych zwierzeń, wyznań żadnych! Nic nas z sobą nie łączyło — diff --git a/tests/test_text.py b/tests/test_text.py index 7797530..9109413 100644 --- a/tests/test_text.py +++ b/tests/test_text.py @@ -2,9 +2,7 @@ # Copyright © Fundacja Wolne Lektury. See NOTICE for more information. # import unittest -from librarian import NoDublinCore from librarian.builders import builders -from librarian.parser import WLDocument as LegacyWLDocument from librarian.document import WLDocument from .utils import get_fixture @@ -12,16 +10,6 @@ from .utils import get_fixture class TextTests(unittest.TestCase): maxDiff = None - def test_transform_legacy(self): - expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected.txt') - - text = LegacyWLDocument.from_file( - get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml') - ).as_text().get_bytes().decode('utf-8') - - with open(expected_output_file_path, 'rb') as f: - self.assertEqual(text, f.read().decode('utf-8')) - def test_transform(self): expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected.txt') @@ -36,22 +24,9 @@ class TextTests(unittest.TestCase): def test_transform_raw(self): expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected_raw.txt') - text = LegacyWLDocument.from_file( - get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml') - ).as_text(flags=['raw-text']).get_bytes().decode('utf-8') + text = WLDocument( + filename=get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml') + ).build(builders['txt'], raw_text=True).get_bytes().decode('utf-8') with open(expected_output_file_path, 'rb') as f: self.assertEqual(text, f.read().decode('utf-8')) - - def test_no_dublincore(self): - with self.assertRaises(NoDublinCore): - LegacyWLDocument.from_file( - get_fixture('text', 'asnyk_miedzy_nami_nodc.xml') - ).as_text() - - def test_passing_parse_dublincore_to_transform(self): - """Passing parse_dublincore=False to the constructor omits DublinCore parsing.""" - LegacyWLDocument.from_file( - get_fixture('text', 'asnyk_miedzy_nami_nodc.xml'), - parse_dublincore=False, - ).as_text() -- 2.20.1 From ddeba8a8483dc73d0103030afe46fc5bce51d8a0 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 17 Sep 2024 14:17:16 +0200 Subject: [PATCH 06/13] Remove legacy code for txt. --- MANIFEST.in | 1 - scripts/book2txt | 32 --- setup.py | 1 - src/librarian/functions.py | 26 -- src/librarian/parser.py | 8 - src/librarian/text.py | 133 ----------- src/librarian/xslt/book2txt.xslt | 391 ------------------------------- 7 files changed, 592 deletions(-) delete mode 100755 scripts/book2txt delete mode 100644 src/librarian/text.py delete mode 100644 src/librarian/xslt/book2txt.xslt diff --git a/MANIFEST.in b/MANIFEST.in index 40f0f90..cdd48f6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,7 +4,6 @@ include NOTICE include tox.ini recursive-include scripts *.py *.css recursive-include tests *.py *.xml *.html *.out *.txt *.jpeg -include src/librarian/xslt/*.xslt include src/librarian/pdf/* include src/librarian/fb2/* include src/librarian/fonts/* diff --git a/scripts/book2txt b/scripts/book2txt deleted file mode 100755 index 8b75f98..0000000 --- a/scripts/book2txt +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -# This file is part of Librarian, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from librarian.book2anything import Book2Anything, Option -from librarian.parser import WLDocument - - -class Book2Txt(Book2Anything): - format_name = "TXT" - ext = "txt" - uses_cover = False - uses_provider = False - parser_options = [ - Option('-i', '--ignore-dublin-core', dest='parse_dublincore', - action='store_false', default=True, - help='don\'t try to parse dublin core metadata') - ] - transform_options = [ - Option('-w', '--wrap', action='store', type='int', dest='wrapping', default=0, - help='set line wrap column') - ] - transform_flags = [ - Option('-r', '--raw', dest='raw-text', - action='store_true', default=False, - help='Produce raw text, without any surrounding info.') - ] - transform = WLDocument.as_text - - -if __name__ == '__main__': - Book2Txt.run() diff --git a/setup.py b/setup.py index 2af0a05..afca003 100755 --- a/setup.py +++ b/setup.py @@ -51,7 +51,6 @@ setup( ] }, scripts=[ - 'scripts/book2txt', 'scripts/book2pdf', 'scripts/book2fb2', 'scripts/book2cover', diff --git a/src/librarian/functions.py b/src/librarian/functions.py index bcaa784..cde6494 100644 --- a/src/librarian/functions.py +++ b/src/librarian/functions.py @@ -64,32 +64,6 @@ def reg_ends_white(): _register_function(ends_white) -def reg_wrap_words(): - def wrap_words(context, text, wrapping): - """ - XPath extension function automatically wrapping words - in passed text. - """ - if isinstance(text, list): - text = ''.join(text) - if not wrapping: - return text - - words = re.split(r'\s', text) - - line_length = 0 - lines = [[]] - for word in words: - line_length += len(word) + 1 - if line_length > wrapping: - # Max line length was exceeded. We create new line - lines.append([]) - line_length = len(word) - lines[-1].append(word) - return '\n'.join(' '.join(line) for line in lines) - _register_function(wrap_words) - - def reg_person_name(): def person_name(context, text): """ Converts "Name, Forename" to "Forename Name" """ diff --git a/src/librarian/parser.py b/src/librarian/parser.py index b4e4c5c..6e0a9c9 100644 --- a/src/librarian/parser.py +++ b/src/librarian/parser.py @@ -222,14 +222,6 @@ class WLDocument: # Converters - def as_html(self, *args, **kwargs): - from librarian import html - return html.transform(self, *args, **kwargs) - - def as_text(self, *args, **kwargs): - from librarian import text - return text.transform(self, *args, **kwargs) - def as_pdf(self, *args, **kwargs): from librarian import pdf return pdf.transform(self, *args, **kwargs) diff --git a/src/librarian/text.py b/src/librarian/text.py deleted file mode 100644 index d3df5fe..0000000 --- a/src/librarian/text.py +++ /dev/null @@ -1,133 +0,0 @@ -# This file is part of Librarian, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Wolne Lektury. See NOTICE for more information. -# -import copy -from librarian import functions, OutputFile, get_resource -from lxml import etree -import io -import os - - -functions.reg_substitute_entities() -functions.reg_wrap_words() -functions.reg_strip() -functions.reg_person_name() - - -with io.open(get_resource("res/text/template.txt")) as f: - TEMPLATE = f.read() - - -def transform(wldoc, flags=None, **options): - """ - Transforms input_file in XML to output_file in TXT. - possible flags: raw-text, - """ - # Parse XSLT - style_filename = os.path.join(os.path.dirname(__file__), - 'xslt/book2txt.xslt') - style = etree.parse(style_filename) - - document = copy.deepcopy(wldoc) - del wldoc - document.swap_endlines() - - if flags: - for flag in flags: - document.edoc.getroot().set(flag, 'yes') - if 'wrapping' in options: - options['wrapping'] = str(options['wrapping']) - - result = document.transform(style, **options) - - if not flags or 'raw-text' not in flags: - if document.book_info: - parsed_dc = document.book_info - description = parsed_dc.description - url = document.book_info.url - - license_name = parsed_dc.license_description - license = parsed_dc.license - license_description = [ - ( - "Wszystkie zasoby Wolnych Lektur możesz swobodnie wykorzystywać, " - "publikować i rozpowszechniać pod warunkiem zachowania warunków " - "licencji i zgodnie z Zasadami wykorzystania Wolnych Lektur." - ) - ] - - if license: - license_description.append( - "Ten utwór jest udostępniony na licencji %s: %s" % ( - license_name, license - ) - ) - else: - license_description.append( - "Ten utwór jest w domenie publicznej." - ) - license_description.append( - "Wszystkie materiały dodatkowe (przypisy, motywy literackie) są " - "udostępnione na Licencji Wolnej Sztuki 1.3: " - "https://artlibre.org/licence/lal/pl/\n" - "Fundacja Wolne Lektury zastrzega sobie prawa do wydania " - "krytycznego zgodnie z art. Art.99(2) Ustawy o prawach autorskich " - "i prawach pokrewnych.\nWykorzystując zasoby z Wolnych Lektur, " - "należy pamiętać o zapisach licencji oraz zasadach, które " - "spisaliśmy w Zasadach wykorzystania Wolnych Lektur: " - "https://wolnelektury.pl/info/zasady-wykorzystania/\nZapoznaj " - "się z nimi, zanim udostępnisz dalej nasze książki." - ) - license_description = "\n".join(license_description) - - source = parsed_dc.source_name - if source: - source = "\n\nTekst opracowany na podstawie: " + source - else: - source = '' - - contributors = ', '.join( - person.readable() - for person in sorted(set( - p for p in ( - parsed_dc.technical_editors + parsed_dc.editors - ) if p)) - ) - if contributors: - contributors = ( - "\n\nOpracowanie redakcyjne i przypisy: %s." - % contributors - ) - funders = ', '.join(parsed_dc.funders) - if funders: - funders = "\n\nPublikację wsparli i wsparły: %s." % funders - publisher = '\n\nWydawca: ' + ', '.join(parsed_dc.publisher) - isbn = getattr(parsed_dc, 'isbn_txt', None) - if isbn: - isbn = '\n\n' + isbn - else: - isbn = '' - else: - description = ("Publikacja zrealizowana w ramach projektu " - "Wolne Lektury (http://wolnelektury.pl).") - url = '*' * 10 - license_description = "" - source = "" - contributors = "" - funders = "" - publisher = "" - isbn = "" - result = (TEMPLATE % { - 'description': description, - 'url': url, - 'license_description': license_description, - 'text': str(result), - 'source': source, - 'contributors': contributors, - 'funders': funders, - 'publisher': publisher, - 'isbn': isbn, - }).encode('utf-8') - else: - result = str(result).encode('utf-8') - return OutputFile.from_bytes(b"\r\n".join(result.splitlines()) + b"\r\n") diff --git a/src/librarian/xslt/book2txt.xslt b/src/librarian/xslt/book2txt.xslt deleted file mode 100644 index d43c7d4..0000000 --- a/src/librarian/xslt/book2txt.xslt +++ /dev/null @@ -1,391 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/ / - - - - - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -„” - - - -** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -* - - - - - - - ------------------------------------------------- - - - - - - - - - - - - - - - - - - - - tłum. - - - , - - - - - - - - - - - - -ISBN - - - - - - - - - - - - - - - - - - - - - - - - -- 2.20.1 From 8939b6a23c816660a6c5366adb03fc0345c911ed Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 17 Sep 2024 16:08:51 +0200 Subject: [PATCH 07/13] fixes --- src/librarian/builders/html.py | 2 ++ src/librarian/builders/txt.py | 2 +- src/librarian/elements/comments/abstrakt.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librarian/builders/html.py b/src/librarian/builders/html.py index f2177ae..ac6b0a7 100644 --- a/src/librarian/builders/html.py +++ b/src/librarian/builders/html.py @@ -240,6 +240,8 @@ class AbstraktHtmlBuilder(HtmlBuilder): def build(self, document, element=None, **kwargs): if element is None: element = document.tree.find('//abstrakt') + if element is None: + return OutputFile.from_bytes(b'') element.attrib['_force'] = '1' return super().build(document, element, **kwargs) diff --git a/src/librarian/builders/txt.py b/src/librarian/builders/txt.py index 28fe709..92ddb46 100644 --- a/src/librarian/builders/txt.py +++ b/src/librarian/builders/txt.py @@ -115,7 +115,7 @@ class TxtBuilder: for translator in meta.translators ) ) - builder.push_margin(2) + self.push_margin(2) if meta.isbn_txt: self.push_margin(2) diff --git a/src/librarian/elements/comments/abstrakt.py b/src/librarian/elements/comments/abstrakt.py index f54a455..b5bf8d6 100644 --- a/src/librarian/elements/comments/abstrakt.py +++ b/src/librarian/elements/comments/abstrakt.py @@ -9,7 +9,7 @@ class Abstrakt(WLElement): pass def html_build(self, builder): - if not self.attrib['_force']: + if not self.attrib.get('_force', False): return return super().html_build(builder) -- 2.20.1 From eb25cada3f68db8f58689bff431edd321620fd72 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 18 Sep 2024 12:40:41 +0200 Subject: [PATCH 08/13] Counting belongs in document. --- src/librarian/builders/html.py | 12 ++---------- src/librarian/document.py | 9 ++++++++- src/librarian/elements/base.py | 10 +++++----- src/librarian/elements/tools/__init__.py | 5 +++-- tests/test_ref.py | 4 +--- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/librarian/builders/html.py b/src/librarian/builders/html.py index ac6b0a7..5bbe76a 100644 --- a/src/librarian/builders/html.py +++ b/src/librarian/builders/html.py @@ -32,7 +32,6 @@ class HtmlBuilder: self.header = etree.Element('h1') self.footnotes = etree.Element('div', id='footnotes') - self.counters = defaultdict(lambda: 1) self.nota_red = etree.Element('div', id='nota_red') @@ -71,8 +70,7 @@ class HtmlBuilder: def build(self, document, element=None, **kwargs): self.document = document - - self.assign_ids(self.document.tree) + self.document.assign_ids() self.prepare_images() if element is None: @@ -82,12 +80,6 @@ class HtmlBuilder: self.postprocess(document) return self.output() - def assign_ids(self, tree): - # Assign IDs depth-first, to account for any inside. - for _e, elem in etree.iterwalk(tree, events=('end',)): - if getattr(elem, 'NUMBERING', None): - elem.assign_id(self) - def prepare_images(self): # Temporarily use the legacy method, before transitioning to external generators. if self.gallery_path is None: @@ -135,7 +127,7 @@ class HtmlBuilder: if self.with_toc: add_table_of_contents(self.tree) - if self.counters['fn'] > 1: + if self.document.counters['fn'] > 1: fnheader = etree.Element("h3") fnheader.text = _("Footnotes") self.footnotes.insert(0, fnheader) diff --git a/src/librarian/document.py b/src/librarian/document.py index d61abb4..7f468fa 100644 --- a/src/librarian/document.py +++ b/src/librarian/document.py @@ -1,7 +1,7 @@ # This file is part of Librarian, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Wolne Lektury. See NOTICE for more information. # -from collections import Counter +from collections import defaultdict, Counter import gettext import os import re @@ -17,6 +17,7 @@ class WLDocument: source = filename or urllib.request.urlopen(url) tree = etree.parse(source, parser=parser) self.tree = tree + self.counters = defaultdict(lambda: 1) tree.getroot().document = self self.preprocess() @@ -41,6 +42,12 @@ class WLDocument: for _e, elem in etree.iterwalk(self.tree, ('start',), 'strofa'): elem.preprocess() + def assign_ids(self): + # Assign IDs depth-first, to account for any inside. + for _e, elem in etree.iterwalk(self.tree, events=('end',)): + if getattr(elem, 'NUMBERING', None): + elem.assign_id(self) + @property def children(self): for part_uri in self.meta.parts or []: diff --git a/src/librarian/elements/base.py b/src/librarian/elements/base.py index 060449c..8f4acc5 100644 --- a/src/librarian/elements/base.py +++ b/src/librarian/elements/base.py @@ -354,16 +354,16 @@ class WLElement(etree.ElementBase): prefix = 'f' # default numbering prefix return prefix - def assign_id(self, builder): + def assign_id(self, document): numbering = self.numbering if numbering: - number = str(builder.counters[numbering]) + number = str(document.counters[numbering]) self.attrib['_id'] = self.id_prefix + number - builder.counters[numbering] += 1 + document.counters[numbering] += 1 if numbering == 'main': - self.attrib['_visible_numbering'] = str(builder.counters['_visible']) - builder.counters['_visible'] += 1 + self.attrib['_visible_numbering'] = str(document.counters['_visible']) + document.counters['_visible'] += 1 if numbering == 'fn': self.attrib['_visible_numbering'] = number diff --git a/src/librarian/elements/tools/__init__.py b/src/librarian/elements/tools/__init__.py index 69a26ea..1fe7e0b 100644 --- a/src/librarian/elements/tools/__init__.py +++ b/src/librarian/elements/tools/__init__.py @@ -6,8 +6,9 @@ from ..base import WLElement class Numeracja(WLElement): NUMBERING = True - def assign_id(self, builder): - builder.counters['_visible'] = int(self.get('start', 1)) + + def assign_id(self, document): + document.counters['_visible'] = int(self.get('start', 1)) class Rownolegle(WLElement): diff --git a/tests/test_ref.py b/tests/test_ref.py index d75228e..2a54fb5 100644 --- a/tests/test_ref.py +++ b/tests/test_ref.py @@ -11,9 +11,7 @@ from lxml import etree class RefTests(TestCase): def test_snippet(self): doc = WLDocument(filename=get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml')) - - hb = builders['html']() - hb.assign_ids(doc.tree) + doc.assign_ids() refs = [] for ref in doc.references(): -- 2.20.1 From ba9a8ba0da6fcf7e89b75774cd07aac9706215da Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 18 Sep 2024 14:50:09 +0200 Subject: [PATCH 09/13] release --- CHANGELOG.md | 11 +++++++++++ setup.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13a3341..2cc365a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ This document records all notable changes to Librarian. +## 24.9 + +- Remove old API for HTML, TXT generators. Move to new API. +- The HTML format is changed: + - text-elements now have 'wl' class and id attribute, + - magic 'secN' ids are removed + - 'a.target' elements removed + - numbering anchors class changed to wl-num +- Removed all code related to art gallery. +- Drop Python 3.7. + ## 24.5 - Smaller images in EPUB (600px width instead of 1200px). diff --git a/setup.py b/setup.py index afca003..b52c069 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def whole_tree(prefix, path): setup( name='librarian', - version='24.5', + version='24.9', description='Converter from WolneLektury.pl XML-based language to XHTML, TXT and other formats', author="Marek Stępniowski", author_email='marek@stepniowski.com', -- 2.20.1 From b1376392167c09775bf57b41cb9ea3016f06cfb8 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Fri, 4 Oct 2024 13:10:23 +0200 Subject: [PATCH 10/13] fix --- src/librarian/builders/html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librarian/builders/html.py b/src/librarian/builders/html.py index 5bbe76a..0b063c6 100644 --- a/src/librarian/builders/html.py +++ b/src/librarian/builders/html.py @@ -127,7 +127,7 @@ class HtmlBuilder: if self.with_toc: add_table_of_contents(self.tree) - if self.document.counters['fn'] > 1: + if len(self.footnotes): fnheader = etree.Element("h3") fnheader.text = _("Footnotes") self.footnotes.insert(0, fnheader) -- 2.20.1 From 82c0860d1520489be56457829d49eb17f165b9cd Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 16 Oct 2024 15:56:57 +0200 Subject: [PATCH 11/13] 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 From 23d025c8875cca1404f274aca7170c9db5e980e7 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 22 Oct 2024 15:59:19 +0200 Subject: [PATCH 12/13] wip change fb2 api --- src/librarian/__init__.py | 3 +- src/librarian/builders/__init__.py | 2 + src/librarian/builders/fb2.py | 173 ++++++++++++++++++ src/librarian/builders/html.py | 5 + src/librarian/elements/base.py | 23 ++- src/librarian/elements/blocks/dedykacja.py | 2 + src/librarian/elements/blocks/dlugi_cytat.py | 2 + src/librarian/elements/blocks/nota.py | 2 + src/librarian/elements/figures/kol.py | 2 +- src/librarian/elements/figures/tabela.py | 2 +- src/librarian/elements/figures/wiersz.py | 2 +- src/librarian/elements/front/base.py | 10 +- src/librarian/elements/front/motto.py | 2 + src/librarian/elements/front/motto_podpis.py | 2 + src/librarian/elements/paragraphs/akap.py | 2 + src/librarian/elements/poetry/strofa.py | 3 + src/librarian/elements/poetry/wers.py | 1 + .../elements/separators/sekcja_asterysk.py | 5 + .../elements/separators/sekcja_swiatlo.py | 4 + .../elements/separators/separator_linia.py | 4 + 20 files changed, 244 insertions(+), 7 deletions(-) create mode 100644 src/librarian/builders/fb2.py diff --git a/src/librarian/__init__.py b/src/librarian/__init__.py index 0ed908c..4fbed92 100644 --- a/src/librarian/__init__.py +++ b/src/librarian/__init__.py @@ -77,7 +77,8 @@ RDFNS = XMLNamespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#') DCNS = XMLNamespace('http://purl.org/dc/elements/1.1/') XHTMLNS = XMLNamespace("http://www.w3.org/1999/xhtml") PLMETNS = XMLNamespace("http://dl.psnc.pl/schemas/plmet/") - +FB2NS = XMLNamespace("http://www.gribuser.ru/xml/fictionbook/2.0") +XLINKNS = XMLNamespace("http://www.w3.org/1999/xlink") WLNS = EmptyNamespace() diff --git a/src/librarian/builders/__init__.py b/src/librarian/builders/__init__.py index e47c557..85f8427 100644 --- a/src/librarian/builders/__init__.py +++ b/src/librarian/builders/__init__.py @@ -9,6 +9,7 @@ from .daisy import DaisyBuilder from .epub import EpubBuilder from .mobi import MobiBuilder from .pdf import PdfBuilder +from .fb2 import FB2Builder builders = OrderedDict([ @@ -23,4 +24,5 @@ builders = OrderedDict([ ("epub", EpubBuilder), ("mobi", MobiBuilder), ("pdf", PdfBuilder), + ("fb2", FB2Builder), ]) diff --git a/src/librarian/builders/fb2.py b/src/librarian/builders/fb2.py new file mode 100644 index 0000000..f4fe635 --- /dev/null +++ b/src/librarian/builders/fb2.py @@ -0,0 +1,173 @@ +# This file is part of Librarian, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Wolne Lektury. See NOTICE for more information. +# +from lxml import etree +from librarian import FB2NS, XLINKNS, OutputFile +from .html import TreeBuilder + + +class FB2Builder(TreeBuilder): + file_extension = 'fb2' + build_method_fn = 'fb2_build' + orphans = False + + def __init__(self, base_url=None): + self.tree = etree.Element( + FB2NS('FictionBook'), + nsmap={ + None: FB2NS.uri, + 'l': XLINKNS.uri, + } + ) + description = etree.SubElement(self.tree, 'description') + self.body = etree.SubElement(self.tree, 'body') + self.header = etree.SubElement(self.body, 'title') + self.epigraph = etree.SubElement(self.body, 'epigraph') + self.text = etree.SubElement(self.body, 'section') + + self.footnotes = etree.Element(FB2NS('body'), name="notes") + self.sections = [] + + self.cursors = { + None: self.text, + 'meta': description, + 'header': self.header, + 'epigraph': self.epigraph, + 'footnotes': self.footnotes, + #'nota_red': self.nota_red, + } + self.current_cursors = [self.text] + self.add_epigraph() + + def start_section(self, precedence): + while self.sections and self.sections[-1] >= precedence: + self.end_element() + self.sections.pop() + self.start_element('section') + self.sections.append(precedence) + + def add_epigraph(self): + self.enter_fragment('epigraph') + self.start_element(FB2NS('p')) + self.push_text('Utwór opracowany został w\xa0ramach projektu ') + self.start_element(FB2NS('a'), {XLINKNS('href'): 'https://wolnelektury.pl/'}) + self.push_text('Wolne Lektury') + self.end_element() + self.push_text(' przez ') + self.start_element(FB2NS('a'), {XLINKNS('href'): 'https://fundacja.wolnelektury.pl/'}) + self.push_text('fundację Wolne Lektury') + self.end_element() + self.push_text('.') + self.end_element() + self.exit_fragment() + + def add_meta(self, doc): + self.enter_fragment('meta') + + self.start_element('title-info') + + self.start_element('genre') + self.push_text('literature') + self.end_element() + for author in doc.meta.authors: + self.start_element('author') + self.simple_element('first-name', ' '.join(author.first_names)) + self.simple_element('last-name', author.last_name) + self.end_element() + self.simple_element('book-title', doc.meta.title) + if doc.meta.released_to_public_domain_at: + self.simple_element('date', doc.meta.released_to_public_domain_at) + self.simple_element('lang', doc.meta.language) + + self.end_element() + + self.start_element('document-info') + # contributor.editor + # contributor.technical_editor + self.simple_element('program-used', 'Wolne Lektury Librarian') + self.simple_element('date', doc.meta.created_at) + self.simple_element('id', str(doc.meta.url)) + self.simple_element('version', '0') + + self.end_element() + self.start_element('publish-info') + self.simple_element('publisher', '; '.join(doc.meta.publisher)) + self.end_element() + self.exit_fragment() + + def build(self, doc, mp3=None): + self.add_meta(doc) + doc.tree.getroot().fb2_build(self) + return self.output() + + def output(self): + return OutputFile.from_bytes( + etree.tostring( + self.tree, + encoding='utf-8', + pretty_print=True, + xml_declaration=True, + ) + ) + + + + +''' +import os.path +from copy import deepcopy +from lxml import etree + +from librarian import functions, OutputFile +from .epub import replace_by_verse + + +functions.reg_substitute_entities() +functions.reg_person_name() + + +def sectionify(tree): + """Finds section headers and adds a tree of _section tags.""" + sections = [ + 'naglowek_czesc', + 'naglowek_akt', 'naglowek_rozdzial', 'naglowek_scena', + 'naglowek_podrozdzial'] + section_level = dict((v, k) for (k, v) in enumerate(sections)) + + # We can assume there are just subelements an no text at section level. + for level, section_name in reversed(list(enumerate(sections))): + for header in tree.findall('//' + section_name): + section = header.makeelement("_section") + header.addprevious(section) + section.append(header) + sibling = section.getnext() + while (sibling is not None and + section_level.get(sibling.tag, 1000) > level): + section.append(sibling) + sibling = section.getnext() + + +def transform(wldoc, verbose=False, + cover=None, flags=None): + document = deepcopy(wldoc) + del wldoc + + if flags: + for flag in flags: + document.edoc.getroot().set(flag, 'yes') + + document.clean_ed_note() + document.clean_ed_note('abstrakt') + + style_filename = os.path.join(os.path.dirname(__file__), 'fb2/fb2.xslt') + style = etree.parse(style_filename) + + replace_by_verse(document.edoc) + sectionify(document.edoc) + + result = document.transform(style) + + return OutputFile.from_bytes(str(result).encode('utf-8')) + +# vim:et +''' diff --git a/src/librarian/builders/html.py b/src/librarian/builders/html.py index 66db675..e6530a5 100644 --- a/src/librarian/builders/html.py +++ b/src/librarian/builders/html.py @@ -45,6 +45,11 @@ class TreeBuilder: else: cursor.text = (cursor.text or '') + text + def simple_element(self, tag, text='', attrib=None): + self.start_element(tag, attrib) + self.push_text(text) + self.end_element() + class HtmlBuilder(TreeBuilder): build_method_fn = 'html_build' diff --git a/src/librarian/elements/base.py b/src/librarian/elements/base.py index 1f22929..2d656ae 100644 --- a/src/librarian/elements/base.py +++ b/src/librarian/elements/base.py @@ -37,7 +37,9 @@ class WLElement(etree.ElementBase): EPUB_ATTR = {} EPUB_CLASS = None EPUB_START_CHUNK = False - + + FB2_TAG = None + CAN_HAVE_TEXT = True STRIP = False NUMBERING = None @@ -209,6 +211,25 @@ class WLElement(etree.ElementBase): if self.HTML_TAG: builder.end_element() + def fb2_build(self, builder): + if self.SECTION_PRECEDENCE: + builder.start_section(self.SECTION_PRECEDENCE) + builder.start_element('title') + builder.start_element('p') + + if self.FB2_TAG: + builder.start_element( + self.FB2_TAG, + #self.get_fb2_attr(builder), + ) + + self.build_inner(builder) + if self.FB2_TAG: + builder.end_element() + if self.SECTION_PRECEDENCE: + builder.end_element() + builder.end_element() + def epub_build_inner(self, builder): self.build_inner(builder) diff --git a/src/librarian/elements/blocks/dedykacja.py b/src/librarian/elements/blocks/dedykacja.py index ae00b72..a8e7406 100644 --- a/src/librarian/elements/blocks/dedykacja.py +++ b/src/librarian/elements/blocks/dedykacja.py @@ -12,3 +12,5 @@ class Dedykacja(WLElement): EPUB_TAG = HTML_TAG = "div" EPUB_CLASS = HTML_CLASS = "dedication" + + FB2_TAG = 'cite' diff --git a/src/librarian/elements/blocks/dlugi_cytat.py b/src/librarian/elements/blocks/dlugi_cytat.py index bdac225..cf1515f 100644 --- a/src/librarian/elements/blocks/dlugi_cytat.py +++ b/src/librarian/elements/blocks/dlugi_cytat.py @@ -14,3 +14,5 @@ class DlugiCytat(WLElement): EPUB_TAG = 'div' EPUB_CLASS = 'block' + + FB2_TAG = 'cite' diff --git a/src/librarian/elements/blocks/nota.py b/src/librarian/elements/blocks/nota.py index dbba883..6bc0ff3 100644 --- a/src/librarian/elements/blocks/nota.py +++ b/src/librarian/elements/blocks/nota.py @@ -10,4 +10,6 @@ class Nota(WLElement): EPUB_TAG = HTML_TAG = "div" EPUB_CLASS = HTML_CLASS = "note" + FB2_TAG = 'cite' + SUPPRESS_NUMBERING = {'main': 'i'} diff --git a/src/librarian/elements/figures/kol.py b/src/librarian/elements/figures/kol.py index fa09fc7..342f89a 100644 --- a/src/librarian/elements/figures/kol.py +++ b/src/librarian/elements/figures/kol.py @@ -5,5 +5,5 @@ from ..base import WLElement class Kol(WLElement): - EPUB_TAG = HTML_TAG = 'td' + EPUB_TAG = HTML_TAG = FB2_TAG = 'td' TXT_PREFIX = ' ' * 4 diff --git a/src/librarian/elements/figures/tabela.py b/src/librarian/elements/figures/tabela.py index 5ab04e0..5422b61 100644 --- a/src/librarian/elements/figures/tabela.py +++ b/src/librarian/elements/figures/tabela.py @@ -11,7 +11,7 @@ class Tabela(WLElement): TXT_TOP_MARGIN = 3 TXT_BOTTOM_MARGIN = 3 - EPUB_TAG = HTML_TAG = 'table' + EPUB_TAG = HTML_TAG = FB2_TAG = 'table' def get_html_attr(self, builder): if self.attrib.get('ramka', '') == '1': diff --git a/src/librarian/elements/figures/wiersz.py b/src/librarian/elements/figures/wiersz.py index c013558..7b57997 100644 --- a/src/librarian/elements/figures/wiersz.py +++ b/src/librarian/elements/figures/wiersz.py @@ -6,6 +6,6 @@ from ..base import WLElement class Wiersz(WLElement): CAN_HAVE_TEXT = False - EPUB_TAG = HTML_TAG = 'tr' + EPUB_TAG = HTML_TAG = FB2_TAG = 'tr' TXT_TOP_MARGIN = 1 TXT_BOTTOM_MARGIN = 1 diff --git a/src/librarian/elements/front/base.py b/src/librarian/elements/front/base.py index ad16ca3..a0fb305 100644 --- a/src/librarian/elements/front/base.py +++ b/src/librarian/elements/front/base.py @@ -7,13 +7,19 @@ from ..base import WLElement class HeaderElement(WLElement): NUMBERING = 'i' HTML_TAG = 'span' + FB2_TAG = 'p' def txt_build(self, builder): builder.enter_fragment('header') - super(HeaderElement, self).txt_build(builder) + super().txt_build(builder) builder.exit_fragment() def html_build(self, builder): builder.enter_fragment('header') - super(HeaderElement, self).html_build(builder) + super().html_build(builder) + builder.exit_fragment() + + def fb2_build(self, builder): + builder.enter_fragment('header') + super().fb2_build(builder) builder.exit_fragment() diff --git a/src/librarian/elements/front/motto.py b/src/librarian/elements/front/motto.py index ac9f209..569a728 100644 --- a/src/librarian/elements/front/motto.py +++ b/src/librarian/elements/front/motto.py @@ -12,3 +12,5 @@ class Motto(WLElement): EPUB_TAG = HTML_TAG = "div" EPUB_CLASS = HTML_CLASS = "motto" + + FB2_TAG = 'cite' diff --git a/src/librarian/elements/front/motto_podpis.py b/src/librarian/elements/front/motto_podpis.py index 199da84..fd0d101 100644 --- a/src/librarian/elements/front/motto_podpis.py +++ b/src/librarian/elements/front/motto_podpis.py @@ -12,3 +12,5 @@ class MottoPodpis(WLElement): EPUB_TAG = "div" EPUB_CLASS = "motto_podpis" + + FB2_TAG = 'p' diff --git a/src/librarian/elements/paragraphs/akap.py b/src/librarian/elements/paragraphs/akap.py index 6ee10d7..726bfcd 100644 --- a/src/librarian/elements/paragraphs/akap.py +++ b/src/librarian/elements/paragraphs/akap.py @@ -16,6 +16,8 @@ class Akap(WLElement): HTML_TAG = 'p' HTML_CLASS = 'wl paragraph' + FB2_TAG = 'p' + has_visible_numbering = True @property diff --git a/src/librarian/elements/poetry/strofa.py b/src/librarian/elements/poetry/strofa.py index f698bc3..93e3a4a 100644 --- a/src/librarian/elements/poetry/strofa.py +++ b/src/librarian/elements/poetry/strofa.py @@ -16,6 +16,9 @@ class Strofa(WLElement): EPUB_TAG = HTML_TAG = 'div' EPUB_CLASS = HTML_CLASS = 'stanza' + FB2_TAG = 'stanza' + + def epub_build(self, builder): super().epub_build(builder) builder.start_element( diff --git a/src/librarian/elements/poetry/wers.py b/src/librarian/elements/poetry/wers.py index f0f274c..c188845 100644 --- a/src/librarian/elements/poetry/wers.py +++ b/src/librarian/elements/poetry/wers.py @@ -13,6 +13,7 @@ class Wers(WLElement): EPUB_TAG = HTML_TAG = 'div' EPUB_CLASS = 'verse' HTML_CLASS = 'wl verse' + FB2_TAG = 'v' NUMBERING = 'main' diff --git a/src/librarian/elements/separators/sekcja_asterysk.py b/src/librarian/elements/separators/sekcja_asterysk.py index 8cc2019..9c012cf 100644 --- a/src/librarian/elements/separators/sekcja_asterysk.py +++ b/src/librarian/elements/separators/sekcja_asterysk.py @@ -19,3 +19,8 @@ class SekcjaAsterysk(WLElement): epub_build_inner = html_build_inner + def fb2_build(self, builder): + builder.simple_element('empty-line') + builder.simple_element('p', '*') + builder.simple_element('empty-line') + diff --git a/src/librarian/elements/separators/sekcja_swiatlo.py b/src/librarian/elements/separators/sekcja_swiatlo.py index f7ea4a3..edfff1f 100644 --- a/src/librarian/elements/separators/sekcja_swiatlo.py +++ b/src/librarian/elements/separators/sekcja_swiatlo.py @@ -15,3 +15,7 @@ class SekcjaSwiatlo(WLElement): def epub_build_inner(self, builder): builder.push_text("\u00a0") + + def fb2_build(self, builder): + for i in range(3): + builder.simple_element('empty-line') diff --git a/src/librarian/elements/separators/separator_linia.py b/src/librarian/elements/separators/separator_linia.py index ac01f5d..e5b0709 100644 --- a/src/librarian/elements/separators/separator_linia.py +++ b/src/librarian/elements/separators/separator_linia.py @@ -14,4 +14,8 @@ class SeparatorLinia(WLElement): def txt_build_inner(self, builder): builder.push_text('-' * 48) + def fb2_build(self, builder): + builder.simple_element('empty-line') + builder.simple_element('p', '—' * 8) + builder.simple_element('empty-line') -- 2.20.1 From f164694b5e7ad5ed5f6d95743f9259bd3a9292bd Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 20 Nov 2024 14:55:31 +0100 Subject: [PATCH 13/13] Basic biblical tools. --- src/librarian/elements/__init__.py | 7 +++++- src/librarian/elements/footnotes/__init__.py | 8 +++++++ .../locale/pl/LC_MESSAGES/messages.mo | Bin 659 -> 717 bytes .../locale/pl/LC_MESSAGES/messages.po | 20 +++++++++++------- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/librarian/elements/__init__.py b/src/librarian/elements/__init__.py index 0191ae5..affcb9e 100644 --- a/src/librarian/elements/__init__.py +++ b/src/librarian/elements/__init__.py @@ -79,6 +79,7 @@ WL_ELEMENTS = { "pe": footnotes.PE, "pr": footnotes.PR, "pt": footnotes.PT, + "ptrad": footnotes.PTrad, "ref": ref.Ref, @@ -127,10 +128,14 @@ WL_ELEMENTS = { "rownolegle": tools.Rownolegle, "tab": tools.Tab, - # Section "wywiad_pyt": blocks.WywiadPyt, "wywiad_odp": blocks.WywiadOdp, + # Biblical + "werset": bible.Werset, + "sekcja_petucha": bible.Petucha, + "sekcja_stuma": bible.Stuma, + # Inline MathML, should really be namespaced. "mrow": styles.MRow, "mi": styles.M, diff --git a/src/librarian/elements/footnotes/__init__.py b/src/librarian/elements/footnotes/__init__.py index a94b968..a342e05 100644 --- a/src/librarian/elements/footnotes/__init__.py +++ b/src/librarian/elements/footnotes/__init__.py @@ -134,3 +134,11 @@ class PE(Footnote): def qualifier(self): _ = self.gettext return _("source editor's footnote") + + +class PTrad(Footnote): + """Przypis tradycyjny.""" + @property + def qualifier(self): + _ = self.gettext + return _("traditional footnote") diff --git a/src/librarian/locale/pl/LC_MESSAGES/messages.mo b/src/librarian/locale/pl/LC_MESSAGES/messages.mo index 1246851f96253d07d1b6cd4f2ff5f52fa1b8b93a..aa1ab3dfa40ddfb86633160d8f71dccabd23f838 100644 GIT binary patch delta 286 zcmbQtdX}~Ro)F7a1|Z-7Vi_Qg0b*_-o&&@nZ~}-qf%qg43j*Zens(A_D*s CSuU*r delta 241 zcmX@hI+?Zpo)F7a1|VPuVi_O~0b*_-?g3&D*a5_xK)e%(1%dc5l)eh2C4l%j5c2{t z10w^2D3Ia<(qcfY0>m6ZzBLmAg8-0r0n$Q1IuuBQ%*g=KYzz!~3{_BpMj#E;0|r0| z1|S#gC}xNd0}F_rxHoLF24j+dfv%x}u7SCNp^=rLp|*k1\n" "Language-Team: \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.3\n" +"X-Generator: Poedit 3.4.2\n" -#: src/librarian/builders/html.py:94 +#: src/librarian/builders/html.py:136 msgid "translated by" msgstr "tłum." -#: src/librarian/builders/html.py:118 +#: src/librarian/builders/html.py:157 msgid "Footnotes" msgstr "Przypisy" -#: src/librarian/elements/footnotes/__init__.py:111 +#: src/librarian/elements/footnotes/__init__.py:112 msgid "author's footnote" msgstr "przypis autorski" -#: src/librarian/elements/footnotes/__init__.py:119 +#: src/librarian/elements/footnotes/__init__.py:120 msgid "translator's footnote" msgstr "przypis tłumacza" -#: src/librarian/elements/footnotes/__init__.py:127 +#: src/librarian/elements/footnotes/__init__.py:128 msgid "editor's footnote" msgstr "przypis redakcyjny" -#: src/librarian/elements/footnotes/__init__.py:135 +#: src/librarian/elements/footnotes/__init__.py:136 msgid "source editor's footnote" msgstr "przypis edytorski" + +#: src/librarian/elements/footnotes/__init__.py:144 +msgid "traditional footnote" +msgstr "przypis tradycyjny" -- 2.20.1