Today, instead of `syntax-rules`, you'll probably use `syntax-case`, which is a lot easier to use for harder purposes, and also easier error-checking, just not as interesting as `syntax-rules`. Or, if you're using Racket, `syntax-parse`.
Greg Hendershott's "Fear of Macros" should be an easy introduction to some of the newer ways, though it has some Racket-specific bits in it: https://www.greghendershott.com/fear-of-macros/
But some things just can't be accomplished with it. I only turn to `syntax-case` for these things, like introducing new identifiers, or fully procedural tasks. It blew my mind when I discovered that I could write a macro that actually reads files from disk and binds variables to each path at macro-expansion time (not saying that's a great idea though...)