From: Elias Pipping <pipping.elias@googlemail.com>
To: Elias Pipping <pipping.elias@googlemail.com>, emacs-devel@gnu.org
Subject: Re: Make doc-view's pdf->png conversion customizable
Date: Sun, 26 Jun 2011 12:47:13 +0200 [thread overview]
Message-ID: <BANLkTi==bC83RwYyL_T0qOWvUNaU=4wsCg@mail.gmail.com> (raw)
In-Reply-To: <81sjqxd3ei.fsf@gmail.com>
On Sat, Jun 25, 2011 at 11:09 PM, Jambunathan K <kjambunathan@gmail.com> wrote:
>
> 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.
I find this very convincing.
Best regards,
Elias Pipping
> [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 <pipping.elias@googlemail.com> writes:
>
>> On Sat, Jun 25, 2011 at 4:35 PM, Elias Pipping
>> <pipping.elias@googlemail.com> 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 <pipping@exherbo.org>
>> 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))
>
> --
>
prev parent reply other threads:[~2011-06-26 10:47 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-25 14:35 Make doc-view's pdf->png conversion customizable Elias Pipping
2011-06-25 14:41 ` Elias Pipping
2011-06-25 21:09 ` Jambunathan K
2011-06-26 10:47 ` Elias Pipping [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='BANLkTi==bC83RwYyL_T0qOWvUNaU=4wsCg@mail.gmail.com' \
--to=pipping.elias@googlemail.com \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).