[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Make doc-view's pdf->png conversion customizable
From: |
Jambunathan K |
Subject: |
Re: Make doc-view's pdf->png conversion customizable |
Date: |
Sun, 26 Jun 2011 02:39:25 +0530 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (windows-nt) |
Hello Elias
(Sorry for the top post)
This more like a braindump and the intention here is not to comment on
your code but to share my thought process.
I had more or less similar requirement wrt viewing of OpenDocument/MS
files [1]. The patch has been pending for a while.
After some thought, I found out that it would be most convenient to
implement this in terms of a unified format-spec.
Search for the defcustom and format-spec in the attached code snippet
[2] (to get my drift).
A quick look at the patch suggests that you can define a format-spec for
each of the following params:
1. resolution
2. pdf
3. png
4. page
and define the converter function as a string with "%" specifiers.
Do you see any issues with this approach?
I also think it might be a good to have some alist like the one below
((PNG->PDF . PNG->PDF-SPECIFIC-FORMAT-SPEC)
(DOC->PDF . DOC->PDF-SPECIFIC-FORMAT-SPEC))
in the doc-view so that users can plug in their own converters in an
easy way.
[1] http://lists.gnu.org/archive/html/emacs-devel/2011-05/msg00239.html
[2] Code snippet from my local area
--8<---------------cut here---------------start------------->8---
(defcustom org-export-convert-process
'("soffice" "-norestore" "-invisible" "-headless"
"\"macro:///BasicODConverter.Main.Convert(%I,%f,%O)\"")
"Command to covert a Org exported format to other formats.
The variable is an list of the form (PROCESS ARG1 ARG2 ARG3
...). Format specifiers used in the ARGs are replaced as below.
%i input file name in full
%I input file name as a URL
%f format of the output file
%o output file name in full
%O output file name as a URL
%d output dir in full
%D output dir as a URL"
:group 'org-export)
(defun org-export-convert (&optional in-file fmt)
"Convert file from one format to another using a converter.
IN-FILE is the file to be converted. If unspecified, it defaults
to variable `buffer-file-name'. FMT is the desired output format. If the
backend has registered a CONVERT-METHOD via it's get function
then that converter is used. Otherwise
`org-export-conver-process' is used."
(interactive
(let* ((input (if (featurep 'ido) 'ido-completing-read 'completing-read))
(in-file (read-file-name "File to be converted: "
nil buffer-file-name t))
(fmt (funcall input "Output format: "
(or (ignore-errors
(org-lparse-get-other-backends
(file-name-extension in-file)))
(org-lparse-all-backends))
nil nil nil)))
(list in-file fmt)))
(require 'browse-url)
(let* ((in-file (expand-file-name (or in-file buffer-file-name)))
(fmt (or fmt "doc") )
(out-file (concat (file-name-sans-extension in-file) "." fmt))
(out-dir (file-name-directory in-file))
(backend (when (boundp 'org-lparse-backend) org-lparse-backend))
(convert-process
(or (ignore-errors (org-lparse-backend-get backend 'CONVERT-METHOD))
org-export-convert-process))
program arglist)
(setq program (and convert-process (consp convert-process)
(car convert-process)))
(unless (executable-find program)
(error "Unable to locate the converter %s" program))
(setq arglist
(mapcar (lambda (arg)
(format-spec arg `((?i . ,in-file)
(?I . ,(browse-url-file-url in-file))
(?f . ,fmt)
(?o . ,out-file)
(?O . ,(browse-url-file-url out-file))
(?d . ,out-dir)
(?D . ,(browse-url-file-url out-dir)))))
(cdr convert-process)))
(ignore-errors (delete-file out-file))
(message "Executing %s %s" program (mapconcat 'identity arglist " "))
(apply 'call-process program nil nil nil arglist)
;; blah blah
))
--8<---------------cut here---------------end--------------->8---
Elias Pipping <address@hidden> writes:
> On Sat, Jun 25, 2011 at 4:35 PM, Elias Pipping
> <address@hidden> wrote:
>> Hello,
>>
>> mupdf[1] provides the program "pdfdraw" that can convert pdf files to
>> png images. I've attached a patch to doc-view.el (against the emacs-23
>> branch, can be applied to 23.3 without any changes as well) that (most
>> prominently) adds a new (customizable) variable
>> doc-view-pdf->png-converter-invocation, which can be set to one of the
>> pre-defined functions
>>
>> doc-view-pdf->png-converter-invocation-ghostscript
>> doc-view-pdf->png-converter-invocation-mupdf
>>
>> or a user-specified function. doc-view-pdf/ps->png and
>> doc-view-pdf/ps->png-1 were made to use them.
>>
>>
>> Best regards,
>>
>> Elias Pipping
>>
>> [1] http://mupdf.com/
>
> I attached an old version of the patch by mistake.
>
> I've attached the new and correct version to this email.
>
> From 870bacaa0e0db0f93d47c333349560fbae64f2fb Mon Sep 17 00:00:00 2001
> From: Elias Pipping <address@hidden>
> Date: Sat, 25 Jun 2011 13:50:11 +0200
> Subject: [PATCH] Make doc-view-pdf->png-1 customizable
>
> ---
> lisp/doc-view.el | 71 ++++++++++++++++++++++++++++++++++++++++-------------
> 1 files changed, 53 insertions(+), 18 deletions(-)
>
> diff --git a/lisp/doc-view.el b/lisp/doc-view.el
> index af6e4f3..8a921a7 100644
> --- a/lisp/doc-view.el
> +++ b/lisp/doc-view.el
> @@ -153,6 +153,26 @@
> :type 'file
> :group 'doc-view)
>
> +(defcustom doc-view-pdfdraw-program (executable-find "pdfdraw")
> + "Program to convert PDF files to PNG."
> + :type 'file
> + :group 'doc-view)
> +
> +(defcustom doc-view-pdf->png-converter-invocation
> + 'doc-view-pdf->png-converter-invocation-ghostscript
> + "Called to convert a PDF file into a PNG file"
> + :type '(radio (function-item
> doc-view-pdf->png-converter-invocation-ghostscript :doc "Use ghostscript")
> + (function-item doc-view-pdf->png-converter-invocation-mupdf
> :doc "Use mupdf")
> + function)
> + :group 'doc-view)
> +
> +(defcustom doc-view-ps->png-converter-invocation
> + 'doc-view-ps->png-converter-invocation-ghostscript
> + "Called to convert a PS file into a PNG file"
> + :type '(radio (function-item
> doc-view-ps->png-converter-invocation-ghostscript :doc "Use ghostscript")
> + function)
> + :group 'doc-view)
> +
> (defcustom doc-view-ghostscript-options
> '("-dSAFER" ;; Avoid security problems when rendering files from untrusted
> ;; sources.
> @@ -692,15 +712,35 @@ Should be invoked when the cached images aren't
> up-to-date."
> (list "-o" pdf dvi)
> callback)))
>
> +(defun doc-view-pdf->png-converter-invocation-ghostscript (resolution pdf
> png &optional page)
> + `((command . ,doc-view-ghostscript-program)
> + (arguments . (,@doc-view-ghostscript-options
> + ,(format "-r%d" resolution)
> + ,@(if page `(,(format "-dFirstPage=%d" page)))
> + ,@(if page `(,(format "-dLastPage=%d" page)))
> + ,(concat "-sOutputFile=" png)
> + ,pdf))))
> +
> +(defalias 'doc-view-ps->png-converter-invocation-ghostscript
> + 'doc-view-pdf->png-converter-invocation-ghostscript)
> +
> +(defun doc-view-pdf->png-converter-invocation-mupdf (resolution pdf png
> &optional page)
> + `((command . ,doc-view-pdfdraw-program)
> + (arguments . (,(concat "-o" png)
> + ,(format "-r%d" resolution)
> + ,pdf
> + ,@(if page `(,(format "%d" page)))))))
>
> (defun doc-view-pdf/ps->png (pdf-ps png)
> "Convert PDF-PS to PNG asynchronously."
> - (doc-view-start-process
> - "pdf/ps->png" doc-view-ghostscript-program
> - (append doc-view-ghostscript-options
> - (list (format "-r%d" (round doc-view-resolution))
> - (concat "-sOutputFile=" png)
> - pdf-ps))
> + (let ((invocation (case doc-view-doc-type
> + (pdf (funcall doc-view-pdf->png-converter-invocation
> + (round doc-view-resolution) pdf-ps png))
> + (t (funcall doc-view-ps->png-converter-invocation
> + (round doc-view-resolution) pdf-ps
> png)))))
> + (doc-view-start-process
> + "pdf/ps->png" (cdr (assoc 'command invocation))
> + (cdr (assoc 'arguments invocation))
> (lexical-let ((resolution doc-view-resolution))
> (lambda ()
> ;; Only create the resolution file when it's all done, so it also
> @@ -712,7 +752,7 @@ Should be invoked when the cached images aren't
> up-to-date."
> (when doc-view-current-timer
> (cancel-timer doc-view-current-timer)
> (setq doc-view-current-timer nil))
> - (doc-view-display (current-buffer) 'force))))
> + (doc-view-display (current-buffer) 'force)))))
> ;; Update the displayed pages as soon as they're done generating.
> (when doc-view-conversion-refresh-interval
> (setq doc-view-current-timer
> @@ -723,17 +763,12 @@ Should be invoked when the cached images aren't
> up-to-date."
> (defun doc-view-pdf->png-1 (pdf png page callback)
> "Convert a PAGE of a PDF file to PNG asynchronously.
> Call CALLBACK with no arguments when done."
> - (doc-view-start-process
> - "pdf->png-1" doc-view-ghostscript-program
> - (append doc-view-ghostscript-options
> - (list (format "-r%d" (round doc-view-resolution))
> - ;; Sadly, `gs' only supports the page-range
> - ;; for PDF files.
> - (format "-dFirstPage=%d" page)
> - (format "-dLastPage=%d" page)
> - (concat "-sOutputFile=" png)
> - pdf))
> - callback))
> + (let ((invocation (funcall doc-view-pdf->png-converter-invocation
> + (round doc-view-resolution) pdf png page)))
> + (doc-view-start-process
> + "pdf/ps->png" (cdr (assoc 'command invocation))
> + (cdr (assoc 'arguments invocation))
> + callback)))
>
> (declare-function clear-image-cache "image.c" (&optional filter))
--