Many FB2 fixes
authorRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Thu, 27 Sep 2012 15:09:02 +0000 (17:09 +0200)
committerRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Thu, 27 Sep 2012 15:09:02 +0000 (17:09 +0200)
12 files changed:
librarian/epub.py
librarian/fb2.py
librarian/fb2/drama.xslt [new file with mode: 0755]
librarian/fb2/fb2.xslt
librarian/fb2/footnotes.xslt
librarian/fb2/inline.xslt
librarian/fb2/paragraphs.xslt
librarian/fb2/poems.xslt
librarian/fb2/sections.xslt
scripts/book2txt
setup.py
tests/files/example-wl.xml [new file with mode: 0644]

index bbeb3d7..10922d4 100644 (file)
@@ -7,6 +7,7 @@ from __future__ import with_statement
 
 import os
 import os.path
+import re
 import subprocess
 from StringIO import StringIO
 from copy import deepcopy
@@ -109,31 +110,74 @@ def find_annotations(annotations, source, part_no):
             find_annotations(annotations, child, part_no)
 
 
+class Stanza(object):
+    """
+    Converts / verse endings into verse elements in a stanza.
+
+    Slashes may only occur directly in the stanza. Any slashes in subelements
+    will be ignored, and the subelements will be put inside verse elements.
+
+    >>> s = etree.fromstring("<strofa>a/\\nb<x>x/\\ny</x>c/ \\nd</strofa>")
+    >>> Stanza(s).versify()
+    >>> print etree.tostring(s)
+    <strofa><wers_normalny>a</wers_normalny><wers_normalny>b<x>x/
+    y</x>c</wers_normalny><wers_normalny>d</wers_normalny></strofa>
+    
+    """
+    def __init__(self, stanza_elem):
+        self.stanza = stanza_elem
+        self.verses = []
+        self.open_verse = None
+
+    def versify(self):
+        self.push_text(self.stanza.text)
+        for elem in self.stanza:
+            self.push_elem(elem)
+            self.push_text(elem.tail)
+        tail = self.stanza.tail
+        self.stanza.clear()
+        self.stanza.tail = tail
+        self.stanza.extend(self.verses)
+
+    def open_normal_verse(self):
+        self.open_verse = self.stanza.makeelement("wers_normalny")
+        self.verses.append(self.open_verse)
+
+    def get_open_verse(self):
+        if self.open_verse is None:
+            self.open_normal_verse()
+        return self.open_verse
+
+    def push_text(self, text):
+        if not text or not text.strip():
+            return
+        for i, verse_text in enumerate(re.split(r"/\s*\n", text)):
+            if i:
+                self.open_normal_verse()
+            verse = self.get_open_verse()
+            if len(verse):
+                verse[-1].tail = (verse[-1].tail or "") + verse_text.strip()
+            else:
+                verse.text = (verse.text or "") + verse_text.strip()
+
+    def push_elem(self, elem):
+        if elem.tag.startswith("wers"):
+            verse = deepcopy(elem)
+            verse.tail = None
+            self.verses.append(verse)
+            self.open_verse = verse
+        else:
+            appended = deepcopy(elem)
+            appended.tail = None
+            self.get_open_verse().append(appended)
+
+
 def replace_by_verse(tree):
     """ Find stanzas and create new verses in place of a '/' character """
 
     stanzas = tree.findall('.//' + WLNS('strofa'))
-    for node in stanzas:
-        for child_node in node:
-            if child_node.tag in ('slowo_obce', 'wyroznienie'):
-                foreign_verses = inner_xml(child_node).split('/\n')
-                if len(foreign_verses) > 1:
-                    new_foreign = ''
-                    for foreign_verse in foreign_verses:
-                        if foreign_verse.startswith('<wers'):
-                            new_foreign += foreign_verse
-                        else:
-                            new_foreign += ''.join(('<wers_normalny>', foreign_verse, '</wers_normalny>'))
-                    set_inner_xml(child_node, new_foreign)
-        verses = inner_xml(node).split('/\n')
-        if len(verses) > 1:
-            modified_inner_xml = ''
-            for verse in verses:
-                if verse.startswith('<wers') or verse.startswith('<extra'):
-                    modified_inner_xml += verse
-                else:
-                    modified_inner_xml += ''.join(('<wers_normalny>', verse, '</wers_normalny>'))
-            set_inner_xml(node, modified_inner_xml)
+    for stanza in stanzas:
+        Stanza(stanza).versify()
 
 
 def add_to_manifest(manifest, partno):
