mirror of
https://github.com/Oreolek/gamebookformat.git
synced 2024-06-26 03:41:04 +03:00
More formatting options.
This commit is contained in:
parent
5a468bdd65
commit
f60a650598
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -8,7 +8,6 @@ test.dot
|
||||||
*.toc
|
*.toc
|
||||||
*.pdf
|
*.pdf
|
||||||
test.rtf
|
test.rtf
|
||||||
*.png
|
|
||||||
*.out
|
*.out
|
||||||
test.html
|
test.html
|
||||||
.lein*
|
.lein*
|
||||||
|
|
4
examples/.gitignore
vendored
4
examples/.gitignore
vendored
|
@ -3,4 +3,6 @@
|
||||||
*.html
|
*.html
|
||||||
*.dot
|
*.dot
|
||||||
*.debug
|
*.debug
|
||||||
*.txt
|
*.txt
|
||||||
|
*.png
|
||||||
|
!testimage.png
|
|
@ -1,12 +1,27 @@
|
||||||
title = Format
|
title = Format
|
||||||
|
starttext = Adventure begins in section 1.
|
||||||
|
hideintrotext = HIDE THE INTRO
|
||||||
|
showintrotext = SHOW THE INTRO
|
||||||
|
|
||||||
|
= Introduction
|
||||||
|
Adding an introduction
|
||||||
|
to the gamebook here. This will create
|
||||||
|
a section, but it will not be shuffled nor numbered
|
||||||
|
with the gamebook sections below.
|
||||||
|
|
||||||
|
= Another Heading
|
||||||
|
This starts another non-shuffled section.
|
||||||
|
|
||||||
* 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,
|
This section contains some tricky characters to quote,
|
||||||
like } and { and " and ' and \.
|
like } and { and " and ' and \.
|
||||||
HTML will probably not like <div> or &boom;.
|
HTML will probably not like <div> or &boom;.
|
||||||
|
There should be an image below as well.
|
||||||
If something broke, turn to [[bad]],
|
If something broke, turn to [[bad]],
|
||||||
otherwise turn to [[good]].
|
otherwise turn to [[good]].
|
||||||
|
[img]testimage.png[/img]
|
||||||
|
|
||||||
* dum :dummy:
|
* dum :dummy:
|
||||||
Sections tagged as dummy will not be
|
Sections tagged as dummy will not be
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
max = 400
|
max = 400
|
||||||
|
|
||||||
|
= Introduction
|
||||||
|
This gamebook demonstrates simple references between sections.
|
||||||
|
Also notice that an intro section like this one can
|
||||||
|
reference sections, like the start at [[start]] or the next
|
||||||
|
section at [[next]].
|
||||||
|
|
||||||
* 1 start
|
* 1 start
|
||||||
This is where the adventure begins. You can go on to the
|
This is where the adventure begins. You can go on to the
|
||||||
next section, see [[next]] or try the other instead, see [[other]].
|
next section, see [[next]] or try the other instead, see [[other]].
|
||||||
|
|
BIN
examples/testimage.png
Normal file
BIN
examples/testimage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 393 KiB |
|
@ -28,6 +28,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import sys
|
import sys
|
||||||
|
@ -41,6 +42,8 @@ from output import OutputFormat
|
||||||
|
|
||||||
USAGE = "usage: %prog [options] inputfile(s)... outputfile"
|
USAGE = "usage: %prog [options] inputfile(s)... outputfile"
|
||||||
|
|
||||||
|
SECTION_NAME_RE = re.compile("^[a-z][a-z_0-9]*$")
|
||||||
|
|
||||||
def of(extension, name, quote):
|
def of(extension, name, quote):
|
||||||
return {'extension' : extension,
|
return {'extension' : extension,
|
||||||
'name' : name,
|
'name' : name,
|
||||||
|
@ -81,17 +84,15 @@ def parse_file_to_book(inputfile, book):
|
||||||
number = None
|
number = None
|
||||||
text = ""
|
text = ""
|
||||||
tags = None
|
tags = None
|
||||||
|
intro_section = False
|
||||||
for line in inputfile.readlines():
|
for line in inputfile.readlines():
|
||||||
if before_first_section:
|
|
||||||
if '=' in line:
|
|
||||||
config = line.split('=')
|
|
||||||
book.configure(config[0].strip(), config[1].strip())
|
|
||||||
if line.startswith('*'):
|
if line.startswith('*'):
|
||||||
before_first_section = False
|
before_first_section = False
|
||||||
if name:
|
if name:
|
||||||
add_section_to_book(book, name, text, number)
|
add_section_to_book(book, name, text, intro_section, number)
|
||||||
number = None
|
number = None
|
||||||
text = ""
|
text = ""
|
||||||
|
intro_section = False
|
||||||
heading = [h.strip() for h in line[1:].strip().split()]
|
heading = [h.strip() for h in line[1:].strip().split()]
|
||||||
if len(heading) > 1 and heading[-1].startswith(':'):
|
if len(heading) > 1 and heading[-1].startswith(':'):
|
||||||
if not heading[-1].endswith(':'):
|
if not heading[-1].endswith(':'):
|
||||||
|
@ -106,20 +107,34 @@ def parse_file_to_book(inputfile, book):
|
||||||
elif len(heading) == 2:
|
elif len(heading) == 2:
|
||||||
number = int(heading[0])
|
number = int(heading[0])
|
||||||
name = heading[1]
|
name = heading[1]
|
||||||
else:
|
if not name or not SECTION_NAME_RE.match(name):
|
||||||
raise Exception("bad section heading %s" % str(heading))
|
raise Exception("bad section heading: %s" % str(heading))
|
||||||
else:
|
elif line.startswith('='):
|
||||||
|
if name:
|
||||||
|
add_section_to_book(book, name, text, intro_section, number)
|
||||||
|
name = line[1:].strip()
|
||||||
|
intro_section = True
|
||||||
|
text = ""
|
||||||
|
elif before_first_section and '=' in line:
|
||||||
|
config = line.split('=')
|
||||||
|
book.configure(config[0].strip(), config[1].strip())
|
||||||
|
elif name:
|
||||||
text = text + " " + line.strip()
|
text = text + " " + line.strip()
|
||||||
|
elif len(line.strip()):
|
||||||
|
raise Exception("unknown content before sections: %s" % line.strip())
|
||||||
if name:
|
if name:
|
||||||
add_section_to_book(book, name, text, number, tags)
|
add_section_to_book(book, name, text, intro_section, number, tags)
|
||||||
|
|
||||||
def add_section_to_book(book, name, text, number=None, tags=None):
|
def add_section_to_book(book, name, text, intro_section=False, number=None, tags=None):
|
||||||
section = sections.Section(name, text)
|
section = sections.Section(name, text)
|
||||||
if tags:
|
if tags:
|
||||||
section.add_tags(tags)
|
section.add_tags(tags)
|
||||||
book.add(section)
|
if intro_section:
|
||||||
if number:
|
book.addintro(section)
|
||||||
book.force_section_nr(name, number)
|
else:
|
||||||
|
book.add(section)
|
||||||
|
if number:
|
||||||
|
book.force_section_nr(name, number)
|
||||||
|
|
||||||
def make_output(outputfilename, templatedirs):
|
def make_output(outputfilename, templatedirs):
|
||||||
for of in OUTPUT_FORMATS:
|
for of in OUTPUT_FORMATS:
|
||||||
|
@ -134,6 +149,8 @@ def write_book(book, output_format, outputfilename):
|
||||||
shuffled_sections = book.shuffle()
|
shuffled_sections = book.shuffle()
|
||||||
output = open(outputfilename, 'w')
|
output = open(outputfilename, 'w')
|
||||||
output_format.write_begin(book, output)
|
output_format.write_begin(book, output)
|
||||||
|
output_format.write_intro_sections(book, shuffled_sections, output)
|
||||||
|
output_format.write_sections_begin(book, output)
|
||||||
output_format.write_shuffled_sections(shuffled_sections, output)
|
output_format.write_shuffled_sections(shuffled_sections, output)
|
||||||
output_format.write_end(book, output)
|
output_format.write_end(book, output)
|
||||||
save_section_mapping(shuffled_sections, outputfilename)
|
save_section_mapping(shuffled_sections, outputfilename)
|
||||||
|
|
31
output.py
31
output.py
|
@ -12,6 +12,27 @@ class OutputFormat (object):
|
||||||
# FIXME make sure book config is properly quoted
|
# 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_intro_sections(self, book, shuffled_sections, output):
|
||||||
|
for s in book.introsections:
|
||||||
|
if not s.hastag('dummy'):
|
||||||
|
self.write_intro_section(s, shuffled_sections, output)
|
||||||
|
|
||||||
|
def write_intro_section(self, section, shuffled_sections, output):
|
||||||
|
# FIXME some serious code-duplication here
|
||||||
|
refs = []
|
||||||
|
refsdict = ReferenceFormatter(section, shuffled_sections,
|
||||||
|
self.format_with_template("section_ref"),
|
||||||
|
self.quote)
|
||||||
|
formatted_text = self.format_section(section, refsdict)
|
||||||
|
print >> output, self.format_with_template("introsection", {
|
||||||
|
'name' : section.name,
|
||||||
|
'text' : formatted_text,
|
||||||
|
'refs' : '\n'.join(refsdict.getfound()) # hack for DOT output
|
||||||
|
}),
|
||||||
|
|
||||||
|
def write_sections_begin(self, book, output):
|
||||||
|
print >> output, self.format_with_template("sections_begin", book.config);
|
||||||
|
|
||||||
def write_shuffled_sections(self, shuffled_sections, output):
|
def write_shuffled_sections(self, shuffled_sections, output):
|
||||||
for i, p in enumerate(shuffled_sections.as_list):
|
for i, p in enumerate(shuffled_sections.as_list):
|
||||||
if p and not p.hastag('dummy'):
|
if p and not p.hastag('dummy'):
|
||||||
|
@ -26,7 +47,7 @@ class OutputFormat (object):
|
||||||
self.quote)
|
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' : section.nr,
|
||||||
'name' : section.name,
|
'name' : section.name,
|
||||||
'text' : formatted_text,
|
'text' : formatted_text,
|
||||||
'refs' : '\n'.join(refsdict.getfound()) # hack for DOT output
|
'refs' : '\n'.join(refsdict.getfound()) # hack for DOT output
|
||||||
|
@ -92,7 +113,7 @@ class OutputFormat (object):
|
||||||
}),
|
}),
|
||||||
|
|
||||||
def write_end(self, book, output):
|
def write_end(self, book, output):
|
||||||
print >> output, self.format_with_template("end"),
|
print >> output, self.format_with_template("end", book.config),
|
||||||
|
|
||||||
def format_with_template(self, name, values=None):
|
def format_with_template(self, name, values=None):
|
||||||
template = self.templates.get(name)
|
template = self.templates.get(name)
|
||||||
|
@ -108,7 +129,7 @@ class ReferenceFormatter (object):
|
||||||
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' : section.nr}
|
||||||
self.quote = quote
|
self.quote = quote
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
|
@ -116,8 +137,8 @@ class ReferenceFormatter (object):
|
||||||
return self.quote(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' : to_section.nr,
|
||||||
'from_nr' : self.shuffled_sections.to_nr[self.section]
|
'from_nr' : self.section.nr
|
||||||
}
|
}
|
||||||
if key in self.shuffled_sections.name_to_nr:
|
if key in self.shuffled_sections.name_to_nr:
|
||||||
self.found.add(res)
|
self.found.add(res)
|
||||||
|
|
50
sections.py
50
sections.py
|
@ -17,30 +17,57 @@ class Section:
|
||||||
return "Section(%s, %s, %s)" % (repr(self.name), repr(self.text),
|
return "Section(%s, %s, %s)" % (repr(self.name), repr(self.text),
|
||||||
repr(self.tags))
|
repr(self.tags))
|
||||||
|
|
||||||
|
class ShuffledSection (Section):
|
||||||
|
def __init__(self, nr, section):
|
||||||
|
self.nr = nr
|
||||||
|
self.name = section.name
|
||||||
|
self.text = section.text
|
||||||
|
self.tags = section.tags.copy()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "ShuffledSection(%d, %s, %s, %s)" % (self.nr,
|
||||||
|
repr(self.name), repr(self.text),
|
||||||
|
repr(self.tags))
|
||||||
|
|
||||||
|
class IntroSection (Section):
|
||||||
|
def __init__(self, section):
|
||||||
|
self.nr = -1
|
||||||
|
self.name = section.name
|
||||||
|
self.text = section.text
|
||||||
|
self.tags = section.tags.copy()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "IntroSection(%d, %s, %s, %s)" % (repr(self.name), repr(self.text),
|
||||||
|
repr(self.tags))
|
||||||
|
|
||||||
class ShuffledSections:
|
class ShuffledSections:
|
||||||
def __init__(self, as_list, from_nr, to_nr, from_name, nr_sections):
|
def __init__(self, as_list, from_nr, from_name, nr_sections):
|
||||||
self.as_list = as_list
|
self.as_list = as_list
|
||||||
self.from_nr = from_nr
|
self.from_nr = from_nr
|
||||||
self.to_nr = to_nr
|
|
||||||
self.from_name = from_name
|
self.from_name = from_name
|
||||||
self.name_to_nr = {}
|
self.name_to_nr = {}
|
||||||
for n in from_name:
|
for n in from_name:
|
||||||
self.name_to_nr[n] = to_nr[from_name[n]]
|
self.name_to_nr[n] = from_name[n].nr
|
||||||
for nr in nr_sections:
|
for nr in nr_sections:
|
||||||
self.name_to_nr[nr_sections[nr]] = nr
|
self.name_to_nr[nr_sections[nr]] = nr
|
||||||
|
|
||||||
STR_BOOK_CONFIG = set(['title', 'author'])
|
STR_BOOK_CONFIG = set(['title', 'author', 'starttext', 'hideintrotext',
|
||||||
|
'showintrotext'])
|
||||||
INT_BOOK_CONFIG = set(['max'])
|
INT_BOOK_CONFIG = set(['max'])
|
||||||
|
|
||||||
class Book:
|
class Book:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.sections = []
|
self.sections = []
|
||||||
|
self.introsections = []
|
||||||
self.from_name = {}
|
self.from_name = {}
|
||||||
self.nr_sections = {}
|
self.nr_sections = {}
|
||||||
self.codewords = set()
|
self.codewords = set()
|
||||||
self.config = {'max' : 0,
|
self.config = {'max' : 0,
|
||||||
'title' : 'Gamebook',
|
'title' : 'Gamebook',
|
||||||
'author' : ''}
|
'author' : '',
|
||||||
|
'starttext' : 'Turn to 1 to begin.',
|
||||||
|
'hideintrotext' : '(hide instructions)',
|
||||||
|
'showintrotext' : '(show instructions)'}
|
||||||
|
|
||||||
def configure(self, name, value):
|
def configure(self, name, value):
|
||||||
if name in INT_BOOK_CONFIG:
|
if name in INT_BOOK_CONFIG:
|
||||||
|
@ -59,6 +86,9 @@ class Book:
|
||||||
if len(self.sections) > self.config['max']:
|
if len(self.sections) > self.config['max']:
|
||||||
self.config['max'] = len(self.sections)
|
self.config['max'] = len(self.sections)
|
||||||
|
|
||||||
|
def addintro(self, section):
|
||||||
|
self.introsections.append(IntroSection(section))
|
||||||
|
|
||||||
def add_codeword(self, word):
|
def add_codeword(self, word):
|
||||||
self.codewords.add(word)
|
self.codewords.add(word)
|
||||||
|
|
||||||
|
@ -70,8 +100,8 @@ class Book:
|
||||||
def shuffle(self):
|
def shuffle(self):
|
||||||
as_list = [None]
|
as_list = [None]
|
||||||
from_nr = {}
|
from_nr = {}
|
||||||
to_nr = {}
|
|
||||||
shuffled = self.sections[:]
|
shuffled = self.sections[:]
|
||||||
|
shuffled_from_name = {}
|
||||||
while len(shuffled) < self.config['max']:
|
while len(shuffled) < self.config['max']:
|
||||||
dummy = Section('Dummy', '')
|
dummy = Section('Dummy', '')
|
||||||
dummy.add_tags(['dummy'])
|
dummy.add_tags(['dummy'])
|
||||||
|
@ -83,16 +113,16 @@ class Book:
|
||||||
for nr in range(1, self.config['max'] + 1):
|
for nr in range(1, self.config['max'] + 1):
|
||||||
if (self.nr_sections.has_key(nr)
|
if (self.nr_sections.has_key(nr)
|
||||||
and self.nr_sections[nr] in self.from_name):
|
and self.nr_sections[nr] in self.from_name):
|
||||||
section = self.from_name[self.nr_sections[nr]]
|
section = ShuffledSection(nr, self.from_name[self.nr_sections[nr]])
|
||||||
elif len(shuffled):
|
elif len(shuffled):
|
||||||
section = shuffled.pop()
|
section = ShuffledSection(nr, shuffled.pop())
|
||||||
else:
|
else:
|
||||||
section = None
|
section = None
|
||||||
as_list.append(section)
|
as_list.append(section)
|
||||||
from_nr[nr] = section
|
from_nr[nr] = section
|
||||||
if section:
|
if section:
|
||||||
to_nr[section] = nr
|
shuffled_from_name[section.name] = section
|
||||||
return ShuffledSections(as_list, from_nr, to_nr, self.from_name.copy(),
|
return ShuffledSections(as_list, from_nr, shuffled_from_name,
|
||||||
self.nr_sections)
|
self.nr_sections)
|
||||||
|
|
||||||
class Item (object):
|
class Item (object):
|
||||||
|
|
0
templates/DEFAULT/img.txt
Normal file
0
templates/DEFAULT/img.txt
Normal file
2
templates/DEFAULT/introsection.txt
Normal file
2
templates/DEFAULT/introsection.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#include "introsectionheading"
|
||||||
|
#include "sectionbody"
|
2
templates/DEFAULT/sections_begin.txt
Normal file
2
templates/DEFAULT/sections_begin.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
%(starttext)s
|
1
templates/debug/img.debug
Normal file
1
templates/debug/img.debug
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[IMG]%(inner)s[/IMG]
|
2
templates/debug/introsection.debug
Normal file
2
templates/debug/introsection.debug
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
%(name)s
|
||||||
|
%(text)s
|
0
templates/dot/introsection.dot
Normal file
0
templates/dot/introsection.dot
Normal file
0
templates/dot/sections_begin.dot
Normal file
0
templates/dot/sections_begin.dot
Normal file
|
@ -12,5 +12,5 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
#include "intro"
|
#include "hideintro"
|
||||||
<div class="gamebook">
|
<div class="gamebook">
|
||||||
|
|
|
@ -3,5 +3,6 @@
|
||||||
<script>
|
<script>
|
||||||
#include "endscript"
|
#include "endscript"
|
||||||
</script>
|
</script>
|
||||||
|
#include "showintro"
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
if (this.gamebook) {
|
if (this.gamebook) {
|
||||||
gamebook.turnTo(1);
|
|
||||||
}
|
}
|
||||||
|
|
2
templates/html/hideintro.html
Normal file
2
templates/html/hideintro.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<div class="hideintrolink nodisplay"
|
||||||
|
onclick="gamebook.hideIntroSections()">%(hideintrotext)s</div>
|
1
templates/html/img.html
Normal file
1
templates/html/img.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<img src="%(inner)s" class="sectionimage"></img>
|
6
templates/html/introsection.html
Normal file
6
templates/html/introsection.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<div class="introsection">
|
||||||
|
<span class="introsectionheading">%(name)s</span>
|
||||||
|
<div class="introsectionbody">
|
||||||
|
%(text)s
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -64,6 +64,12 @@
|
||||||
this.displaySection(nr);
|
this.displaySection(nr);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'start' : function() {
|
||||||
|
this.hideIntroSections();
|
||||||
|
this.addClassToClass('startlink', 'nodisplay');
|
||||||
|
this.turnTo(1);
|
||||||
|
},
|
||||||
|
|
||||||
'displaySection' : function(nr) {
|
'displaySection' : function(nr) {
|
||||||
if (this.player.currentSection) {
|
if (this.player.currentSection) {
|
||||||
this.player.currentSection.element.style.display = 'none';
|
this.player.currentSection.element.style.display = 'none';
|
||||||
|
@ -74,6 +80,35 @@
|
||||||
this.player.currentSection = gamebook.sections[nr];
|
this.player.currentSection = gamebook.sections[nr];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'hideIntroSections' : function() {
|
||||||
|
this.addClassToClass('introsection', 'nodisplay');
|
||||||
|
this.removeClassFromClass('displayintrolink', 'nodisplay');
|
||||||
|
this.addClassToClass('hideintrolink', 'nodisplay');
|
||||||
|
},
|
||||||
|
|
||||||
|
'showIntroSections' : function() {
|
||||||
|
this.removeClassFromClass('introsection', 'nodisplay');
|
||||||
|
this.addClassToClass('displayintrolink', 'nodisplay');
|
||||||
|
this.removeClassFromClass('hideintrolink', 'nodisplay');
|
||||||
|
document.body.scrollIntoView();
|
||||||
|
},
|
||||||
|
|
||||||
|
'addClassToClass' : function(className, addClass) {
|
||||||
|
Array.prototype.forEach.call(
|
||||||
|
document.getElementsByClassName(className),
|
||||||
|
function(e) {
|
||||||
|
e.classList.add(addClass);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'removeClassFromClass' : function(className, removeClass) {
|
||||||
|
Array.prototype.forEach.call(
|
||||||
|
document.getElementsByClassName(className),
|
||||||
|
function(e) {
|
||||||
|
e.classList.remove(removeClass);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
'runActions' : function(e) {
|
'runActions' : function(e) {
|
||||||
var enableNextLink = true;
|
var enableNextLink = true;
|
||||||
var hasXorScope = false;
|
var hasXorScope = false;
|
||||||
|
|
2
templates/html/sections_begin.html
Normal file
2
templates/html/sections_begin.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<div class="startlink"
|
||||||
|
onclick="gamebook.start()">%(starttext)s</div>
|
2
templates/html/showintro.html
Normal file
2
templates/html/showintro.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<div class="displayintrolink nodisplay"
|
||||||
|
onclick="gamebook.showIntroSections()">%(showintrotext)s</div>
|
2
templates/html/startlink.html
Normal file
2
templates/html/startlink.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<div class="startlink"
|
||||||
|
onclick="gamebook.start()">%(starttext)s</div>
|
|
@ -18,3 +18,8 @@
|
||||||
.has {font-style: italic;}
|
.has {font-style: italic;}
|
||||||
.hasnot {font-style: italic;}
|
.hasnot {font-style: italic;}
|
||||||
.collectionTemplate {display: none;}
|
.collectionTemplate {display: none;}
|
||||||
|
.sectionimage {width: 100%%; padding: 1em;}
|
||||||
|
.nodisplay {display: none;}
|
||||||
|
.startlink {font-weight: bold; cursor: pointer;}
|
||||||
|
.displayintrolink {cursor: pointer;}
|
||||||
|
.hideintrolink {cursor: pointer;}
|
2
templates/rtf/introsectionheading.rtf
Normal file
2
templates/rtf/introsectionheading.rtf
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
\b \qc %(name)s
|
||||||
|
\b0\
|
|
@ -2,6 +2,7 @@
|
||||||
\usepackage[utf8]{inputenc}
|
\usepackage[utf8]{inputenc}
|
||||||
\usepackage[T1]{fontenc}
|
\usepackage[T1]{fontenc}
|
||||||
\usepackage[hidelinks]{hyperref}
|
\usepackage[hidelinks]{hyperref}
|
||||||
|
\usepackage{graphicx}
|
||||||
|
|
||||||
#include "geometry"
|
#include "geometry"
|
||||||
\newif\ifpdf
|
\newif\ifpdf
|
||||||
|
@ -24,5 +25,8 @@
|
||||||
\begin{document}
|
\begin{document}
|
||||||
|
|
||||||
#include "titlepage"
|
#include "titlepage"
|
||||||
|
|
||||||
|
\pagestyle{empty}
|
||||||
|
|
||||||
\clearpage
|
\clearpage
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
\documentclass[A5,twocolumn]{book}
|
\documentclass[a5,onecolumn]{book}
|
||||||
|
|
||||||
|
|
4
templates/tex/img.tex
Normal file
4
templates/tex/img.tex
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
\begin{center}
|
||||||
|
\includegraphics[width=.9\textwidth]{%(inner)s}
|
||||||
|
\end{center}
|
||||||
|
|
3
templates/tex/introsectionheading.tex
Normal file
3
templates/tex/introsectionheading.tex
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
\subsection*{\begin{center} \textbf{%(name)s} \end{center}}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
\subsection*{\begin{center} \textbf{%(nr)d} \end{center}}
|
|
||||||
|
|
||||||
\noindent
|
\noindent
|
||||||
%(text)s
|
%(text)s
|
||||||
\newline
|
\vspace{1em}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
\phantomsection
|
\phantomsection
|
||||||
\refstepcounter{sectionnr}
|
\refstepcounter{sectionnr}
|
||||||
\label{section%(nr)d}
|
\label{section%(nr)d}
|
||||||
|
\subsection*{\begin{center} \textbf{%(nr)d} \end{center}}
|
||||||
|
|
||||||
|
|
1
templates/txt/introsectionheading.txt
Normal file
1
templates/txt/introsectionheading.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
%(name)s
|
|
@ -1,2 +1 @@
|
||||||
%(nr)d
|
%(nr)d
|
||||||
|
|
||||||
|
|
32
todo.org
32
todo.org
|
@ -1,4 +1,4 @@
|
||||||
* TODO [33/59] [55%]
|
* TODO [37/65] [56%]
|
||||||
- [X] Debug output
|
- [X] Debug output
|
||||||
- [X] DOT output
|
- [X] DOT output
|
||||||
- [X] LaTeX output
|
- [X] LaTeX output
|
||||||
|
@ -36,13 +36,12 @@
|
||||||
- [X] Book option to set max section number to use
|
- [X] Book option to set max section number to use
|
||||||
- [X] 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)
|
- [X] 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.
|
||||||
- [ ] Inserting images
|
- [X] Inserting images
|
||||||
- [ ] More formatting possibilities in sections
|
- [X] HTML hide intro sections with link to display again
|
||||||
Look at existing gamebooks to get ideas.
|
- [X] Only accept specific characters in section names
|
||||||
- [ ] Only accept specific characters in identifiers (eg section names)
|
|
||||||
eg [a-z][a-z_0-9]+
|
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
|
||||||
|
@ -73,6 +72,27 @@
|
||||||
- [ ] 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.
|
- [ ] Defensive removal of any weird unicode not handled by quoting.
|
||||||
- [ ] Somewhat user-friendly error messages
|
- [ ] Somewhat user-friendly error messages
|
||||||
|
- [ ] More formatting possibilities in sections
|
||||||
|
Look at existing gamebooks to get ideas.
|
||||||
- [ ] Document Gamebook format
|
- [ ] Document Gamebook format
|
||||||
- [ ] HTML CSS
|
- [ ] HTML CSS
|
||||||
- [ ] Higher level text-language for Gamebooks
|
- [ ] Higher level text-language for Gamebooks
|
||||||
|
- [ ] BGG forum output (.bgg)
|
||||||
|
- [ ] Make sure HTML output works with javascript disabled and in inferior browsers
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue