From f4e124333e9d197be09a574d324f904a73f79a9d Mon Sep 17 00:00:00 2001 From: Louis Date: Mon, 9 May 2016 22:12:41 +0200 Subject: [PATCH] Change syntax of image directive arguments: `{image: foo.png width=3cm height=2cm}` --- patacrep/songs/chordpro/__init__.py | 33 ++---- patacrep/songs/chordpro/ast.py | 4 +- patacrep/songs/chordpro/syntax.py | 100 ++++++++---------- test/test_book/syntax.tex.control | 7 +- .../test_book/syntax_datadir/songs/images.csg | 37 ++++--- test/test_song/image.csg | 35 +++--- test/test_song/image.csg.source | 37 ++++--- test/test_song/image.tsg | 7 +- 8 files changed, 125 insertions(+), 135 deletions(-) diff --git a/patacrep/songs/chordpro/__init__.py b/patacrep/songs/chordpro/__init__.py index cbb09792..8464131f 100644 --- a/patacrep/songs/chordpro/__init__.py +++ b/patacrep/songs/chordpro/__init__.py @@ -206,18 +206,10 @@ class Chordpro2LatexSong(ChordproSong): @staticmethod def _render_size(size): - if size is None: - return "" - if size[0] == "size": - sizelist = [] - width, height = size[1:3] - if all(width): - sizelist.append("width=" + "".join(width)) - if all(height): - sizelist.append("height=" + "".join(height)) - return ", ".join(sizelist) - if size[0] == "scale": - return "scale=" + size[1] + items = [] + for name, value, unit in size: + items.append(name + "=" + value + unit) + return ", ".join(items) class Chordpro2ChordproSong(ChordproSong): """Render chordpro song to chordpro code""" @@ -248,19 +240,10 @@ class Chordpro2ChordproSong(ChordproSong): @staticmethod def _render_size(size): - if size is None: - return "" - if size[0] == "size": - text = "size=" - width, height = size[1:3] - if all(width): - text += "".join(width) - text += "x" - if all(height): - text += "".join(height) - return text - if size[0] == "scale": - return "scale=" + size[1] + items = [] + for name, value, unit in size: + items.append(name + "=" + value + unit) + return " ".join(items) SONG_RENDERERS = { diff --git a/patacrep/songs/chordpro/ast.py b/patacrep/songs/chordpro/ast.py index 9e65a7d7..6f764e34 100644 --- a/patacrep/songs/chordpro/ast.py +++ b/patacrep/songs/chordpro/ast.py @@ -411,11 +411,13 @@ class Image(Directive): .. attribute:: filename The filename of the image. .. attribute:: size - A tuple of ``(width, height)`` of the image. Both can be ``None``. + 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) diff --git a/patacrep/songs/chordpro/syntax.py b/patacrep/songs/chordpro/syntax.py index e6d9ca5e..e300d227 100644 --- a/patacrep/songs/chordpro/syntax.py +++ b/patacrep/songs/chordpro/syntax.py @@ -125,56 +125,54 @@ 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: + 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 + self.error( + line=lineno, + message="Image: Ignoring unparsable argument '{}'.".format(item), + ) + + def _iter_image_size_arguments(self, argument, *, lineno): + arguments = set() + for name, value, unit in self._iter_raw_image_size_arguments(argument, lineno=lineno): + if name in arguments: self.error( line=lineno, - message="Cannot parse image size '{}'.".format(argument), + message="Image: Ignoring extra {} argument.".format(name), ) - 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: + continue + if ( + name == "scale" and ("width" in arguments or "height" in arguments) + ) or ( + name in ["width", "height"] and "scale" in arguments + ): self.error( line=lineno, - message="Cannot parse image size '{}'.".format(argument), + message=( + "Image: Ignoring '{}' argument: Cannot mix scale and " + "width or height argument." + ).format(name), ) - return None - return ('scale', match.groupdict()['scale']) - self.error( - line=lineno, - message="Cannot parse image size '{}'.".format(argument), - ) - return None - + continue + arguments.add(name) + yield name, value, unit def p_directive(self, symbols): """directive : LBRACE KEYWORD directive_next RBRACE @@ -233,19 +231,11 @@ class ChordproParser(Parser): ) 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), + list( + self._iter_image_size_arguments(splitted[1:], lineno=symbols.lexer.lineno) + ), ) else: directive = ast.Directive(keyword, argument) diff --git a/test/test_book/syntax.tex.control b/test/test_book/syntax.tex.control index 543a30b5..719dfc2f 100644 --- a/test/test_book/syntax.tex.control +++ b/test/test_book/syntax.tex.control @@ -105,7 +105,7 @@ guitar, -\image[scale=.2]{img/image.png} +\image[scale=2]{img/image.png} \image[scale=.20]{img/image with spaces.png} \image[scale=1.2]{img/image.png} @@ -137,14 +137,17 @@ guitar, \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.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 diff --git a/test/test_book/syntax_datadir/songs/images.csg b/test/test_book/syntax_datadir/songs/images.csg index 8cc3a351..49d843a2 100644 --- a/test/test_book/syntax_datadir/songs/images.csg +++ b/test/test_book/syntax_datadir/songs/images.csg @@ -1,32 +1,35 @@ {image: image.png} {image: "image with spaces.png"} -{image: image.png scale=.2 } +{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} -{image: image.png size=2cmx1cm} +{image: image.png width=2cm} +{image: "image with spaces.png" height=2cm} +{image: image.png width=2cm height=1cm} -{image: image.png size=2emx} -{image: "image with spaces.png" size=x2em} -{image: image.png size=2emx1em} +{image: image.png width=2em} +{image: "image with spaces.png" height=2em} +{image: image.png width=2em height=1em} -{image: image.png size=50ptx} -{image: "image with spaces.png" size=x50pt} -{image: image.png size=50ptx100pt} +{image: image.png width=50pt} +{image: "image with spaces.png" height=50pt} +{image: image.png width=50pt height=100pt} -{image: image.png size=2.5cmx} -{image: "image with spaces.png" size=x2.5cm} -{image: image.png size=2.5cmx1.5cm} +{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 size=3cmx10pt} -{image: "image with spaces.png" size=10ptx3cm} -{image: image.png size=x} +{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 size=2exx3km} +{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.csg b/test/test_song/image.csg index 6e4cb846..9f698456 100644 --- a/test/test_song/image.csg +++ b/test/test_song/image.csg @@ -4,38 +4,41 @@ {image: "image with spaces.png" } -{image: "image.png" scale=.2} +{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} -{image: "image.png" size=2cmx1cm} +{image: "image.png" width=2cm} +{image: "image with spaces.png" height=2cm} +{image: "image.png" width=2cm height=1cm} -{image: "image.png" size=2emx} -{image: "image with spaces.png" size=x2em} -{image: "image.png" size=2emx1em} +{image: "image.png" width=2em} +{image: "image with spaces.png" height=2em} +{image: "image.png" width=2em height=1em} -{image: "image.png" size=50ptx} -{image: "image with spaces.png" size=x50pt} -{image: "image.png" size=50ptx100pt} +{image: "image.png" width=50pt} +{image: "image with spaces.png" height=50pt} +{image: "image.png" width=50pt height=100pt} -{image: "image.png" size=2.5cmx} -{image: "image with spaces.png" size=x2.5cm} -{image: "image.png" size=2.5cmx1.5cm} +{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" size=3cmx10pt} -{image: "image with spaces.png" size=10ptx3cm} -{image: "image.png" size=x} +{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 index 8cc3a351..49d843a2 100644 --- a/test/test_song/image.csg.source +++ b/test/test_song/image.csg.source @@ -1,32 +1,35 @@ {image: image.png} {image: "image with spaces.png"} -{image: image.png scale=.2 } +{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} -{image: image.png size=2cmx1cm} +{image: image.png width=2cm} +{image: "image with spaces.png" height=2cm} +{image: image.png width=2cm height=1cm} -{image: image.png size=2emx} -{image: "image with spaces.png" size=x2em} -{image: image.png size=2emx1em} +{image: image.png width=2em} +{image: "image with spaces.png" height=2em} +{image: image.png width=2em height=1em} -{image: image.png size=50ptx} -{image: "image with spaces.png" size=x50pt} -{image: image.png size=50ptx100pt} +{image: image.png width=50pt} +{image: "image with spaces.png" height=50pt} +{image: image.png width=50pt height=100pt} -{image: image.png size=2.5cmx} -{image: "image with spaces.png" size=x2.5cm} -{image: image.png size=2.5cmx1.5cm} +{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 size=3cmx10pt} -{image: "image with spaces.png" size=10ptx3cm} -{image: image.png size=x} +{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 size=2exx3km} +{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.tsg b/test/test_song/image.tsg index d735095b..1ec6a98d 100644 --- a/test/test_song/image.tsg +++ b/test/test_song/image.tsg @@ -11,7 +11,7 @@ -\image[scale=.2]{img/image.png} +\image[scale=2]{img/image.png} \image[scale=.20]{img/image with spaces.png} \image[scale=1.2]{img/image.png} @@ -43,14 +43,17 @@ \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.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