mirror of https://github.com/patacrep/patacrep.git
Louis
9 years ago
38 changed files with 438 additions and 18 deletions
@ -0,0 +1 @@ |
|||
["subdir/chordpro.csg"] |
@ -0,0 +1 @@ |
|||
[["cwd(subdir)"]] |
@ -0,0 +1 @@ |
|||
["subdir/chordpro.csg", "exsong.sg"] |
@ -0,0 +1 @@ |
|||
[["cwd(subdir)", "exsong.sg", "intersong.is", "jsonlist.json", "texfile.tex", "texsong.tsg", "chordpro.csg", "subdir/chordpro.csg"], "exsong.sg"] |
@ -0,0 +1 @@ |
|||
["exsong.sg", "chordpro.csg", "subdir/chordpro.csg"] |
@ -0,0 +1,51 @@ |
|||
{lang : en} |
|||
{columns : 2} |
|||
{ title : Greensleeves} |
|||
{subtitle: Test of the chordpro format} |
|||
{artist: Traditionnel} |
|||
{artist: Prénom Nom} |
|||
{cover : traditionnel.jpg } |
|||
{album :Angleterre} |
|||
|
|||
{partition : greensleeves.ly} |
|||
|
|||
|
|||
A[Am]las, my love, ye [G]do me wrong |
|||
To [Am]cast me oft dis[E]curteously |
|||
And [Am]I have loved [G]you so long |
|||
De[Am]lighting [E]in your [Am]companie |
|||
|
|||
{start_of_chorus} |
|||
[C]Greensleeves was [G]all my joy |
|||
[Am]Greensleeves was [E]my delight |
|||
[C]Greensleeves was my [G]heart of gold |
|||
And [Am]who but [E]Ladie [Am]Greensleeves |
|||
{end_of_chorus} |
|||
|
|||
I [Am]have been ready [G]at your hand |
|||
To [Am]grant what ever [E]you would crave |
|||
I [Am]have both waged [G]life and land |
|||
Your [Am]love and [E]good will [Am]for to have |
|||
|
|||
I [Am]bought thee kerchers [G]to thy head |
|||
That [Am]were wrought fine and [E]gallantly |
|||
I [Am]kept thee both at [G]boord and bed |
|||
Which [Am]cost my [E]purse well [Am]favouredly |
|||
|
|||
I [Am]bought thee peticotes [G]of the best |
|||
The [Am]cloth so fine as [E]fine might be |
|||
I [Am]gave thee jewels [G]for thy chest |
|||
And [Am]all this [E]cost I [Am]spent on thee |
|||
|
|||
{c:test of comment} |
|||
|
|||
{gc: test of guitar comment} |
|||
|
|||
{image: traditionnel.jpg} |
|||
|
|||
Thy [Am]smock of silke, both [G]faire and white |
|||
With [Am]gold embrodered [E]gorgeously |
|||
Thy [Am]peticote of [G]sendall right |
|||
And [Am]this I [E]bought thee [Am]gladly |
|||
|
|||
|
@ -0,0 +1,10 @@ |
|||
\beginsong{Image included from a different datadir\\\LaTeX} |
|||
[cover={img/datadir2}] |
|||
|
|||
\cover |
|||
|
|||
\lilypond{scores/datadir2.ly} |
|||
|
|||
\image{img/datadir2} |
|||
|
|||
\endsong |
@ -0,0 +1,6 @@ |
|||
\selectlanguage{french} |
|||
\sortassong{}[by={QQ}] |
|||
\begin{intersong} |
|||
|
|||
Lorem ipsum |
|||
\end{intersong} |
@ -0,0 +1,51 @@ |
|||
{lang : en} |
|||
{columns : 2} |
|||
{ title : Greensleeves} |
|||
{subtitle: Test of the chordpro format} |
|||
{artist: Traditionnel} |
|||
{artist: Prénom Nom} |
|||
{cover : traditionnel.jpg } |
|||
{album :Angleterre} |
|||
|
|||
{partition : greensleeves.ly} |
|||
|
|||
|
|||
A[Am]las, my love, ye [G]do me wrong |
|||
To [Am]cast me oft dis[E]curteously |
|||
And [Am]I have loved [G]you so long |
|||
De[Am]lighting [E]in your [Am]companie |
|||
|
|||
{start_of_chorus} |
|||
[C]Greensleeves was [G]all my joy |
|||
[Am]Greensleeves was [E]my delight |
|||
[C]Greensleeves was my [G]heart of gold |
|||
And [Am]who but [E]Ladie [Am]Greensleeves |
|||
{end_of_chorus} |
|||
|
|||
I [Am]have been ready [G]at your hand |
|||
To [Am]grant what ever [E]you would crave |
|||
I [Am]have both waged [G]life and land |
|||
Your [Am]love and [E]good will [Am]for to have |
|||
|
|||
I [Am]bought thee kerchers [G]to thy head |
|||
That [Am]were wrought fine and [E]gallantly |
|||
I [Am]kept thee both at [G]boord and bed |
|||
Which [Am]cost my [E]purse well [Am]favouredly |
|||
|
|||
I [Am]bought thee peticotes [G]of the best |
|||
The [Am]cloth so fine as [E]fine might be |
|||
I [Am]gave thee jewels [G]for thy chest |
|||
And [Am]all this [E]cost I [Am]spent on thee |
|||
|
|||
{c:test of comment} |
|||
|
|||
{gc: test of guitar comment} |
|||
|
|||
{image: traditionnel.jpg} |
|||
|
|||
Thy [Am]smock of silke, both [G]faire and white |
|||
With [Am]gold embrodered [E]gorgeously |
|||
Thy [Am]peticote of [G]sendall right |
|||
And [Am]this I [E]bought thee [Am]gladly |
|||
|
|||
|
@ -0,0 +1,70 @@ |
|||
\selectlanguage{french} |
|||
\songcolumns{2} |
|||
\beginsong{Chevaliers de la table ronde} |
|||
[by={Traditionnel},cover={traditionnel},album={France}] |
|||
|
|||
\cover |
|||
\gtab{C}{X32010} |
|||
\gtab{G7}{320001} |
|||
\gtab{F}{1:022100} |
|||
|
|||
\begin{verse} |
|||
Cheva\[C]liers de la Table Ronde |
|||
Goûtons \[G7]voir si le vin est \[C]bon |
|||
\rep{2} |
|||
\end{verse} |
|||
|
|||
\begin{chorus} |
|||
Goûtons \[F]voir, \echo{oui, oui, oui} |
|||
Goûtons \[C]voir, \echo{non, non, non} |
|||
Goûtons \[G7]voir si le vin est bon |
|||
\rep{2} |
|||
\end{chorus} |
|||
|
|||
\begin{verse} |
|||
S'il est bon, s'il est agréable |
|||
J'en boirai jusqu'à mon plaisir |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
J'en boirai cinq à six bouteilles |
|||
Et encore, ce n'est pas beaucoup |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Si je meurs, je veux qu'on m'enterre |
|||
Dans une cave où il y a du bon vin |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Les deux pieds contre la muraille |
|||
Et la tête sous le robinet |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Et les quatre plus grands ivrognes |
|||
Porteront les quatre coins du drap |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Pour donner le discours d'usage |
|||
On prendra le bistrot du coin |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Et si le tonneau se débouche |
|||
J'en boirai jusqu'à mon plaisir |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Et s'il en reste quelques gouttes |
|||
Ce sera pour nous rafraîchir |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Sur ma tombe, je veux qu'on inscrive |
|||
\emph{Ici gît le roi des buveurs} |
|||
\end{verse} |
|||
|
|||
\endsong |
|||
|
@ -0,0 +1,70 @@ |
|||
\selectlanguage{french} |
|||
\songcolumns{2} |
|||
\beginsong{Chevaliers de la table ronde} |
|||
[by={Traditionnel},cover={traditionnel},album={France}] |
|||
|
|||
\cover |
|||
\gtab{C}{X32010} |
|||
\gtab{G7}{320001} |
|||
\gtab{F}{1:022100} |
|||
|
|||
\begin{verse} |
|||
Cheva\[C]liers de la Table Ronde |
|||
Goûtons \[G7]voir si le vin est \[C]bon |
|||
\rep{2} |
|||
\end{verse} |
|||
|
|||
\begin{chorus} |
|||
Goûtons \[F]voir, \echo{oui, oui, oui} |
|||
Goûtons \[C]voir, \echo{non, non, non} |
|||
Goûtons \[G7]voir si le vin est bon |
|||
\rep{2} |
|||
\end{chorus} |
|||
|
|||
\begin{verse} |
|||
S'il est bon, s'il est agréable |
|||
J'en boirai jusqu'à mon plaisir |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
J'en boirai cinq à six bouteilles |
|||
Et encore, ce n'est pas beaucoup |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Si je meurs, je veux qu'on m'enterre |
|||
Dans une cave où il y a du bon vin |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Les deux pieds contre la muraille |
|||
Et la tête sous le robinet |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Et les quatre plus grands ivrognes |
|||
Porteront les quatre coins du drap |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Pour donner le discours d'usage |
|||
On prendra le bistrot du coin |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Et si le tonneau se débouche |
|||
J'en boirai jusqu'à mon plaisir |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Et s'il en reste quelques gouttes |
|||
Ce sera pour nous rafraîchir |
|||
\end{verse} |
|||
|
|||
\begin{verse} |
|||
Sur ma tombe, je veux qu'on inscrive |
|||
\emph{Ici gît le roi des buveurs} |
|||
\end{verse} |
|||
|
|||
\endsong |
|||
|
@ -0,0 +1 @@ |
|||
["chordpro.csg"] |
@ -0,0 +1 @@ |
|||
["*.csg"] |
@ -0,0 +1 @@ |
|||
["exsong.sg", "chordpro.csg", "subdir/chordpro.csg"] |
@ -0,0 +1 @@ |
|||
[["include" , "custom_list.json"]] |
@ -0,0 +1 @@ |
|||
["section:Traditional", "exsong.sg", "section:Example", "texsong.tsg", "chordpro.csg", "exsong.sg"] |
@ -0,0 +1,6 @@ |
|||
[["section", "Traditional"], |
|||
"exsong.sg", |
|||
["section", "Example"], |
|||
"texsong.tsg", |
|||
"chordpro.csg", |
|||
"exsong.sg"] |
@ -0,0 +1 @@ |
|||
["section:(tradi)Traditional", "exsong.sg", "section*:Example", "texsong.tsg", "chordpro.csg", "exsong.sg"] |
@ -0,0 +1,6 @@ |
|||
[["section", "Traditional", "tradi"], |
|||
"exsong.sg", |
|||
["section*", "Example"], |
|||
"texsong.tsg", |
|||
"chordpro.csg", |
|||
"exsong.sg"] |
@ -0,0 +1 @@ |
|||
["exsong.sg", "texsong.tsg", "chordpro.csg", "subdir/chordpro.csg"] |
@ -0,0 +1 @@ |
|||
["exsong.sg", "intersong.is", "jsonlist.json", "texfile.tex", "texsong.tsg", "chordpro.csg", "subdir/chordpro.csg"] |
@ -0,0 +1 @@ |
|||
["songsection:Traditional", "exsong.sg", "songchapter:English", "texsong.tsg", "chordpro.csg", "exsong.sg"] |
@ -0,0 +1,6 @@ |
|||
[["songsection", "Traditional"], |
|||
"exsong.sg", |
|||
["songchapter", "English"], |
|||
"texsong.tsg", |
|||
"chordpro.csg", |
|||
"exsong.sg"] |
@ -0,0 +1 @@ |
|||
["chordpro.csg", "exsong.sg", "subdir/chordpro.csg", "texsong.tsg"] |
@ -0,0 +1 @@ |
|||
[["sorted(fullpath)"]] |
@ -0,0 +1,118 @@ |
|||
"""Tests for the content plugins.""" |
|||
|
|||
# pylint: disable=too-few-public-methods |
|||
|
|||
import glob |
|||
import os |
|||
import unittest |
|||
import json |
|||
|
|||
from patacrep.songs import DataSubpath, DEFAULT_CONFIG |
|||
from patacrep import content, files |
|||
from patacrep.content import song, section, songsection, tex |
|||
|
|||
from .. import logging_reduced |
|||
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" |
|||
argument of a .sb file. |
|||
It controls that the generated file list is equal to the one in `foo.control`. |
|||
""" |
|||
|
|||
maxDiff = None |
|||
config = None |
|||
|
|||
@classmethod |
|||
def setUpClass(cls): |
|||
cls._generate_config() |
|||
|
|||
@classmethod |
|||
def _iter_testmethods(cls): |
|||
"""Iterate over dynamically generated test methods""" |
|||
for source in sorted(glob.glob(os.path.join( |
|||
os.path.dirname(__file__), |
|||
'*.source', |
|||
))): |
|||
base = source[:-len(".source")] |
|||
yield ( |
|||
"test_content_{}".format(os.path.basename(base)), |
|||
cls._create_content_test(base), |
|||
) |
|||
|
|||
@classmethod |
|||
def _create_content_test(cls, base): |
|||
"""Return a function that `base.source` produces the correct file list""" |
|||
|
|||
def test_content(self): |
|||
"""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) |
|||
|
|||
with logging_reduced('patacrep.content.song'): |
|||
expandedlist = content.process_content(sbcontent, cls.config.copy()) |
|||
sourcelist = [cls._clean_path(elem) for elem in expandedlist] |
|||
|
|||
controlname = "{}.control".format(base) |
|||
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) |
|||
|
|||
self.assertEqual(controllist, sourcelist) |
|||
|
|||
test_content.__doc__ = ( |
|||
"Test that '{base}.source' produces the correct file list""" |
|||
).format(base=os.path.basename(base)) |
|||
return test_content |
|||
|
|||
@classmethod |
|||
def _clean_path(cls, elem): |
|||
"""Shorten the path relative to the `songs` directory""" |
|||
if 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, section.Section): |
|||
if elem.short is None: |
|||
return "{}:{}".format(elem.keyword, elem.name) |
|||
else: |
|||
return "{}:({}){}".format(elem.keyword, elem.short, elem.name) |
|||
|
|||
elif isinstance(elem, songsection.SongSection): |
|||
return "{}:{}".format(elem.keyword, elem.name) |
|||
|
|||
elif isinstance(elem, tex.LaTeX): |
|||
return files.path2posix(elem.filename) |
|||
|
|||
else: |
|||
raise Exception(elem) |
|||
|
|||
@classmethod |
|||
def _generate_config(cls): |
|||
"""Generate the config to process the content""" |
|||
|
|||
config = DEFAULT_CONFIG.copy() |
|||
|
|||
datadirpaths = [os.path.join(os.path.dirname(__file__), 'datadir')] |
|||
|
|||
config['datadir'] = datadirpaths |
|||
|
|||
config['_songdir'] = [ |
|||
DataSubpath(path, 'songs') |
|||
for path in datadirpaths |
|||
] |
|||
config['_content_plugins'] = files.load_plugins( |
|||
datadirs=datadirpaths, |
|||
root_modules=['content'], |
|||
keyword='CONTENT_PLUGINS', |
|||
) |
|||
config['_song_plugins'] = files.load_plugins( |
|||
datadirs=datadirpaths, |
|||
root_modules=['songs'], |
|||
keyword='SONG_RENDERERS', |
|||
)['tsg'] |
|||
cls.config = config |
@ -0,0 +1 @@ |
|||
["test/test_content/datadir/songs/texfile.tex"] |
@ -0,0 +1 @@ |
|||
[["tex", "texfile.tex", "chordpro.csg"]] |
Loading…
Reference in new issue