25a4c1fc88eea97a72b7cdfebe178820b6c0206c
[librarian.git] / librarian / fb2.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 import os.path
7 from copy import deepcopy
8 from lxml import etree
9
10 from librarian import functions, OutputFile
11 from .epub import replace_by_verse
12
13
14 functions.reg_substitute_entities()
15 functions.reg_person_name()
16
17
18 def sectionify(tree):
19     """Finds section headers and adds a tree of _section tags."""
20     sections = [
21         'naglowek_czesc',
22         'naglowek_akt', 'naglowek_rozdzial', 'naglowek_scena',
23         'naglowek_podrozdzial']
24     section_level = dict((v, k) for (k, v) in enumerate(sections))
25
26     # We can assume there are just subelements an no text at section level.
27     for level, section_name in reversed(list(enumerate(sections))):
28         for header in tree.findall('//' + section_name):
29             section = header.makeelement("_section")
30             header.addprevious(section)
31             section.append(header)
32             sibling = section.getnext()
33             while (sibling is not None and
34                     section_level.get(sibling.tag, 1000) > level):
35                 section.append(sibling)
36                 sibling = section.getnext()
37
38
39 def transform(wldoc, verbose=False,
40               cover=None, flags=None):
41     """ produces a FB2 file
42
43     cover: a cover.Cover object or True for default
44     flags: less-advertising, working-copy
45     """
46
47     document = deepcopy(wldoc)
48     del wldoc
49
50     if flags:
51         for flag in flags:
52             document.edoc.getroot().set(flag, 'yes')
53
54     document.clean_ed_note()
55     document.clean_ed_note('abstrakt')
56
57     style_filename = os.path.join(os.path.dirname(__file__), 'fb2/fb2.xslt')
58     style = etree.parse(style_filename)
59
60     replace_by_verse(document.edoc)
61     sectionify(document.edoc)
62
63     result = document.transform(style)
64
65     return OutputFile.from_string(unicode(result).encode('utf-8'))
66
67 # vim:et