diff --git a/examples/withdemo.gamebook b/examples/withdemo.gamebook index 3d95723..b58d35e 100644 --- a/examples/withdemo.gamebook +++ b/examples/withdemo.gamebook @@ -10,6 +10,13 @@ Go on to [[demo1]] or [[demo2]] or [[notindemo1]]. * notindemo1 This section is not included in the demo. Turn to [[notindemo2]]. +* actuallynotindemoeither :demo:notthisone: +Tagged as demo, but excluded anyay because of the --exclude flag given. + +* notatall :notthisone: +Not included at all, because excluded by command-line, and not +demo-tagged either. + * demo1 :demo: This is the first demo section (not counting the start section). You can go on to the end at [[theend]]. diff --git a/examples/withdemo.gamebook.options b/examples/withdemo.gamebook.options index bedbae2..80f686c 100644 --- a/examples/withdemo.gamebook.options +++ b/examples/withdemo.gamebook.options @@ -1 +1 @@ ---include demo \ No newline at end of file +--include demo --exclude notthisone \ No newline at end of file diff --git a/examples/withoutdemo.gamebook b/examples/withoutdemo.gamebook index 094993b..b78a2bd 100644 --- a/examples/withoutdemo.gamebook +++ b/examples/withoutdemo.gamebook @@ -11,6 +11,13 @@ Go on to [[demo1]] or [[demo2]] or [[notindemo1]]. * notindemo1 This section is not included in the demo. Turn to [[notindemo2]]. +* actuallynotindemoeither :demo:notthisone: +Tagged as demo, but excluded anyay because of the --exclude flag given. + +* notatall :notthisone: +Not included at all, because excluded by command-line, and not +demo-tagged either. + * demo1 :demo: This is the first demo section (not counting the start section). You can go on to the end at [[theend]]. diff --git a/examples/withoutdemo.gamebook.options b/examples/withoutdemo.gamebook.options new file mode 100644 index 0000000..abb3120 --- /dev/null +++ b/examples/withoutdemo.gamebook.options @@ -0,0 +1 @@ + --exclude notthisone \ No newline at end of file diff --git a/formatgamebook.py b/formatgamebook.py index df32e33..7d9a8e8 100755 --- a/formatgamebook.py +++ b/formatgamebook.py @@ -68,10 +68,11 @@ def format_gamebook(inputfilenames, import_default_map_file, templatedirs, shuffle, - includetag, + includetags, + excludetags, mapfilenames): output_format = make_output(outputfilename, templatedirs) - book = sections.Book(make_bookid(outputfilename), includetag) + book = sections.Book(make_bookid(outputfilename), includetags, excludetags) for inputfilename in inputfilenames: parse_file_to_book(open(inputfilename, 'r'), book) if import_default_map_file: @@ -194,8 +195,10 @@ if __name__ == '__main__': help='input gamebook file (eg test.gamebook)') ap.add_argument('outputfile', metavar='outputfile', help='output file (eg test.tex or test.rtf)') - ap.add_argument('-i', '--include', action='store', metavar='T', - dest='includetag', help='only include sections with tag') + ap.add_argument('-i', '--include', action='append', metavar='T', + dest='includetags', help='only include sections with tag') + ap.add_argument('-e', '--exclude', action='append', metavar='T', + dest='excludetags', help='exclude sections with tag') ap.add_argument('-M', '--no-default-map', action='store_false', dest='import_default_map_file', help='ignore default map file') @@ -223,5 +226,6 @@ if __name__ == '__main__': args.import_default_map_file, templatedirs, args.shuffle, - args.includetag, + args.includetags or [], + args.excludetags or [], args.mapfiles or []) diff --git a/readme.org b/readme.org index 301aa72..13bff60 100644 --- a/readme.org +++ b/readme.org @@ -13,6 +13,7 @@ gamebook on paper or a screen (or for debugging it). : optional arguments: : -h, --help show this help message and exit : -i T, --include T only include sections with tag +: -e T, --exclude T exclude sections with tag : -M, --no-default-map ignore default map file : -t D, --template D add custom template dir : -o D, --option D add template override options dir diff --git a/sections.py b/sections.py index de0b841..e51f2c3 100644 --- a/sections.py +++ b/sections.py @@ -13,6 +13,9 @@ class Section: def hastag(self, tag): return tag in self.tags + def hastag_in_set(self, tags): + return not self.tags.isdisjoint(tags) + def __repr__(self): return "Section(%s, %s, %s)" % (repr(self.name), repr(self.text), repr(self.tags)) @@ -59,13 +62,14 @@ STR_BOOK_CONFIG = set(['id', 'title', 'author', 'starttext', 'hideintrotext', INT_BOOK_CONFIG = set(['max']) class Book: - def __init__(self, bookid='gamebook', includetag=None): + def __init__(self, bookid='gamebook', includetags=None, excludetags=None): self.sections = [] self.introsections = [] self.from_name = {} self.nr_sections = {} self.codewords = set() - self.includetag = includetag + self.includetags = set(includetags or []) + self.excludetags = set(excludetags or []) self.config = {'max' : 0, 'title' : 'Gamebook', 'author' : '', @@ -85,7 +89,9 @@ class Book: raise Exception("Unknown book option '%s'." % name) def add(self, section): - if self.includetag and not section.hastag(self.includetag): + if ((len(self.includetags) > 0 + and not section.hastag_in_set(self.includetags)) + or section.hastag_in_set(self.excludetags)): return if section.name in self.from_name: raise Exception('Duplicate section names (%s) not allowed.' % diff --git a/test_sections.py b/test_sections.py index 3188a4d..c7af940 100755 --- a/test_sections.py +++ b/test_sections.py @@ -36,14 +36,14 @@ class TestBook(TestCase): self.assertEqual(b.config['max'], 0) def test_includetag(self): - b = sections.Book(includetag='test') + b = sections.Book(includetags=['test']) sec = sections.Section("nnn", "text") sec.add_tags(['some', 'test', 'other']) b.add(sec) self.assertEqual(b.sections, [sec]) def test_excludetag(self): - b = sections.Book(includetag='test') + b = sections.Book(includetags=['test']) sec = sections.Section("nnn", "text") sec.add_tags(['some', 'other']) b.add(sec)