index 78707a9..d979566 100644 (file)
@@ -12,6 +12,28 @@ 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):
@@ -32,6 +54,7 @@ def transform(wldoc, verbose=False,
     style = etree.parse(style_filename)
 
     replace_by_verse(document.edoc)
+    sectionify(document.edoc)
 
     result = document.transform(style)
 
diff --git a/librarian/fb2/drama.xslt b/librarian/fb2/drama.xslt
new file mode 100755 (executable)
index 0000000..ab8fb06
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+       This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
+       Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       xmlns:wl="http://wolnelektury.pl/functions"
+       xmlns:dc="http://purl.org/dc/elements/1.1/"
+       xmlns="http://www.gribuser.ru/xml/fictionbook/2.0"
+       xmlns:l="http://www.w3.org/1999/xlink">
+
+       <xsl:template mode="para" match="lista_osob">
+        <empty-line/>
+               <xsl:apply-templates mode="para"/>
+        <empty-line/>
+       </xsl:template>
+
+       <xsl:template mode="para" match="kwestia">
+        <empty-line/>
+               <xsl:apply-templates mode="para"/>
+        <empty-line/>
+       </xsl:template>
+
+       <xsl:template mode="para" match="lista_osoba">
+               <p><xsl:apply-templates mode="inline"/></p>
+       </xsl:template>
+
+       <xsl:template mode="para" match="naglowek_listy|naglowek_osoba">
+               <p><strong><xsl:apply-templates mode="inline"/></strong></p>
+       </xsl:template>
+
+       <xsl:template mode="para" match="miejsce_czas|didaskalia|didask_tekst">
+               <p><emphasis><xsl:apply-templates mode="inline"/></emphasis></p>
+       </xsl:template>
+
+       <xsl:template mode="inline" match="didaskalia|didask_tekst">
+               <emphasis><xsl:apply-templates mode="inline"/></emphasis>
+       </xsl:template>
+
+</xsl:stylesheet>
index 2a07e35..950b526 100644 (file)
@@ -7,6 +7,7 @@
 -->
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:wl="http://wolnelektury.pl/functions"
+    xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns="http://www.gribuser.ru/xml/fictionbook/2.0"
        xmlns:l="http://www.w3.org/1999/xlink">
 
@@ -16,6 +17,7 @@
        <xsl:include href="paragraphs.xslt"/>
        <xsl:include href="poems.xslt"/>
        <xsl:include href="sections.xslt"/>
+       <xsl:include href="drama.xslt"/>
 
        <xsl:strip-space elements="*"/>
        <xsl:output encoding="utf-8" method="xml" indent="yes"/>
        </xsl:template>
 
        <!-- we can't handle lyrics nicely yet -->
-       <xsl:template match="powiesc|opowiadanie|liryka_l|liryka_lp" mode="outer">
+       <xsl:template match="powiesc|opowiadanie|liryka_l|liryka_lp|dramat_wierszowany_l|dramat_wierszowany_lp" mode="outer">
                <body> <!-- main body for main book flow -->
                        <xsl:if test="autor_utworu or nazwa_utworu">
                                <title>
                                        <xsl:apply-templates mode="title"
-                                               select="autor_utworu|dzielo_nadrzedne|nazwa_utworu"/>
+                                               select="autor_utworu|dzielo_nadrzedne|nazwa_utworu|podtytul"/>
+                    <xsl:call-template name="translators" />
                                </title>
                        </xsl:if>
 
                                </p>
                        </epigraph>
 
-                       <xsl:variable name="sections" select="count(naglowek_rozdzial)"/>
-                       <section>
-                               <xsl:choose>
-                                       <xsl:when test="local-name() = 'liryka_l'">
-                                               <poem>
-                                                       <xsl:apply-templates mode="para"/>
-                                               </poem>
-                                       </xsl:when>
-
-                                       <xsl:otherwise>
-                                               <xsl:apply-templates mode="para"
-                                                       select="*[count(following-sibling::naglowek_rozdzial)
-                                                       = $sections]"/>
-                                       </xsl:otherwise>
-                               </xsl:choose>
-                       </section>
-
-                       <xsl:apply-templates mode="sections"/>
+                       <xsl:call-template name="section" />
                </body>
        </xsl:template>
 
                <p><xsl:apply-templates mode="inline"/></p>
        </xsl:template>
 
