[epub, mobi] Paragraph indentation improvements plus support for initials in chapters
[librarian.git] / scripts / normalize.py
1 # -*- coding: utf-8 -*-
2 #
3 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
5 #
6 from __future__ import with_statement
7
8 import re
9 import sys
10 import os.path
11
12 sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
13
14 from StringIO import StringIO
15 from lxml import etree
16 import librarian
17
18 REPLACEMENTS = (
19     (u'---', u'\u2014'), # mdash
20     (u'--', u'\u2013'),  # ndash
21     (u'...', u'\u2026'), # ldots
22     (u',,', u'\u201E'),  # lower double back-quote
23     (u'"', u'\u201D'),   # upper double quote
24 )
25
26 DIALOG_EXPR = re.compile(r"\s*---\s(.*)")
27
28 def wl_normalize_text(context, text):
29     """XPath extension function converting all entites in passed text."""
30     if isinstance(text, list):
31         text = u''.join(text)
32
33     for code, ucode in REPLACEMENTS:
34         text = text.replace(code, ucode)
35
36     return text
37
38 def wl_fix_dialog(context, data):
39
40     if isinstance(data, list):
41         text = u''.join(data)
42     else:
43         text = data
44
45     m = DIALOG_EXPR.match(text)
46
47     if m is not None:
48         return m.group(1)
49     else:
50         return text
51
52
53 def filter_verse_ends(data):
54     return data.replace('/\n', '<br />')
55
56 ns = etree.FunctionNamespace('http://wolnelektury.pl/functions')
57 ns['normalize-text'] = wl_normalize_text
58 ns['fix-dialog-line'] = wl_fix_dialog
59
60 def normalize_stylesheet():
61     return etree.XSLT(etree.parse(os.path.join(os.path.dirname(librarian.__file__), 'xslt', 'normalize.xslt')))
62
63 if __name__ == '__main__':
64     tran = normalize_stylesheet()
65     input = StringIO( f )
66     doc = trans( etree.parse(input) )
67     print etree.tostring(doc, pretty_print=True, encoding=unicode).encode('utf-8')
68
69     for err in trans.error_log:
70         sys.stderr.write( (u"%s\n" % err).encode('utf-8') )
71