I want to make a macro that takes a form and returns a string with some parts of the form evaluated. The form can have any number of elements (e.g. additional options for the title font, color, size,...). Say the macro is called "gset".
(gset title (format "\"x=%s\"" (+ 1 1))))
would expand to: "set title \"x=2\""
(let ((x 3)) (s (gset title (format "\"x=%s\"" x))))
would expand to "set title\"x=3\"". The form(s) that get expanded will not always be in the third position.
The place this has a role is in a DSL for gnuplot in elisp I am working on. Here is an example.
(let* ((x '(0 1 2 3)) (y (loop for xx in x collect (* xx xx)))) (gnuplot (gset terminal png) (gset output "test.png") (gset title "A Title") (gset xlabel "x") (gset ylabel "y") (plot x y with lines title "data")) (format "[[./test.png]]"))
The gset macro is the one I was describing above. the plot macro has the x and y arguments in the definition, so they expand fine (although nothing after them would). This block above as is works fine and generates the figure. But if I add something like
(gset title (format "A Title (%s) datapoints" (length x)))
This doesn't work because the format form doesn't expand. It won't always be the third position where something like this might happen.
It seems like this should work because when I look at it I can see what I want to happen, which is if it is a symbol use the symbol name, and if it is a list, evaluate it and use that value.
I came up with this macro:
(defmacro vset (&rest args) `(format "set %s" (mapconcat 'identity ',(mapcar (lambda (s) (format "%s" (if (listp s) (eval s) s))) args) " ")))
This works on this:
(setq y '(2 4 6 8)) (let ((x '(1 2 3 4))) (vset title (format "\"%s xpoints %s ypoints\"" (length x) (length y)))) set title "4 xpoints 4 ypoints"
I didn't think I would need to use eval, but I can't figure out another way to do it.