Support for block annotations. Option to use endnotes in PDF.
[librarian.git] / src / librarian / builders / txt.py
1 # coding: utf-8
2 from __future__ import unicode_literals
3
4 import io
5 from librarian import OutputFile, get_resource
6
7
8 with io.open(get_resource("res/text/template.txt")) as f:
9     TEMPLATE = f.read()
10
11
12 class TxtFragment:
13     def __init__(self):
14         self.pieces = []
15         self.current_margin = 0
16         self.starting_block = True
17
18     def push_legacy_margin(self, margin):
19         if margin:
20             if self.pieces:
21                 self.pieces[-1] = self.pieces[-1].rstrip(' ')
22             self.pieces.append('\r\n' * margin)
23             self.current_margin += margin
24             self.starting_block = True
25         
26     def push_margin(self, margin):
27         if margin:
28             if self.pieces:
29                 self.pieces[-1] = self.pieces[-1].rstrip(' ')
30             if margin > self.current_margin:
31                 self.pieces.append('\r\n' * (margin - self.current_margin))
32                 self.current_margin = margin
33                 self.starting_block = True
34
35     def push_text(self, text, prepared=False):
36         if text:
37             if self.starting_block and not prepared:
38                 text = text.lstrip()
39             self.pieces.append(text)
40             self.current_margin = 0
41             if not prepared:
42                 self.starting_block = False
43
44
45 class TxtBuilder:
46     """
47     """
48     file_extension = "txt"
49     identifier = "txt"
50
51     default_license_description = {
52         "pol": (
53             "Wszystkie zasoby Wolnych Lektur możesz swobodnie wykorzystywać, "
54             "publikować i rozpowszechniać pod warunkiem zachowania warunków "
55             "licencji i zgodnie z Zasadami wykorzystania Wolnych Lektur.\n"
56             "Ten utwór jest w domenie publicznej. "
57             "Wszystkie materiały dodatkowe (przypisy, motywy literackie) są "
58             "udostępnione na Licencji Wolnej Sztuki 1.3 "
59             "(https://artlibre.org/licence/lal/pl/).\n"
60             "Fundacja Nowoczesna Polska zastrzega sobie prawa do wydania "
61             "krytycznego zgodnie z art. Art.99(2) Ustawy o prawach autorskich "
62             "i prawach pokrewnych. Wykorzystując zasoby z Wolnych Lektur, "
63             "należy pamiętać o zapisach licencji oraz zasadach, które "
64             "spisaliśmy w Zasadach wykorzystania Wolnych Lektur "
65             "(https://wolnelektury.pl/info/zasady-wykorzystania/). Zapoznaj "
66             "się z nimi, zanim udostępnisz dalej nasze książki."
67         )
68     }
69     license_description = {
70         "pol": (
71             #"Ten utwór jest udostępniony na licencji {meta.license_description}: \n{meta.license}",
72             "Wszystkie zasoby Wolnych Lektur możesz swobodnie wykorzystywać, "
73             "publikować i rozpowszechniać pod warunkiem zachowania warunków "
74             "licencji i zgodnie z Zasadami wykorzystania Wolnych Lektur.\n"
75             "Ten utwór jest jest udostępniony na licencji {meta.license_description} ({meta.license}). "
76             "Wszystkie materiały dodatkowe (przypisy, motywy literackie) są "
77             "udostępnione na Licencji Wolnej Sztuki 1.3 "
78             "(https://artlibre.org/licence/lal/pl/).\n"
79             "Fundacja Nowoczesna Polska zastrzega sobie prawa do wydania "
80             "krytycznego zgodnie z art. Art.99(2) Ustawy o prawach autorskich "
81             "i prawach pokrewnych. Wykorzystując zasoby z Wolnych Lektur, "
82             "należy pamiętać o zapisach licencji oraz zasadach, które "
83             "spisaliśmy w Zasadach wykorzystania Wolnych Lektur "
84             "(https://wolnelektury.pl/info/zasady-wykorzystania/). Zapoznaj "
85             "się z nimi, zanim udostępnisz dalej nasze książki."
86         )
87     }
88
89     def __init__(self):
90         self.fragments = {
91             None: TxtFragment(),
92             'header': TxtFragment()
93         }
94         self.current_fragments = [self.fragments[None]]
95
96     def enter_fragment(self, fragment):
97         self.current_fragments.append(self.fragments[fragment])
98
99     def exit_fragment(self):
100         self.current_fragments.pop()
101         
102     def push_text(self, text, prepared=False):
103         self.current_fragments[-1].push_text(text, prepared=prepared)
104
105     def push_margin(self, margin):
106         self.current_fragments[-1].push_margin(margin)
107         
108     def push_legacy_margin(self, margin, where=None):
109         self.current_fragments[-1].push_legacy_margin(margin)
110         
111     def build(self, document, raw_text=False, **kwargs):
112         document.tree.getroot().txt_build(self)
113         meta = document.meta
114
115         self.enter_fragment('header')
116         if meta.translators:
117             self.push_text("tłum. ")
118             self.push_text(
119                 ", ".join(
120                     translator.readable()
121                     for translator in meta.translators
122                 )
123             )
124             #builder.push_margin(2)
125             self.push_legacy_margin(1)
126
127         if meta.isbn_txt:
128             #builder.push_margin(2)
129             self.push_legacy_margin(1)
130             isbn = meta.isbn_txt
131             if isbn.startswith(('ISBN-' , 'ISBN ')):
132                 isbn = isbn[5:]
133             self.push_text('ISBN {isbn}'.format(isbn=isbn))
134             #builder.push_margin(5)
135
136         #builder.push_margin(4)
137         self.push_legacy_margin(1)
138         self.exit_fragment()
139         
140         text = ''.join(self.fragments['header'].pieces) +  ''.join(self.fragments[None].pieces)
141
142         if raw_text:
143             result = text
144         else:
145             if meta.license:
146                 license_description = self.license_description['pol'].format(meta=meta)
147             else:
148                 license_description = self.default_license_description['pol']
149
150             if meta.source_name:
151                 source = "\n\nTekst opracowany na podstawie: " + meta.source_name
152             else:
153                 source = ''
154
155             contributors = ', '.join(
156                 person.readable()
157                 for person in sorted(set(
158                     p for p in (
159                         meta.technical_editors + meta.editors
160                     ) if p))
161             )
162             if contributors:
163                 contributors = (
164                     "\n\nOpracowanie redakcyjne i przypisy: %s."
165                     % contributors
166                 )
167
168             funders = ', '.join(meta.funders)
169             if funders:
170                 funders = u"\n\nPublikację wsparli i wsparły: %s." % funders
171
172             isbn = getattr(meta, 'isbn_txt', None)
173             if isbn:
174                 isbn = '\n\n' + isbn
175             else:
176                 isbn = ''
177                 
178             result = TEMPLATE % {
179                 "text": text,
180                 "description": meta.description,
181                 "url": meta.url,
182                 "license_description": license_description,
183                 "source": source,
184                 "contributors": contributors,
185                 "funders": funders,
186                 "publisher":  '\n\nWydawca: ' + ', '.join(meta.publisher),
187                 "isbn": isbn,
188             }
189
190         result = '\r\n'.join(result.splitlines()) + '\r\n'
191         return OutputFile.from_bytes(result.encode('utf-8'))