+    <xsl:template name="translators">
+        <xsl:if test="//dc:contributor.translator">
+            <p>
+                <xsl:text>tłum. </xsl:text>
+                <xsl:for-each select="//dc:contributor.translator">
+                    <xsl:if test="position() != 1">, </xsl:if>
+                    <xsl:apply-templates mode="person" />
+                </xsl:for-each>
+            </p>
+        </xsl:if>
+    </xsl:template>
+
+    <xsl:template match="text()" mode="person">
+        <xsl:value-of select="wl:person_name(.)" />
+    </xsl:template>
+
+
        <xsl:template match="uwaga" mode="title"/>
        <xsl:template match="extra" mode="title"/>
 </xsl:stylesheet>
index 37f467f..09270b9 100644 (file)
        xmlns:l="http://www.w3.org/1999/xlink">
 
        <!-- footnote body mode -->
-       <xsl:template match="pe" mode="footnotes">
+       <xsl:template match="pa|pe|pr|pt" mode="footnotes">
                <!-- we number them absolutely -->
-               <xsl:variable name="n" select="count(preceding::pe) + 1"/>
+               <xsl:variable name="n" select="count(preceding::pa) + count(preceding::pe) + count(preceding::pr) + count(preceding::pt) + 1"/>
 
                <xsl:element name="section">
                        <xsl:attribute name="id">fn<xsl:value-of select="$n"/></xsl:attribute>
 
-                       <p><xsl:apply-templates mode="inline"/></p>
+                       <p><xsl:apply-templates mode="inline"/>
+                <xsl:if test="local-name() = 'pa'">
+                    <xsl:text> [przypis autorski]</xsl:text>
+                </xsl:if></p>
                </xsl:element>
        </xsl:template>
        <xsl:template match="text()" mode="footnotes"/>
 
        <!-- footnote links -->
-       <xsl:template match="pe" mode="inline">
-               <xsl:variable name="n" select="count(preceding::pe) + 1"/>
+       <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:element name="a">
                        <xsl:attribute name="type">note</xsl:attribute>
                        <xsl:attribute name="l:href">#fn<xsl:value-of select="$n"/></xsl:attribute>
index 221fbfd..03c6b65 100644 (file)
        <xsl:template match="motyw" mode="inline"/>
 
        <!-- formatting -->
-       <xsl:template match="slowo_obce|tytul_dziela">
+       <xsl:template match="slowo_obce" mode="inline">
                <emphasis>
                        <xsl:apply-templates mode="inline"/>
                </emphasis>
        </xsl:template>
-       <xsl:template match="wyroznienie">
+       <xsl:template match="tytul_dziela" mode="inline">
+               <emphasis>
+            <xsl:if test="@typ">„</xsl:if>
+                       <xsl:apply-templates mode="inline"/>
+            <xsl:if test="@typ">”</xsl:if>
+               </emphasis>
+       </xsl:template>
+       <xsl:template match="wyroznienie" mode="inline">
                <strong>
                        <xsl:apply-templates mode="inline"/>
                </strong>
index 01943a3..68c6257 100644 (file)
 
        <!-- in paragraph mode -->
 
-       <xsl:template mode="para" match="akap|akap_dialog">
+       <xsl:template mode="para" match="akap|akap_dialog|akap_cd|motto_podpis">
                <!-- 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>
+
+       <xsl:template mode="para" match="srodtytul">
+               <p><strong><xsl:apply-templates mode="inline"/></strong></p>
+       </xsl:template>
+
+       <xsl:template mode="para" match="sekcja_swiatlo">
+               <empty-line/><empty-line/><empty-line/>
+       </xsl:template>
+
+       <xsl:template mode="para" match="sekcja_asterysk">
+               <empty-line/><p>*</p><empty-line/>
+       </xsl:template>
+
+       <xsl:template mode="para" match="separator_linia">
+               <empty-line/><p>————————</p><empty-line/>
+       </xsl:template>
+
+
+
        <xsl:template mode="para" match="*"/>
        <xsl:template mode="sections" match="*"/>
 </xsl:stylesheet>
