diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000..913363b9 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,50 @@ +environment: + matrix: + - PYTHON: "C:\\Python34" + PYTHON_VERSION: "3.4.x" # currently 3.4.3 + PYTHON_ARCH: "32" + +install: + # Download setup scripts and unzip + - ps: "wget https://github.com/cloudify-cosmo/appveyor-utils/archive/master.zip -OutFile ./master.zip" + - "7z e master.zip */appveyor/* -oappveyor" + + # Install Python (from the official .msi of http://python.org) and pip when + # not already installed. + - "powershell ./appveyor/install.ps1" + + # Prepend newly installed Python to the PATH of this build (this cannot be + # done from inside the powershell script as it would require to restart + # the parent CMD process). + - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" + + # Check that we have the expected version and architecture for Python + - "python --version" + - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" + + # Download miktex portable (if not cached) + - ps: "If (!(Test-Path miktex-portable.exe)){wget http://mirrors.ctan.org/systems/win32/miktex/setup/miktex-portable-2.9.5719.exe -OutFile ./miktex-portable.exe}" + + # Unzip miktex portable + - "7z x miktex-portable.exe * -aot -omiktex > nul" + + # Let the binaries be directly callable + - cmd: set PATH=%PATH%;C:\projects\patacrep\miktex\miktex\bin + + # Update fonts + - cmd: luaotfload-tool.exe --update + + # Manually install required texlive packages + - cmd: mpm.exe --install-some texlive_packages.txt + +build: false # Not a C# project, build stuff at the test step instead. + +before_test: + - "pip install tox" + +test_script: + - "tox" + +# Cache Miktex Portable file +cache: +- C:\projects\patacrep\miktex-portable.exe \ No newline at end of file diff --git a/examples/songs/chevaliers_de_la_table_ronde.sg b/examples/songs/chevaliers_de_la_table_ronde.sg index 77dfa869..81a725ef 100644 --- a/examples/songs/chevaliers_de_la_table_ronde.sg +++ b/examples/songs/chevaliers_de_la_table_ronde.sg @@ -1,7 +1,7 @@ \selectlanguage{french} \songcolumns{2} \beginsong{Chevaliers de la table ronde} - [by={Traditionnel},cov={traditionnel},album={France}] + [by={Traditionnel},cover={traditionnel},album={France}] \cover \gtab{C}{X32010} diff --git a/examples/songs/example-en.sg b/examples/songs/example-en.sg index 7009cc68..971507a6 100644 --- a/examples/songs/example-en.sg +++ b/examples/songs/example-en.sg @@ -24,7 +24,7 @@ % traditionnel : the file "8-bit-lagerfeuer.jpg" that corresponds to the album art % 8 bit lagerfeuer : the album whose song is extracted from \beginsong{Sad robot} - [by={Pornophonique},cov={traditionnel},album={8 bit lagerfeuer}] + [by={Pornophonique},cover={traditionnel},album={8 bit lagerfeuer}] % inserts the album art (8-bit-lagerfeuer.jpg) \cover diff --git a/examples/songs/example-fr.sg b/examples/songs/example-fr.sg index c9264096..a0d68b58 100644 --- a/examples/songs/example-fr.sg +++ b/examples/songs/example-fr.sg @@ -26,7 +26,7 @@ % traditionnel : le fichier "8-bit-lagerfeuer.jpg" correspondant à la pochette de l'album % 8 bit lagerfeuer : le nom de l'album dont la chanson est extraite \beginsong{Sad robot} - [by={Pornophonique},cov={traditionnel},album={8 bit lagerfeuer}] + [by={Pornophonique},cover={traditionnel},album={8 bit lagerfeuer}] % insère la pochette de l'album (8-bit-lagerfeuer.jpg) \cover diff --git a/examples/songs/greensleeves.sg b/examples/songs/greensleeves.sg index 469fab99..2d9f3c19 100644 --- a/examples/songs/greensleeves.sg +++ b/examples/songs/greensleeves.sg @@ -1,7 +1,7 @@ \selectlanguage{english} \songcolumns{2} \beginsong{Greensleeves} - [by={Traditionnel},cov={traditionnel},album={Angleterre}] + [by={Traditionnel},cover={traditionnel},album={Angleterre}] \cover \gtab{Am}{X02210} diff --git a/examples/songs/vent_frais.sg b/examples/songs/vent_frais.sg index 36584ad7..662a9ea2 100644 --- a/examples/songs/vent_frais.sg +++ b/examples/songs/vent_frais.sg @@ -1,7 +1,7 @@ \selectlanguage{french} \songcolumns{2} \beginsong{Vent frais} - [by={Traditionnel},cov={traditionnel},album={France}] + [by={Traditionnel},cover={traditionnel},album={France}] \cover \gtab{Dm}{XX0231} diff --git a/patacrep/__init__.py b/patacrep/__init__.py index e63b5123..60e4cd6a 100644 --- a/patacrep/__init__.py +++ b/patacrep/__init__.py @@ -17,3 +17,6 @@ __version__ = '.'.join([str(number) for number in __TUPLE_VERSION__]) # etc.) __DATADIR__ = os.path.abspath(resource_filename(__name__, 'data')) +def pkg_datapath(*path): + """Return the package data path""" + return os.path.join(__DATADIR__, *path) diff --git a/patacrep/build.py b/patacrep/build.py index 99e8190a..a720b9b1 100644 --- a/patacrep/build.py +++ b/patacrep/build.py @@ -6,7 +6,7 @@ import glob import logging import threading import os.path -from subprocess import Popen, PIPE, call +from subprocess import Popen, PIPE, call, check_call from patacrep import __DATADIR__, authors, content, errors, files from patacrep.index import process_sxd @@ -213,13 +213,27 @@ class SongbookBuilder(object): LOGGER.info("Building '{}.pdf'…".format(self.basename)) self._run_once(self._set_latex) + compiler = "lualatex" + + # Test if the LaTeX compiler is accessible + try: + check_call( + [compiler, "--version"], + stdin=PIPE, + stdout=PIPE, + stderr=PIPE, + universal_newlines=True, + ) + except Exception as error: + raise errors.ExecutableNotFound(compiler) + + # Perform compilation try: process = Popen( - ["lualatex"] + self._lualatex_options + [self.basename], + [compiler] + self._lualatex_options + [self.basename], stdin=PIPE, stdout=PIPE, stderr=PIPE, - env=os.environ, universal_newlines=True, ) except Exception as error: diff --git a/patacrep/content/song.py b/patacrep/content/song.py index 71473aa8..4f9ab809 100755 --- a/patacrep/content/song.py +++ b/patacrep/content/song.py @@ -42,7 +42,7 @@ class SongRenderer(Content): {song} """).format( separator="%"*80, - path=self.song.subpath, + path=files.path2posix(self.song.subpath), song=self.song.render(output=context['filename']), ) diff --git a/patacrep/songs/chordpro/data/chordpro/content_chord b/patacrep/data/ast_templates/chordpro/chordpro/content_chord similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_chord rename to patacrep/data/ast_templates/chordpro/chordpro/content_chord diff --git a/patacrep/songs/chordpro/data/chordpro/content_chordlist b/patacrep/data/ast_templates/chordpro/chordpro/content_chordlist similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_chordlist rename to patacrep/data/ast_templates/chordpro/chordpro/content_chordlist diff --git a/patacrep/songs/chordpro/data/chordpro/content_comment b/patacrep/data/ast_templates/chordpro/chordpro/content_comment similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_comment rename to patacrep/data/ast_templates/chordpro/chordpro/content_comment diff --git a/patacrep/songs/chordpro/data/chordpro/content_define b/patacrep/data/ast_templates/chordpro/chordpro/content_define similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_define rename to patacrep/data/ast_templates/chordpro/chordpro/content_define diff --git a/patacrep/songs/chordpro/data/chordpro/content_endofline b/patacrep/data/ast_templates/chordpro/chordpro/content_endofline similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_endofline rename to patacrep/data/ast_templates/chordpro/chordpro/content_endofline diff --git a/patacrep/songs/chordpro/data/chordpro/content_error b/patacrep/data/ast_templates/chordpro/chordpro/content_error similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_error rename to patacrep/data/ast_templates/chordpro/chordpro/content_error diff --git a/patacrep/songs/chordpro/data/chordpro/content_guitar_comment b/patacrep/data/ast_templates/chordpro/chordpro/content_guitar_comment similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_guitar_comment rename to patacrep/data/ast_templates/chordpro/chordpro/content_guitar_comment diff --git a/patacrep/songs/chordpro/data/chordpro/content_image b/patacrep/data/ast_templates/chordpro/chordpro/content_image similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_image rename to patacrep/data/ast_templates/chordpro/chordpro/content_image diff --git a/patacrep/songs/chordpro/data/chordpro/content_line b/patacrep/data/ast_templates/chordpro/chordpro/content_line similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_line rename to patacrep/data/ast_templates/chordpro/chordpro/content_line diff --git a/patacrep/songs/chordpro/data/chordpro/content_newline b/patacrep/data/ast_templates/chordpro/chordpro/content_newline similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_newline rename to patacrep/data/ast_templates/chordpro/chordpro/content_newline diff --git a/patacrep/songs/chordpro/data/chordpro/content_partition b/patacrep/data/ast_templates/chordpro/chordpro/content_partition similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_partition rename to patacrep/data/ast_templates/chordpro/chordpro/content_partition diff --git a/patacrep/songs/chordpro/data/chordpro/content_space b/patacrep/data/ast_templates/chordpro/chordpro/content_space similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_space rename to patacrep/data/ast_templates/chordpro/chordpro/content_space diff --git a/patacrep/songs/chordpro/data/chordpro/content_tablature b/patacrep/data/ast_templates/chordpro/chordpro/content_tablature similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_tablature rename to patacrep/data/ast_templates/chordpro/chordpro/content_tablature diff --git a/patacrep/songs/chordpro/data/chordpro/content_verse b/patacrep/data/ast_templates/chordpro/chordpro/content_verse similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_verse rename to patacrep/data/ast_templates/chordpro/chordpro/content_verse diff --git a/patacrep/songs/chordpro/data/chordpro/content_word b/patacrep/data/ast_templates/chordpro/chordpro/content_word similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/content_word rename to patacrep/data/ast_templates/chordpro/chordpro/content_word diff --git a/patacrep/songs/chordpro/data/chordpro/song b/patacrep/data/ast_templates/chordpro/chordpro/song similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/song rename to patacrep/data/ast_templates/chordpro/chordpro/song diff --git a/patacrep/songs/chordpro/data/chordpro/song_body b/patacrep/data/ast_templates/chordpro/chordpro/song_body similarity index 100% rename from patacrep/songs/chordpro/data/chordpro/song_body rename to patacrep/data/ast_templates/chordpro/chordpro/song_body diff --git a/patacrep/songs/chordpro/data/chordpro/song_header b/patacrep/data/ast_templates/chordpro/chordpro/song_header similarity index 71% rename from patacrep/songs/chordpro/data/chordpro/song_header rename to patacrep/data/ast_templates/chordpro/chordpro/song_header index 2ffb1d30..56ad6a3a 100644 --- a/patacrep/songs/chordpro/data/chordpro/song_header +++ b/patacrep/data/ast_templates/chordpro/chordpro/song_header @@ -14,16 +14,20 @@ (*- for author in authors -*) {artist: (( author[1] )) (( author[0] ))} -(* endfor *) +(* endfor -*) -(*- for key in ['album', 'copyright', 'tag'] *) +(*- for key in ['album', 'copyright'] *) (* if key in metadata -*) {(( key )): (( metadata[key] ))} (* endif *) (* endfor *) -(* if 'cov' in metadata -*) - {(( 'cov' )): (( metadata['cov'].argument|search_image ))} -(* endif *) +(* if 'cover' in metadata -*) + {(( 'cover' )): (( metadata['cover'].argument|search_image ))} +(* endif -*) + +(* for tag in metadata.get("tag", [])|sortargs -*) + {tag: (( tag.argument ))} +(* endfor -*) (*- for key in metadata.morekeys -*) {key: (( key.keyword )): (( key.argument ))} diff --git a/patacrep/songs/chordpro/data/html/content_chord b/patacrep/data/ast_templates/chordpro/html/content_chord similarity index 100% rename from patacrep/songs/chordpro/data/html/content_chord rename to patacrep/data/ast_templates/chordpro/html/content_chord diff --git a/patacrep/songs/chordpro/data/html/content_chordlist b/patacrep/data/ast_templates/chordpro/html/content_chordlist similarity index 100% rename from patacrep/songs/chordpro/data/html/content_chordlist rename to patacrep/data/ast_templates/chordpro/html/content_chordlist diff --git a/patacrep/songs/chordpro/data/html/content_comment b/patacrep/data/ast_templates/chordpro/html/content_comment similarity index 100% rename from patacrep/songs/chordpro/data/html/content_comment rename to patacrep/data/ast_templates/chordpro/html/content_comment diff --git a/patacrep/songs/chordpro/data/html/content_define b/patacrep/data/ast_templates/chordpro/html/content_define similarity index 100% rename from patacrep/songs/chordpro/data/html/content_define rename to patacrep/data/ast_templates/chordpro/html/content_define diff --git a/patacrep/songs/chordpro/data/html/content_define_list b/patacrep/data/ast_templates/chordpro/html/content_define_list similarity index 100% rename from patacrep/songs/chordpro/data/html/content_define_list rename to patacrep/data/ast_templates/chordpro/html/content_define_list diff --git a/patacrep/songs/chordpro/data/html/content_endofline b/patacrep/data/ast_templates/chordpro/html/content_endofline similarity index 100% rename from patacrep/songs/chordpro/data/html/content_endofline rename to patacrep/data/ast_templates/chordpro/html/content_endofline diff --git a/patacrep/songs/chordpro/data/html/content_error b/patacrep/data/ast_templates/chordpro/html/content_error similarity index 100% rename from patacrep/songs/chordpro/data/html/content_error rename to patacrep/data/ast_templates/chordpro/html/content_error diff --git a/patacrep/songs/chordpro/data/html/content_guitar_comment b/patacrep/data/ast_templates/chordpro/html/content_guitar_comment similarity index 100% rename from patacrep/songs/chordpro/data/html/content_guitar_comment rename to patacrep/data/ast_templates/chordpro/html/content_guitar_comment diff --git a/patacrep/songs/chordpro/data/html/content_image b/patacrep/data/ast_templates/chordpro/html/content_image similarity index 100% rename from patacrep/songs/chordpro/data/html/content_image rename to patacrep/data/ast_templates/chordpro/html/content_image diff --git a/patacrep/songs/chordpro/data/html/content_line b/patacrep/data/ast_templates/chordpro/html/content_line similarity index 100% rename from patacrep/songs/chordpro/data/html/content_line rename to patacrep/data/ast_templates/chordpro/html/content_line diff --git a/patacrep/songs/chordpro/data/html/content_metadata_cover b/patacrep/data/ast_templates/chordpro/html/content_metadata_cover similarity index 100% rename from patacrep/songs/chordpro/data/html/content_metadata_cover rename to patacrep/data/ast_templates/chordpro/html/content_metadata_cover diff --git a/patacrep/songs/chordpro/data/html/content_newline b/patacrep/data/ast_templates/chordpro/html/content_newline similarity index 100% rename from patacrep/songs/chordpro/data/html/content_newline rename to patacrep/data/ast_templates/chordpro/html/content_newline diff --git a/patacrep/songs/chordpro/data/html/content_partition b/patacrep/data/ast_templates/chordpro/html/content_partition similarity index 100% rename from patacrep/songs/chordpro/data/html/content_partition rename to patacrep/data/ast_templates/chordpro/html/content_partition diff --git a/patacrep/songs/chordpro/data/html/content_space b/patacrep/data/ast_templates/chordpro/html/content_space similarity index 100% rename from patacrep/songs/chordpro/data/html/content_space rename to patacrep/data/ast_templates/chordpro/html/content_space diff --git a/patacrep/songs/chordpro/data/html/content_tablature b/patacrep/data/ast_templates/chordpro/html/content_tablature similarity index 100% rename from patacrep/songs/chordpro/data/html/content_tablature rename to patacrep/data/ast_templates/chordpro/html/content_tablature diff --git a/patacrep/songs/chordpro/data/html/content_verse b/patacrep/data/ast_templates/chordpro/html/content_verse similarity index 100% rename from patacrep/songs/chordpro/data/html/content_verse rename to patacrep/data/ast_templates/chordpro/html/content_verse diff --git a/patacrep/songs/chordpro/data/html/content_word b/patacrep/data/ast_templates/chordpro/html/content_word similarity index 100% rename from patacrep/songs/chordpro/data/html/content_word rename to patacrep/data/ast_templates/chordpro/html/content_word diff --git a/patacrep/songs/chordpro/data/html/song b/patacrep/data/ast_templates/chordpro/html/song similarity index 100% rename from patacrep/songs/chordpro/data/html/song rename to patacrep/data/ast_templates/chordpro/html/song diff --git a/patacrep/songs/chordpro/data/html/song_body b/patacrep/data/ast_templates/chordpro/html/song_body similarity index 100% rename from patacrep/songs/chordpro/data/html/song_body rename to patacrep/data/ast_templates/chordpro/html/song_body diff --git a/patacrep/songs/chordpro/data/html/song_header b/patacrep/data/ast_templates/chordpro/html/song_header similarity index 100% rename from patacrep/songs/chordpro/data/html/song_header rename to patacrep/data/ast_templates/chordpro/html/song_header diff --git a/patacrep/songs/chordpro/data/latex/content_chord b/patacrep/data/ast_templates/chordpro/latex/content_chord similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_chord rename to patacrep/data/ast_templates/chordpro/latex/content_chord diff --git a/patacrep/songs/chordpro/data/latex/content_chordlist b/patacrep/data/ast_templates/chordpro/latex/content_chordlist similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_chordlist rename to patacrep/data/ast_templates/chordpro/latex/content_chordlist diff --git a/patacrep/songs/chordpro/data/latex/content_comment b/patacrep/data/ast_templates/chordpro/latex/content_comment similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_comment rename to patacrep/data/ast_templates/chordpro/latex/content_comment diff --git a/patacrep/songs/chordpro/data/latex/content_define b/patacrep/data/ast_templates/chordpro/latex/content_define similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_define rename to patacrep/data/ast_templates/chordpro/latex/content_define diff --git a/patacrep/songs/chordpro/data/latex/content_endofline b/patacrep/data/ast_templates/chordpro/latex/content_endofline similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_endofline rename to patacrep/data/ast_templates/chordpro/latex/content_endofline diff --git a/patacrep/songs/chordpro/data/latex/content_error b/patacrep/data/ast_templates/chordpro/latex/content_error similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_error rename to patacrep/data/ast_templates/chordpro/latex/content_error diff --git a/patacrep/songs/chordpro/data/latex/content_guitar_comment b/patacrep/data/ast_templates/chordpro/latex/content_guitar_comment similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_guitar_comment rename to patacrep/data/ast_templates/chordpro/latex/content_guitar_comment diff --git a/patacrep/songs/chordpro/data/latex/content_image b/patacrep/data/ast_templates/chordpro/latex/content_image similarity index 58% rename from patacrep/songs/chordpro/data/latex/content_image rename to patacrep/data/ast_templates/chordpro/latex/content_image index ac97404b..a567730d 100644 --- a/patacrep/songs/chordpro/data/latex/content_image +++ b/patacrep/data/ast_templates/chordpro/latex/content_image @@ -1,5 +1,5 @@ (* block image *) -(* set image = content.argument|search_image *) +(* set image = content.argument|search_image|path2posix *) (* if image *) \image{(( image ))} (*- endif *) diff --git a/patacrep/songs/chordpro/data/latex/content_line b/patacrep/data/ast_templates/chordpro/latex/content_line similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_line rename to patacrep/data/ast_templates/chordpro/latex/content_line diff --git a/patacrep/songs/chordpro/data/latex/content_newline b/patacrep/data/ast_templates/chordpro/latex/content_newline similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_newline rename to patacrep/data/ast_templates/chordpro/latex/content_newline diff --git a/patacrep/data/ast_templates/chordpro/latex/content_partition b/patacrep/data/ast_templates/chordpro/latex/content_partition new file mode 100644 index 00000000..6942492a --- /dev/null +++ b/patacrep/data/ast_templates/chordpro/latex/content_partition @@ -0,0 +1,6 @@ +(* block partition *) +(* set partition = content.argument|search_partition|path2posix *) +(* if partition *) +\lilypond{ ((- partition -)) } +(*- endif -*) +(*- endblock -*) diff --git a/patacrep/songs/chordpro/data/latex/content_space b/patacrep/data/ast_templates/chordpro/latex/content_space similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_space rename to patacrep/data/ast_templates/chordpro/latex/content_space diff --git a/patacrep/songs/chordpro/data/latex/content_tablature b/patacrep/data/ast_templates/chordpro/latex/content_tablature similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_tablature rename to patacrep/data/ast_templates/chordpro/latex/content_tablature diff --git a/patacrep/songs/chordpro/data/latex/content_verse b/patacrep/data/ast_templates/chordpro/latex/content_verse similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_verse rename to patacrep/data/ast_templates/chordpro/latex/content_verse diff --git a/patacrep/songs/chordpro/data/latex/content_word b/patacrep/data/ast_templates/chordpro/latex/content_word similarity index 100% rename from patacrep/songs/chordpro/data/latex/content_word rename to patacrep/data/ast_templates/chordpro/latex/content_word diff --git a/patacrep/songs/chordpro/data/latex/song b/patacrep/data/ast_templates/chordpro/latex/song similarity index 77% rename from patacrep/songs/chordpro/data/latex/song rename to patacrep/data/ast_templates/chordpro/latex/song index 6f026c79..e8016107 100644 --- a/patacrep/songs/chordpro/data/latex/song +++ b/patacrep/data/ast_templates/chordpro/latex/song @@ -22,16 +22,16 @@ (* endif *) (* endfor *) }, - (* for key in ['album', 'copyright', 'tag'] *) + (* for key in ['album', 'copyright'] *) (* if key in metadata *) (( key ))={(( metadata[key] ))}, (* endif *) (* endfor *) - (* if 'cov' in metadata *) - (* block cov *) - (* set cov = metadata["cov"].argument|search_image *) - (* if cov *) - cov={(( cov ))}, + (* if 'cover' in metadata *) + (* block cover *) + (* set cover = metadata["cover"].argument|search_image|path2posix *) + (* if cover *) + cover={(( cover ))}, (* endif *) (* endblock *) (* endif *) @@ -40,7 +40,7 @@ (* endfor *) ] -(* if (metadata.cov is defined) *) +(* if (metadata.cover is defined) *) \cover (* endif *) diff --git a/patacrep/songs/chordpro/data/latex/song_body b/patacrep/data/ast_templates/chordpro/latex/song_body similarity index 100% rename from patacrep/songs/chordpro/data/latex/song_body rename to patacrep/data/ast_templates/chordpro/latex/song_body diff --git a/patacrep/data/latex/patacrep.sty b/patacrep/data/latex/patacrep.sty index d3735739..9368d118 100644 --- a/patacrep/data/latex/patacrep.sty +++ b/patacrep/data/latex/patacrep.sty @@ -139,7 +139,7 @@ \setlength{\coverspace}{0.1cm} \newcommand{\songcover}{} \newcommand{\songalbum}{} -\newsongkey{cov}{\let\songcover\@empty}{\def\songcover{#1}} +\newsongkey{cover}{\let\songcover\@empty}{\def\songcover{#1}} \newsongkey{album}{\let\songalbum\@empty}{\def\songalbum{#1}} \newsongkey{url}{\let\songurl\@empty}{\def\songurl{#1}} \newsongkey{original}{\let\songoriginal\@empty}{\def\songoriginal{#1}} diff --git a/patacrep/errors.py b/patacrep/errors.py index 5ec9fd9b..d1d3a74f 100644 --- a/patacrep/errors.py +++ b/patacrep/errors.py @@ -31,6 +31,16 @@ class TemplateError(SongbookError): else: return self.message +class ExecutableNotFound(SongbookError): + """Couldn't find a LaTeX executable.""" + + def __init__(self, executable): + super(ExecutableNotFound, self).__init__( + ( + """Could not find the following executable: {executable}""" + ).format(executable=executable) + ) + class StepError(SongbookError): """Error during execution of one compilation step.""" @@ -47,7 +57,7 @@ class LatexCompilationError(StepError): def __init__(self, basename): super(LatexCompilationError, self).__init__( ( - """Error while pdfLaTeX compilation of "{basename}.tex" """ + """Error while LaTeX compilation of "{basename}.tex" """ """(see {basename}.log for more information).""" ).format(basename=basename) ) diff --git a/patacrep/songbook/__init__.py b/patacrep/songbook/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index c46a0880..513977f6 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -3,17 +3,22 @@ from jinja2 import Environment, FileSystemLoader, contextfunction, ChoiceLoader import jinja2 import logging +import operator import os -from pkg_resources import resource_filename -from patacrep import encoding, files +from patacrep import encoding, files, pkg_datapath from patacrep.songs import Song from patacrep.songs.chordpro.syntax import parse_song from patacrep.templates import Renderer from patacrep.latex import lang2babel +from patacrep.files import path2posix LOGGER = logging.getLogger(__name__) +def sort_directive_argument(directives): + """Sort directives by their argument.""" + return sorted(directives, key=operator.attrgetter("argument")) + class ChordproSong(Song): """Chordpro song parser""" # pylint: disable=abstract-method @@ -26,7 +31,7 @@ class ChordproSong(Song): song = parse_song(song.read(), self.fullpath) self.authors = song.authors self.titles = song.titles - self.lang = song.get_data_argument('lang', self.config['lang']) + self.lang = song.get_data_argument('language', self.config['lang']) self.data = song.meta self.cached = { 'song': song, @@ -48,12 +53,14 @@ class ChordproSong(Song): self.get_datadirs(os.path.join("templates", self.output_language)) ), FileSystemLoader( - os.path.join(resource_filename(__name__, 'data'), self.output_language) + pkg_datapath('ast_templates', 'chordpro', self.output_language) ), ])) jinjaenv.filters['search_image'] = self.search_image jinjaenv.filters['search_partition'] = self.search_partition jinjaenv.filters['lang2babel'] = lang2babel + jinjaenv.filters['sortargs'] = sort_directive_argument + jinjaenv.filters['path2posix'] = path2posix try: return Renderer( diff --git a/patacrep/songs/chordpro/ast.py b/patacrep/songs/chordpro/ast.py index 9213ed37..17afc0c9 100644 --- a/patacrep/songs/chordpro/ast.py +++ b/patacrep/songs/chordpro/ast.py @@ -11,6 +11,27 @@ def _indent(string): """Return and indented version of argument.""" return "\n".join([" {}".format(line) for line in string.split('\n')]) +#: Available directives, that is, directives that we know how to deal with +AVAILABLE_DIRECTIVES = [ + "album", + "artist", + "capo", + "comment", + "copyright", + "columns", + "cov", + "define", + "guitar_comment", + "image", + "key", + "language", + "newline", + "partition", + "subtitle", + "tag", + "title", + ] + #: List of properties that are to be displayed in the flow of the song (not as #: metadata at the beginning or end of song. INLINE_DIRECTIVES = { @@ -30,8 +51,8 @@ DIRECTIVE_SHORTCUTS = { "by": "artist", "c": "comment", "gc": "guitar_comment", - "cover": "cov", - "language": "lang", + "cov": "cover", + "lang": "language", } def directive_name(text): @@ -194,6 +215,7 @@ class Song(AST): "artist": "add_author", "key": "add_key", "define": "add_cumulative", + "tag": "add_cumulative", } def __init__(self, filename): @@ -207,6 +229,7 @@ class Song(AST): def add(self, data): """Add an element to the song""" + # pylint: disable=too-many-branches if isinstance(data, Error): pass elif data is None: @@ -221,6 +244,8 @@ class Song(AST): self.content[0].prepend(data.strip()) elif isinstance(data, Directive) and data.inline: # Add a directive in the content of the song. + # It is useless to check if directive is in AVAILABLE_DIRECTIVES, + # since it is in INLINE_DIRECTIVES. self.content.append(data) elif data.inline: # Add an object in the content of the song. @@ -228,6 +253,8 @@ class Song(AST): elif isinstance(data, Directive): # Add a metadata directive. Some of them are added using special # methods listed in ``METADATA_ADD``. + if data.keyword not in AVAILABLE_DIRECTIVES: + LOGGER.warning("Ignoring unknown directive '{}'.".format(data.keyword)) if data.keyword in self.METADATA_ADD: getattr(self, self.METADATA_ADD[data.keyword])(data) else: diff --git a/patacrep/songs/chordpro/data/latex/content_partition b/patacrep/songs/chordpro/data/latex/content_partition deleted file mode 100644 index a3c35a3e..00000000 --- a/patacrep/songs/chordpro/data/latex/content_partition +++ /dev/null @@ -1,6 +0,0 @@ -(* block partition *) -(* set partition = content.argument|search_partition *) -(* if partition *) -\lilypond{ ((- content.argument|search_partition -)) } -(*- endif -*) -(*- endblock -*) diff --git a/setup.py b/setup.py index 4cfaeda0..023201eb 100755 --- a/setup.py +++ b/setup.py @@ -21,7 +21,12 @@ setup( "unidecode", "jinja2", "chardet", "ply", ], setup_requires=["hgtools"], - include_package_data=True, + package_data={'patacrep': [ + 'data/ast_templates/*/*/*', + 'data/img/*', + 'data/latex/*', + 'data/templates/*', + ]}, entry_points={ 'console_scripts': [ "songbook = patacrep.songbook.__main__:main", diff --git a/test/test_chordpro/greensleeves.sgc b/test/test_chordpro/greensleeves.sgc index 7ff25a58..aec06809 100644 --- a/test/test_chordpro/greensleeves.sgc +++ b/test/test_chordpro/greensleeves.sgc @@ -5,7 +5,7 @@ {title: Un sous titre} {artist: Traditionnel} {album: Angleterre} -{cov: traditionnel} +{cover: traditionnel} {partition: greensleeves.ly} diff --git a/test/test_chordpro/greensleeves.tex b/test/test_chordpro/greensleeves.tex index f582b0c8..c4bc461d 100644 --- a/test/test_chordpro/greensleeves.tex +++ b/test/test_chordpro/greensleeves.tex @@ -7,7 +7,7 @@ Un sous titre}[ by={ Traditionnel }, album={Angleterre}, - cov={img/traditionnel}, + cover={img/traditionnel}, ] \cover diff --git a/test/test_chordpro/invalid_directive.sgc b/test/test_chordpro/invalid_directive.sgc new file mode 100644 index 00000000..768ee9ee --- /dev/null +++ b/test/test_chordpro/invalid_directive.sgc @@ -0,0 +1 @@ +{lang: en} diff --git a/test/test_chordpro/invalid_directive.source b/test/test_chordpro/invalid_directive.source new file mode 100644 index 00000000..4f582c43 --- /dev/null +++ b/test/test_chordpro/invalid_directive.source @@ -0,0 +1,2 @@ +{foo: bar} +{bar} diff --git a/test/test_chordpro/invalid_directive.tex b/test/test_chordpro/invalid_directive.tex new file mode 100644 index 00000000..bd99a922 --- /dev/null +++ b/test/test_chordpro/invalid_directive.tex @@ -0,0 +1,10 @@ +\selectlanguage{english} + +\beginsong{}[ + by={ + }, +] + + + +\endsong diff --git a/test/test_chordpro/metadata.sgc b/test/test_chordpro/metadata.sgc index 22c59f59..322a591b 100644 --- a/test/test_chordpro/metadata.sgc +++ b/test/test_chordpro/metadata.sgc @@ -10,7 +10,7 @@ {artist: Texte de Jean Richepin, chanté par Georges Brassens} {album: Album} {copyright: Copyright} -{cov: metadata_cover} +{cover: metadata_cover} {key: foo: Foo} {comment: Comment} diff --git a/test/test_chordpro/metadata.tex b/test/test_chordpro/metadata.tex index d2a2273a..0be273f1 100644 --- a/test/test_chordpro/metadata.tex +++ b/test/test_chordpro/metadata.tex @@ -11,7 +11,7 @@ Subtitle5}[ Texte de Jean Richepin, chanté par Georges Brassens }, album={Album}, copyright={Copyright}, - cov={img/test/test_chordpro/metadata_cover}, + cover={img/test/test_chordpro/metadata_cover}, foo={Foo}, ] diff --git a/test/test_chordpro/tags.sgc b/test/test_chordpro/tags.sgc new file mode 100644 index 00000000..555948c9 --- /dev/null +++ b/test/test_chordpro/tags.sgc @@ -0,0 +1,5 @@ +{lang: en} +{title: Tag test} +{tag: a third tag} +{tag: another} +{tag: one tag} diff --git a/test/test_chordpro/tags.source b/test/test_chordpro/tags.source new file mode 100644 index 00000000..5408dae0 --- /dev/null +++ b/test/test_chordpro/tags.source @@ -0,0 +1,4 @@ +{title: Tag test} +{tag: one tag} +{tag: another} +{tag: a third tag} diff --git a/test/test_chordpro/tags.tex b/test/test_chordpro/tags.tex new file mode 100644 index 00000000..e27a462a --- /dev/null +++ b/test/test_chordpro/tags.tex @@ -0,0 +1,10 @@ +\selectlanguage{english} + +\beginsong{Tag test}[ + by={ + }, +] + + + +\endsong diff --git a/test/test_compilation/datadir.tex.control b/test/test_compilation/datadir.tex.control index 4f6c8521..a003cd42 100644 --- a/test/test_compilation/datadir.tex.control +++ b/test/test_compilation/datadir.tex.control @@ -103,7 +103,7 @@ guitar, Chordpro}[ by={ }, - cov={img/datadir.png}, + cover={img/datadir.png}, ] \cover @@ -130,7 +130,7 @@ Chordpro}[ Chordpro}[ by={ }, - cov={img/datadir2.png}, + cover={img/datadir2.png}, ] \cover @@ -157,7 +157,7 @@ Chordpro}[ Chordpro}[ by={ }, - cov={@TEST_FOLDER@/datadir_datadir/songs/./relative.png}, + cover={@TEST_FOLDER@/datadir_datadir/songs/./relative.png}, ] \cover @@ -184,7 +184,7 @@ Chordpro}[ Chordpro}[ by={ }, - cov={@TEST_FOLDER@/datadir_datadir/songs/./subdir/subdir.png}, + cover={@TEST_FOLDER@/datadir_datadir/songs/./subdir/subdir.png}, ] \cover diff --git a/test/test_compilation/datadir_datadir/songs/datadir.sg b/test/test_compilation/datadir_datadir/songs/datadir.sg index 933e208b..eb937410 100644 --- a/test/test_compilation/datadir_datadir/songs/datadir.sg +++ b/test/test_compilation/datadir_datadir/songs/datadir.sg @@ -1,5 +1,5 @@ \beginsong{Image included from datadir\\\LaTeX} - [cov={img/datadir}] + [cover={img/datadir}] \cover diff --git a/test/test_compilation/datadir_datadir/songs/datadir2.sg b/test/test_compilation/datadir_datadir/songs/datadir2.sg index 6a805725..f37f351f 100644 --- a/test/test_compilation/datadir_datadir/songs/datadir2.sg +++ b/test/test_compilation/datadir_datadir/songs/datadir2.sg @@ -1,5 +1,5 @@ \beginsong{Image included from a different datadir\\\LaTeX} - [cov={img/datadir2}] + [cover={img/datadir2}] \cover diff --git a/test/test_compilation/datadir_datadir/songs/relative.sg b/test/test_compilation/datadir_datadir/songs/relative.sg index 681b4086..3fc326f0 100644 --- a/test/test_compilation/datadir_datadir/songs/relative.sg +++ b/test/test_compilation/datadir_datadir/songs/relative.sg @@ -1,5 +1,5 @@ \beginsong{Image included from song directory\\\LaTeX} - [cov={relative}] + [cover={relative}] \cover diff --git a/test/test_compilation/datadir_datadir/songs/subdir/subdir.sg b/test/test_compilation/datadir_datadir/songs/subdir/subdir.sg index f86b47b4..b2199460 100644 --- a/test/test_compilation/datadir_datadir/songs/subdir/subdir.sg +++ b/test/test_compilation/datadir_datadir/songs/subdir/subdir.sg @@ -1,5 +1,5 @@ \beginsong{Image included from a nested song directory\\\LaTeX} - [cov={subdir}] + [cover={subdir}] \cover diff --git a/test/test_compilation/test_compilation.py b/test/test_compilation/test_compilation.py index dc07107a..11067c55 100644 --- a/test/test_compilation/test_compilation.py +++ b/test/test_compilation/test_compilation.py @@ -5,10 +5,12 @@ import glob import logging import os +import sys import subprocess import unittest from patacrep.encoding import open_read +from patacrep.files import path2posix from .. import dynamic # pylint: disable=unused-import @@ -67,16 +69,18 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): expected = expectfile.read().strip() expected = expected.replace( "@TEST_FOLDER@", - os.path.dirname(__file__), + path2posix(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(), + path2posix( + subprocess.check_output( + [sys.executable, "-c", 'import patacrep; print(patacrep.__DATADIR__)'], # pylint: disable=line-too-long + universal_newlines=True, + cwd=os.path.dirname(songbook), + ).strip() + ), ) self.assertMultiLineEqual( @@ -108,12 +112,16 @@ 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 = [sys.executable, '-m', 'patacrep.songbook', songbook] if steps: command.extend(['--steps', steps]) + # Continuous Integration will be verbose + if 'CI' in os.environ: + command.append('-v') + try: - subprocess.check_output( + subprocess.check_call( command, stderr=subprocess.STDOUT, universal_newlines=True, diff --git a/texlive_packages.txt b/texlive_packages.txt new file mode 100644 index 00000000..9320ca2e --- /dev/null +++ b/texlive_packages.txt @@ -0,0 +1,18 @@ +babel-english +babel-esperanto +babel-french +babel-german +babel-latin +babel-spanish +fancybox +framed +import +l3kernel +l3packages +mptopdf +ms +pgf +tipa +url +xcolor +xstring \ No newline at end of file diff --git a/tox.ini b/tox.ini index 1b6a3337..10fb9b9b 100644 --- a/tox.ini +++ b/tox.ini @@ -7,7 +7,7 @@ envlist = py34, lint [testenv] commands = {envpython} setup.py test -passenv = TRAVIS +passenv = TRAVIS APPVEYOR CI deps = [testenv:lint]