Version 1.2.1.
[librarian.git] / librarian / text.py
1 # -*- coding: utf-8 -*-
2 import os
3 import cStringIO
4 import re
5 import codecs
6
7 from lxml import etree
8
9 from librarian import dcparser
10
11
12 ENTITY_SUBSTITUTIONS = [
13     (u'---', u'—'),
14     (u'--', u'–'),
15     (u'...', u'…'),
16     (u',,', u'„'),
17     (u'"', u'”'),
18 ]
19
20
21 TEMPLATE = u"""\
22 Kodowanie znaków w dokumencie: UTF-8.
23 -----
24 Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl/). Reprodukcja cyfrowa wykonana przez
25 Bibliotekę Narodową z egzemplarza pochodzącego ze zbiorów BN. Ten utwór nie jest chroniony prawem autorskim i znajduje
26 się w domenie publicznej, co oznacza, że możesz go swobodnie wykorzystywać, publikować i rozpowszechniać.
27
28 Wersja lektury w opracowaniu merytorycznym i krytycznym (przypisy i motywy) dostępna jest na stronie %(url)s.
29 -----
30
31
32
33 %(text)s
34 """
35
36
37 def strip(context, text):
38     """Remove unneeded whitespace from beginning and end"""
39     if isinstance(text, list):
40         text = ''.join(text)
41     return re.sub(r'\s+', ' ', text).strip()
42
43
44 def substitute_entities(context, text):
45     """XPath extension function converting all entites in passed text."""
46     if isinstance(text, list):
47         text = ''.join(text)
48     for entity, substitutution in ENTITY_SUBSTITUTIONS:
49         text = text.replace(entity, substitutution)
50     return text
51
52
53 def wrap_words(context, text, wrapping):
54     """XPath extension function automatically wrapping words in passed text"""
55     if isinstance(text, list):
56         text = ''.join(text)
57     if not wrapping:
58         return text
59     
60     words = re.split(r'\s', text)
61     
62     line_length = 0
63     lines = [[]]
64     for word in words:
65         line_length += len(word) + 1
66         if line_length > wrapping:
67             # Max line length was exceeded. We create new line
68             lines.append([])
69             line_length = len(word)
70         lines[-1].append(word)
71     return '\n'.join(' '.join(line) for line in lines)
72
73
74 # Register substitute_entities function with lxml
75 ns = etree.FunctionNamespace('http://wolnelektury.pl/functions')
76 ns['strip'] = strip
77 ns['substitute_entities'] = substitute_entities
78 ns['wrap_words'] = wrap_words
79
80
81 def transform(input_filename, output_filename, **options):
82     """Transforms file input_filename in XML to output_filename in TXT."""
83     # Parse XSLT
84     style_filename = os.path.join(os.path.dirname(__file__), 'book2txt.xslt')
85     style = etree.parse(style_filename)
86
87     if is_file:
88         document = WLDocument.from_file(input, True)
89     else:
90         document = WLDocument.from_string(input, True)
91
92     result = document.transform(style, **options)
93
94     output_file = codecs.open(output_filename, 'wb', encoding='utf-8')
95     output_file.write(TEMPLATE % {
96         'url': dcparser.parse(input_filename).url,
97         'text': unicode(result),
98     })
99