diff --git a/syntax/attribute_value.ml b/syntax/attribute_value.ml
index 4630d6e11..4abef0d83 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\n]+") "space"
+let commas = list (Re_str.regexp "[ \t\r\n]*,[ \t\r\n]*") "comma"
+let semicolons = list (Re_str.regexp "[ \t\r\n]*;[ \t\r\n]*") "semicolon"
-let spaces_or_commas_regexp = Re_str.regexp "\\( *, *\\)\\| +"
+let spaces_or_commas_regexp = Re_str.regexp "\\([ \t\r\n]*,[ \t\r\n]*\\)\\|[ \t\r\n]+"
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\n]*(\\([^)]*\\))" 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\n]*" in
+ let regexp = Re_str.regexp "[ \t\r\n]*\\([a-zA-Z]+[ \t\r\n]*([^)]*)\\)\\(.*\\)" in
+
+ fun ?separated_by:_ ?default:_ loc name s ->
+ if does_match regexp_wsp s then
+ Some [%expr []]
+ else if does_match regexp 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 loc name item) (fun item ->
+ Option.bind (transform loc name rest) (fun l ->
+ Some [%expr [%e item] :: [%e 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..1827b7e5b 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.))), `Matrix((-0., 1., 0.1, 0., 1e-5, 1e5)), `Scale((-1., Some(0.)))])], [])],
+ ),
],
),
);
diff --git a/test/test_ppx.ml b/test/test_ppx.ml
index b521aada4..4fa3d06c0 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.); `Matrix (-0., 1., 0.1, 0., 1e-5, 1e5); `Scale (-1., Some 0.)]] []] ;
+
]
let svg_element_names = "svg element names", SvgTests.make Svg.[