Update docstring with api keyword and ospworks url
[o_s.git] / spices.py
blob3c753ffe6f79ca088591f8c570f9953abe225082
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 """
5 A possible use of the odfpy api for the `Openbaar Schrijver' book.
6 Written by Open Source Publishing.
8 http://ospublish.constantvzw.org/works/valentine-scripting
9 http://ospublish.constantvzw.org/works/index.php?/project/publication-templates---openbaar-schrijver/
10 """
12 # vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
14 try:
15 from odf.opendocument import OpenDocumentText
16 from odf.text import P, Span
17 from odf.style import Style, TextProperties, ParagraphProperties
18 from odf.style import BackgroundImage, GraphicProperties
19 except ImportError:
20 raise
22 import texts
23 import stylesheet
24 from liblove import *
26 class Spice:
27 """Contains the common methods needed to generate an ODT corresponding to
28 a genre/style/spice combination. Its character, dingbat and image
29 subclasses add the spice-specific methods.
31 This class instantiates the OpenDocumentText class at the end of nested
32 loops that look like:
34 for genre in ["brief", "verhaal", "gedicht"]:
35 for style in genre.styles:
36 for spice in spice_list:
37 myodt = OpenDocumentText()
39 The spice_list is specific to each subclass.
41 """
42 def __init__(self, genre, style):
43 self.genre = genre
44 self.style = style
46 def read_stylesheet(self):
47 """Fetches the styles specified by the designer in a CSS-ish
48 stylesheet and returns a Style instance for use in an ODT document.
50 """
51 stylesheet.text_template[self.genre].update(\
52 stylesheet.text_style[self.genre][self.style])
53 stylesheet.paragraph_template[self.genre].update(\
54 stylesheet.paragraph_style[self.genre][self.style])
55 # this paragraph vs text distinction in odf, argh...
56 oostyle = Style(name="Body Text", family="paragraph")
57 oostyle.addElement(TextProperties(\
58 attributes=stylesheet.text_template[self.genre]))
59 oostyle.addElement(ParagraphProperties(\
60 attributes=stylesheet.paragraph_template[self.genre]))
61 return oostyle
63 def text_frame(self, odt):
64 """Produces the main body of text of the ODT's."""
66 ### header frame (for letter)
67 if self.genre == "brief":
68 header(odt)
70 ### textframe
71 graphic_style = Style(name="Main Body Frame", family="graphic")
72 graphic_properties = GraphicProperties(backgroundcolor="#ffffff", \
73 border="10mm double #ffffff")
74 graphic_style.addElement(graphic_properties)
75 frame = make_frame(odt, graphic_style, "240mm", "170mm", "0mm", "0mm", "1")
76 frameframe = frame["frame"]
77 textbox = frame["textbox"]
79 for paragraph in texts.txt[self.genre]:
80 kinda_p("Body Text", paragraph, textbox)
82 odt.text.addElement(frameframe)
84 def label(self, odt, spice):
85 """Places a text label in an ODT that identifies it by style and
86 spice.
88 """
89 ## graphic
90 graphic_style = Style(name="Label Frame", family="graphic")
91 graphic_properties = GraphicProperties()
92 graphic_style.addElement(graphic_properties)
93 frame = make_frame(odt, graphic_style, "5mm", "50mm", "60mm", "263mm", "1")
94 frameframe = frame["frame"]
95 textbox = frame["textbox"]
97 ## paragraphic
98 paragraphic_style = Style(name="Label Text", family="paragraph")
99 text_props = TextProperties(fontsize="11.1pt", \
100 fontfamily="Nimbus Sans L", color="#ffffff")
101 paragraphic_style.addElement(text_props)
102 paragraph_props = ParagraphProperties(backgroundcolor="#000000", \
103 textalign="center")
104 paragraphic_style.addElement(paragraph_props)
105 odt.styles.addElement(paragraphic_style)
106 kinda_p(paragraphic_style, spice + " " + self.style, textbox)
108 odt.text.addElement(frameframe)
110 class Character(Spice):
111 """These methods are used to generate ODT's where certain words are
112 highlighted. The style of highlighting depends on the spice.
116 spices = ["sexy", "champagne", "lungo"]
117 words = [u"aai", u"aan", u"alleen", u"beloofde", u"bemind", u"benen", u"bewust", u"borst", u"eenzaam", u"elkaar", u"geloofde", u"gesmoord", u"gevoel", u"gezicht", u"giechelend", u"glimlachte", u"haar", u"hand", u"haren", u"hem", u"hen", u"herinner", u"herinneren", u"herinneringen", u"hier", u"hij", u"hoofd", u"hoop", u"huilen", u"ik", u"ja", u"je", u"jij", u"jou", u"jouw", u"kiezen", u"kleurde", u"leven", u"liefde", u"liefdes", u"liefs", u"liefste", u"lieve", u"lippen", u"man", u"me", u"mijn", u"moed", u"moeilijk", u"ogen", u"ons", u"ontmoeting", u"onze", u"opnieuw", u"rituelen", u"roos", u"routine", u"ruggen", u"samen", u"smoorverliefd", u"spijt", u"stotterde", u"streelde", u"tenen", u"troost", u"vergat", u"vergeet", u"vergeten", u"voorzichtig", u"vriend", u"vrienden", u"vrijheid", u"vrouw", u"we", u"wij", u"wil", u"wilde", u"wilden", u"willen", u"ze", u"zelf", u"zij", u"zijn", u"zinnen"]
119 # leaving it here because it was built for this spice
120 def kinda_p4char_spice(self, paragraphic_style, boldstyle, text, textbox):
121 """Special version of this method from liblove for Character spice class."""
122 sectioned = text.split()
123 p = P(text=u"", stylename=paragraphic_style)
124 try:
125 sectioned[-1]
126 for i in range(len(sectioned)-1):
127 if sectioned[i].lower() in self.words:
128 boldpart = Span(stylename=boldstyle, text=sectioned[i] + u" ")
129 p.addElement(boldpart)
130 else:
131 normalpart = Span(text=sectioned[i] + u" ")
132 p.addElement(normalpart)
133 p.addText(sectioned[-1])
134 except IndexError:
135 p.addText(u"")
136 textbox.addElement(p)
138 def character_text_frame(self, odt, spice):
139 """Used instead of the generic `text_frame' method from Spice class."""
140 if spice == "sexy":
141 boldstyle = Style(name=spice + "Bold", family="text")
142 boldprop = TextProperties(fontfamily="diluvienne", fontsize="28pt")
143 boldstyle.addElement(boldprop)
144 odt.automaticstyles.addElement(boldstyle)
145 elif spice == "champagne":
146 boldstyle = Style(name=spice + "Bold", family="text")
147 boldprop = TextProperties(fontfamily="Cimatics_Trash")
148 boldstyle.addElement(boldprop)
149 odt.automaticstyles.addElement(boldstyle)
150 else:
151 boldstyle = Style(name=spice + "Bold", family="text")
152 boldprop = TextProperties(fontweight="bold", \
153 fontfamily="NotCourierSans", letterspacing="2mm")
154 boldstyle.addElement(boldprop)
155 odt.automaticstyles.addElement(boldstyle)
157 ### header frame (for letter)
158 if self.genre == "brief":
159 header(odt)
161 ### textframe
162 graphic_style = Style(name="Main Body Frame", family="graphic")
163 graphic_properties = GraphicProperties(backgroundcolor="#ffffff", \
164 border="10mm double #ffffff")
165 graphic_style.addElement(graphic_properties)
166 frame = make_frame(odt, graphic_style, "240mm", "170mm", "0mm", "0mm", "1")
167 frameframe = frame["frame"]
168 textbox = frame["textbox"]
170 for paragraph in texts.txt[self.genre]:
171 self.kinda_p4char_spice("Body Text", boldstyle, paragraph, textbox)
173 odt.text.addElement(frameframe)
175 def loop_over_spices(self):
176 """Iterates over ["sexy", "champagne", "lungo"] and produces 1 ODT
177 per cycle.
179 The names of the ODT's depend on the iteration, as well as the genre
180 and style attributes specified in the current instance.
182 These are the main loops of the Spice subclasses.
185 for myspice in self.spices:
187 myodt = OpenDocumentText()
189 genredotstyle = self.read_stylesheet()
190 myodt.styles.addElement(genredotstyle)
191 frame_border(myodt)
193 self.character_text_frame(myodt, myspice)
196 self.label(myodt, myspice)
198 myname = self.genre + "/" + self.style + "/character/" +\
199 self.genre + "_" + self.style + "_" + myspice
200 myodt.save(myname, True)
202 class Dingbat(Spice):
203 """These methods are used to generate ODT's with a column of dingbats on
204 the left. The collection of dingbats that's used depends on the spice.
207 dingbats = {"kristallen" : [u"✭", u"✮", u"✯", u"✰", u"✱", u"✲", u"✳", u"✴", u"✭", u"✮", u"✯", u"✰", u"✱", u"✲", u"✳", u"✴", u"✭", u"✮", u"✯", u"✰", u"✱", u"✲", u"✳", u"✴", u"✭", u"✮", u"✯", u"✰", u"✱", u"✲", u"✳", u"✴",u"✭", u"✮", u"✯", u"✰", u"✱", u"✲", u"✳", u"✴", u"✭", u"✮", u"✯", u"✰", u"✱", u"✲", u"✳", u"✴", u"✭", u"✮", u"✯", u"✰", u"✱", u"✲", u"✳", u"✴", u"✭", u"✮", u"✯", u"✰", u"✱", u"✲", u"✳", u"✴"],
208 "roze" : [u"✿", u"❀", u"✿", u"❀", u"❁", u"✼", u" ", u"✿", u"❀",u"✿", u"❀", u"❁", u"✼", u" ", u"✿", u"❀", u"✿", u"❀", u"❁", u"✼", u" ", u"✿", u"❀",u"✿", u"❀", u"❁", u"✼", u" ", u"✿", u"❀", u"✿", u"❀", u"❁", u"✼", u" ", u"✿", u"❀",u"✿", u"❀", u"❁", u"✼"],
209 "lavendel" : [u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍",u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍",u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍",u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍", u"҈", u"❍"]
212 def dingbat_column(self, odt, spice):
213 """Generates the vertical dingbat strip on the left of the ODT's."""
215 ## graphic
216 graphic_style = Style(name="Dingbat Frame", family="graphic")
217 graphic_properties = GraphicProperties()
218 graphic_style.addElement(graphic_properties)
219 frame = make_frame(odt, graphic_style, "240mm", "10mm", "0mm", "0mm", "100")
220 frameframe = frame["frame"]
221 textbox = frame["textbox"]
223 ## paragraphic
224 paragraphic_style = Style(name="Dingbats", family="paragraph")
225 text_props = TextProperties(fontsize="14pt", fontfamily="FreeSerif")
226 paragraphic_style.addElement(text_props)
227 paragraph_props = ParagraphProperties()
228 paragraphic_style.addElement(paragraph_props)
229 odt.styles.addElement(paragraphic_style)
231 for i in self.dingbats[spice]:
232 kinda_p(paragraphic_style, i, textbox)
234 odt.text.addElement(frameframe)
236 def loop_over_spices(self):
237 """Iterates over ["kristallen", "roze", "lavendel"] and produces 1 ODT
238 per cycle.
240 The names of the ODT's depend on the iteration, as well as the genre
241 and style attributes specified in the current instance.
243 These are the main loops of the Spice subclasses.
246 spices = self.dingbats.keys()
247 for myspice in spices:
248 myodt = OpenDocumentText()
250 genredotstyle = self.read_stylesheet()
251 myodt.styles.addElement(genredotstyle)
252 frame_border(myodt)
254 self.text_frame(myodt)
255 self.dingbat_column(myodt, myspice)
257 self.label(myodt, myspice)
259 myname = self.genre + "/" + self.style + "/dingbat/" +\
260 self.genre + "_" + self.style + "_" + myspice
261 myodt.save(myname, True)
263 class ImageSpice(Spice):
264 """Generates ODT's with a background image. The image and its positioning
265 depend on the spice.
269 # leaving this method here because it was built for this spice
270 def image_spices(self, odt, spice):
271 """Places the background image in the ODT's."""
273 ## graphic
274 graphic_style = Style(name="Border Frame", family="graphic")
275 href = odt.addPicture(spice + ".jpg")
276 if spice == "chocolade":
277 backgroundimage = BackgroundImage(href=href, \
278 position="top left", repeat="no")
279 elif spice == "koraal":
280 backgroundimage = BackgroundImage(href=href, \
281 position="bottom right", repeat="no")
282 elif spice == "expresso":
283 backgroundimage = BackgroundImage(href=href, \
284 position="top left", repeat="repeat")
285 graphic_properties = GraphicProperties(border="0.5mm double #000000")
286 graphic_properties.addElement(backgroundimage)
287 graphic_style.addElement(graphic_properties)
288 frame = make_frame(odt, graphic_style, "273mm", "194mm", "-12mm", \
289 "-12mm", "1")
290 frameframe = frame["frame"]
291 textbox = frame["textbox"]
293 ## paragraphic
294 paragraphic_style = Style(name="Frame Border is Empty", family="paragraph")
295 text_props = TextProperties()
296 paragraphic_style.addElement(text_props)
297 paragraph_props = ParagraphProperties()
298 paragraphic_style.addElement(paragraph_props)
299 odt.styles.addElement(paragraphic_style)
301 kinda_p(paragraphic_style, u"", textbox)
303 odt.text.addElement(frameframe)
305 def loop_over_spices(self):
306 """Iterates over ["chocolade", "koraal", "expresso"] and produces 1
307 ODT per cycle.
309 The names of the ODT's depend on the iteration, as well as the genre
310 and style attributes specified in the current instance.
312 These are the main loops of the Spice subclasses.
315 for myspice in ["chocolade", "koraal", "expresso"]:
316 myodt = OpenDocumentText()
318 genredotstyle = self.read_stylesheet()
319 myodt.styles.addElement(genredotstyle)
320 self.image_spices(myodt, myspice)
322 self.text_frame(myodt)
325 self.label(myodt, myspice)
327 myname = self.genre + "/" + self.style + "/image/" +\
328 self.genre + "_" + self.style + "_" + myspice
329 myodt.save(myname, True)