diff --git a/patacrep/content/__init__.py b/patacrep/content/__init__.py index a2268ee7..43192a00 100755 --- a/patacrep/content/__init__.py +++ b/patacrep/content/__init__.py @@ -232,8 +232,8 @@ def process_content(content, config=None): """Process content, and return a list of ContentItem() objects. Arguments are: - - content: the content field of the .sb file, which should be a list, and - describe what is to be included in the songbook; + - content: the content field of the .sb file, which should be an imbricated list + and describe what is to be included in the songbook; - config: the configuration dictionary of the current songbook. Return: a list of ContentItem objects, corresponding to the content to be @@ -245,21 +245,34 @@ def process_content(content, config=None): if not content: content = [["song"]] for elem in content: - if isinstance(elem, str): - elem = ["song", elem] - try: - match = keyword_re.match(elem[0]).groupdict() - except AttributeError: - contentlist.append_error(ContentError(elem[0], "Cannot parse content type.")) - continue - (keyword, argument) = (match['keyword'], match['argument']) - if keyword not in plugins: - contentlist.append_error(ContentError(keyword, "Unknown content type.")) - continue - contentlist.extend(plugins[keyword]( - keyword, - argument=argument, - contentlist=elem[1:], - config=config, - )) + if isinstance(elem, dict): + # new way + for keyword, argument in elem.items(): + if keyword not in plugins: + contentlist.append_error(ContentError(keyword, "Unknown content type.")) + continue + contentlist.extend(plugins[keyword]( + keyword, + argument=argument, + config=config, + )) + else: + # old way + if isinstance(elem, str): + elem = ["song", elem] + try: + match = keyword_re.match(elem[0]).groupdict() + except AttributeError: + contentlist.append_error(ContentError(elem[0], "Cannot parse content type.")) + continue + (keyword, argument) = (match['keyword'], match['argument']) + if keyword not in plugins: + contentlist.append_error(ContentError(keyword, "Unknown content type.")) + continue + contentlist.extend(plugins[keyword]( + keyword, + argument=argument, + contentlist=elem[1:], + config=config, + )) return contentlist diff --git a/patacrep/content/section.py b/patacrep/content/section.py index 6aed27c6..24a27640 100755 --- a/patacrep/content/section.py +++ b/patacrep/content/section.py @@ -23,35 +23,29 @@ class Section(ContentItem): self.short = short def render(self, __context): - if self.short is None: + if self.short is None or self.keyword not in KEYWORDS: return r'\{}{{{}}}'.format(self.keyword, self.name) else: return r'\{}[{}]{{{}}}'.format(self.keyword, self.short, self.name) #pylint: disable=unused-argument -def parse(keyword, argument, contentlist, config): +def parse(keyword, argument, config): """Parse the contentlist. Arguments: - keyword (one of "part", "chapter", "section", ... , "subparagraph", and their starred versions "part*", "chapter*", ... , "subparagraph*"): the section to use; - - argument: unused; - - contentlist: a list of one or two strings, which are the names (long - and short) of the section; + - argument: + either a string describing the section name + or a dict + name: Name of the section + short: Shortname of the section (only for non starred sections) - config: configuration dictionary of the current songbook. """ - try: - if (keyword not in KEYWORDS) and (len(contentlist) != 1): - raise ContentError( - keyword, - "Starred section names must have exactly one argument." - ) - if (len(contentlist) not in [1, 2]): - raise ContentError(keyword, "Section can have one or two arguments.") - return ContentList([Section(keyword, *contentlist)]) - except ContentError as error: - return EmptyContentList(errors=[error]) + if isinstance(argument, str): + argument = {'name': argument} + return ContentList([Section(keyword, **argument)]) CONTENT_PLUGINS = dict([ diff --git a/test/test_content/sections.source b/test/test_content/sections.source index 339815be..26ca63dc 100644 --- a/test/test_content/sections.source +++ b/test/test_content/sections.source @@ -1,6 +1,6 @@ -[["section", "Traditional"], - "exsong.sg", - ["section", "Example"], - "texsong.tsg", - "chordpro.csg", - "exsong.sg"] \ No newline at end of file +- section: Traditional +- "exsong.sg" +- section: Example +- "texsong.tsg" +- "chordpro.csg" +- "exsong.sg" \ No newline at end of file diff --git a/test/test_content/sections_short.source b/test/test_content/sections_short.source index fe70d510..8f6c0582 100644 --- a/test/test_content/sections_short.source +++ b/test/test_content/sections_short.source @@ -1,6 +1,8 @@ -[["section", "Traditional", "tradi"], - "exsong.sg", - ["section*", "Example"], - "texsong.tsg", - "chordpro.csg", - "exsong.sg"] \ No newline at end of file +- section: + name: Traditional + short: tradi +- "exsong.sg" +- section*: Example +- "texsong.tsg" +- "chordpro.csg" +- "exsong.sg" \ No newline at end of file diff --git a/test/test_content/test_content.py b/test/test_content/test_content.py index 23d498bc..e2a48496 100644 --- a/test/test_content/test_content.py +++ b/test/test_content/test_content.py @@ -5,7 +5,7 @@ import glob import os import unittest -import json +import yaml from patacrep.songs import DataSubpath from patacrep import content, files @@ -18,7 +18,7 @@ from .. import dynamic # pylint: disable=unused-import class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): """Test of the content plugins. - For any given `foo.source`, it parses the content as a json "content" + For any given `foo.source`, it parses the content as a yaml "content" argument of a .sb file. It controls that the generated file list is equal to the one in `foo.control`. """ @@ -51,7 +51,7 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): """Test that `base.source` produces the correct file list""" sourcename = "{}.source".format(base) with open(sourcename, mode="r", encoding="utf8") as sourcefile: - sbcontent = json.load(sourcefile) + sbcontent = yaml.load(sourcefile) with logging_reduced('patacrep.content.song'): expandedlist = content.process_content(sbcontent, cls.config.copy()) @@ -61,7 +61,7 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): if not os.path.exists(controlname): raise Exception("Missing control:" + str(sourcelist).replace("'", '"')) with open(controlname, mode="r", encoding="utf8") as controlfile: - controllist = json.load(controlfile) + controllist = yaml.load(controlfile) self.assertEqual(controllist, sourcelist) diff --git a/test/test_songbook/content.sb b/test/test_songbook/content.sb index 7e5ee2c8..d012cd0d 100644 --- a/test/test_songbook/content.sb +++ b/test/test_songbook/content.sb @@ -6,13 +6,12 @@ chords: repeatchords: no diagramreminder: all -content: [ - ["section", "Test of section"], - ["sorted"], - ["songsection", "Test of song section"], - ["cwd(content_datadir/content)", +content: + - section: Test of section + - ["sorted"] + - ["songsection", "Test of song section"] + - ["cwd(content_datadir/content)", "song.csg", "song.tsg", ["tex", "foo.tex"] - ], - ["include", "include.sbc"] - ] \ No newline at end of file + ] + - ["include", "include.sbc"] \ No newline at end of file diff --git a/test/test_songbook/content_datadir/songs/include.sbc b/test/test_songbook/content_datadir/songs/include.sbc index fefa39b1..16351055 100644 --- a/test/test_songbook/content_datadir/songs/include.sbc +++ b/test/test_songbook/content_datadir/songs/include.sbc @@ -1 +1 @@ -[["section", "This is an included section"]] +[{"section": "This is an included section"}]