index bbc9407..31b05b4 100644 (file)
@@ -33,7 +33,7 @@
                puts it here -->
        <xsl:template match="motyw" mode="poem"/>
 
-       <xsl:template mode="poem" match="wers_normalny">
+       <xsl:template mode="poem" match="wers_normalny|wers_cd|wers_wciety|wers_akap">
                <v><xsl:apply-templates mode="inline"/></v>
        </xsl:template>
 </xsl:stylesheet>
index b698652..80ffb65 100644 (file)
        xmlns="http://www.gribuser.ru/xml/fictionbook/2.0"
        xmlns:l="http://www.w3.org/1999/xlink">
 
-       <!-- a nice epigraph section -->
-       <xsl:template match="dedykacja|nota|nota_red" mode="sections">
-               <epigraph>
-                       <xsl:apply-templates mode="para"/>
-                       <!-- XXX: <strofa/> can be here as well -->
-               </epigraph>
-       </xsl:template>
-
-       <!-- main text is split by headings -->
-       <xsl:template match="naglowek_rozdzial" mode="sections">
-               <!--
-
-               This one's tricky - we need to sections text into sections.
-               In order to do that, all elements belonging to a single section
-               must have something in common. We assume that this common factor
-               is having the same number of following section headings.
-
-               -->
-
-               <section>
-                       <xsl:apply-templates mode="para"
-                               select="../*[count(following-sibling::naglowek_rozdzial)
-                                       = count(current()/following-sibling::naglowek_rozdzial)]"/>
-               </section>
-       </xsl:template>
+    <xsl:template name="section">
+        <!-- All the <_section> are in the end. -->
+        <xsl:if test="count(*) &gt; count(_section)">
+            <section>
+                <xsl:choose>
+                    <xsl:when test="(local-name() = 'liryka_l' or local-name() = 'liryka_lp')
+                                     and count(_section) = 0">
+                        <poem>
+                            <xsl:apply-templates mode="para" />
+                        </poem>
+                    </xsl:when>
+                    <xsl:otherwise>
+                        <xsl:apply-templates mode="para" />
+                    </xsl:otherwise>
+                </xsl:choose>
+            </section>
+        </xsl:if>
+
+        <!-- Now, recursively, all the _section tags. -->
+        <xsl:apply-templates mode="section" select="_section" />
+    </xsl:template>
+
+    <xsl:template match="_section" mode="para" />
+    <xsl:template match="_section" mode="section" >
+        <section>
+            <xsl:call-template name="section" />
+        </section>
+    </xsl:template>
 
        <!-- actual headings -->
-       <xsl:template match="naglowek_rozdzial" mode="para">
+       <xsl:template match="naglowek_czesc|naglowek_rozdzial|naglowek_podrozdzial|naglowek_akt|naglowek_scena" mode="para">
                <title><p><xsl:apply-templates mode="inline"/></p></title>
        </xsl:template>
 </xsl:stylesheet>
index e584579..1b4c0ef 100755 (executable)
@@ -5,6 +5,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from librarian.book2anything import Book2Anything, Option
+from librarian.parser import WLDocument
 
 
 class Book2Txt(Book2Anything):
@@ -21,6 +22,7 @@ class Book2Txt(Book2Anything):
         Option('-w', '--wrap', action='store', type='int', dest='wrapping', default=0,
                 help='set line wrap column')
     ]
+    transform = WLDocument.as_text
 
 
 if __name__ == '__main__':
