Basic biblical tools.
[librarian.git] / src / librarian / functions.py
1 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
3 #
4 from lxml import etree
5 import re
6 from ebooklib import epub
7
8 from librarian.dcparser import Person
9 from librarian import get_resource
10
11
12 def _register_function(f):
13     """ Register extension function with lxml """
14     ns = etree.FunctionNamespace('http://wolnelektury.pl/functions')
15     ns[f.__name__] = f
16
17
18 def reg_substitute_entities():
19     entity_substitutions = [
20         ('---', '—'),
21         ('--', '–'),
22         ('...', '…'),
23         (',,', '„'),
24         ('"', '”'),
25     ]
26
27     def substitute_entities(context, text):
28         """XPath extension function converting all entites in passed text."""
29         if isinstance(text, list):
30             text = ''.join(text)
31         for entity, substitutution in entity_substitutions:
32             text = text.replace(entity, substitutution)
33         return text
34
35     _register_function(substitute_entities)
36
37
38 def reg_strip():
39     def strip(context, text):
40         """Remove unneeded whitespace from beginning and end"""
41         if isinstance(text, list):
42             text = ''.join(text)
43         return re.sub(r'\s+', ' ', text).strip()
44     _register_function(strip)
45
46
47 def reg_starts_white():
48     def starts_white(context, text):
49         if isinstance(text, list):
50             text = ''.join(text)
51         if not text:
52             return False
53         return text[0].isspace()
54     _register_function(starts_white)
55
56
57 def reg_ends_white():
58     def ends_white(context, text):
59         if isinstance(text, list):
60             text = ''.join(text)
61         if not text:
62             return False
63         return text[-1].isspace()
64     _register_function(ends_white)
65
66
67 def reg_person_name():
68     def person_name(context, text):
69         """ Converts "Name, Forename" to "Forename Name" """
70         if isinstance(text, list):
71             text = ''.join(text)
72         return Person.from_text(text).readable()
73     _register_function(person_name)
74
75
76 def reg_texcommand():
77     def texcommand(context, text):
78         """Remove non-letters"""
79         if isinstance(text, list):
80             text = ''.join(text)
81         return re.sub(r'[^a-zA-Z]', '', text).strip()
82     _register_function(texcommand)
83
84
85 def lang_code_3to2(text):
86     """Convert 3-letter language code to 2-letter code"""
87     result = ''
88     text = ''.join(text)
89     with open(get_resource('res/ISO-639-2_8859-1.txt'), 'rb') as f:
90         for line in f.read().decode('latin1').split('\n'):
91             codes = line.strip().split('|')
92             if codes[0] == text:
93                 result = codes[2]
94     if result == '':
95         return text
96     else:
97         return result
98
99
100 def mathml_latex(context, trees):
101     from librarian.embeds.mathml import MathML
102     text = MathML(trees[0]).to_latex().data
103     # Remove invisible multiplications, they produce unwanted spaces.
104     text = text.replace('\u2062', '')
105     return text
106
107
108 def reg_mathml_latex():
109     _register_function(mathml_latex)
110
111
112 def reg_mathml_epub(output):
113     from librarian.embeds.mathml import MathML
114
115     def mathml(context, trees):
116         data = MathML(trees[0]).to_latex().to_png().data
117         name = "math%d.png" % mathml.count
118         mathml.count += 1
119         output.add_item(
120             epub.EpubItem(
121                 uid='math%d' % mathml.count,
122                 file_name=name,
123                 media_type='image/png',
124                 content=data
125             )
126         )
127
128         return name
129     mathml.count = 0
130     _register_function(mathml)