From 177940f7ecac8083231435e823056b3e3abcb7bf Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sun, 26 Jun 2016 17:21:53 +0200 Subject: [PATCH 01/10] _config does not need to be attached to self --- patacrep/build.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/patacrep/build.py b/patacrep/build.py index 15a4ca78..9e0428af 100644 --- a/patacrep/build.py +++ b/patacrep/build.py @@ -60,44 +60,44 @@ class Songbook: - output: a file object, in which the file will be written. """ # Updating configuration - self._config = self._raw_config.copy() + tex_config = self._raw_config.copy() renderer = TexBookRenderer( - self._config['book']['template'], - self._config['_datadir'], - self._config['book']['lang'], - self._config['book']['encoding'], + tex_config['book']['template'], + tex_config['_datadir'], + tex_config['book']['lang'], + tex_config['book']['encoding'], ) try: - self._config['_template'] = renderer.get_all_variables(self._config.get('template', {})) + tex_config['_template'] = renderer.get_all_variables(tex_config.get('template', {})) except errors.SchemaError as exception: exception.message = "The songbook file '{}' is not valid\n{}".format( self.basename, exception.message) raise exception - self._config['_compiled_authwords'] = authors.compile_authwords( - copy.deepcopy(self._config['authors']) + tex_config['_compiled_authwords'] = authors.compile_authwords( + copy.deepcopy(tex_config['authors']) ) # Configuration set - self._config['render'] = content.render - self._config['content'] = content.process_content( - self._config.get('content', []), - self._config, + tex_config['render'] = content.render + tex_config['content'] = content.process_content( + tex_config.get('content', []), + tex_config, ) - self._config['filename'] = output.name[:-4] + tex_config['filename'] = output.name[:-4] # Processing special options - self._config['_bookoptions'] = iter_bookoptions(self._config) - self._config['chords']['_notenames'] = self._get_chord_names( - self._config['chords']['notation'] + tex_config['_bookoptions'] = iter_bookoptions(tex_config) + tex_config['chords']['_notenames'] = self._get_chord_names( + tex_config['chords']['notation'] ) - renderer.render_tex(output, self._config) + renderer.render_tex(output, tex_config) # Get all errors, and maybe exit program self._errors.extend(renderer.errors) - if self._config['_error'] == "failonbook": + if tex_config['_error'] == "failonbook": if self.has_errors(): raise errors.SongbookError("Some songs contain errors. Stopping as requested.") From fe99f1bc03bd75e7b6bef0b6bdf5bce1b652b024 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sun, 26 Jun 2016 17:42:41 +0200 Subject: [PATCH 02/10] add a method to get the songbook content items --- patacrep/build.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/patacrep/build.py b/patacrep/build.py index 9e0428af..87bb7a7f 100644 --- a/patacrep/build.py +++ b/patacrep/build.py @@ -53,6 +53,19 @@ class Songbook: self._errors = list() self._config = dict() + def get_content_items(self): + """Return: a list of ContentItem objects, corresponding to the content to be + included in the .tex file. + """ + content_config = self._raw_config.copy() + # Updates the '_langs' key + content_items = content.process_content( + content_config.get('content', []), + content_config, + ) + content_langs = content_config['_langs'] + return content_langs, content_items + def write_tex(self, output): """Build the '.tex' file corresponding to self. @@ -81,10 +94,7 @@ class Songbook: # Configuration set tex_config['render'] = content.render - tex_config['content'] = content.process_content( - tex_config.get('content', []), - tex_config, - ) + tex_config['_langs'], tex_config['content'] = self.get_content_items() tex_config['filename'] = output.name[:-4] # Processing special options From ffbd77928589b2e6ac23280936e22e615cb7b3c3 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sun, 26 Jun 2016 17:49:21 +0200 Subject: [PATCH 03/10] Add a command to get a flattened list of the item --- NEWS.md | 3 ++ patacrep/content/__init__.py | 4 ++ patacrep/content/section.py | 6 +++ patacrep/content/setcounter.py | 3 ++ patacrep/content/song.py | 3 ++ patacrep/content/songsection.py | 3 ++ patacrep/content/tex.py | 3 ++ patacrep/songs/__init__.py | 2 +- patacrep/tools/content/__init__.py | 0 patacrep/tools/content/__main__.py | 76 ++++++++++++++++++++++++++++++ 10 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 patacrep/tools/content/__init__.py create mode 100644 patacrep/tools/content/__main__.py diff --git a/NEWS.md b/NEWS.md index 1bb8b80a..1966a401 100644 --- a/NEWS.md +++ b/NEWS.md @@ -19,6 +19,9 @@ * LaTeX songs * The `meta` directive is now supported: `\metacrep{COMMANDNAME}{arg}` [#220](https://github.com/patacrep/patacrep/pull/220) * Faster index generation [#233](https://github.com/patacrep/patacrep/pull/233) + * Patatools + * New command to generate the list of the content items (songs, sections...): `patatools content items ` [#232](https://github.com/patacrep/patacrep/pull/232) + # patacrep 5.0.0 diff --git a/patacrep/content/__init__.py b/patacrep/content/__init__.py index 5acc2aae..3edc0cf3 100755 --- a/patacrep/content/__init__.py +++ b/patacrep/content/__init__.py @@ -116,6 +116,10 @@ class ContentItem: """Return the string to end a block.""" return "" + def file_entry(self): + """Return the dict representation (as in the yaml file).""" + raise NotImplementedError() + class ContentError(SharedError): """Error in a content plugin.""" def __init__(self, keyword=None, message=None): diff --git a/patacrep/content/section.py b/patacrep/content/section.py index 316b0fa3..403e2072 100755 --- a/patacrep/content/section.py +++ b/patacrep/content/section.py @@ -28,6 +28,12 @@ class Section(ContentItem): else: return r'\{}[{}]{{{}}}'.format(self.keyword, self.short, self.name) + def file_entry(self): + if self.short is None or self.keyword not in KEYWORDS: + return {self.keyword: self.name} + else: + return {self.keyword: {'name': self.name, 'short': self.short}} + #pylint: disable=unused-argument @validate_parser_argument(""" type: //any diff --git a/patacrep/content/setcounter.py b/patacrep/content/setcounter.py index 41729b52..0b20b223 100755 --- a/patacrep/content/setcounter.py +++ b/patacrep/content/setcounter.py @@ -14,6 +14,9 @@ class CounterSetter(ContentItem): """Set the value of the counter.""" return r'\setcounter{{{}}}{{{}}}'.format(self.name, self.value) + def file_entry(self): + return {'setcounter': {'name': self.name, 'value': self.value}} + #pylint: disable=unused-argument @validate_parser_argument(""" type: //any diff --git a/patacrep/content/song.py b/patacrep/content/song.py index 3063a700..73ace8cf 100755 --- a/patacrep/content/song.py +++ b/patacrep/content/song.py @@ -63,6 +63,9 @@ class SongRenderer(ContentItem): """Order by song path""" return self.song.fullpath < other.song.fullpath + def file_entry(self): + return {'song': self.song.fullpath} + #pylint: disable=unused-argument #pylint: disable=too-many-branches @validate_parser_argument(""" diff --git a/patacrep/content/songsection.py b/patacrep/content/songsection.py index abc9d609..57d4e5e7 100755 --- a/patacrep/content/songsection.py +++ b/patacrep/content/songsection.py @@ -19,6 +19,9 @@ class SongSection(ContentItem): """Render this section or chapter.""" return r'\{}{{{}}}'.format(self.keyword, self.name) + def file_entry(self): + return {self.keyword: self.name} + #pylint: disable=unused-argument @validate_parser_argument(""" //str diff --git a/patacrep/content/tex.py b/patacrep/content/tex.py index b00f3539..9346e725 100755 --- a/patacrep/content/tex.py +++ b/patacrep/content/tex.py @@ -20,6 +20,9 @@ class LaTeX(ContentItem): os.path.dirname(context['filename']), ))) + def file_entry(self): + return {'tex': self.filename} + #pylint: disable=unused-argument @validate_parser_argument(""" type: //any diff --git a/patacrep/songs/__init__.py b/patacrep/songs/__init__.py index c58aaae9..0afcf9cf 100644 --- a/patacrep/songs/__init__.py +++ b/patacrep/songs/__init__.py @@ -43,7 +43,7 @@ class DataSubpath: self.subpath = subpath def __str__(self): - return os.path.join(self.datadir, self.subpath) + return self.fullpath @property def fullpath(self): diff --git a/patacrep/tools/content/__init__.py b/patacrep/tools/content/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/patacrep/tools/content/__main__.py b/patacrep/tools/content/__main__.py new file mode 100644 index 00000000..72cefc4e --- /dev/null +++ b/patacrep/tools/content/__main__.py @@ -0,0 +1,76 @@ +"""Perform operations on songbook content.""" + +import argparse +import logging +import os +import shutil +import sys +import textwrap +import yaml + +from patacrep import errors +from patacrep.songbook import open_songbook +from patacrep.build import Songbook + +LOGGER = logging.getLogger("patatools.content") + +def filename(name): + """Check that argument is an existing, readable file name. + + Return the argument for convenience. + """ + if os.path.isfile(name) and os.access(name, os.R_OK): + return name + raise argparse.ArgumentTypeError("Cannot read file '{}'.".format(name)) + +def commandline_parser(): + """Return a command line parser.""" + + parser = argparse.ArgumentParser( + prog="patatools content", + description="Operations related to the content of a songbook.", + formatter_class=argparse.RawTextHelpFormatter, + ) + + subparsers = parser.add_subparsers( + description="", + dest="command", + ) + subparsers.required = True + + content_items = subparsers.add_parser( + "items", + description="Display the content items of a songbook.", + help="Return the content items.", + ) + content_items.add_argument( + 'songbook', + metavar="SONGBOOK", + help=textwrap.dedent("""Songbook file to be used to look for content items."""), + type=filename, + ) + content_items.set_defaults(command=do_content_items) + + return parser + +def do_content_items(namespace): + """Execute the `patatools content items` command.""" + config = open_songbook(namespace.songbook) + config['_cache'] = True + config['_error'] = "fix" + songbook = Songbook(config, config['_outputname']) + _, content_items = songbook.get_content_items() + content_items = [item.file_entry() for item in content_items] + print(yaml.safe_dump(content_items, allow_unicode=True, default_flow_style=False)) + +def main(args): + """Main function: run from command line.""" + options = commandline_parser().parse_args(args[1:]) + try: + options.command(options) + except errors.SongbookError as error: + LOGGER.error(str(error)) + sys.exit(1) + +if __name__ == "__main__": + main(sys.argv) From 87b3a876eb6d24181f7afe1ddb6532bba64ded8d Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 20 Jul 2016 15:36:52 +0200 Subject: [PATCH 04/10] normalize path --- patacrep/tools/content/__main__.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/patacrep/tools/content/__main__.py b/patacrep/tools/content/__main__.py index 72cefc4e..4bc45410 100644 --- a/patacrep/tools/content/__main__.py +++ b/patacrep/tools/content/__main__.py @@ -60,9 +60,19 @@ def do_content_items(namespace): config['_error'] = "fix" songbook = Songbook(config, config['_outputname']) _, content_items = songbook.get_content_items() - content_items = [item.file_entry() for item in content_items] + yaml_dir = os.path.dirname(os.path.abspath(namespace.songbook)) + ref_dir = os.path.join(yaml_dir, 'songs') + content_items = [ + normalize_song_path(item.file_entry(), ref_dir) + for item in content_items + ] print(yaml.safe_dump(content_items, allow_unicode=True, default_flow_style=False)) +def normalize_song_path(file_entry, ref_dir): + if 'song' in file_entry: + file_entry['song'] = os.path.relpath(file_entry['song'], ref_dir) + return file_entry + def main(args): """Main function: run from command line.""" options = commandline_parser().parse_args(args[1:]) From 7464dda62573cae3f60b387650c06520971cbd01 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 20 Jul 2016 15:41:24 +0200 Subject: [PATCH 05/10] factorize valid_filename --- patacrep/tools/__init__.py | 13 +++++++++++++ patacrep/tools/cache/__main__.py | 12 ++---------- patacrep/tools/content/__main__.py | 14 +++----------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/patacrep/tools/__init__.py b/patacrep/tools/__init__.py index e69de29b..84a58f68 100644 --- a/patacrep/tools/__init__.py +++ b/patacrep/tools/__init__.py @@ -0,0 +1,13 @@ +"""Common functions for patatools""" + +import argparse +import os + +def existing_file(name): + """Check that argument is an existing, readable file name. + + Return the argument for convenience. + """ + if os.path.isfile(name) and os.access(name, os.R_OK): + return name + raise argparse.ArgumentTypeError("Cannot read file '{}'.".format(name)) \ No newline at end of file diff --git a/patacrep/tools/cache/__main__.py b/patacrep/tools/cache/__main__.py index f48de224..e5aada68 100644 --- a/patacrep/tools/cache/__main__.py +++ b/patacrep/tools/cache/__main__.py @@ -9,18 +9,10 @@ import textwrap from patacrep import errors from patacrep.songbook import open_songbook +from .. import existing_file LOGGER = logging.getLogger("patatools.cache") -def filename(name): - """Check that argument is an existing, readable file name. - - Return the argument for convenience. - """ - if os.path.isfile(name) and os.access(name, os.R_OK): - return name - raise argparse.ArgumentTypeError("Cannot read file '{}'.".format(name)) - def commandline_parser(): """Return a command line parser.""" @@ -45,7 +37,7 @@ def commandline_parser(): 'songbook', metavar="SONGBOOK", help=textwrap.dedent("""Songbook file to be used to look for cache path."""), - type=filename, + type=existing_file, ) clean.set_defaults(command=do_clean) diff --git a/patacrep/tools/content/__main__.py b/patacrep/tools/content/__main__.py index 4bc45410..0f040e38 100644 --- a/patacrep/tools/content/__main__.py +++ b/patacrep/tools/content/__main__.py @@ -3,7 +3,6 @@ import argparse import logging import os -import shutil import sys import textwrap import yaml @@ -11,18 +10,10 @@ import yaml from patacrep import errors from patacrep.songbook import open_songbook from patacrep.build import Songbook +from .. import existing_file LOGGER = logging.getLogger("patatools.content") -def filename(name): - """Check that argument is an existing, readable file name. - - Return the argument for convenience. - """ - if os.path.isfile(name) and os.access(name, os.R_OK): - return name - raise argparse.ArgumentTypeError("Cannot read file '{}'.".format(name)) - def commandline_parser(): """Return a command line parser.""" @@ -47,7 +38,7 @@ def commandline_parser(): 'songbook', metavar="SONGBOOK", help=textwrap.dedent("""Songbook file to be used to look for content items."""), - type=filename, + type=existing_file, ) content_items.set_defaults(command=do_content_items) @@ -69,6 +60,7 @@ def do_content_items(namespace): print(yaml.safe_dump(content_items, allow_unicode=True, default_flow_style=False)) def normalize_song_path(file_entry, ref_dir): + """Normalize the 'song' value, relative to ref_dir""" if 'song' in file_entry: file_entry['song'] = os.path.relpath(file_entry['song'], ref_dir) return file_entry From be3827ae8d1c84a5e34fc37e3a93b57d0b55292f Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 20 Jul 2016 15:53:19 +0200 Subject: [PATCH 06/10] minor simplifications --- patacrep/tools/cache/__main__.py | 5 +---- patacrep/tools/content/__main__.py | 13 +++---------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/patacrep/tools/cache/__main__.py b/patacrep/tools/cache/__main__.py index e5aada68..6faf7989 100644 --- a/patacrep/tools/cache/__main__.py +++ b/patacrep/tools/cache/__main__.py @@ -22,10 +22,7 @@ def commandline_parser(): formatter_class=argparse.RawTextHelpFormatter, ) - subparsers = parser.add_subparsers( - description="", - dest="command", - ) + subparsers = parser.add_subparsers() subparsers.required = True clean = subparsers.add_parser( diff --git a/patacrep/tools/content/__main__.py b/patacrep/tools/content/__main__.py index 0f040e38..67d6b1de 100644 --- a/patacrep/tools/content/__main__.py +++ b/patacrep/tools/content/__main__.py @@ -23,10 +23,7 @@ def commandline_parser(): formatter_class=argparse.RawTextHelpFormatter, ) - subparsers = parser.add_subparsers( - description="", - dest="command", - ) + subparsers = parser.add_subparsers() subparsers.required = True content_items = subparsers.add_parser( @@ -57,7 +54,7 @@ def do_content_items(namespace): normalize_song_path(item.file_entry(), ref_dir) for item in content_items ] - print(yaml.safe_dump(content_items, allow_unicode=True, default_flow_style=False)) + sys.stdout.write(yaml.safe_dump(content_items, allow_unicode=True, default_flow_style=False)) def normalize_song_path(file_entry, ref_dir): """Normalize the 'song' value, relative to ref_dir""" @@ -68,11 +65,7 @@ def normalize_song_path(file_entry, ref_dir): def main(args): """Main function: run from command line.""" options = commandline_parser().parse_args(args[1:]) - try: - options.command(options) - except errors.SongbookError as error: - LOGGER.error(str(error)) - sys.exit(1) + options.command(options) if __name__ == "__main__": main(sys.argv) From 36ff6d283bb26ecdf49a5e4ec6309ec566d42b4a Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 20 Jul 2016 15:56:41 +0200 Subject: [PATCH 07/10] (pylint) minor cleaing --- patacrep/tools/__init__.py | 2 +- patacrep/tools/content/__main__.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/patacrep/tools/__init__.py b/patacrep/tools/__init__.py index 84a58f68..90ae902b 100644 --- a/patacrep/tools/__init__.py +++ b/patacrep/tools/__init__.py @@ -10,4 +10,4 @@ def existing_file(name): """ if os.path.isfile(name) and os.access(name, os.R_OK): return name - raise argparse.ArgumentTypeError("Cannot read file '{}'.".format(name)) \ No newline at end of file + raise argparse.ArgumentTypeError("Cannot read file '{}'.".format(name)) diff --git a/patacrep/tools/content/__main__.py b/patacrep/tools/content/__main__.py index 67d6b1de..a2b65977 100644 --- a/patacrep/tools/content/__main__.py +++ b/patacrep/tools/content/__main__.py @@ -7,7 +7,6 @@ import sys import textwrap import yaml -from patacrep import errors from patacrep.songbook import open_songbook from patacrep.build import Songbook from .. import existing_file From d304578ca07ae56f5164b2e0afaabbdfd4cff6d3 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 20 Jul 2016 21:01:20 +0200 Subject: [PATCH 08/10] Update test --- test/test_content/custom.control | 2 +- test/test_content/custom.source | 2 +- test/test_content/customzipped.control | 2 +- test/test_content/customzipped.source | 2 +- test/test_content/cwd.control | 2 +- test/test_content/cwd_list.control | 4 +- .../datadir/python/content/customplugin.py | 2 +- .../datadir_zippedcontent/python/content | Bin 420 -> 418 bytes test/test_content/glob.control | 2 +- test/test_content/include.control | 12 ++-- test/test_content/sections.control | 24 ++++---- test/test_content/setcounter.control | 16 ++++-- test/test_content/songs.control | 8 +-- test/test_content/songsection.control | 12 ++-- test/test_content/sort.control | 54 +++++++++--------- test/test_content/test_content.py | 38 ++++-------- test/test_content/tex.control | 6 +- 17 files changed, 92 insertions(+), 96 deletions(-) diff --git a/test/test_content/custom.control b/test/test_content/custom.control index b549c6a3..52e29862 100644 --- a/test/test_content/custom.control +++ b/test/test_content/custom.control @@ -1 +1 @@ -- "{'customname:': ''}" \ No newline at end of file +- customname: '' \ No newline at end of file diff --git a/test/test_content/custom.source b/test/test_content/custom.source index ded39db8..52e29862 100644 --- a/test/test_content/custom.source +++ b/test/test_content/custom.source @@ -1 +1 @@ -- customname: \ No newline at end of file +- customname: '' \ No newline at end of file diff --git a/test/test_content/customzipped.control b/test/test_content/customzipped.control index 6d3fd533..8a6bbc0d 100644 --- a/test/test_content/customzipped.control +++ b/test/test_content/customzipped.control @@ -1 +1 @@ -- "{'customzippedname:': ''}" \ No newline at end of file +- customzippedname: '' diff --git a/test/test_content/customzipped.source b/test/test_content/customzipped.source index 7c67530d..8a6bbc0d 100644 --- a/test/test_content/customzipped.source +++ b/test/test_content/customzipped.source @@ -1 +1 @@ -- customzippedname: +- customzippedname: '' diff --git a/test/test_content/cwd.control b/test/test_content/cwd.control index e1ed6693..9ea8e105 100644 --- a/test/test_content/cwd.control +++ b/test/test_content/cwd.control @@ -1 +1 @@ -- subdir/chordpro.csg \ No newline at end of file +- song: datadir/songs/subdir/chordpro.csg \ No newline at end of file diff --git a/test/test_content/cwd_list.control b/test/test_content/cwd_list.control index 3c9377a4..c52db118 100644 --- a/test/test_content/cwd_list.control +++ b/test/test_content/cwd_list.control @@ -1,2 +1,2 @@ -- subdir/chordpro.csg -- exsong.sg \ No newline at end of file +- song: datadir/songs/subdir/chordpro.csg +- song: datadir/songs/exsong.sg \ No newline at end of file diff --git a/test/test_content/datadir/python/content/customplugin.py b/test/test_content/datadir/python/content/customplugin.py index e7333b30..d579aca8 100755 --- a/test/test_content/datadir/python/content/customplugin.py +++ b/test/test_content/datadir/python/content/customplugin.py @@ -6,7 +6,7 @@ class FakeContent(ContentItem): """Fake content.""" def file_entry(self): - return {'customname:':''} + return {'customname':''} def parse(keyword, argument, config): return ContentList([FakeContent()]) diff --git a/test/test_content/datadir_zippedcontent/python/content b/test/test_content/datadir_zippedcontent/python/content index a333d318a650a18aa11e723f9930df3f4a98577d..9c4371ffabcccf1b23b62812e5283125317ec209 100644 GIT binary patch delta 337 zcmZ3&yogygz?+#xgn@y9gF(9Ki^sW}vqK&Mc?FCN45AD&lM@&v>Ny#hueSGxUjyRO z3T_5QmKV$n3}7O+-`D$yfk4~)pQ6rsxeMR$M|{|_LPsaGz_xSB1wXGFHHI^_R{yx4 zn~Z?R@p1Q|zUV9cA-+*kw5+gq`PTwzXucFBNeLE)Wo1-DvQx?SZ6ibD^QY z;l$Yfo^^Y5)hF+$Z{<%tyF%jk3Jt}tUCVCjhAXnI4r=nzYpl9_=?$xna(C3hwQ4^N z7O~~(d^@cj`?@7;x`&+8ypxB^P0w^T|28sw^kVAatoTrSrzc+JB^ zk+*!7t~JTs7qUNh>g?}s9fyO<_q{*&_w&oIA8+hEaCiTcsXH#zGX{8zGcw6BV+oV!Z delta 339 zcmZ3)yo6acz?+#xgn@y9gW=1T#~#U22lo?$#IMl^_&dMJQbDUd_Y`U z!Og(P@`9Ox0ZiofJ7yg=5ODo&b#y^*u7PF4!qpe1ITUbvhA)*!?C5vRldBH2+aX+J(LbLxUe4_gHzXHJ1v^n!~z2;%iIY_1!ZI(+sXz zC*4^8y7A(*?@u$B>aQ1sPL>o&elE(o#P6cS+al3L^Fuf$oUjbYi(2J&z{qHI>Yc1f ze9T!F(hlWSE{&EfxMVr0ZG!UI53yeiH*AhSRxOj3x>0l1q91}vNB_5+;=X4m%WHb) z=qr}XX=h4zW_@1%srGeDZHUvG_*zyJV7n2LM= diff --git a/test/test_content/glob.control b/test/test_content/glob.control index 177bc945..2cb022f2 100644 --- a/test/test_content/glob.control +++ b/test/test_content/glob.control @@ -1 +1 @@ -- chordpro.csg \ No newline at end of file +- song: datadir/songs/chordpro.csg \ No newline at end of file diff --git a/test/test_content/include.control b/test/test_content/include.control index 6aba97ae..4b39aced 100644 --- a/test/test_content/include.control +++ b/test/test_content/include.control @@ -1,6 +1,6 @@ -- exsong.sg -- chordpro.csg -- subdir/chordpro.csg -- chordpro.csg -- subdir/chordpro.csg -- exsong.sg \ No newline at end of file +- song: datadir/songs/exsong.sg +- song: datadir/songs/chordpro.csg +- song: datadir/songs/subdir/chordpro.csg +- song: datadir/songs/chordpro.csg +- song: datadir/songs/subdir/chordpro.csg +- song: datadir/songs/exsong.sg \ No newline at end of file diff --git a/test/test_content/sections.control b/test/test_content/sections.control index 5a87c67c..f96345f2 100644 --- a/test/test_content/sections.control +++ b/test/test_content/sections.control @@ -1,11 +1,13 @@ -- section{First Section!} -- section{Named section} -- section[section_short_name]{Section with short name} -- section*{Section* with short name} -- part{part section test} -- chapter{chapter section test} -- section{section section test} -- subsection{subsection section test} -- subsubsection{subsubsection section test} -- paragraph{paragraph section test} -- subparagraph{subparagraph section test} \ No newline at end of file +- section: First Section! +- section: Named section +- section: + name: Section with short name + short: section_short_name +- section*: Section* with short name +- part: part section test +- chapter: chapter section test +- section: section section test +- subsection: subsection section test +- subsubsection: subsubsection section test +- paragraph: paragraph section test +- subparagraph: subparagraph section test \ No newline at end of file diff --git a/test/test_content/setcounter.control b/test/test_content/setcounter.control index dff14be1..453c67e4 100644 --- a/test/test_content/setcounter.control +++ b/test/test_content/setcounter.control @@ -1,4 +1,12 @@ -- setcounter{songnum}{101} -- setcounter{songnum}{1} -- setcounter{songnum}{5} -- setcounter{counter_name}{-1} \ No newline at end of file +- setcounter: + name: songnum + value: 101 +- setcounter: + name: songnum + value: 1 +- setcounter: + name: songnum + value: 5 +- setcounter: + name: counter_name + value: -1 \ No newline at end of file diff --git a/test/test_content/songs.control b/test/test_content/songs.control index 6ad0622a..61723113 100644 --- a/test/test_content/songs.control +++ b/test/test_content/songs.control @@ -1,4 +1,4 @@ -- exsong.sg -- texsong.tsg -- chordpro.csg -- subdir/chordpro.csg \ No newline at end of file +- song: datadir/songs/exsong.sg +- song: datadir/songs/texsong.tsg +- song: datadir/songs/chordpro.csg +- song: datadir/songs/subdir/chordpro.csg \ No newline at end of file diff --git a/test/test_content/songsection.control b/test/test_content/songsection.control index 81197f08..4bbd48f8 100644 --- a/test/test_content/songsection.control +++ b/test/test_content/songsection.control @@ -1,6 +1,6 @@ -- songsection{Traditional} -- exsong.sg -- songchapter{English} -- texsong.tsg -- chordpro.csg -- exsong.sg \ No newline at end of file +- songsection: Traditional +- song: datadir/songs/exsong.sg +- songchapter: English +- song: datadir/songs/texsong.tsg +- song: datadir/songs/chordpro.csg +- song: datadir/songs/exsong.sg \ No newline at end of file diff --git a/test/test_content/sort.control b/test/test_content/sort.control index a7430273..4778a6e5 100644 --- a/test/test_content/sort.control +++ b/test/test_content/sort.control @@ -1,27 +1,27 @@ -- section{Title} -- "@TEST_FOLDER@/datadir_sort/path1_title1_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path1_title1_author2.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title1_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title1_author2.csg" -- "@TEST_FOLDER@/datadir_sort/path1_title2_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path1_title2_author2.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title2_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title2_author2.csg" -- section{Author, Title} -- "@TEST_FOLDER@/datadir_sort/path1_title1_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title1_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path1_title2_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title2_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path1_title1_author2.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title1_author2.csg" -- "@TEST_FOLDER@/datadir_sort/path1_title2_author2.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title2_author2.csg" -- section{Path, Title} -- "@TEST_FOLDER@/datadir_sort/path1_title1_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path1_title1_author2.csg" -- "@TEST_FOLDER@/datadir_sort/path1_title2_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path1_title2_author2.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title1_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title1_author2.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title2_author1.csg" -- "@TEST_FOLDER@/datadir_sort/path2_title2_author2.csg" +- section: Title +- song: datadir_sort/path1_title1_author1.csg +- song: datadir_sort/path1_title1_author2.csg +- song: datadir_sort/path2_title1_author1.csg +- song: datadir_sort/path2_title1_author2.csg +- song: datadir_sort/path1_title2_author1.csg +- song: datadir_sort/path1_title2_author2.csg +- song: datadir_sort/path2_title2_author1.csg +- song: datadir_sort/path2_title2_author2.csg +- section: Author, Title +- song: datadir_sort/path1_title1_author1.csg +- song: datadir_sort/path2_title1_author1.csg +- song: datadir_sort/path1_title2_author1.csg +- song: datadir_sort/path2_title2_author1.csg +- song: datadir_sort/path1_title1_author2.csg +- song: datadir_sort/path2_title1_author2.csg +- song: datadir_sort/path1_title2_author2.csg +- song: datadir_sort/path2_title2_author2.csg +- section: Path, Title +- song: datadir_sort/path1_title1_author1.csg +- song: datadir_sort/path1_title1_author2.csg +- song: datadir_sort/path1_title2_author1.csg +- song: datadir_sort/path1_title2_author2.csg +- song: datadir_sort/path2_title1_author1.csg +- song: datadir_sort/path2_title1_author2.csg +- song: datadir_sort/path2_title2_author1.csg +- song: datadir_sort/path2_title2_author2.csg diff --git a/test/test_content/test_content.py b/test/test_content/test_content.py index 1ca8c67d..14a56800 100644 --- a/test/test_content/test_content.py +++ b/test/test_content/test_content.py @@ -10,7 +10,6 @@ import yaml from pkg_resources import resource_filename from patacrep import content, files -from patacrep.content import song, section, setcounter, songsection, tex from patacrep.songbook import prepare_songbook from .. import logging_reduced @@ -55,16 +54,13 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): with logging_reduced('patacrep.content.song'): expandedlist = content.process_content(sbcontent, config) - sourcelist = [cls._clean_path(elem) for elem in expandedlist] + sourcelist = [cls._clean_path(elem.file_entry()) for elem in expandedlist] controlname = "{}.control".format(base) if not os.path.exists(controlname): - raise Exception("Missing control:" + str(sourcelist).replace("'", '"')) + raise Exception("Missing control:" + str(controlname).replace("'", '"')) with open(controlname, mode="r", encoding="utf8") as controlfile: - controllist = [ - elem.replace("@TEST_FOLDER@", files.path2posix(resource_filename(__name__, ""))) - for elem in yaml.load(controlfile) - ] + controllist = yaml.load(controlfile) self.assertEqual(controllist, sourcelist) @@ -75,25 +71,15 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): @classmethod def _clean_path(cls, elem): - """Shorten the path relative to the `songs` directory""" - - latex_command_classes = ( - section.Section, - songsection.SongSection, - setcounter.CounterSetter, - ) - if isinstance(elem, latex_command_classes): - return elem.render(None)[1:] - - elif isinstance(elem, song.SongRenderer): - songpath = os.path.join(os.path.dirname(__file__), 'datadir', 'songs') - return files.path2posix(files.relpath(elem.song.fullpath, songpath)) - - elif isinstance(elem, tex.LaTeX): - return files.path2posix(elem.filename) - - else: - return str(elem.file_entry()) + """Shorten the path relative to the test directory""" + if not isinstance(elem, dict): + return elem + + test_path = files.path2posix(resource_filename(__name__, ""))+"/" + for key in ['song', 'tex']: + if key in elem: + elem[key] = os.path.normpath(elem[key]).replace(test_path, "") + return elem @classmethod def _generate_config(cls, sbcontent, outputdir, base): diff --git a/test/test_content/tex.control b/test/test_content/tex.control index 47d8fe2c..6a9a4749 100644 --- a/test/test_content/tex.control +++ b/test/test_content/tex.control @@ -1,3 +1,3 @@ -- test/test_content/datadir/songs/texfile.tex -- test/test_content/datadir/songs/texfile.tex -- test/test_content/datadir/songs/texfile.tex \ No newline at end of file +- tex: test/test_content/datadir/songs/texfile.tex +- tex: test/test_content/datadir/songs/texfile.tex +- tex: test/test_content/datadir/songs/texfile.tex \ No newline at end of file From 60a99d3a44df897cd94cc02c8ad1fb41c2799d23 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 20 Jul 2016 21:09:54 +0200 Subject: [PATCH 09/10] change method name: to_dict --- patacrep/content/__init__.py | 2 +- patacrep/content/section.py | 2 +- patacrep/content/setcounter.py | 2 +- patacrep/content/song.py | 2 +- patacrep/content/songsection.py | 2 +- patacrep/content/tex.py | 2 +- patacrep/tools/content/__main__.py | 2 +- .../datadir/python/content/customplugin.py | 2 +- .../datadir_zippedcontent/python/content | Bin 418 -> 416 bytes test/test_content/test_content.py | 2 +- 10 files changed, 9 insertions(+), 9 deletions(-) diff --git a/patacrep/content/__init__.py b/patacrep/content/__init__.py index 3edc0cf3..12e9bed9 100755 --- a/patacrep/content/__init__.py +++ b/patacrep/content/__init__.py @@ -116,7 +116,7 @@ class ContentItem: """Return the string to end a block.""" return "" - def file_entry(self): + def to_dict(self): """Return the dict representation (as in the yaml file).""" raise NotImplementedError() diff --git a/patacrep/content/section.py b/patacrep/content/section.py index 403e2072..78776d5c 100755 --- a/patacrep/content/section.py +++ b/patacrep/content/section.py @@ -28,7 +28,7 @@ class Section(ContentItem): else: return r'\{}[{}]{{{}}}'.format(self.keyword, self.short, self.name) - def file_entry(self): + def to_dict(self): if self.short is None or self.keyword not in KEYWORDS: return {self.keyword: self.name} else: diff --git a/patacrep/content/setcounter.py b/patacrep/content/setcounter.py index 0b20b223..400ce26b 100755 --- a/patacrep/content/setcounter.py +++ b/patacrep/content/setcounter.py @@ -14,7 +14,7 @@ class CounterSetter(ContentItem): """Set the value of the counter.""" return r'\setcounter{{{}}}{{{}}}'.format(self.name, self.value) - def file_entry(self): + def to_dict(self): return {'setcounter': {'name': self.name, 'value': self.value}} #pylint: disable=unused-argument diff --git a/patacrep/content/song.py b/patacrep/content/song.py index 73ace8cf..dc35b5ae 100755 --- a/patacrep/content/song.py +++ b/patacrep/content/song.py @@ -63,7 +63,7 @@ class SongRenderer(ContentItem): """Order by song path""" return self.song.fullpath < other.song.fullpath - def file_entry(self): + def to_dict(self): return {'song': self.song.fullpath} #pylint: disable=unused-argument diff --git a/patacrep/content/songsection.py b/patacrep/content/songsection.py index 57d4e5e7..132c0666 100755 --- a/patacrep/content/songsection.py +++ b/patacrep/content/songsection.py @@ -19,7 +19,7 @@ class SongSection(ContentItem): """Render this section or chapter.""" return r'\{}{{{}}}'.format(self.keyword, self.name) - def file_entry(self): + def to_dict(self): return {self.keyword: self.name} #pylint: disable=unused-argument diff --git a/patacrep/content/tex.py b/patacrep/content/tex.py index 9346e725..ef588d04 100755 --- a/patacrep/content/tex.py +++ b/patacrep/content/tex.py @@ -20,7 +20,7 @@ class LaTeX(ContentItem): os.path.dirname(context['filename']), ))) - def file_entry(self): + def to_dict(self): return {'tex': self.filename} #pylint: disable=unused-argument diff --git a/patacrep/tools/content/__main__.py b/patacrep/tools/content/__main__.py index a2b65977..0d64c480 100644 --- a/patacrep/tools/content/__main__.py +++ b/patacrep/tools/content/__main__.py @@ -50,7 +50,7 @@ def do_content_items(namespace): yaml_dir = os.path.dirname(os.path.abspath(namespace.songbook)) ref_dir = os.path.join(yaml_dir, 'songs') content_items = [ - normalize_song_path(item.file_entry(), ref_dir) + normalize_song_path(item.to_dict(), ref_dir) for item in content_items ] sys.stdout.write(yaml.safe_dump(content_items, allow_unicode=True, default_flow_style=False)) diff --git a/test/test_content/datadir/python/content/customplugin.py b/test/test_content/datadir/python/content/customplugin.py index d579aca8..b835459c 100755 --- a/test/test_content/datadir/python/content/customplugin.py +++ b/test/test_content/datadir/python/content/customplugin.py @@ -5,7 +5,7 @@ from patacrep.content import ContentItem, ContentList, validate_parser_argument class FakeContent(ContentItem): """Fake content.""" - def file_entry(self): + def to_dict(self): return {'customname':''} def parse(keyword, argument, config): diff --git a/test/test_content/datadir_zippedcontent/python/content b/test/test_content/datadir_zippedcontent/python/content index 9c4371ffabcccf1b23b62812e5283125317ec209..2c5e1ee5d2b83ddf2659a4c0e18c2736892ceb6e 100644 GIT binary patch delta 334 zcmZ3)yntCYz?+#xgn@y9gW>jyFCKmmGI<{WdAW=X45AD&lj9gA>Ny#h&z|lNKL^C6 z72FJrEH9WD7{Eks|G})o20U%=>$o0z3vtvo9P&$*Zk@z;ZSFA+wQ0?nGSZRvZXCN; z`|*(z-(_EqU;F)oPO+D|as*4g?vvb37U~txbjR- zGWW9G_@&GW7&I@5lvYZJM-TVI;#Rix#bZ=qk6UF`l&Ub+6q&xfAd3nph7 zpSZDc$273;6I_lI8t;?fFk21b?_%nS@* zBDdey`-p)++xwrQ&U(2E-|$C#*s?-LC$zw}bIJujuNyUnGqqO#xSyLNR#lKU`C;vR z^`KMirH&nC^Lp52IV6Og=V-RIWU4O}aSARF5MAA9@UHEFq-}Gdp}^t9*#4e%dv(<( z?`Y*utv|a$;`a&-#jjnfx;TPZv?`|E3gUk25Klk_Z%da1A>^*RI|C6aZF4Qvycr!A|i7;acm&qQC`b<~bCs#5m LvKcZ0Ly7?apSO#r diff --git a/test/test_content/test_content.py b/test/test_content/test_content.py index 14a56800..78fef0ea 100644 --- a/test/test_content/test_content.py +++ b/test/test_content/test_content.py @@ -54,7 +54,7 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): with logging_reduced('patacrep.content.song'): expandedlist = content.process_content(sbcontent, config) - sourcelist = [cls._clean_path(elem.file_entry()) for elem in expandedlist] + sourcelist = [cls._clean_path(elem.to_dict()) for elem in expandedlist] controlname = "{}.control".format(base) if not os.path.exists(controlname): From bd22c136c3c80cd49c55b1aece17f0b9be7ba601 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 20 Jul 2016 21:10:12 +0200 Subject: [PATCH 10/10] normalize path --- test/test_content/test_content.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/test_content/test_content.py b/test/test_content/test_content.py index 78fef0ea..eb405c90 100644 --- a/test/test_content/test_content.py +++ b/test/test_content/test_content.py @@ -78,7 +78,9 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): test_path = files.path2posix(resource_filename(__name__, ""))+"/" for key in ['song', 'tex']: if key in elem: - elem[key] = os.path.normpath(elem[key]).replace(test_path, "") + elem[key] = files.path2posix( + os.path.normpath(elem[key]) + ).replace(test_path, "") return elem @classmethod