index f88817e..51003ef 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -29,7 +29,7 @@ setup(
     maintainer_email='radoslaw.czajka@nowoczesnapolska.org.pl',
     url='http://github.com/fnp/librarian',
     packages=['librarian'],
-    package_data={'librarian': ['xslt/*.xslt', 'epub/*', 'mobi/*', 'pdf/*', 'fonts/*', 'res/*'] +
+    package_data={'librarian': ['xslt/*.xslt', 'epub/*', 'mobi/*', 'pdf/*', 'fb2/*', 'fonts/*', 'res/*'] +
                                 whole_tree(os.path.join(os.path.dirname(__file__), 'librarian'), 'font-optimizer')},
     include_package_data=True,
     install_requires=['lxml>=2.2'],
@@ -38,6 +38,7 @@ setup(
              'scripts/book2epub',
              'scripts/book2mobi',
              'scripts/book2pdf',
+             'scripts/book2fb2',
              'scripts/book2partner',
              'scripts/book2cover',
              'scripts/bookfragments',
diff --git a/tests/files/example-wl.xml b/tests/files/example-wl.xml
new file mode 100644 (file)
index 0000000..d2fd87b
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!--
+  Example file for testing a converter.
+  Just run it through and see if everything looks ok.
+-->
+<utwor>
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
+xmlns:dc="http://purl.org/dc/elements/1.1/">
+<rdf:Description rdf:about="LINK DO PLATFORMY REDAKCYJNEJ">
+<dc:creator xml:lang="pl">Utworu, Autor</dc:creator>
+<dc:title xml:lang="pl">Tytuł w DC</dc:title>
+<dc:contributor.translator xml:lang="pl">Utworu, Tłumacz</dc:contributor.translator>
+<dc:contributor.editor xml:lang="pl">Literacki, Redaktor</dc:contributor.editor>
+<dc:contributor.technical_editor xml:lang="pl">Techniczny, Redaktor</dc:contributor.technical_editor>
+<dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+<dc:subject.period xml:lang="pl">period</dc:subject.period>
+<dc:subject.type xml:lang="pl">type</dc:subject.type>
+<dc:subject.genre xml:lang="pl">genre</dc:subject.genre>
+<dc:description xml:lang="pl">Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl). Reprodukcja cyfrowa wykonana
+ przez Bibliotekę Narodową z egzemplarza pochodzącego ze zbiorów BN.</dc:description>
+<dc:identifier.url xml:lang="pl">http://wolnelektury.pl/katalog/lektura/test1</dc:identifier.url>
+<dc:source xml:lang="pl">source</dc:source>
+<dc:rights xml:lang="pl">Domena publiczna</dc:rights>
+<dc:date.pd xml:lang="pl">1500</dc:date.pd>
+<dc:format xml:lang="pl">xml</dc:format>
+<dc:type xml:lang="pl">text</dc:type>
+<dc:type xml:lang="en">text</dc:type>
+<dc:date xml:lang="pl">2000</dc:date>
+<dc:language xml:lang="pl">pol</dc:language>
+</rdf:Description>
+</rdf:RDF>
+<liryka_l>
+
+<nota_red><akap>nota_red</akap></nota_red>
+
+<autor_utworu>autor_utworu</autor_utworu>
+<dzielo_nadrzedne>dzielo_nadrzedne</dzielo_nadrzedne>
+<nazwa_utworu>nazwa_utworu</nazwa_utworu>
+<podtytul>podtytul</podtytul>
+
+<akap>[powyżej: 
+nota_red (nie pojawia się w tekście, może być podana osobno),
+autor_utworu, dzielo_nadrzedne, nazwa_utworu, podtytul, tłumacz (z DC)]</akap>
+
+<akap>[Noty: nota/akap, dedykacja/akap, motto/akap, motto_podpis]</akap>
+
+
+<nota><akap>nota/akap</akap></nota>
+<dedykacja><akap>dedykacja/akap</akap></dedykacja>
+<motto><akap>motto/akap</akap></motto>
+<motto_podpis>motto_podpis</motto_podpis>
+
+<akap>[Początek dramatu: lista_osob, naglowek_listy, lista_osoba, miejsce_czas]</akap>
+
+<lista_osob>
+  <naglowek_listy>lista_osob/naglowek_listy</naglowek_listy>
+  <lista_osoba>lista_osob/lista_osoba</lista_osoba>
+  <lista_osoba>lista_osob/lista_osoba</lista_osoba>
+</lista_osob>
+<miejsce_czas>miejsce_czas</miejsce_czas>
+
+<akap>[naglowek_czesc, naglowek_rozdzial, naglowek_podrozdzial, srodtytul]</akap>
+
+<naglowek_czesc>naglowek_czesc</naglowek_czesc>
+<naglowek_rozdzial>naglowek_rozdzial</naglowek_rozdzial>
+<naglowek_podrozdzial>naglowek_podrozdzial</naglowek_podrozdzial>
+<srodtytul>srodtytul</srodtytul>
+
+<akap>[akap, akap_cd, akap_dialog, motyw]</akap>
+
+<akap>akap<begin id="a"/><motyw>motyw</motyw></akap>
+<akap_cd>akap_cd</akap_cd>
+<akap_dialog>akap_dialog<end id="a"/></akap_dialog>
+
+<akap>[strofa, wers_akap, wers_wciety,typ=1-6, wers_cd, zastepnik_wersu]</akap>
+
+<strofa>strofa/
+<wers_akap>wers_akap</wers_akap>/
+<wers_wciety typ="1">wers_wciety@typ=1</wers_wciety>/
+<wers_wciety typ="2">wers_wciety@typ=2</wers_wciety>/
+<wers_wciety typ="3">wers_wciety@typ=3</wers_wciety>
+</strofa><strofa>
+<wers_wciety typ="4">wers_wciety@typ=4</wers_wciety>/
+<wers_wciety typ="5">wers_wciety@typ=5</wers_wciety>/
+<wers_wciety typ="6">wers_wciety@typ=6</wers_wciety>/
+<wers_cd>wers_cd</wers_cd>/
+<zastepnik_wersu />. . . . . . . . . . . . . . . .
+</strofa>
+
+<akap>[dlugi_cytat/akap]</akap>
+
+<dlugi_cytat><akap>Cytowany akapit powinien wyglądać jak cytowany akapit.
+Znaczy, może mieć jakieś dodatkowe wcięcie, jakiś rodzaj wyróżnienia czy coś.</akap></dlugi_cytat>
+
+<akap>[poezja_cyt/strofa]</akap>
+
+<poezja_cyt><strofa>To jest poezja/
+cytowana/
+ma być porządnie/
+wyrównana</strofa></poezja_cyt>
+
+<akap>[naglowek_akt, naglowek_scena]</akap>
+
+<naglowek_akt>naglowek_akt</naglowek_akt>
+<naglowek_scena>naglowek_scena</naglowek_scena>
+
+<akap>[Kwestia: naglowek_osoba, kwestia, didask_tekst, didaskalia, strofa, akap]</akap>
+
+<naglowek_osoba>naglowek_osoba</naglowek_osoba>
+
+<kwestia>
+<didask_tekst>didask_tekst</didask_tekst>
+<didaskalia>didaskalia</didaskalia>
+<strofa>Strofa w dramacie/
+jak amen w pacie/
+rzu.</strofa>
+<akap>Powyższy kawałek wiersza jest najzupełniej bez sensu i tak naprawdę wcale nie trzyma rytmu ani rymu. Być może należy skoncentrować się na dramacie prozą, jak ta tutaj niniejsza wypowiedź. </akap></kwestia>
+
+<akap>[didaskalia, osoba]</akap>
+
+<didaskalia>odezwał się <osoba>autor</osoba>.</didaskalia>
+
+<akap>[Wyróżnienia: tytul_dziela, tytul_dziela@typ=1, wyroznienie, slowo_obce]</akap>
+
+<akap>
+<tytul_dziela>tytul_dziela</tytul_dziela>,
+<tytul_dziela typ="1">tytul_dziela@typ=1</tytul_dziela>,
+<wyroznienie>wyroznienie</wyroznienie>,
+<slowo_obce>slowo_obce</slowo_obce>
+</akap>
+
+<akap>[Przypisy: pa, pt, pr, pe]</akap>
+
+<akap>
+<pa>pa - - - przypis <wyroznienie>autorski</wyroznienie></pa>
+<pt>pt - - - przypis tłumacza</pt>
+<pr>pr - - - przypis redakcyjny</pr>
+<pe>pe - - - przypis edytorski</pe>
+</akap>
+
+<akap>[Separatory]</akap>
+
+<akap>[sekcja_swiatlo:]</akap>
+
+<sekcja_swiatlo></sekcja_swiatlo>
+
+<akap>[sekcja_asterysk:]</akap>
+
+<sekcja_asterysk></sekcja_asterysk>
+
+<akap>[separator_linia:]</akap>
+
+<separator_linia></separator_linia>
+
+
+
+<akap>[Komentarze: uwaga, extra]</akap>
+<uwaga>uwaga</uwaga>
+<extra>extra</extra>
+
+<akap>[Nieużywane]</akap>
+
+<wyp_osoba>wyp_osoba</wyp_osoba>
+<wywiad_pyt><akap>wywiad_pyt/akap</akap></wywiad_pyt>
+<wywiad_odp><akap>wywiad_odp/akap</akap></wywiad_odp>
+<mat>mat</mat>
+<www>www</www>
+
+</liryka_l>
+</utwor>