Remove DateValue, drop Py<3.6, fix tests.
[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     orphans = False
52     
53     default_license_description = {
54         "pol": (
55             "Wszystkie zasoby Wolnych Lektur możesz swobodnie wykorzystywać, "
56             "publikować i rozpowszechniać pod warunkiem zachowania warunków "
57             "licencji i zgodnie z Zasadami wykorzystania Wolnych Lektur.\n"
58             "Ten utwór jest w domenie publicznej.\n"
59             "Wszystkie materiały dodatkowe (przypisy, motywy literackie) są "
60             "udostępnione na Licencji Wolnej Sztuki 1.3: "
61             "https://artlibre.org/licence/lal/pl/\n"
62             "Fundacja Nowoczesna Polska zastrzega sobie prawa do wydania "
63             "krytycznego zgodnie z art. Art.99(2) Ustawy o prawach autorskich "
64             "i prawach pokrewnych.\nWykorzystując zasoby z Wolnych Lektur, "
65             "należy pamiętać o zapisach licencji oraz zasadach, które "
66             "spisaliśmy w Zasadach wykorzystania Wolnych Lektur: "
67             "https://wolnelektury.pl/info/zasady-wykorzystania/\nZapoznaj "
68             "się z nimi, zanim udostępnisz dalej nasze książki."
69         )
70     }
71     license_description = {
72         "pol": (
73             #"Ten utwór jest udostępniony na licencji {meta.license_description}: \n{meta.license}",
74             "Wszystkie zasoby Wolnych Lektur możesz swobodnie wykorzystywać, "
75             "publikować i rozpowszechniać pod warunkiem zachowania warunków "
76             "licencji i zgodnie z Zasadami wykorzystania Wolnych Lektur.\n"
77             "Ten utwór jest jest udostępniony na licencji {meta.license_description} ({meta.license}). "
78             "Wszystkie materiały dodatkowe (przypisy, motywy literackie) są "
79             "udostępnione na Licencji Wolnej Sztuki 1.3: "
80             "https://artlibre.org/licence/lal/pl/\n"
81             "Fundacja Nowoczesna Polska zastrzega sobie prawa do wydania "
82             "krytycznego zgodnie z art. Art.99(2) Ustawy o prawach autorskich "
83             "i prawach pokrewnych.\nWykorzystując zasoby z Wolnych Lektur, "
84             "należy pamiętać o zapisach licencji oraz zasadach, które "
85             "spisaliśmy w Zasadach wykorzystania Wolnych Lektur: "
86             "https://wolnelektury.pl/info/zasady-wykorzystania/\nZapoznaj "
87             "się z nimi, zanim udostępnisz dalej nasze książki."
88         )
89     }
90
91     def __init__(self, base_url=None):
92         self.fragments = {
93             None: TxtFragment(),
94             'header': TxtFragment()
95         }
96         self.current_fragments = [self.fragments[None]]
97
98     def enter_fragment(self, fragment):
99         self.current_fragments.append(self.fragments[fragment])
100
101     def exit_fragment(self):
102         self.current_fragments.pop()
103         
104     def push_text(self, text, prepared=False):
105         self.current_fragments[-1].push_text(text, prepared=prepared)
106
107     def push_margin(self, margin):
108         self.current_fragments[-1].push_margin(margin)
109         
110     def push_legacy_margin(self, margin, where=None):
111         self.current_fragments[-1].push_legacy_margin(margin)
112         
113     def build(self, document, raw_text=False, **kwargs):
114         document.tree.getroot().txt_build(self)
115         meta = document.meta
116
117         self.enter_fragment('header')
118         if meta.translators:
119             self.push_text("tłum. ")
120             self.push_text(
121                 ", ".join(
122                     translator.readable()
123                     for translator in meta.translators
124                 )
125             )
126             #builder.push_margin(2)
127             self.push_legacy_margin(1)
128
129         if meta.isbn_txt:
130             #builder.push_margin(2)
131             self.push_legacy_margin(1)
132             isbn = meta.isbn_txt
133             if isbn.startswith(('ISBN-' , 'ISBN ')):
134                 isbn = isbn[5:]
135             self.push_text('ISBN {isbn}'.format(isbn=isbn))
136             #builder.push_margin(5)
137
138         #builder.push_margin(4)
139         self.push_legacy_margin(1)
140         self.exit_fragment()
141         
142         text = ''.join(self.fragments['header'].pieces) +  ''.join(self.fragments[None].pieces)
143
144         if raw_text:
145             result = text
146         else:
147             if meta.license:
148                 license_description = self.license_description['pol'].format(meta=meta)
149             else:
150                 license_description = self.default_license_description['pol']
151
152             if meta.source_name:
153                 source = "\n\nTekst opracowany na podstawie: " + meta.source_name
154             else:
155                 source = ''
156
157             contributors = ', '.join(
158                 person.readable()
159                 for person in sorted(set(
160                     p for p in (
161                         meta.technical_editors + meta.editors
162                     ) if p))
163             )
164             if contributors:
165                 contributors = (
166                     "\n\nOpracowanie redakcyjne i przypisy: %s."
167                     % contributors
168                 )
169
170             funders = ', '.join(meta.funders)
171             if funders:
172                 funders = u"\n\nPublikację wsparli i wsparły: %s." % funders
173
174             isbn = getattr(meta, 'isbn_txt', None)
175             if isbn:
176                 isbn = '\n\n' + isbn
177             else:
178                 isbn = ''
179                 
180             result = TEMPLATE % {
181                 "text": text,
182                 "description": meta.description,
183                 "url": meta.url,
184                 "license_description": license_description,
185                 "source": source,
186                 "contributors": contributors,
187                 "funders": funders,
188                 "publisher":  '\n\nWydawca: ' + ', '.join(meta.publisher),
189                 "isbn": isbn,
190             }
191
192         result = '\r\n'.join(result.splitlines()) + '\r\n'
193         return OutputFile.from_bytes(result.encode('utf-8'))