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 at 12:21
  • 1
    Further to what Phil wrote, see (info "(elisp) Problems with Macros"). – Basil Feb 9 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. – Gabriele Nicolardi Feb 9 at 12:37
  • Finally it works! Thanks! – Gabriele Nicolardi Feb 9 at 12:46
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 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?). – Gabriele Nicolardi Feb 10 at 9:41
  • Whatever you think best describes the fix/answer, please add that to the answer. – Drew Feb 10 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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