diff --git a/.travis.yml b/.travis.yml index 3aceab0a..c398bbfe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,14 +8,16 @@ install: script: - tox sudo: false -addons: - apt: - packages: - - texlive-latex-base - - latex-xcolor - - texlive-latex-extra - - pgf - - lmodern - - lilypond +# addons: +# apt: +# packages: +# - texlive-latex-base +# - latex-xcolor +# - texlive-latex-extra +# - texlive-luatex +# - texlive-xetex +# - pgf +# - lmodern +# - lilypond notifications: email: false diff --git a/patacrep/build.py b/patacrep/build.py index 40ef74ff..00be667e 100644 --- a/patacrep/build.py +++ b/patacrep/build.py @@ -136,10 +136,10 @@ class SongbookBuilder(object): # if False, do not expect anything from stdin. interactive = False - # if True, allow unsafe option, like adding the --shell-escape to pdflatex + # if True, allow unsafe option, like adding the --shell-escape to lualatex unsafe = False - # Options to add to pdflatex - _pdflatex_options = [] + # Options to add to lualatex + _lualatex_options = [] # Dictionary of functions that have been called by self._run_once(). Keys # are function; values are return values of functions. _called_functions = {} @@ -165,11 +165,11 @@ class SongbookBuilder(object): def _set_latex(self): """Set LaTeX options.""" if self.unsafe: - self._pdflatex_options.append("--shell-escape") + self._lualatex_options.append("--shell-escape") if not self.interactive: - self._pdflatex_options.append("-halt-on-error") + self._lualatex_options.append("-halt-on-error") for datadir in self.songbook.config["datadir"]: - self._pdflatex_options.append( + self._lualatex_options.append( '--include-directory="{}"'.format(datadir) ) @@ -180,7 +180,7 @@ class SongbookBuilder(object): - steps: list of steps to perform to compile songbook. Available steps are: - tex: build .tex file from templates; - - pdf: compile .tex using pdflatex; + - pdf: compile .tex using lualatex; - sbx: compile song and author indexes; - clean: remove temporary files, - any string beginning with a sharp sign (#): it is interpreted as a @@ -219,7 +219,7 @@ class SongbookBuilder(object): try: process = Popen( - ["pdflatex"] + self._pdflatex_options + [self.basename], + ["lualatex"] + self._lualatex_options + [self.basename], stdin=PIPE, stdout=PIPE, stderr=PIPE, diff --git a/patacrep/data/latex/patacrep.sty b/patacrep/data/latex/patacrep.sty index f3218005..d3735739 100644 --- a/patacrep/data/latex/patacrep.sty +++ b/patacrep/data/latex/patacrep.sty @@ -75,6 +75,11 @@ \pdfobjcompresslevel=0 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Unicode characters +\RequirePackage{fontspec} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Multilanguage management diff --git a/patacrep/data/templates/layout.tex b/patacrep/data/templates/layout.tex index ae23d681..099772a4 100644 --- a/patacrep/data/templates/layout.tex +++ b/patacrep/data/templates/layout.tex @@ -41,8 +41,6 @@ (* endblock *) (* block songbookpreambule *) -\usepackage[utf8]{inputenc} -\usepackage[T1]{fontenc} \usepackage{lmodern} (* endblock songbookpreambule *) diff --git a/test/dynamic.py b/test/dynamic.py index 19b721a3..494dfc8f 100644 --- a/test/dynamic.py +++ b/test/dynamic.py @@ -13,13 +13,9 @@ class DynamicTest(type): def __init__(cls, name, bases, nmspc): super().__init__(name, bases, nmspc) - for methodname, args in cls._iter_testmethods(): - setattr(cls, methodname, cls._create_test(*args)) + for methodname, testmethod in cls._iter_testmethods(): + setattr(cls, methodname, testmethod) def _iter_testmethods(cls): - """Iterate over test methods.""" - raise NotImplementedError() - - def _create_test(cls, *args, **kwargs): - """Create and return a test method.""" + """Iterate over dynamically generated test methods.""" raise NotImplementedError() diff --git a/test/test_chordpro/test_parser.py b/test/test_chordpro/test_parser.py index 727cabba..f0e94290 100644 --- a/test/test_chordpro/test_parser.py +++ b/test/test_chordpro/test_parser.py @@ -58,7 +58,7 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): continue yield ( "test_{}_{}".format(os.path.basename(base), dest), - [base, dest], + cls._create_test(base, dest), ) @classmethod diff --git a/test/test_compilation/subdir.sb b/test/test_compilation/datadir.sb similarity index 51% rename from test/test_compilation/subdir.sb rename to test/test_compilation/datadir.sb index 28132138..357c28d7 100644 --- a/test/test_compilation/subdir.sb +++ b/test/test_compilation/datadir.sb @@ -2,6 +2,6 @@ "bookoptions" : [ "pictures" ], -"datadir": ["subdir_datadir", "subdir_datadir2"], +"datadir": ["datadir_datadir", "datadir_datadir2"], "lang": "en" } diff --git a/test/test_compilation/subdir.tex.control b/test/test_compilation/datadir.tex.control similarity index 68% rename from test/test_compilation/subdir.tex.control rename to test/test_compilation/datadir.tex.control index 7c816f7e..4f6c8521 100644 --- a/test/test_compilation/subdir.tex.control +++ b/test/test_compilation/datadir.tex.control @@ -13,8 +13,8 @@ \makeatletter \def\input@path{ % - {@TEST_FOLDER@/subdir_datadir/latex/} % - {@TEST_FOLDER@/subdir_datadir2/latex/} % + {@TEST_FOLDER@/datadir_datadir/latex/} % + {@TEST_FOLDER@/datadir_datadir2/latex/} % {@TEST_FOLDER@/latex/} % {@DATA_FOLDER@/latex/} % } @@ -29,8 +29,6 @@ pictures, guitar, ]{patacrep} -\usepackage[utf8]{inputenc} -\usepackage[T1]{fontenc} \usepackage{lmodern} @@ -41,8 +39,8 @@ guitar, \usepackage{graphicx} \graphicspath{ % - {@TEST_FOLDER@/subdir_datadir/} % - {@TEST_FOLDER@/subdir_datadir2/} % + {@TEST_FOLDER@/datadir_datadir/} % + {@TEST_FOLDER@/datadir_datadir2/} % {@TEST_FOLDER@/} % {@DATA_FOLDER@/} % } @@ -63,8 +61,8 @@ guitar, \title{Guitar songbook} \author{The Patacrep Team} -\newindex{titleidx}{subdir_title} -\newauthorindex{authidx}{subdir_auth} +\newindex{titleidx}{datadir_title} +\newauthorindex{authidx}{datadir_auth} \notenamesout{A}{B}{C}{D}{E}{F}{G} @@ -94,7 +92,7 @@ guitar, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% songs/./datadir.sg -\import{subdir_datadir/songs/}{datadir.sg} +\import{datadir_datadir/songs/}{datadir.sg} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% songs/./datadir.sgc @@ -121,7 +119,7 @@ Chordpro}[ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% songs/./datadir2.sg -\import{subdir_datadir/songs/}{datadir2.sg} +\import{datadir_datadir/songs/}{datadir2.sg} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% songs/./datadir2.sgc @@ -148,7 +146,7 @@ Chordpro}[ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% songs/./relative.sg -\import{subdir_datadir/songs/}{relative.sg} +\import{datadir_datadir/songs/}{relative.sg} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% songs/./relative.sgc @@ -159,15 +157,42 @@ Chordpro}[ Chordpro}[ by={ }, - cov={@TEST_FOLDER@/subdir_datadir/songs/./relative.png}, + cov={@TEST_FOLDER@/datadir_datadir/songs/./relative.png}, ] \cover -\lilypond{@TEST_FOLDER@/subdir_datadir/songs/./relative.ly} -\image{@TEST_FOLDER@/subdir_datadir/songs/./relative.png} +\lilypond{@TEST_FOLDER@/datadir_datadir/songs/./relative.ly} +\image{@TEST_FOLDER@/datadir_datadir/songs/./relative.png} + + +\endsong + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% songs/./subdir/subdir.sg + +\import{datadir_datadir/songs/subdir/}{subdir.sg} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% songs/./subdir/subdir.sgc + +\selectlanguage{english} + +\beginsong{Image included from a nested song directory\\ +Chordpro}[ + by={ + }, + cov={@TEST_FOLDER@/datadir_datadir/songs/./subdir/subdir.png}, +] + +\cover + + + +\lilypond{@TEST_FOLDER@/datadir_datadir/songs/./subdir/subdir.ly} +\image{@TEST_FOLDER@/datadir_datadir/songs/./subdir/subdir.png} \endsong diff --git a/test/test_compilation/subdir_datadir/img/datadir.png b/test/test_compilation/datadir_datadir/img/datadir.png similarity index 100% rename from test/test_compilation/subdir_datadir/img/datadir.png rename to test/test_compilation/datadir_datadir/img/datadir.png diff --git a/test/test_compilation/subdir_datadir/scores/datadir.ly b/test/test_compilation/datadir_datadir/scores/datadir.ly similarity index 100% rename from test/test_compilation/subdir_datadir/scores/datadir.ly rename to test/test_compilation/datadir_datadir/scores/datadir.ly diff --git a/test/test_compilation/subdir_datadir/songs/datadir.sg b/test/test_compilation/datadir_datadir/songs/datadir.sg similarity index 100% rename from test/test_compilation/subdir_datadir/songs/datadir.sg rename to test/test_compilation/datadir_datadir/songs/datadir.sg diff --git a/test/test_compilation/subdir_datadir/songs/datadir.sgc b/test/test_compilation/datadir_datadir/songs/datadir.sgc similarity index 100% rename from test/test_compilation/subdir_datadir/songs/datadir.sgc rename to test/test_compilation/datadir_datadir/songs/datadir.sgc diff --git a/test/test_compilation/subdir_datadir/songs/datadir2.sg b/test/test_compilation/datadir_datadir/songs/datadir2.sg similarity index 100% rename from test/test_compilation/subdir_datadir/songs/datadir2.sg rename to test/test_compilation/datadir_datadir/songs/datadir2.sg diff --git a/test/test_compilation/subdir_datadir/songs/datadir2.sgc b/test/test_compilation/datadir_datadir/songs/datadir2.sgc similarity index 100% rename from test/test_compilation/subdir_datadir/songs/datadir2.sgc rename to test/test_compilation/datadir_datadir/songs/datadir2.sgc diff --git a/test/test_compilation/subdir_datadir/songs/relative.ly b/test/test_compilation/datadir_datadir/songs/relative.ly similarity index 100% rename from test/test_compilation/subdir_datadir/songs/relative.ly rename to test/test_compilation/datadir_datadir/songs/relative.ly diff --git a/test/test_compilation/subdir_datadir/songs/relative.png b/test/test_compilation/datadir_datadir/songs/relative.png similarity index 100% rename from test/test_compilation/subdir_datadir/songs/relative.png rename to test/test_compilation/datadir_datadir/songs/relative.png diff --git a/test/test_compilation/subdir_datadir/songs/relative.sg b/test/test_compilation/datadir_datadir/songs/relative.sg similarity index 100% rename from test/test_compilation/subdir_datadir/songs/relative.sg rename to test/test_compilation/datadir_datadir/songs/relative.sg diff --git a/test/test_compilation/subdir_datadir/songs/relative.sgc b/test/test_compilation/datadir_datadir/songs/relative.sgc similarity index 100% rename from test/test_compilation/subdir_datadir/songs/relative.sgc rename to test/test_compilation/datadir_datadir/songs/relative.sgc diff --git a/test/test_compilation/subdir_datadir2/scores/datadir2.ly b/test/test_compilation/datadir_datadir/songs/subdir/subdir.ly similarity index 100% rename from test/test_compilation/subdir_datadir2/scores/datadir2.ly rename to test/test_compilation/datadir_datadir/songs/subdir/subdir.ly diff --git a/test/test_compilation/datadir_datadir/songs/subdir/subdir.png b/test/test_compilation/datadir_datadir/songs/subdir/subdir.png new file mode 100644 index 00000000..2e134e8f Binary files /dev/null and b/test/test_compilation/datadir_datadir/songs/subdir/subdir.png differ diff --git a/test/test_compilation/datadir_datadir/songs/subdir/subdir.sg b/test/test_compilation/datadir_datadir/songs/subdir/subdir.sg new file mode 100644 index 00000000..f86b47b4 --- /dev/null +++ b/test/test_compilation/datadir_datadir/songs/subdir/subdir.sg @@ -0,0 +1,10 @@ +\beginsong{Image included from a nested song directory\\\LaTeX} + [cov={subdir}] + + \cover + + \lilypond{subdir.ly} + + \image{subdir} + +\endsong diff --git a/test/test_compilation/datadir_datadir/songs/subdir/subdir.sgc b/test/test_compilation/datadir_datadir/songs/subdir/subdir.sgc new file mode 100644 index 00000000..0f2cb436 --- /dev/null +++ b/test/test_compilation/datadir_datadir/songs/subdir/subdir.sgc @@ -0,0 +1,7 @@ +{title : Image included from a nested song directory} +{subtitle: Chordpro} +{cover: subdir.png} +{lang: en} + +{partition: subdir.ly} +{image: subdir.png} diff --git a/test/test_compilation/subdir_datadir2/img/datadir2.png b/test/test_compilation/datadir_datadir2/img/datadir2.png similarity index 100% rename from test/test_compilation/subdir_datadir2/img/datadir2.png rename to test/test_compilation/datadir_datadir2/img/datadir2.png diff --git a/test/test_compilation/datadir_datadir2/scores/datadir2.ly b/test/test_compilation/datadir_datadir2/scores/datadir2.ly new file mode 100644 index 00000000..1fd2bccb --- /dev/null +++ b/test/test_compilation/datadir_datadir2/scores/datadir2.ly @@ -0,0 +1,19 @@ +\include "_lilypond/header" +\paper{paper-height = 6.5\cm} + +{ + \key a \minor + \time 6/8 + \partial 8 a'8 + \relative c''{ + c4 d8 e8. (f16) e8 d4 b8 g8. (a16) b8 + c4 a8 a8. (gis16) a8 b4 gis8 e4 a8 + c4 d8 e8. (f16 e8) d4 b8 g8. (a16) b8 + c8. (b16) a8 gis8. (fis16) gis8 a4 a8 a4. + + g'4. g8. (fis16) e8 d4 b8 g8. (a16) b8 + c4 (a8) a8. (gis16) a8 b4 gis8 e4. + g'4. g8. (fis16) e8 d4 b8 g8. (a16) b8 + c8. (b16) a8 gis8. (fis16) gis8 a4. a4. + } +} diff --git a/test/test_compilation/test_compilation.py b/test/test_compilation/test_compilation.py index 812ba0ac..dc07107a 100644 --- a/test/test_compilation/test_compilation.py +++ b/test/test_compilation/test_compilation.py @@ -3,10 +3,10 @@ # pylint: disable=too-few-public-methods import glob +import logging import os import subprocess import unittest -import logging from patacrep.encoding import open_read @@ -30,7 +30,7 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): @classmethod def _iter_testmethods(cls): - """Iterate over songbook files to test.""" + """Iterate over dynamically generated test methods.""" for songbook in sorted(glob.glob(os.path.join( os.path.dirname(__file__), '*.sb', @@ -40,19 +40,20 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): if not os.path.exists(control): continue yield ( - "test_{}".format(os.path.basename(base)), - [base], + "test_generation_{}".format(os.path.basename(base)), + cls._create_generation_test(base), + ) + yield ( + "test_compilation_{}".format(os.path.basename(base)), + cls._create_compilation_test(base), ) @classmethod - def _create_test(cls, base): - """Return a function testing that `base` compiles.""" - - def test_compile(self): - """Test that `base` is correctly compiled.""" - if base is None: - return + def _create_generation_test(cls, base): + """Return a function testing that `base.tex` is correctly generated.""" + def test_generation(self): + """Test that `base.tex` is correctly generated.""" songbook = "{}.sb".format(base) # Check tex generation @@ -83,13 +84,26 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): expected, ) + test_generation.__doc__ = ( + "Test that '{base}' is correctly generated." + ).format(base=os.path.basename(base)) + return test_generation + + @classmethod + def _create_compilation_test(cls, base): + """Return a function testing that `base.tex` is correctly compiled.""" + @unittest.skipIf('TRAVIS' in os.environ, + "Travis does not support lualatex compilation yet") + def test_compilation(self): + """Test that `base` is rendered to pdf.""" # Check compilation + songbook = "{}.sb".format(base) self.assertEqual(0, self.compile_songbook(songbook)) - test_compile.__doc__ = ( + test_compilation.__doc__ = ( "Test that '{base}' is correctly compiled." ).format(base=os.path.basename(base)) - return test_compile + return test_compilation @staticmethod def compile_songbook(songbook, steps=None): diff --git a/test/test_compilation/unicode.sb b/test/test_compilation/unicode.sb new file mode 100644 index 00000000..fffed7cc --- /dev/null +++ b/test/test_compilation/unicode.sb @@ -0,0 +1,4 @@ +{ +"datadir": ["unicode_datadir"], +"lang": "en" +} diff --git a/test/test_compilation/unicode.tex.control b/test/test_compilation/unicode.tex.control new file mode 100644 index 00000000..9c8e946d --- /dev/null +++ b/test/test_compilation/unicode.tex.control @@ -0,0 +1,114 @@ + + + + + + +%% 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@/unicode_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@/unicode_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}{unicode_title} +\newauthorindex{authidx}{unicode_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/./nonbreak.sgc + +\selectlanguage{english} + +\beginsong{Song with non breakable space}[ + by={ + Author with non breaking space chars }, +] + + + + +\begin{verse} + Non break +\end{verse} + +\endsong + +\end{songs} + + + + +\end{document} diff --git a/test/test_compilation/unicode_datadir/songs/nonbreak.sgc b/test/test_compilation/unicode_datadir/songs/nonbreak.sgc new file mode 100644 index 00000000..841d9acb --- /dev/null +++ b/test/test_compilation/unicode_datadir/songs/nonbreak.sgc @@ -0,0 +1,5 @@ +{title : Song with non breakable space} +{by: Author with non breaking space chars} +{lang: en} + +Non break diff --git a/tox.ini b/tox.ini index aa6c7c00..1b6a3337 100644 --- a/tox.ini +++ b/tox.ini @@ -7,6 +7,7 @@ envlist = py34, lint [testenv] commands = {envpython} setup.py test +passenv = TRAVIS deps = [testenv:lint]