From 29e0ac9f3a620bdf77453afad7cc447922d05964 Mon Sep 17 00:00:00 2001 From: Louis Date: Fri, 6 May 2016 22:44:02 +0200 Subject: [PATCH] [WIP][Image size] Refactoring --- .../songs/chordpro/latex/content_image | 2 +- patacrep/songs/chordpro/__init__.py | 30 ++++-- patacrep/songs/chordpro/ast.py | 5 +- patacrep/songs/chordpro/syntax.py | 96 +++++++++++++------ test/test_song/image.csg | 36 ++++--- test/test_song/image.csg.source | 15 +-- 6 files changed, 117 insertions(+), 67 deletions(-) diff --git a/patacrep/data/templates/songs/chordpro/latex/content_image b/patacrep/data/templates/songs/chordpro/latex/content_image index e2007ad2..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.filename|search_image|path2posix *) (* if image *) -\image{(( image ))} +\image[(( content.size|render_size ))]{(( image ))} (*- endif *) (*- endblock *) diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index 07ca17f8..97302de1 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -97,15 +97,7 @@ class ChordproSong(Song): @staticmethod def _render_size(size): - if size == (None, None): - return "" - text = "size=" - if size[0] != (None, None): - text += "".join(size[0]) - text += "x" - if size[1] != (None, None): - text += "".join(size[1]) - return text + raise NotImplementedError() def _escape_specials(self, content, chars=None, *, translation_map=None): if translation_map is None: @@ -216,6 +208,10 @@ class Chordpro2LatexSong(ChordproSong): self.errors.append(new_error) return error.babel + @staticmethod + def _render_size(size): + return "TODO" + class Chordpro2ChordproSong(ChordproSong): """Render chordpro song to chordpro code""" @@ -236,6 +232,22 @@ class Chordpro2ChordproSong(ChordproSong): # pylint: disable=unused-variable return filename + @staticmethod + def _render_size(size): + if size is None: + return "" + if size[0] == "size": + text = "size=" + if size[1] != (None, None): + text += "".join(size[1]) + text += "x" + if size[2] != (None, None): + text += "".join(size[2]) + return text + if size[0] == "scale": + return "scale=" + size[1] + + SONG_RENDERERS = { "tsg": { 'csg': Chordpro2LatexSong, diff --git a/patacrep/songs/chordpro/ast.py b/patacrep/songs/chordpro/ast.py index 61298b39..9e65a7d7 100644 --- a/patacrep/songs/chordpro/ast.py +++ b/patacrep/songs/chordpro/ast.py @@ -416,10 +416,7 @@ class Image(Directive): def __init__(self, filename, size=None): self.filename = filename - if size is None: - self.size = (None, None) - else: - self.size = size + self.size = size super().__init__("image", None) class Tab(AST): diff --git a/patacrep/songs/chordpro/syntax.py b/patacrep/songs/chordpro/syntax.py index 63322d52..074caacb 100644 --- a/patacrep/songs/chordpro/syntax.py +++ b/patacrep/songs/chordpro/syntax.py @@ -125,6 +125,57 @@ class ChordproParser(Parser): fingers=fingers, ) + def _parse_image_size(self, argument, *, lineno): + if argument is None: + return None + if argument.startswith("size="): + match = re.compile( + r""" + ^ + size= + ((?P\d*\.\d+|\d+)(?P%|cm|em|pt))? + x + ((?P\d*\.\d+|\d+)(?P%|cm|em|pt))? + $ + """, + re.VERBOSE + ).match(argument) + if match is None: + self.error( + line=lineno, + message="Cannot parse image size '{}'.".format(argument), + ) + return None + groupdict = match.groupdict() + return ( + 'size', + (groupdict['widthvalue'], groupdict['widthunit']), + (groupdict['heightvalue'], groupdict['heightunit']), + ) + elif argument.startswith("scale="): + match = re.compile( + r""" + ^ + scale= + (?P\d*\.\d+|\d+) + $ + """, + re.VERBOSE + ).match(argument) + if match is None: + self.error( + line=lineno, + message="Cannot parse image size '{}'.".format(argument), + ) + return None + return ('scale', match.groupdict()['scale']) + self.error( + line=lineno, + message="Cannot parse image size '{}'.".format(argument), + ) + return None + + def p_directive(self, symbols): """directive : LBRACE KEYWORD directive_next RBRACE | LBRACE SPACE KEYWORD directive_next RBRACE @@ -174,41 +225,24 @@ class ChordproParser(Parser): self._directives.append(define) elif keyword == "image": splitted = shlex.split(argument) - if len(splitted) == 1: - symbols[0] = ast.Image(splitted[0]) - elif len(splitted) == 2: - match = re.compile( - r""" - ^ - size= - ((?P\d*\.\d+|\d+)(?P%|cm|em|pt))? - x - ((?P\d*\.\d+|\d+)(?P%|cm|em|pt))? - $ - """, - re.VERBOSE - ).match(splitted[1]) - if match is None: - self.error( - line=symbols.lexer.lineno, - message="Cannot parse image size '{}'.".format(splitted[1]), - ) - symbols[0] = ast.Error() - else: - groupdict = match.groupdict() - symbols[0] = ast.Image( - splitted[0], - ( - (groupdict['widthvalue'], groupdict['widthunit']), - (groupdict['heightvalue'], groupdict['heightunit']), - ), - ) - else: + if len(splitted) < 1: self.error( line=symbols.lexer.lineno, - message="Too many arguments to 'image' directive.", + message="Missing filename for image directive", ) symbols[0] = ast.Error() + else: + if len(splitted) > 2: + self.error( + line=symbols.lexer.lineno, + message="Ignoring extra arguments for image directive: " + " ".join(['"{}"'.format(arg) for arg in splitted[2:]]), + ) + if len(splitted) == 1: + splitted.append(None) + symbols[0] = ast.Image( + splitted[0], + self._parse_image_size(splitted[1], lineno=symbols.lexer.lineno), + ) else: directive = ast.Directive(keyword, argument) if directive.inline: diff --git a/test/test_song/image.csg b/test/test_song/image.csg index 47db149a..83631bff 100644 --- a/test/test_song/image.csg +++ b/test/test_song/image.csg @@ -1,34 +1,40 @@ -{image: image.png } +{lang: en} + +{image: "image.png" } {image: "image with spaces.png" } -{image: image.png size=20%x} -{image: "image with spaces.png" size=x20%} -{image: image.png size=20%x10%} +{image: "image.png" scale=.2} +{image: "image with spaces.png" scale=.20} +{image: "image.png" scale=1.2} -{image: image.png size=2cmx} +{image: "image.png" size=2cmx} {image: "image with spaces.png" size=x2cm} -{image: image.png size=2cmx1cm} +{image: "image.png" size=2cmx1cm} -{image: image.png size=2emx} +{image: "image.png" size=2emx} {image: "image with spaces.png" size=x2em} -{image: image.png size=2emx1em} +{image: "image.png" size=2emx1em} -{image: image.png size=50ptx} +{image: "image.png" size=50ptx} {image: "image with spaces.png" size=x50pt} -{image: image.png size=50ptx100pt} +{image: "image.png" size=50ptx100pt} -{image: image.png size=2.5cmx} +{image: "image.png" size=2.5cmx} {image: "image with spaces.png" size=x2.5cm} -{image: image.png size=2.5cmx1.5cm} +{image: "image.png" size=2.5cmx1.5cm} + +{image: "image.png" size=3cmx10pt} +{image: "image with spaces.png" size=10ptx3cm} +{image: "image.png" size=x} -{image: image.png size=3cmx10%} -{image: "image with spaces.png" size=10%x3cm} -{image: image.png size=x} +{image: "image.png" } +{image: "image with spaces.png" } +{image: "image with spaces.png" } diff --git a/test/test_song/image.csg.source b/test/test_song/image.csg.source index 6cde5921..8cc3a351 100644 --- a/test/test_song/image.csg.source +++ b/test/test_song/image.csg.source @@ -1,9 +1,9 @@ {image: image.png} {image: "image with spaces.png"} -{image: image.png size=20%x } -{image: "image with spaces.png" size=x20%} -{image: image.png size=20%x10%} +{image: image.png scale=.2 } +{image: "image with spaces.png" scale=.20} +{image: image.png scale=1.2} {image: image.png size=2cmx} {image: "image with spaces.png" size=x2cm} @@ -21,11 +21,12 @@ {image: "image with spaces.png" size=x2.5cm} {image: image.png size=2.5cmx1.5cm} -{image: image.png size=3cmx10%} -{image: "image with spaces.png" size=10%x3cm} +{image: image.png size=3cmx10pt} +{image: "image with spaces.png" size=10ptx3cm} {image: image.png size=x} {image: image.png error=foo} -{image: "image with spaces.png" image.png} -{image: "image with spaces.png" image.png image.png} +{image: "image with spaces.png" not_a_size} +{image: "image with spaces.png" too many arguments} {image: image.png size=2exx3km} +{image: }