From b00abcebf4b6d8cee76f026c3201dc5897d28fc0 Mon Sep 17 00:00:00 2001
From: Emin Martinian <emin.martinian@gmail.com>
Date: Sun, 11 May 2025 23:36:21 -0400
Subject: [PATCH] lisp/ox-latex.el: Convert SVG to PDF on latex export

* ox-latex.el (org-export-latex-link-svg, org-latex--inline-image): Convert SVG to PDF on latex export.
(org-latex--inline-image): Call new org-export-latex-link-svg to
convert SVG to PDF. The current SVG handling uses `\includesvg` which
seems brittle, does not work for me, and seems to require inkscape. If
we are going to require inkscape, it seems cleaner to convert SVG to
PDF and just `\includegraphics` instead of `\includesvg`.
---
 lisp/ox-latex.el | 61 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 53 insertions(+), 8 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 2867cc695..d7a8ca724 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2842,6 +2842,47 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 (defun org-latex-image-link-filter (data _backend info)
   (org-export-insert-image-links data info org-latex-inline-image-rules))
 
+;; Setup varaibles for export command and options,
+;; then we try to automatically set them if possible.
+
+(defvar org-latex-svg-to-pdf-command nil
+  "Executable to convert svg to pdf for latex export (e.g., inkscape).")
+(defvar org-latex-svg-to-pdf-command-options nil
+  "Options for org-latex-svg-to-pdf-command for latex export (e.g., -A).")
+
+(if (and (not org-latex-svg-to-pdf-command) (executable-find "inkscape"))
+    (progn (message "Using inkscape for svg to pdf on latex export")
+	   (setq org-latex-svg-to-pdf-command "inkscape")
+	   (setq org-latex-svg-to-pdf-command-options "-A")))
+
+(if (and (not org-latex-svg-to-pdf-command) (executable-find "rsvg-convert"))
+    (progn (message "Using rsvg-convert for svg to pdf on latex export")
+	   (setq org-latex-svg-to-pdf-command "rsvg-convert")
+	   (setq org-latex-svg-to-pdf-command-options "-f pdf -o ")))
+
+(if (not org-latex-svg-to-pdf-command)
+    (display-warning :warning
+		     "org-latex-svg-to-pdf-command not set for latex export"))
+
+;; The following will get called on latex export and will
+;; try converting svg files to pdf and include them in latex.
+(defun org-export-latex-link-svg (svg-file)
+  "Export SVG links by converting them to PDF.
+SVG-FILE is the path to the SVG file to convert."
+  (let* ((pdf-file (concat (file-name-sans-extension svg-file) ".pdf")))
+          ;; Convert SVG to PDF if needed
+    (when (and (file-exists-p svg-file)
+               (or (not (file-exists-p pdf-file))
+		   (file-newer-than-file-p svg-file pdf-file)))
+      (message "Converting %s to %s for LaTeX export" svg-file pdf-file)
+      (call-process org-latex-svg-to-pdf-command nil nil nil
+		    svg-file
+		    org-latex-svg-to-pdf-command-options
+		    pdf-file))
+    )
+  )
+
+
 (defun org-latex--inline-image (link info)
   "Return LaTeX code for an inline image.
 LINK is the link pointing to the inline image.  INFO is a plist
@@ -2966,14 +3007,18 @@ used as a communication channel."
                         (concat "\\detokenize{" path "}")
                       path)))
       (when (equal filetype "svg")
-	(setq image-code (replace-regexp-in-string "^\\\\includegraphics"
-						   "\\includesvg"
-						   image-code
-						   nil t))
-	(setq image-code (replace-regexp-in-string "\\.svg}"
-						   "}"
-						   image-code
-						   nil t))))
+	(org-export-latex-link-svg path)
+        (if (file-exists-p  ;; check if we converted the svg to pdf
+             (concat (file-name-sans-extension path) ".pdf"))
+	    (setq image-code (replace-regexp-in-string "\\.svg}"
+						       "}"
+						       image-code
+						       nil t))
+          ;; if we did not create a PDF of the SVG, then try to includesvg
+          (setq image-code (replace-regexp-in-string "^\\\\includegraphics"
+                                                     "\\includesvg"
+						     image-code
+						     nil t)))))
     ;; Return proper string, depending on FLOAT.
     (pcase float
       ((and (pred stringp) env-string)
-- 
2.25.1

