# Issue with macro and buffer-name

I want to write a macro that makes a diffpdf before and after some changes in my LaTeX file (that would be compiled twice by pdflatex).

I tried:

(defmacro with-diffpdf-after-changes (&rest body)
"DOCSTRING"
(declare (indent 1))
(let* ((FILE_NAME (file-name-sans-extension (buffer-name)))
(PDF_FILE (concat FILE_NAME ".pdf")))

(progn
(save-buffer)
(call-process-shell-command
(concat "pdflatex \"\\let\\oldExecuteOptions\\ExecuteOptions\"\\\n"
"\"\\def\\ExecuteOptions#1{\\oldExecuteOptions{#1,draft}}\"\\\n"
"\"\\nonstopmode\\input{" (buffer-name) "}\";"
"mv "  ,PDF_FILE " /tmp/"  )
nil nil)

,@body

(save-buffer)
(call-process-shell-command
(concat "pdflatex \"\\let\\oldExecuteOptions\\ExecuteOptions\"\\\n"
"\"\\def\\ExecuteOptions#1{\\oldExecuteOptions{#1,draft}}\"\\\n"
"\"\\nonstopmode\\input{" (buffer-name) "}\";"
"diffpdf -a " ,PDF_FILE " /tmp/" ,PDF_FILE )
nil nil)

)
))


But something's wrong with my code. PDF_FILE is named by the file that calls the macro while I need it to be named by the buffer of my LaTeX file.

E.g. my LaTeX file is paper.tex, the macro is called by a function in the file replacements.el

I get that the macro makes diffpdf look for ./replacements.pdf and /tmp/replacements.pdf

I need diffpdf paper.pdf /tmp/paper.pdf.

• Macros are expanded at compile time, not (generally) at run-time. Any code which you need to be evaluated at run-time must be part of the code generated (returned) by the macro. Your let bindings are happening outside of that. Feb 9, 2021 at 12:21
• Further to what Phil wrote, see (info "(elisp) Problems with Macros"). Feb 9, 2021 at 12:29
• @Basil I had already red the page you suggested... but I'm getting lost in the expansion. I'm not really sure of what i'm doing. Feb 9, 2021 at 12:37
• Finally it works! Thanks! Feb 9, 2021 at 12:46

My let-bindings was outside the quoted part.

The working code is:

(defmacro with-diffpdf-after-changes (&rest body)
"DOCSTRING"
(declare (indent 1))

(progn
(let* ((FILE_NAME (file-name-sans-extension (buffer-name)))
(PDF_FILE (concat FILE_NAME ".pdf")))
(save-buffer)
(call-process-shell-command
(concat "pdflatex \"\\let\\oldExecuteOptions\\ExecuteOptions\"\\\n"
"\"\\def\\ExecuteOptions#1{\\oldExecuteOptions{#1,draft}}\"\\\n"
"\"\\nonstopmode\\input{" (buffer-name) "}\";"
"mv "  PDF_FILE " /tmp/"  )
nil nil)

,@body

(save-buffer)
(call-process-shell-command
(concat "pdflatex \"\\let\\oldExecuteOptions\\ExecuteOptions\"\\\n"
"\"\\def\\ExecuteOptions#1{\\oldExecuteOptions{#1,draft}}\"\\\n"
"\"\\nonstopmode\\input{" (buffer-name) "}\";"
"diffpdf -a " PDF_FILE " /tmp/" PDF_FILE )
nil nil)

)
))


Thanks to phils and Basil for their usefull comments.

• Please consider describing what your correction amounts to, to help readers understand and not just have to diff the code and attempt to work it out on their own. Thx.
– Drew
Feb 9, 2021 at 21:05
• @Drew, I have an idea of what I've done, but it's not easy to me to tecnically explain it. I just put the let-binding part into the backquoted one (right?). Feb 10, 2021 at 9:41