@ -1,18 +0,0 @@ |
|||||
{ |
|
||||
"bookoptions" : [ |
|
||||
"diagram", |
|
||||
"repeatchords", |
|
||||
"lilypond", |
|
||||
"pictures" |
|
||||
], |
|
||||
"datadir": ["datadir2"], |
|
||||
"booktype" : "chorded", |
|
||||
"template" : "patacrep.tex", |
|
||||
"lang" : "french", |
|
||||
"encoding": "utf8", |
|
||||
"authwords" : { |
|
||||
"sep" : ["and", "et"] |
|
||||
}, |
|
||||
"content": [["sorted", "subdir/*.sg", "subdir/*.sgc"]] |
|
||||
|
|
||||
} |
|
Before Width: | Height: | Size: 645 B |
@ -1,19 +0,0 @@ |
|||||
\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. |
|
||||
} |
|
||||
} |
|
Before Width: | Height: | Size: 513 B |
Before Width: | Height: | Size: 645 B |
@ -1,10 +0,0 @@ |
|||||
\beginsong{Image included from root directory\\\LaTeX} |
|
||||
[cov={root}] |
|
||||
|
|
||||
\cover |
|
||||
|
|
||||
\lilypond{root.ly} |
|
||||
|
|
||||
\image{root} |
|
||||
|
|
||||
\endsong |
|
@ -1,6 +0,0 @@ |
|||||
{title : Image included from root directory} |
|
||||
{subtitle: Chordpro} |
|
||||
{cover: root.png} |
|
||||
|
|
||||
{partition: root.ly} |
|
||||
{image: root.png} |
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
@ -1,9 +1,6 @@ |
|||||
#! /usr/bin/env python3 |
#! /bin/sh |
||||
|
|
||||
# Do not edit this file. This file is just a helper file for development test. |
# Do not edit this file. This file is just a helper file for development test. |
||||
# It is not part of the distributed software. |
# It is not part of the distributed software. |
||||
|
|
||||
"""Command line tool to compile songbooks using the songbook library.""" |
python -m patacrep.songbook $* |
||||
|
|
||||
from patacrep.songbook import main |
|
||||
main() |
|
||||
|
@ -0,0 +1,25 @@ |
|||||
|
"""Dynamic creation of test methods.""" |
||||
|
|
||||
|
class DynamicTest(type): |
||||
|
"""Metaclass that creates on-the-fly test methods. |
||||
|
|
||||
|
Each class implementing this metaclass must define two class methods: |
||||
|
|
||||
|
- `_iter_testmethods`, which iterate over `(methodname, args)`, where |
||||
|
`methodname` is the name of a test method to create, and `args` is a list |
||||
|
of arguments to pass to `_create_test`; |
||||
|
- `_create_test`, a method returning a test method. |
||||
|
""" |
||||
|
|
||||
|
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)) |
||||
|
|
||||
|
def _iter_testmethods(cls): |
||||
|
"""Iterate over test methods.""" |
||||
|
raise NotImplementedError() |
||||
|
|
||||
|
def _create_test(cls, *args, **kwargs): |
||||
|
"""Create and return a test method.""" |
||||
|
raise NotImplementedError() |
@ -0,0 +1,2 @@ |
|||||
|
/*tex |
||||
|
.cache |
@ -0,0 +1,7 @@ |
|||||
|
{ |
||||
|
"bookoptions" : [ |
||||
|
"pictures" |
||||
|
], |
||||
|
"datadir": ["subdir_datadir", "subdir_datadir2"], |
||||
|
"lang": "en" |
||||
|
} |
@ -0,0 +1,179 @@ |
|||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
%% 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 <http://www.patacrep.com> |
||||
|
|
||||
|
\makeatletter |
||||
|
\def\input@path{ % |
||||
|
{@TEST_FOLDER@/subdir_datadir/latex/} % |
||||
|
{@TEST_FOLDER@/subdir_datadir2/latex/} % |
||||
|
{@TEST_FOLDER@/latex/} % |
||||
|
{@DATA_FOLDER@/latex/} % |
||||
|
} |
||||
|
\makeatother |
||||
|
|
||||
|
\documentclass[ |
||||
|
]{article} |
||||
|
|
||||
|
\usepackage[ |
||||
|
chorded, |
||||
|
pictures, |
||||
|
guitar, |
||||
|
]{patacrep} |
||||
|
|
||||
|
\usepackage[utf8]{inputenc} |
||||
|
\usepackage[T1]{fontenc} |
||||
|
\usepackage{lmodern} |
||||
|
|
||||
|
|
||||
|
\PassOptionsToPackage{english}{babel} |
||||
|
\usepackage[english]{babel} |
||||
|
\lang{english} |
||||
|
|
||||
|
\usepackage{graphicx} |
||||
|
\graphicspath{ % |
||||
|
{@TEST_FOLDER@/subdir_datadir/} % |
||||
|
{@TEST_FOLDER@/subdir_datadir2/} % |
||||
|
{@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}{subdir_title} |
||||
|
\newauthorindex{authidx}{subdir_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/./datadir.sg |
||||
|
|
||||
|
\import{subdir_datadir/songs/}{datadir.sg} |
||||
|
|
||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
||||
|
%% songs/./datadir.sgc |
||||
|
|
||||
|
\selectlanguage{english} |
||||
|
|
||||
|
\beginsong{Image included from datadir\\ |
||||
|
Chordpro}[ |
||||
|
by={ |
||||
|
}, |
||||
|
cov={img/datadir.png}, |
||||
|
] |
||||
|
|
||||
|
\cover |
||||
|
|
||||
|
|
||||
|
|
||||
|
\lilypond{scores/datadir.ly} |
||||
|
\image{img/datadir.png} |
||||
|
|
||||
|
|
||||
|
\endsong |
||||
|
|
||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
||||
|
%% songs/./datadir2.sg |
||||
|
|
||||
|
\import{subdir_datadir/songs/}{datadir2.sg} |
||||
|
|
||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
||||
|
%% songs/./datadir2.sgc |
||||
|
|
||||
|
\selectlanguage{english} |
||||
|
|
||||
|
\beginsong{Image included from a different datadir\\ |
||||
|
Chordpro}[ |
||||
|
by={ |
||||
|
}, |
||||
|
cov={img/datadir2.png}, |
||||
|
] |
||||
|
|
||||
|
\cover |
||||
|
|
||||
|
|
||||
|
|
||||
|
\lilypond{scores/datadir2.ly} |
||||
|
\image{img/datadir2.png} |
||||
|
|
||||
|
|
||||
|
\endsong |
||||
|
|
||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
||||
|
%% songs/./relative.sg |
||||
|
|
||||
|
\import{subdir_datadir/songs/}{relative.sg} |
||||
|
|
||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
||||
|
%% songs/./relative.sgc |
||||
|
|
||||
|
\selectlanguage{english} |
||||
|
|
||||
|
\beginsong{Image included from song directory\\ |
||||
|
Chordpro}[ |
||||
|
by={ |
||||
|
}, |
||||
|
cov={@TEST_FOLDER@/subdir_datadir/songs/./relative.png}, |
||||
|
] |
||||
|
|
||||
|
\cover |
||||
|
|
||||
|
|
||||
|
|
||||
|
\lilypond{@TEST_FOLDER@/subdir_datadir/songs/./relative.ly} |
||||
|
\image{@TEST_FOLDER@/subdir_datadir/songs/./relative.png} |
||||
|
|
||||
|
|
||||
|
\endsong |
||||
|
|
||||
|
\end{songs} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
\end{document} |
After Width: | Height: | Size: 4.0 KiB |
@ -1,6 +1,7 @@ |
|||||
{title : Image included from datadir} |
{title : Image included from datadir} |
||||
{subtitle: Chordpro} |
{subtitle: Chordpro} |
||||
{cover: datadir.png} |
{cover: datadir.png} |
||||
|
{lang: en} |
||||
|
|
||||
{partition: datadir.ly} |
{partition: datadir.ly} |
||||
{image: datadir.png} |
{image: datadir.png} |
@ -1,6 +1,7 @@ |
|||||
{title : Image included from a different datadir} |
{title : Image included from a different datadir} |
||||
{subtitle: Chordpro} |
{subtitle: Chordpro} |
||||
{cover: datadir2.png} |
{cover: datadir2.png} |
||||
|
{lang: en} |
||||
|
|
||||
{partition: datadir2.ly} |
{partition: datadir2.ly} |
||||
{image: datadir2.png} |
{image: datadir2.png} |
After Width: | Height: | Size: 3.9 KiB |
@ -1,6 +1,7 @@ |
|||||
{title : Image included from song directory} |
{title : Image included from song directory} |
||||
{subtitle: Chordpro} |
{subtitle: Chordpro} |
||||
{cover: relative.png} |
{cover: relative.png} |
||||
|
{lang: en} |
||||
|
|
||||
{partition: relative.ly} |
{partition: relative.ly} |
||||
{image: relative.png} |
{image: relative.png} |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1,111 @@ |
|||||
|
"""Tests for the chordpro parser.""" |
||||
|
|
||||
|
# pylint: disable=too-few-public-methods |
||||
|
|
||||
|
import glob |
||||
|
import os |
||||
|
import subprocess |
||||
|
import unittest |
||||
|
import logging |
||||
|
|
||||
|
from patacrep.encoding import open_read |
||||
|
|
||||
|
from .. import dynamic # pylint: disable=unused-import |
||||
|
|
||||
|
LOGGER = logging.getLogger(__name__) |
||||
|
|
||||
|
class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): |
||||
|
"""Test of songbook compilation. |
||||
|
|
||||
|
For any given `foo.sb`, it performs several checks: |
||||
|
- the corresponding tex file is generated; |
||||
|
- the generated tex file matches the `foo.tex.control` control file; |
||||
|
- the compilation (tex, pdf, indexes) works without errors. |
||||
|
|
||||
|
This class does nothing by itself, but its metaclass populates it with test |
||||
|
methods testing parser and renderers. |
||||
|
""" |
||||
|
|
||||
|
maxDiff = None |
||||
|
|
||||
|
@classmethod |
||||
|
def _iter_testmethods(cls): |
||||
|
"""Iterate over songbook files to test.""" |
||||
|
for songbook in sorted(glob.glob(os.path.join( |
||||
|
os.path.dirname(__file__), |
||||
|
'*.sb', |
||||
|
))): |
||||
|
base = songbook[:-len(".sb")] |
||||
|
control = "{}.tex.control".format(base) |
||||
|
if not os.path.exists(control): |
||||
|
continue |
||||
|
yield ( |
||||
|
"test_{}".format(os.path.basename(base)), |
||||
|
[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 |
||||
|
|
||||
|
songbook = "{}.sb".format(base) |
||||
|
|
||||
|
# Check tex generation |
||||
|
self.assertEqual(0, self.compile_songbook(songbook, "tex")) |
||||
|
|
||||
|
# Check generated tex |
||||
|
control = "{}.tex.control".format(base) |
||||
|
tex = "{}.tex".format(base) |
||||
|
with open_read(control) as expectfile: |
||||
|
with open_read(tex) as latexfile: |
||||
|
expected = expectfile.read().strip() |
||||
|
expected = expected.replace( |
||||
|
"@TEST_FOLDER@", |
||||
|
os.path.dirname(__file__), |
||||
|
) |
||||
|
|
||||
|
expected = expected.replace( |
||||
|
"@DATA_FOLDER@", |
||||
|
subprocess.check_output( |
||||
|
["python", "-c", 'import patacrep, pkg_resources; print(pkg_resources.resource_filename(patacrep.__name__, "data"))'], # pylint: disable=line-too-long |
||||
|
universal_newlines=True, |
||||
|
cwd=os.path.dirname(songbook), |
||||
|
).strip(), |
||||
|
) |
||||
|
|
||||
|
self.assertMultiLineEqual( |
||||
|
latexfile.read().strip(), |
||||
|
expected, |
||||
|
) |
||||
|
|
||||
|
# Check compilation |
||||
|
self.assertEqual(0, self.compile_songbook(songbook)) |
||||
|
|
||||
|
test_compile.__doc__ = ( |
||||
|
"Test that '{base}' is correctly compiled." |
||||
|
).format(base=os.path.basename(base)) |
||||
|
return test_compile |
||||
|
|
||||
|
@staticmethod |
||||
|
def compile_songbook(songbook, steps=None): |
||||
|
"""Compile songbook, and return the command return code.""" |
||||
|
command = ['python', '-m', 'patacrep.songbook', songbook, '-v'] |
||||
|
if steps: |
||||
|
command.extend(['--steps', steps]) |
||||
|
|
||||
|
try: |
||||
|
subprocess.check_output( |
||||
|
command, |
||||
|
stderr=subprocess.STDOUT, |
||||
|
universal_newlines=True, |
||||
|
cwd=os.path.dirname(songbook), |
||||
|
) |
||||
|
return 0 |
||||
|
except subprocess.CalledProcessError as error: |
||||
|
LOGGER.warning(error.output) |
||||
|
return error.returncode |