The core ideas behind macros: code as data, quoting, and evaluation.
Metaprogramming in Clojure starts with one idea: code is data. A Clojure form is just a data structure (often a list) that the evaluator reads and executes.
Quoting is the simplest way to feel the difference:
1'(+ 1 2) ;; a list (data), not evaluated
2(+ 1 2) ;; => 3
Once you can treat code as a value, macros become less mystical: they are just functions that take forms (data) and return new forms (data) that the compiler/evaluator will run.