Browse Source

[chordpro] Songs can now be rendered in any format (given that it has been implemented)

pull/79/head
Louis 10 years ago
parent
commit
3c89a70f73
  1. 5
      patacrep/songs/chordpro/__init__.py
  2. 13
      patacrep/songs/chordpro/ast.py
  3. 9
      patacrep/songs/chordpro/data/chordpro/content_chord
  4. 6
      patacrep/songs/chordpro/data/chordpro/content_chordlist
  5. 1
      patacrep/songs/chordpro/data/chordpro/content_comment
  6. 25
      patacrep/songs/chordpro/data/chordpro/content_define
  7. 3
      patacrep/songs/chordpro/data/chordpro/content_error
  8. 1
      patacrep/songs/chordpro/data/chordpro/content_guitar_comment
  9. 1
      patacrep/songs/chordpro/data/chordpro/content_image
  10. 3
      patacrep/songs/chordpro/data/chordpro/content_line
  11. 2
      patacrep/songs/chordpro/data/chordpro/content_newline
  12. 1
      patacrep/songs/chordpro/data/chordpro/content_partition
  13. 1
      patacrep/songs/chordpro/data/chordpro/content_space
  14. 5
      patacrep/songs/chordpro/data/chordpro/content_tablature
  15. 5
      patacrep/songs/chordpro/data/chordpro/content_verse
  16. 1
      patacrep/songs/chordpro/data/chordpro/content_word
  17. 34
      patacrep/songs/chordpro/data/chordpro/song
  18. 2
      patacrep/songs/chordpro/data/latex/content_error
  19. 2
      patacrep/songs/chordpro/test/00.txt
  20. 1
      patacrep/songs/chordpro/test/01.txt
  21. 1
      patacrep/songs/chordpro/test/02.txt
  22. 1
      patacrep/songs/chordpro/test/03.txt
  23. 1
      patacrep/songs/chordpro/test/04.txt
  24. 1
      patacrep/songs/chordpro/test/05.txt
  25. 1
      patacrep/songs/chordpro/test/06.txt
  26. 1
      patacrep/songs/chordpro/test/07.txt
  27. 3
      patacrep/songs/chordpro/test/08.txt
  28. 3
      patacrep/songs/chordpro/test/09.txt
  29. 1
      patacrep/songs/chordpro/test/10.txt
  30. 1
      patacrep/songs/chordpro/test/11.txt
  31. 1
      patacrep/songs/chordpro/test/12.txt
  32. 1
      patacrep/songs/chordpro/test/13.txt
  33. 1
      patacrep/songs/chordpro/test/21.txt
  34. 1
      patacrep/songs/chordpro/test/22.txt
  35. 2
      patacrep/songs/chordpro/test/23.txt
  36. 1
      patacrep/songs/chordpro/test/24.txt
  37. 1
      patacrep/songs/chordpro/test/25.txt
  38. 1
      patacrep/songs/chordpro/test/26.txt
  39. 1
      patacrep/songs/chordpro/test/27.txt
  40. 3
      patacrep/songs/chordpro/test/28.txt
  41. 3
      patacrep/songs/chordpro/test/29.txt
  42. 1
      patacrep/songs/chordpro/test/chords.txt
  43. 2
      patacrep/songs/chordpro/test/customchords.txt
  44. 16
      patacrep/songs/chordpro/test/greensleeves.txt
  45. 1
      patacrep/songs/chordpro/test/invalid_chord.txt
  46. 2
      patacrep/songs/chordpro/test/invalid_customchord.txt
  47. 2
      patacrep/songs/chordpro/test/metadata.sgc
  48. 13
      patacrep/songs/chordpro/test/metadata.txt
  49. 17
      patacrep/songs/chordpro/test/test_parser.py
  50. 14
      patacrep/songs/syntax.py

5
patacrep/songs/chordpro/__init__.py

