2013-05-29 00:31:09 +03:00
|
|
|
import os
|
|
|
|
import os.path
|
|
|
|
import sys
|
2013-05-28 00:33:36 +03:00
|
|
|
|
|
|
|
class OutputFormat (object):
|
2013-06-04 01:22:54 +03:00
|
|
|
"Handles book output. Big FIXME required to make sense."
|
|
|
|
def __init__(self, templates):
|
2013-06-03 23:19:06 +03:00
|
|
|
self.templates = templates
|
2013-05-28 00:33:36 +03:00
|
|
|
|
|
|
|
def write_begin(self, book, output):
|
2013-06-04 23:32:03 +03:00
|
|
|
print >> output, self.format_with_template("begin", {
|
2013-05-29 00:31:09 +03:00
|
|
|
'max' : book.max
|
2013-06-04 23:32:03 +03:00
|
|
|
}),
|
2013-05-28 00:33:36 +03:00
|
|
|
|
2013-06-03 22:57:55 +03:00
|
|
|
def write_shuffled_sections(self, shuffled_sections, output):
|
2013-06-04 23:32:03 +03:00
|
|
|
for i, p in enumerate(shuffled_sections.as_list):
|
2013-06-04 00:45:31 +03:00
|
|
|
if p:
|
|
|
|
self.write_section(p, shuffled_sections, output)
|
2013-06-04 23:32:03 +03:00
|
|
|
elif i > 0:
|
|
|
|
self.write_empty_section(i, output)
|
2013-05-28 00:33:36 +03:00
|
|
|
|
2013-06-03 22:57:55 +03:00
|
|
|
def write_section(self, section, shuffled_sections, output):
|
2013-05-29 01:00:30 +03:00
|
|
|
refs = []
|
2013-06-03 22:57:55 +03:00
|
|
|
refsdict = ReferenceFormatter(section, shuffled_sections,
|
2013-06-04 23:32:03 +03:00
|
|
|
self.format_with_template("section_ref"))
|
2013-06-07 01:14:06 +03:00
|
|
|
formatted_text = self.format_section(section, refsdict)
|
2013-06-04 23:32:03 +03:00
|
|
|
print >> output, self.format_with_template("section", {
|
2013-06-03 22:57:55 +03:00
|
|
|
'nr' : shuffled_sections.to_nr[section],
|
2013-06-04 23:32:03 +03:00
|
|
|
'name' : section.name,
|
2013-05-29 01:00:30 +03:00
|
|
|
'text' : formatted_text,
|
2013-05-30 01:18:05 +03:00
|
|
|
'refs' : '\n'.join(refsdict.getfound()) # hack for DOT output
|
2013-06-04 23:32:03 +03:00
|
|
|
}),
|
|
|
|
|
2013-06-07 01:14:06 +03:00
|
|
|
def format_section(self, section, references):
|
|
|
|
i = 0
|
|
|
|
res = ""
|
2013-06-10 22:21:13 +03:00
|
|
|
# FIXME refactor for readability once good tests are in place
|
2013-06-07 01:14:06 +03:00
|
|
|
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()
|
2013-06-09 01:55:24 +03:00
|
|
|
tagparts = tag.split()
|
|
|
|
tagname = tagparts[0]
|
2013-06-07 01:14:06 +03:00
|
|
|
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
|
2013-06-09 01:55:24 +03:00
|
|
|
for i, arg in enumerate(tagparts[1:]):
|
|
|
|
references['arg%d' % (i+1)] = arg
|
|
|
|
f = self.format_with_template(tagname,
|
|
|
|
references)
|
2013-06-07 01:14:06 +03:00
|
|
|
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
|
|
|
|
|
2013-06-04 23:32:03 +03:00
|
|
|
def write_empty_section(self, nr, output):
|
|
|
|
print >> output, self.format_with_template("empty_section", {
|
|
|
|
'nr' : nr,
|
|
|
|
}),
|
2013-05-28 00:33:36 +03:00
|
|
|
|
|
|
|
def write_end(self, book, output):
|
2013-06-04 23:32:03 +03:00
|
|
|
print >> output, self.format_with_template("end"),
|
2013-05-28 00:33:36 +03:00
|
|
|
|
2013-06-04 23:32:03 +03:00
|
|
|
def format_with_template(self, name, values=None):
|
|
|
|
template = self.templates.get(name)
|
|
|
|
if values:
|
|
|
|
return template % values
|
|
|
|
else:
|
|
|
|
return template
|
2013-05-29 00:31:09 +03:00
|
|
|
|
2013-05-30 01:18:05 +03:00
|
|
|
class ReferenceFormatter (object):
|
|
|
|
"There is probably a better way, but this hack seems to work."
|
2013-06-03 22:57:55 +03:00
|
|
|
def __init__(self, section, shuffled_sections, ref_template):
|
|
|
|
self.section = section
|
|
|
|
self.shuffled_sections = shuffled_sections
|
2013-05-30 01:18:05 +03:00
|
|
|
self.found = set()
|
|
|
|
self.ref_template = ref_template
|
2013-06-07 22:41:52 +03:00
|
|
|
self.items = {'nr' : shuffled_sections.to_nr[section]}
|
2013-05-30 01:18:05 +03:00
|
|
|
|
|
|
|
def __getitem__(self, key):
|
2013-06-07 01:14:06 +03:00
|
|
|
if key in self.items:
|
|
|
|
return self.items[key]
|
2013-06-03 22:57:55 +03:00
|
|
|
to_section = self.shuffled_sections.from_name[key]
|
2013-05-30 01:18:05 +03:00
|
|
|
res = self.ref_template % {
|
2013-06-03 22:57:55 +03:00
|
|
|
'nr' : self.shuffled_sections.to_nr[to_section],
|
|
|
|
'from_nr' : self.shuffled_sections.to_nr[self.section]
|
2013-05-30 01:18:05 +03:00
|
|
|
}
|
2013-06-03 22:57:55 +03:00
|
|
|
if key in self.shuffled_sections.name_to_nr:
|
2013-05-30 01:18:05 +03:00
|
|
|
self.found.add(res)
|
|
|
|
return res
|
|
|
|
|
|
|
|
def getfound(self):
|
|
|
|
return list(self.found)
|
2013-06-07 01:14:06 +03:00
|
|
|
|
|
|
|
def __setitem__(self, key, value):
|
|
|
|
self.items[key] = value
|
|
|
|
|
|
|
|
def __delitem__(self, key):
|
|
|
|
del self.items[key]
|