content 24.5.2
authorRadek Czajka <rczajka@rczajka.pl>
Tue, 3 Dec 2024 14:54:33 +0000 (15:54 +0100)
committerRadek Czajka <rczajka@rczajka.pl>
Tue, 3 Dec 2024 14:54:33 +0000 (15:54 +0100)
14 files changed:
setup.py
src/librarian/builders/epub.py
src/librarian/covers/widgets/author.py
src/librarian/dcparser.py
src/librarian/elements/__init__.py
src/librarian/elements/tools/__init__.py
src/librarian/fb2/footnotes.xslt
src/librarian/fb2/paragraphs.xslt
src/librarian/html.py
src/librarian/parser.py
src/librarian/pdf/wl.cls
src/librarian/pdf/wl2tex.xslt
src/librarian/xslt/book2html.xslt
src/librarian/xslt/book2txt.xslt

index 42cf475..750b124 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@ def whole_tree(prefix, path):
 
 setup(
     name='librarian',
-    version='24.5.1',
+    version='24.5.2',
     description='Converter from WolneLektury.pl XML-based language to XHTML, TXT and other formats',
     author="Marek Stępniowski",
     author_email='marek@stepniowski.com',
index e009d4a..1e57583 100644 (file)
@@ -82,6 +82,7 @@ class EpubBuilder(Builder):
     orphans = True
 
     def __init__(self, *args, debug=False, **kwargs):
+        self.numbering = 0
         self.chars = set()
         self.fundr = 0
         self.debug = debug
@@ -288,7 +289,7 @@ class EpubBuilder(Builder):
                 file_as=str(author),
                 uid='creator{}'.format(i)
             )
-        for translator in self.document.meta.translators:
+        for i, translator in enumerate(self.document.meta.translators):
             self.output.add_author(
                 translator.readable(),
                 file_as=str(translator),
index 381b7af..db35949 100644 (file)
@@ -134,6 +134,30 @@ class AuthorBox(Widget):
 
             self.textboxes = [author_box]
 
+        elif translators:
+            translators_shortened = False
+            translator_box = None
+            while translator_box is None:
+                translator_str = 'tłum. ' + ', '.join(translators)
+                if translators_shortened:
+                    translator_str += ' i in.'
+                try:
+                    translator_box = TextBox(
+                        self.width,
+                        self.m.leading * 2,
+                        [translator_str],
+                        translator_font,
+                        1,
+                        self.m.leading,
+                        0,
+                        1, 0
+                    )
+                except DoesNotFit:
+                    translators.pop()
+                    translators_shortened = True
+
+            self.textboxes = [translator_box]
+
         if self.textboxes:
             self.margin_top = self.textboxes[0].margin_top
 
index 910f5e1..629411e 100644 (file)
@@ -106,7 +106,7 @@ class DCInfo(type):
 class WorkInfo(metaclass=DCInfo):
     FIELDS = (
         Field(DCNS('creator'), 'authors', Person, salias='author',
-              multiple=True),
+              multiple=True, required=False),
         Field(DCNS('title'), 'title'),
         Field(DCNS('type'), 'type', required=False, multiple=True),
 
@@ -140,6 +140,7 @@ class WorkInfo(metaclass=DCInfo):
         Field(WLNS('contentWarning'), 'content_warnings', multiple=True,
               required=False),
         Field(WLNS('developmentStage'), 'stage', required=False),
+        Field(WLNS('original'), 'original', required=False),
     )
 
     @classmethod
