1 ## This file is part of Crapvine.
3 ## Copyright (C) 2007 Andrew Sayman <lorien420@myrealbox.com>
5 ## Crapvine is free software; you can redistribute it and/or modify
6 ## it under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or
8 ## (at your option) any later version.
10 ## Crapvine is distributed in the hope that it will be useful,
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ## GNU General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with this program. If not, see <http://www.gnu.org/licenses/>.
18 from __future__
import with_statement
20 class Keyword(object):
27 class Template(object):
28 def __init__(self
, template_filepath
, character
, output_filepath
, progress
= None):
29 self
.character
= character
30 self
.template_filepath
= template_filepath
31 self
.output_filepath
= output_filepath
32 self
.__progress
= progress
34 def get_keywords(self
, out_str
):
37 for i
in range(len(out_str
)):
41 cur_key
.text
= "%s" % (out_str
[cur_key
.begin
+ 1:cur_key
.end
])
42 keywords
.append(cur_key
)
52 # Map of output name to traitlist name
54 'physicalneg' : 'negative physical',
55 'socialneg' : 'negative social',
56 'mentalneg' : 'negative mental',
57 'healthlevels' : 'health levels'
60 def translate_iterable_name(self
, name
):
61 if self
.iterable_map
.has_key(name
):
62 return self
.iterable_map
[name
]
65 # Map of output name to attribute name
67 'playstatus' : 'status'
70 def translate_attribute_name(self
, name
):
71 if self
.attribute_map
.has_key(name
):
72 return self
.attribute_map
[name
]
75 def __get_named_traitlist(self
, traitlist_name
):
76 for tl
in self
.character
.traitlists
:
77 if tl
.name
.lower() == traitlist_name
:
81 def __start_progress(self
, total_passes
, text
=None):
83 self
.__progress
.set_pulse_step(100.0 / float(total_passes
) / 100.0)
84 self
.__progress
.show_now()
88 my_out
= ". %s" % (text
)
89 print "Processing %s%s" % (self
.character
.name
, my_out
)
90 self
.__total
_passes
= total_passes
91 self
.__current
_pass
= 0
92 def __increment_progress(self
, text
=None):
95 self
.__progress
.set_text(text
)
96 self
.__progress
.pulse()
98 self
.__current
_pass
+= 1
101 my_out
= ". %s" % (text
)
102 print "%d%% complete%s" % ((100.0 / self
.__total
_passes
) * self
.__current
_pass
, my_out
)
103 def save(self
, progress
=None):
104 self
.__start
_progress
(8, "Reading file %s" % (self
.template_filepath
))
106 with
open(self
.template_filepath
) as f
:
108 self
.__increment
_progress
('Processing repeats')
110 out_str
= "%s" % (in_str
)
112 # Parse repeat keyword
113 keywords
= self
.get_keywords(out_str
)
117 for i
in range(len(keywords
)):
118 if keywords
[i
].text
== '/repeat':
119 assert cur_repeat
== None
120 #print 'Found repeat'
121 cur_repeat
= Keyword()
122 cur_repeat
.end
= keywords
[i
].end
123 elif keywords
[i
].text
== 'repeat':
124 assert cur_repeat
!= None
126 cur_repeat
.begin
= keywords
[i
].begin
127 cur_repeat
.text
= "%s" % (out_str
[cur_repeat
.begin
+8:cur_repeat
.end
-8])
128 repeat_blocks
.append(cur_repeat
)
131 for repeat_block
in repeat_blocks
:
132 out_str
= self
.__expandinate
_repeat
_block
(repeat_block
, out_str
)
133 self
.__increment
_progress
('Processing attributes')
136 keywords
= self
.get_keywords(out_str
)
138 for keyword
in keywords
:
139 tokens
= keyword
.text
.split(' ')
141 rep_str
= self
.character
[self
.translate_attribute_name(tokens
[0].lower())]
142 out_str
= "%s%s%s" % (out_str
[:keyword
.begin
], rep_str
, out_str
[keyword
.end
+1:])
143 except AttributeError:
144 # It's either incorrect or a language keyword
146 self
.__increment
_progress
('Processing traitlist counts')
148 # Parse iterable counts
149 keywords
= self
.get_keywords(out_str
)
151 for keyword
in keywords
:
152 tokens
= keyword
.text
.lower().split(' ')
153 if tokens
[0].find('#') == 0:
154 tl_name
= self
.translate_iterable_name(tokens
[0][1:])
155 tl
= self
.__get
_named
_traitlist
(tl_name
)
158 rep_str
= "%d" % (tl
.get_display_total())
159 out_str
= "%s%s%s" % (out_str
[:keyword
.begin
], rep_str
, out_str
[keyword
.end
+1:])
160 self
.__increment
_progress
('Processing tallies')
162 # Parse tally keyword
166 keywords
= self
.get_keywords(out_str
)
168 for keyword
in keywords
:
169 tokens
= keyword
.text
.split(' ')
170 if tokens
[0].lower() == 'tally':
173 #print "%s" % (tokens[1].lower())
174 tally_val
= self
.character
[tokens
[1].lower()]
175 rep_str
= "%s" % (dot
* int(round(float(tally_val
))))
176 out_str
= "%s%s%s" % (out_str
[:keyword
.begin
], rep_str
, out_str
[keyword
.end
+1:])
177 except AttributeError:
179 elif len(tokens
) == 3:
181 prm_val
= int(round(float(self
.character
[tokens
[1].lower()])))
182 tmp_val
= int(round(float(self
.character
[tokens
[2].lower()])))
184 if prm_val
== tmp_val
:
185 rep_str
= "%s" % (dot
* prm_val
)
186 elif prm_val
> tmp_val
:
187 tmp_dots
= prm_val
- tmp_val
188 prm_dots
= prm_val
- tmp_dots
189 rep_str
= "%s%s" % (dot
* prm_dots
, emptydot
* tmp_dots
)
190 elif prm_val
< tmp_val
:
191 tmp_dots
= tmp_val
- prm_val
192 rep_str
= "%s%s" % (dot
* prm_val
, tempdot
* tmp_dots
)
193 out_str
= "%s%s%s" % (out_str
[:keyword
.begin
], rep_str
, out_str
[keyword
.end
+1:])
194 except AttributeError:
196 self
.__increment
_progress
('Processing tabs')
199 keywords
= self
.get_keywords(out_str
)
201 for keyword
in keywords
:
202 tokens
= keyword
.text
.split(' ')
203 if tokens
[0].lower() == 'tab':
205 out_str
= "%s%s%s" % (out_str
[:keyword
.begin
], rep_str
, out_str
[keyword
.end
+1:])
206 self
.__increment
_progress
('Formatting columns')
209 lines
= out_str
.split("\n")
212 keywords
= self
.get_keywords(line
)
216 for keyword
in keywords
:
217 tokens
= keyword
.text
.split(' ')
218 if tokens
[0].lower() == 'col':
219 width
= int(tokens
[1])
221 #newline_index = out_str.rfind("\n", 0, keyword.begin)
223 #print out_str[keyword.end+1:keyword.end+30]
224 #justified_str = line[:keyword.begin].rstrip().ljust(width, ' ')
225 #print "Len: %d\n|%s|" % (len(justified_str), justified_str)
226 line
= "%s%s" % (line
[:keyword
.begin
- gathered_offset
], line
[keyword
.end
+1 - gathered_offset
:])
227 replaces
.append((width
, keyword
.begin
- gathered_offset
))
228 gathered_offset
+= len(keyword
.text
) + 2
229 #if len(replaces) > 0:
230 #print "Beginning replace for:\n%s" % (line)
234 begin
= rep
[1] + gathered_offset
235 #print "Chunk: |%s|" % (line[:begin])
236 old_len
= len(line
[:begin
])
237 justified_str
= line
[:begin
].rstrip().ljust(width
, ' ')
238 gathered_offset
+= len(justified_str
) - old_len
239 line
= "%s%s" % (justified_str
, line
[begin
:])
240 out_lines
.append(line
)
242 out_str
= "\n".join(out_lines
)
243 self
.__increment
_progress
("Writing file %s" % (self
.output_filepath
))
245 with
open(self
.output_filepath
, 'w') as f
:
247 self
.__increment
_progress
()
249 def __expandinate_repeat_block(self
, repeat_block
, out_str
):
250 pre_string
= out_str
[:repeat_block
.begin
]
251 post_string
= out_str
[repeat_block
.end
+1:]
252 # Find all of the trait categories we need
255 keywords
= self
.get_keywords(repeat_block
.text
)
257 tl
= self
.__get
_named
_traitlist
(self
.translate_iterable_name(k
.text
.lower()))
259 #print tl.name.lower()
260 traitlists
[tl
.name
.lower()] = tl
261 traitlist_iters
[tl
.name
.lower()] = tl
.get_iter_first()
263 if len(traitlists
) == 0:
264 return "%s%s" % (pre_string
, post_string
)
266 # Begin replacination von fuquon
270 l_str
= "%s" % (repeat_block
.text
)
271 #print "l_str at start\n%s" % (l_str)
272 keywords
= self
.get_keywords(l_str
)
276 tokens
= k
.text
.lower().split(' ')
279 if tokens
[0].find('+') == 0:
281 tl_name
= tokens
[0][1:]
283 tl_name
= self
.translate_iterable_name(tl_name
)
284 if traitlist_iters
.has_key(tl_name
):
285 tl
= traitlists
[tl_name
]
290 iter = traitlist_iters
[tl_name
]
291 if mod
== '+' and iter:
292 iter = tl
.iter_next(iter)
293 traitlist_iters
[tl_name
] = iter
295 trait
= tl
.get_item_from_path(tl
.get_path(iter))
296 rep_str
= "%s" % (trait
.display_str(display
))
297 replaces
.append((k
.begin
, rep_str
, k
.end
+1))
298 #l_str = "%s%s%s" % (l_str[:k.begin], rep_str, l_str[k.end+1:])
299 #print "l_str on keyword %s with %s\n%s" % (k.text.lower(), rep_str, l_str)
300 to_increment
[tl_name
] = True
302 replaces
.append((k
.begin
, '', k
.end
+1))
303 #l_str = "%s%s" % (l_str[:k.begin], l_str[k.end+1:])
306 l_str
= "%s%s%s" % (l_str
[:rep
[0]], rep
[1], l_str
[rep
[2]:])
308 for n
in to_increment
.keys():
309 iter = traitlist_iters
[n
]
312 traitlist_iters
[n
] = tl
.iter_next(iter)
315 #print "Num none: %d | to_increment: %d" % (num_none, len(to_increment))
316 if num_none
== len(to_increment
):
319 imprints
.append(l_str
)
320 imprint_str
= ''.join(imprints
)
321 return "%s%s%s" % (pre_string
, imprint_str
, post_string
)
324 def temporary_tally_str(cls
, prm_val
, tmp_val
, dot
='o', emptydot
='/', tempdot
='+', wrap
=0, doubledot
='8', doubleemptydot
='X', doubletempdot
='#'):
325 if prm_val
== tmp_val
:
326 if wrap
== 0 or prm_val
< wrap
:
327 return "%s" % (dot
* prm_val
)
329 num_doubles
= prm_val
/ 2
330 num_singles
= prm_val
% 2
331 return "%s%s" % (doubledot
* num_doubles
, dot
* num_singles
)
332 elif prm_val
> tmp_val
:
333 tmp_dots
= prm_val
- tmp_val
334 prm_dots
= prm_val
- tmp_dots
335 if wrap
== 0 or prm_val
< wrap
:
336 return "%s%s" % (dot
* prm_dots
, emptydot
* tmp_dots
)
338 return "%s%s%s%s" % (
339 doubledot
* (prm_dots
/ 2),
340 doubledot
* (prm_dots
% 2),
341 doubleemptydot
* (tmp_dots
/ 2),
342 doubleemptydot
* (tmp_dots
% 2)
344 elif prm_val
< tmp_val
:
345 tmp_dots
= tmp_val
- prm_val
346 if wrap
== 0 or (prm_val
+ tmp_dots
) < wrap
:
347 return "%s%s" % (dot
* prm_val
, tempdot
* tmp_dots
)
349 return "%s%s%s%s" % (
350 doubledot
* (prm_val
/ 2),
351 doubledot
* (prm_val
% 2),
352 doubletempdot
* (tmp_dots
/ 2),
353 doubletempdot
* (tmp_dots
% 2)