mirror of
https://github.com/Oreolek/gamebookformat.git
synced 2024-05-08 20:18:19 +03:00
Require -x to use tags not in a builtin hardcoded list.
This commit is contained in:
parent
2176aef22f
commit
f1fd536995
1
examples/format.gamebook.options
Normal file
1
examples/format.gamebook.options
Normal file
|
@ -0,0 +1 @@
|
||||||
|
-x
|
|
@ -70,8 +70,9 @@ def format_gamebook(inputfilenames,
|
||||||
shuffle,
|
shuffle,
|
||||||
includetags,
|
includetags,
|
||||||
excludetags,
|
excludetags,
|
||||||
mapfilenames):
|
mapfilenames,
|
||||||
output_format = make_output(outputfilename, templatedirs)
|
allow_unknown_tags):
|
||||||
|
output_format = make_output(outputfilename, allow_unknown_tags, templatedirs)
|
||||||
book = sections.Book(make_bookid(outputfilename), includetags, excludetags)
|
book = sections.Book(make_bookid(outputfilename), includetags, excludetags)
|
||||||
for inputfilename in inputfilenames:
|
for inputfilename in inputfilenames:
|
||||||
parse_file_to_book(open(inputfilename, 'r'), output_format.name, book)
|
parse_file_to_book(open(inputfilename, 'r'), output_format.name, book)
|
||||||
|
@ -153,11 +154,12 @@ def add_section_to_book(book, name, text, intro_section=False,
|
||||||
if number:
|
if number:
|
||||||
book.force_section_nr(name, number)
|
book.force_section_nr(name, number)
|
||||||
|
|
||||||
def make_output(outputfilename, templatedirs):
|
def make_output(outputfilename, allow_unknown_tags, 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),
|
||||||
|
allow_unknown_tags,
|
||||||
of['quote'], extension.upper())
|
of['quote'], extension.upper())
|
||||||
raise Exception("Unsupported or unknown output format for %s."
|
raise Exception("Unsupported or unknown output format for %s."
|
||||||
% outputfilename)
|
% outputfilename)
|
||||||
|
@ -220,6 +222,8 @@ if __name__ == '__main__':
|
||||||
help='do not shuffle sections')
|
help='do not shuffle sections')
|
||||||
ap.add_argument('-m', '--map-file', metavar='F', dest='mapfiles',
|
ap.add_argument('-m', '--map-file', metavar='F', dest='mapfiles',
|
||||||
action='append', help='number map file')
|
action='append', help='number map file')
|
||||||
|
ap.add_argument('-x', '--allow-unknown', action='store_true',
|
||||||
|
dest='allow_unknown_tags')
|
||||||
args = ap.parse_args()
|
args = ap.parse_args()
|
||||||
templatedirs = ['templates',
|
templatedirs = ['templates',
|
||||||
os.path.join(os.path.dirname(sys.argv[0]), 'templates')]
|
os.path.join(os.path.dirname(sys.argv[0]), 'templates')]
|
||||||
|
@ -237,4 +241,5 @@ if __name__ == '__main__':
|
||||||
args.shuffle,
|
args.shuffle,
|
||||||
args.includetags or [],
|
args.includetags or [],
|
||||||
args.excludetags or [],
|
args.excludetags or [],
|
||||||
args.mapfiles or [])
|
args.mapfiles or [],
|
||||||
|
args.allow_unknown_tags)
|
||||||
|
|
31
output.py
31
output.py
|
@ -2,14 +2,41 @@ import os
|
||||||
import os.path
|
import os.path
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
# Hardcoded list of tags allowed without -x flag.
|
||||||
|
BUILTIN_TAGS = ['add',
|
||||||
|
'atleast',
|
||||||
|
'b',
|
||||||
|
'collect',
|
||||||
|
'cost',
|
||||||
|
'count',
|
||||||
|
'dec',
|
||||||
|
'drop',
|
||||||
|
'found',
|
||||||
|
'has',
|
||||||
|
'hasnot',
|
||||||
|
'img',
|
||||||
|
'inc',
|
||||||
|
'init',
|
||||||
|
'lessthan',
|
||||||
|
'min',
|
||||||
|
'morethan',
|
||||||
|
'random',
|
||||||
|
'set',
|
||||||
|
'take',
|
||||||
|
'trade',
|
||||||
|
'xor']
|
||||||
|
|
||||||
|
NOT_BUILTIN_TAG_MESSAGE = "Unknown tag %s not allowed without -x flag."
|
||||||
|
|
||||||
COUNTER_CREATE_TAG = 'count'
|
COUNTER_CREATE_TAG = 'count'
|
||||||
COUNTER_USE_TAGS = set(['set', 'inc', 'dec', 'min',
|
COUNTER_USE_TAGS = set(['set', 'inc', 'dec', 'min',
|
||||||
'lessthan', 'morethan', 'atleast'])
|
'lessthan', 'morethan', 'atleast'])
|
||||||
|
|
||||||
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, quote, name):
|
def __init__(self, templates, allow_unknown_tags, quote, name):
|
||||||
self.templates = templates
|
self.templates = templates
|
||||||
|
self.allow_unknown_tags = allow_unknown_tags
|
||||||
self.format_quote = quote
|
self.format_quote = quote
|
||||||
self.name = name
|
self.name = name
|
||||||
self.counter_names = {}
|
self.counter_names = {}
|
||||||
|
@ -112,6 +139,8 @@ class OutputFormat (object):
|
||||||
tag = section.text[tag_start+1:tag_end].strip()
|
tag = section.text[tag_start+1:tag_end].strip()
|
||||||
tagparts = tag.split()
|
tagparts = tag.split()
|
||||||
tagname = tagparts[0]
|
tagname = tagparts[0]
|
||||||
|
if not self.allow_unknown_tags and tagname not in BUILTIN_TAGS:
|
||||||
|
raise Exception(NOT_BUILTIN_TAG_MESSAGE % tagname)
|
||||||
end_tag_start = section.text.find('[', tag_end)
|
end_tag_start = section.text.find('[', tag_end)
|
||||||
if (not end_tag_start > tag_end
|
if (not end_tag_start > tag_end
|
||||||
and section.text[end_tag_start].startswith('[/' + tagname
|
and section.text[end_tag_start].startswith('[/' + tagname
|
||||||
|
|
21
readme.org
21
readme.org
|
@ -19,6 +19,7 @@ gamebook on paper or a screen (or for debugging it).
|
||||||
: -o D, --option D add template override options dir
|
: -o D, --option D add template override options dir
|
||||||
: -S, --no-shuffle do not shuffle sections
|
: -S, --no-shuffle do not shuffle sections
|
||||||
: -m F, --map-file F number map file
|
: -m F, --map-file F number map file
|
||||||
|
: -x, --allow_unknown allow unknown tags
|
||||||
** Supported Output Formats
|
** Supported Output Formats
|
||||||
|
|
||||||
| Name | Extension | Description |
|
| Name | Extension | Description |
|
||||||
|
@ -56,6 +57,26 @@ todo (or substitute whatever other tag(s) you are interested in).
|
||||||
| static | html | Remove script link from HTML output. |
|
| static | html | Remove script link from HTML output. |
|
||||||
| twine2 | html | Generate story that can be imported to [[http://twinery.org/2/#stories][Twine 2]] |
|
| twine2 | html | Generate story that can be imported to [[http://twinery.org/2/#stories][Twine 2]] |
|
||||||
|
|
||||||
|
** Adding Custom Templates
|
||||||
|
Any of the built-in templates can be overridden easily. New
|
||||||
|
tags can be added that can generate any output you need for
|
||||||
|
different file formats. However to add a tag that is not
|
||||||
|
included in the default distribution the command-line
|
||||||
|
flat *-x* is required to tell gamebookformat that you
|
||||||
|
know what you are doing. Otherwise when an unknown
|
||||||
|
tag is encountered you get an ugly error message.
|
||||||
|
The reason for making it moderately difficult to add
|
||||||
|
a new tag is that all the builtin tags have been
|
||||||
|
choosen to work reasonably well in anything from
|
||||||
|
static printed gamebooks to dynamic digital app
|
||||||
|
gamebooks. Anyone thinking of adding a new tag
|
||||||
|
should think twice about how having that tag might
|
||||||
|
mean that some output formats are not longer useful.
|
||||||
|
Sticking to the default tags and not overriding them
|
||||||
|
to do bad things ensures that your gamebooks are
|
||||||
|
still readable and playable in all supported
|
||||||
|
output formats. (The process of adding new templates and new output
|
||||||
|
formats really should be better documented.)
|
||||||
** Styles and Scripts
|
** Styles and Scripts
|
||||||
Generated *html* files use the included *gamebookformat.css* for
|
Generated *html* files use the included *gamebookformat.css* for
|
||||||
styling and *gamebookformat.js* for scripting (except with the
|
styling and *gamebookformat.js* for scripting (except with the
|
||||||
|
|
|
@ -20,10 +20,10 @@ class TestOutputFormat(TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
of = output.OutputFormat(FakeTemplates({}), "TEST", str)
|
of = output.OutputFormat(FakeTemplates({}), "TEST", False, str)
|
||||||
|
|
||||||
def test_format_begin(self):
|
def test_format_begin(self):
|
||||||
of = output.OutputFormat(FakeTemplates({'begin' : 'b %(max)d'}), "TEST", str)
|
of = output.OutputFormat(FakeTemplates({'begin' : 'b %(max)d'}), "TEST", False, str)
|
||||||
self.assertEqual(of.format_begin({'max' : 2}), 'b 2')
|
self.assertEqual(of.format_begin({'max' : 2}), 'b 2')
|
||||||
|
|
||||||
class TestReferenceFormatter(TestCase):
|
class TestReferenceFormatter(TestCase):
|
||||||
|
|
Loading…
Reference in a new issue