index b08c3e1..9481190 100644 (file)
@@ -4,7 +4,7 @@
 from lxml import etree
 from . import (blocks, comments, drama, figures, footnotes, front, headers,
                masters, paragraphs, poetry, ref, root, separators, styles, themes,
-               tools, base)
+               tools, base, bible)
 
 
 WL_ELEMENTS = {
@@ -17,6 +17,7 @@ WL_ELEMENTS = {
     "coverLogoUrl": etree.ElementBase,
     "contentWarning": etree.ElementBase,
     "endnotes": etree.ElementBase,
+    "original": etree.ElementBase,
 
     "utwor": root.Utwor,
     "dramat_wierszowany_l": masters.Master,
@@ -131,6 +132,8 @@ WL_ELEMENTS = {
     "wywiad_pyt": blocks.WywiadPyt,
     "wywiad_odp": blocks.WywiadOdp,
 
+    "werset": bible.Werset,
+    
     # Inline MathML, should really be namespaced.
     "mrow": etree.ElementBase,
     "mi": etree.ElementBase,
index 99f81d9..0da3599 100644 (file)
@@ -5,7 +5,8 @@ from ..base import WLElement
 
 
 class Numeracja(WLElement):
-    pass
+    def build_epub(self, builder):
+        builder.numbering = 0
 
 
 class Rownolegle(WLElement):
index 6d396fc..566de4c 100644 (file)
@@ -12,9 +12,9 @@
        xmlns:l="http://www.w3.org/1999/xlink">
 
        <!-- footnote body mode -->
-       <xsl:template match="pa|pe|pr|pt" mode="footnotes">
+       <xsl:template match="pa|pe|pr|pt|ptrad" mode="footnotes">
                <!-- we number them absolutely -->
-               <xsl:variable name="n" select="count(preceding::pa) + count(preceding::pe) + count(preceding::pr) + count(preceding::pt) + 1"/>
+               <xsl:variable name="n" select="count(preceding::pa) + count(preceding::pe) + count(preceding::pr) + count(preceding::pt) + count(preceding::ptrad) + 1"/>
 
                <xsl:element name="section">
                        <xsl:attribute name="id">fn<xsl:value-of select="$n"/></xsl:attribute>
                 </xsl:if>
                 <xsl:if test="local-name() = 'pe'">
                     <xsl:text> [przypis edytorski]</xsl:text>
+                </xsl:if>
+                <xsl:if test="local-name() = 'ptrad'">
+                    <xsl:text> [przypis tradycyjny]</xsl:text>
                 </xsl:if></p>
                </xsl:element>
        </xsl:template>
        <xsl:template match="text()" mode="footnotes"/>
 
        <!-- footnote links -->
-       <xsl:template match="pa|pe|pr|pt" mode="inline">
-               <xsl:variable name="n" select="count(preceding::pa) + count(preceding::pe) + count(preceding::pr) + count(preceding::pt) + 1"/>
+       <xsl:template match="pa|pe|pr|pt|ptrad" mode="inline">
+               <xsl:variable name="n" select="count(preceding::pa) + count(preceding::pe) + count(preceding::pr) + count(preceding::pt) + count(preceding::ptrad) + 1"/>
                <xsl:element name="a">
                        <xsl:attribute name="type">note</xsl:attribute>
                        <xsl:attribute name="l:href">#fn<xsl:value-of select="$n"/></xsl:attribute>
index 13d3482..1ac9064 100644 (file)
                <p><xsl:apply-templates mode="inline"/></p>
        </xsl:template>
 
+       <xsl:template mode="para" match="werset">
+               <!-- paragraphs & similar -->
+
+               <p><xsl:apply-templates mode="inline"/></p>
+       </xsl:template>
+
        <xsl:template mode="para" match="dlugi_cytat|motto|dedykacja|nota">
                <cite><xsl:apply-templates mode="para"/></cite>
        </xsl:template>
index 2919498..456f281 100644 (file)
@@ -115,6 +115,7 @@ def transform(wldoc, stylesheet='legacy', options=None, flags=None, css=None, ga
         document.clean_ed_note()
         document.clean_ed_note('abstrakt')
         document.fix_pa_akap()
+        document.hebr_protect()
         
         if not options:
             options = {}
@@ -311,7 +312,8 @@ def any_ancestor(element, test):
 
 
 def add_anchors(root):
-    counter = 1
+    link_prefix = "f"
+    counter = {"f": 1}
     visible_counter = 1
     for element in root.iterdescendants():
         def f(e):
@@ -329,18 +331,21 @@ def add_anchors(root):
                 visible_counter = int(element.get('data-start'))
             except ValueError:
                 visible_counter = 1
+            if element.get("data-link"):
+                link_prefix = element.get("data-link")
+                counter[link_prefix] = 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
+                add_anchor(element, "%s%d" % (link_prefix, counter[link_prefix]), link_text=visible_counter)
+            counter[link_prefix] += 1
             visible_counter += 1
         elif 'paragraph' in element.get('class', ''):
-            add_anchor(element, "f%d" % counter, link_text=visible_counter)
-            counter += 1
+            add_anchor(element, "%s%d" % (link_prefix, counter[link_prefix]), link_text=visible_counter)
+            counter[link_prefix] += 1
             visible_counter += 1
 
 
index b4e4c5c..ca9691a 100644 (file)
@@ -192,19 +192,26 @@ class WLDocument:
 
         for node in self.edoc.xpath('|'.join(
                 '//%s//%s' % (note_tag, tag) for tag in
-                ('pa', 'pe', 'pr', 'pt', 'begin', 'end', 'motyw'))):
+                ('pa', 'pe', 'pr', 'pt', 'ptrad', 'begin', 'end', 'motyw'))):
             tail = node.tail
             node.clear()
             node.tag = 'span'
             node.tail = tail
 
     def fix_pa_akap(self):
-        for pa in ('pa','pe','pr','pt'):
+        for pa in ('pa','pe','pr','pt', 'ptrad'):
             for akap in self.edoc.findall(f'//{pa}/akap'):
                 akap.getparent().set('blocks', 'true')
                 if not akap.getparent().index(akap):
                     akap.set('inline', 'true')
             
+    def hebr_protect(self):
+        for s in self.edoc.findall('//slowo_obce'):
+            if not s.text and len(s) == 1 and s[0].tag == 'slowo_obce':
+                continue
+            if re.match(r'^[\s\u0590-\u05ff]+$', s.text):
+                s.attrib['protect'] = 'true'
+
     def editors(self):
         """Returns a set of all editors for book and its children.
 
index d2eac63..33efa78 100644 (file)
@@ -751,6 +751,10 @@ Letters={Uppercase}
 \par{\N#1}%
 }
 
+\newcommand{\werset}[1]{%
+\par{\noindent{\ignorespaces#1\vspace{1em}}}%
+}
+
 \newcommand{\mottopodpis}[1]{%
 \begin{em}%
 \begin{flushright}%
index ab189e0..547c61c 100644 (file)
 
 
 <xsl:template
-    match="naglowek_osoba|naglowek_podrozdzial|podtytul_podrozdzial|miejsce_czas|didaskalia|lista_osoba|akap|akap_dialog|akap_cd|motto_podpis|naglowek_listy|srodtytul|podtytul_czesc|podtytul_rozdzial|podtytul_akt|podtytul_scena">
+    match="naglowek_osoba|naglowek_podrozdzial|podtytul_podrozdzial|miejsce_czas|didaskalia|lista_osoba|akap|akap_dialog|akap_cd|motto_podpis|naglowek_listy|srodtytul|podtytul_czesc|podtytul_rozdzial|podtytul_akt|podtytul_scena|werset">
   <xsl:choose>
     <xsl:when test="@inline">
       <xsl:apply-templates mode="inline"/>
index b009345..c06e41a 100644 (file)
 <xsl:template name="book-text">
     <div id="book-text">
         <xsl:apply-templates select="powiesc|opowiadanie|liryka_l|liryka_lp|dramat_wierszowany_l|dramat_wierszowany_lp|dramat_wspolczesny" />
-        <xsl:if test="count(descendant::*[self::pe or self::pa or self::pr or self::pt][not(parent::extra)])">
+        <xsl:if test="count(descendant::*[self::pe or self::pa or self::pr or self::pt or self::ptrad][not(parent::extra)])">
             <div id="footnotes">
                 <h3>Przypisy</h3>
-                <xsl:for-each select="descendant::*[self::pe or self::pa or self::pr or self::pt][not(parent::extra)]">
+                <xsl:for-each select="descendant::*[self::pe or self::pa or self::pr or self::pt or self::ptrad][not(parent::extra)]">
                     <div>
                         <xsl:attribute name="class">fn-<xsl:value-of select="name()" /></xsl:attribute>
                         <a name="{concat('footnote-', generate-id(.))}" />
-                        <a href="{concat('#anchor-', generate-id(.))}" class="annotation">[<xsl:number value="count(preceding::*[self::pa or self::pe or self::pr or self::pt]) + 1" />]</a>
+                        <a href="{concat('#anchor-', generate-id(.))}" class="annotation">[<xsl:number value="count(preceding::*[self::pa or self::pe or self::pr or self::pt or self::ptrad]) + 1" />]</a>
                         <xsl:choose>
                             <xsl:when test="count(akap|akap_cd|strofa) = 0">
                                 <p><xsl:apply-templates select="text()|*" mode="inline" />
                                 <xsl:if test="name()='pt'"> [przypis tłumacza]</xsl:if>
                                 <xsl:if test="name()='pr'"> [przypis redakcyjny]</xsl:if>
                                 <xsl:if test="name()='pe'"> [przypis edytorski]</xsl:if>
+                                <xsl:if test="name()='ptrad'"> [przypis tradycyjny]</xsl:if>
                                 </p>
                             </xsl:when>
                             <xsl:otherwise>
                                 <xsl:if test="name()='pt'"> [przypis tłumacza]</xsl:if>
                                 <xsl:if test="name()='pr'"> [przypis redakcyjny]</xsl:if>
                                 <xsl:if test="name()='pe'"> [przypis edytorski]</xsl:if>
+                                <xsl:if test="name()='ptrad'"> [przypis tradycyjny]</xsl:if>
                               </p>
                             </xsl:otherwise>
                         </xsl:choose>
 <!-- = (contain other inline tags and special tags) = -->
 <!-- ================================================ -->
 <!-- Annotations -->
-<xsl:template match="pa|pe|pr|pt" mode="inline">
+<xsl:template match="pa|pe|pr|pt|ptrad" mode="inline">
     <a name="{concat('anchor-', generate-id(.))}" />
-    <a href="{concat('#footnote-', generate-id(.))}" class="annotation">[<xsl:number value="count(preceding::*[self::pa or self::pe or self::pr or self::pt]) + 1" />]</a>
+    <a href="{concat('#footnote-', generate-id(.))}" class="annotation">[<xsl:number value="count(preceding::*[self::pa or self::pe or self::pr or self::pt or self::ptrad]) + 1" />]</a>
 </xsl:template>
 
 <xsl:template match="ref" mode="inline">
 </xsl:template>
 
 <xsl:template match="slowo_obce" mode="inline">
-    <em class="foreign-word"><xsl:apply-templates mode="inline" /></em>
+  <em>
+    <xsl:attribute name="class">
+      <xsl:text>foreign-word</xsl:text>
+      <xsl:if test="@protect">
+       <xsl:text> foreign-word-protected</xsl:text>
+      </xsl:if>
+    </xsl:attribute>
+    <xsl:apply-templates mode="inline" />
+  </em>
 </xsl:template>
 
 <xsl:template match="tytul_dziela" mode="inline">
 </xsl:template>
 
 
+<xsl:template match="werset">
+    <p class="werset paragraph">
+      <xsl:call-template name="block-args" />
+      <xsl:call-template name="section-anchor"/>
+       <xsl:apply-templates mode="inline" />
+    </p>
+</xsl:template>
+
+
 <!-- ================ -->
 <!-- = IGNORED TAGS = -->
 <!-- ================ -->
                <xsl:attribute name="data-start">
                        <xsl:value-of select="@start" />
                </xsl:attribute>
+               <xsl:attribute name="data-link">
+                       <xsl:value-of select="@link" />
+               </xsl:attribute>
        </span>
 </xsl:template>
 
index d43c7d4..4bc919b 100644 (file)
 <xsl:apply-templates mode="inline" />
 </xsl:template>
 
-<xsl:template match="akap|akap_dialog|akap_cd">
+<xsl:template match="akap|akap_dialog|akap_cd|werset">
 <xsl:variable name="content">
     <xsl:apply-templates select="*|text()" mode="inline" />
 </xsl:variable>
 <!-- = (contain other inline tags and special tags) = -->
 <!-- ================================================ -->
 <!-- Annotations -->
-<xsl:template match="pa|pe|pr|pt" mode="inline" />
+<xsl:template match="pa|pe|pr|pt|ptrad" mode="inline" />
 
 <!-- Other inline tags -->
 <xsl:template match="mat" mode="inline"><xsl:apply-templates mode="inline" /></xsl:template>