From 6dff8528f5546b7831a982da5a9ef125afe2f2a4 Mon Sep 17 00:00:00 2001 From: Martin Bodin Date: Mon, 4 Dec 2023 17:12:00 +0100 Subject: [PATCH] This should fix #326. --- syntax/attribute_value.ml | 31 +++++++++++++++++++++++++------ syntax/reflect/reflect.ml | 2 +- test/test_jsx.re | 5 +++++ test/test_ppx.ml | 4 ++++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/syntax/attribute_value.ml b/syntax/attribute_value.ml index 4630d6e11..a38710c72 100644 --- a/syntax/attribute_value.ml +++ b/syntax/attribute_value.ml @@ -74,11 +74,11 @@ let list |> Common.list loc |> fun e -> Some e -let spaces = list (Re_str.regexp " +") "space" -let commas = list (Re_str.regexp " *, *") "comma" -let semicolons = list (Re_str.regexp " *; *") "semicolon" +let spaces = list (Re_str.regexp "[ \t\r\f]+") "space" +let commas = list (Re_str.regexp "[ \t\r\f]*,[ \t\r\f]*") "comma" +let semicolons = list (Re_str.regexp "[ \t\r\f]*;[ \t\r\f]*") "semicolon" -let spaces_or_commas_regexp = Re_str.regexp "\\( *, *\\)\\| +" +let spaces_or_commas_regexp = Re_str.regexp "\\([ \t\r\f]*,[ \t\r\f]*\\)\\|[ \t\r\f]+" let spaces_or_commas_ = exp_list spaces_or_commas_regexp "space- or comma" let spaces_or_commas = list spaces_or_commas_regexp "space- or comma" @@ -347,8 +347,8 @@ let offset = else Some [%expr `Number [%e n]] end [@metaloc loc] -let transform = - let regexp = Re_str.regexp "\\([^(]+\\)(\\([^)]*\\))" in +let transform_item = + let regexp = Re_str.regexp "\\([a-zA-Z]+\\)[ \t\r\f]*(\\([^)]*\\))" in fun ?separated_by:_ ?default:_ loc name s -> if not @@ does_match regexp s then @@ -408,6 +408,25 @@ let transform = Some e +let rec transform = + let regexp_wsp = Re_str.regexp "[ \t\r\f]*" in + let regexp = Re_str.regexp "[ \t\r\f]*\\([a-zA-Z]+[ \t\r\f]*([^)]*)\\)\\(.*\\)" in + + fun ?separated_by:_ ?default:_ loc name s -> + if does_match regexp_wsp s then + Some [%expr []] + else if does_match regexp_wsp s then + begin + let item = Re_str.matched_group 1 s in + let rest = Re_str.matched_group 2 s in + Option.bind (transform_item ~separated_by ~default loc name item) (fun item -> + Option.bind (transform ~separated_by ~default loc name rest) (fun l -> + Some (item :: l))) + end + else + Common.error loc "Value of %s is not a list of SVG transform" name + [@metaloc loc] + (* String-like. *) diff --git a/syntax/reflect/reflect.ml b/syntax/reflect/reflect.ml index dafd1975b..d8abebf60 100644 --- a/syntax/reflect/reflect.ml +++ b/syntax/reflect/reflect.ml @@ -200,7 +200,7 @@ let rec to_attribute_parser lang name ~loc = function [%expr spaces_or_commas svg_length] | [[%type: transforms]] -> - [%expr spaces_or_commas transform] + [%expr transform] | [[%type: paint]] -> [%expr paint] diff --git a/test/test_jsx.re b/test/test_jsx.re index 18a5d4a7c..3f811a9b8 100644 --- a/test/test_jsx.re +++ b/test/test_jsx.re @@ -341,6 +341,11 @@ let svg = ( [], [path(~a=[a_fill_rule(`Evenodd)], [])], ), + ( + "transform with random spacing", + [], + [g(~a:[a_transform([`Translate((200., Some(200.))), `Rotate((1., None)), `Matrix((-0., 1, 0.1, 0., 1e-5, 1e5)), `Scale((1., Some 0.)), `SkewY(-0.)])], [])], + ), ], ), ); diff --git a/test/test_ppx.ml b/test/test_ppx.ml index b521aada4..0d45c154c 100644 --- a/test/test_ppx.ml +++ b/test/test_ppx.ml @@ -424,6 +424,10 @@ let svg = "svg", SvgTests.make Svg.[ [[%svg ""]], [path ~a:[a_fill_rule `Evenodd] []] ; + "transform with random spacing", + [[%svg ""]], + [g ~a:[a_transform [`Translate (200., Some 200.); `Rotate (1., None); `Matrix (-0., 1, 0.1, 0., 1e-5, 1e5); `Scale (1., Some 0.); `SkewY (-0.)]] []] ; + ] let svg_element_names = "svg element names", SvgTests.make Svg.[