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.[