*.pyc
MANIFEST
dist
+build
+nbproject
+nbproject/*
include librarian/*.xslt
-recursive-include librarian/tests/files/ *.xml
+recursive-include tests/files/ *.xml
--- /dev/null
+Librarian
+=========
+Librarian (*ang. bibliotekarz*) to biblioteka służąca do konwersji języka składu książek opartego na XML opracowanego przez Fundację Nowoczesna Polska na inne formaty.
+
+Obecnie obsługiwane są formaty:
+
+ * XML
+ * TXT
+
+Biblioteka librarian potrafi również parsować metadane opisane przez DublinCore oraz wyciągać fragmenty motywów z lektur.
+
+
+Wymagania
+---------
+
+ * [lxml 2.2](http://codespeak.net/lxml/)
+
+
+Instalacja
+----------
+Zainstaluj biblioteki z sekcji *Wymagania* powyżej. Następnie rozpakuj archiwum z biblioteką librarian, przejdź w terminalu do rozpakowanego katalogu i wpisz:
+
+<pre>python setup.py install</pre>
+
+Na Linuxie i OSX mogą być wymagane uprawnienia administratora. W takim wypadku wpisz:
+
+<pre>sudo python setup.py install</pre>
+
+Alternatywnie możesz zainstalować bibliotekę librarian w wybranym przez siebie katalogu. W takim wypadku należy użyć argumentu *prefix* do *setup.py*:
+
+<pre>python setup.py install --prefix=ŚCIEŻKA_DO_WYBRANEGO_KATALOGU</pre>
+
+W takim wypadku będzie jednak potrzebne własnoręczne edytowanie zmiennych systemowych *PATH* i *PYTHONPATH*.
+
+
+Sposób użycia
+-------------
+Konwersja plików lektur do XHTML:
+
+<pre>book2html LEKTURA1 LEKTURA2...</pre>
+
+Konwersja plików lektur do TXT:
+
+<pre>book2txt LEKTURA1 LEKTURA2...</pre>
+
+Wyciągnięcie wszystkich fragmentów motywów z wygenerowanych plików XHTML:
+
+<pre>bookfragments PLIK1 PLIK2...</pre>
+
+# -*- coding: utf-8 -*-
+# exception classes
+
+class ParseError(Exception):
+ pass
+
+class ValidationError(Exception):
+ pass
+
+class NoDublinCore(ValidationError):
+ pass
<xsl:output encoding="utf-8" method="text" />
+<xsl:param name="wrapping" select="0" />
+
<!-- ============================================================================== -->
<!-- = MASTER TAG = -->
<!-- = (can contain block tags, paragraph tags, standalone tags and special tags) = -->
<!-- ============================================================================== -->
<xsl:template match="powiesc|opowiadanie|liryka_l|liryka_lp|dramat_wierszowany_l|dramat_wierszowany_lp|dramat_wspolczesny">
-<xsl:text>Kodowanie znaków w dokumencie: UTF-8.
------
-Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl/). Reprodukcja cyfrowa wykonana przez
-Bibliotekę Narodową z egzemplarza pochodzącego ze zbiorów BN. Ten utwór nie jest chroniony prawem autorskim i znajduje
-się w domenie publicznej, co oznacza, że możesz go swobodnie wykorzystywać, publikować i rozpowszechniać.
-
-Wersja lektury w opracowaniu merytorycznym i krytycznym (przypisy i motywy) dostępna jest na stronie %s.
------
-
-
-</xsl:text>
<xsl:if test="nazwa_utworu"><xsl:apply-templates select="autor_utworu|dzielo_nadrzedne|nazwa_utworu|podtytul" mode="header" /></xsl:if>
<xsl:text>
<xsl:apply-templates select="*|text()" mode="inline" />
</xsl:variable>
<xsl:text>
-
-/ </xsl:text><xsl:value-of select="wl:wrap_words(wl:strip($content))" /><xsl:text> /</xsl:text>
+
+/ </xsl:text><xsl:value-of select="wl:wrap_words(wl:strip($content), $wrapping)" /><xsl:text> /</xsl:text>
</xsl:template>
<xsl:template match="lista_osoba">
<xsl:text>
</xsl:text>
-<xsl:value-of select="wl:wrap_words(wl:strip($content))" />
+<xsl:value-of select="wl:wrap_words(wl:strip($content), $wrapping)" />
</xsl:template>
<xsl:template match="strofa">
from datetime import date
import time
-# Import ElementTree from anywhere
-try:
- import xml.etree.ElementTree as etree # Python >= 2.5
-except ImportError:
- try:
- import elementtree.ElementTree as etree # effbot's pure Python module
- except ImportError:
- import lxml.etree as etree # ElementTree API using libxml2
+from librarian import ValidationError, NoDublinCore
+
+import lxml.etree as etree # ElementTree API using libxml2
+from lxml.etree import XMLSyntaxError
# ==============
def __init__(self, last_name, *first_names):
self.last_name = last_name
self.first_names = first_names
-
+
+ @classmethod
+ def from_text(cls, text):
+ parts = [ token.strip() for token in text.split(',') ]
+ if len(parts) == 1:
+ surname = parts[0]
+ names = []
+ elif len(parts) != 2:
+ raise ValueError("Invalid person name. There should be at most one comma: \"%s\"." % text)
+ else:
+ surname = parts[0]
+ if len(parts[1]) == 0:
+ # there is no non-whitespace data after the comma
+ raise ValueError("Found a comma, but no names given: \"%s\" -> %r." % (text, parts))
+ names = [ name for name in parts[1].split() if len(name) ] # all non-whitespace tokens
+ return cls(surname, *names)
def __eq__(self, right):
return self.last_name == right.last_name and self.first_names == right.first_names
return '%s, %s' % (self.last_name, ' '.join(self.first_names))
else:
return self.last_name
-
-
+
def __repr__(self):
return 'Person(last_name=%r, first_names=*%r)' % (self.last_name, self.first_names)
+def as_date(text):
+ try:
+ try:
+ t = time.strptime(text, '%Y-%m-%d')
+ except ValueError:
+ t = time.strptime(text, '%Y')
+ return date(t[0], t[1], t[2])
+ except ValueError, e:
+ raise ValueError("Unrecognized date format. Try YYYY-MM-DD or YYYY.")
-def str_to_unicode(value, previous):
- return unicode(value)
-
+def as_person(text):
+ return Person.from_text(text)
-def str_to_unicode_list(value, previous):
- if previous is None:
- previous = []
- previous.append(str_to_unicode(value, None))
- return previous
+def as_unicode(text):
+ if isinstance(text, unicode):
+ return text
+ else:
+ return text.decode('utf-8')
+class Field(object):
+ def __init__(self, uri, attr_name, type=as_unicode, multiple=False, salias=None, **kwargs):
+ self.uri = uri
+ self.name = attr_name
+ self.validator = type
+ self.multiple = multiple
+ self.salias = salias
-def str_to_person(value, previous):
- comma_count = value.count(',')
-
- if comma_count == 0:
- last_name, first_names = value, []
- elif comma_count == 1:
- last_name, first_names = value.split(',')
- first_names = [name for name in first_names.split(' ') if len(name)]
- else:
- raise ValueError("value contains more than one comma: %r" % value)
-
- return Person(last_name.strip(), *first_names)
+ self.required = kwargs.get('required', True) and not kwargs.has_key('default')
+ self.default = kwargs.get('default', [] if multiple else [None])
+ def validate_value(self, val):
+ try:
+ if self.multiple:
+ if self.validator is None:
+ return val
+ return [ self.validator(v) if v is not None else v for v in val ]
+ elif len(val) > 1:
+ raise ValidationError("Mulitply values not allowed for field '%s'" % self.uri)
+ elif len(val) == 0:
+ raise ValidationError("Field %s has no value to assign. Check your defaults." % self.uri)
+ else:
+ if self.validator is None or val[0] is None:
+ return val[0]
+ return self.validator(val[0])
+ except ValueError, e:
+ raise ValidationError("Field '%s' - invald value: %s" % (self.uri, e.message))
-def str_to_date(value, previous):
- try:
- t = time.strptime(value, '%Y-%m-%d')
- except ValueError:
- t = time.strptime(value, '%Y')
- return date(t[0], t[1], t[2])
+ def validate(self, fdict):
+ if not fdict.has_key(self.uri):
+ if not self.required:
+ f = self.default
+ else:
+ raise ValidationError("Required field %s not found" % self.uri)
+ else:
+ f = fdict[self.uri]
+ return self.validate_value(f)
# ==========
# = Parser =
# ==========
-class ParseError(Exception):
- def __init__(self, message):
- super(ParseError, self).__init__(message)
-
class XMLNamespace(object):
'''Represents XML namespace.'''
RDF = XMLNamespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
DC = XMLNamespace('http://purl.org/dc/elements/1.1/')
- mapping = {
- DC('creator') : ('author', str_to_person),
- DC('title') : ('title', str_to_unicode),
- DC('subject.period') : ('epoch', str_to_unicode),
- DC('subject.type') : ('kind', str_to_unicode),
- DC('subject.genre') : ('genre', str_to_unicode),
- DC('date') : ('created_at', str_to_date),
- DC('date.pd') : ('released_to_public_domain_at', str_to_date),
- DC('contributor.translator') : ('translator', str_to_person),
- DC('contributor.technical_editor') : ('technical_editor', str_to_person),
- DC('publisher') : ('publisher', str_to_unicode),
- DC('source') : ('source_name', str_to_unicode),
- DC('source.URL') : ('source_url', str_to_unicode),
- DC('identifier.url') : ('url', str_to_unicode),
- DC('relation.hasPart') : ('parts', str_to_unicode_list),
- DC('rights.license') : ('license', str_to_unicode),
- DC('rights') : ('license_description', str_to_unicode),
- }
+ FIELDS = (
+ Field( DC('creator'), 'author', as_person),
+ Field( DC('title'), 'title'),
+ Field( DC('subject.period'), 'epoches', salias='epoch', multiple=True),
+ Field( DC('subject.type'), 'kinds', salias='kind', multiple=True),
+ Field( DC('subject.genre'), 'genres', salias='genre', multiple=True),
+ Field( DC('date'), 'created_at', as_date),
+ Field( DC('date.pd'), 'released_to_public_domain_at', as_date, required=False),
+ Field( DC('contributor.editor'), 'editors', \
+ as_person, salias='editor', multiple=True, default=[]),
+ Field( DC('contributor.translator'), 'translators', \
+ as_person, salias='translator', multiple=True, default=[]),
+ Field( DC('contributor.technical_editor'), 'technical_editors',
+ as_person, salias='technical_editor', multiple=True, default=[]),
+ Field( DC('publisher'), 'publisher'),
+ Field( DC('source'), 'source_name', required=False),
+ Field( DC('source.URL'), 'source_url', required=False),
+ Field( DC('identifier.url'), 'url'),
+ Field( DC('relation.hasPart'), 'parts', multiple=True, required=False),
+ Field( DC('rights.license'), 'license', required=False),
+ Field( DC('rights'), 'license_description'),
+ )
@classmethod
def from_string(cls, xml):
from StringIO import StringIO
return cls.from_file(StringIO(xml))
-
+
@classmethod
- def from_file(cls, xml_file):
- book_info = cls()
-
+ def from_file(cls, xmlfile):
+ desc_tag = None
try:
- tree = etree.parse(xml_file)
+ iter = etree.iterparse(xmlfile, ['start', 'end'])
+ for (event, element) in iter:
+ if element.tag == cls.RDF('RDF') and event == 'start':
+ desc_tag = element
+ break
+
+ if desc_tag is None:
+ raise NoDublinCore("DublinCore section not found. \
+ Check if there are rdf:RDF and rdf:Description tags.")
+
+ # continue 'till the end of RDF section
+ for (event, element) in iter:
+ if element.tag == cls.RDF('RDF') and event == 'end':
+ break
+
+ # if there is no end, Expat should yell at us with an ExpatError
+
+ # extract data from the element and make the info
+ return cls.from_element(desc_tag)
+ except XMLSyntaxError, e:
+ raise ParseError(e)
except ExpatError, e:
raise ParseError(e)
- description = tree.find('//' + book_info.RDF('Description'))
- book_info.wiki_url = description.get(cls.RDF('about'), None)
-
- if description is None:
- raise ParseError('no Description tag found in document')
-
- for element in description.findall('*'):
- book_info.parse_element(element)
+ @classmethod
+ def from_element(cls, rdf_tag):
+ # the tree is already parsed, so we don't need to worry about Expat errors
+ field_dict = {}
+ desc = rdf_tag.find(".//" + cls.RDF('Description') )
- return book_info
+ if desc is None:
+ raise NoDublinCore("No DublinCore section found.")
+
+ for e in desc.getchildren():
+ fv = field_dict.get(e.tag, [])
+ fv.append(e.text)
+ field_dict[e.tag] = fv
+
+ return cls( desc.attrib, field_dict )
+
+ def __init__(self, rdf_attrs, dc_fields):
+ """rdf_attrs should be a dictionary-like object with any attributes of the RDF:Description.
+ dc_fields - dictionary mapping DC fields (with namespace) to list of text values for the
+ given field. """
+
+ self.about = rdf_attrs.get(self.RDF('about'))
+ self.fmap = {}
+
+ for field in self.FIELDS:
+ value = field.validate( dc_fields )
+ setattr(self, 'prop_' + field.name, value)
+ self.fmap[field.name] = field
+ if field.salias: self.fmap[field.salias] = field
+
+ def __getattribute__(self, name):
+ try:
+ field = object.__getattribute__(self, 'fmap')[name]
+ value = object.__getattribute__(self, 'prop_'+field.name)
+ if field.name == name:
+ return value
+ else: # singular alias
+ if not field.multiple:
+ raise "OUCH!! for field %s" % name
+
+ return value[0]
+ except (KeyError, AttributeError):
+ return object.__getattribute__(self, name)
- def parse_element(self, element):
+ def __setattr__(self, name, newvalue):
try:
- attribute, converter = self.mapping[element.tag]
- setattr(self, attribute, converter(element.text, getattr(self, attribute, None)))
- except KeyError:
- pass
+ field = object.__getattribute__(self, 'fmap')[name]
+ if field.name == name:
+ object.__setattr__(self, 'prop_'+field.name, newvalue)
+ else: # singular alias
+ if not field.multiple:
+ raise "OUCH! while setting field %s" % name
- def to_xml(self):
+ object.__setattr__(self, 'prop_'+field.name, [newvalue])
+ except (KeyError, AttributeError):
+ return object.__setattr__(self, name, newvalue)
+
+ def update(self, field_dict):
+ """Update using field_dict. Verify correctness, but don't check if all
+ required fields are present."""
+ for field in self.FIELDS:
+ if field_dict.has_key(field.name):
+ setattr(self, field.name, field_dict[field.name])
+
+ def to_etree(self, parent = None):
"""XML representation of this object."""
- etree._namespace_map[str(self.RDF)] = 'rdf'
- etree._namespace_map[str(self.DC)] = 'dc'
+ #etree._namespace_map[str(self.RDF)] = 'rdf'
+ #etree._namespace_map[str(self.DC)] = 'dc'
- root = etree.Element(self.RDF('RDF'))
+ if parent is None:
+ root = etree.Element(self.RDF('RDF'))
+ else:
+ root = parent.makeelement(self.RDF('RDF'))
+
description = etree.SubElement(root, self.RDF('Description'))
- if self.wiki_url:
- description.set(self.RDF('about'), self.wiki_url)
+ if self.about:
+ description.set(self.RDF('about'), self.about)
- for tag, (attribute, converter) in self.mapping.iteritems():
- if hasattr(self, attribute):
- e = etree.Element(tag)
- e.text = unicode(getattr(self, attribute))
- description.append(e)
+ for field in self.FIELDS:
+ v = getattr(self, field.name, None)
+ if v is not None:
+ if field.multiple:
+ if len(v) == 0: continue
+ for x in v:
+ e = etree.Element(field.uri)
+ e.text = unicode(x)
+ description.append(e)
+ else:
+ e = etree.Element(field.uri)
+ e.text = unicode(v)
+ description.append(e)
- return unicode(etree.tostring(root, 'utf-8'), 'utf-8')
+ return root
def to_dict(self):
- etree._namespace_map[str(self.RDF)] = 'rdf'
- etree._namespace_map[str(self.DC)] = 'dc'
-
- result = {'about': self.wiki_url}
- for tag, (attribute, converter) in self.mapping.iteritems():
- if hasattr(self, attribute):
- result[attribute] = unicode(getattr(self, attribute))
+ result = {'about': self.about}
+ for field in self.FIELDS:
+ v = getattr(self, field.name, None)
+
+ if v is not None:
+ if field.multiple:
+ if len(v) == 0: continue
+ v = [ unicode(x) for x in v ]
+ else:
+ v = unicode(v)
+ result[field.name] = v
+
+ if field.salias:
+ v = getattr(self, field.salias)
+ if v is not None: result[field.salias] = v
return result
-
def parse(file_name):
return BookInfo.from_file(file_name)
-
-
-if __name__ == '__main__':
- import sys
-
- info = parse(sys.argv[1])
- for attribute, _ in BookInfo.mapping.values():
- print '%s: %r' % (attribute, getattr(info, attribute, None))
-
import cStringIO
import re
import copy
-import pkgutil
from lxml import etree
+from librarian.parser import WLDocument
ENTITY_SUBSTITUTIONS = [
ns['substitute_entities'] = substitute_entities
-def transform(input_filename, output_filename):
+def transform(input, output_filename=None, is_file=True):
"""Transforms file input_filename in XML to output_filename in XHTML."""
# Parse XSLT
style_filename = os.path.join(os.path.dirname(__file__), 'book2html.xslt')
style = etree.parse(style_filename)
- doc_file = cStringIO.StringIO()
- expr = re.compile(r'/\s', re.MULTILINE | re.UNICODE);
-
- f = open(input_filename, 'r')
- for line in f:
- line = line.decode('utf-8')
- line = expr.sub(u'<br/>\n', line)
- doc_file.write(line.encode('utf-8'))
- f.close()
-
- doc_file.seek(0);
+ if is_file:
+ document = WLDocument.from_file(input, True)
+ else:
+ document = WLDocument.from_string(input, True)
- parser = etree.XMLParser(remove_blank_text=True)
- doc = etree.parse(doc_file, parser)
+ result = document.transform(style)
+ del document # no longer needed large object :)
- result = doc.xslt(style)
if result.find('//p') is not None:
add_anchors(result.getroot())
add_table_of_contents(result.getroot())
- result.write(output_filename, xml_declaration=False, pretty_print=True, encoding='utf-8')
+
+ if output_filename is not None:
+ result.write(output_filename, xml_declaration=False, pretty_print=True, encoding='utf-8')
+ else:
+ return result
return True
else:
return False
--- /dev/null
+# -*- coding: utf-8 -*-
+from librarian import ValidationError, NoDublinCore, dcparser, ParseError
+from xml.parsers.expat import ExpatError
+from lxml import etree
+from lxml.etree import XMLSyntaxError
+
+import re
+from StringIO import StringIO
+
+class WLDocument(object):
+ LINE_SWAP_EXPR = re.compile(r'/\s', re.MULTILINE | re.UNICODE);
+
+ def __init__(self, edoc):
+ self.edoc = edoc
+
+ root_elem = edoc.getroot()
+ rdf_ns = dcparser.BookInfo.RDF
+ dc_path = './/' + rdf_ns('RDF')
+
+ if root_elem.tag != 'utwor':
+ raise ValidationError("Invalid root element. Found '%s', should be 'utwor'" % root_elem.tag)
+
+ self.rdf_elem = root_elem.find(dc_path)
+
+ if self.rdf_elem is None:
+ raise NoDublinCore('Document has no DublinCore - which is required.')
+
+ self.book_info = dcparser.BookInfo.from_element(self.rdf_elem)
+
+ @classmethod
+ def from_string(cls, xml, swap_endlines=False):
+ return cls.from_file(StringIO(xml), swap_endlines)
+
+ @classmethod
+ def from_file(cls, xmlfile, swap_endlines=False):
+
+ # first, prepare for parsing
+ if isinstance(xmlfile, basestring):
+ file = open(xmlfile, 'rb')
+ try:
+ data = file.read()
+ finally:
+ file.close()
+ else:
+ data = xmlfile.read()
+
+ if not isinstance(data, unicode):
+ data = data.decode('utf-8')
+
+ if swap_endlines:
+ data = cls.LINE_SWAP_EXPR.sub(u'<br />\n', data)
+
+ try:
+ parser = etree.XMLParser(remove_blank_text=True)
+ return cls( etree.parse(StringIO(data), parser) )
+ except XMLSyntaxError, e:
+ raise ParseError(e.message)
+ except ExpatError, e:
+ raise ParseError(e.message)
+
+ def transform(self, stylesheet, **options):
+ return self.edoc.xslt(stylesheet, **options)
+
+ def update_dc(self):
+ parent = self.rdf_elem.getparent()
+ parent.replace( self.rdf_elem, self.book_info.to_etree(parent) )
+
+ def serialize(self):
+ self.update_dc()
+ return etree.tostring(self.edoc, encoding=unicode, pretty_print=True)
+++ /dev/null
-# -*- coding: utf-8 -*-
-import unittest
-from os.path import dirname, join, realpath
-
-from lxml import etree
-from librarian import dcparser, html
-
-
-def test_file_path(dir_name, file_name):
- return realpath(join(dirname(__file__), 'files', dir_name, file_name))
-
-
-class TestDCParser(unittest.TestCase):
- KNOWN_RESULTS = (
- ('dcparser', 'andersen_brzydkie_kaczatko.xml', {
- 'publisher': u'Fundacja Nowoczesna Polska',
- 'about': u'http://wiki.wolnepodreczniki.pl/Lektury:Andersen/Brzydkie_kaczątko',
- 'source_name': u'Andersen, Hans Christian (1805-1875), Baśnie, Gebethner i Wolff, wyd. 7, Kraków, 1925',
- 'author': u'Andersen, Hans Christian',
- 'url': u'http://wolnelektury.pl/katalog/lektura/brzydkie-kaczatko',
- 'created_at': u'2007-08-14',
- 'title': u'Brzydkie kaczątko',
- 'kind': u'Epika',
- 'source_url': u'http://www.polona.pl/dlibra/doccontent2?id=3563&dirids=4',
- 'translator': u'Niewiadomska, Cecylia',
- 'released_to_public_domain_at': u'1925-01-01',
- 'epoch': u'Romantyzm',
- 'genre': u'Baśń',
- 'technical_editor': u'Gałecki, Dariusz',
- 'license_description': u'Domena publiczna - tłumacz Cecylia Niewiadomska zm. 1925',
- }),
- ('dcparser', 'kochanowski_piesn7.xml', {
- 'publisher': u'Fundacja Nowoczesna Polska',
- 'about': u'http://wiki.wolnepodreczniki.pl/Lektury:Kochanowski/Pieśni/Pieśń_VII_(1)',
- 'source_name': u'Kochanowski, Jan (1530-1584), Dzieła polskie, tom 1, oprac. Julian Krzyżanowski, wyd. 8, Państwowy Instytut Wydawniczy, Warszawa, 1976',
- 'author': u'Kochanowski, Jan',
- 'url': u'http://wolnelektury.pl/katalog/lektura/piesni-ksiegi-pierwsze-piesn-vii-trudna-rada-w-tej-mierze-pr',
- 'created_at': u'2007-08-31',
- 'title': u'Pieśń VII (Trudna rada w tej mierze: przyjdzie się rozjechać...)',
- 'kind': u'Liryka',
- 'source_url': u'http://www.polona.pl/Content/1499',
- 'released_to_public_domain_at': u'1584-01-01',
- 'epoch': u'Renesans',
- 'genre': u'Pieśń',
- 'technical_editor': u'Gałecki, Dariusz',
- 'license_description': u'Domena publiczna - Jan Kochanowski zm. 1584 ',
- }),
- ('dcparser', 'mickiewicz_rybka.xml', {
- 'publisher': u'Fundacja Nowoczesna Polska',
- 'about': 'http://wiki.wolnepodreczniki.pl/Lektury:Mickiewicz/Ballady/Rybka',
- 'source_name': u'Mickiewicz, Adam (1798-1855), Poezje, tom 1 (Wiersze młodzieńcze - Ballady i romanse - Wiersze do r. 1824), Krakowska Spółdzielnia Wydawnicza, wyd. 2 zwiększone, Kraków, 1922',
- 'author': u'Mickiewicz, Adam',
- 'url': u'http://wolnelektury.pl/katalog/lektura/ballady-i-romanse-rybka',
- 'created_at': u'2007-09-06',
- 'title': u'Rybka',
- 'kind': u'Liryka',
- 'source_url': u'http://www.polona.pl/Content/2222',
- 'released_to_public_domain_at': u'1855-01-01',
- 'epoch': u'Romantyzm',
- 'genre': u'Ballada',
- 'technical_editor': u'Sutkowska, Olga',
- 'license_description': u'Domena publiczna - Adam Mickiewicz zm. 1855',
- }),
- ('dcparser', 'sofokles_antygona.xml', {
- 'publisher': u'Fundacja Nowoczesna Polska',
- 'about': 'http://wiki.wolnepodreczniki.pl/Lektury:Sofokles/Antygona',
- 'source_name': u'Sofokles (496-406 a.C.), Antygona, Zakład Narodowy im. Ossolińskich, wyd. 7, Lwów, 1939',
- 'author': u'Sofokles',
- 'url': u'http://wolnelektury.pl/katalog/lektura/antygona',
- 'created_at': u'2007-08-30',
- 'title': u'Antygona',
- 'kind': u'Dramat',
- 'source_url': u'http://www.polona.pl/Content/3768',
- 'translator': u'Morawski, Kazimierz',
- 'released_to_public_domain_at': u'1925-01-01',
- 'epoch': u'Starożytność',
- 'genre': u'Tragedia',
- 'technical_editor': u'Gałecki, Dariusz',
- 'license_description': u'Domena publiczna - tłumacz Kazimierz Morawski zm. 1925',
- }),
- ('dcparser', 'biedrzycki_akslop.xml', {
- 'publisher': u'Fundacja Nowoczesna Polska',
- 'about': 'http://wiki.wolnepodreczniki.pl/Lektury:Biedrzycki/Akslop',
- 'source_name': u'Miłosz Biedrzycki, * ("Gwiazdka"), Fundacja "brulion", Kraków-Warszawa, 1993',
- 'author': u'Biedrzycki, Miłosz',
- 'url': u'http://wolnelektury.pl/katalog/lektura/akslop',
- 'created_at': u'2009-06-04',
- 'title': u'Akslop',
- 'kind': u'Liryka',
- 'source_url': u'http://free.art.pl/mlb/gwiazdka.html#t1',
- 'epoch': u'Współczesność',
- 'genre': u'Wiersz',
- 'technical_editor': u'Sutkowska, Olga',
- 'license': u'http://creativecommons.org/licenses/by-sa/3.0/',
- 'license_description': u'Creative Commons Uznanie Autorstwa - Na Tych Samych Warunkach 3.0.PL'
- }),
- )
-
- def test_parse(self):
- for dir_name, file_name, result in self.KNOWN_RESULTS:
- self.assertEqual(dcparser.parse(test_file_path(dir_name, file_name)).to_dict(), result)
-
-
-class TestParserErrors(unittest.TestCase):
- def test_error(self):
- try:
- html.transform(test_file_path('erroneous', 'asnyk_miedzy_nami.xml'),
- test_file_path('erroneous', 'asnyk_miedzy_nami.html'))
- self.fail()
- except etree.XMLSyntaxError, e:
- self.assertEqual(e.position, (25, 13))
-
-
-if __name__ == '__main__':
- unittest.main()
\ No newline at end of file
+++ /dev/null
-<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="http://wiki.wolnepodreczniki.pl/Lektury:Andersen/Brzydkie_kaczątko">
- <dc:creator xml:lang="pl">Andersen, Hans Christian</dc:creator>
- <dc:title xml:lang="pl">Brzydkie kaczątko</dc:title>
- <dc:contributor.translator xml:lang="pl">Niewiadomska, Cecylia</dc:contributor.translator>
- <dc:contributor.technical_editor xml:lang="pl">Gałecki, Dariusz</dc:contributor.technical_editor>
- <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
- <dc:subject.period xml:lang="pl">Romantyzm</dc:subject.period>
- <dc:subject.type xml:lang="pl">Epika</dc:subject.type>
- <dc:subject.genre xml:lang="pl">Baśń</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/brzydkie-kaczatko</dc:identifier.url>
- <dc:source.URL xml:lang="pl">http://www.polona.pl/dlibra/doccontent2?id=3563&dirids=4</dc:source.URL>
- <dc:source xml:lang="pl">Andersen, Hans Christian (1805-1875), Baśnie, Gebethner i Wolff, wyd. 7, Kraków, 1925</dc:source>
- <dc:rights xml:lang="pl">Domena publiczna - tłumacz Cecylia Niewiadomska zm. 1925</dc:rights>
- <dc:date.pd xml:lang="pl">1925</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">2007-08-14</dc:date>
- <dc:audience xml:lang="pl">SP1</dc:audience>
- <dc:language xml:lang="pl">pol</dc:language>
- </rdf:Description>
-</rdf:RDF>
\ No newline at end of file
+++ /dev/null
-<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="http://wiki.wolnepodreczniki.pl/Lektury:Biedrzycki/Akslop">
- <dc:creator xml:lang="pl">Biedrzycki, Miłosz</dc:creator>
- <dc:title xml:lang="pl">Akslop</dc:title>
- <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
- <dc:contributor.technical_editor xml:lang="pl">Sutkowska, Olga</dc:contributor.technical_editor>
- <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
- <dc:subject.period xml:lang="pl">Współczesność</dc:subject.period>
- <dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
- <dc:subject.genre xml:lang="pl">Wiersz</dc:subject.genre>
- <dc:description xml:lang="pl">Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl).</dc:description>
- <dc:identifier.url xml:lang="pl">http://wolnelektury.pl/katalog/lektura/akslop</dc:identifier.url>
- <dc:source.URL xml:lang="pl">http://free.art.pl/mlb/gwiazdka.html#t1</dc:source.URL>
- <dc:source xml:lang="pl">Miłosz Biedrzycki, * ("Gwiazdka"), Fundacja "brulion", Kraków-Warszawa, 1993</dc:source>
- <dc:rights xml:lang="pl">Creative Commons Uznanie Autorstwa - Na Tych Samych Warunkach 3.0.PL</dc:rights>
- <dc:rights.license>http://creativecommons.org/licenses/by-sa/3.0/</dc:rights.license>
- <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">2009-06-04</dc:date>
- <dc:audience xml:lang="pl">L</dc:audience>
- <dc:language xml:lang="pl">pol</dc:language>
- </rdf:Description>
-</rdf:RDF>
\ No newline at end of file
+++ /dev/null
-<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="http://wiki.wolnepodreczniki.pl/Lektury:Kochanowski/Pieśni/Pieśń_VII_(1)">
- <dc:creator xml:lang="pl">Kochanowski, Jan</dc:creator>
- <dc:title xml:lang="pl">Pieśń VII (Trudna rada w tej mierze: przyjdzie się rozjechać...)</dc:title>
- <dc:relation.isPartOf xml:lang="pl">http://www.wolnelektury.pl/lektura/piesni-ksiegi-pierwsze</dc:relation.isPartOf>
- <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
- <dc:contributor.editor xml:lang="pl">Krzyżanowski, Julian</dc:contributor.editor>
- <dc:contributor.editor xml:lang="pl">Otwinowska, Barbara</dc:contributor.editor>
- <dc:contributor.technical_editor xml:lang="pl">Gałecki, Dariusz</dc:contributor.technical_editor>
- <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
- <dc:subject.period xml:lang="pl">Renesans</dc:subject.period>
- <dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
- <dc:subject.genre xml:lang="pl">Pieśń</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/piesni-ksiegi-pierwsze-piesn-vii-trudna-rada-w-tej-mierze-pr</dc:identifier.url>
- <dc:source.URL xml:lang="pl">http://www.polona.pl/Content/1499</dc:source.URL>
- <dc:source xml:lang="pl">Kochanowski, Jan (1530-1584), Dzieła polskie, tom 1, oprac. Julian Krzyżanowski, wyd. 8, Państwowy Instytut Wydawniczy, Warszawa, 1976</dc:source>
- <dc:rights xml:lang="pl">Domena publiczna - Jan Kochanowski zm. 1584 </dc:rights>
- <dc:date.pd xml:lang="pl">1584</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">2007-08-31</dc:date>
- <dc:audience xml:lang="pl">L</dc:audience>
- <dc:language xml:lang="pl">pol</dc:language>
- </rdf:Description>
-</rdf:RDF>
\ No newline at end of file
+++ /dev/null
-<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="http://wiki.wolnepodreczniki.pl/Lektury:Mickiewicz/Ballady/Rybka">
- <dc:creator xml:lang="pl">Mickiewicz, Adam</dc:creator>
- <dc:title xml:lang="pl">Rybka</dc:title>
- <dc:relation.isPartOf xml:lang="pl">http://www.wolnelektury.pl/lektura/ballady-i-romanse</dc:relation.isPartOf>
- <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
- <dc:contributor.editor xml:lang="pl">Kallenbach, Józef</dc:contributor.editor>
- <dc:contributor.technical_editor xml:lang="pl">Sutkowska, Olga</dc:contributor.technical_editor>
- <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
- <dc:subject.period xml:lang="pl">Romantyzm</dc:subject.period>
- <dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
- <dc:subject.genre xml:lang="pl">Ballada</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/ballady-i-romanse-rybka</dc:identifier.url>
- <dc:source.URL xml:lang="pl">http://www.polona.pl/Content/2222</dc:source.URL>
- <dc:source xml:lang="pl">Mickiewicz, Adam (1798-1855), Poezje, tom 1 (Wiersze młodzieńcze - Ballady i romanse - Wiersze do r. 1824), Krakowska Spółdzielnia Wydawnicza, wyd. 2 zwiększone, Kraków, 1922</dc:source>
- <dc:rights xml:lang="pl">Domena publiczna - Adam Mickiewicz zm. 1855</dc:rights>
- <dc:date.pd xml:lang="pl">1855</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">2007-09-06</dc:date>
- <dc:audience xml:lang="pl">SP2</dc:audience>
- <dc:audience xml:lang="pl">G</dc:audience>
- <dc:audience xml:lang="pl">L</dc:audience>
- <dc:language xml:lang="pl">pol</dc:language>
- </rdf:Description>
-</rdf:RDF>
\ No newline at end of file
+++ /dev/null
-<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="http://wiki.wolnepodreczniki.pl/Lektury:Sofokles/Antygona">
- <dc:creator xml:lang="pl">Sofokles</dc:creator>
- <dc:title xml:lang="pl">Antygona</dc:title>
- <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
- <dc:contributor.translator xml:lang="pl">Morawski, Kazimierz</dc:contributor.translator>
- <dc:contributor.technical_editor xml:lang="pl">Gałecki, Dariusz</dc:contributor.technical_editor>
- <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
- <dc:subject.period xml:lang="pl">Starożytność</dc:subject.period>
- <dc:subject.type xml:lang="pl">Dramat</dc:subject.type>
- <dc:subject.genre xml:lang="pl">Tragedia</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/antygona</dc:identifier.url>
- <dc:source.URL xml:lang="pl">http://www.polona.pl/Content/3768</dc:source.URL>
- <dc:source xml:lang="pl">Sofokles (496-406 a.C.), Antygona, Zakład Narodowy im. Ossolińskich, wyd. 7, Lwów, 1939</dc:source>
- <dc:rights xml:lang="pl">Domena publiczna - tłumacz Kazimierz Morawski zm. 1925</dc:rights>
- <dc:date.pd xml:lang="pl">1925</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">2007-08-30</dc:date>
- <dc:audience xml:lang="pl">G</dc:audience>
- <dc:language xml:lang="pl">pol</dc:language>
- </rdf:Description>
-</rdf:RDF>
\ No newline at end of file
+++ /dev/null
-<div xmlns:wl="http://wolnelektury.pl/functions" id="book-text">
- <div id="toc">
- <h2>Spis treści</h2>
- <ol/>
- </div>
- <h1>
- <span class="author">Adam Asnyk</span>
- <span class="title">Między nami nic nie było</span>
- </h1>
- <div class="stanza">
- <p class="verse"><a name="f1" class="target"> </a><a href="#f1" class="anchor">1</a>Między nami nic nie było!</p>
- <p class="verse">
- Żadnych zwierzeń, wyznań żadnych!</p>
- <p class="verse">
- Nic nas z sobą nie łączyło —</p>
- <p class="verse">
- Prócz wiosennych marzeń zdradnych;</p>
- </div>
- <div class="stanza">
- <p class="verse"><a name="f5" class="target"> </a><a href="#f5" class="anchor">5</a>Prócz tych woni, barw i blasków,</p>
- <p class="verse">
- Unoszących się w przestrzeni;</p>
- <p class="verse">
- Prócz szumiących śpiewem lasków</p>
- <p class="verse">
- I tej świeżej łąk zieleni;</p>
- </div>
- <div class="stanza">
- <p class="verse">Prócz tych kaskad i potoków,</p>
- <p class="verse"><a name="f10" class="target"> </a><a href="#f10" class="anchor">10</a>
- Zraszających każdy parów,</p>
- <p class="verse">
- Prócz girlandy tęcz, obłoków,</p>
- <p class="verse">
- Prócz natury słodkich czarów;</p>
- </div>
- <div class="stanza">
- <p class="verse">Prócz tych wspólnych, jasnych zdrojów,</p>
- <p class="verse">
- Z których serce zachwyt piło;</p>
- <p class="verse"><a name="f15" class="target"> </a><a href="#f15" class="anchor">15</a>
- Prócz pierwiosnków i powojów,—</p>
- <p class="verse">
- Między nami nic nie było!</p>
- </div>
-</div>
+++ /dev/null
-<?xml version='1.0' encoding='utf-8'?>
-<utwor><liryka_lp>
- <autor_utworu>Adam Asnyk</autor_utworu>
- <nazwa_utworu>Między nami nic nie było</nazwa_utworu>
-
- <strofa>Między nami nic nie było!/
- Żadnych zwierzeń, wyznań żadnych!/
- Nic nas z sobą nie łączyło ---/
- Prócz wiosennych marzeń zdradnych;</strofa>
-
- <strofa>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;
-
- <strofa>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;</strofa>
-
- <strofa>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!</strofa>
-</liryka_lp></utwor>
]
-MAX_LINE_LENGTH = 80
+TEMPLATE = u"""\
+Kodowanie znaków w dokumencie: UTF-8.
+-----
+Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl/). Reprodukcja cyfrowa wykonana przez
+Bibliotekę Narodową z egzemplarza pochodzącego ze zbiorów BN. Ten utwór nie jest chroniony prawem autorskim i znajduje
+się w domenie publicznej, co oznacza, że możesz go swobodnie wykorzystywać, publikować i rozpowszechniać.
+
+Wersja lektury w opracowaniu merytorycznym i krytycznym (przypisy i motywy) dostępna jest na stronie %(url)s.
+-----
+
+
+
+%(text)s
+"""
def strip(context, text):
return text
-def wrap_words(context, text):
+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 > MAX_LINE_LENGTH:
+ if line_length > wrapping:
# Max line length was exceeded. We create new line
lines.append([])
line_length = len(word)
ns['wrap_words'] = wrap_words
-def transform(input_filename, output_filename):
+def transform(input_filename, output_filename, **options):
"""Transforms file input_filename in XML to output_filename in TXT."""
# Parse XSLT
style_filename = os.path.join(os.path.dirname(__file__), 'book2txt.xslt')
style = etree.parse(style_filename)
- doc_file = cStringIO.StringIO()
- expr = re.compile(r'/\s', re.MULTILINE | re.UNICODE);
-
- f = open(input_filename, 'r')
- for line in f:
- line = line.decode('utf-8')
- line = expr.sub(u'<br/>\n', line)
- doc_file.write(line.encode('utf-8'))
- f.close()
+ if is_file:
+ document = WLDocument.from_file(input, True)
+ else:
+ document = WLDocument.from_string(input, True)
- doc_file.seek(0)
+ result = document.transform(style, **options)
- parser = etree.XMLParser(remove_blank_text=True)
- doc = etree.parse(doc_file, parser)
-
- result = doc.xslt(style)
output_file = codecs.open(output_filename, 'wb', encoding='utf-8')
- output_file.write(unicode(result) % dcparser.parse(input_filename).url)
+ output_file.write(TEMPLATE % {
+ 'url': dcparser.parse(input_filename).url,
+ 'text': unicode(result),
+ })
import os
import optparse
-from librarian import html
+from librarian import html, ParseError
if __name__ == '__main__':
print input_filename
output_filename = os.path.splitext(input_filename)[0] + '.html'
- html.transform(input_filename, output_filename)
+ try:
+ html.transform(input_filename, output_filename)
+ except ParseError, e:
+ print '%(file)s:%(name)s:%(message)s' % {
+ 'file': input_filename,
+ 'name': e.__class__.__name__,
+ 'message': e.message
+ }
+ except IOError, e:
+ print '%(file)s:%(name)s:%(message)s' % {
+ 'file': input_filename,
+ 'name': e.__class__.__name__,
+ 'message': e.strerror,
+ }
+ except BaseException, e:
+ print '%(file)s:%(etype)s:%(message)s' % {
+ 'file': input_filename,
+ 'etype': e.__class__.__name__,
+ 'message': e.message,
+ }
+ raise e
import optparse
from librarian import text
+from librarian import dcparser, ParseError
if __name__ == '__main__':
parser.add_option('-v', '--verbose', action='store_true', dest='verbose', default=False,
help='print status messages to stdout')
-
+ parser.add_option('-w', '--wrap', action='store', type='int', dest='wrapping', default=0,
+ help='set line wrap column')
+
options, input_filenames = parser.parse_args()
-
+
if len(input_filenames) < 1:
parser.print_help()
exit(1)
print input_filename
output_filename = os.path.splitext(input_filename)[0] + '.txt'
- text.transform(input_filename, output_filename)
-
+ try:
+ text.transform(input_filename, output_filename, wrapping=str(options.wrapping))
+ except ParseError, e:
+ print '%(file)s:%(name)s:%(message)s' % {
+ 'file': input_filename,
+ 'name': e.__class__.__name__,
+ 'message': e.message
+ }
+ except IOError, e:
+ print '%(file)s:%(name)s:%(message)s' % {
+ 'file': input_filename,
+ 'name': e.__class__.__name__,
+ 'message': e.strerror,
+ }
+ except BaseException, e:
+ print '%(file)s:%(etype)s:%(message)s' % {
+ 'file': input_filename,
+ 'etype': e.__class__.__name__,
+ 'message': e.message,
+ }
+ raise e
+#!/usr/bin/env python
# -*- coding: utf-8 -*-
from distutils.core import setup
-
+from tests.utils import TestCommand
setup(
name='librarian',
- version='1.1',
+ version='1.2.1',
description='Converter from WolneLektury.pl XML-based language to XHTML, TXT and other formats',
author='Marek Stępniowski',
author_email='marek@stepniowski.com',
url='http://redmine.nowoczesnapolska.org.pl/',
- packages=['librarian', 'librarian.tests'],
- package_dir={'librarian': 'librarian'},
+ packages=['librarian', 'tests'],
+ package_dir={'librarian': 'librarian', 'tests': 'tests'},
package_data={
'librarian': ['*.xslt'],
- 'librarian.tests': ['files/dcparser/*.xml', 'files/erroneous/*.xml'],
+ 'tests': ['files/dcparser/*.xml', 'files/erroneous/*.xml'],
},
scripts=['scripts/book2html', 'scripts/book2txt', 'scripts/bookfragments', 'scripts/genslugs'],
+ cmdclass={'test': TestCommand},
)
--- /dev/null
+{
+ 'publisher': u'Fundacja Nowoczesna Polska',
+ 'about': u'http://wiki.wolnepodreczniki.pl/Lektury:Andersen/Brzydkie_kaczątko',
+ 'source_name': u'Andersen, Hans Christian (1805-1875), Baśnie, Gebethner i Wolff, wyd. 7, Kraków, 1925',
+ 'author': u'Andersen, Hans Christian',
+ 'url': u'http://wolnelektury.pl/katalog/lektura/brzydkie-kaczatko',
+ 'created_at': u'2007-08-14',
+ 'title': u'Brzydkie kaczątko',
+ 'kind': u'Epika',
+ 'source_url': u'http://www.polona.pl/dlibra/doccontent2?id=3563&dirids=4',
+ 'translators': [u'Niewiadomska, Cecylia'],
+ 'released_to_public_domain_at': u'1925-01-01',
+ 'epoch': u'Romantyzm',
+ 'genre': u'Baśń',
+ 'technical_editors': [u'Gałecki, Dariusz'],
+ 'license_description': u'Domena publiczna - tłumacz Cecylia Niewiadomska zm. 1925',
+}
--- /dev/null
+<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="http://wiki.wolnepodreczniki.pl/Lektury:Andersen/Brzydkie_kaczątko">
+ <dc:creator xml:lang="pl">Andersen, Hans Christian</dc:creator>
+ <dc:title xml:lang="pl">Brzydkie kaczątko</dc:title>
+ <dc:contributor.translator xml:lang="pl">Niewiadomska, Cecylia</dc:contributor.translator>
+ <dc:contributor.technical_editor xml:lang="pl">Gałecki, Dariusz</dc:contributor.technical_editor>
+ <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+ <dc:subject.period xml:lang="pl">Romantyzm</dc:subject.period>
+ <dc:subject.type xml:lang="pl">Epika</dc:subject.type>
+ <dc:subject.genre xml:lang="pl">Baśń</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/brzydkie-kaczatko</dc:identifier.url>
+ <dc:source.URL xml:lang="pl">http://www.polona.pl/dlibra/doccontent2?id=3563&dirids=4</dc:source.URL>
+ <dc:source xml:lang="pl">Andersen, Hans Christian (1805-1875), Baśnie, Gebethner i Wolff, wyd. 7, Kraków, 1925</dc:source>
+ <dc:rights xml:lang="pl">Domena publiczna - tłumacz Cecylia Niewiadomska zm. 1925</dc:rights>
+ <dc:date.pd xml:lang="pl">1925</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">2007-08-14</dc:date>
+ <dc:audience xml:lang="pl">SP1</dc:audience>
+ <dc:language xml:lang="pl">pol</dc:language>
+ </rdf:Description>
+</rdf:RDF>
\ No newline at end of file
--- /dev/null
+{
+ 'editors': [u'Sekuła, Aleksandra'],
+ 'publisher': u'Fundacja Nowoczesna Polska',
+ 'about': 'http://wiki.wolnepodreczniki.pl/Lektury:Biedrzycki/Akslop',
+ 'source_name': u'Miłosz Biedrzycki, * ("Gwiazdka"), Fundacja "brulion", Kraków-Warszawa, 1993',
+ 'author': u'Biedrzycki, Miłosz',
+ 'url': u'http://wolnelektury.pl/katalog/lektura/akslop',
+ 'created_at': u'2009-06-04',
+ 'title': u'Akslop',
+ 'kind': u'Liryka',
+ 'source_url': u'http://free.art.pl/mlb/gwiazdka.html#t1',
+ 'epoch': u'Współczesność',
+ 'genre': u'Wiersz',
+ 'technical_editors': [u'Sutkowska, Olga'],
+ 'license': u'http://creativecommons.org/licenses/by-sa/3.0/',
+ 'license_description': u'Creative Commons Uznanie Autorstwa - Na Tych Samych Warunkach 3.0.PL'
+}
--- /dev/null
+<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="http://wiki.wolnepodreczniki.pl/Lektury:Biedrzycki/Akslop">
+ <dc:creator xml:lang="pl">Biedrzycki, Miłosz</dc:creator>
+ <dc:title xml:lang="pl">Akslop</dc:title>
+ <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
+ <dc:contributor.technical_editor xml:lang="pl">Sutkowska, Olga</dc:contributor.technical_editor>
+ <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+ <dc:subject.period xml:lang="pl">Współczesność</dc:subject.period>
+ <dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
+ <dc:subject.genre xml:lang="pl">Wiersz</dc:subject.genre>
+ <dc:description xml:lang="pl">Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl).</dc:description>
+ <dc:identifier.url xml:lang="pl">http://wolnelektury.pl/katalog/lektura/akslop</dc:identifier.url>
+ <dc:source.URL xml:lang="pl">http://free.art.pl/mlb/gwiazdka.html#t1</dc:source.URL>
+ <dc:source xml:lang="pl">Miłosz Biedrzycki, * ("Gwiazdka"), Fundacja "brulion", Kraków-Warszawa, 1993</dc:source>
+ <dc:rights xml:lang="pl">Creative Commons Uznanie Autorstwa - Na Tych Samych Warunkach 3.0.PL</dc:rights>
+ <dc:rights.license>http://creativecommons.org/licenses/by-sa/3.0/</dc:rights.license>
+ <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">2009-06-04</dc:date>
+ <dc:audience xml:lang="pl">L</dc:audience>
+ <dc:language xml:lang="pl">pol</dc:language>
+ </rdf:Description>
+</rdf:RDF>
\ No newline at end of file
--- /dev/null
+{
+ 'publisher': u'Fundacja Nowoczesna Polska',
+ 'about': u'http://wiki.wolnepodreczniki.pl/Lektury:Kochanowski/Pieśni/Pieśń_VII_(1)',
+ 'source_name': u'Kochanowski, Jan (1530-1584), Dzieła polskie, tom 1, oprac. Julian Krzyżanowski, wyd. 8, Państwowy Instytut Wydawniczy, Warszawa, 1976',
+ 'author': u'Kochanowski, Jan',
+ 'url': u'http://wolnelektury.pl/katalog/lektura/piesni-ksiegi-pierwsze-piesn-vii-trudna-rada-w-tej-mierze-pr',
+ 'created_at': u'2007-08-31',
+ 'title': u'Pieśń VII (Trudna rada w tej mierze: przyjdzie się rozjechać...)',
+ 'kind': u'Liryka',
+ 'source_url': u'http://www.polona.pl/Content/1499',
+ 'released_to_public_domain_at': u'1584-01-01',
+ 'epoch': u'Renesans',
+ 'genre': u'Pieśń',
+ 'technical_editors': [u'Gałecki, Dariusz'],
+ 'license_description': u'Domena publiczna - Jan Kochanowski zm. 1584 ',
+ 'editors': [u'Sekuła, Aleksandra', u'Krzyżanowski, Julian', u'Otwinowska, Barbara'],
+}
+
--- /dev/null
+<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="http://wiki.wolnepodreczniki.pl/Lektury:Kochanowski/Pieśni/Pieśń_VII_(1)">
+ <dc:creator xml:lang="pl">Kochanowski, Jan</dc:creator>
+ <dc:title xml:lang="pl">Pieśń VII (Trudna rada w tej mierze: przyjdzie się rozjechać...)</dc:title>
+ <dc:relation.isPartOf xml:lang="pl">http://www.wolnelektury.pl/lektura/piesni-ksiegi-pierwsze</dc:relation.isPartOf>
+ <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
+ <dc:contributor.editor xml:lang="pl">Krzyżanowski, Julian</dc:contributor.editor>
+ <dc:contributor.editor xml:lang="pl">Otwinowska, Barbara</dc:contributor.editor>
+ <dc:contributor.technical_editor xml:lang="pl">Gałecki, Dariusz</dc:contributor.technical_editor>
+ <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+ <dc:subject.period xml:lang="pl">Renesans</dc:subject.period>
+ <dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
+ <dc:subject.genre xml:lang="pl">Pieśń</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/piesni-ksiegi-pierwsze-piesn-vii-trudna-rada-w-tej-mierze-pr</dc:identifier.url>
+ <dc:source.URL xml:lang="pl">http://www.polona.pl/Content/1499</dc:source.URL>
+ <dc:source xml:lang="pl">Kochanowski, Jan (1530-1584), Dzieła polskie, tom 1, oprac. Julian Krzyżanowski, wyd. 8, Państwowy Instytut Wydawniczy, Warszawa, 1976</dc:source>
+ <dc:rights xml:lang="pl">Domena publiczna - Jan Kochanowski zm. 1584 </dc:rights>
+ <dc:date.pd xml:lang="pl">1584</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">2007-08-31</dc:date>
+ <dc:audience xml:lang="pl">L</dc:audience>
+ <dc:language xml:lang="pl">pol</dc:language>
+ </rdf:Description>
+</rdf:RDF>
--- /dev/null
+{
+ 'editors': [u'Sekuła, Aleksandra', u'Kallenbach, Józef'],
+ 'publisher': u'Fundacja Nowoczesna Polska',
+ 'about': 'http://wiki.wolnepodreczniki.pl/Lektury:Mickiewicz/Ballady/Rybka',
+ 'source_name': u'Mickiewicz, Adam (1798-1855), Poezje, tom 1 (Wiersze młodzieńcze - Ballady i romanse - Wiersze do r. 1824), Krakowska Spółdzielnia Wydawnicza, wyd. 2 zwiększone, Kraków, 1922',
+ 'author': u'Mickiewicz, Adam',
+ 'url': u'http://wolnelektury.pl/katalog/lektura/ballady-i-romanse-rybka',
+ 'created_at': u'2007-09-06',
+ 'title': u'Rybka',
+ 'kind': u'Liryka',
+ 'source_url': u'http://www.polona.pl/Content/2222',
+ 'released_to_public_domain_at': u'1855-01-01',
+ 'epoch': u'Romantyzm',
+ 'genre': u'Ballada',
+ 'technical_editors': [u'Sutkowska, Olga'],
+ 'license_description': u'Domena publiczna - Adam Mickiewicz zm. 1855',
+}
+
--- /dev/null
+<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="http://wiki.wolnepodreczniki.pl/Lektury:Mickiewicz/Ballady/Rybka">
+ <dc:creator xml:lang="pl">Mickiewicz, Adam</dc:creator>
+ <dc:title xml:lang="pl">Rybka</dc:title>
+ <dc:relation.isPartOf xml:lang="pl">http://www.wolnelektury.pl/lektura/ballady-i-romanse</dc:relation.isPartOf>
+ <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
+ <dc:contributor.editor xml:lang="pl">Kallenbach, Józef</dc:contributor.editor>
+ <dc:contributor.technical_editor xml:lang="pl">Sutkowska, Olga</dc:contributor.technical_editor>
+ <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+ <dc:subject.period xml:lang="pl">Romantyzm</dc:subject.period>
+ <dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
+ <dc:subject.genre xml:lang="pl">Ballada</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/ballady-i-romanse-rybka</dc:identifier.url>
+ <dc:source.URL xml:lang="pl">http://www.polona.pl/Content/2222</dc:source.URL>
+ <dc:source xml:lang="pl">Mickiewicz, Adam (1798-1855), Poezje, tom 1 (Wiersze młodzieńcze - Ballady i romanse - Wiersze do r. 1824), Krakowska Spółdzielnia Wydawnicza, wyd. 2 zwiększone, Kraków, 1922</dc:source>
+ <dc:rights xml:lang="pl">Domena publiczna - Adam Mickiewicz zm. 1855</dc:rights>
+ <dc:date.pd xml:lang="pl">1855</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">2007-09-06</dc:date>
+ <dc:audience xml:lang="pl">SP2</dc:audience>
+ <dc:audience xml:lang="pl">G</dc:audience>
+ <dc:audience xml:lang="pl">L</dc:audience>
+ <dc:language xml:lang="pl">pol</dc:language>
+ </rdf:Description>
+</rdf:RDF>
\ No newline at end of file
--- /dev/null
+{
+ 'editors': [u'Sekuła, Aleksandra'],
+ 'publisher': u'Fundacja Nowoczesna Polska',
+ 'about': 'http://wiki.wolnepodreczniki.pl/Lektury:Sofokles/Antygona',
+ 'source_name': u'Sofokles (496-406 a.C.), Antygona, Zakład Narodowy im. Ossolińskich, wyd. 7, Lwów, 1939',
+ 'author': u'Sofokles',
+ 'url': u'http://wolnelektury.pl/katalog/lektura/antygona',
+ 'created_at': u'2007-08-30',
+ 'title': u'Antygona',
+ 'kind': u'Dramat',
+ 'source_url': u'http://www.polona.pl/Content/3768',
+ 'translators': [u'Morawski, Kazimierz'],
+ 'released_to_public_domain_at': u'1925-01-01',
+ 'epoch': u'Starożytność',
+ 'genre': u'Tragedia',
+ 'technical_editors': [u'Gałecki, Dariusz'],
+ 'license_description': u'Domena publiczna - tłumacz Kazimierz Morawski zm. 1925',
+}
+
--- /dev/null
+<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="http://wiki.wolnepodreczniki.pl/Lektury:Sofokles/Antygona">
+ <dc:creator xml:lang="pl">Sofokles</dc:creator>
+ <dc:title xml:lang="pl">Antygona</dc:title>
+ <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
+ <dc:contributor.translator xml:lang="pl">Morawski, Kazimierz</dc:contributor.translator>
+ <dc:contributor.technical_editor xml:lang="pl">Gałecki, Dariusz</dc:contributor.technical_editor>
+ <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+ <dc:subject.period xml:lang="pl">Starożytność</dc:subject.period>
+ <dc:subject.type xml:lang="pl">Dramat</dc:subject.type>
+ <dc:subject.genre xml:lang="pl">Tragedia</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/antygona</dc:identifier.url>
+ <dc:source.URL xml:lang="pl">http://www.polona.pl/Content/3768</dc:source.URL>
+ <dc:source xml:lang="pl">Sofokles (496-406 a.C.), Antygona, Zakład Narodowy im. Ossolińskich, wyd. 7, Lwów, 1939</dc:source>
+ <dc:rights xml:lang="pl">Domena publiczna - tłumacz Kazimierz Morawski zm. 1925</dc:rights>
+ <dc:date.pd xml:lang="pl">1925</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">2007-08-30</dc:date>
+ <dc:audience xml:lang="pl">G</dc:audience>
+ <dc:language xml:lang="pl">pol</dc:language>
+ </rdf:Description>
+</rdf:RDF>
\ No newline at end of file
--- /dev/null
+<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="http://wiki.wolnepodreczniki.pl/Lektury:Andersen/Brzydkie_kaczątko">
+ <dc:creator xml:lang="pl">Andersen, Hans Christian</dc:creator>
+ <dc:title xml:lang="pl">Brzydkie kaczątko</dc:title>
+ <dc:contributor.translator xml:lang="pl">Niewiadomska, Cecylia</dc:contributor.translator>
+ <dc:contributor.technical_editor xml:lang="pl">Gałecki, Dariusz</dc:contributor.technical_editor>
+ <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+ <dc:subject.period xml:lang="pl">Romantyzm</dc:subject.period>
+ <dc:subject.type xml:lang="pl">Epika</dc:subject.type>
+ <dc:subject.genre xml:lang="pl">Baśń</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/brzydkie-kaczatko</dc:identifier.url>
+ <dc:source.URL xml:lang="pl">http://www.polona.pl/dlibra/doccontent2?id=3563&dirids=4</dc:source.URL>
+ <dc:source xml:lang="pl">Andersen, Hans Christian (1805-1875), Baśnie, Gebethner i Wolff, wyd. 7, Kraków, 1925</dc:source>
+ <dc:rights xml:lang="pl">Domena publiczna - tłumacz Cecylia Niewiadomska zm. 1925</dc:rights>
+ <dc:date.pd xml:lang="pl">1925</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">2007-08-14</dc:date>
+ <dc:audience xml:lang="pl">SP1</dc:audience>
+ <dc:language xml:lang="pl">pol</dc:language>
+ </rdf:Description>
+</rdf:RDF>
\ No newline at end of file
--- /dev/null
+<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="http://wiki.wolnepodreczniki.pl/Lektury:Biedrzycki/Akslop">
+ <dc:creator xml:lang="pl">Biedrzycki, Miłosz</dc:creator>
+ <dc:title xml:lang="pl">Akslop</dc:title>
+ <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
+ <dc:contributor.technical_editor xml:lang="pl">Sutkowska, Olga</dc:contributor.technical_editor>
+ <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+ <dc:subject.period xml:lang="pl">Współczesność</dc:subject.period>
+ <dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
+ <dc:subject.genre xml:lang="pl">Wiersz</dc:subject.genre>
+ <dc:description xml:lang="pl">Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl).</dc:description>
+ <dc:identifier.url xml:lang="pl">http://wolnelektury.pl/katalog/lektura/akslop</dc:identifier.url>
+ <dc:source.URL xml:lang="pl">http://free.art.pl/mlb/gwiazdka.html#t1</dc:source.URL>
+ <dc:source xml:lang="pl">Miłosz Biedrzycki, * ("Gwiazdka"), Fundacja "brulion", Kraków-Warszawa, 1993</dc:source>
+ <dc:rights xml:lang="pl">Creative Commons Uznanie Autorstwa - Na Tych Samych Warunkach 3.0.PL</dc:rights>
+ <dc:rights.license>http://creativecommons.org/licenses/by-sa/3.0/</dc:rights.license>
+ <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">2009-06-04</dc:date>
+ <dc:audience xml:lang="pl">L</dc:audience>
+ <dc:language xml:lang="pl">pol</dc:language>
+ </rdf:Description>
+</rdf:RDF>
\ No newline at end of file
--- /dev/null
+<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="http://wiki.wolnepodreczniki.pl/Lektury:Kochanowski/Pieśni/Pieśń_VII_(1)">
+ <dc:creator xml:lang="pl">Kochanowski, Jan</dc:creator>
+ <dc:title xml:lang="pl">Pieśń VII (Trudna rada w tej mierze: przyjdzie się rozjechać...)</dc:title>
+ <dc:relation.isPartOf xml:lang="pl">http://www.wolnelektury.pl/lektura/piesni-ksiegi-pierwsze</dc:relation.isPartOf>
+ <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
+ <dc:contributor.editor xml:lang="pl">Krzyżanowski, Julian</dc:contributor.editor>
+ <dc:contributor.editor xml:lang="pl">Otwinowska, Barbara</dc:contributor.editor>
+ <dc:contributor.technical_editor xml:lang="pl">Gałecki, Dariusz</dc:contributor.technical_editor>
+ <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+ <dc:subject.period xml:lang="pl">Renesans</dc:subject.period>
+ <dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
+ <dc:subject.genre xml:lang="pl">Pieśń</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/piesni-ksiegi-pierwsze-piesn-vii-trudna-rada-w-tej-mierze-pr</dc:identifier.url>
+ <dc:source.URL xml:lang="pl">http://www.polona.pl/Content/1499</dc:source.URL>
+ <dc:source xml:lang="pl">Kochanowski, Jan (1530-1584), Dzieła polskie, tom 1, oprac. Julian Krzyżanowski, wyd. 8, Państwowy Instytut Wydawniczy, Warszawa, 1976</dc:source>
+ <dc:rights xml:lang="pl">Domena publiczna - Jan Kochanowski zm. 1584 </dc:rights>
+ <dc:date.pd xml:lang="pl">1584</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">2007-08-31</dc:date>
+ <dc:audience xml:lang="pl">L</dc:audience>
+ <dc:language xml:lang="pl">pol</dc:language>
+ </rdf:Description>
+</rdf:RDF>
--- /dev/null
+<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="http://wiki.wolnepodreczniki.pl/Lektury:Mickiewicz/Ballady/Rybka">
+ <dc:creator xml:lang="pl">Mickiewicz, Adam</dc:creator>
+ <dc:title xml:lang="pl">Rybka</dc:title>
+ <dc:relation.isPartOf xml:lang="pl">http://www.wolnelektury.pl/lektura/ballady-i-romanse</dc:relation.isPartOf>
+ <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
+ <dc:contributor.editor xml:lang="pl">Kallenbach, Józef</dc:contributor.editor>
+ <dc:contributor.technical_editor xml:lang="pl">Sutkowska, Olga</dc:contributor.technical_editor>
+ <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+ <dc:subject.period xml:lang="pl">Romantyzm</dc:subject.period>
+ <dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
+ <dc:subject.genre xml:lang="pl">Ballada</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/ballady-i-romanse-rybka</dc:identifier.url>
+ <dc:source.URL xml:lang="pl">http://www.polona.pl/Content/2222</dc:source.URL>
+ <dc:source xml:lang="pl">Mickiewicz, Adam (1798-1855), Poezje, tom 1 (Wiersze młodzieńcze - Ballady i romanse - Wiersze do r. 1824), Krakowska Spółdzielnia Wydawnicza, wyd. 2 zwiększone, Kraków, 1922</dc:source>
+ <dc:rights xml:lang="pl">Domena publiczna - Adam Mickiewicz zm. 1855</dc:rights>
+ <dc:date.pd xml:lang="pl">1855</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">2007-09-06</dc:date>
+ <dc:audience xml:lang="pl">SP2</dc:audience>
+ <dc:audience xml:lang="pl">G</dc:audience>
+ <dc:audience xml:lang="pl">L</dc:audience>
+ <dc:language xml:lang="pl">pol</dc:language>
+ </rdf:Description>
+</rdf:RDF>
\ No newline at end of file
--- /dev/null
+<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="http://wiki.wolnepodreczniki.pl/Lektury:Sofokles/Antygona">
+ <dc:creator xml:lang="pl">Sofokles</dc:creator>
+ <dc:title xml:lang="pl">Antygona</dc:title>
+ <dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
+ <dc:contributor.translator xml:lang="pl">Morawski, Kazimierz</dc:contributor.translator>
+ <dc:contributor.technical_editor xml:lang="pl">Gałecki, Dariusz</dc:contributor.technical_editor>
+ <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+ <dc:subject.period xml:lang="pl">Starożytność</dc:subject.period>
+ <dc:subject.type xml:lang="pl">Dramat</dc:subject.type>
+ <dc:subject.genre xml:lang="pl">Tragedia</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/antygona</dc:identifier.url>
+ <dc:source.URL xml:lang="pl">http://www.polona.pl/Content/3768</dc:source.URL>
+ <dc:source xml:lang="pl">Sofokles (496-406 a.C.), Antygona, Zakład Narodowy im. Ossolińskich, wyd. 7, Lwów, 1939</dc:source>
+ <dc:rights xml:lang="pl">Domena publiczna - tłumacz Kazimierz Morawski zm. 1925</dc:rights>
+ <dc:date.pd xml:lang="pl">1925</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">2007-08-30</dc:date>
+ <dc:audience xml:lang="pl">G</dc:audience>
+ <dc:language xml:lang="pl">pol</dc:language>
+ </rdf:Description>
+</rdf:RDF>
\ No newline at end of file
--- /dev/null
+<div xmlns:wl="http://wolnelektury.pl/functions" id="book-text">
+ <div id="toc">
+ <h2>Spis treści</h2>
+ <ol/>
+ </div>
+ <h1>
+ <span class="author">Adam Asnyk</span>
+ <span class="title">Między nami nic nie było</span>
+ </h1>
+ <div class="stanza">
+ <p class="verse"><a name="f1" class="target"> </a><a href="#f1" class="anchor">1</a>Między nami nic nie było!</p>
+ <p class="verse">
+ Żadnych zwierzeń, wyznań żadnych!</p>
+ <p class="verse">
+ Nic nas z sobą nie łączyło —</p>
+ <p class="verse">
+ Prócz wiosennych marzeń zdradnych;</p>
+ </div>
+ <div class="stanza">
+ <p class="verse"><a name="f5" class="target"> </a><a href="#f5" class="anchor">5</a>Prócz tych woni, barw i blasków,</p>
+ <p class="verse">
+ Unoszących się w przestrzeni;</p>
+ <p class="verse">
+ Prócz szumiących śpiewem lasków</p>
+ <p class="verse">
+ I tej świeżej łąk zieleni;</p>
+ </div>
+ <div class="stanza">
+ <p class="verse">Prócz tych kaskad i potoków,</p>
+ <p class="verse"><a name="f10" class="target"> </a><a href="#f10" class="anchor">10</a>
+ Zraszających każdy parów,</p>
+ <p class="verse">
+ Prócz girlandy tęcz, obłoków,</p>
+ <p class="verse">
+ Prócz natury słodkich czarów;</p>
+ </div>
+ <div class="stanza">
+ <p class="verse">Prócz tych wspólnych, jasnych zdrojów,</p>
+ <p class="verse">
+ Z których serce zachwyt piło;</p>
+ <p class="verse"><a name="f15" class="target"> </a><a href="#f15" class="anchor">15</a>
+ Prócz pierwiosnków i powojów,—</p>
+ <p class="verse">
+ Między nami nic nie było!</p>
+ </div>
+</div>
--- /dev/null
+<?xml version='1.0' encoding='utf-8'?>
+<utwor><liryka_lp>
+ <autor_utworu>Adam Asnyk</autor_utworu>
+ <nazwa_utworu>Między nami nic nie było</nazwa_utworu>
+
+ <strofa>Między nami nic nie było!/
+ Żadnych zwierzeń, wyznań żadnych!/
+ Nic nas z sobą nie łączyło ---/
+ Prócz wiosennych marzeń zdradnych;</strofa>
+
+ <strofa>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;
+
+ <strofa>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;</strofa>
+
+ <strofa>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!</strofa>
+</liryka_lp></utwor>
--- /dev/null
+<?xml version='1.0' encoding='utf-8'?>
+<utwor><liryka_lp>
+ <autor_utworu>Adam Asnyk</autor_utworu>
+ <nazwa_utworu>Między nami nic nie było</nazwa_utworu>
+
+ <strofa>Między nami nic nie było!/
+ Żadnych zwierzeń, wyznań żadnych!/
+ Nic nas z sobą nie łączyło ---/
+ Prócz wiosennych marzeń zdradnych;</strofa>
+
+ <strofa>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;</strofa>
+
+ <strofa>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;</strofa>
+
+ <strofa>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!</strofa>
+</liryka_lp></utwor>
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import unittest
+
+from lxml import etree
+from utils import get_file_path
+from librarian import dcparser, html, ParseError
+from utils import AutoTestMetaclass
+
+class TestDCParser(unittest.TestCase):
+ __metaclass__ = AutoTestMetaclass
+
+ TEST_DIR = 'dcparser'
+
+ def run_auto_test(self, in_data, out_data):
+ info = dcparser.BookInfo.from_string(in_data).to_dict()
+ should_be = eval(out_data)
+ for key in should_be:
+ self.assertEqual( info[key], should_be[key] )
+
+class TestDCSerialize(unittest.TestCase):
+ __metaclass__ = AutoTestMetaclass
+
+ TEST_DIR = 'dcserialize'
+
+ def run_auto_test(self, in_data, out_data):
+ import lxml.etree
+ # first parse the input
+ info = dcparser.BookInfo.from_string(in_data)
+
+ # serialize
+ serialized = lxml.etree.tostring(info.to_etree(), encoding=unicode).encode('utf-8')
+
+ # then parse again
+ info_bis = dcparser.BookInfo.from_string(serialized)
+
+ # check if they are the same
+ for key in vars(info):
+ self.assertEqual( getattr(info, key), getattr(info_bis, key))
+
+ for key in vars(info_bis):
+ self.assertEqual( getattr(info, key), getattr(info_bis, key))
+
+class TestParserErrors(unittest.TestCase):
+ def test_error(self):
+ try:
+ html.transform(get_file_path('erroneous', 'asnyk_miedzy_nami.xml'),
+ get_file_path('erroneous', 'asnyk_miedzy_nami.html'))
+ self.fail()
+ except ParseError:
+ pass
+ #self.assertEqual(e.position, (25, 13))
+
+if __name__ == '__main__':
+ unittest.main()
--- /dev/null
+#!/usr/bin/env python
+# encoding: utf-8
+
+import unittest
+
+from utils import get_file_path
+from librarian import dcparser
+from librarian import text, NoDublinCore
+
+
+class TestXML(unittest.TestCase):
+ def test_no_dublincore(self):
+ try:
+ text.transform(get_file_path('text', 'asnyk_miedzy_nami.xml'),
+ get_file_path('text', 'asnyk_miedzy_nami.txt'))
+ self.fail()
+ except NoDublinCore, e:
+ pass
+
+
+if __name__ == '__main__':
+ unittest.main()
--- /dev/null
+from __future__ import with_statement
+
+import os
+from distutils.core import Command
+from unittest import TextTestRunner, TestLoader
+from glob import glob
+from os.path import dirname, join, realpath, splitext, basename, walk
+from os import listdir
+import codecs
+
+class AutoTestMetaclass(type):
+
+ def __new__(cls, name, bases, class_dict):
+ test_dir = class_dict.pop('TEST_DIR')
+ path = realpath( join(dirname(__file__), 'files', test_dir) )
+
+ for file in listdir(path):
+ base, ext = splitext(file)
+ if ext != '.xml':
+ continue
+
+ class_dict['test_'+base] = cls.make_test_runner(base, \
+ join(path, base +'.xml'), join(path, base + '.out') )
+
+ return type.__new__(cls, name, bases, class_dict)
+
+ @staticmethod
+ def make_test_runner(name, inputf, outputf):
+ def runner(self):
+ with open(inputf, 'rb') as ifd:
+ with codecs.open(outputf, 'rb', encoding='utf-8') as ofd:
+ self.run_auto_test(ifd.read(), ofd.read())
+ return runner
+
+
+def get_file_path(dir_name, file_name):
+ return realpath(join(dirname(__file__), 'files', dir_name, file_name))
+
+class TestCommand(Command):
+ user_options = []
+
+ def initialize_options(self):
+ self._dir = os.getcwd()
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ '''
+ Finds all the tests modules in tests/, and runs them.
+ '''
+ testfiles = []
+ for t in glob(join(self._dir, 'tests', '*.py')):
+ module_name = splitext(basename(t))[0]
+ if module_name.startswith('test'):
+ testfiles.append('.'.join(['tests', module_name])
+ )
+
+ tests = TestLoader().loadTestsFromNames(testfiles)
+ t = TextTestRunner(verbosity=2)
+ t.run(tests)
+