mirror of
https://github.com/Oreolek/gamebookformat.git
synced 2024-05-20 09:58:18 +03:00
Basic quoting of different output formats.
Need to be improved and also add strict filtering later.
This commit is contained in:
parent
160519e7e5
commit
0c0a3f7afd
|
@ -2,7 +2,18 @@ title = Format
|
||||||
* 1 start
|
* 1 start
|
||||||
This examples tests gamebook formatting, not so much game mechanics or
|
This examples tests gamebook formatting, not so much game mechanics or
|
||||||
references. Currently there is nothing here really.
|
references. Currently there is nothing here really.
|
||||||
|
This section contains some tricky characters to quote,
|
||||||
|
like } and { and " and ' and \.
|
||||||
|
HTML will probably not like <div> or &boom;.
|
||||||
|
If something broke, turn to [[bad]],
|
||||||
|
otherwise turn to [[good]].
|
||||||
|
|
||||||
* dum :dummy:
|
* dum :dummy:
|
||||||
Sections tagged as dummy will not be
|
Sections tagged as dummy will not be
|
||||||
visible in output at all.
|
visible in output at all.
|
||||||
|
|
||||||
|
* good
|
||||||
|
Good!
|
||||||
|
|
||||||
|
* bad
|
||||||
|
Bad.
|
||||||
|
|
|
@ -33,6 +33,7 @@ import os.path
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
import quote
|
||||||
import sections
|
import sections
|
||||||
import templates
|
import templates
|
||||||
import verifygamebook
|
import verifygamebook
|
||||||
|
@ -40,18 +41,19 @@ from output import OutputFormat
|
||||||
|
|
||||||
USAGE = "usage: %prog [options] inputfile(s)... outputfile"
|
USAGE = "usage: %prog [options] inputfile(s)... outputfile"
|
||||||
|
|
||||||
def of(extension, name):
|
def of(extension, name, quote):
|
||||||
return {'extension' : extension,
|
return {'extension' : extension,
|
||||||
'name' : name,
|
'name' : name,
|
||||||
|
'quote' : quote
|
||||||
}
|
}
|
||||||
|
|
||||||
OUTPUT_FORMATS = [
|
OUTPUT_FORMATS = [
|
||||||
of('tex', 'LaTeX'),
|
of('tex', 'LaTeX', quote.latex),
|
||||||
of('rtf', 'Rich Text Format'),
|
of('rtf', 'Rich Text Format', quote.rtf),
|
||||||
of('dot', 'Graphviz section flowchart'),
|
of('dot', 'Graphviz section flowchart', quote.no),
|
||||||
of('html', 'HTML+JS playable in browser'),
|
of('html', 'HTML+JS playable in browser', quote.html),
|
||||||
of('txt', 'Plain text'),
|
of('txt', 'Plain text', quote.no),
|
||||||
of('debug', 'Gamebook Debug Output'),
|
of('debug', 'Gamebook Debug Output', quote.no),
|
||||||
]
|
]
|
||||||
|
|
||||||
def make_supported_formats_list_string():
|
def make_supported_formats_list_string():
|
||||||
|
@ -123,7 +125,8 @@ def make_output(outputfilename, templatedirs):
|
||||||
for of in OUTPUT_FORMATS:
|
for of in OUTPUT_FORMATS:
|
||||||
extension = of['extension']
|
extension = of['extension']
|
||||||
if outputfilename.endswith('.' + extension):
|
if outputfilename.endswith('.' + extension):
|
||||||
return OutputFormat(templates.Templates(templatedirs, extension))
|
return OutputFormat(templates.Templates(templatedirs, extension),
|
||||||
|
of['quote'])
|
||||||
raise Exception("Unsupported or unknown output format for %s."
|
raise Exception("Unsupported or unknown output format for %s."
|
||||||
% outputfilename)
|
% outputfilename)
|
||||||
|
|
||||||
|
|
24
output.py
24
output.py
|
@ -4,10 +4,12 @@ import sys
|
||||||
|
|
||||||
class OutputFormat (object):
|
class OutputFormat (object):
|
||||||
"Handles book output. Big FIXME required to make sense."
|
"Handles book output. Big FIXME required to make sense."
|
||||||
def __init__(self, templates):
|
def __init__(self, templates, quote):
|
||||||
self.templates = templates
|
self.templates = templates
|
||||||
|
self.quote = quote
|
||||||
|
|
||||||
def write_begin(self, book, output):
|
def write_begin(self, book, output):
|
||||||
|
# FIXME make sure book config is properly quoted
|
||||||
print >> output, self.format_with_template("begin", book.config)
|
print >> output, self.format_with_template("begin", book.config)
|
||||||
|
|
||||||
def write_shuffled_sections(self, shuffled_sections, output):
|
def write_shuffled_sections(self, shuffled_sections, output):
|
||||||
|
@ -20,7 +22,8 @@ class OutputFormat (object):
|
||||||
def write_section(self, section, shuffled_sections, output):
|
def write_section(self, section, shuffled_sections, output):
|
||||||
refs = []
|
refs = []
|
||||||
refsdict = ReferenceFormatter(section, shuffled_sections,
|
refsdict = ReferenceFormatter(section, shuffled_sections,
|
||||||
self.format_with_template("section_ref"))
|
self.format_with_template("section_ref"),
|
||||||
|
self.quote)
|
||||||
formatted_text = self.format_section(section, refsdict)
|
formatted_text = self.format_section(section, refsdict)
|
||||||
print >> output, self.format_with_template("section", {
|
print >> output, self.format_with_template("section", {
|
||||||
'nr' : shuffled_sections.to_nr[section],
|
'nr' : shuffled_sections.to_nr[section],
|
||||||
|
@ -37,7 +40,7 @@ class OutputFormat (object):
|
||||||
ref_start = section.text.find('[[', i)
|
ref_start = section.text.find('[[', i)
|
||||||
tag_start = section.text.find('[', i)
|
tag_start = section.text.find('[', i)
|
||||||
if ref_start >= 0 and ref_start <= tag_start:
|
if ref_start >= 0 and ref_start <= tag_start:
|
||||||
res += section.text[i:ref_start]
|
res += self.quote(section.text[i:ref_start])
|
||||||
ref_end = section.text.find(']]', ref_start)
|
ref_end = section.text.find(']]', ref_start)
|
||||||
if ref_end > ref_start:
|
if ref_end > ref_start:
|
||||||
ref = section.text[ref_start+2:ref_end]
|
ref = section.text[ref_start+2:ref_end]
|
||||||
|
@ -52,7 +55,7 @@ class OutputFormat (object):
|
||||||
raise Exception('Mismatched ref start [[ in section %s' %
|
raise Exception('Mismatched ref start [[ in section %s' %
|
||||||
self.name)
|
self.name)
|
||||||
elif tag_start >= 0:
|
elif tag_start >= 0:
|
||||||
res += section.text[i:tag_start]
|
res += self.quote(section.text[i:tag_start])
|
||||||
tag_end = section.text.find(']', tag_start)
|
tag_end = section.text.find(']', tag_start)
|
||||||
if tag_end < 0:
|
if tag_end < 0:
|
||||||
raise Exception('Mismatched tag start [ in section %s' %
|
raise Exception('Mismatched tag start [ in section %s' %
|
||||||
|
@ -68,18 +71,18 @@ class OutputFormat (object):
|
||||||
tag, self.name))
|
tag, self.name))
|
||||||
inner = section.text[tag_end+1:end_tag_start]
|
inner = section.text[tag_end+1:end_tag_start]
|
||||||
# FIXME this pollutes the mutable references object
|
# FIXME this pollutes the mutable references object
|
||||||
references['inner'] = inner
|
references['inner'] = self.quote(self.quote(inner))
|
||||||
for i, arg in enumerate(tagparts[1:]):
|
for i, arg in enumerate(tagparts[1:]):
|
||||||
references['arg%d' % (i+1)] = arg
|
references['arg%d' % (i+1)] = self.quote(arg)
|
||||||
f = self.format_with_template(tagname,
|
f = self.format_with_template(tagname,
|
||||||
references)
|
references)
|
||||||
if len(f) > 0:
|
if len(f) > 0:
|
||||||
res += f
|
res += f
|
||||||
else:
|
else:
|
||||||
res += inner
|
res += self.quote(inner)
|
||||||
i = section.text.find(']', end_tag_start) + 1
|
i = section.text.find(']', end_tag_start) + 1
|
||||||
else:
|
else:
|
||||||
res += section.text[i:]
|
res += self.quote(section.text[i:])
|
||||||
break
|
break
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@ -100,16 +103,17 @@ class OutputFormat (object):
|
||||||
|
|
||||||
class ReferenceFormatter (object):
|
class ReferenceFormatter (object):
|
||||||
"There is probably a better way, but this hack seems to work."
|
"There is probably a better way, but this hack seems to work."
|
||||||
def __init__(self, section, shuffled_sections, ref_template):
|
def __init__(self, section, shuffled_sections, ref_template, quote):
|
||||||
self.section = section
|
self.section = section
|
||||||
self.shuffled_sections = shuffled_sections
|
self.shuffled_sections = shuffled_sections
|
||||||
self.found = set()
|
self.found = set()
|
||||||
self.ref_template = ref_template
|
self.ref_template = ref_template
|
||||||
self.items = {'nr' : shuffled_sections.to_nr[section]}
|
self.items = {'nr' : shuffled_sections.to_nr[section]}
|
||||||
|
self.quote = quote
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
if key in self.items:
|
if key in self.items:
|
||||||
return self.items[key]
|
return self.quote(self.items[key])
|
||||||
to_section = self.shuffled_sections.from_name[key]
|
to_section = self.shuffled_sections.from_name[key]
|
||||||
res = self.ref_template % {
|
res = self.ref_template % {
|
||||||
'nr' : self.shuffled_sections.to_nr[to_section],
|
'nr' : self.shuffled_sections.to_nr[to_section],
|
||||||
|
|
26
quote.py
Normal file
26
quote.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#FIXME entire file is a hack
|
||||||
|
|
||||||
|
def latex(s):
|
||||||
|
return (s.replace('\\', '\\textbackslash')
|
||||||
|
.replace('&', '\&')
|
||||||
|
.replace('%', '\%')
|
||||||
|
.replace('$', '\$')
|
||||||
|
.replace('#', '\#')
|
||||||
|
.replace('_', '\_')
|
||||||
|
.replace('{', '\{')
|
||||||
|
.replace('}', '\}')
|
||||||
|
.replace('~', '\\textasciitilde')
|
||||||
|
.replace('^', '\\textasciicircum'))
|
||||||
|
|
||||||
|
def rtf(s):
|
||||||
|
return (s.replace('\\', '\\\\')
|
||||||
|
.replace('{', '\\{')
|
||||||
|
.replace('}', '\\}'))
|
||||||
|
|
||||||
|
import cgi
|
||||||
|
|
||||||
|
def html(s):
|
||||||
|
return cgi.escape(s)
|
||||||
|
|
||||||
|
def no(s):
|
||||||
|
return s
|
8
todo.org
8
todo.org
|
@ -1,4 +1,4 @@
|
||||||
* TODO [32/57] [56%]
|
* TODO [33/59] [55%]
|
||||||
- [X] Debug output
|
- [X] Debug output
|
||||||
- [X] DOT output
|
- [X] DOT output
|
||||||
- [X] LaTeX output
|
- [X] LaTeX output
|
||||||
|
@ -34,13 +34,15 @@
|
||||||
- [X] Book option to set title
|
- [X] Book option to set title
|
||||||
- [X] Book option to set author
|
- [X] Book option to set author
|
||||||
- [X] Book option to set max section number to use
|
- [X] Book option to set max section number to use
|
||||||
- [ ] Quote strings to not break formatting.
|
- [X] Quote strings to not break formatting.
|
||||||
- [X] Include other templates from a template.
|
- [X] Include other templates from a template.
|
||||||
- [ ] Template for book introduction (including rules etc)
|
- [ ] Template for book introduction (including rules etc)
|
||||||
Sections with some markup (has number 0?) are added as chapters
|
Sections with some markup (has number 0?) are added as chapters
|
||||||
of introduction, otherwise formatted identical to other sections.
|
of introduction, otherwise formatted identical to other sections.
|
||||||
- [ ] More formatting possibilities in sections
|
- [ ] More formatting possibilities in sections
|
||||||
Look at existing gamebooks to get ideas.
|
Look at existing gamebooks to get ideas.
|
||||||
|
- [ ] Only accept specific characters in identifiers (eg section names)
|
||||||
|
eg [a-z][a-z_0-9]+
|
||||||
- [ ] Random pick of link to follow from a section.
|
- [ ] Random pick of link to follow from a section.
|
||||||
- [ ] Possibility to make predictable random numbers and shuffling for testing
|
- [ ] Possibility to make predictable random numbers and shuffling for testing
|
||||||
- [ ] Test generate examples and compare to expected output in all formats
|
- [ ] Test generate examples and compare to expected output in all formats
|
||||||
|
@ -63,6 +65,8 @@
|
||||||
- [ ] Some way to insert character sheet in book introduction
|
- [ ] Some way to insert character sheet in book introduction
|
||||||
- [ ] Some way to insert dice at bottom of pages for LaTeX
|
- [ ] Some way to insert dice at bottom of pages for LaTeX
|
||||||
- [ ] Some way to insert optional random numbers table at end of book
|
- [ ] Some way to insert optional random numbers table at end of book
|
||||||
|
- [ ] Defensive removal of any weird unicode not handled by quoting.
|
||||||
|
- [ ] Somewhat user-friendly error messages
|
||||||
- [ ] Document Gamebook format
|
- [ ] Document Gamebook format
|
||||||
- [ ] HTML CSS
|
- [ ] HTML CSS
|
||||||
- [ ] Higher level text-language for Gamebooks
|
- [ ] Higher level text-language for Gamebooks
|
||||||
|
|
Loading…
Reference in a new issue