From 6f7ea3c4d0810f8e97739136b02379511ed6e0df Mon Sep 17 00:00:00 2001 From: Louis Date: Sat, 19 Mar 2016 20:37:57 +0100 Subject: [PATCH 01/15] [test] Latex special characters: Add failing and incomplete tests --- test/test_songbook/latex_special.yaml | 14 ++++++++++++++ .../latex_special_datadir/songs/special.csg | 8 ++++++++ 2 files changed, 22 insertions(+) create mode 100644 test/test_songbook/latex_special.yaml create mode 100644 test/test_songbook/latex_special_datadir/songs/special.csg diff --git a/test/test_songbook/latex_special.yaml b/test/test_songbook/latex_special.yaml new file mode 100644 index 00000000..8e479e91 --- /dev/null +++ b/test/test_songbook/latex_special.yaml @@ -0,0 +1,14 @@ +book: + datadir: + - latex_special_datadir + +template: + default.tex: + title: "TODO" + author: "TODO" + patacrep.tex: + subtitle: "TODO" + url: "TODO" + email: "TODO" + picture: "img/treble_a" + diff --git a/test/test_songbook/latex_special_datadir/songs/special.csg b/test/test_songbook/latex_special_datadir/songs/special.csg new file mode 100644 index 00000000..7740b6df --- /dev/null +++ b/test/test_songbook/latex_special_datadir/songs/special.csg @@ -0,0 +1,8 @@ +{title : & % $ # _ } { ~ ^ \ } +{by: & % $ # _ } { ~ ^ \ } + +& % $ # _ } { ~ ^ \ + +{soc} + & % $ # _ } { ~ ^ \ +{eoc} From 863951dab5279c913ab9d9968b93ff31f7c58b3d Mon Sep 17 00:00:00 2001 From: Louis Date: Sat, 19 Mar 2016 22:22:28 +0100 Subject: [PATCH 02/15] [test] More complex tests --- test/test_songbook/latex_special.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/test_songbook/latex_special.yaml b/test/test_songbook/latex_special.yaml index 8e479e91..206bea46 100644 --- a/test/test_songbook/latex_special.yaml +++ b/test/test_songbook/latex_special.yaml @@ -4,11 +4,11 @@ book: template: default.tex: - title: "TODO" - author: "TODO" + title: "& % $ # _ } { ~ ^ \\" + author: "& % $ # _ } { ~ ^ \\" patacrep.tex: - subtitle: "TODO" - url: "TODO" - email: "TODO" + subtitle: "& % $ # _ } { ~ ^ \\" + url: "& % $ # _ } { ~ ^ \\" + email: "& % $ # _ } { ~ ^ \\" picture: "img/treble_a" From 443e8509a12b3a2513921021b20bc8390c77f34c Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 20 Mar 2016 07:38:19 +0100 Subject: [PATCH 03/15] [test] Refine tests. Untested draft of fix. --- patacrep/songs/chordpro/lexer.py | 8 ++++++++ test/test_song/latex.csg | 0 test/test_song/latex.csg.source | 9 +++++++++ test/test_song/latex.tsg | 0 .../latex_special_datadir/songs/special.csg | 8 ++++---- 5 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 test/test_song/latex.csg create mode 100644 test/test_song/latex.csg.source create mode 100644 test/test_song/latex.tsg diff --git a/patacrep/songs/chordpro/lexer.py b/patacrep/songs/chordpro/lexer.py index 7674c22f..ad9c4d20 100644 --- a/patacrep/songs/chordpro/lexer.py +++ b/patacrep/songs/chordpro/lexer.py @@ -30,6 +30,8 @@ tokens = ( 'EE', ) +literals = [ '{', '}', "\\", ' ' ] + class ChordProLexer: """ChordPro Lexer class""" # pylint: disable=too-many-public-methods @@ -150,6 +152,12 @@ class ChordProLexer: self.lexer.push_state('directiveargument') return token + @staticmethod + def t_literal(token): + r'\[{} \]' + t.type = t.type[1] + return t + def error(self, token, more=""): """Display error message, and skip illegal token.""" message = "Illegal character '{char}'{more}.".format( diff --git a/test/test_song/latex.csg b/test/test_song/latex.csg new file mode 100644 index 00000000..e69de29b diff --git a/test/test_song/latex.csg.source b/test/test_song/latex.csg.source new file mode 100644 index 00000000..c00062f6 --- /dev/null +++ b/test/test_song/latex.csg.source @@ -0,0 +1,9 @@ +{title: & $ % # _ \} \{ ~ ^ \\} +{artist: & $ % # _ \} \{ ~ ^ \\} +{album: & $ % # _ \} \{ ~ ^ \\} + +& $ % # _ \} \{ ~ ^ \\ + +{start_of_chorus} +& $ % # _ \} \{ ~ ^ \\ +{end_of_chorus} diff --git a/test/test_song/latex.tsg b/test/test_song/latex.tsg new file mode 100644 index 00000000..e69de29b diff --git a/test/test_songbook/latex_special_datadir/songs/special.csg b/test/test_songbook/latex_special_datadir/songs/special.csg index 7740b6df..0f058af6 100644 --- a/test/test_songbook/latex_special_datadir/songs/special.csg +++ b/test/test_songbook/latex_special_datadir/songs/special.csg @@ -1,8 +1,8 @@ -{title : & % $ # _ } { ~ ^ \ } -{by: & % $ # _ } { ~ ^ \ } +{title : & % $ # _ \} \{ ~ ^ \\ } +{by: & % $ # _ }\ \{ ~ ^ \\ } -& % $ # _ } { ~ ^ \ +& % $ # _ }\ \{ ~ ^ \\ {soc} - & % $ # _ } { ~ ^ \ + & % $ # _ }\ \{ ~ ^ \\ {eoc} From c52d309a883b90c3ef21d5b3f515ee17ace0279c Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 20 Mar 2016 22:05:27 +0100 Subject: [PATCH 04/15] [test] Mark # as an escapable character --- patacrep/songs/chordpro/lexer.py | 2 +- test/test_song/latex.csg.source | 4 ++-- .../test_songbook/latex_special_datadir/songs/special.csg | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/patacrep/songs/chordpro/lexer.py b/patacrep/songs/chordpro/lexer.py index ad9c4d20..ffeec7d4 100644 --- a/patacrep/songs/chordpro/lexer.py +++ b/patacrep/songs/chordpro/lexer.py @@ -154,7 +154,7 @@ class ChordProLexer: @staticmethod def t_literal(token): - r'\[{} \]' + r'\[{} \#]' t.type = t.type[1] return t diff --git a/test/test_song/latex.csg.source b/test/test_song/latex.csg.source index c00062f6..bbe53f98 100644 --- a/test/test_song/latex.csg.source +++ b/test/test_song/latex.csg.source @@ -2,8 +2,8 @@ {artist: & $ % # _ \} \{ ~ ^ \\} {album: & $ % # _ \} \{ ~ ^ \\} -& $ % # _ \} \{ ~ ^ \\ +& $ % \# _ \} \{ ~ ^ \\ {start_of_chorus} -& $ % # _ \} \{ ~ ^ \\ +& $ % \# _ \} \{ ~ ^ \\ {end_of_chorus} diff --git a/test/test_songbook/latex_special_datadir/songs/special.csg b/test/test_songbook/latex_special_datadir/songs/special.csg index 0f058af6..29caee7a 100644 --- a/test/test_songbook/latex_special_datadir/songs/special.csg +++ b/test/test_songbook/latex_special_datadir/songs/special.csg @@ -1,8 +1,8 @@ -{title : & % $ # _ \} \{ ~ ^ \\ } -{by: & % $ # _ }\ \{ ~ ^ \\ } +{title : & % $ \# _ \} \{ ~ ^ \\ } +{by: & % $ \# _ }\ \{ ~ ^ \\ } -& % $ # _ }\ \{ ~ ^ \\ +& % $ \# _ }\ \{ ~ ^ \\ {soc} - & % $ # _ }\ \{ ~ ^ \\ + & % $ \# _ }\ \{ ~ ^ \\ {eoc} From da9215aacd4036d2750e698de5221c9e0f011265 Mon Sep 17 00:00:00 2001 From: Louis Date: Wed, 23 Mar 2016 07:18:23 +0100 Subject: [PATCH 05/15] [WIP] Escaped characters are correctly parsed. They now have to be correctly rendered [ci skip] --- patacrep/songs/chordpro/lexer.py | 22 ++++++++++++++-------- patacrep/songs/chordpro/syntax.py | 15 ++++++++++++--- test/test_song/latex.csg | 10 ++++++++++ 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/patacrep/songs/chordpro/lexer.py b/patacrep/songs/chordpro/lexer.py index ffeec7d4..c63049aa 100644 --- a/patacrep/songs/chordpro/lexer.py +++ b/patacrep/songs/chordpro/lexer.py @@ -30,8 +30,6 @@ tokens = ( 'EE', ) -literals = [ '{', '}', "\\", ' ' ] - class ChordProLexer: """ChordPro Lexer class""" # pylint: disable=too-many-public-methods @@ -51,7 +49,7 @@ class ChordProLexer: t_directive_SPACE = r'[ \t]+' t_directive_KEYWORD = r'[a-zA-Z_]+' - t_directiveargument_TEXT = r'[^}]+' + t_directiveargument_TEXT = r'[^\\}]+' @staticmethod def t_SOC(token): @@ -120,7 +118,7 @@ class ChordProLexer: @staticmethod def t_WORD(token): - r'[^{}\r\n\]\[\t ]+' + r'[^{}\\\r\n\]\[\t ]+' return token def t_LBRACKET(self, __token): @@ -153,10 +151,18 @@ class ChordProLexer: return token @staticmethod - def t_literal(token): - r'\[{} \#]' - t.type = t.type[1] - return t + def t_ESCAPED(token): + r'\\[{} #\\]' + token.value = token.value[1] + token.type = "WORD" + return token + + @staticmethod + def t_directiveargument_ESCAPED(token): + r'\\[{} #\\]' + token.value = token.value[1] + token.type = "TEXT" + return token def error(self, token, more=""): """Display error message, and skip illegal token.""" diff --git a/patacrep/songs/chordpro/syntax.py b/patacrep/songs/chordpro/syntax.py index b4c28cc7..9a7b9feb 100644 --- a/patacrep/songs/chordpro/syntax.py +++ b/patacrep/songs/chordpro/syntax.py @@ -182,9 +182,8 @@ class ChordproParser(Parser): @staticmethod def p_directive_next(symbols): - """directive_next : SPACE COLON TEXT - | COLON TEXT - | COLON + """directive_next : SPACE COLON directive_argument + | COLON directive_argument | empty """ if len(symbols) == 3: @@ -196,6 +195,16 @@ class ChordproParser(Parser): else: symbols[0] = None + @staticmethod + def p_directive_argument(symbols): + """directive_argument : TEXT directive_argument + | empty + """ + if len(symbols) == 3: + symbols[0] = symbols[1] + symbols[2] + else: + symbols[0] = "" + def p_line_error(self, symbols): """line_error : error directive""" self.error( diff --git a/test/test_song/latex.csg b/test/test_song/latex.csg index e69de29b..7fd9cf9f 100644 --- a/test/test_song/latex.csg +++ b/test/test_song/latex.csg @@ -0,0 +1,10 @@ +{lang: en} +{title: & $ % # _ \} \{ ~ ^ \\} +{artist: & $ % # _ \} \{ ~ ^ \\} +{album: & $ % # _ \} \{ ~ ^ \\} + +& $ % \# _ \} \{ ~ ^ \\ + +{start_of_chorus} + & $ % \# _ \} \{ ~ ^ \\ +{end_of_chorus} From 83ed9ddf71744de3c3fd89a3442bfb80f4ba0099 Mon Sep 17 00:00:00 2001 From: Louis Date: Fri, 15 Apr 2016 10:05:04 +0200 Subject: [PATCH 06/15] [WIP] Escaping characters when generating chordpro files works. --- .../songs/chordpro/chordpro/content_word | 2 +- .../templates/songs/chordpro/chordpro/song_header | 8 ++++---- patacrep/songs/chordpro/__init__.py | 15 +++++++++++++++ test/test_song/latex.csg | 4 +++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/patacrep/data/templates/songs/chordpro/chordpro/content_word b/patacrep/data/templates/songs/chordpro/chordpro/content_word index d9dd7a30..e90a86e9 100644 --- a/patacrep/data/templates/songs/chordpro/chordpro/content_word +++ b/patacrep/data/templates/songs/chordpro/chordpro/content_word @@ -1 +1 @@ -(( content.value )) +(( content.value|escape_specials('{}\\#') )) diff --git a/patacrep/data/templates/songs/chordpro/chordpro/song_header b/patacrep/data/templates/songs/chordpro/chordpro/song_header index 56ad6a3a..fe9feb48 100644 --- a/patacrep/data/templates/songs/chordpro/chordpro/song_header +++ b/patacrep/data/templates/songs/chordpro/chordpro/song_header @@ -9,16 +9,16 @@ (* endif *) (*- for title in titles -*) - {title: (( title ))} + {title: (( title|escape_specials('{}\\') ))} (* endfor -*) (*- for author in authors -*) - {artist: (( author[1] )) (( author[0] ))} + {artist: (( author[1]|escape_specials('{}\\') )) (( author[0]|escape_specials('{}\\') ))} (* endfor -*) (*- for key in ['album', 'copyright'] *) (* if key in metadata -*) - {(( key )): (( metadata[key] ))} + {(( key )): (( metadata[key]|escape_specials('{}\\') ))} (* endif *) (* endfor *) (* if 'cover' in metadata -*) @@ -30,7 +30,7 @@ (* endfor -*) (*- for key in metadata.morekeys -*) - {key: (( key.keyword )): (( key.argument ))} + {key: (( key.keyword )): (( key.argument|escape_specials('{}\\') ))} (* endfor *) (*- for chord in metadata['define'] *) diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index a7fd3e3b..c63a07b8 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -30,6 +30,7 @@ class ChordproSong(Song): # pylint: disable=abstract-method output_language = None + _translation_map = {} def _parse(self): """Parse content, and return the dictionary of song data.""" @@ -50,6 +51,7 @@ class ChordproSong(Song): filters.update({ 'search_image': self.search_image, 'search_partition': self.search_partition, + 'escape_specials': self._escape_specials, }) return filters @@ -84,6 +86,13 @@ class ChordproSong(Song): context.vars['content'] = content return context.environment.get_template(content.template()).render(context) + def _escape_specials(self, content, chars): + return str(content).translate(str.maketrans({ + key: value + for key, value in self._translation_map.items() + if key in chars + })) + class Chordpro2HtmlSong(ChordproSong): """Render chordpro song to html code""" @@ -164,6 +173,12 @@ class Chordpro2ChordproSong(ChordproSong): """Render chordpro song to chordpro code""" output_language = "chordpro" + _translation_map = { + '{': r'\{', + '}': r'\}', + '\\': '\\\\', + '#': r'\#', + } def search_file(self, filename, extensions=None, *, datadirs=None): # pylint: disable=unused-variable diff --git a/test/test_song/latex.csg b/test/test_song/latex.csg index 7fd9cf9f..c26ff044 100644 --- a/test/test_song/latex.csg +++ b/test/test_song/latex.csg @@ -1,10 +1,12 @@ {lang: en} {title: & $ % # _ \} \{ ~ ^ \\} -{artist: & $ % # _ \} \{ ~ ^ \\} +{artist: & $ % # _ \} \{ ~ ^ \\} {album: & $ % # _ \} \{ ~ ^ \\} + & $ % \# _ \} \{ ~ ^ \\ + {start_of_chorus} & $ % \# _ \} \{ ~ ^ \\ {end_of_chorus} From 1e488b26eca2756bc7d7b2da2e7cbc509b260367 Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 17 Apr 2016 07:37:52 +0200 Subject: [PATCH 07/15] [WIP] Special chars, and TODO --- test/test_song/latex.tsg | 0 test/test_song/{latex.csg => special.csg} | 0 .../{latex.csg.source => special.csg.source} | 1 + test/test_song/special.tsg | 21 +++++++++++++++++++ .../{latex_special.yaml => special.yaml} | 2 +- .../songs/special.csg | 0 6 files changed, 23 insertions(+), 1 deletion(-) delete mode 100644 test/test_song/latex.tsg rename test/test_song/{latex.csg => special.csg} (100%) rename test/test_song/{latex.csg.source => special.csg.source} (94%) create mode 100644 test/test_song/special.tsg rename test/test_songbook/{latex_special.yaml => special.yaml} (90%) rename test/test_songbook/{latex_special_datadir => special_datadir}/songs/special.csg (100%) diff --git a/test/test_song/latex.tsg b/test/test_song/latex.tsg deleted file mode 100644 index e69de29b..00000000 diff --git a/test/test_song/latex.csg b/test/test_song/special.csg similarity index 100% rename from test/test_song/latex.csg rename to test/test_song/special.csg diff --git a/test/test_song/latex.csg.source b/test/test_song/special.csg.source similarity index 94% rename from test/test_song/latex.csg.source rename to test/test_song/special.csg.source index bbe53f98..128cfa98 100644 --- a/test/test_song/latex.csg.source +++ b/test/test_song/special.csg.source @@ -1,3 +1,4 @@ +TODO url ? {title: & $ % # _ \} \{ ~ ^ \\} {artist: & $ % # _ \} \{ ~ ^ \\} {album: & $ % # _ \} \{ ~ ^ \\} diff --git a/test/test_song/special.tsg b/test/test_song/special.tsg new file mode 100644 index 00000000..aa42a9cc --- /dev/null +++ b/test/test_song/special.tsg @@ -0,0 +1,21 @@ +\selectlanguage{english} + +\beginsong{\& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}}[ + by={ + \& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} }, + album={\& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}}, +] + + + + +\begin{verse} + \& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} +\end{verse} + + +\begin{chorus} + \& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} +\end{chorus} + +\endsong diff --git a/test/test_songbook/latex_special.yaml b/test/test_songbook/special.yaml similarity index 90% rename from test/test_songbook/latex_special.yaml rename to test/test_songbook/special.yaml index 206bea46..895b838c 100644 --- a/test/test_songbook/latex_special.yaml +++ b/test/test_songbook/special.yaml @@ -1,6 +1,6 @@ book: datadir: - - latex_special_datadir + - special_datadir template: default.tex: diff --git a/test/test_songbook/latex_special_datadir/songs/special.csg b/test/test_songbook/special_datadir/songs/special.csg similarity index 100% rename from test/test_songbook/latex_special_datadir/songs/special.csg rename to test/test_songbook/special_datadir/songs/special.csg From dfc7762931b7b0e350e99f2799de42eda02e2753 Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 17 Apr 2016 08:27:47 +0200 Subject: [PATCH 08/15] [WIP] Special characters: Song generation works. Songbook generation remains to implement --- .../templates/songs/chordpro/latex/content_word | 2 +- patacrep/data/templates/songs/chordpro/latex/song | 8 ++++---- patacrep/songs/chordpro/__init__.py | 12 ++++++++++++ test/test_song/special.csg.source | 2 +- .../special_datadir/songs/special.csg | 14 ++++++++------ 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/patacrep/data/templates/songs/chordpro/latex/content_word b/patacrep/data/templates/songs/chordpro/latex/content_word index d9dd7a30..ebe4d86f 100644 --- a/patacrep/data/templates/songs/chordpro/latex/content_word +++ b/patacrep/data/templates/songs/chordpro/latex/content_word @@ -1 +1 @@ -(( content.value )) +(( content.value|escape_specials('{}&#_^%~$\\') )) diff --git a/patacrep/data/templates/songs/chordpro/latex/song b/patacrep/data/templates/songs/chordpro/latex/song index cb29cc29..d2cbe830 100644 --- a/patacrep/data/templates/songs/chordpro/latex/song +++ b/patacrep/data/templates/songs/chordpro/latex/song @@ -8,7 +8,7 @@ \beginsong{ (*- for title in titles -*) - (( title )) + (( title|escape_specials('{}&#_^%~$\\') )) (*- if not loop.last -*) \\ (* endif *) @@ -16,7 +16,7 @@ }[ by={ (* for author in authors *) - (( author[1] )) (( author[0] )) + (( author[1]|escape_specials('{}&#_^%~$\\') )) (( author[0]|escape_specials('{}&#_^%~$\\') )) (*- if not loop.last -*) , (* endif *) @@ -24,7 +24,7 @@ }, (* for key in ['album', 'copyright'] *) (* if key in metadata *) - (( key ))={(( metadata[key] ))}, + (( key ))={(( metadata[key]|escape_specials('{}&#_^%~$\\') ))}, (* endif *) (* endfor *) (* if 'cover' in metadata *) @@ -36,7 +36,7 @@ (* endblock *) (* endif *) (* for key in metadata.morekeys *) - (( key.keyword ))={(( key.argument ))}, + (( key.keyword ))={(( key.argument|escape_specials('{}&#_^%~$\\') ))}, (* endfor *) ] diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index c63a07b8..4318cd6a 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -113,6 +113,18 @@ class Chordpro2LatexSong(ChordproSong): """Render chordpro song to latex code""" output_language = "latex" + _translation_map = { + '{': r'\{', + '}': r'\}', + '\\': r'\textbackslash{}', + '^': r'\textasciicircum{}', + '~': r'\textasciitilde{}', + '#': r'\#', + '&': r'\&', + '$': r'\$', + '%': r'\%', + '_': r'\_', + } def search_file(self, filename, extensions=None, *, datadirs=None): _datadir, filename, _extension = self.search_datadir_file( diff --git a/test/test_song/special.csg.source b/test/test_song/special.csg.source index 128cfa98..cb8d7c9d 100644 --- a/test/test_song/special.csg.source +++ b/test/test_song/special.csg.source @@ -1,7 +1,7 @@ -TODO url ? {title: & $ % # _ \} \{ ~ ^ \\} {artist: & $ % # _ \} \{ ~ ^ \\} {album: & $ % # _ \} \{ ~ ^ \\} +{url: & $ % # _ \} \{ ~ ^ \\} & $ % \# _ \} \{ ~ ^ \\ diff --git a/test/test_songbook/special_datadir/songs/special.csg b/test/test_songbook/special_datadir/songs/special.csg index 29caee7a..cb8d7c9d 100644 --- a/test/test_songbook/special_datadir/songs/special.csg +++ b/test/test_songbook/special_datadir/songs/special.csg @@ -1,8 +1,10 @@ -{title : & % $ \# _ \} \{ ~ ^ \\ } -{by: & % $ \# _ }\ \{ ~ ^ \\ } +{title: & $ % # _ \} \{ ~ ^ \\} +{artist: & $ % # _ \} \{ ~ ^ \\} +{album: & $ % # _ \} \{ ~ ^ \\} +{url: & $ % # _ \} \{ ~ ^ \\} -& % $ \# _ }\ \{ ~ ^ \\ +& $ % \# _ \} \{ ~ ^ \\ -{soc} - & % $ \# _ }\ \{ ~ ^ \\ -{eoc} +{start_of_chorus} +& $ % \# _ \} \{ ~ ^ \\ +{end_of_chorus} From 446181d818398e0d233272822ae1ec2a87ee7c18 Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 17 Apr 2016 09:49:10 +0200 Subject: [PATCH 09/15] todo --- test/test_song/special.csg | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_song/special.csg b/test/test_song/special.csg index c26ff044..ea9460d8 100644 --- a/test/test_song/special.csg +++ b/test/test_song/special.csg @@ -2,6 +2,7 @@ {title: & $ % # _ \} \{ ~ ^ \\} {artist: & $ % # _ \} \{ ~ ^ \\} {album: & $ % # _ \} \{ ~ ^ \\} +{url: & $ % # _ \} \{ ~ ^ \\} & $ % \# _ \} \{ ~ ^ \\ From ef58fb63e7bff8a7e5cb70745c4fc6b737698664 Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 17 Apr 2016 12:27:04 +0200 Subject: [PATCH 10/15] [WIP] Url rendering works --- patacrep/data/templates/songs/chordpro/chordpro/song_header | 4 ++++ patacrep/data/templates/songs/chordpro/latex/song | 3 +++ test/test_song/special.csg | 2 +- test/test_song/special.csg.source | 2 +- test/test_song/special.tsg | 1 + 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/patacrep/data/templates/songs/chordpro/chordpro/song_header b/patacrep/data/templates/songs/chordpro/chordpro/song_header index fe9feb48..e73da259 100644 --- a/patacrep/data/templates/songs/chordpro/chordpro/song_header +++ b/patacrep/data/templates/songs/chordpro/chordpro/song_header @@ -33,6 +33,10 @@ {key: (( key.keyword )): (( key.argument|escape_specials('{}\\') ))} (* endfor *) +(*- if 'url' in metadata -*) + {url: (( metadata.url ))} +(* endif -*) + (*- for chord in metadata['define'] *) ((- render(chord) )) (* endfor *) diff --git a/patacrep/data/templates/songs/chordpro/latex/song b/patacrep/data/templates/songs/chordpro/latex/song index d2cbe830..2830fc34 100644 --- a/patacrep/data/templates/songs/chordpro/latex/song +++ b/patacrep/data/templates/songs/chordpro/latex/song @@ -27,6 +27,9 @@ (( key ))={(( metadata[key]|escape_specials('{}&#_^%~$\\') ))}, (* endif *) (* endfor *) + (* if 'url' in metadata *) + url={(( metadata.url|escape_specials('%#') ))}, + (* endif *) (* if 'cover' in metadata *) (* block cover *) (* set cover = metadata["cover"].argument|search_image|path2posix *) diff --git a/test/test_song/special.csg b/test/test_song/special.csg index ea9460d8..59b8d817 100644 --- a/test/test_song/special.csg +++ b/test/test_song/special.csg @@ -2,7 +2,7 @@ {title: & $ % # _ \} \{ ~ ^ \\} {artist: & $ % # _ \} \{ ~ ^ \\} {album: & $ % # _ \} \{ ~ ^ \\} -{url: & $ % # _ \} \{ ~ ^ \\} +{url: http://&$%#_~^} & $ % \# _ \} \{ ~ ^ \\ diff --git a/test/test_song/special.csg.source b/test/test_song/special.csg.source index cb8d7c9d..f5874022 100644 --- a/test/test_song/special.csg.source +++ b/test/test_song/special.csg.source @@ -1,7 +1,7 @@ {title: & $ % # _ \} \{ ~ ^ \\} {artist: & $ % # _ \} \{ ~ ^ \\} {album: & $ % # _ \} \{ ~ ^ \\} -{url: & $ % # _ \} \{ ~ ^ \\} +{url: http://&$%#_~^} & $ % \# _ \} \{ ~ ^ \\ diff --git a/test/test_song/special.tsg b/test/test_song/special.tsg index aa42a9cc..a7b232bb 100644 --- a/test/test_song/special.tsg +++ b/test/test_song/special.tsg @@ -4,6 +4,7 @@ by={ \& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} }, album={\& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}}, + url={http://&$\%\#_~^}, ] From cfb739d2bbf4500e437cb8a473af97bb052c0241 Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 17 Apr 2016 12:49:55 +0200 Subject: [PATCH 11/15] Move missing image from patadata --- patacrep/data/img/internet.png | Bin 0 -> 1690 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 patacrep/data/img/internet.png diff --git a/patacrep/data/img/internet.png b/patacrep/data/img/internet.png new file mode 100644 index 0000000000000000000000000000000000000000..43299f171a2a6e92b9580c6f2f6eb86394022faa GIT binary patch literal 1690 zcmV;L24(q)P)eiku)l}3_WJhP`h-%7=hfk3$2MEK_0?F0{jpSE3Zt+mj3N~U z;mwL)y|h-T=9NxVA}RmYRNv6NzkjclPNylC%Xps0mMvR( zvA2i2V`Fr6b}=$C%-yju{{H?4{wJRfj-%q^*RNf>@mzs#9e(BKxm@c=K0={qv*PUQZaEH^UizksXzYtY>47#Hwst(@RYzS zN007LCX$y2`uCcfnwn5bF+V?tVHlXE#kRI>?ArAL<<&B|Yzu~AVi-D7O2RNe2*C#* ze#md${9T}8Ik4_TD5dD@>oeOrI)*#ix3_KI)~d-!l1wJCY#T$@>FDTWXV*@IP;8v2 zuIrelNu{zz6h$bd_~-cx>Q`^PIjYO3w^%HO8i1Ls`K4uAxu(VjO)16h-Mf)eGC6Ud z9Xr}-X~|J2T;<%`=NK6oX6)V==o%r$>`^~0?M$+jz9LHto&JY4Pc<>;JM1t}0apG7pJ3GUww~B4rw6(R--rml> zeSHK$@W_{9XlRHZpZIAgHL=wYk^{DF2g!tMJ}9qHtyZvY2jBNeC6lynZKbufmAzls z3qYw<;`V2^$zyCHN6$8l)g+Dc<%6YcHo)YaCJzxpv99i2pxzaN@i&ebG&~-e|BM1UyED1uNjvYHtNsg$w7= zG>y^EM>zY|UrD$wv5NO->*nJ)CJaNOFd~X1|GIqniAb*Bd?WGW&m;r`2L_0wn5J+X_`h$u7%-|VG6}-OwTM< zK%5@T=VuK7BaTijE|rcqHq`HEZq8~C9;^_CA+@!2luAoakgdBELLh{O5OD78b5yET zJkMicX(bM$Xu^o2Qve!3u~-bFFgSMWvpdn!Qi;aKCOSI1*x$dOTrNjlZ5^3(hUQJp z+@F{rilWEv=H}+PGdxUPZ5@NRZn3bm9HHXl>)Y*#g|nxB;3o*qG&N+5)-5@$zP_GR zBE?#@LJ$OmVL%v!9654?{=R-5l*^nw`xhL?Wqfiv&R;7=&s{h|2pe$QJ3ISo(wRS5 zrkQKWHaIn@6t->Sc^* zp#e$21rnBJ)okzTKH<2|4@|=dlL^;y97{JJ<=+nis?|Wou?j*d&6VYqx9*MH`F#)s zWnc}c0G?7R-snIB5`gmvcBZMRrLL}ipY2#LS(dX`(?lmg9IMeFsD9#CgPSWWOaCs- k&rbtBP<@0orBn>?U%}=R$B%^+O#lD@07*qoM6N<$f{L6u^8f$< literal 0 HcmV?d00001 From 46912414335776db0a9993368a4965141278dcd5 Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 17 Apr 2016 13:04:17 +0200 Subject: [PATCH 12/15] [test][WIP] More tests [CI skip] --- test/test_book/special.tex.control | 163 ++++++++++++++++++ test/test_book/special.yaml | 4 +- .../special_datadir/songs/special.csg | 2 +- 3 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 test/test_book/special.tex.control diff --git a/test/test_book/special.tex.control b/test/test_book/special.tex.control new file mode 100644 index 00000000..82092969 --- /dev/null +++ b/test/test_book/special.tex.control @@ -0,0 +1,163 @@ + + + + + + +%% Automatically generated document. +%% You may edit this file but all changes will be overwritten. +%% If you want to change this document, have a look at +%% the templating system. +%% +%% Generated using Songbook + +\makeatletter +\def\input@path{ % + {@TEST_FOLDER@/special_datadir/templates/styles/} % + {@TEST_FOLDER@/templates/styles/} % + {@DATA_FOLDER@/templates/styles/} % +} +\makeatother + +\documentclass[ + ]{article} + +\usepackage[ +chorded, +pictures, +repeatchords, +importantdiagramonly, +diagrampage, +guitar, + ]{crepbook} + +\usepackage[ + a4paper % paper size + ,includeheadfoot % include header and footer into text size + ,hmarginratio=1:1 % ratio between inner and outer margin (default) + ,outer=1.8cm % outer margin (right) + ,vmarginratio=1:1 % ratio between top and bottom margin + ,bmargin=1.3cm % bottom margin + ]{geometry} + +\usepackage{lmodern} + + +\PassOptionsToPackage{english}{babel} +\usepackage[english]{babel} +\lang{english} + +\usepackage{graphicx} +\graphicspath{ % + {@TEST_FOLDER@/special_datadir/} % + {@TEST_FOLDER@/} % + {@DATA_FOLDER@/} % +} + + +\makeatletter +\@ifpackageloaded{hyperref}{}{ + \usepackage{url} + \newcommand{\phantomsection}{} + \newcommand{\hyperlink}[2]{#2} + \newcommand{\href}[2]{\expandafter\url\expandafter{#1}} +} +\makeatother + + +\usepackage{chords} + +\title{\& \% \$ \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} } +\author{\& \% \$ \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} } + +\newindex{titleidx}{special_title} +\newauthorindex{authidx}{special_auth} + +\authignoreword{unknown} +\authbyword{by} +\authsepword{and} + +\notenamesout{A}{B}{C}{D}{E}{F}{G} + + +\pagestyle{empty}\definecolor{SongNumberBgColor}{HTML}{D1E4AE} +\definecolor{NoteBgColor}{HTML}{D1E4AE} +\definecolor{IndexBgColor}{HTML}{D1E4AE} + +\renewcommand{\snumbgcolor}{SongNumberBgColor} +\renewcommand{\notebgcolor}{NoteBgColor} +\renewcommand{\idxbgcolor}{IndexBgColor} + +\definecolor{tango-green-3}{HTML}{4e9a06} +\definecolor{tango-blue-3}{HTML}{204a87} +\usepackage[ + bookmarks, + bookmarksopen, + hyperfigures=true, + colorlinks=true, + linkcolor=tango-green-3, + urlcolor=tango-blue-3 + ]{hyperref} + + +\subtitle{\& \% \$ \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}} +\mail{http://\%25\%20\%26\%24\%5C\%23_\%7E\%5E\%7B\%7D} +\web{http://\%25\%20\%26\%24\%5C\%23_\%7E\%5E\%7B\%7D} + +\picture{img/treble_a} +\picturecopyright{Dbolton \url{http://commons.wikimedia.org/wiki/User:Dbolton}} +\footer{Generated using Songbook (\url{http://www.patacrep.com})} + + +\begin{document} + +\maketitle + + +\showindex{\songindexname}{titleidx} +\showindex{\authorindexname}{authidx} + +% list of chords +\ifdiagrampage + \phantomsection + \addcontentsline{toc}{section}{\chordlistname} + \chords +\fi +\setcounter{songnum}{1}% + +\phantomsection +\addcontentsline{toc}{section}{\songlistname} + +\begin{songs}{titleidx,authidx} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% songs/./special.csg + +\selectlanguage{english} + +\beginsong{\& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}}[ + by={ + \& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} }, + album={\& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}}, + url={http://&$\%\#_~^}, +] + + + + +\begin{verse} + \& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} +\end{verse} + + +\begin{chorus} + \& \$ \% \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} +\end{chorus} + +\endsong + +\end{songs} + + + + +\end{document} diff --git a/test/test_book/special.yaml b/test/test_book/special.yaml index 895b838c..005bc2c7 100644 --- a/test/test_book/special.yaml +++ b/test/test_book/special.yaml @@ -8,7 +8,7 @@ template: author: "& % $ # _ } { ~ ^ \\" patacrep.tex: subtitle: "& % $ # _ } { ~ ^ \\" - url: "& % $ # _ } { ~ ^ \\" - email: "& % $ # _ } { ~ ^ \\" + url: "http://% &$\\#_~^{}" + email: "% &$\\#_~^{}" picture: "img/treble_a" diff --git a/test/test_book/special_datadir/songs/special.csg b/test/test_book/special_datadir/songs/special.csg index cb8d7c9d..f5874022 100644 --- a/test/test_book/special_datadir/songs/special.csg +++ b/test/test_book/special_datadir/songs/special.csg @@ -1,7 +1,7 @@ {title: & $ % # _ \} \{ ~ ^ \\} {artist: & $ % # _ \} \{ ~ ^ \\} {album: & $ % # _ \} \{ ~ ^ \\} -{url: & $ % # _ \} \{ ~ ^ \\} +{url: http://&$%#_~^} & $ % \# _ \} \{ ~ ^ \\ From a831b421a97ea28f11bccbd9fe6733d6c9537716 Mon Sep 17 00:00:00 2001 From: Louis Date: Sun, 17 Apr 2016 16:23:13 +0200 Subject: [PATCH 13/15] TODO --- test/test_book/special.tex.control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_book/special.tex.control b/test/test_book/special.tex.control index 82092969..f303e5d5 100644 --- a/test/test_book/special.tex.control +++ b/test/test_book/special.tex.control @@ -101,8 +101,8 @@ guitar, \subtitle{\& \% \$ \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}} -\mail{http://\%25\%20\%26\%24\%5C\%23_\%7E\%5E\%7B\%7D} -\web{http://\%25\%20\%26\%24\%5C\%23_\%7E\%5E\%7B\%7D} +\mail{http://\%25\%20\%26\%24\%5C\%23_\%7E\%5E\%7B\%7D} TODO Do not use encoded chars (%24, and so on). It is eventually a bad idea. Or as least as possible. +\web{http://\%25\%20\%26\%24\%5C\%23_\%7E\%5E\%7B\%7D} TODO Idem \picture{img/treble_a} \picturecopyright{Dbolton \url{http://commons.wikimedia.org/wiki/User:Dbolton}} From 173c0cafc3d07bc3bf156f82d893c3eb419a3e7d Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 19 Apr 2016 15:25:28 +0200 Subject: [PATCH 14/15] [WIP] TeX generation works; TeX compilation does not --- patacrep/data/templates/songbook/default.tex | 4 +- patacrep/data/templates/songbook/patacrep.tex | 6 +-- .../songs/chordpro/chordpro/song_header | 2 +- .../data/templates/songs/chordpro/latex/song | 2 +- patacrep/songs/chordpro/__init__.py | 31 ++++++++++- patacrep/templates.py | 52 +++++++++++++------ test/test_book/special.tex.control | 9 ++-- test/test_book/special.yaml | 4 +- 8 files changed, 79 insertions(+), 31 deletions(-) diff --git a/patacrep/data/templates/songbook/default.tex b/patacrep/data/templates/songbook/default.tex index 5eef827a..d3b6fd34 100644 --- a/patacrep/data/templates/songbook/default.tex +++ b/patacrep/data/templates/songbook/default.tex @@ -66,8 +66,8 @@ description: \usepackage{chords} -\title{(( template_var.title ))} -\author{(( template_var.author ))} +\title{(( template_var.title|escape_specials() ))} +\author{(( template_var.author|escape_specials() ))} \newindex{titleidx}{((filename))_title} \newauthorindex{authidx}{((filename))_auth} diff --git a/patacrep/data/templates/songbook/patacrep.tex b/patacrep/data/templates/songbook/patacrep.tex index 627ee080..d57f44e4 100644 --- a/patacrep/data/templates/songbook/patacrep.tex +++ b/patacrep/data/templates/songbook/patacrep.tex @@ -138,12 +138,12 @@ description: ]{hyperref} -\subtitle{(( template_var.subtitle ))} +\subtitle{(( template_var.subtitle|escape_specials ))} (* if template_var.version -*) \version{(( template_var.version ))} (* endif *) -\mail{(( template_var.email ))} -\web{(( template_var.url ))} +\mail{(( template_var.email|escape_url ))} +\web{(( template_var.url|escape_url ))} \picture{(( template_var.picture ))} \picturecopyright{(( template_var.picturecopyright ))} \footer{(( template_var.footer ))} diff --git a/patacrep/data/templates/songs/chordpro/chordpro/song_header b/patacrep/data/templates/songs/chordpro/chordpro/song_header index e73da259..bca4357e 100644 --- a/patacrep/data/templates/songs/chordpro/chordpro/song_header +++ b/patacrep/data/templates/songs/chordpro/chordpro/song_header @@ -34,7 +34,7 @@ (* endfor *) (*- if 'url' in metadata -*) - {url: (( metadata.url ))} + {url: (( metadata.url|escape_url ))} (* endif -*) (*- for chord in metadata['define'] *) diff --git a/patacrep/data/templates/songs/chordpro/latex/song b/patacrep/data/templates/songs/chordpro/latex/song index 2830fc34..08591d3a 100644 --- a/patacrep/data/templates/songs/chordpro/latex/song +++ b/patacrep/data/templates/songs/chordpro/latex/song @@ -28,7 +28,7 @@ (* endif *) (* endfor *) (* if 'url' in metadata *) - url={(( metadata.url|escape_specials('%#') ))}, + url={(( metadata.url|escape_url ))}, (* endif *) (* if 'cover' in metadata *) (* block cover *) diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index 4318cd6a..6f1ca655 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -3,6 +3,7 @@ import logging import operator import os +import urllib from jinja2 import Environment, FileSystemLoader, ChoiceLoader from jinja2 import contextfunction @@ -31,6 +32,12 @@ class ChordproSong(Song): output_language = None _translation_map = {} + _translation_map_url = None + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if self._translation_map_url is None: + self._translation_map_url = self._translation_map def _parse(self): """Parse content, and return the dictionary of song data.""" @@ -52,6 +59,7 @@ class ChordproSong(Song): 'search_image': self.search_image, 'search_partition': self.search_partition, 'escape_specials': self._escape_specials, + 'escape_url': self._escape_url, }) return filters @@ -86,13 +94,20 @@ class ChordproSong(Song): context.vars['content'] = content return context.environment.get_template(content.template()).render(context) - def _escape_specials(self, content, chars): + def _escape_specials(self, content, chars=None, *, translation_map=None): + if translation_map is None: + translation_map = self._translation_map + if chars is None: + chars = translation_map.keys() return str(content).translate(str.maketrans({ key: value - for key, value in self._translation_map.items() + for key, value in translation_map.items() if key in chars })) + def _escape_url(self, content): + return self._escape_specials(content, translation_map=self._translation_map_url) + class Chordpro2HtmlSong(ChordproSong): """Render chordpro song to html code""" @@ -125,6 +140,13 @@ class Chordpro2LatexSong(ChordproSong): '%': r'\%', '_': r'\_', } + _translation_map_url = { + " ": urllib.parse.quote(" "), + "{": urllib.parse.quote("{"), + "}": urllib.parse.quote("}"), + '%': r'\%', + '#': r'\#', + } def search_file(self, filename, extensions=None, *, datadirs=None): _datadir, filename, _extension = self.search_datadir_file( @@ -191,6 +213,11 @@ class Chordpro2ChordproSong(ChordproSong): '\\': '\\\\', '#': r'\#', } + _translation_map_url = { + '{': r'\{', + '}': r'\}', + '\\': '\\\\', + } def search_file(self, filename, extensions=None, *, datadirs=None): # pylint: disable=unused-variable diff --git a/patacrep/templates.py b/patacrep/templates.py index c18ef454..c68f78cc 100644 --- a/patacrep/templates.py +++ b/patacrep/templates.py @@ -2,6 +2,7 @@ import logging import re +import urllib import yaml @@ -16,15 +17,6 @@ import patacrep.encoding LOGGER = logging.getLogger(__name__) -_LATEX_SUBS = ( - (re.compile(r'\\'), r'\\textbackslash'), - (re.compile(r'([{}_#%&$])'), r'\\\1'), - (re.compile(r'~'), r'\~{}'), - (re.compile(r'\^'), r'\^{}'), - (re.compile(r'"'), r"''"), - (re.compile(r'\.\.\.+'), r'\\ldots'), -) - _VARIABLE_REGEXP = re.compile( r""" \(\*-?\ *variables\ *\*\) # Match (* variables *) or (*- variables *) @@ -46,15 +38,45 @@ _VARIABLE_REGEXP = re.compile( """, re.VERBOSE|re.DOTALL) -def _escape_tex(value): +TRANSLATION_MAP = { + '{': r'\{', + '}': r'\}', + '\\': r'\textbackslash{}', + '^': r'\textasciicircum{}', + '~': r'\textasciitilde{}', + '#': r'\#', + '&': r'\&', + '$': r'\$', + '%': r'\%', + '_': r'\_', +} +TRANSLATION_MAP_URL = { + ' ': '\\' + urllib.parse.quote(" "), + '{': '\\' + urllib.parse.quote("{"), + '}': '\\' + urllib.parse.quote("}"), + '%': '\\%', + '\\': '\\\\', + } + +def _escape_specials(text, *, chars=None, translation_map=None): '''Escape TeX special characters''' - newval = value - for pattern, replacement in _LATEX_SUBS: - newval = pattern.sub(replacement, newval) - return newval + if translation_map is None: + translation_map = TRANSLATION_MAP + if chars is None: + chars = translation_map.keys() + return str(text).translate(str.maketrans({ + key: value + for key, value in translation_map.items() + if key in chars + })) + +def _escape_url(text): + """Escape TeX special characters, in url.""" + return _escape_specials(text, translation_map=TRANSLATION_MAP_URL) DEFAULT_FILTERS = { - "escape_tex": _escape_tex, + "escape_specials": _escape_specials, + "escape_url": _escape_url, "iter_datadirs": files.iter_datadirs, "path2posix": files.path2posix, } diff --git a/test/test_book/special.tex.control b/test/test_book/special.tex.control index f303e5d5..7c8e24ca 100644 --- a/test/test_book/special.tex.control +++ b/test/test_book/special.tex.control @@ -67,8 +67,8 @@ guitar, \usepackage{chords} -\title{\& \% \$ \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} } -\author{\& \% \$ \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{} } +\title{\& \% \$ \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}} +\author{\& \% \$ \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}} \newindex{titleidx}{special_title} \newauthorindex{authidx}{special_auth} @@ -101,9 +101,8 @@ guitar, \subtitle{\& \% \$ \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}} -\mail{http://\%25\%20\%26\%24\%5C\%23_\%7E\%5E\%7B\%7D} TODO Do not use encoded chars (%24, and so on). It is eventually a bad idea. Or as least as possible. -\web{http://\%25\%20\%26\%24\%5C\%23_\%7E\%5E\%7B\%7D} TODO Idem - +\mail{foo@\\\%&$#_~^\%20\%7B\%7D} +\web{http://\\\%&$#_~^\%20\%7B\%7D} \picture{img/treble_a} \picturecopyright{Dbolton \url{http://commons.wikimedia.org/wiki/User:Dbolton}} \footer{Generated using Songbook (\url{http://www.patacrep.com})} diff --git a/test/test_book/special.yaml b/test/test_book/special.yaml index 005bc2c7..24731c57 100644 --- a/test/test_book/special.yaml +++ b/test/test_book/special.yaml @@ -8,7 +8,7 @@ template: author: "& % $ # _ } { ~ ^ \\" patacrep.tex: subtitle: "& % $ # _ } { ~ ^ \\" - url: "http://% &$\\#_~^{}" - email: "% &$\\#_~^{}" + url: "http://\\%&$#_~^ {}" + email: "foo@\\%&$#_~^ {}" picture: "img/treble_a" From 24515962f18aa7430f6980ccfc258d5355708d7b Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 19 Apr 2016 16:55:44 +0200 Subject: [PATCH 15/15] LaTeX compilation of URLs containing weird characters works --- patacrep/data/templates/styles/crepbook.sty | 4 ++-- patacrep/templates.py | 2 ++ test/test_book/special.tex.control | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/patacrep/data/templates/styles/crepbook.sty b/patacrep/data/templates/styles/crepbook.sty index 8d7139c0..f89bebee 100644 --- a/patacrep/data/templates/styles/crepbook.sty +++ b/patacrep/data/templates/styles/crepbook.sty @@ -79,8 +79,8 @@ % Title page \long\def\subtitle#1{\long\def\@subtitle{#1}} \def\version#1{\def\@version{#1}} -\def\web#1{\def\@web{#1}} -\def\mail#1{\def\@mail{#1}} +\def\web#1{\def\@web{\url{#1}}} +\def\mail#1{\def\@mail{\href{mailto:#1}{\nolinkurl{#1}}}} \def\email#1{\def\@email{#1}} \def\picture#1{\def\@picture{#1}} \def\picturecopyright#1{\def\@picturecopyright{#1}} diff --git a/patacrep/templates.py b/patacrep/templates.py index c68f78cc..214320eb 100644 --- a/patacrep/templates.py +++ b/patacrep/templates.py @@ -56,6 +56,8 @@ TRANSLATION_MAP_URL = { '}': '\\' + urllib.parse.quote("}"), '%': '\\%', '\\': '\\\\', + '#': '\\#', + '&': '\\&', } def _escape_specials(text, *, chars=None, translation_map=None): diff --git a/test/test_book/special.tex.control b/test/test_book/special.tex.control index 7c8e24ca..8f7d845a 100644 --- a/test/test_book/special.tex.control +++ b/test/test_book/special.tex.control @@ -101,8 +101,8 @@ guitar, \subtitle{\& \% \$ \# \_ \} \{ \textasciitilde{} \textasciicircum{} \textbackslash{}} -\mail{foo@\\\%&$#_~^\%20\%7B\%7D} -\web{http://\\\%&$#_~^\%20\%7B\%7D} +\mail{foo@\\\%\&$\#_~^\%20\%7B\%7D} +\web{http://\\\%\&$\#_~^\%20\%7B\%7D} \picture{img/treble_a} \picturecopyright{Dbolton \url{http://commons.wikimedia.org/wiki/User:Dbolton}} \footer{Generated using Songbook (\url{http://www.patacrep.com})}