From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Jambunathan K Newsgroups: gmane.emacs.devel Subject: Re: Make doc-view's pdf->png conversion customizable Date: Sun, 26 Jun 2011 02:39:25 +0530 Message-ID: <81sjqxd3ei.fsf@gmail.com> References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: dough.gmane.org 1309036339 30571 80.91.229.12 (25 Jun 2011 21:12:19 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 25 Jun 2011 21:12:19 +0000 (UTC) Cc: emacs-devel@gnu.org To: Elias Pipping Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Jun 25 23:12:15 2011 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Qaa9G-0004y8-Gn for ged-emacs-devel@m.gmane.org; Sat, 25 Jun 2011 23:12:14 +0200 Original-Received: from localhost ([::1]:55871 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qaa9F-0008HH-N5 for ged-emacs-devel@m.gmane.org; Sat, 25 Jun 2011 17:12:13 -0400 Original-Received: from eggs.gnu.org ([140.186.70.92]:40255) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qaa6p-0007x2-KR for emacs-devel@gnu.org; Sat, 25 Jun 2011 17:09:45 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Qaa6m-00025h-RX for emacs-devel@gnu.org; Sat, 25 Jun 2011 17:09:43 -0400 Original-Received: from mail-pz0-f41.google.com ([209.85.210.41]:35479) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qaa6m-00025U-95 for emacs-devel@gnu.org; Sat, 25 Jun 2011 17:09:40 -0400 Original-Received: by pzk4 with SMTP id 4so2876850pzk.0 for ; Sat, 25 Jun 2011 14:09:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:references:mail-followup-to :date:in-reply-to:message-id:user-agent:mime-version:content-type :content-transfer-encoding; bh=CFTSrMbKc3Rnnj0Iih8RDf+0WoT5MB2CDvpUARvsWzI=; b=L32GqkvSIlLoi0N8YJuFNTBs2pAzPkrpV7phZxIdT4i828QsuP3ugu5yRahGu/6n/9 WCSuaD/EaFHQiVouA+TG9ASj2Qtmah5MmJK89jj49E1eWQSiNUQWB0nlGazaJHWFeohP fVv6kGoxmaVG2MUbfUliW0XxM1jc1O61kRfc8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:references:mail-followup-to:date:in-reply-to :message-id:user-agent:mime-version:content-type :content-transfer-encoding; b=Ejx051pXTplYlhyXjPPTiT2XqsrbiRB0dOfMj8tY9VrMU/JH9ZC2Pd/VW40uHZ/4Cq /8SjtXh8z+SNWBo2kvbkQB3WJo1ZvY1bH9nzZgWxG32VgF0DoooXTTiTe00lOBbOY8wA 6eTXtjk6T42L1p0bQJqkb4uXTxcsO7TOZbcvo= Original-Received: by 10.68.35.74 with SMTP id f10mr2259101pbj.180.1309036179484; Sat, 25 Jun 2011 14:09:39 -0700 (PDT) Original-Received: from JAMBU-NETBOOK ([122.174.27.186]) by mx.google.com with ESMTPS id v6sm3083397pbh.6.2011.06.25.14.09.36 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 25 Jun 2011 14:09:38 -0700 (PDT) Mail-Followup-To: Elias Pipping , emacs-devel@gnu.org In-Reply-To: (Elias Pipping's message of "Sat, 25 Jun 2011 16:41:07 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (windows-nt) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.210.41 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:140971 Archived-At: 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=20 2. pdf=20 3. png=20 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=20 ((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:///BasicODConv= erter.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 writes: > On Sat, Jun 25, 2011 at 4:35 PM, Elias Pipping > 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 >> >> =A0doc-view-pdf->png-converter-invocation-ghostscript >> =A0doc-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 > 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) >=20=20 > +(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-gh= ostscript :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-gho= stscript :doc "Use ghostscript") > + function) > + :group 'doc-view) > + > (defcustom doc-view-ghostscript-options > '("-dSAFER" ;; Avoid security problems when rendering files from untru= sted > ;; sources. > @@ -692,15 +712,35 @@ Should be invoked when the cached images aren't up-= to-date." > (list "-o" pdf dvi) > callback))) >=20=20 > +(defun doc-view-pdf->png-converter-invocation-ghostscript (resolution pd= f png &optional page) > + `((command . ,doc-view-ghostscript-program) > + (arguments . (,@doc-view-ghostscript-options > + ,(format "-r%d" resolution) > + ,@(if page `(,(format "-dFirstPage=3D%d" page))) > + ,@(if page `(,(format "-dLastPage=3D%d" page))) > + ,(concat "-sOutputFile=3D" 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))))))) >=20=20 > (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=3D" 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=3D%d" page) > - (format "-dLastPage=3D%d" page) > - (concat "-sOutputFile=3D" 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))) >=20=20 > (declare-function clear-image-cache "image.c" (&optional filter)) --=20