2 # -*- coding: utf-8 -*-
5 A possible use of odfpy for the `Openbaar Schrijver' book.
6 Written by Open Source Publishing.
8 http://ospublish.constantvzw.org/works/valentine-scripting
12 from odf
.opendocument
import OpenDocumentText
13 from odf
.text
import P
, Span
14 from odf
.style
import Style
, TextProperties
, ParagraphProperties
15 from odf
.style
import BackgroundImage
, GraphicProperties
24 """Contains the common methods needed to generate an ODT corresponding to
25 a genre/style/spice combination. Its character, dingbat and image
26 subclasses add the spice-specific methods.
28 This class instantiates the OpenDocumentText class at the end of nested
31 for genre in ["brief", "verhaal", "gedicht"]:
32 for style in genre.styles:
33 for spice in spice_list:
34 myodt = OpenDocumentText()
36 The spice_list is specific to each subclass.
39 def __init__(self
, genre
, style
):
43 def read_stylesheet(self
):
44 """Fetches the styles specified by the designer in a CSS-ish
45 stylesheet and returns a Style instance for use in an ODT document.
48 stylesheet
.text_template
[self
.genre
].update(\
49 stylesheet
.text_style
[self
.genre
][self
.style
])
50 stylesheet
.paragraph_template
[self
.genre
].update(\
51 stylesheet
.paragraph_style
[self
.genre
][self
.style
])
52 # this paragraph vs text distinction in odf, argh...
53 oostyle
= Style(name
="Body Text", family
="paragraph")
54 oostyle
.addElement(TextProperties(\
55 attributes
=stylesheet
.text_template
[self
.genre
]))
56 oostyle
.addElement(ParagraphProperties(\
57 attributes
=stylesheet
.paragraph_template
[self
.genre
]))
60 def text_frame(self
, odt
):
61 """Produces the main body of text of the ODT's."""
63 ### header frame (for letter)
64 if self
.genre
== "brief":
68 graphic_style
= Style(name
="Main Body Frame", family
="graphic")
69 graphic_properties
= GraphicProperties(backgroundcolor
="#ffffff", \
70 border
="10mm double #ffffff")
71 graphic_style
.addElement(graphic_properties
)
72 frame
= make_frame(odt
, graphic_style
, "240mm", "170mm", "0mm", "0mm", "1")
73 frameframe
= frame
["frame"]
74 textbox
= frame
["textbox"]
76 for paragraph
in texts
.txt
[self
.genre
]:
77 kinda_p("Body Text", paragraph
, textbox
)
79 odt
.text
.addElement(frameframe
)
81 def label(self
, odt
, spice
):
82 """Places a text label in an ODT that identifies it by style and
87 graphic_style
= Style(name
="Label Frame", family
="graphic")
88 graphic_properties
= GraphicProperties()
89 graphic_style
.addElement(graphic_properties
)
90 frame
= make_frame(odt
, graphic_style
, "5mm", "50mm", "60mm", "263mm", "1")
91 frameframe
= frame
["frame"]
92 textbox
= frame
["textbox"]
95 paragraphic_style
= Style(name
="Label Text", family
="paragraph")
96 text_props
= TextProperties(fontsize
="11.1pt", \
97 fontfamily
="Nimbus Sans L", color
="#ffffff")
98 paragraphic_style
.addElement(text_props
)
99 paragraph_props
= ParagraphProperties(backgroundcolor
="#000000", \
101 paragraphic_style
.addElement(paragraph_props
)
102 odt
.styles
.addElement(paragraphic_style
)
103 kinda_p(paragraphic_style
, spice
+ " " + self
.style
, textbox
)
105 odt
.text
.addElement(frameframe
)
107 class Character(Spice
):
108 """These methods are used to generate ODT's where certain words are
109 highlighted. The style of highlighting depends on the spice.
113 spices
= ["sexy", "champagne", "lungo"]
114 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"]
116 # leaving it here because it was built for this spice
117 def kinda_p4char_spice(self
, paragraphic_style
, boldstyle
, text
, textbox
):
118 """Special version of this method from liblove for Character spice class."""
119 sectioned
= text
.split()
120 p
= P(text
=u
"", stylename
=paragraphic_style
)
123 for i
in range(len(sectioned
)-1):
124 if sectioned
[i
].lower() in self
.words
:
125 boldpart
= Span(stylename
=boldstyle
, text
=sectioned
[i
] + u
" ")
126 p
.addElement(boldpart
)
128 normalpart
= Span(text
=sectioned
[i
] + u
" ")
129 p
.addElement(normalpart
)
130 p
.addText(sectioned
[-1])
133 textbox
.addElement(p
)
135 def character_text_frame(self
, odt
, spice
):
136 """Used instead of the generic `text_frame' method from Spice class."""
138 boldstyle
= Style(name
=spice
+ "Bold", family
="text")
139 boldprop
= TextProperties(fontfamily
="diluvienne", fontsize
="28pt")
140 boldstyle
.addElement(boldprop
)
141 odt
.automaticstyles
.addElement(boldstyle
)
142 elif spice
== "champagne":
143 boldstyle
= Style(name
=spice
+ "Bold", family
="text")
144 boldprop
= TextProperties(fontfamily
="Cimatics_Trash")
145 boldstyle
.addElement(boldprop
)
146 odt
.automaticstyles
.addElement(boldstyle
)
148 boldstyle
= Style(name
=spice
+ "Bold", family
="text")
149 boldprop
= TextProperties(fontweight
="bold", \
150 fontfamily
="NotCourierSans", letterspacing
="2mm")
151 boldstyle
.addElement(boldprop
)
152 odt
.automaticstyles
.addElement(boldstyle
)
154 ### header frame (for letter)
155 if self
.genre
== "brief":
159 graphic_style
= Style(name
="Main Body Frame", family
="graphic")
160 graphic_properties
= GraphicProperties(backgroundcolor
="#ffffff", \
161 border
="10mm double #ffffff")
162 graphic_style
.addElement(graphic_properties
)
163 frame
= make_frame(odt
, graphic_style
, "240mm", "170mm", "0mm", "0mm", "1")
164 frameframe
= frame
["frame"]
165 textbox
= frame
["textbox"]
167 for paragraph
in texts
.txt
[self
.genre
]:
168 self
.kinda_p4char_spice("Body Text", boldstyle
, paragraph
, textbox
)
170 odt
.text
.addElement(frameframe
)
172 def loop_over_spices(self
):
173 """Iterates over ["sexy", "champagne", "lungo"] and produces 1 ODT
176 The names of the ODT's depend on the iteration, as well as the genre
177 and style attributes specified in the current instance.
179 These are the main loops of the Spice subclasses.
182 for myspice
in self
.spices
:
184 myodt
= OpenDocumentText()
186 genredotstyle
= self
.read_stylesheet()
187 myodt
.styles
.addElement(genredotstyle
)
190 self
.character_text_frame(myodt
, myspice
)
193 self
.label(myodt
, myspice
)
195 myname
= self
.genre
+ "/" + self
.style
+ "/character/" +\
196 self
.genre
+ "_" + self
.style
+ "_" + myspice
197 myodt
.save(myname
, True)
199 class Dingbat(Spice
):
200 """These methods are used to generate ODT's with a column of dingbats on
201 the left. The collection of dingbats that's used depends on the spice.
204 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
"✴"],
205 "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
"✼"],
206 "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
"❍"]
209 def dingbat_column(self
, odt
, spice
):
210 """Generates the vertical dingbat strip on the left of the ODT's."""
213 graphic_style
= Style(name
="Dingbat Frame", family
="graphic")
214 graphic_properties
= GraphicProperties()
215 graphic_style
.addElement(graphic_properties
)
216 frame
= make_frame(odt
, graphic_style
, "240mm", "10mm", "0mm", "0mm", "100")
217 frameframe
= frame
["frame"]
218 textbox
= frame
["textbox"]
221 paragraphic_style
= Style(name
="Dingbats", family
="paragraph")
222 text_props
= TextProperties(fontsize
="14pt", fontfamily
="FreeSerif")
223 paragraphic_style
.addElement(text_props
)
224 paragraph_props
= ParagraphProperties()
225 paragraphic_style
.addElement(paragraph_props
)
226 odt
.styles
.addElement(paragraphic_style
)
228 for i
in self
.dingbats
[spice
]:
229 kinda_p(paragraphic_style
, i
, textbox
)
231 odt
.text
.addElement(frameframe
)
233 def loop_over_spices(self
):
234 """Iterates over ["kristallen", "roze", "lavendel"] and produces 1 ODT
237 The names of the ODT's depend on the iteration, as well as the genre
238 and style attributes specified in the current instance.
240 These are the main loops of the Spice subclasses.
243 spices
= self
.dingbats
.keys()
244 for myspice
in spices
:
245 myodt
= OpenDocumentText()
247 genredotstyle
= self
.read_stylesheet()
248 myodt
.styles
.addElement(genredotstyle
)
251 self
.text_frame(myodt
)
252 self
.dingbat_column(myodt
, myspice
)
254 self
.label(myodt
, myspice
)
256 myname
= self
.genre
+ "/" + self
.style
+ "/dingbat/" +\
257 self
.genre
+ "_" + self
.style
+ "_" + myspice
258 myodt
.save(myname
, True)
260 class ImageSpice(Spice
):
261 """Generates ODT's with a background image. The image and its positioning
266 # leaving this method here because it was built for this spice
267 def image_spices(self
, odt
, spice
):
268 """Places the background image in the ODT's."""
271 graphic_style
= Style(name
="Border Frame", family
="graphic")
272 href
= odt
.addPicture(spice
+ ".jpg")
273 if spice
== "chocolade":
274 backgroundimage
= BackgroundImage(href
=href
, \
275 position
="top left", repeat
="no")
276 elif spice
== "koraal":
277 backgroundimage
= BackgroundImage(href
=href
, \
278 position
="bottom right", repeat
="no")
279 elif spice
== "expresso":
280 backgroundimage
= BackgroundImage(href
=href
, \
281 position
="top left", repeat
="repeat")
282 graphic_properties
= GraphicProperties(border
="0.5mm double #000000")
283 graphic_properties
.addElement(backgroundimage
)
284 graphic_style
.addElement(graphic_properties
)
285 frame
= make_frame(odt
, graphic_style
, "273mm", "194mm", "-12mm", \
287 frameframe
= frame
["frame"]
288 textbox
= frame
["textbox"]
291 paragraphic_style
= Style(name
="Frame Border is Empty", family
="paragraph")
292 text_props
= TextProperties()
293 paragraphic_style
.addElement(text_props
)
294 paragraph_props
= ParagraphProperties()
295 paragraphic_style
.addElement(paragraph_props
)
296 odt
.styles
.addElement(paragraphic_style
)
298 kinda_p(paragraphic_style
, u
"", textbox
)
300 odt
.text
.addElement(frameframe
)
302 def loop_over_spices(self
):
303 """Iterates over ["chocolade", "koraal", "expresso"] and produces 1
306 The names of the ODT's depend on the iteration, as well as the genre
307 and style attributes specified in the current instance.
309 These are the main loops of the Spice subclasses.
312 for myspice
in ["chocolade", "koraal", "expresso"]:
313 myodt
= OpenDocumentText()
315 genredotstyle
= self
.read_stylesheet()
316 myodt
.styles
.addElement(genredotstyle
)
317 self
.image_spices(myodt
, myspice
)
319 self
.text_frame(myodt
)
322 self
.label(myodt
, myspice
)
324 myname
= self
.genre
+ "/" + self
.style
+ "/image/" +\
325 self
.genre
+ "_" + self
.style
+ "_" + myspice
326 myodt
.save(myname
, True)