6d52b84555b97d5415f0a744989c97f30fd89667
[librarian.git] / librarian / functions.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 lxml import etree
7 import re
8
9 def _register_function(f):
10     """ Register extension function with lxml """
11     ns = etree.FunctionNamespace('http://wolnelektury.pl/functions')
12     ns[f.__name__] = f
13
14
15 def reg_substitute_entities(): 
16     ENTITY_SUBSTITUTIONS = [
17         (u'---', u'—'),
18         (u'--', u'–'),
19         (u'...', u'…'),
20         (u',,', u'„'),
21         (u'"', u'”'),
22     ]
23
24     def substitute_entities(context, text):
25         """XPath extension function converting all entites in passed text."""
26         if isinstance(text, list):
27             text = ''.join(text)
28         for entity, substitutution in ENTITY_SUBSTITUTIONS:
29             text = text.replace(entity, substitutution)
30         return text
31
32     _register_function(substitute_entities)
33
34
35 def reg_strip():
36     def strip(context, text):
37         """Remove unneeded whitespace from beginning and end"""
38         if isinstance(text, list):
39             text = ''.join(text)
40         return re.sub(r'\s+', ' ', text).strip()
41     _register_function(strip)
42
43
44 def reg_wrap_words():
45     def wrap_words(context, text, wrapping):
46         """XPath extension function automatically wrapping words in passed text"""
47         if isinstance(text, list):
48             text = ''.join(text)
49         if not wrapping:
50             return text
51     
52         words = re.split(r'\s', text)
53     
54         line_length = 0
55         lines = [[]]
56         for word in words:
57             line_length += len(word) + 1
58             if line_length > wrapping:
59                 # Max line length was exceeded. We create new line
60                 lines.append([])
61                 line_length = len(word)
62             lines[-1].append(word)
63         return '\n'.join(' '.join(line) for line in lines)
64     _register_function(wrap_words)
65