Racket improves on Scheme: its macros are fully hygienic whilst not being limited to template -> pattern transforms. See https://docs.racket-lang.org/guide/macro-transformers.html
EDIT: syntax-case -> syntax-rules; R6RS specifies the latter—I believe the former is a Racket construct equivalent in power to `syntax-rules`.
It does not have the same power as `defmacro`: you cannot define general procedural macros with `syntax-rules`, as you are limited to the pattern-matching language to compute over and construct syntax objects.
[1]: https://docs.racket-lang.org/reference/stx-patterns.html#%28...
R6 having `syntax-case` macros is one of the more controversial things about it; a surprising number of implementers don't care for them.
(macroexpand '(when-let (foo (frob bar))
(jib foo)))
;; (let ((foo (frob bar)))
;; (when foo
;; (jib foo)))