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}
\end{center}
@@ -76,5 +77,24 @@ Adventure begins in section 1.
\noindent
Good!
\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}
\end{document}
diff --git a/expected/format.txt b/expected/format.txt
index 01f08f7..da0fd87 100644
--- a/expected/format.txt
+++ b/expected/format.txt
@@ -10,7 +10,7 @@ Another Heading
Adventure begins in section 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
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
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
@@ -19,3 +19,9 @@ Adventure begins in section 1.
3
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).
+
diff --git a/expected/references.debug b/expected/references.debug
index 0090867..544eeed 100644
--- a/expected/references.debug
+++ b/expected/references.debug
@@ -2,7 +2,7 @@ BEGIN DEBUG OUTPUT
Book title: Gamebook
Number of sections: 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 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.
diff --git a/expected/references.html b/expected/references.html
index a99a319..cb682e3 100644
--- a/expected/references.html
+++ b/expected/references.html
@@ -23,7 +23,9 @@
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.
+href="#section400">400. References can include an optional name that is used in some formats, so the same links could also be rendered as
start and
next.
diff --git a/expected/references.rtf b/expected/references.rtf
index d7c611f..e0cd3a7 100644
--- a/expected/references.rtf
+++ b/expected/references.rtf
@@ -18,6 +18,14 @@
\b0
or the next section at \b 400
\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
+)
. \
\
diff --git a/expected/references.tex b/expected/references.tex
index 4954441..0f3b24f 100644
--- a/expected/references.tex
+++ b/expected/references.tex
@@ -37,7 +37,9 @@
\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}
diff --git a/expected/references.txt b/expected/references.txt
index c5d6f88..aeda53e 100644
--- a/expected/references.txt
+++ b/expected/references.txt
@@ -1,7 +1,7 @@
Gamebook
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).
diff --git a/output.py b/output.py
index 725cf25..c4e6d56 100644
--- a/output.py
+++ b/output.py
@@ -10,9 +10,15 @@ class OutputFormat (object):
"Handles book output. Big FIXME required to make sense."
def __init__(self, templates, quote):
self.templates = templates
- self.quote = quote
+ self.format_quote = quote
self.counter_names = {}
+ def quote(self, s):
+ if s:
+ return self.format_quote(s)
+ else:
+ return ""
+
def format_begin(self, bookconfig):
# FIXME make sure book config is properly quoted
return self.format_with_template("begin", bookconfig)
@@ -30,7 +36,8 @@ class OutputFormat (object):
refsdict = ReferenceFormatter(section.nr,
shuffled_sections.name_to_nr,
shuffled_sections.missingto,
- self.format_with_template("section_ref"),
+ self.templates.get("section_ref"),
+ self.templates.get("named_section_ref"),
self.quote)
formatted_text = self.format_section_body(section, refsdict)
return self.format_with_template("introsection", {
@@ -56,7 +63,8 @@ class OutputFormat (object):
refsdict = ReferenceFormatter(section.nr,
shuffled_sections.name_to_nr,
shuffled_sections.missingto,
- self.format_with_template("section_ref"),
+ self.templates.get("section_ref"),
+ self.templates.get("named_section_ref"),
self.quote)
formatted_text = self.format_section_body(section, refsdict)
return self.format_with_template("section", {
@@ -72,17 +80,24 @@ class OutputFormat (object):
while i < len(section.text):
ref_start = section.text.find('[[', i)
tag_start = section.text.find('[', i)
+ ref_name = None
if ref_start >= 0 and ref_start <= tag_start:
res += self.format_text(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]
+ 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()
if len(splitref) > 1:
for refmod in splitref[:-1]:
res += self.format_with_template(refmod,
references)
- res += references[splitref[-1]]
+ res += references.ref(splitref[-1], ref_name)
i = ref_end + 2
else:
raise Exception('Mismatched ref start [[ in section %s' %
@@ -144,26 +159,41 @@ class OutputFormat (object):
class ReferenceFormatter (object):
"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.name_to_nr = name_to_nr
self.ref_template = ref_template
+ self.named_ref_template = named_ref_template
self.items = {'nr' : from_nr}
self.quote = quote
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):
if key in self.items:
return self.quote(self.items[key])
- if key in self.name_to_nr:
- to_nr = self.name_to_nr[key]
else:
- to_nr = self.name_to_nr[self.missingto]
- res = self.ref_template % {
- 'nr' : to_nr,
+ return self.ref_template % {
+ 'nr' : self.get_to_nr(key),
'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):
self.items[key] = value
diff --git a/templates/debug/named_section_ref.debug b/templates/debug/named_section_ref.debug
new file mode 100644
index 0000000..9b340b5
--- /dev/null
+++ b/templates/debug/named_section_ref.debug
@@ -0,0 +1 @@
+%(name)s (%(nr)d)
\ No newline at end of file
diff --git a/templates/dot/named_section_ref.dot b/templates/dot/named_section_ref.dot
new file mode 100644
index 0000000..06e47b1
--- /dev/null
+++ b/templates/dot/named_section_ref.dot
@@ -0,0 +1 @@
+%(from_nr)d->%(nr)d
diff --git a/templates/html/named_section_ref.html b/templates/html/named_section_ref.html
new file mode 100644
index 0000000..1c3f857
--- /dev/null
+++ b/templates/html/named_section_ref.html
@@ -0,0 +1,2 @@
+
%(name)s
\ No newline at end of file
diff --git a/templates/rtf/named_section_ref.rtf b/templates/rtf/named_section_ref.rtf
new file mode 100644
index 0000000..088599c
--- /dev/null
+++ b/templates/rtf/named_section_ref.rtf
@@ -0,0 +1,4 @@
+%(name)s (
+\b %(nr)d
+\b0
+)
diff --git a/templates/tex/named_section_ref.tex b/templates/tex/named_section_ref.tex
new file mode 100644
index 0000000..28f5e1d
--- /dev/null
+++ b/templates/tex/named_section_ref.tex
@@ -0,0 +1 @@
+%(name)s (\textbf{\autoref{section%(nr)d}})
diff --git a/templates/txt/named_section_ref.txt b/templates/txt/named_section_ref.txt
new file mode 100644
index 0000000..9b340b5
--- /dev/null
+++ b/templates/txt/named_section_ref.txt
@@ -0,0 +1 @@
+%(name)s (%(nr)d)
\ No newline at end of file
diff --git a/test_output.py b/test_output.py
index 2fdb434..58237c2 100755
--- a/test_output.py
+++ b/test_output.py
@@ -31,22 +31,29 @@ class TestReferenceFormatter(TestCase):
pass
def test_create(self):
- rf = output.ReferenceFormatter(1, {}, None, "", str)
+ rf = output.ReferenceFormatter(1, {}, None, "", "", str)
def test_get_item(self):
rf = output.ReferenceFormatter(1, {'a' : 1, 'b' : 2}, None,
- "%(nr)d", int)
+ "%(nr)d", "", int)
self.assertEqual(rf['nr'], 1)
def test_get_quoted_item(self):
rf = output.ReferenceFormatter(1, {'a' : 1, 'b' : 2}, None,
- "%(nr)d", str)
+ "%(nr)d", "", str)
self.assertEqual(rf['nr'], '1')
def test_get_reference(self):
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')
+ 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__':
unittest.main()
diff --git a/todo.org b/todo.org
index 4739196..e6628d5 100644
--- a/todo.org
+++ b/todo.org
@@ -69,6 +69,8 @@
Implemented by adding cost to the old found tag (put cost tag after it).
Might reconsider and make explicit buy tag for clarity?
- [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.
- [ ] Add json output file containing sections, counters, collections etc.
- [ ] Javascript GUI tests running in a browser