@ -30,10 +30,7 @@ class ChordproSong(Song):
def render(self, output, output_format):
context = {
'language': self.config.get(
'lang',
self.cached['song'].get_data_argument('language', 'english'),
),
'language': self.languages[0],
"path": files.relpath(self.fullpath, os.path.dirname(output)),
"titles": self.titles,
"authors": self.authors,

13
patacrep/songs/chordpro/ast.py

@ -367,19 +367,13 @@ class Song(AST):
def add_key(self, data):
"""Add a new {key: foo: bar} directive."""
key, *argument = data.argument.split(":")
self._keys.insert(0, Directive(
if 'keys' not in self.meta:
self.meta['keys'] = []
self.meta['keys'].insert(0, Directive(
key.strip(),
":".join(argument).strip(),
))
@property
def keys(self):
"""Return the list of keys.
That is, directive that where given of the form ``{key: foo: bar}``.
"""
return self._keys
def _process_relative(self, directive):
"""Return the directive, in which the argument is given relative to file
@ -484,6 +478,7 @@ class Tab(AST):
"""Tablature"""
inline = True
_template = "tablature"
def __init__(self):
super().__init__()

9
patacrep/songs/chordpro/data/chordpro/content_chord

@ -0,0 +1,9 @@
((- content.key -))
(* if content.alteration *)(( content.alteration ))(* endif -*)
(* if content.modifier *)((content.modifier))(* endif -*)
(* if content.addnote *)((content.addnote))(* endif -*)
(* if content.basskey -*)
/
((- content.basskey -))
(* if content.bassalteration *)(( content.bassalteration ))(* endif -*)
(* endif -*)

6
patacrep/songs/chordpro/data/chordpro/content_chordlist

@ -0,0 +1,6 @@
[
(*- for chord in content.chords -*)
(* if not loop.first *) (* endif -*)
(( render(chord) -))
(* endfor -*)
]

1
patacrep/songs/chordpro/data/chordpro/content_comment

@ -0,0 +1 @@
{comment: (( content.argument ))}

25
patacrep/songs/chordpro/data/chordpro/content_define

@ -0,0 +1,25 @@
{define: (( render(content.key) ))
(*- if content.basefret *)
base-fret ((content.basefret))
(*- endif *)
frets
(*- for string in content.frets -*)
(( " " -))
(*- if string is none -*)
x
(*- else -*)
(( string -))
(*- endif -*)
(*- endfor -*)
(* if content.fingers *)
fingers
(*- for finger in content.fingers -*)
(( " " -))
(* if finger is none -*)
-
(*- else -*)
(( finger -))
(* endif -*)
(* endfor -*)
(* endif -*)
}

3
patacrep/songs/chordpro/data/chordpro/content_error

@ -0,0 +1,3 @@
ERROR : Template not found for "(( content.__class__.__name__ ))". See the logs for details.

1
patacrep/songs/chordpro/data/chordpro/content_guitar_comment

@ -0,0 +1 @@
{guitar_comment: (( content.argument ))}

1
patacrep/songs/chordpro/data/chordpro/content_image

@ -0,0 +1 @@
{image: (( content.argument ))}

3
patacrep/songs/chordpro/data/chordpro/content_line

@ -0,0 +1,3 @@
(* for item in content.line -*)
(( render(item) ))
(*- endfor *)

2
patacrep/songs/chordpro/data/chordpro/content_newline

@ -0,0 +1,2 @@

1
patacrep/songs/chordpro/data/chordpro/content_partition

@ -0,0 +1 @@
{partition: ((content.argument))}

1
patacrep/songs/chordpro/data/chordpro/content_space

@ -0,0 +1 @@

5
patacrep/songs/chordpro/data/chordpro/content_tablature

@ -0,0 +1,5 @@
{start_of_tab}
(* for foo in content.content *)
(( foo ))
(* endfor *)
{end_of_tab}

5
patacrep/songs/chordpro/data/chordpro/content_verse

@ -0,0 +1,5 @@
{start_of_(( content.type ))}
(* for line in content.lines *)
(( render(line) ))
(* endfor *)
{end_of_(( content.type ))}

1
patacrep/songs/chordpro/data/chordpro/content_word

@ -0,0 +1 @@
(( content.value ))

34
patacrep/songs/chordpro/data/chordpro/song

@ -0,0 +1,34 @@
(* if language is defined -*)
{language: (( language ))}
(* endif *)
(* if metadata.columns is defined -*)
{columns: (( metadata.columns ))}
(* endif *)
(* if metadata.capo is defined -*)
{capo: (( metadata.capo ))}
(* endif *)
(*- for title in titles -*)
{title: (( title ))}
(* endfor -*)
(* for author in authors -*)
{artist: (( author[1] )) (( author[0] ))}
(* endfor *)
(*- for key in ['album', 'copyright', 'cov', 'vcov', 'tag'] *)
(* if key in metadata -*)
{(( key )): (( metadata[key] ))}
(* endif *)
(* endfor *)
(*- for key in metadata.keys -*)
{key: (( key.keyword )): (( key.argument ))}
(* endfor *)
(*- for chord in metadata['define'] *)
((- render(chord) ))
(* endfor *)
(* for item in content -*)
(( render(item) ))
(* endfor *)

2
patacrep/songs/chordpro/data/latex/content_error

@ -1,3 +1,3 @@
ERROR : Template not found for \verb+(( content.__class__))+. See the logs for details.
ERROR : Template not found for \verb+(( content.__class__.__name__ ))+. See the logs for details.

2
patacrep/songs/chordpro/test/00.txt

@ -1 +1 @@
{language: english}

1
patacrep/songs/chordpro/test/01.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_verse}
A verse line

1
patacrep/songs/chordpro/test/02.txt

@ -1,2 +1,3 @@
{language: english}
{title: A directive}

1
patacrep/songs/chordpro/test/03.txt

@ -1 +1,2 @@
{language: english}

1
patacrep/songs/chordpro/test/04.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_chorus}
A one line chorus

1
patacrep/songs/chordpro/test/05.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_bridge}
A one line bridge

1
patacrep/songs/chordpro/test/06.txt

@ -1 +1,2 @@
{language: english}

1
patacrep/songs/chordpro/test/07.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_tab}
A tab

3
patacrep/songs/chordpro/test/08.txt

@ -1,3 +1,6 @@
{language: english}
{start_of_verse}
A lot of new lines

3
patacrep/songs/chordpro/test/09.txt

@ -1,5 +1,8 @@
{language: english}
{title: and a directive}
{start_of_verse}
A lot of new lines
{end_of_verse}

1
patacrep/songs/chordpro/test/10.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_verse}
A line[A] with a chord

1
patacrep/songs/chordpro/test/11.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_verse}
A line ending with a chord[A]

1
patacrep/songs/chordpro/test/12.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_verse}
[A]A line starting with a chord

1
patacrep/songs/chordpro/test/13.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_tab}
A table

1
patacrep/songs/chordpro/test/21.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_verse}
A verse line

1
patacrep/songs/chordpro/test/22.txt

@ -1,2 +1,3 @@
{language: english}
{title: A directive}

2
patacrep/songs/chordpro/test/23.txt

@ -1 +1 @@
{language: english}

1
patacrep/songs/chordpro/test/24.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_chorus}
A one line chorus

1
patacrep/songs/chordpro/test/25.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_bridge}
A one line bridge

1
patacrep/songs/chordpro/test/26.txt

@ -1 +1,2 @@
{language: english}

1
patacrep/songs/chordpro/test/27.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_tab}
A tab

3
patacrep/songs/chordpro/test/28.txt

@ -1,3 +1,6 @@
{language: english}
{start_of_verse}
A lot of new lines

3
patacrep/songs/chordpro/test/29.txt

@ -1,5 +1,8 @@
{language: english}
{title: and a directive}
{start_of_verse}
A lot of new lines
{end_of_verse}

1
patacrep/songs/chordpro/test/chords.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_verse}
[A]Simple

2
patacrep/songs/chordpro/test/customchords.txt

@ -1,3 +1,3 @@
{language: english}
{define: E4 base-fret 7 frets 0 1 3 3 x x}
{define: E5 base-fret 7 frets 0 1 3 3 x x fingers - 1 2 3 - -}

16
patacrep/songs/chordpro/test/greensleeves.txt

@ -1,14 +1,17 @@
{language: english}
{columns: 2}
{title: Greensleeves}
{title: Un autre sous-titre}
{title: Un sous titre}
{by: Traditionnel}
{language: english}
{columns: 2}
{cov: DIRNAME/traditionnel}
{artist: Traditionnel}
{album: Angleterre}
{cov: DIRNAME/traditionnel}
{partition: DIRNAME/greensleeves.ly}
{start_of_verse}
A[Am]las, my love, ye [G]do me wrong
To [Am]cast me oft dis[E]curteously
@ -16,6 +19,7 @@
De[Am]lighting [E]in your [Am]companie
{end_of_verse}
{start_of_chorus}
[C]Green[B]sleeves was [G]all my joy
[Am]Greensleeves was [E]my delight
@ -23,6 +27,7 @@
And [Am]who but [E]Ladie [Am]Greensleeves
{end_of_chorus}
{start_of_verse}
I [Am]have been ready [G]at your hand
To [Am]grant what ever [E]you would crave
@ -30,6 +35,7 @@
Your [Am]love and [E]good will [Am]for to have
{end_of_verse}
{start_of_verse}
I [Am]bought thee kerchers [G]to thy head
That [Am]were wrought fine and [E]gallantly
@ -37,6 +43,7 @@
Which [Am]cost my [E]purse well [Am]favouredly
{end_of_verse}
{start_of_verse}
I [Am]bought thee peticotes [G]of the best
The [Am]cloth so fine as [E]fine might be
@ -44,6 +51,7 @@
And [Am]all this [E]cost I [Am]spent on thee
{end_of_verse}
{start_of_verse}
Thy [Am]smock of silke, both [G]faire and white
With [Am]gold embrodered [E]gorgeously

1
patacrep/songs/chordpro/test/invalid_chord.txt

@ -1,3 +1,4 @@
{language: english}
{start_of_verse}
This is invalid.

2
patacrep/songs/chordpro/test/invalid_customchord.txt

@ -0,0 +1,2 @@
{language: english}

2
patacrep/songs/chordpro/test/metadata.sgc

@ -8,7 +8,7 @@
{language: english}
{by: Author1}
{artist: Author2}
{album: Albom}
{album: Album}
{copyright: Copyright}
{cover: Cover}
{vcover: VCover}

13
patacrep/songs/chordpro/test/metadata.txt

@ -1,19 +1,18 @@
{language: french}
{capo: Capo}
{title: Title}
{title: Subtitle1}
{title: Subtitle2}
{title: Subtitle3}
{title: Subtitle4}
{title: Subtitle5}
{by: Author1}
{by: Author2}
{key: {foo: Foo}}
{language: french}
{language: english}
{album: Albom}
{artist: Author1}
{artist: Author2}
{album: Album}
{copyright: Copyright}
{cov: DIRNAME/Cover}
{vcov: VCover}
{capo: Capo}
{key: foo: Foo}
{comment: Comment}
{guitar_comment: GuitarComment}

17
patacrep/songs/chordpro/test/test_parser.py

@ -6,7 +6,8 @@ import glob
import os
import unittest
from patacrep.songs.chordpro import syntax as chordpro
from patacrep.build import DEFAULT_CONFIG
from patacrep.songs.chordpro import ChordproSong
class ParserTxtRenderer(unittest.TestCase):
"""Test parser, and renderer as a txt file."""
@ -26,14 +27,16 @@ class ParserTxtRenderer(unittest.TestCase):
if self.basename is None:
return
with open("{}.sgc".format(self.basename), 'r', encoding='utf8') as sourcefile:
config = DEFAULT_CONFIG.copy()
config.update({
'encoding': 'utf8',
'_compiled_authwords': {},
})
with open("{}.txt".format(self.basename), 'r', encoding='utf8') as expectfile:
chordproname = "{}.sgc".format(self.basename)
self.assertMultiLineEqual(
chordpro.parse_song(
sourcefile.read(),
os.path.abspath(sourcefile.name),
).chordpro().strip(),
expectfile.read().strip().replace("DIRNAME", os.path.dirname(self.basename)),
ChordproSong(None, chordproname, config).render(output=chordproname, output_format="chordpro").strip(),
expectfile.read().strip().replace("DIRNAME", os.path.dirname(self.basename)).strip(),
)
def load_tests(__loader, tests, __pattern):

14
patacrep/songs/syntax.py

@ -21,13 +21,18 @@ class Parser:
return column
@staticmethod
def error(*, line, column=None, message=""):
def error(*, line=None, column=None, message=""):
"""Display an error message"""
text = "Line {}".format(line)
coordinates = []
if line is not None:
coordinates.append("line {}".format(line))
if column is not None:
text += ", column {}".format(column)
if message:
coordinates.append("column {}".format(column))
text = ", ".join(coordinates)
if message and text:
text += ": " + message
elif message:
text += message
else:
text += "."
LOGGER.error(text)
@ -36,7 +41,6 @@ class Parser:
"""Manage parsing errors."""
if token is None:
self.error(
line=token.lineno,
message="Unexpected end of file.",
)
else:

Loading…
Cancel
Save