diff --git a/org-inline-pdf.el b/org-inline-pdf.el index 81a3f0e..ee8b7cf 100644 --- a/org-inline-pdf.el +++ b/org-inline-pdf.el @@ -61,7 +61,14 @@ (defvar org-babel-temporary-directory) -(defvar org-inline-pdf-make-preview-program "pdf2svg") +(defvar org-inline-pdf-make-preview-program + ;; "magick" + "pdf2svg" + ) +(defvar org-inline-pdf-preview-format + ;; "png" + "svg" + ) (defvar org-inline-pdf-cache-directory nil) @@ -69,8 +76,8 @@ "Return temp directory for caching preview images." (or org-inline-pdf-cache-directory (if (eval-when-compile (fboundp 'org-babel-temp-directory)) - (org-babel-temp-directory) - org-babel-temporary-directory))) + (org-babel-temp-directory) + org-babel-temporary-directory))) (defconst org-inline-pdf--org-html-image-extensions-for-file ;; This list is taken from the definition of the variable @@ -83,42 +90,88 @@ You can use `#+attr_org: :page NUM' to specify the page number." (let* ((case-fold-search t) - (datum (org-element-context)) - (par (org-element-lineage datum '(paragraph))) - (attr-re "^[ \t]*#\\+attr_.*?: +.*?:page +\\(\\S-+\\)") - (par-end (org-element-property :post-affiliated par)) - (attr-page-num - (if (and par - (org-with-point-at - (org-element-property :begin par) - (re-search-forward attr-re par-end t))) - (match-string-no-properties 1) - "1"))) + (datum (org-element-context)) + (par (org-element-lineage datum '(paragraph))) + (attr-re "^[ \t]*#\\+attr_.*?: +.*?:page +\\(\\S-+\\)") + (par-end (org-element-property :post-affiliated par)) + (attr-page-num + (if (and par + (org-with-point-at + (org-element-property :begin par) + (re-search-forward attr-re par-end t))) + (match-string-no-properties 1) + nil))) attr-page-num)) (defun org-inline-pdf--make-preview-for-pdf (original-org--create-inline-image &rest arguments) - "Make a SVG preview when the inline image is a PDF. + "Make a preview file when the inline image is a PDF. This function is to be used as an `around' advice to `org--create-inline-image'. The original function is passed in ORIGINAL-ORG--CREATE-INLINE-IMAGE and arguments in ARGUMENTS." (let ((file (car arguments)) - (page-num (org-inline-pdf--get-page-number))) + (page-num (org-inline-pdf--get-page-number))) (apply original-org--create-inline-image - (cons - (if (member (file-name-extension file) '("pdf" "PDF")) - (let ((svg (expand-file-name - (concat "org-inline-pdf-" - (md5 (format "%s:%s" file page-num))) - (org-inline-pdf-cache-directory)))) - (when (or (not (file-exists-p svg)) - (time-less-p (nth 5 (file-attributes svg)) - (nth 5 (file-attributes file)))) - (call-process org-inline-pdf-make-preview-program - nil nil nil file svg page-num)) - svg) - file) - (cdr arguments))))) - + (cons + (if (member (downcase (file-name-extension file)) '("pdf")) + (let (cmd + (output_file (expand-file-name + (concat "org-inline-pdf-" + (md5 (format "%s:%s" file page-num)) + (concat "." org-inline-pdf-preview-format)) + (org-inline-pdf-cache-directory)))) + (when (or (not (file-exists-p output_file)) + (time-less-p (nth 5 (file-attributes output_file)) + (nth 5 (file-attributes file)))) +;;; + (setq cmd + (cond + ((s-ends-with-p "pdf2svg" org-inline-pdf-make-preview-program) + (list org-inline-pdf-make-preview-program file output_file + (or page-num "1"))) + ((s-ends-with-p "magick" org-inline-pdf-make-preview-program) + (append + (list + org-inline-pdf-make-preview-program + "convert" + "-density" + "150" + "-trim") + (cond + ((not (null page-num)) + (list (concat file "[" page-num "]"))) + (t (list file))) + (list + ;; "-resize" + ;; "200%" + "-quality" + "100" + ;; "-flatten" + ;; "-sharpen" + ;; "0x1.0" + output_file))) + (t + (error "Unsupported `org-inline-pdf-make-preview-program': %s" org-inline-pdf-make-preview-program)))) + + (message "Executing command: %s" cmd) + (run-command-and-check-error cmd)) + output_file) + file) + (cdr arguments))))) + +(defun run-command-and-check-error (cmd) + (let* ((command (if (file-name-absolute-p (car cmd)) + (car cmd) + (executable-find (car cmd)))) + (output-buffer (generate-new-buffer "*cmd-output*")) + (exit-status (apply 'call-process command nil output-buffer nil (cdr cmd)))) + + (if (/= exit-status 0) + (progn + (with-current-buffer output-buffer + (message "Command failed with exit status %d:\n%s" + exit-status + (buffer-string))) + (kill-buffer output-buffer))))) ;;;###autoload (define-minor-mode org-inline-pdf-mode "Toggle inline previewing of PDF images in Org buffer." @@ -126,18 +179,18 @@ ORIGINAL-ORG--CREATE-INLINE-IMAGE and arguments in ARGUMENTS." (cond (org-inline-pdf-mode (if (called-interactively-p 'interactive) - (message "org-inline-pdf-mode enabled")) + (message "org-inline-pdf-mode enabled")) (add-to-list 'image-file-name-extensions "pdf") (advice-add 'org--create-inline-image :around #'org-inline-pdf--make-preview-for-pdf) (setf (alist-get "file" org-html-inline-image-rules nil t 'string=) - (regexp-opt (cons "pdf" org-inline-pdf--org-html-image-extensions-for-file)))) + (regexp-opt (cons "pdf" org-inline-pdf--org-html-image-extensions-for-file)))) (t (if (called-interactively-p 'interactive) - (message "org-inline-pdf-mode disabled")) + (message "org-inline-pdf-mode disabled")) (setq image-file-name-extensions (delete "pdf" image-file-name-extensions)) (advice-remove 'org--create-inline-image #'org-inline-pdf--make-preview-for-pdf) (setf (alist-get "file" org-html-inline-image-rules nil t 'string=) - (regexp-opt org-inline-pdf--org-html-image-extensions-for-file)) + (regexp-opt org-inline-pdf--org-html-image-extensions-for-file)) (org-remove-inline-images)))) (provide 'org-inline-pdf)