From 60a22d223593bdb0eee79067546480248986a894 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Mon, 19 Oct 2015 20:39:49 +0200 Subject: [PATCH 01/10] Differentiate language code (lang) and babel language (language) --- examples/example-all.sb | 2 +- examples/songs/greensleeves.sgc | 2 +- examples/songs/tests/chords.sgc | 2 +- examples/songs/tests/errors.sgc | 2 +- patacrep/build.py | 2 +- patacrep/data/templates/songs.tex | 10 +++---- patacrep/songs/__init__.py | 30 +++++++++++++++++++ patacrep/songs/chordpro/__init__.py | 5 +++- patacrep/songs/chordpro/ast.py | 2 +- .../songs/chordpro/data/chordpro/song_header | 4 +-- patacrep/templates.py | 3 +- test/test_chordpro/00.sgc | 2 +- test/test_chordpro/01.sgc | 2 +- test/test_chordpro/02.sgc | 2 +- test/test_chordpro/03.sgc | 2 +- test/test_chordpro/04.sgc | 2 +- test/test_chordpro/05.sgc | 2 +- test/test_chordpro/06.sgc | 2 +- test/test_chordpro/07.sgc | 2 +- test/test_chordpro/08.sgc | 2 +- test/test_chordpro/09.sgc | 2 +- test/test_chordpro/10.sgc | 2 +- test/test_chordpro/11.sgc | 2 +- test/test_chordpro/12.sgc | 2 +- test/test_chordpro/13.sgc | 2 +- test/test_chordpro/21.sgc | 2 +- test/test_chordpro/22.sgc | 2 +- test/test_chordpro/23.sgc | 2 +- test/test_chordpro/24.sgc | 2 +- test/test_chordpro/25.sgc | 2 +- test/test_chordpro/26.sgc | 2 +- test/test_chordpro/27.sgc | 2 +- test/test_chordpro/28.sgc | 2 +- test/test_chordpro/29.sgc | 2 +- test/test_chordpro/author_names.sgc | 2 +- test/test_chordpro/chords.sgc | 2 +- test/test_chordpro/customchords.sgc | 2 +- test/test_chordpro/greensleeves.sgc | 2 +- test/test_chordpro/greensleeves.source | 2 +- test/test_chordpro/invalid_chord.sgc | 2 +- test/test_chordpro/invalid_customchord.sgc | 2 +- test/test_chordpro/metadata.sgc | 2 +- test/test_chordpro/metadata.source | 4 +-- test/test_chordpro/newline.sgc | 2 +- test/test_chordpro/nolyrics.sgc | 2 +- test/test_chordpro/ukulelechords.sgc | 2 +- 46 files changed, 85 insertions(+), 51 deletions(-) diff --git a/examples/example-all.sb b/examples/example-all.sb index 7b94d020..8f5d80a6 100644 --- a/examples/example-all.sb +++ b/examples/example-all.sb @@ -8,7 +8,7 @@ "booktype" : "chorded", "datadir": ["datadir2"], "template" : "patacrep.tex", -"lang" : "french", +"lang" : "fr", "encoding": "utf8", "authwords" : { "sep" : ["and", "et"] diff --git a/examples/songs/greensleeves.sgc b/examples/songs/greensleeves.sgc index e7a6d7cb..c1295968 100644 --- a/examples/songs/greensleeves.sgc +++ b/examples/songs/greensleeves.sgc @@ -1,4 +1,4 @@ -{language : english} +{lang : en} {columns : 2} { title : Greensleeves} {subtitle: Test of the chordpro format} diff --git a/examples/songs/tests/chords.sgc b/examples/songs/tests/chords.sgc index 8779a140..1539387b 100644 --- a/examples/songs/tests/chords.sgc +++ b/examples/songs/tests/chords.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {columns: 1} {title: Chords testing} {subtitle: Test of the chords specification and LaTeX translation} diff --git a/examples/songs/tests/errors.sgc b/examples/songs/tests/errors.sgc index 56cb61b7..3b682f4c 100644 --- a/examples/songs/tests/errors.sgc +++ b/examples/songs/tests/errors.sgc @@ -1,4 +1,4 @@ -{language : english} +{lang : en} {columns : 2} { title : Error} {subtitle: A chordpro file with many errors} diff --git a/patacrep/build.py b/patacrep/build.py index 492f30fc..44023e65 100644 --- a/patacrep/build.py +++ b/patacrep/build.py @@ -29,7 +29,7 @@ GENERATED_EXTENSIONS = [ ] DEFAULT_CONFIG = { 'template': "default.tex", - 'lang': 'english', + 'lang': 'en', 'content': [], 'titleprefixwords': [], 'encoding': None, diff --git a/patacrep/data/templates/songs.tex b/patacrep/data/templates/songs.tex index bdfcf7bb..5f7c8af6 100644 --- a/patacrep/data/templates/songs.tex +++ b/patacrep/data/templates/songs.tex @@ -52,7 +52,7 @@ "mandatory": true }, "lang": {"description": {"english": "Language", "french": "Langue"}, - "default": {"english": "english", "french": "french"} + "default": {"en": "english", "fr": "french"} }, "titleprefixwords": {"description": {"english": "Ignore some words in the beginning of song titles", "french": "Ignore des mots dans le classement des chansons"}, @@ -80,11 +80,11 @@ (* block songbookpreambule *) (( super() )) -(* for lang in _languages -*) - \PassOptionsToPackage{((lang))}{babel} +(* for language in _languages -*) + \PassOptionsToPackage{((language))}{babel} (* endfor *) -\usepackage[((lang))]{babel} -\lang{((lang))} +\usepackage[(( lang2language(lang) ))]{babel} +\lang{(( lang2language(lang) ))} \usepackage{graphicx} \graphicspath{ % diff --git a/patacrep/songs/__init__.py b/patacrep/songs/__init__.py index 5c6eb797..818de044 100644 --- a/patacrep/songs/__init__.py +++ b/patacrep/songs/__init__.py @@ -7,12 +7,27 @@ import logging import os import pickle import re +from collections import OrderedDict from patacrep.authors import process_listauthors from patacrep import files, encoding LOGGER = logging.getLogger(__name__) +BABEL_LANGUAGES = OrderedDict(( + ('fr', 'french'), + ('en', 'english'), + ('de', 'german'), +)) + +def lang2language(lang): + try: + return BABEL_LANGUAGES[lang] + except KeyError: + # TODO: raise a nice error + print('Unknown lang:' + lang) + return 'english' + def cached_name(datadir, filename): """Return the filename of the cache version of the file.""" fullpath = os.path.abspath(os.path.join(datadir, '.cache', filename)) @@ -246,6 +261,21 @@ class Song: filepath = self.search_file(filename, ['', '.ly']) return filepath if none_if_not_found or filepath else filename + @property + def language(self): + """Return the string corresponding to the babel (LaTeX) language""" + return lang2language(self.lang) + + @language.setter + def language(self, language): + """Set the language code""" + for lang, babel_language in BABEL_LANGUAGES.items(): + if language == babel_language: + self.lang = lang + return + # TODO: raise a nice error + print('Unsupported language:' + language) + def unprefixed_title(title, prefixes): """Remove the first prefix of the list in the beginning of title (if any). """ diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index 52b926a8..4b95b7b0 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -35,7 +35,9 @@ class ChordproSong(Song): song = parse_song(song.read(), self.fullpath) self.authors = song.authors self.titles = song.titles - self.language = song.get_data_argument('language', self.config['lang']) + #language and lang are synomyms in the directives + language = song.get_data_argument('language', self.config['lang']) + self.lang = song.get_data_argument('lang', language) self.data = song.meta self.cached = { 'song': song, @@ -47,6 +49,7 @@ class ChordproSong(Song): context = { 'language': self.language, + 'lang': self.lang, "titles": self.titles, "authors": self.authors, "metadata": self.data, diff --git a/patacrep/songs/chordpro/ast.py b/patacrep/songs/chordpro/ast.py index 526f7d93..09a3b226 100644 --- a/patacrep/songs/chordpro/ast.py +++ b/patacrep/songs/chordpro/ast.py @@ -181,7 +181,7 @@ class Song(AST): - content: the song content, as a list of objects `foo` such that `foo.inline` is True. - titles: The list of titles - - language: The language (if set), None otherwise + - lang: The language code (if set), None otherwise - authors: The list of authors - meta: Every other metadata. """ diff --git a/patacrep/songs/chordpro/data/chordpro/song_header b/patacrep/songs/chordpro/data/chordpro/song_header index ac5d8329..2ffb1d30 100644 --- a/patacrep/songs/chordpro/data/chordpro/song_header +++ b/patacrep/songs/chordpro/data/chordpro/song_header @@ -1,5 +1,5 @@ -(* if language is defined -*) - {language: (( language ))} +(* if lang is defined -*) + {lang: (( lang ))} (* endif *) (* if metadata.columns is defined -*) {columns: (( metadata.columns ))} diff --git a/patacrep/templates.py b/patacrep/templates.py index 3673f878..204d0b7a 100644 --- a/patacrep/templates.py +++ b/patacrep/templates.py @@ -8,7 +8,7 @@ import os import re import json -from patacrep import errors, files +from patacrep import errors, files, songs import patacrep.encoding _LATEX_SUBS = ( @@ -84,6 +84,7 @@ class Renderer: self.jinjaenv.trim_blocks = True self.jinjaenv.lstrip_blocks = True self.jinjaenv.globals["path2posix"] = files.path2posix + self.jinjaenv.globals["lang2language"] = songs.lang2language self.template = self.jinjaenv.get_template(template) diff --git a/test/test_chordpro/00.sgc b/test/test_chordpro/00.sgc index 3e2185b7..768ee9ee 100644 --- a/test/test_chordpro/00.sgc +++ b/test/test_chordpro/00.sgc @@ -1 +1 @@ -{language: english} +{lang: en} diff --git a/test/test_chordpro/01.sgc b/test/test_chordpro/01.sgc index 25d6a677..6cf1934e 100644 --- a/test/test_chordpro/01.sgc +++ b/test/test_chordpro/01.sgc @@ -1,3 +1,3 @@ -{language: english} +{lang: en} A verse line diff --git a/test/test_chordpro/02.sgc b/test/test_chordpro/02.sgc index 2a8629e0..365a1b9b 100644 --- a/test/test_chordpro/02.sgc +++ b/test/test_chordpro/02.sgc @@ -1,3 +1,3 @@ -{language: english} +{lang: en} {title: A directive} diff --git a/test/test_chordpro/03.sgc b/test/test_chordpro/03.sgc index 341c9bd4..6468f5e9 100644 --- a/test/test_chordpro/03.sgc +++ b/test/test_chordpro/03.sgc @@ -1,2 +1,2 @@ -{language: english} +{lang: en} diff --git a/test/test_chordpro/04.sgc b/test/test_chordpro/04.sgc index e9c2a952..d25f38a8 100644 --- a/test/test_chordpro/04.sgc +++ b/test/test_chordpro/04.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {start_of_chorus} A one line chorus diff --git a/test/test_chordpro/05.sgc b/test/test_chordpro/05.sgc index 9bc7f016..cf6a654b 100644 --- a/test/test_chordpro/05.sgc +++ b/test/test_chordpro/05.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {start_of_bridge} A one line bridge diff --git a/test/test_chordpro/06.sgc b/test/test_chordpro/06.sgc index 341c9bd4..6468f5e9 100644 --- a/test/test_chordpro/06.sgc +++ b/test/test_chordpro/06.sgc @@ -1,2 +1,2 @@ -{language: english} +{lang: en} diff --git a/test/test_chordpro/07.sgc b/test/test_chordpro/07.sgc index b05a536f..1362cdeb 100644 --- a/test/test_chordpro/07.sgc +++ b/test/test_chordpro/07.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {start_of_tab} A tab diff --git a/test/test_chordpro/08.sgc b/test/test_chordpro/08.sgc index 9a9f0566..bfcb44dd 100644 --- a/test/test_chordpro/08.sgc +++ b/test/test_chordpro/08.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} A lot of new lines diff --git a/test/test_chordpro/09.sgc b/test/test_chordpro/09.sgc index 193db1b0..b252de69 100644 --- a/test/test_chordpro/09.sgc +++ b/test/test_chordpro/09.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {title: and a directive} diff --git a/test/test_chordpro/10.sgc b/test/test_chordpro/10.sgc index e7537b3b..431ddd11 100644 --- a/test/test_chordpro/10.sgc +++ b/test/test_chordpro/10.sgc @@ -1,3 +1,3 @@ -{language: english} +{lang: en} A line[A] with a chord diff --git a/test/test_chordpro/11.sgc b/test/test_chordpro/11.sgc index 3610f67c..350f195d 100644 --- a/test/test_chordpro/11.sgc +++ b/test/test_chordpro/11.sgc @@ -1,3 +1,3 @@ -{language: english} +{lang: en} A line ending with a chord[A] diff --git a/test/test_chordpro/12.sgc b/test/test_chordpro/12.sgc index 029ccad4..946d7add 100644 --- a/test/test_chordpro/12.sgc +++ b/test/test_chordpro/12.sgc @@ -1,3 +1,3 @@ -{language: english} +{lang: en} [A]A line starting with a chord diff --git a/test/test_chordpro/13.sgc b/test/test_chordpro/13.sgc index aa6f6603..1000c0db 100644 --- a/test/test_chordpro/13.sgc +++ b/test/test_chordpro/13.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {start_of_tab} A table diff --git a/test/test_chordpro/21.sgc b/test/test_chordpro/21.sgc index 25d6a677..6cf1934e 100644 --- a/test/test_chordpro/21.sgc +++ b/test/test_chordpro/21.sgc @@ -1,3 +1,3 @@ -{language: english} +{lang: en} A verse line diff --git a/test/test_chordpro/22.sgc b/test/test_chordpro/22.sgc index 2a8629e0..365a1b9b 100644 --- a/test/test_chordpro/22.sgc +++ b/test/test_chordpro/22.sgc @@ -1,3 +1,3 @@ -{language: english} +{lang: en} {title: A directive} diff --git a/test/test_chordpro/23.sgc b/test/test_chordpro/23.sgc index 3e2185b7..768ee9ee 100644 --- a/test/test_chordpro/23.sgc +++ b/test/test_chordpro/23.sgc @@ -1 +1 @@ -{language: english} +{lang: en} diff --git a/test/test_chordpro/24.sgc b/test/test_chordpro/24.sgc index e9c2a952..d25f38a8 100644 --- a/test/test_chordpro/24.sgc +++ b/test/test_chordpro/24.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {start_of_chorus} A one line chorus diff --git a/test/test_chordpro/25.sgc b/test/test_chordpro/25.sgc index 9bc7f016..cf6a654b 100644 --- a/test/test_chordpro/25.sgc +++ b/test/test_chordpro/25.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {start_of_bridge} A one line bridge diff --git a/test/test_chordpro/26.sgc b/test/test_chordpro/26.sgc index 341c9bd4..6468f5e9 100644 --- a/test/test_chordpro/26.sgc +++ b/test/test_chordpro/26.sgc @@ -1,2 +1,2 @@ -{language: english} +{lang: en} diff --git a/test/test_chordpro/27.sgc b/test/test_chordpro/27.sgc index b05a536f..1362cdeb 100644 --- a/test/test_chordpro/27.sgc +++ b/test/test_chordpro/27.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {start_of_tab} A tab diff --git a/test/test_chordpro/28.sgc b/test/test_chordpro/28.sgc index 9a9f0566..bfcb44dd 100644 --- a/test/test_chordpro/28.sgc +++ b/test/test_chordpro/28.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} A lot of new lines diff --git a/test/test_chordpro/29.sgc b/test/test_chordpro/29.sgc index 193db1b0..b252de69 100644 --- a/test/test_chordpro/29.sgc +++ b/test/test_chordpro/29.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {title: and a directive} diff --git a/test/test_chordpro/author_names.sgc b/test/test_chordpro/author_names.sgc index 36a39230..b1756cc3 100644 --- a/test/test_chordpro/author_names.sgc +++ b/test/test_chordpro/author_names.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {title: Title} {artist: The Beatles} {artist: Oasis} diff --git a/test/test_chordpro/chords.sgc b/test/test_chordpro/chords.sgc index 040dcf07..983e03ee 100644 --- a/test/test_chordpro/chords.sgc +++ b/test/test_chordpro/chords.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} [A]Simple [Bb]BĂ©mol diff --git a/test/test_chordpro/customchords.sgc b/test/test_chordpro/customchords.sgc index 3357bb96..dd42e025 100644 --- a/test/test_chordpro/customchords.sgc +++ b/test/test_chordpro/customchords.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {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 - -} {define: E5/A* base-fret 7 frets 0 1 3 3 x x fingers - 1 2 3 - -} diff --git a/test/test_chordpro/greensleeves.sgc b/test/test_chordpro/greensleeves.sgc index 389f14d1..7ff25a58 100644 --- a/test/test_chordpro/greensleeves.sgc +++ b/test/test_chordpro/greensleeves.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {columns: 2} {title: Greensleeves} {title: Un autre sous-titre} diff --git a/test/test_chordpro/greensleeves.source b/test/test_chordpro/greensleeves.source index 1dee93ff..3801418d 100644 --- a/test/test_chordpro/greensleeves.source +++ b/test/test_chordpro/greensleeves.source @@ -1,4 +1,4 @@ -{language : english} +{lang : en} {columns : 2} {subtitle : Un sous titre} { title : Greensleeves} diff --git a/test/test_chordpro/invalid_chord.sgc b/test/test_chordpro/invalid_chord.sgc index acb5444f..3d6319be 100644 --- a/test/test_chordpro/invalid_chord.sgc +++ b/test/test_chordpro/invalid_chord.sgc @@ -1,3 +1,3 @@ -{language: english} +{lang: en} This is invalid. diff --git a/test/test_chordpro/invalid_customchord.sgc b/test/test_chordpro/invalid_customchord.sgc index 341c9bd4..6468f5e9 100644 --- a/test/test_chordpro/invalid_customchord.sgc +++ b/test/test_chordpro/invalid_customchord.sgc @@ -1,2 +1,2 @@ -{language: english} +{lang: en} diff --git a/test/test_chordpro/metadata.sgc b/test/test_chordpro/metadata.sgc index 979c1388..d48ded77 100644 --- a/test/test_chordpro/metadata.sgc +++ b/test/test_chordpro/metadata.sgc @@ -1,4 +1,4 @@ -{language: french} +{lang: fr} {capo: Capo} {title: Title} {title: Subtitle1} diff --git a/test/test_chordpro/metadata.source b/test/test_chordpro/metadata.source index 514ac2c0..02167238 100644 --- a/test/test_chordpro/metadata.source +++ b/test/test_chordpro/metadata.source @@ -4,8 +4,8 @@ {subtitle: Subtitle4} {t: Subtitle2} {st: Subtitle5} -{language: english} -{language: french} +{lang: en} +{lang: fr} {by: Author1} {artist: Author2} {album: Album} diff --git a/test/test_chordpro/newline.sgc b/test/test_chordpro/newline.sgc index 72bdc1a2..e9bf0c62 100644 --- a/test/test_chordpro/newline.sgc +++ b/test/test_chordpro/newline.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} This is a verse With a new line diff --git a/test/test_chordpro/nolyrics.sgc b/test/test_chordpro/nolyrics.sgc index fd59c884..2ad06b03 100644 --- a/test/test_chordpro/nolyrics.sgc +++ b/test/test_chordpro/nolyrics.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} A chorus [A]with lyrics [Emaj3]maj et nombre diff --git a/test/test_chordpro/ukulelechords.sgc b/test/test_chordpro/ukulelechords.sgc index 3b37123d..bbf4aa81 100644 --- a/test/test_chordpro/ukulelechords.sgc +++ b/test/test_chordpro/ukulelechords.sgc @@ -1,4 +1,4 @@ -{language: english} +{lang: en} {define: G frets 0 2 3 2} {define: D7 frets 2 2 2 3 fingers 1 1 1 2} {define: G frets 3 2 0 0 0 3} From 410e7465a46c9e72d860e07cc4b9f4b4b0c10062 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Mon, 19 Oct 2015 21:47:02 +0200 Subject: [PATCH 02/10] Allow {language: bable_language} and {lang: code_lang} in chordpro --- patacrep/songs/chordpro/__init__.py | 15 ++++++++++++--- patacrep/songs/chordpro/ast.py | 2 +- test/test_chordpro/lang.sgc | 1 + test/test_chordpro/lang.source | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 test/test_chordpro/lang.sgc create mode 100644 test/test_chordpro/lang.source diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index 4b95b7b0..e0a4be2e 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -35,9 +35,18 @@ class ChordproSong(Song): song = parse_song(song.read(), self.fullpath) self.authors = song.authors self.titles = song.titles - #language and lang are synomyms in the directives - language = song.get_data_argument('language', self.config['lang']) - self.lang = song.get_data_argument('lang', language) + + # Lang inverted priority (last one is preferred): + # config['lang'] + # song.language + # song.lang + self.lang = self.config['lang'] + language = song.get_data_argument('language') + if language: + # self.lang is automatically updated + self.language = language + self.lang = song.get_data_argument('lang', self.lang) + self.data = song.meta self.cached = { 'song': song, diff --git a/patacrep/songs/chordpro/ast.py b/patacrep/songs/chordpro/ast.py index 09a3b226..c0497c48 100644 --- a/patacrep/songs/chordpro/ast.py +++ b/patacrep/songs/chordpro/ast.py @@ -245,7 +245,7 @@ class Song(AST): self.meta[data.keyword] = [] self.meta[data.keyword].append(data) - def get_data_argument(self, keyword, default): + def get_data_argument(self, keyword, default=None): """Return `self.meta[keyword].argument`. Return `default` if `self.meta[keyword]` does not exist. diff --git a/test/test_chordpro/lang.sgc b/test/test_chordpro/lang.sgc new file mode 100644 index 00000000..be2eff89 --- /dev/null +++ b/test/test_chordpro/lang.sgc @@ -0,0 +1 @@ +{lang: fr} \ No newline at end of file diff --git a/test/test_chordpro/lang.source b/test/test_chordpro/lang.source new file mode 100644 index 00000000..ac284b64 --- /dev/null +++ b/test/test_chordpro/lang.source @@ -0,0 +1 @@ +{language: french} From 38a2d5eb1b834c178175d96da838fbfadf814634 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Mon, 19 Oct 2015 22:59:38 +0200 Subject: [PATCH 03/10] Support spanish, italian and portuguese --- patacrep/songs/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/patacrep/songs/__init__.py b/patacrep/songs/__init__.py index 818de044..7830f5c4 100644 --- a/patacrep/songs/__init__.py +++ b/patacrep/songs/__init__.py @@ -18,6 +18,9 @@ BABEL_LANGUAGES = OrderedDict(( ('fr', 'french'), ('en', 'english'), ('de', 'german'), + ('es', 'spanish'), + ('it', 'italian'), + ('pt', 'portuguese'), )) def lang2language(lang): From f7c8b52e40464b932c9aa6d7b74174d9cbeca401 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Mon, 19 Oct 2015 23:04:43 +0200 Subject: [PATCH 04/10] Properly log the error when the language code is unknown --- patacrep/songs/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patacrep/songs/__init__.py b/patacrep/songs/__init__.py index 7830f5c4..dcea0e27 100644 --- a/patacrep/songs/__init__.py +++ b/patacrep/songs/__init__.py @@ -27,8 +27,8 @@ def lang2language(lang): try: return BABEL_LANGUAGES[lang] except KeyError: - # TODO: raise a nice error - print('Unknown lang:' + lang) + available = ", ".join(BABEL_LANGUAGES.keys()) + LOGGER.error('Unknown lang code: ' + lang + '. Supported: ' + available) return 'english' def cached_name(datadir, filename): From 909d8120d0e3a8d1daa764cc4c98f468815e5c7c Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 21 Oct 2015 12:55:33 +0200 Subject: [PATCH 05/10] Complete the transition to support only language code --- patacrep/content/song.py | 6 +-- patacrep/data/templates/songs.tex | 10 ++--- patacrep/latex/__init__.py | 22 +++++++++++ patacrep/songs/__init__.py | 38 +------------------ patacrep/songs/chordpro/__init__.py | 3 +- patacrep/songs/chordpro/ast.py | 1 + patacrep/songs/chordpro/data/html/song_header | 4 +- patacrep/songs/chordpro/data/latex/song | 4 +- patacrep/songs/latex/__init__.py | 15 ++++++-- patacrep/templates.py | 3 +- test/test_chordpro/lang.source | 2 +- test/test_chordpro/newline.html | 2 +- 12 files changed, 55 insertions(+), 55 deletions(-) diff --git a/patacrep/content/song.py b/patacrep/content/song.py index 42b4abba..c5455c92 100755 --- a/patacrep/content/song.py +++ b/patacrep/content/song.py @@ -60,8 +60,8 @@ def parse(keyword, argument, contentlist, config): Return a list of Song() instances. """ plugins = config['_song_plugins'] - if '_languages' not in config: - config['_languages'] = set() + if '_langs' not in config: + config['_langs'] = set() songlist = [] for songdir in config['_songdir']: if contentlist: @@ -92,7 +92,7 @@ def parse(keyword, argument, contentlist, config): datadir=songdir.datadir, )) songlist.append(renderer) - config["_languages"].add(renderer.song.language) + config["_langs"].add(renderer.song.lang) if len(songlist) > before: break if len(songlist) == before: diff --git a/patacrep/data/templates/songs.tex b/patacrep/data/templates/songs.tex index 5f7c8af6..957e610e 100644 --- a/patacrep/data/templates/songs.tex +++ b/patacrep/data/templates/songs.tex @@ -52,7 +52,7 @@ "mandatory": true }, "lang": {"description": {"english": "Language", "french": "Langue"}, - "default": {"en": "english", "fr": "french"} + "default": {"english": "en", "french": "fr"} }, "titleprefixwords": {"description": {"english": "Ignore some words in the beginning of song titles", "french": "Ignore des mots dans le classement des chansons"}, @@ -80,11 +80,11 @@ (* block songbookpreambule *) (( super() )) -(* for language in _languages -*) - \PassOptionsToPackage{((language))}{babel} +(* for lang in _langs -*) + \PassOptionsToPackage{(( lang2babel(lang) ))}{babel} (* endfor *) -\usepackage[(( lang2language(lang) ))]{babel} -\lang{(( lang2language(lang) ))} +\usepackage[(( lang2babel(lang) ))]{babel} +\lang{(( lang2babel(lang) ))} \usepackage{graphicx} \graphicspath{ % diff --git a/patacrep/latex/__init__.py b/patacrep/latex/__init__.py index 2c6db73a..108ea445 100644 --- a/patacrep/latex/__init__.py +++ b/patacrep/latex/__init__.py @@ -5,4 +5,26 @@ This module uses an LALR parser to try to parse LaTeX code. LaTeX language will work on simple cases, but not on complex ones. """ +import logging +from collections import OrderedDict + from patacrep.latex.syntax import tex2plain, parse_song + +LOGGER = logging.getLogger(__name__) + +BABEL_LANGUAGES = OrderedDict(( + ('fr', 'french'), + ('en', 'english'), + ('de', 'german'), + ('es', 'spanish'), + ('it', 'italian'), + ('pt', 'portuguese'), +)) + +def lang2babel(lang): + try: + return BABEL_LANGUAGES[lang] + except KeyError: + available = ", ".join(BABEL_LANGUAGES.keys()) + LOGGER.error('Unknown lang code: ' + lang + '. Supported: ' + available) + return 'english' diff --git a/patacrep/songs/__init__.py b/patacrep/songs/__init__.py index dcea0e27..63be6f62 100644 --- a/patacrep/songs/__init__.py +++ b/patacrep/songs/__init__.py @@ -7,30 +7,12 @@ import logging import os import pickle import re -from collections import OrderedDict from patacrep.authors import process_listauthors from patacrep import files, encoding LOGGER = logging.getLogger(__name__) -BABEL_LANGUAGES = OrderedDict(( - ('fr', 'french'), - ('en', 'english'), - ('de', 'german'), - ('es', 'spanish'), - ('it', 'italian'), - ('pt', 'portuguese'), -)) - -def lang2language(lang): - try: - return BABEL_LANGUAGES[lang] - except KeyError: - available = ", ".join(BABEL_LANGUAGES.keys()) - LOGGER.error('Unknown lang code: ' + lang + '. Supported: ' + available) - return 'english' - def cached_name(datadir, filename): """Return the filename of the cache version of the file.""" fullpath = os.path.abspath(os.path.join(datadir, '.cache', filename)) @@ -107,7 +89,7 @@ class Song: "cached", "data", "subpath", - "language", + "lang", "authors", "_filehash", "_version", @@ -204,8 +186,7 @@ class Song: - titles: the list of (raw) titles. This list will be processed to remove prefixes. - - language: the main language of the song, as language recognized by - the LaTeX babel package. + - lang: the main language of the song, as language code.. - authors: the list of (raw) authors. This list will be processed to 'clean' it (see function :func:`patacrep.authors.processauthors`). - data: song metadata. Used (among others) to sort the songs. @@ -264,21 +245,6 @@ class Song: filepath = self.search_file(filename, ['', '.ly']) return filepath if none_if_not_found or filepath else filename - @property - def language(self): - """Return the string corresponding to the babel (LaTeX) language""" - return lang2language(self.lang) - - @language.setter - def language(self, language): - """Set the language code""" - for lang, babel_language in BABEL_LANGUAGES.items(): - if language == babel_language: - self.lang = lang - return - # TODO: raise a nice error - print('Unsupported language:' + language) - def unprefixed_title(title, prefixes): """Remove the first prefix of the list in the beginning of title (if any). """ diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index e0a4be2e..ca597af0 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -9,6 +9,7 @@ from patacrep import encoding, files from patacrep.songs import Song from patacrep.songs.chordpro.syntax import parse_song from patacrep.templates import Renderer +from patacrep.latex import lang2babel class ChordproSong(Song): """Chordpros song parser.""" @@ -57,7 +58,6 @@ class ChordproSong(Song): templatedirs = [] context = { - 'language': self.language, 'lang': self.lang, "titles": self.titles, "authors": self.authors, @@ -72,6 +72,7 @@ class ChordproSong(Song): )) jinjaenv.filters['search_image'] = self.search_image jinjaenv.filters['search_partition'] = self.search_partition + jinjaenv.filters['lang2babel'] = lang2babel try: return Renderer( diff --git a/patacrep/songs/chordpro/ast.py b/patacrep/songs/chordpro/ast.py index c0497c48..a02c93bb 100644 --- a/patacrep/songs/chordpro/ast.py +++ b/patacrep/songs/chordpro/ast.py @@ -31,6 +31,7 @@ DIRECTIVE_SHORTCUTS = { "c": "comment", "gc": "guitar_comment", "cover": "cov", + "language": "lang", } def directive_name(text): diff --git a/patacrep/songs/chordpro/data/html/song_header b/patacrep/songs/chordpro/data/html/song_header index 963ef686..bd401864 100644 --- a/patacrep/songs/chordpro/data/html/song_header +++ b/patacrep/songs/chordpro/data/html/song_header @@ -17,8 +17,8 @@ (* endif *) (* endfor *) -(* if language is defined -*) - Language: (( language ))
+(* if lang is defined -*) + Lang: (( lang ))
(* endif *) (* include 'content_metadata_cover' *) diff --git a/patacrep/songs/chordpro/data/latex/song b/patacrep/songs/chordpro/data/latex/song index 6f51d673..d106c2e8 100644 --- a/patacrep/songs/chordpro/data/latex/song +++ b/patacrep/songs/chordpro/data/latex/song @@ -1,5 +1,5 @@ -(* if language is defined -*) - \selectlanguage{((language))} +(* if lang is defined -*) + \selectlanguage{(( lang2babel(lang) ))} (* endif *) (*- if metadata.columns is defined *) diff --git a/patacrep/songs/latex/__init__.py b/patacrep/songs/latex/__init__.py index 2371c7d9..620475a2 100644 --- a/patacrep/songs/latex/__init__.py +++ b/patacrep/songs/latex/__init__.py @@ -8,19 +8,19 @@ will work on simple cases, but not on complex ones. import os from patacrep import files, encoding -from patacrep.latex import parse_song +from patacrep.latex import parse_song, BABEL_LANGUAGES from patacrep.songs import Song class LatexSong(Song): """LaTeX song parser.""" def _parse(self, __config): - """Parse content, and return the dictinory of song data.""" + """Parse content, and return the dictionary of song data.""" with encoding.open_read(self.fullpath, encoding=self.encoding) as song: self.data = parse_song(song.read(), self.fullpath) self.titles = self.data['@titles'] del self.data['@titles'] - self.language = self.data['@language'] + self.set_lang(self.data['@language']) del self.data['@language'] if "by" in self.data: self.authors = [self.data['by']] @@ -38,6 +38,15 @@ class LatexSong(Song): )) return r'\import{{{}/}}{{{}}}'.format(os.path.dirname(path), os.path.basename(path)) + def set_lang(self, language): + """Set the language code""" + for lang, babel_language in BABEL_LANGUAGES.items(): + if language == babel_language: + self.lang = lang + return + # TODO: add as custom language + LOGGER.error('Unsupported language:' + language) + SONG_PARSERS = { 'is': LatexSong, 'sg': LatexSong, diff --git a/patacrep/templates.py b/patacrep/templates.py index 204d0b7a..a3ac78b9 100644 --- a/patacrep/templates.py +++ b/patacrep/templates.py @@ -9,6 +9,7 @@ import re import json from patacrep import errors, files, songs +from patacrep.latex import lang2babel import patacrep.encoding _LATEX_SUBS = ( @@ -84,7 +85,7 @@ class Renderer: self.jinjaenv.trim_blocks = True self.jinjaenv.lstrip_blocks = True self.jinjaenv.globals["path2posix"] = files.path2posix - self.jinjaenv.globals["lang2language"] = songs.lang2language + self.jinjaenv.globals["lang2babel"] = lang2babel self.template = self.jinjaenv.get_template(template) diff --git a/test/test_chordpro/lang.source b/test/test_chordpro/lang.source index ac284b64..c9a4c305 100644 --- a/test/test_chordpro/lang.source +++ b/test/test_chordpro/lang.source @@ -1 +1 @@ -{language: french} +{language: fr} diff --git a/test/test_chordpro/newline.html b/test/test_chordpro/newline.html index 1fbb02a3..aca33fa6 100644 --- a/test/test_chordpro/newline.html +++ b/test/test_chordpro/newline.html @@ -1,4 +1,4 @@ -Language: english
+Lang: en
From cda6ea3c9475e2c68c173d412a5d74b18b3f2a69 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 21 Oct 2015 13:23:57 +0200 Subject: [PATCH 06/10] Cleanup Chordpro lang management --- patacrep/songs/chordpro/__init__.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index ca597af0..4469e40f 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -36,17 +36,7 @@ class ChordproSong(Song): song = parse_song(song.read(), self.fullpath) self.authors = song.authors self.titles = song.titles - - # Lang inverted priority (last one is preferred): - # config['lang'] - # song.language - # song.lang - self.lang = self.config['lang'] - language = song.get_data_argument('language') - if language: - # self.lang is automatically updated - self.language = language - self.lang = song.get_data_argument('lang', self.lang) + self.lang = song.get_data_argument('lang', self.config['lang']) self.data = song.meta self.cached = { From 3f7ed4cb00ae89d35afb600d6d1adea3a20162a1 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 21 Oct 2015 13:25:19 +0200 Subject: [PATCH 07/10] Revert unneeded customization --- patacrep/songs/chordpro/ast.py | 2 +- patacrep/templates.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/patacrep/songs/chordpro/ast.py b/patacrep/songs/chordpro/ast.py index a02c93bb..9213ed37 100644 --- a/patacrep/songs/chordpro/ast.py +++ b/patacrep/songs/chordpro/ast.py @@ -246,7 +246,7 @@ class Song(AST): self.meta[data.keyword] = [] self.meta[data.keyword].append(data) - def get_data_argument(self, keyword, default=None): + def get_data_argument(self, keyword, default): """Return `self.meta[keyword].argument`. Return `default` if `self.meta[keyword]` does not exist. diff --git a/patacrep/templates.py b/patacrep/templates.py index a3ac78b9..6a799295 100644 --- a/patacrep/templates.py +++ b/patacrep/templates.py @@ -8,7 +8,7 @@ import os import re import json -from patacrep import errors, files, songs +from patacrep import errors, files from patacrep.latex import lang2babel import patacrep.encoding From c62549a2e77b14f73b13aa515b6884a478b8328a Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 21 Oct 2015 13:57:47 +0200 Subject: [PATCH 08/10] Don't crash on unknonwn babel languages --- patacrep/songs/latex/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/patacrep/songs/latex/__init__.py b/patacrep/songs/latex/__init__.py index 620475a2..980fece2 100644 --- a/patacrep/songs/latex/__init__.py +++ b/patacrep/songs/latex/__init__.py @@ -44,8 +44,11 @@ class LatexSong(Song): if language == babel_language: self.lang = lang return - # TODO: add as custom language - LOGGER.error('Unsupported language:' + language) + + # Add a custom language to the babel dictionary (language is not officially supported) + custom_lang = '_' + language + BABEL_LANGUAGES[custom_lang] = language + self.lang = custom_lang SONG_PARSERS = { 'is': LatexSong, From 5942fd8483194a80d986460eb6f59a5e8222641c Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 21 Oct 2015 13:58:02 +0200 Subject: [PATCH 09/10] Lint conformity --- patacrep/latex/__init__.py | 1 + patacrep/songs/__init__.py | 1 + 2 files changed, 2 insertions(+) diff --git a/patacrep/latex/__init__.py b/patacrep/latex/__init__.py index 108ea445..d01cfbe5 100644 --- a/patacrep/latex/__init__.py +++ b/patacrep/latex/__init__.py @@ -22,6 +22,7 @@ BABEL_LANGUAGES = OrderedDict(( )) def lang2babel(lang): + """Return the language used by babel, corresponding to the language code""" try: return BABEL_LANGUAGES[lang] except KeyError: diff --git a/patacrep/songs/__init__.py b/patacrep/songs/__init__.py index 63be6f62..a9cef025 100644 --- a/patacrep/songs/__init__.py +++ b/patacrep/songs/__init__.py @@ -131,6 +131,7 @@ class Song: self.titles = [] self.data = {} self.cached = None + self.lang = None self._parse(config) # Post processing of data From a2973d2272cee2ba42c5fb42f8436dbbaa9f61e7 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Wed, 21 Oct 2015 14:02:22 +0200 Subject: [PATCH 10/10] Line cleaning --- patacrep/songs/chordpro/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index 4469e40f..cc0807bb 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -37,7 +37,6 @@ class ChordproSong(Song): self.authors = song.authors self.titles = song.titles self.lang = song.get_data_argument('lang', self.config['lang']) - self.data = song.meta self.cached = { 'song': song,