0

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.

4
  • 2
    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.
    – phils
    Feb 9, 2021 at 12:21
  • 1
    Further to what Phil wrote, see (info "(elisp) Problems with Macros").
    – Basil
    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

1 Answer 1

1

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.

3
  • 1
    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
  • Whatever you think best describes the fix/answer, please add that to the answer.
    – Drew
    Feb 10, 2021 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.