From e5723bdf708ad5c389a1934325c10703d9d85333 Mon Sep 17 00:00:00 2001 From: Pelle Nilsson Date: Sun, 28 Jul 2013 18:45:02 +0200 Subject: [PATCH] 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. --- examples/format.gamebook | 11 +++++ examples/references.gamebook | 4 +- expected/format.debug | 8 ++-- expected/format.dot | 6 ++- expected/format.html | 26 +++++++++++- expected/format.rtf | 28 ++++++++++++- expected/format.tex | 22 +++++++++- expected/format.txt | 8 +++- expected/references.debug | 2 +- expected/references.html | 4 +- expected/references.rtf | 8 ++++ expected/references.tex | 4 +- expected/references.txt | 2 +- output.py | 54 +++++++++++++++++++------ templates/debug/named_section_ref.debug | 1 + templates/dot/named_section_ref.dot | 1 + templates/html/named_section_ref.html | 2 + templates/rtf/named_section_ref.rtf | 4 ++ templates/tex/named_section_ref.tex | 1 + templates/txt/named_section_ref.txt | 1 + test_output.py | 15 +++++-- todo.org | 2 + 22 files changed, 185 insertions(+), 29 deletions(-) create mode 100644 templates/debug/named_section_ref.debug create mode 100644 templates/dot/named_section_ref.dot create mode 100644 templates/html/named_section_ref.html create mode 100644 templates/rtf/named_section_ref.rtf create mode 100644 templates/tex/named_section_ref.tex create mode 100644 templates/txt/named_section_ref.txt diff --git a/examples/format.gamebook b/examples/format.gamebook index 809cd77..3f43c6f 100644 --- a/examples/format.gamebook +++ b/examples/format.gamebook @@ -19,6 +19,8 @@ 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 [[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. If something broke, turn to [[bad]], otherwise turn to [[good]]. @@ -28,6 +30,15 @@ otherwise turn to [[good]]. Sections tagged as dummy will not be 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! diff --git a/examples/references.gamebook b/examples/references.gamebook index 571a70f..ab16bf4 100644 --- a/examples/references.gamebook +++ b/examples/references.gamebook @@ -4,7 +4,9 @@ max = 400 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]]. +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 This is where the adventure begins. You can go on to the diff --git a/expected/format.debug b/expected/format.debug index 360d5be..63b57fa 100644 --- a/expected/format.debug +++ b/expected/format.debug @@ -1,6 +1,6 @@ BEGIN DEBUG OUTPUT Book title: Format -Number of sections: 4 +Number of sections: 6 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 @@ -8,8 +8,10 @@ Another Heading 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
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
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. 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 diff --git a/expected/format.dot b/expected/format.dot index cbbe68a..1100443 100644 --- a/expected/format.dot +++ b/expected/format.dot @@ -1,6 +1,10 @@ digraph gamebook { - 1->2 + 1->5 +1->2 1->3 +4->3 +5->4 +5->3 } diff --git a/expected/format.html b/expected/format.html index 3988542..19cce31 100644 --- a/expected/format.html +++ b/expected/format.html @@ -47,7 +47,8 @@
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 like this (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.
@@ -76,6 +77,29 @@ if (typeof gamebook !== 'undefined') { if (typeof gamebook !== 'undefined') { gamebook.addSection(3, document.getElementById('section3')); } +
+
4
+
+ Very good. You win. +
+
+
+
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 or to the good end. +
+
+
diff --git a/expected/format.rtf b/expected/format.rtf index e2458c7..a9ee5d7 100644 --- a/expected/format.rtf +++ b/expected/format.rtf @@ -30,7 +30,11 @@ \ \b \qc 1 \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
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
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 , otherwise turn to \b 3 \b0 @@ -47,4 +51,26 @@ \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 +) +. \ +\ + } diff --git a/expected/format.tex b/expected/format.tex index df9f3bc..b1dc065 100644 --- a/expected/format.tex +++ b/expected/format.tex @@ -54,7 +54,8 @@ Adventure begins in section 1. \subsection*{\begin{center} \textbf{1} \end{center}} \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
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
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