From e1d4af646bc887ebc5fdaee350394d0fefb25d99 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 28 Oct 2015 08:15:29 +0100 Subject: [PATCH 1/9] Compilation bug if # is present in nolyrics environment --- test/test_compilation/datadir.tex.control | 7 +++++++ test/test_compilation/datadir_datadir/songs/datadir.sgc | 2 ++ 2 files changed, 9 insertions(+) diff --git a/test/test_compilation/datadir.tex.control b/test/test_compilation/datadir.tex.control index a003cd42..9444d4de 100644 --- a/test/test_compilation/datadir.tex.control +++ b/test/test_compilation/datadir.tex.control @@ -114,6 +114,13 @@ Chordpro}[ \image{img/datadir.png} + +\ifchorded +\begin{verse*} + \musicnote {\nolyrics \[Am C#m]} +\end{verse*} +\fi + \endsong %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/test/test_compilation/datadir_datadir/songs/datadir.sgc b/test/test_compilation/datadir_datadir/songs/datadir.sgc index 73a6a15f..11bb1f54 100644 --- a/test/test_compilation/datadir_datadir/songs/datadir.sgc +++ b/test/test_compilation/datadir_datadir/songs/datadir.sgc @@ -5,3 +5,5 @@ {partition: datadir.ly} {image: datadir.png} + +[Am C#m] From a6a7edcfc873f40b3a8833c7c8a4cfaa857a96f1 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 28 Oct 2015 08:16:34 +0100 Subject: [PATCH 2/9] Replace # with {\shrp} in nolyrics environment --- patacrep/data/ast_templates/chordpro/latex/content_verse | 2 +- test/test_chordpro/nolyrics.tex | 2 +- test/test_compilation/datadir.tex.control | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/patacrep/data/ast_templates/chordpro/latex/content_verse b/patacrep/data/ast_templates/chordpro/latex/content_verse index ae3aa34f..72859732 100644 --- a/patacrep/data/ast_templates/chordpro/latex/content_verse +++ b/patacrep/data/ast_templates/chordpro/latex/content_verse @@ -6,7 +6,7 @@ \ifchorded \begin{verse*} (* for line in content.lines *) - \musicnote {\nolyrics (( render(line) ))} + \musicnote {\nolyrics (( render(line)|replace("#", "{\shrp}") ))} (* endfor *) \end{verse*} \fi diff --git a/test/test_chordpro/nolyrics.tex b/test/test_chordpro/nolyrics.tex index 343f4e63..3ce5d6b3 100644 --- a/test/test_chordpro/nolyrics.tex +++ b/test/test_chordpro/nolyrics.tex @@ -14,7 +14,7 @@ \ifchorded \begin{verse*} - \musicnote {\nolyrics \[A B#]} + \musicnote {\nolyrics \[A B{\shrp}]} \end{verse*} \fi diff --git a/test/test_compilation/datadir.tex.control b/test/test_compilation/datadir.tex.control index 9444d4de..0e37b1e7 100644 --- a/test/test_compilation/datadir.tex.control +++ b/test/test_compilation/datadir.tex.control @@ -117,7 +117,7 @@ Chordpro}[ \ifchorded \begin{verse*} - \musicnote {\nolyrics \[Am C#m]} + \musicnote {\nolyrics \[Am C{\shrp}m]} \end{verse*} \fi From 59fbf0e46b84c0d46c692020e128643191954d99 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 4 Nov 2015 08:42:39 +0100 Subject: [PATCH 3/9] Move syntax tests into a separate songbook --- test/test_compilation/datadir.tex.control | 7 -- .../datadir_datadir/songs/datadir.sgc | 2 - test/test_compilation/syntax.sb | 4 + test/test_compilation/syntax.tex.control | 116 ++++++++++++++++++ .../syntax_datadir/songs/musicnote.sgc | 4 + 5 files changed, 124 insertions(+), 9 deletions(-) create mode 100644 test/test_compilation/syntax.sb create mode 100644 test/test_compilation/syntax.tex.control create mode 100644 test/test_compilation/syntax_datadir/songs/musicnote.sgc diff --git a/test/test_compilation/datadir.tex.control b/test/test_compilation/datadir.tex.control index 0e37b1e7..a003cd42 100644 --- a/test/test_compilation/datadir.tex.control +++ b/test/test_compilation/datadir.tex.control @@ -114,13 +114,6 @@ Chordpro}[ \image{img/datadir.png} - -\ifchorded -\begin{verse*} - \musicnote {\nolyrics \[Am C{\shrp}m]} -\end{verse*} -\fi - \endsong %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/test/test_compilation/datadir_datadir/songs/datadir.sgc b/test/test_compilation/datadir_datadir/songs/datadir.sgc index 11bb1f54..73a6a15f 100644 --- a/test/test_compilation/datadir_datadir/songs/datadir.sgc +++ b/test/test_compilation/datadir_datadir/songs/datadir.sgc @@ -5,5 +5,3 @@ {partition: datadir.ly} {image: datadir.png} - -[Am C#m] diff --git a/test/test_compilation/syntax.sb b/test/test_compilation/syntax.sb new file mode 100644 index 00000000..fb16ce10 --- /dev/null +++ b/test/test_compilation/syntax.sb @@ -0,0 +1,4 @@ +{ +"datadir": ["syntax_datadir"], +"lang": "en" +} diff --git a/test/test_compilation/syntax.tex.control b/test/test_compilation/syntax.tex.control new file mode 100644 index 00000000..2794e2fa --- /dev/null +++ b/test/test_compilation/syntax.tex.control @@ -0,0 +1,116 @@ + + + + + + +%% Automatically generated document. +%% You may edit this file but all changes will be overwritten. +%% If you want to change this document, have a look at +%% the templating system. +%% +%% Generated using Songbook + +\makeatletter +\def\input@path{ % + {@TEST_FOLDER@/syntax_datadir/latex/} % + {@TEST_FOLDER@/latex/} % + {@DATA_FOLDER@/latex/} % +} +\makeatother + +\documentclass[ + ]{article} + +\usepackage[ + chorded, +diagram, +pictures, +guitar, + ]{patacrep} + +\usepackage{lmodern} + + +\PassOptionsToPackage{english}{babel} +\usepackage[english]{babel} +\lang{english} + +\usepackage{graphicx} +\graphicspath{ % + {@TEST_FOLDER@/syntax_datadir/} % + {@TEST_FOLDER@/} % + {@DATA_FOLDER@/} % +} + + +\makeatletter +\@ifpackageloaded{hyperref}{}{ + \usepackage{url} + \newcommand{\phantomsection}{} + \newcommand{\hyperlink}[2]{#2} + \newcommand{\href}[2]{\expandafter\url\expandafter{#1}} +} +\makeatother + + +\usepackage{chords} + +\title{Guitar songbook} +\author{The Patacrep Team} + +\newindex{titleidx}{syntax_title} +\newauthorindex{authidx}{syntax_auth} + + +\notenamesout{A}{B}{C}{D}{E}{F}{G} + + +\begin{document} + +\maketitle + + +\showindex{\songindexname}{titleidx} +\showindex{\authorindexname}{authidx} + +% list of chords +\ifchorded + \ifdiagram + \phantomsection + \addcontentsline{toc}{section}{\chordlistname} + \chords + \fi +\fi + +\phantomsection +\addcontentsline{toc}{section}{\songlistname} + +\begin{songs}{titleidx,authidx} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% songs/./musicnote.sgc + +\selectlanguage{english} + +\beginsong{Song with Sharp in musicnote}[ + by={ + }, +] + + + + +\ifchorded +\begin{verse*} + \musicnote {\nolyrics \[Am C{\shrp}m]} +\end{verse*} +\fi + +\endsong + +\end{songs} + + + + +\end{document} \ No newline at end of file diff --git a/test/test_compilation/syntax_datadir/songs/musicnote.sgc b/test/test_compilation/syntax_datadir/songs/musicnote.sgc new file mode 100644 index 00000000..830f14d9 --- /dev/null +++ b/test/test_compilation/syntax_datadir/songs/musicnote.sgc @@ -0,0 +1,4 @@ +{title : Song with Sharp in musicnote} +{lang: en} + +[Am C#m] From 48840847e539a0b45f7cf7696b255bb9c1c7b861 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 4 Nov 2015 08:57:36 +0100 Subject: [PATCH 4/9] Dynamically skip tex.control if non-existent --- test/test_compilation/test_compilation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_compilation/test_compilation.py b/test/test_compilation/test_compilation.py index 11067c55..9bf24cc2 100644 --- a/test/test_compilation/test_compilation.py +++ b/test/test_compilation/test_compilation.py @@ -38,9 +38,6 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): '*.sb', ))): base = songbook[:-len(".sb")] - control = "{}.tex.control".format(base) - if not os.path.exists(control): - continue yield ( "test_generation_{}".format(os.path.basename(base)), cls._create_generation_test(base), @@ -63,6 +60,9 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): # Check generated tex control = "{}.tex.control".format(base) + if not os.path.exists(control): + raise unittest.SkipTest('No control file for {}'.format(songbook)) + tex = "{}.tex".format(base) with open_read(control) as expectfile: with open_read(tex) as latexfile: From 1d6f8c2bbdbeccfa3d9a2c7f8b4ff127af06c6f4 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 4 Nov 2015 08:59:47 +0100 Subject: [PATCH 5/9] Rename compilation test to force better ordering --- test/test_compilation/test_compilation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_compilation/test_compilation.py b/test/test_compilation/test_compilation.py index 9bf24cc2..3af70d19 100644 --- a/test/test_compilation/test_compilation.py +++ b/test/test_compilation/test_compilation.py @@ -39,11 +39,11 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): ))): base = songbook[:-len(".sb")] yield ( - "test_generation_{}".format(os.path.basename(base)), + "test_latex_generation_{}".format(os.path.basename(base)), cls._create_generation_test(base), ) yield ( - "test_compilation_{}".format(os.path.basename(base)), + "test_pdf_compilation_{}".format(os.path.basename(base)), cls._create_compilation_test(base), ) From 08e5e000b71b70137c163293d7c3e2e8f27e21aa Mon Sep 17 00:00:00 2001 From: Louis Date: Thu, 5 Nov 2015 18:24:14 +0100 Subject: [PATCH 6/9] Add a '--cache' option --- patacrep/songbook/__main__.py | 16 ++++++++++++++++ patacrep/songs/__init__.py | 4 ++-- patacrep/songs/convert/__main__.py | 17 +++++++---------- patacrep/utils.py | 16 ++++++++++++++++ test/test_compilation/test_compilation.py | 2 +- 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/patacrep/songbook/__main__.py b/patacrep/songbook/__main__.py index 5713b4a9..7006e16f 100644 --- a/patacrep/songbook/__main__.py +++ b/patacrep/songbook/__main__.py @@ -9,6 +9,7 @@ import textwrap import sys from patacrep.build import SongbookBuilder, DEFAULT_STEPS +from patacrep.utils import yesno from patacrep import __version__ from patacrep import errors import patacrep.encoding @@ -37,6 +38,12 @@ class VerboseAction(argparse.Action): def __call__(self, *_args, **_kwargs): LOGGER.setLevel(logging.DEBUG) +def yesno_type(string): + try: + return yesno(string) + except ValueError as error: + raise argparse.ArgumentTypeError(str(error)) + def argument_parser(args): """Parse arguments""" parser = argparse.ArgumentParser( @@ -68,6 +75,14 @@ def argument_parser(args): """) ) + parser.add_argument( + '--cache', '-c', nargs=1, + help=textwrap.dedent("""\ + Enable song cache. + """), + type=yesno_type, + ) + parser.add_argument( '--steps', '-s', nargs=1, type=str, action=ParseStepsAction, @@ -147,6 +162,7 @@ def main(): datadirs.append(os.path.dirname(os.path.abspath(songbook_path))) songbook['datadir'] = datadirs + songbook['_cache'] = options.cache[0] try: sb_builder = SongbookBuilder(songbook, basename) diff --git a/patacrep/songs/__init__.py b/patacrep/songs/__init__.py index 129c8045..a36c17bc 100644 --- a/patacrep/songs/__init__.py +++ b/patacrep/songs/__init__.py @@ -104,7 +104,7 @@ class Song: self.encoding = config["encoding"] self.config = config - if datadir: + if self.datadir and self.config['_cache']: # Only songs in datadirs are cached self._filehash = hashlib.md5( open(self.fullpath, 'rb').read() @@ -155,7 +155,7 @@ class Song: def _write_cache(self): """If relevant, write a dumbed down version of self to the cache.""" - if self.datadir: + if self.datadir and self.config['_cache']: cached = {} for attribute in self.cached_attributes: cached[attribute] = getattr(self, attribute) diff --git a/patacrep/songs/convert/__main__.py b/patacrep/songs/convert/__main__.py index 6b40dca4..2880cdab 100644 --- a/patacrep/songs/convert/__main__.py +++ b/patacrep/songs/convert/__main__.py @@ -7,24 +7,21 @@ import os import logging import sys -from patacrep.build import DEFAULT_CONFIG from patacrep import files +from patacrep.build import DEFAULT_CONFIG +from patacrep.utils import yesno LOGGER = logging.getLogger(__name__) def __usage(): return "python3 -m patacrep.songs.convert INPUTFORMAT OUTPUTFORMAT FILES" -def yesno(prompt): - while True: - answer = input("{} [yn] ".format(prompt)) - if answer.strip().lower() == "y": - return True - if answer.strip().lower() == "n": - return False - def confirm(destname): - return yesno("File '{}' already exist. Overwrite?".format(destname)) + while True + try: + return yesno(input("File '{}' already exist. Overwrite? [yn] ".format(destname))) + except ValueError: + continue if __name__ == "__main__": if len(sys.argv) < 4: diff --git a/patacrep/utils.py b/patacrep/utils.py index 6d9eab4c..998fe738 100644 --- a/patacrep/utils.py +++ b/patacrep/utils.py @@ -59,3 +59,19 @@ class DictOfDict(UserDict): DictOfDict._update(left[key], right[key]) else: left[key] = right[key] + +def yesno(string): + """Interpret string argument as a boolean. + + May raise `ValueError` if argument cannot be interpreted. + """ + yes_strings = ["y", "yes", "true", "1"] + no_strings = ["n", "no", "false", "0"] + if string.lower() in yes_strings: + return True + if string.lower() in no_strings: + return False + raise ValueError("'{}' is supposed to be one of {}.".format( + string, + ", ".join(["'{}'".format(string) for string in yes_strings + no_strings]), + )) diff --git a/test/test_compilation/test_compilation.py b/test/test_compilation/test_compilation.py index dc07107a..5b76e3e7 100644 --- a/test/test_compilation/test_compilation.py +++ b/test/test_compilation/test_compilation.py @@ -108,7 +108,7 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): @staticmethod def compile_songbook(songbook, steps=None): """Compile songbook, and return the command return code.""" - command = ['python', '-m', 'patacrep.songbook', songbook, '-v'] + command = ['python', '-m', 'patacrep.songbook', '--cache=no', songbook, '-v'] if steps: command.extend(['--steps', steps]) From d076be098a8cefa1182d5bd3e473780a9f74c066 Mon Sep 17 00:00:00 2001 From: Louis Date: Thu, 5 Nov 2015 18:56:29 +0100 Subject: [PATCH 7/9] Add docstring --- patacrep/songbook/__main__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/patacrep/songbook/__main__.py b/patacrep/songbook/__main__.py index 7006e16f..523cae07 100644 --- a/patacrep/songbook/__main__.py +++ b/patacrep/songbook/__main__.py @@ -39,6 +39,10 @@ class VerboseAction(argparse.Action): LOGGER.setLevel(logging.DEBUG) def yesno_type(string): + """Interpret argument as a "yes" or a "no". + + Raise `argparse.ArgumentTypeError` if string cannot be analysed. + """ try: return yesno(string) except ValueError as error: From bdef0b1e010533de06d40b466bad98c9ad183334 Mon Sep 17 00:00:00 2001 From: Louis Date: Fri, 6 Nov 2015 19:43:31 +0100 Subject: [PATCH 8/9] Add a default value for the '--cache' option When option is given several times, use the last argument provided --- patacrep/songbook/__main__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/patacrep/songbook/__main__.py b/patacrep/songbook/__main__.py index 523cae07..004f3e95 100644 --- a/patacrep/songbook/__main__.py +++ b/patacrep/songbook/__main__.py @@ -85,6 +85,7 @@ def argument_parser(args): Enable song cache. """), type=yesno_type, + default=[True], ) parser.add_argument( @@ -126,7 +127,7 @@ def main(): options = argument_parser(sys.argv[1:]) - songbook_path = options.book[0] + songbook_path = options.book[-1] if os.path.exists(songbook_path + ".sb") and not os.path.exists(songbook_path): songbook_path += ".sb" From df2f9bfea927d84ca3cfa98a1139c9010e6a08c4 Mon Sep 17 00:00:00 2001 From: Louis Date: Sat, 7 Nov 2015 05:32:30 +0100 Subject: [PATCH 9/9] [test] Ensure tex and control files are read as UTF8 References #155 --- test/test_compilation/test_compilation.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/test_compilation/test_compilation.py b/test/test_compilation/test_compilation.py index 3af70d19..0444efa2 100644 --- a/test/test_compilation/test_compilation.py +++ b/test/test_compilation/test_compilation.py @@ -9,7 +9,6 @@ import sys import subprocess import unittest -from patacrep.encoding import open_read from patacrep.files import path2posix from .. import dynamic # pylint: disable=unused-import @@ -64,8 +63,8 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): raise unittest.SkipTest('No control file for {}'.format(songbook)) tex = "{}.tex".format(base) - with open_read(control) as expectfile: - with open_read(tex) as latexfile: + with open(control, mode="r", encoding="utf8") as expectfile: + with open(tex, mode="r", encoding="utf8") as latexfile: expected = expectfile.read().strip() expected = expected.replace( "@TEST_FOLDER@",