1
0
Fork 0
mirror of https://github.com/Oreolek/gamebookformat.git synced 2024-05-17 00:18:20 +03:00
gamebookformat/output.py

130 lines
5.1 KiB
Python
Raw Normal View History

import os
import os.path
import sys
class OutputFormat (object):
"Handles book output. Big FIXME required to make sense."
def __init__(self, templates):
self.templates = templates
def write_begin(self, book, output):
print >> output, self.format_with_template("begin", book.config)
def write_shuffled_sections(self, shuffled_sections, output):
for i, p in enumerate(shuffled_sections.as_list):
if p:
self.write_section(p, shuffled_sections, output)
elif i > 0:
self.write_empty_section(i, output)
def write_section(self, section, shuffled_sections, output):
2013-05-29 01:00:30 +03:00
refs = []
refsdict = ReferenceFormatter(section, shuffled_sections,
self.format_with_template("section_ref"))
formatted_text = self.format_section(section, refsdict)
print >> output, self.format_with_template("section", {
'nr' : shuffled_sections.to_nr[section],
'name' : section.name,
2013-05-29 01:00:30 +03:00
'text' : formatted_text,
'refs' : '\n'.join(refsdict.getfound()) # hack for DOT output
}),
def format_section(self, section, references):
i = 0
res = ""
# FIXME refactor for readability once good tests are in place
while i < len(section.text):
ref_start = section.text.find('[[', i)
tag_start = section.text.find('[', i)
if ref_start >= 0 and ref_start <= tag_start:
res += section.text[i:ref_start]
ref_end = section.text.find(']]', ref_start)
if ref_end > ref_start:
ref = section.text[ref_start+2:ref_end]
splitref = ref.split()
if len(splitref) > 1:
for refmod in splitref[:-1]:
res += self.format_with_template(refmod,
references)
res += references[splitref[-1]]
i = ref_end + 2
else:
raise Exception('Mismatched ref start [[ in section %s' %
self.name)
elif tag_start >= 0:
res += section.text[i:tag_start]
tag_end = section.text.find(']', tag_start)
if tag_end < 0:
raise Exception('Mismatched tag start [ in section %s' %
self.name)
tag = section.text[tag_start+1:tag_end].strip()
tagparts = tag.split()
tagname = tagparts[0]
end_tag_start = section.text.find('[', tag_end)
if (not end_tag_start > tag_end
and section.text[end_tag_start].startswith('[/' + tagname
+ ']')):
raise Exception('Bad format %s tag in %s.' % (
tag, self.name))
inner = section.text[tag_end+1:end_tag_start]
# FIXME this pollutes the mutable references object
references['inner'] = inner
for i, arg in enumerate(tagparts[1:]):
references['arg%d' % (i+1)] = arg
f = self.format_with_template(tagname,
references)
if len(f) > 0:
res += f
else:
res += inner
i = section.text.find(']', end_tag_start) + 1
else:
res += section.text[i:]
break
return res
def write_empty_section(self, nr, output):
print >> output, self.format_with_template("empty_section", {
'nr' : nr,
}),
def write_end(self, book, output):
print >> output, self.format_with_template("end"),
def format_with_template(self, name, values=None):
template = self.templates.get(name)
if values:
return template % values
else:
return template
class ReferenceFormatter (object):
"There is probably a better way, but this hack seems to work."
def __init__(self, section, shuffled_sections, ref_template):
self.section = section
self.shuffled_sections = shuffled_sections
self.found = set()
self.ref_template = ref_template
self.items = {'nr' : shuffled_sections.to_nr[section]}
def __getitem__(self, key):
if key in self.items:
return self.items[key]
to_section = self.shuffled_sections.from_name[key]
res = self.ref_template % {
'nr' : self.shuffled_sections.to_nr[to_section],
'from_nr' : self.shuffled_sections.to_nr[self.section]
}
if key in self.shuffled_sections.name_to_nr:
self.found.add(res)
return res
def getfound(self):
return list(self.found)
def __setitem__(self, key, value):
self.items[key] = value
def __delitem__(self, key):
del self.items[key]