diff --git a/patacrep/data/templates/songs/chordpro/chordpro/content_image b/patacrep/data/templates/songs/chordpro/chordpro/content_image index 4f9bf06c..7398eec3 100644 --- a/patacrep/data/templates/songs/chordpro/chordpro/content_image +++ b/patacrep/data/templates/songs/chordpro/chordpro/content_image @@ -1 +1 @@ -{image: (( content.argument|search_image ))} +{image: "(( content.filename|search_image ))" ((content.size|render_size))} diff --git a/patacrep/data/templates/songs/chordpro/latex/content_image b/patacrep/data/templates/songs/chordpro/latex/content_image index a567730d..be75cec6 100644 --- a/patacrep/data/templates/songs/chordpro/latex/content_image +++ b/patacrep/data/templates/songs/chordpro/latex/content_image @@ -1,6 +1,6 @@ (* block image *) -(* set image = content.argument|search_image|path2posix *) +(* set image = content.filename|search_image|path2posix *) (* if image *) -\image{(( image ))} +\image[(( content.size|render_size ))]{(( image ))} (*- endif *) (*- endblock *) diff --git a/patacrep/data/templates/styles/patacrep.sty b/patacrep/data/templates/styles/patacrep.sty index d4fb85f1..dad1e7d5 100644 --- a/patacrep/data/templates/styles/patacrep.sty +++ b/patacrep/data/templates/styles/patacrep.sty @@ -6,6 +6,7 @@ \NeedsTeXFormat{LaTeX2e}[1994/06/01] \ProvidesPackage{patacrep}[2014/06/17 Patacrep Package, version 1] +\RequirePackage[space]{grffile} \RequirePackage{graphicx,xcolor} % \RequirePackage{epstopdf} % \RequirePackage{fancybox} @@ -400,7 +401,9 @@ \renewcommand{\textnote}[2][]{% \vspace{.1cm} \IfStrEq{}{#1}{\@textnoteold{#2}}{ - \iflanguage{#1}{\@textnoteold{#2}}{} + \IfStrEq{\mainlanguage}{#1}{ + \@textnoteold{#2} + }{} } } @@ -408,7 +411,9 @@ \renewcommand{\musicnote}[2][]{% \vspace{.1cm} \IfStrEq{}{#1}{\@musicnoteold{#2}}{ - \iflanguage{#1}{\@musicnoteold{#2}}{} + \IfStrEq{\mainlanguage}{#1}{ + \@musicnoteold{#2} + }{} } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/patacrep/latex/__init__.py b/patacrep/latex/__init__.py index d2a57fc8..34954a15 100644 --- a/patacrep/latex/__init__.py +++ b/patacrep/latex/__init__.py @@ -16,7 +16,7 @@ LOGGER = logging.getLogger(__name__) DEFAULT_LANGUAGE = "en_us" BABEL_LANGUAGES = OrderedDict(( - ('de_de', 'german'), + ('de_de', 'ngerman'), # german (old), germanb (like german) ('de_at', 'austrian'), ('eo_uy', 'esperanto'), ('en_us', 'english'), # USenglish, american @@ -53,8 +53,6 @@ BABEL_LANGUAGES = OrderedDict(( # ('??_??', 'finnish'), # ('??_??', 'acadian'), # ('??_??', 'galician'), - # ('??_??', 'germanb'), - # ('??_??', 'ngerman'), # ('??_??', 'naustrian'), # ('??_??', 'greek'), # ('??_??', 'polutonikogreek'), diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index 6f1ca655..8464131f 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -182,6 +182,7 @@ class Chordpro2LatexSong(ChordproSong): parent = super()._filters() parent.update({ 'lang2babel': self.lang2babel, + 'render_size': self._render_size, }) return parent @@ -203,6 +204,13 @@ class Chordpro2LatexSong(ChordproSong): self.errors.append(new_error) return error.babel + @staticmethod + def _render_size(size): + items = [] + for name, value, unit in size: + items.append(name + "=" + value + unit) + return ", ".join(items) + class Chordpro2ChordproSong(ChordproSong): """Render chordpro song to chordpro code""" @@ -219,10 +227,25 @@ class Chordpro2ChordproSong(ChordproSong): '\\': '\\\\', } + def _filters(self): + parent = super()._filters() + parent.update({ + 'render_size': self._render_size, + }) + return parent + def search_file(self, filename, extensions=None, *, datadirs=None): # pylint: disable=unused-variable return filename + @staticmethod + def _render_size(size): + items = [] + for name, value, unit in size: + items.append(name + "=" + value + unit) + return " ".join(items) + + SONG_RENDERERS = { "tsg": { 'csg': Chordpro2LatexSong, diff --git a/patacrep/songs/chordpro/ast.py b/patacrep/songs/chordpro/ast.py index dc5021da..2bbddaf1 100644 --- a/patacrep/songs/chordpro/ast.py +++ b/patacrep/songs/chordpro/ast.py @@ -408,6 +408,22 @@ class Define(Directive): def __str__(self): return None +class Image(Directive): + """An image + + .. attribute:: filename + The filename of the image. + .. attribute:: size + An iterable of tuples ``(type, float, unit)``. + """ + + def __init__(self, filename, size=None): + self.filename = filename + if size is None: + size = [] + self.size = size + super().__init__("image", None) + class Tab(AST): """Tablature""" diff --git a/patacrep/songs/chordpro/syntax.py b/patacrep/songs/chordpro/syntax.py index 9a7b9feb..a1e3f6e6 100644 --- a/patacrep/songs/chordpro/syntax.py +++ b/patacrep/songs/chordpro/syntax.py @@ -2,6 +2,7 @@ import logging import re +import shlex import ply.yacc as yacc @@ -124,10 +125,67 @@ class ChordproParser(Parser): fingers=fingers, ) + def _iter_raw_image_size_arguments(self, arguments, *, lineno): + for item in arguments: + prefix, _, suffix = item.partition("=") + if prefix in ['width', 'height']: + match = re.compile( + r"^(?P(\d*\.\d+|\d+))(?Pcm|em|pt)$", + re.VERBOSE, + ).match(suffix) + if match is not None: + yield (prefix, match.groupdict()['value'], match.groupdict()['unit']) + continue + elif prefix in ['scale']: + match = re.compile( + r"^(?P(\d*\.\d+|\d+))$", + re.VERBOSE, + ).match(suffix) + if match is not None: + yield (prefix, match.groupdict()['value'], "") + continue + else: + self.error( + line=lineno, + message="Image: Unknown argument name '{}'.".format(prefix), + ) + continue + self.error( + line=lineno, + message="Image: Unsupported {} value: '{}'.".format(prefix, suffix), + ) + + def _iter_image_size_arguments(self, argument, *, lineno): + arguments = set() + length_names = frozenset(["width", "height"]) + for name, value, unit in self._iter_raw_image_size_arguments(argument, lineno=lineno): + if name in arguments: + self.error( + line=lineno, + message="Image: Ignoring repeated argument: {}.".format(name), + ) + continue + if ( + name == "scale" and not length_names.isdisjoint(arguments) + ) or ( + name in length_names and "scale" in arguments + ): + self.error( + line=lineno, + message=( + "Image: Ignoring '{}' argument: Cannot mix scale and " + "width or height argument." + ).format(name), + ) + continue + arguments.add(name) + yield name, value, unit + def p_directive(self, symbols): """directive : LBRACE KEYWORD directive_next RBRACE | LBRACE SPACE KEYWORD directive_next RBRACE """ + # pylint: disable=too-many-branches if len(symbols) == 5: keyword = symbols[2] argument = symbols[3] @@ -171,7 +229,21 @@ class ChordproParser(Parser): symbols[0] = ast.Error() return self._directives.append(define) - + elif keyword == "image": + splitted = shlex.split(argument) + if len(splitted) < 1: + self.error( + line=symbols.lexer.lineno, + message="Missing filename for image directive", + ) + symbols[0] = ast.Error() + else: + symbols[0] = ast.Image( + splitted[0], + list( + self._iter_image_size_arguments(splitted[1:], lineno=symbols.lexer.lineno) + ), + ) else: directive = ast.Directive(keyword, argument) if directive.inline: diff --git a/test/test_book/datadir.tex.control b/test/test_book/datadir.tex.control index 687a6096..bdc8a210 100644 --- a/test/test_book/datadir.tex.control +++ b/test/test_book/datadir.tex.control @@ -111,7 +111,7 @@ Chordpro}[ \lilypond{scores/datadir.ly} -\image{img/datadir.png} +\image[]{img/datadir.png} \endsong @@ -138,7 +138,7 @@ Chordpro}[ \lilypond{scores/datadir2.ly} -\image{img/datadir2.png} +\image[]{img/datadir2.png} \endsong @@ -165,7 +165,7 @@ Chordpro}[ \lilypond{@TEST_FOLDER@/datadir_datadir/songs/./relative.ly} -\image{@TEST_FOLDER@/datadir_datadir/songs/./relative.png} +\image[]{@TEST_FOLDER@/datadir_datadir/songs/./relative.png} \endsong @@ -192,7 +192,7 @@ Chordpro}[ \lilypond{@TEST_FOLDER@/datadir_datadir/songs/./subdir/subdir.ly} -\image{@TEST_FOLDER@/datadir_datadir/songs/./subdir/subdir.png} +\image[]{@TEST_FOLDER@/datadir_datadir/songs/./subdir/subdir.png} \endsong diff --git a/test/test_book/lang_de.tex.control b/test/test_book/lang_de.tex.control new file mode 100644 index 00000000..5ed6126b --- /dev/null +++ b/test/test_book/lang_de.tex.control @@ -0,0 +1,131 @@ + + + + + + +%% 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@/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} + + +\usepackage[ngerman]{babel} +\lang{ngerman} + +\usepackage{graphicx} +\graphicspath{ % + {@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{Guitar songbook} +\author{The Patacrep Team} + +\newindex{titleidx}{lang_de_title} +\newauthorindex{authidx}{lang_de_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{} +\mail{crep@team-on-fire.com} +\web{http://www.patacrep.com} +\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} + + + + + +\end{document} diff --git a/test/test_book/lang_de.yaml b/test/test_book/lang_de.yaml new file mode 100644 index 00000000..12ba0364 --- /dev/null +++ b/test/test_book/lang_de.yaml @@ -0,0 +1,5 @@ +book: + lang: de + +content: + - sort: \ No newline at end of file diff --git a/test/test_book/syntax.tex.control b/test/test_book/syntax.tex.control index 1b6604f6..47684dd7 100644 --- a/test/test_book/syntax.tex.control +++ b/test/test_book/syntax.tex.control @@ -2,8 +2,6 @@ - - %% 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 @@ -34,7 +32,7 @@ guitar, \usepackage{lmodern} -\PassOptionsToPackage{german}{babel} +\PassOptionsToPackage{ngerman}{babel} \PassOptionsToPackage{english}{babel} \usepackage[english]{babel} \lang{english} @@ -92,10 +90,73 @@ guitar, \addcontentsline{toc}{section}{\songlistname} \begin{songs}{titleidx,authidx} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% songs/./images.csg + +\selectlanguage{english} + +\beginsong{}[ + by={ + }, +] + + +\image[]{img/image.png} +\image[]{img/image with spaces.png} + + + +\image[scale=2]{img/image.png} +\image[scale=.20]{img/image with spaces.png} +\image[scale=1.2]{img/image.png} + + + +\image[width=2cm]{img/image.png} +\image[height=2cm]{img/image with spaces.png} +\image[width=2cm, height=1cm]{img/image.png} + + + +\image[width=2em]{img/image.png} +\image[height=2em]{img/image with spaces.png} +\image[width=2em, height=1em]{img/image.png} + + + +\image[width=50pt]{img/image.png} +\image[height=50pt]{img/image with spaces.png} +\image[width=50pt, height=100pt]{img/image.png} + + + +\image[width=2.5cm]{img/image.png} +\image[height=2.5cm]{img/image with spaces.png} +\image[width=2.5cm, height=1.5cm]{img/image.png} + + + +\image[width=3cm, height=10pt]{img/image.png} +\image[width=10pt, height=3cm]{img/image with spaces.png} + + + +\image[]{img/image.png} +\image[]{img/image.png} +\image[]{img/image with spaces.png} +\image[]{img/image with spaces.png} +\image[]{img/image.png} +\image[width=2cm]{img/image.png} +\image[width=2cm]{img/image.png} +\image[width=2cm]{img/image.png} + + +\endsong + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% songs/./metacrep.csg -\selectlanguage{german} +\selectlanguage{ngerman} \beginsong{Der kleine Troll}[ by={ @@ -148,4 +209,4 @@ guitar, -\end{document} \ No newline at end of file +\end{document} diff --git a/test/test_book/syntax_datadir/img/image with spaces.png b/test/test_book/syntax_datadir/img/image with spaces.png new file mode 100644 index 00000000..f088bf46 Binary files /dev/null and b/test/test_book/syntax_datadir/img/image with spaces.png differ diff --git a/test/test_book/syntax_datadir/img/image.png b/test/test_book/syntax_datadir/img/image.png new file mode 100644 index 00000000..f088bf46 Binary files /dev/null and b/test/test_book/syntax_datadir/img/image.png differ diff --git a/test/test_book/syntax_datadir/songs/images.csg b/test/test_book/syntax_datadir/songs/images.csg new file mode 100644 index 00000000..49d843a2 --- /dev/null +++ b/test/test_book/syntax_datadir/songs/images.csg @@ -0,0 +1,35 @@ +{image: image.png} +{image: "image with spaces.png"} + +{image: image.png scale=2 } +{image: "image with spaces.png" scale=.20} +{image: image.png scale=1.2} + +{image: image.png width=2cm} +{image: "image with spaces.png" height=2cm} +{image: image.png width=2cm height=1cm} + +{image: image.png width=2em} +{image: "image with spaces.png" height=2em} +{image: image.png width=2em height=1em} + +{image: image.png width=50pt} +{image: "image with spaces.png" height=50pt} +{image: image.png width=50pt height=100pt} + +{image: image.png width=2.5cm} +{image: "image with spaces.png" height=2.5cm} +{image: image.png width=2.5cm height=1.5cm} + +{image: image.png width=3cm height=10pt} +{image: "image with spaces.png" width=10pt height=3cm} + +{image: image.png width= height=} +{image: image.png error=foo} +{image: "image with spaces.png" not_a_size} +{image: "image with spaces.png" too many arguments} +{image: image.png width=2ex height=3km} +{image: image.png width=2cm width=3cm} +{image: image.png width=2cm scale=3cm} +{image: image.png width=2cm scale=3} +{image: } diff --git a/test/test_song/image with spaces.png b/test/test_song/image with spaces.png new file mode 100644 index 00000000..e69de29b diff --git a/test/test_song/image.csg b/test/test_song/image.csg new file mode 100644 index 00000000..9f698456 --- /dev/null +++ b/test/test_song/image.csg @@ -0,0 +1,44 @@ +{lang: en} + +{image: "image.png" } +{image: "image with spaces.png" } + + +{image: "image.png" scale=2} +{image: "image with spaces.png" scale=.20} +{image: "image.png" scale=1.2} + + +{image: "image.png" width=2cm} +{image: "image with spaces.png" height=2cm} +{image: "image.png" width=2cm height=1cm} + + +{image: "image.png" width=2em} +{image: "image with spaces.png" height=2em} +{image: "image.png" width=2em height=1em} + + +{image: "image.png" width=50pt} +{image: "image with spaces.png" height=50pt} +{image: "image.png" width=50pt height=100pt} + + +{image: "image.png" width=2.5cm} +{image: "image with spaces.png" height=2.5cm} +{image: "image.png" width=2.5cm height=1.5cm} + + +{image: "image.png" width=3cm height=10pt} +{image: "image with spaces.png" width=10pt height=3cm} + + +{image: "image.png" } +{image: "image.png" } +{image: "image with spaces.png" } +{image: "image with spaces.png" } +{image: "image.png" } +{image: "image.png" width=2cm} +{image: "image.png" width=2cm} +{image: "image.png" width=2cm} + diff --git a/test/test_song/image.csg.source b/test/test_song/image.csg.source new file mode 100644 index 00000000..49d843a2 --- /dev/null +++ b/test/test_song/image.csg.source @@ -0,0 +1,35 @@ +{image: image.png} +{image: "image with spaces.png"} + +{image: image.png scale=2 } +{image: "image with spaces.png" scale=.20} +{image: image.png scale=1.2} + +{image: image.png width=2cm} +{image: "image with spaces.png" height=2cm} +{image: image.png width=2cm height=1cm} + +{image: image.png width=2em} +{image: "image with spaces.png" height=2em} +{image: image.png width=2em height=1em} + +{image: image.png width=50pt} +{image: "image with spaces.png" height=50pt} +{image: image.png width=50pt height=100pt} + +{image: image.png width=2.5cm} +{image: "image with spaces.png" height=2.5cm} +{image: image.png width=2.5cm height=1.5cm} + +{image: image.png width=3cm height=10pt} +{image: "image with spaces.png" width=10pt height=3cm} + +{image: image.png width= height=} +{image: image.png error=foo} +{image: "image with spaces.png" not_a_size} +{image: "image with spaces.png" too many arguments} +{image: image.png width=2ex height=3km} +{image: image.png width=2cm width=3cm} +{image: image.png width=2cm scale=3cm} +{image: image.png width=2cm scale=3} +{image: } diff --git a/test/test_song/image.png b/test/test_song/image.png new file mode 100644 index 00000000..e69de29b diff --git a/test/test_song/image.tsg b/test/test_song/image.tsg new file mode 100644 index 00000000..1ec6a98d --- /dev/null +++ b/test/test_song/image.tsg @@ -0,0 +1,59 @@ +\selectlanguage{english} + +\beginsong{}[ + by={ + }, +] + + +\image[]{img/image.png} +\image[]{img/image with spaces.png} + + + +\image[scale=2]{img/image.png} +\image[scale=.20]{img/image with spaces.png} +\image[scale=1.2]{img/image.png} + + + +\image[width=2cm]{img/image.png} +\image[height=2cm]{img/image with spaces.png} +\image[width=2cm, height=1cm]{img/image.png} + + + +\image[width=2em]{img/image.png} +\image[height=2em]{img/image with spaces.png} +\image[width=2em, height=1em]{img/image.png} + + + +\image[width=50pt]{img/image.png} +\image[height=50pt]{img/image with spaces.png} +\image[width=50pt, height=100pt]{img/image.png} + + + +\image[width=2.5cm]{img/image.png} +\image[height=2.5cm]{img/image with spaces.png} +\image[width=2.5cm, height=1.5cm]{img/image.png} + + + +\image[width=3cm, height=10pt]{img/image.png} +\image[width=10pt, height=3cm]{img/image with spaces.png} + + + +\image[]{img/image.png} +\image[]{img/image.png} +\image[]{img/image with spaces.png} +\image[]{img/image with spaces.png} +\image[]{img/image.png} +\image[width=2cm]{img/image.png} +\image[width=2cm]{img/image.png} +\image[width=2cm]{img/image.png} + + +\endsong \ No newline at end of file diff --git a/test/test_song/metacrep.tsg b/test/test_song/metacrep.tsg index c83308ac..33a223d7 100644 --- a/test/test_song/metacrep.tsg +++ b/test/test_song/metacrep.tsg @@ -1,4 +1,4 @@ -\selectlanguage{german} +\selectlanguage{ngerman} \beginsong{Der kleine Troll}[ by={ diff --git a/test/test_song/metadata.csg b/test/test_song/metadata.csg index 322a591b..825b8ece 100644 --- a/test/test_song/metadata.csg +++ b/test/test_song/metadata.csg @@ -16,7 +16,7 @@ {comment: Comment} {guitar_comment: GuitarComment} {partition: metadata_lilypond} -{image: metadata_image} +{image: "metadata_image" } Foo diff --git a/test/test_song/metadata.tsg b/test/test_song/metadata.tsg index 52582de4..09c768bf 100644 --- a/test/test_song/metadata.tsg +++ b/test/test_song/metadata.tsg @@ -20,7 +20,7 @@ Subtitle5}[ \textnote{Comment} \musicnote{GuitarComment} \lilypond{scores/metadata_lilypond} -\image{img/metadata_image} +\image[]{img/metadata_image}