1
0
Fork 0
mirror of https://github.com/Oreolek/gamebookformat.git synced 2024-06-26 03:41:04 +03:00

Named references.

Instead of just [[section]] you can  have [[section][name]] and
depending on format the name will be displayed instead of or
in addition to the section number referred to.
This commit is contained in:
Pelle Nilsson 2013-07-28 18:45:02 +02:00
parent cc58cc0580
commit e5723bdf70
22 changed files with 185 additions and 29 deletions

View file

@ -19,6 +19,8 @@ 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;.
You can make named references [[named1][like this]] (just happens
to be exactly the same syntax as in emacs org-mode btw).
There should be an image below as well. 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]].
@ -28,6 +30,15 @@ otherwise turn to [[good]].
Sections tagged as dummy will not be Sections tagged as dummy will not be
visible in output at all. visible in output at all.
* named1
This is where you should end up when you follow the named
reference from the starting section.
From here you can go to [[named2][the second named section]] or
to the [[good][good end]].
* named2
Very good. [[good][You win]].
* good * good
Good! Good!

View file

@ -4,7 +4,9 @@ max = 400
This gamebook demonstrates simple references between sections. This gamebook demonstrates simple references between sections.
Also notice that an intro section like this one can Also notice that an intro section like this one can
reference sections, like the start at [[start]] or the next reference sections, like the start at [[start]] or the next
section at [[next]]. section at [[next]]. References can include an optional
name that is used in some formats, so the same links
could also be rendered as [[start][start]] and [[next][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

View file

@ -1,6 +1,6 @@
BEGIN DEBUG OUTPUT BEGIN DEBUG OUTPUT
Book title: Format Book title: Format
Number of sections: 4 Number of sections: 6
Introduction 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. 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 Another Heading
@ -8,8 +8,10 @@ Another Heading
Adventure begins in section 1. Adventure begins in section 1.
1 (start) - This examples tests gamebook formatting, not so much game mechanics or 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;. There should be an image below as well. If something broke, turn to 2, otherwise turn to 3. [IMG]testimage.png[/IMG] 1 (start) - This examples tests gamebook formatting, not so much game mechanics or 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;. You can make named references like this (5) (just happens to be exactly the same syntax as in emacs org-mode btw). There should be an image below as well. If something broke, turn to 2, otherwise turn to 3. [IMG]testimage.png[/IMG]
2 (bad) - Bad. 2 (bad) - Bad.
3 (good) - Good! 3 (good) - Good!
4 () - (EMPTY) 4 (named2) - Very good. You win (3).
5 (named1) - This is where you should end up when you follow the named reference from the starting section. From here you can go to the second named section (4) or to the good end (3).
6 () - (EMPTY)
END DEBUG OUTPUT END DEBUG OUTPUT

View file

@ -1,6 +1,10 @@
digraph gamebook { digraph gamebook {
1->2 1->5
1->2
1->3 1->3
4->3
5->4
5->3
} }

View file

@ -47,7 +47,8 @@
<div class="section" id="section1"> <div class="section" id="section1">
<div class="sectionnumber" id="para1">1</div> <div class="sectionnumber" id="para1">1</div>
<div class="sectiontext"> <div class="sectiontext">
This examples tests gamebook formatting, not so much game mechanics or 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 &lt;div&gt; or &amp;boom;. There should be an image below as well. If something broke, turn to <a class="sectionref enabledlink" data-ref="2" This examples tests gamebook formatting, not so much game mechanics or 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 &lt;div&gt; or &amp;boom;. You can make named references <a class="sectionref enabledlink" data-ref="5"
href="#section5">like this</a> (just happens to be exactly the same syntax as in emacs org-mode btw). There should be an image below as well. If something broke, turn to <a class="sectionref enabledlink" data-ref="2"
href="#section2">2</a>, otherwise turn to <a class="sectionref enabledlink" data-ref="3" href="#section2">2</a>, otherwise turn to <a class="sectionref enabledlink" data-ref="3"
href="#section3">3</a>. <img src="testimage.png" class="sectionimage"></img> href="#section3">3</a>. <img src="testimage.png" class="sectionimage"></img>
</div> </div>
@ -76,6 +77,29 @@ if (typeof gamebook !== 'undefined') {
if (typeof gamebook !== 'undefined') { if (typeof gamebook !== 'undefined') {
gamebook.addSection(3, document.getElementById('section3')); gamebook.addSection(3, document.getElementById('section3'));
} }
</script><div class="section" id="section4">
<div class="sectionnumber" id="para4">4</div>
<div class="sectiontext">
Very good. <a class="sectionref enabledlink" data-ref="3"
href="#section3">You win</a>.
</div>
</div>
<script>
if (typeof gamebook !== 'undefined') {
gamebook.addSection(4, document.getElementById('section4'));
}
</script><div class="section" id="section5">
<div class="sectionnumber" id="para5">5</div>
<div class="sectiontext">
This is where you should end up when you follow the named reference from the starting section. From here you can go to <a class="sectionref enabledlink" data-ref="4"
href="#section4">the second named section</a> or to the <a class="sectionref enabledlink" data-ref="3"
href="#section3">good end</a>.
</div>
</div>
<script>
if (typeof gamebook !== 'undefined') {
gamebook.addSection(5, document.getElementById('section5'));
}
</script> <div id="counters" class="counters"> </script> <div id="counters" class="counters">
</div> </div>
<div id="counterTemplate" class="counterTemplate"> <div id="counterTemplate" class="counterTemplate">

View file

@ -30,7 +30,11 @@
\ \
\b \qc 1 \b \qc 1
\b0\ \b0\
\ql This examples tests gamebook formatting, not so much game mechanics or 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;. There should be an image below as well. If something broke, turn to \b 2 \ql This examples tests gamebook formatting, not so much game mechanics or 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;. You can make named references like this (
\b 5
\b0
)
(just happens to be exactly the same syntax as in emacs org-mode btw). There should be an image below as well. If something broke, turn to \b 2
\b0 \b0
, otherwise turn to \b 3 , otherwise turn to \b 3
\b0 \b0
@ -47,4 +51,26 @@
\ql Good! \ \ql Good! \
\ \
\b \qc 4
\b0\
\ql Very good. You win (
\b 3
\b0
)
. \
\
\b \qc 5
\b0\
\ql This is where you should end up when you follow the named reference from the starting section. From here you can go to the second named section (
\b 4
\b0
)
or to the good end (
\b 3
\b0
)
. \
\
} }

View file

@ -54,7 +54,8 @@ Adventure begins in section 1.
\subsection*{\begin{center} \textbf{1} \end{center}} \subsection*{\begin{center} \textbf{1} \end{center}}
\noindent \noindent
This examples tests gamebook formatting, not so much game mechanics or references. Currently there is nothing here really. This section contains some tricky characters to quote, like \} and \{ and " and ' and \textbackslash. HTML will probably not like <div> or \&boom;. There should be an image below as well. If something broke, turn to \textbf{\autoref{section2}}, otherwise turn to \textbf{\autoref{section3}}. \begin{center} This examples tests gamebook formatting, not so much game mechanics or references. Currently there is nothing here really. This section contains some tricky characters to quote, like \} and \{ and " and ' and \textbackslash. HTML will probably not like <div> or \&boom;. You can make named references like this (\textbf{\autoref{section5}})
(just happens to be exactly the same syntax as in emacs org-mode btw). There should be an image below as well. If something broke, turn to \textbf{\autoref{section2}}, otherwise turn to \textbf{\autoref{section3}}. \begin{center}
\includegraphics[width=.9\textwidth]{testimage.png} \includegraphics[width=.9\textwidth]{testimage.png}
\end{center} \end{center}
@ -76,5 +77,24 @@ Adventure begins in section 1.
\noindent \noindent
Good! Good!
\vspace{1em} \vspace{1em}
\phantomsection
\refstepcounter{sectionnr}
\label{section4}
\subsection*{\begin{center} \textbf{4} \end{center}}
\noindent
Very good. You win (\textbf{\autoref{section3}})
.
\vspace{1em}
\phantomsection
\refstepcounter{sectionnr}
\label{section5}
\subsection*{\begin{center} \textbf{5} \end{center}}
\noindent
This is where you should end up when you follow the named reference from the starting section. From here you can go to the second named section (\textbf{\autoref{section4}})
or to the good end (\textbf{\autoref{section3}})
.
\vspace{1em}
\refstepcounter{sectionnr} \refstepcounter{sectionnr}
\end{document} \end{document}

View file

@ -10,7 +10,7 @@ Another Heading
Adventure begins in section 1. Adventure begins in section 1.
1 1
This examples tests gamebook formatting, not so much game mechanics or 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;. There should be an image below as well. If something broke, turn to 2, otherwise turn to 3. This examples tests gamebook formatting, not so much game mechanics or 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;. You can make named references like this (5) (just happens to be exactly the same syntax as in emacs org-mode btw). There should be an image below as well. If something broke, turn to 2, otherwise turn to 3.
2 2
@ -19,3 +19,9 @@ Adventure begins in section 1.
3 3
Good! Good!
4
Very good. You win (3).
5
This is where you should end up when you follow the named reference from the starting section. From here you can go to the second named section (4) or to the good end (3).

View file

@ -2,7 +2,7 @@ BEGIN DEBUG OUTPUT
Book title: Gamebook Book title: Gamebook
Number of sections: 400 Number of sections: 400
Introduction Introduction
This gamebook demonstrates simple references between sections. Also notice that an intro section like this one can reference sections, like the start at 1 or the next section at 400. This gamebook demonstrates simple references between sections. Also notice that an intro section like this one can reference sections, like the start at 1 or the next section at 400. References can include an optional name that is used in some formats, so the same links could also be rendered as start (1) and next (400).
Turn to 1 to begin. Turn to 1 to begin.

View file

@ -23,7 +23,9 @@
<div class="introsectionbody"> <div class="introsectionbody">
This gamebook demonstrates simple references between sections. Also notice that an intro section like this one can reference sections, like the start at <a class="sectionref enabledlink" data-ref="1" This gamebook demonstrates simple references between sections. Also notice that an intro section like this one can reference sections, like the start at <a class="sectionref enabledlink" data-ref="1"
href="#section1">1</a> or the next section at <a class="sectionref enabledlink" data-ref="400" href="#section1">1</a> or the next section at <a class="sectionref enabledlink" data-ref="400"
href="#section400">400</a>. href="#section400">400</a>. References can include an optional name that is used in some formats, so the same links could also be rendered as <a class="sectionref enabledlink" data-ref="1"
href="#section1">start</a> and <a class="sectionref enabledlink" data-ref="400"
href="#section400">next</a>.
</div> </div>
</div> </div>

View file

@ -18,6 +18,14 @@
\b0 \b0
or the next section at \b 400 or the next section at \b 400
\b0 \b0
. References can include an optional name that is used in some formats, so the same links could also be rendered as start (
\b 1
\b0
)
and next (
\b 400
\b0
)
. \ . \
\ \

View file

@ -37,7 +37,9 @@
\noindent \noindent
This gamebook demonstrates simple references between sections. Also notice that an intro section like this one can reference sections, like the start at \textbf{\autoref{section1}} or the next section at \textbf{\autoref{section400}}. This gamebook demonstrates simple references between sections. Also notice that an intro section like this one can reference sections, like the start at \textbf{\autoref{section1}} or the next section at \textbf{\autoref{section400}}. References can include an optional name that is used in some formats, so the same links could also be rendered as start (\textbf{\autoref{section1}})
and next (\textbf{\autoref{section400}})
.
\vspace{1em} \vspace{1em}

View file

@ -1,7 +1,7 @@
Gamebook Gamebook
Introduction Introduction
This gamebook demonstrates simple references between sections. Also notice that an intro section like this one can reference sections, like the start at 1 or the next section at 400. This gamebook demonstrates simple references between sections. Also notice that an intro section like this one can reference sections, like the start at 1 or the next section at 400. References can include an optional name that is used in some formats, so the same links could also be rendered as start (1) and next (400).

View file

@ -10,9 +10,15 @@ 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): def __init__(self, templates, quote):
self.templates = templates self.templates = templates
self.quote = quote self.format_quote = quote
self.counter_names = {} self.counter_names = {}
def quote(self, s):
if s:
return self.format_quote(s)
else:
return ""
def format_begin(self, bookconfig): def format_begin(self, bookconfig):
# FIXME make sure book config is properly quoted # FIXME make sure book config is properly quoted
return self.format_with_template("begin", bookconfig) return self.format_with_template("begin", bookconfig)
@ -30,7 +36,8 @@ class OutputFormat (object):
refsdict = ReferenceFormatter(section.nr, refsdict = ReferenceFormatter(section.nr,
shuffled_sections.name_to_nr, shuffled_sections.name_to_nr,
shuffled_sections.missingto, shuffled_sections.missingto,
self.format_with_template("section_ref"), self.templates.get("section_ref"),
self.templates.get("named_section_ref"),
self.quote) self.quote)
formatted_text = self.format_section_body(section, refsdict) formatted_text = self.format_section_body(section, refsdict)
return self.format_with_template("introsection", { return self.format_with_template("introsection", {
@ -56,7 +63,8 @@ class OutputFormat (object):
refsdict = ReferenceFormatter(section.nr, refsdict = ReferenceFormatter(section.nr,
shuffled_sections.name_to_nr, shuffled_sections.name_to_nr,
shuffled_sections.missingto, shuffled_sections.missingto,
self.format_with_template("section_ref"), self.templates.get("section_ref"),
self.templates.get("named_section_ref"),
self.quote) self.quote)
formatted_text = self.format_section_body(section, refsdict) formatted_text = self.format_section_body(section, refsdict)
return self.format_with_template("section", { return self.format_with_template("section", {
@ -72,17 +80,24 @@ class OutputFormat (object):
while i < len(section.text): while i < len(section.text):
ref_start = section.text.find('[[', i) ref_start = section.text.find('[[', i)
tag_start = section.text.find('[', i) tag_start = section.text.find('[', i)
ref_name = None
if ref_start >= 0 and ref_start <= tag_start: if ref_start >= 0 and ref_start <= tag_start:
res += self.format_text(section.text[i:ref_start]) res += self.format_text(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_name_div_start = section.text.find('][',
ref_start, ref_end)
if ref_name_div_start > ref_start:
ref_name = section.text[ref_name_div_start+2:ref_end]
ref = section.text[ref_start+2:ref_name_div_start]
else:
ref = section.text[ref_start+2:ref_end]
splitref = ref.split() splitref = ref.split()
if len(splitref) > 1: if len(splitref) > 1:
for refmod in splitref[:-1]: for refmod in splitref[:-1]:
res += self.format_with_template(refmod, res += self.format_with_template(refmod,
references) references)
res += references[splitref[-1]] res += references.ref(splitref[-1], ref_name)
i = ref_end + 2 i = ref_end + 2
else: else:
raise Exception('Mismatched ref start [[ in section %s' % raise Exception('Mismatched ref start [[ in section %s' %
@ -144,26 +159,41 @@ 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, from_nr, name_to_nr, missingto, ref_template, quote): def __init__(self, from_nr, name_to_nr, missingto, ref_template,
named_ref_template, quote):
self.from_nr = from_nr self.from_nr = from_nr
self.name_to_nr = name_to_nr self.name_to_nr = name_to_nr
self.ref_template = ref_template self.ref_template = ref_template
self.named_ref_template = named_ref_template
self.items = {'nr' : from_nr} self.items = {'nr' : from_nr}
self.quote = quote self.quote = quote
self.missingto = missingto self.missingto = missingto
def get_to_nr(self, key):
if key in self.name_to_nr:
return self.name_to_nr[key]
else:
return self.name_to_nr[self.missingto]
def __getitem__(self, key): def __getitem__(self, key):
if key in self.items: if key in self.items:
return self.quote(self.items[key]) return self.quote(self.items[key])
if key in self.name_to_nr:
to_nr = self.name_to_nr[key]
else: else:
to_nr = self.name_to_nr[self.missingto] return self.ref_template % {
res = self.ref_template % { 'nr' : self.get_to_nr(key),
'nr' : to_nr,
'from_nr' : self.from_nr 'from_nr' : self.from_nr
}
def ref(self, key, name):
values = {
'nr' : self.get_to_nr(key),
'from_nr' : self.from_nr,
'name' : self.quote(name)
} }
return res if name:
return self.named_ref_template % values
else:
return self.ref_template % values
def __setitem__(self, key, value): def __setitem__(self, key, value):
self.items[key] = value self.items[key] = value

View file

@ -0,0 +1 @@
%(name)s (%(nr)d)

View file

@ -0,0 +1 @@
%(from_nr)d->%(nr)d

View file

@ -0,0 +1,2 @@
<a class="sectionref enabledlink" data-ref="%(nr)d"
href="#section%(nr)d">%(name)s</a>

View file

@ -0,0 +1,4 @@
%(name)s (
\b %(nr)d
\b0
)

View file

@ -0,0 +1 @@
%(name)s (\textbf{\autoref{section%(nr)d}})

View file

@ -0,0 +1 @@
%(name)s (%(nr)d)

View file

@ -31,22 +31,29 @@ class TestReferenceFormatter(TestCase):
pass pass
def test_create(self): def test_create(self):
rf = output.ReferenceFormatter(1, {}, None, "", str) rf = output.ReferenceFormatter(1, {}, None, "", "", str)
def test_get_item(self): def test_get_item(self):
rf = output.ReferenceFormatter(1, {'a' : 1, 'b' : 2}, None, rf = output.ReferenceFormatter(1, {'a' : 1, 'b' : 2}, None,
"%(nr)d", int) "%(nr)d", "", int)
self.assertEqual(rf['nr'], 1) self.assertEqual(rf['nr'], 1)
def test_get_quoted_item(self): def test_get_quoted_item(self):
rf = output.ReferenceFormatter(1, {'a' : 1, 'b' : 2}, None, rf = output.ReferenceFormatter(1, {'a' : 1, 'b' : 2}, None,
"%(nr)d", str) "%(nr)d", "", str)
self.assertEqual(rf['nr'], '1') self.assertEqual(rf['nr'], '1')
def test_get_reference(self): def test_get_reference(self):
rf = output.ReferenceFormatter(1, {'a' : 1, 'b' : 2}, None, rf = output.ReferenceFormatter(1, {'a' : 1, 'b' : 2}, None,
"%(from_nr)d to %(nr)d", None) "%(from_nr)d to %(nr)d", "", str)
self.assertEqual(rf['b'], '1 to 2') self.assertEqual(rf['b'], '1 to 2')
def test_get_named_reference(self):
rf = output.ReferenceFormatter(1, {'a' : 1, 'b' : 2}, None,
"%(from_nr)d to %(nr)d",
"%(from_nr)d to %(name)s(%(nr)d)", str)
self.assertEqual(rf.ref('b', 'name'), '1 to name(2)')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View file

@ -69,6 +69,8 @@
Implemented by adding cost to the old found tag (put cost tag after it). Implemented by adding cost to the old found tag (put cost tag after it).
Might reconsider and make explicit buy tag for clarity? Might reconsider and make explicit buy tag for clarity?
- [X] Add text template used for outputting non-tagged (plain) text. - [X] Add text template used for outputting non-tagged (plain) text.
- [X] Named references, when that style is wanted (especially for HTML).
- [ ] Seems to be a bug in rtf template, inserting image filename.
- [ ] Make debug output more useful with a stricter format easy to parse. - [ ] Make debug output more useful with a stricter format easy to parse.
- [ ] Add json output file containing sections, counters, collections etc. - [ ] Add json output file containing sections, counters, collections etc.
- [ ] Javascript GUI tests running in a browser - [ ] Javascript GUI tests running in a browser