From 5d42472385f991cbad66f178819eec2f4b2de890 Mon Sep 17 00:00:00 2001 From: Pelle Nilsson Date: Mon, 3 Jun 2013 21:57:55 +0200 Subject: [PATCH] Use term section instead of paragraph. Because it will become confusing later when there is support for sections split up in several paragraphs otherwise. --- formatgamebook.py | 10 +-- output.py | 34 ++++----- paragraphs.py | 61 --------------- readme.org | 4 +- sections.py | 61 +++++++++++++++ templates/debug/begin.debug | 2 +- .../debug/{paragraph.debug => section.debug} | 0 ...{paragraph_ref.debug => section_ref.debug} | 0 templates/dot/{paragraph.dot => section.dot} | 0 .../{paragraph_ref.dot => section_ref.dot} | 0 .../html/{paragraph.html => section.html} | 0 .../{paragraph_ref.html => section_ref.html} | 0 templates/rtf/{paragraph.rtf => section.rtf} | 0 .../{paragraph_ref.rtf => section_ref.rtf} | 0 templates/tex/{paragraph.tex => section.tex} | 0 .../{paragraph_ref.tex => section_ref.tex} | 0 test.gamebook | 6 +- test_paragraphs.py | 76 ------------------- test_sections.py | 76 +++++++++++++++++++ todo.org | 13 ++-- 20 files changed, 171 insertions(+), 172 deletions(-) delete mode 100644 paragraphs.py create mode 100644 sections.py rename templates/debug/{paragraph.debug => section.debug} (100%) rename templates/debug/{paragraph_ref.debug => section_ref.debug} (100%) rename templates/dot/{paragraph.dot => section.dot} (100%) rename templates/dot/{paragraph_ref.dot => section_ref.dot} (100%) rename templates/html/{paragraph.html => section.html} (100%) rename templates/html/{paragraph_ref.html => section_ref.html} (100%) rename templates/rtf/{paragraph.rtf => section.rtf} (100%) rename templates/rtf/{paragraph_ref.rtf => section_ref.rtf} (100%) rename templates/tex/{paragraph.tex => section.tex} (100%) rename templates/tex/{paragraph_ref.tex => section_ref.tex} (100%) delete mode 100755 test_paragraphs.py create mode 100755 test_sections.py diff --git a/formatgamebook.py b/formatgamebook.py index 421c151..93868f2 100755 --- a/formatgamebook.py +++ b/formatgamebook.py @@ -33,7 +33,7 @@ import os.path import sys import json -import paragraphs +import sections from output import OutputFormat from latex import LatexFormat @@ -57,7 +57,7 @@ def make_supported_formats_list_string(): def format_gamebook(inputfilenames, outputfilename): output_format = find_output_format(outputfilename) - book = paragraphs.Book() + book = sections.Book() for inputfilename in inputfilenames: parse_file_to_book(open(inputfilename, 'r'), book) output_format.write(book, open(outputfilename, 'w')) @@ -69,7 +69,7 @@ def parse_file_to_book(inputfile, book): for line in inputfile.readlines(): if line.startswith('*'): if name: - book.add(paragraphs.Paragraph(name, text), number) + book.add(sections.Section(name, text), number) number = None text = "" heading = line[1:].strip().split(' ') @@ -79,11 +79,11 @@ def parse_file_to_book(inputfile, book): number = int(heading[0]) name = heading[1] else: - raise Exception("bad paragraph heading %s" % str(heading)) + raise Exception("bad section heading %s" % str(heading)) else: text = text + " " + line.strip() if name: - book.add(paragraphs.Paragraph(name, text), number) + book.add(sections.Section(name, text), number) def find_output_format(outputfilename): for of in OUTPUT_FORMATS: diff --git a/output.py b/output.py index bb53a94..e5d3b1b 100644 --- a/output.py +++ b/output.py @@ -13,7 +13,7 @@ class OutputFormat (object): def write(self, book, output): self.write_begin(book, output) - self.write_shuffled_paragraphs(book.shuffle(), output) + self.write_shuffled_sections(book.shuffle(), output) self.write_end(book, output) def write_begin(self, book, output): @@ -21,17 +21,17 @@ class OutputFormat (object): 'max' : book.max }, - def write_shuffled_paragraphs(self, shuffled_paragraphs, output): - for p in shuffled_paragraphs.as_list[1:]: - self.write_paragraph(p, shuffled_paragraphs, output) + def write_shuffled_sections(self, shuffled_sections, output): + for p in shuffled_sections.as_list[1:]: + self.write_section(p, shuffled_sections, output) - def write_paragraph(self, paragraph, shuffled_paragraphs, output): + def write_section(self, section, shuffled_sections, output): refs = [] - refsdict = ReferenceFormatter(paragraph, shuffled_paragraphs, - self.load_template("paragraph_ref")) - formatted_text = paragraph.format(refsdict) - print >> output, self.load_template("paragraph") % { - 'nr' : shuffled_paragraphs.to_nr[paragraph], + refsdict = ReferenceFormatter(section, shuffled_sections, + self.load_template("section_ref")) + formatted_text = section.format(refsdict) + print >> output, self.load_template("section") % { + 'nr' : shuffled_sections.to_nr[section], 'text' : formatted_text, 'refs' : '\n'.join(refsdict.getfound()) # hack for DOT output }, @@ -58,19 +58,19 @@ class OutputFormat (object): class ReferenceFormatter (object): "There is probably a better way, but this hack seems to work." - def __init__(self, paragraph, shuffled_paragraphs, ref_template): - self.paragraph = paragraph - self.shuffled_paragraphs = shuffled_paragraphs + def __init__(self, section, shuffled_sections, ref_template): + self.section = section + self.shuffled_sections = shuffled_sections self.found = set() self.ref_template = ref_template def __getitem__(self, key): - to_paragraph = self.shuffled_paragraphs.from_name[key] + to_section = self.shuffled_sections.from_name[key] res = self.ref_template % { - 'nr' : self.shuffled_paragraphs.to_nr[to_paragraph], - 'from_nr' : self.shuffled_paragraphs.to_nr[self.paragraph] + 'nr' : self.shuffled_sections.to_nr[to_section], + 'from_nr' : self.shuffled_sections.to_nr[self.section] } - if key in self.shuffled_paragraphs.name_to_nr: + if key in self.shuffled_sections.name_to_nr: self.found.add(res) return res diff --git a/paragraphs.py b/paragraphs.py deleted file mode 100644 index 0512932..0000000 --- a/paragraphs.py +++ /dev/null @@ -1,61 +0,0 @@ -import random -import sys - -class Paragraph: - def __init__(self, name, text): - self.name = name - self.text = text - - def __repr__(self): - return "Paragraph(%s, %s)" % (repr(self.name), repr(self.text)) - - def format(self, references): - return self.text % references - -class ShuffledParagraphs: - def __init__(self, as_list, from_nr, to_nr, from_name): - self.as_list = as_list - self.from_nr = from_nr - self.to_nr = to_nr - self.from_name = from_name - self.name_to_nr = {} - for n in from_name: - self.name_to_nr[n] = to_nr[from_name[n]] - -class Book: - def __init__(self): - self.paragraphs = [] - self.nr_paragraphs = {} - self.max = 0 - - def add(self, paragraph, nr=None): - self.paragraphs.append(paragraph) - if len(self.paragraphs) > self.max: - self.max = len(self.paragraphs) - if nr: - self.nr_paragraphs[nr] = paragraph - if nr > self.max: - self.max = nr - - def shuffle(self): - as_list = [None] - from_nr = {} - to_nr = {} - from_name = {} - shuffled = self.paragraphs[:] - for p in self.nr_paragraphs.values(): - shuffled.remove(p) - random.shuffle(shuffled) - for nr in range(1, self.max + 1): - if self.nr_paragraphs.has_key(nr): - paragraph = self.nr_paragraphs[nr] - elif len(shuffled): - paragraph = shuffled.pop() - else: - paragraph = None - as_list.append(paragraph) - from_nr[nr] = paragraph - if paragraph: - to_nr[paragraph] = nr - from_name[paragraph.name] = paragraph - return ShuffledParagraphs(as_list, from_nr, to_nr, from_name) diff --git a/readme.org b/readme.org index e4c6733..80ec91a 100644 --- a/readme.org +++ b/readme.org @@ -9,7 +9,7 @@ gamebook on paper or a screen (or for debugging it). |------------------+-----------+-------------------------------------------------------------------------------------------------| | LaTeX | .tex | Useful to generate PDFs using pdflatex or whatever LaTeX tools you prefer. | | Rich Text Format | .rtf | Supported because the Windhammer Prize requires it. | -| Graphviz DOT | .dot | Use with the Graphviz dot tool to generate a flowchart graph of all paragraphs in the gamebook. | +| Graphviz DOT | .dot | Use with the Graphviz dot tool to generate a flowchart graph of all sections in the gamebook. | | HTML | .html | Play gamebook in browser. | | Debug Plain Text | .debug | Plain text debug output of gamebook contents. | @@ -18,7 +18,7 @@ More to be added. ** Gamebook Format The input file expected by the formatgamebook.py script must be in a -format containing information about all paragraphs in the book +format containing information about all sections in the book plus some optional metadata. The format should (when TBD) be documented here, but it is not expected that most users would ever have to look at the gamebook file, but rather use a higher level format or a diff --git a/sections.py b/sections.py new file mode 100644 index 0000000..c8d2875 --- /dev/null +++ b/sections.py @@ -0,0 +1,61 @@ +import random +import sys + +class Section: + def __init__(self, name, text): + self.name = name + self.text = text + + def __repr__(self): + return "Section(%s, %s)" % (repr(self.name), repr(self.text)) + + def format(self, references): + return self.text % references + +class ShuffledSections: + def __init__(self, as_list, from_nr, to_nr, from_name): + self.as_list = as_list + self.from_nr = from_nr + self.to_nr = to_nr + self.from_name = from_name + self.name_to_nr = {} + for n in from_name: + self.name_to_nr[n] = to_nr[from_name[n]] + +class Book: + def __init__(self): + self.sections = [] + self.nr_sections = {} + self.max = 0 + + def add(self, section, nr=None): + self.sections.append(section) + if len(self.sections) > self.max: + self.max = len(self.sections) + if nr: + self.nr_sections[nr] = section + if nr > self.max: + self.max = nr + + def shuffle(self): + as_list = [None] + from_nr = {} + to_nr = {} + from_name = {} + shuffled = self.sections[:] + for p in self.nr_sections.values(): + shuffled.remove(p) + random.shuffle(shuffled) + for nr in range(1, self.max + 1): + if self.nr_sections.has_key(nr): + section = self.nr_sections[nr] + elif len(shuffled): + section = shuffled.pop() + else: + section = None + as_list.append(section) + from_nr[nr] = section + if section: + to_nr[section] = nr + from_name[section.name] = section + return ShuffledSections(as_list, from_nr, to_nr, from_name) diff --git a/templates/debug/begin.debug b/templates/debug/begin.debug index 0814207..f71aca8 100644 --- a/templates/debug/begin.debug +++ b/templates/debug/begin.debug @@ -1,2 +1,2 @@ BEGIN DEBUG OUTPUT -Number of paragraphs: %(max)d +Number of sections: %(max)d diff --git a/templates/debug/paragraph.debug b/templates/debug/section.debug similarity index 100% rename from templates/debug/paragraph.debug rename to templates/debug/section.debug diff --git a/templates/debug/paragraph_ref.debug b/templates/debug/section_ref.debug similarity index 100% rename from templates/debug/paragraph_ref.debug rename to templates/debug/section_ref.debug diff --git a/templates/dot/paragraph.dot b/templates/dot/section.dot similarity index 100% rename from templates/dot/paragraph.dot rename to templates/dot/section.dot diff --git a/templates/dot/paragraph_ref.dot b/templates/dot/section_ref.dot similarity index 100% rename from templates/dot/paragraph_ref.dot rename to templates/dot/section_ref.dot diff --git a/templates/html/paragraph.html b/templates/html/section.html similarity index 100% rename from templates/html/paragraph.html rename to templates/html/section.html diff --git a/templates/html/paragraph_ref.html b/templates/html/section_ref.html similarity index 100% rename from templates/html/paragraph_ref.html rename to templates/html/section_ref.html diff --git a/templates/rtf/paragraph.rtf b/templates/rtf/section.rtf similarity index 100% rename from templates/rtf/paragraph.rtf rename to templates/rtf/section.rtf diff --git a/templates/rtf/paragraph_ref.rtf b/templates/rtf/section_ref.rtf similarity index 100% rename from templates/rtf/paragraph_ref.rtf rename to templates/rtf/section_ref.rtf diff --git a/templates/tex/paragraph.tex b/templates/tex/section.tex similarity index 100% rename from templates/tex/paragraph.tex rename to templates/tex/section.tex diff --git a/templates/tex/paragraph_ref.tex b/templates/tex/section_ref.tex similarity index 100% rename from templates/tex/paragraph_ref.tex rename to templates/tex/section_ref.tex diff --git a/test.gamebook b/test.gamebook index 0a116f6..4599d83 100644 --- a/test.gamebook +++ b/test.gamebook @@ -1,12 +1,12 @@ *1 start This is where the adventure begins. You can go on to the -next paragraph, see %(next)s or try the other instead, see %(other)s. +next section, see %(next)s or try the other instead, see %(other)s. *next -This is the next paragraph. Go on to the end at %(end)s. +This is the next section. Go on to the end at %(end)s. *other -This is another paragraph. You can try the next paragraph now, +This is another section. You can try the next section now, see %(next)s, or go on to the end, see %(end)s. *end diff --git a/test_paragraphs.py b/test_paragraphs.py deleted file mode 100755 index cd136ca..0000000 --- a/test_paragraphs.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python2.5 - -import unittest -from unittest import TestCase - -import paragraphs - -class TestParagraph(TestCase): - def setUp(self): - pass - - def test_create(self): - p = paragraphs.Paragraph("foo") - self.assertEqual(p.name, "foo") - -class TestBook(TestCase): - def setUp(self): - pass - - def test_create(self): - g = paragraphs.Book() - self.assertEqual(g.paragraphs, []) - self.assertEqual(g.nr_paragraphs, {}) - self.assertEqual(g.max, 0) - - def test_old_big_mess(self): - """This was tested using print statements in the old - paragraphs __main__. Not pretty. Keeping it here anyway - as long as it doesn't cause too many problems to update.""" - from paragraphs import paragraph_refs_format - g = paragraphs.Book() - c = paragraphs.Paragraph("c", "aaac") - g.add(paragraphs.Paragraph("a", "aaa")) - g.add(paragraphs.Paragraph("b", "aaab")) - g.add(c) - g.add(paragraphs.Paragraph("d", "aaad"), 22) - g.add(paragraphs.Paragraph("e", "aaae"), 1) - g.add(paragraphs.Paragraph("f", "aaaf", - [paragraphs.ParagraphItem("fff")])) - g.add(paragraphs.Paragraph("g", "aaag", - [paragraphs.ParagraphItem("ggg", "G")])) - m = paragraphs.Paragraph("m") - m.addtext("m") - m.addtext("t") - g.add(m) - shuffled = g.shuffle() - - self.assertEqual(len(shuffled.as_list), 23) - self.assertEqual(paragraph_refs_format('abc', []), 'abc') - self.assertEqual(paragraph_refs_format('abc%%z', []), 'abc%z') - self.assertEqual(paragraph_refs_format( - 'abc%sx', - [paragraphs.Paragraph("p1", "111")]), - 'abcp1x') - self.assertEqual(paragraph_refs_format( - 'abc%ry', [paragraphs.Paragraph("p2", "222")]), - "abc'p2'y") - self.assertEqual(paragraph_refs_format('%%a%nbc%su', ["f", c], - shuffled), - '%%a%dbccu' % shuffled.name_to_nr["f"]) - self.assertEqual(paragraph_refs_format('abc%nu', ["c"], shuffled), - 'abc%du' % shuffled.name_to_nr["c"]) - self.assertEqual(paragraph_refs_format('%s', [m]), - 'm') - self.assertEqual(m.text, 'mt') - - def test_name_replace(self): - game = paragraphs.Book() - game.add(paragraphs.Paragraph('foo')) - shuffled = game.shuffle() - self.assertEqual( - 'a1b', - paragraphs.paragraph_refs_format('a%(foo)nb', [], shuffled)) - -if __name__ == '__main__': - unittest.main() diff --git a/test_sections.py b/test_sections.py new file mode 100755 index 0000000..aafb07e --- /dev/null +++ b/test_sections.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python2.5 + +import unittest +from unittest import TestCase + +import sections + +class TestSection(TestCase): + def setUp(self): + pass + + def test_create(self): + p = sections.Section("foo") + self.assertEqual(p.name, "foo") + +class TestBook(TestCase): + def setUp(self): + pass + + def test_create(self): + g = sections.Book() + self.assertEqual(g.sections, []) + self.assertEqual(g.nr_sections, {}) + self.assertEqual(g.max, 0) + + def test_old_big_mess(self): + """This was tested using print statements in the old + sections __main__. Not pretty. Keeping it here anyway + as long as it doesn't cause too many problems to update.""" + from sections import section_refs_format + g = sections.Book() + c = sections.Section("c", "aaac") + g.add(sections.Section("a", "aaa")) + g.add(sections.Section("b", "aaab")) + g.add(c) + g.add(sections.Section("d", "aaad"), 22) + g.add(sections.Section("e", "aaae"), 1) + g.add(sections.Section("f", "aaaf", + [sections.SectionItem("fff")])) + g.add(sections.Section("g", "aaag", + [sections.SectionItem("ggg", "G")])) + m = sections.Section("m") + m.addtext("m") + m.addtext("t") + g.add(m) + shuffled = g.shuffle() + + self.assertEqual(len(shuffled.as_list), 23) + self.assertEqual(section_refs_format('abc', []), 'abc') + self.assertEqual(section_refs_format('abc%%z', []), 'abc%z') + self.assertEqual(section_refs_format( + 'abc%sx', + [sections.Section("p1", "111")]), + 'abcp1x') + self.assertEqual(section_refs_format( + 'abc%ry', [sections.Section("p2", "222")]), + "abc'p2'y") + self.assertEqual(section_refs_format('%%a%nbc%su', ["f", c], + shuffled), + '%%a%dbccu' % shuffled.name_to_nr["f"]) + self.assertEqual(section_refs_format('abc%nu', ["c"], shuffled), + 'abc%du' % shuffled.name_to_nr["c"]) + self.assertEqual(section_refs_format('%s', [m]), + 'm') + self.assertEqual(m.text, 'mt') + + def test_name_replace(self): + game = sections.Book() + game.add(sections.Section('foo')) + shuffled = game.shuffle() + self.assertEqual( + 'a1b', + sections.section_refs_format('a%(foo)nb', [], shuffled)) + +if __name__ == '__main__': + unittest.main() diff --git a/todo.org b/todo.org index 2c2528b..626621c 100644 --- a/todo.org +++ b/todo.org @@ -4,20 +4,19 @@ - [X] LaTeX output - [X] RTF output - [X] HTML output -- [ ] Save paragraph-number mapping and reuse automatically -- [ ] Add support for custom begin/end document templates. +- [ ] Save section-number mapping and reuse automatically +- [ ] Add support for custom document templates. Fixed names and/or command-line options. -- [ ] Add paragraph links in LaTeX output. +- [ ] Add section links in LaTeX output. - [ ] Debug HTML output - [ ] Inventory (take, drop, check) - [ ] Codewords/Sightings (set, check, clean) -- [ ] Skill checks? Or is this higher level? No? -- [ ] More formatting possibilities in paragraphs +- [ ] More formatting possibilities in sections Look at existing gamebooks to get ideas. - [ ] Prettier LaTeX output Look at how some existing gamebooks are formatted. -- [ ] Command-line flag to set max paragraph number to use -- [ ] Dummy paragraphs +- [ ] Command-line flag to set max section number to use +- [ ] Dummy sections - [ ] Combat? Or is this higher level? - [ ] Document Gamebook JSON format. - [ ] Higher level text-language for Gamebooks