summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJambunathan K <kjambunathan@gmail.com>2011-08-05 02:01:19 +0530
committerJambunathan K <kjambunathan@gmail.com>2011-08-05 02:04:30 +0530
commit44472fa6cf3082019342ef022f81c4b7980a2739 (patch)
tree87d3a3b35e9ef6a20064b55fce649ac74fc73a83
parent049c0776ff35ac006ef6be09bf931b0d8e67b426 (diff)
downloadorg-mode-44472fa6cf3082019342ef022f81c4b7980a2739.tar.gz
Usability improvements to org-lparse-convert and co (First cut)
* contrib/lisp/org-lparse.el (org-lparse-and-open) (org-lparse-register-backend, org-lparse-format-table) (org-lparse-begin, org-lparse-end): Checkdoc related fixes. (org-lparse-get-converter): Added (org-lparse-get-other-backends, org-lparse-all-backends): Re-implemented. Also improved docstring. (org-lparse): Make use of improvements in the converter routines. Improve the following: a) gathering of target-backend and native-backend args during interactive calls b) error handling. (org-lparse-convert): Introduced prefix arg for opening of converted files. Make use of improvements in the converter routines. Improve error handling. (org-lparse-convert-processes): New customizable variable. (org-lparse-convert-process): Make it customizable. Set default value to nil. (org-lparse-convert-capabilities): New customizable variable. (org-lparse-use-flashy-warning): Fix group and improve docstring. * contrib/lisp/org-odt.el (org-odt-get): Don't set CONVERT-METHOD and OTHER-BACKENDS options. Fallback to the global converter settings for now. (org-export-odt-preferred-output-format): New variable (org-export-as-odt-and-open, org-export-as-odt): Use the afore-mentioned variable. * contrib/lisp/org-xhtml.el (org-xhtml-get): Don't set CONVERT-METHOD and OTHER-BACKENDS options. Fallback to the global converter settings for now.
-rwxr-xr-xcontrib/lisp/org-lparse.el260
-rw-r--r--contrib/lisp/org-odt.el37
-rw-r--r--contrib/lisp/org-xhtml.el15
3 files changed, 236 insertions, 76 deletions
diff --git a/contrib/lisp/org-lparse.el b/contrib/lisp/org-lparse.el
index 71a7a2b..b8a3708 100755
--- a/contrib/lisp/org-lparse.el
+++ b/contrib/lisp/org-lparse.el
@@ -57,7 +57,7 @@
;;;###autoload
(defun org-lparse-and-open (target-backend native-backend arg)
- "Export the outline to TARGET-BACKEND via NATIVE-BACKEND and open exported file.
+ "Export outline to TARGET-BACKEND via NATIVE-BACKEND and open exported file.
If there is an active region, export only the region. The prefix
ARG specifies how many levels of the outline should become
headlines. The default is 3. Lower levels will become bulleted
@@ -357,7 +357,7 @@ For the sake of illustration, the html backend implements
ENTITY-CONTROL and ENTITY-FORMAT settings.")
(defun org-lparse-register-backend (backend)
- "Make BACKEND known to org-lparse library.
+ "Make BACKEND known to `org-lparse' library.
Add BACKEND to `org-lparse-native-backends'."
(when backend
(setq backend (cond
@@ -374,17 +374,41 @@ Add BACKEND to `org-lparse-native-backends'."
org-lparse-native-backends))
(message "Unregistered backend %S" backend))
-(defun org-lparse-get-other-backends (native-backend)
- (org-lparse-backend-get native-backend 'OTHER-BACKENDS))
+(defun org-lparse-get-other-backends (in-fmt)
+ "Return OUTPUT-FMT-ALIST corresponding to IN-FMT.
+See `org-lparse-convert-capabilities' for definition of
+OUTPUT-FMT-ALIST."
+ (when (org-lparse-get-converter in-fmt)
+ (or (ignore-errors (org-lparse-backend-get in-fmt 'OTHER-BACKENDS) )
+ (catch 'out-fmts
+ (dolist (c org-lparse-convert-capabilities)
+ (when (member in-fmt (nth 1 c))
+ (throw 'out-fmts (nth 2 c))))))))
+
+(defun org-lparse-get-converter (in-fmt)
+ "Return converter associated with IN-FMT.
+See `org-lparse-convert-capabilities' for further information."
+ (or (ignore-errors (org-lparse-backend-get in-fmt 'CONVERT-METHOD))
+ org-lparse-convert-process))
(defun org-lparse-all-backends ()
+ "Return all formats to which `org-lparse' could export to.
+The return value is an alist of the form (TARGET-BACKEND
+NATIVE-BACKEND-1 NATIVE-BACKEND-2 ...) with the condition that
+the org file can be exported to TARGET-BACKEND via any one of
+NATIVE-BACKEND-1, NATIVE-BACKEND-2 etc.
+
+For example, an entry of the form \"(\"pdf\" \"odt\" \"xhtml\")\"
+would mean that the org file could be exported to \"pdf\" format
+by exporting natively either to \"xhtml\" or \"odt\" backends."
(let (all-backends)
(flet ((add (other native)
(let ((val (assoc-string other all-backends t)))
(if val (setcdr val (nconc (list native) (cdr val)))
(push (cons other (list native)) all-backends)))))
(loop for backend in org-lparse-native-backends
- do (loop for other in (org-lparse-get-other-backends backend)
+ do (loop for other in
+ (mapcar #'car (org-lparse-get-other-backends backend))
do (add other backend))))
all-backends))
@@ -428,97 +452,203 @@ PUB-DIR specifies the publishing directory."
(let* ((input (if (featurep 'ido) 'ido-completing-read 'completing-read))
(all-backends (org-lparse-all-backends))
(target-backend
- (funcall input "Export to: " all-backends nil t nil))
+ (and all-backends
+ (funcall input "Export to: " all-backends nil t nil)))
(native-backend
- (or
- ;; (and (org-lparse-backend-is-native-p target-backend)
- ;; target-backend)
- (funcall input "Use Native backend: "
- (cdr (assoc target-backend all-backends)) nil t nil))))
+ (let ((choices (if target-backend
+ (cdr (assoc target-backend all-backends))
+ (or org-lparse-native-backends
+ (error "No registered backends")))))
+ (funcall input "Use Native backend: " choices nil t nil))))
(list target-backend native-backend current-prefix-arg)))
(let* ((org-lparse-backend (intern native-backend))
- (org-lparse-other-backend (intern target-backend)))
+ (org-lparse-other-backend (and target-backend
+ (intern target-backend))))
(unless (org-lparse-backend-is-native-p native-backend)
(error "Don't know how to export natively to backend %s" native-backend))
(unless (or (not target-backend)
(equal target-backend native-backend)
- (member target-backend (org-lparse-get 'OTHER-BACKENDS)))
+ (assoc target-backend (org-lparse-get-other-backends
+ native-backend)))
(error "Don't know how to export to backend %s %s" target-backend
(format "via %s" native-backend)))
(run-hooks 'org-export-first-hook)
(org-do-lparse arg hidden ext-plist to-buffer body-only pub-dir)))
-(defcustom org-lparse-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.
+(defcustom org-lparse-convert-processes
+ '(("BasicODConverter"
+ ("soffice" "-norestore" "-invisible" "-headless"
+ "\"macro:///BasicODConverter.Main.Convert(%I,%f,%O)\""))
+ ("unoconv"
+ ("unoconv" "-f" "%f" "-o" "%d" "%i")))
+ "Specify a list of document converters and their usage.
+The converters in this list are offered as choices while
+customizing `org-lparse-convert-process'.
+
+This variable is an alist where each element is of the
+form (CONVERTER-NAME (CONVERTER-PROGRAM ARG1 ARG2 ...)).
+CONVERTER-NAME is name of the converter. CONVERTER-PROGRAM is
+the name of the executable. ARG1, ARG2 etc are command line
+options that are passed to CONVERTER-PROGRAM. Format specifiers
+can be used in the ARGs and they are interpreted 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-lparse)
+%D output dir as a URL."
+ :group 'org-lparse
+ :type
+ '(choice
+ (const :tag "None" nil)
+ (alist :tag "Converters"
+ :key-type (string :tag "Converter Name")
+ :value-type (group (cons (string :tag "Executable")
+ (repeat (string :tag "Command line args")))))))
+(defcustom org-lparse-convert-process nil
+ "Command to convert from an Org exported format to other formats.
+During customization, the list of choices are populated from
+`org-lparse-convert-processes'. Refer afore-mentioned variable
+for further information."
+ :group 'org-lparse
+ :type '(choice :convert-widget
+ (lambda (w)
+ (apply 'widget-convert (widget-type w)
+ (eval (car (widget-get w :args)))))
+ `((const :tag "None" nil)
+ ,@(mapcar (lambda (c)
+ `(const :tag ,(car c) ,(cadr c)))
+ org-lparse-convert-processes))))
+
+(defcustom org-lparse-convert-capabilities
+ '(("Text"
+ ("odt" "ott" "doc" "rtf")
+ (("pdf" "pdf") ("odt" "odt") ("xhtml" "html") ("rtf" "rtf")
+ ("ott" "ott") ("doc" "doc") ("ooxml" "xml") ("html" "html")))
+ ("Web"
+ ("html" "xhtml") (("pdf" "pdf") ("odt" "txt") ("html" "html")))
+ ("Spreadsheet"
+ ("ods" "ots" "xls" "csv")
+ (("pdf" "pdf") ("ots" "ots") ("html" "html") ("csv" "csv")
+ ("ods" "ods") ("xls" "xls") ("xhtml" "xhtml") ("ooxml" "xml")))
+ ("Presentation"
+ ("odp" "otp" "ppt")
+ (("pdf" "pdf") ("swf" "swf") ("odp" "odp") ("xhtml" "xml")
+ ("otp" "otp") ("ppt" "ppt") ("odg" "odg") ("html" "html"))))
+ "Specify input and output formats of `org-lparse-convert-process'.
+More correctly, specify the set of input and output formats that
+the user is actually interested in.
+
+This variable is an alist where each element is of the
+form (DOCUMENT-CLASS INPUT-FMT-LIST OUTPUT-FMT-ALIST).
+INPUT-FMT-LIST is a list of INPUT-FMTs. OUTPUT-FMT-ALIST is an
+alist where each element is of the form (OUTPUT-FMT
+OUTPUT-FILE-EXTENSION).
+
+The variable is interpreted as follows:
+`org-lparse-convert-process' can take any document that is in
+INPUT-FMT-LIST and produce any document that is in the
+OUTPUT-FMT-LIST. A document converted to OUTPUT-FMT will have
+OUTPUT-FILE-EXTENSION as the file name extension. OUTPUT-FMT
+serves dual purposes:
+- It is used for populating completion candidates during
+ `org-lparse' and `org-lparse-convert' commands.
+
+- It is used as the value of \"%f\" specifier in
+ `org-lparse-convert-process'.
+
+DOCUMENT-CLASS is used to group a set of file formats in
+INPUT-FMT-LIST in to a single class.
+
+Note that this variable inherently captures how LibreOffice based
+converters work. LibreOffice maps documents of various formats
+to classes like Text, Web, Spreadsheet, Presentation etc and
+allow document of a given class (irrespective of it's source
+format) to be converted to any of the export formats associated
+with that class.
+
+See default setting of this variable for an typical
+configuration."
+ :group 'org-lparse
+ :type
+ '(choice
+ (const :tag "None" nil)
+ (alist :key-type (string :tag "Document Class")
+ :value-type
+ (group (repeat :tag "Input formats" (string :tag "Input format"))
+ (alist :tag "Output formats"
+ :key-type (string :tag "Output format")
+ :value-type
+ (group (string :tag "Output file extension")))))))
(defcustom org-lparse-use-flashy-warning nil
- "Use flashy warnings when exporting to ODT."
+ "Control flashing of messages logged with `org-lparse-warn'.
+When non-nil, messages are fontified with warning face and the
+exporter lingers for a while to catch user's attention."
:type 'boolean
- :group 'org-export)
+ :group 'org-lparse)
-(defun org-lparse-convert (&optional in-file fmt)
- "Convert file from one format to another using a converter.
+(defun org-lparse-convert (&optional in-file out-fmt prefix-arg)
+ "Convert IN-FILE to format OUT-FMT using a command line 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."
+to variable `buffer-file-name'. OUT-FMT is the desired output
+format. If the backend has registered a CONVERT-METHOD as part
+of it's get function then that converter is used. Otherwise
+`org-lparse-convert-process' is used. If PREFIX-ARG is non-nil
+then the newly converted file is opened using `org-open-file'."
(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)))
+ (in-fmt (file-name-extension in-file))
+ (out-fmt-choices (org-lparse-get-other-backends in-fmt))
+ (out-fmt
+ (or (and out-fmt-choices
+ (funcall input "Output format: "
+ out-fmt-choices nil nil nil))
+ (error
+ "No known converter or no known output formats for %s files"
+ in-fmt))))
+ (list in-file out-fmt current-prefix-arg)))
(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))
+ (dummy (or (file-readable-p in-file)
+ (error "Cannot read %s" in-file)))
+ (in-fmt (file-name-extension in-file))
+ (out-fmt (or out-fmt (error "Output format unspecified")))
+ (convert-process (org-lparse-get-converter in-fmt))
+ (program (car convert-process))
+ (dummy (and (or program (error "Converter not configured"))
+ (or (executable-find program)
+ (error "Cannot find converter %s" program))))
+ (out-fmt-alist
+ (or (assoc out-fmt (org-lparse-get-other-backends in-fmt))
+ (error "Cannot convert from %s to %s format" in-fmt out-fmt)))
+ (out-file (concat (file-name-sans-extension in-file) "."
+ (nth 1 out-fmt-alist)))
(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-lparse-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))
+ (arglist (mapcar (lambda (arg)
+ (format-spec
+ arg `((?i . ,in-file)
+ (?I . ,(browse-url-file-url in-file))
+ (?f . ,out-fmt)
+ (?o . ,out-file)
+ (?O . ,(browse-url-file-url out-file))
+ (?d . ,out-dir)
+ (?D . ,(browse-url-file-url out-dir)))))
+ (cdr convert-process))))
+ (when (file-exists-p out-file)
+ (delete-file out-file))
(message "Executing %s %s" program (mapconcat 'identity arglist " "))
(apply 'call-process program nil nil nil arglist)
-
(cond
((file-exists-p out-file)
(message "Exported to %s using %s" out-file program)
+ (when prefix-arg
+ (message "Opening %s..." out-file)
+ (org-open-file out-file))
out-file
;; (set-buffer (find-file-noselect out-file))
)
@@ -1134,7 +1264,8 @@ version."
(or (when (and (boundp 'org-lparse-other-backend)
org-lparse-other-backend
(not (equal org-lparse-backend org-lparse-other-backend)))
- (let ((org-lparse-convert-process (org-lparse-get 'CONVERT-METHOD)))
+ (let ((org-lparse-convert-process
+ (org-lparse-get-converter org-lparse-backend)))
(when org-lparse-convert-process
(org-lparse-convert buffer-file-name
(symbol-name org-lparse-other-backend)))))
@@ -1145,8 +1276,7 @@ version."
(t (current-buffer))))))
(defun org-lparse-format-table (lines olines)
- "Retuns backend-specific code for org-type and table-type
-tables."
+ "Retuns backend-specific code for org-type and table-type tables."
(if (stringp lines)
(setq lines (org-split-string lines "\n")))
(if (string-match "^[ \t]*|" (car lines))
@@ -1623,7 +1753,7 @@ t : Log all invocations of `org-lparse-begin', `org-lparse-end'
(const :tag "Format and Control callbacks" t)))
(defun org-lparse-begin (entity &rest args)
- "Begin ENTITY in current buffer. ARGS is entity specific.
+ "Begin ENTITY in current buffer. ARGS is entity specific.
ENTITY can be one of PARAGRAPH, LIST, LIST-ITEM etc.
Use (org-lparse-begin 'LIST \"o\") to begin a list in current
@@ -1640,7 +1770,7 @@ information."
(apply f args)))
(defun org-lparse-end (entity &rest args)
- "Close ENTITY in current buffer. ARGS is entity specific.
+ "Close ENTITY in current buffer. ARGS is entity specific.
ENTITY can be one of PARAGRAPH, LIST, LIST-ITEM
etc.
diff --git a/contrib/lisp/org-odt.el b/contrib/lisp/org-odt.el
index efa777b..60e6491 100644
--- a/contrib/lisp/org-odt.el
+++ b/contrib/lisp/org-odt.el
@@ -266,6 +266,30 @@ be linked only."
(error "Cannot determine style name for entity %s of type %s"
entity category))))
+(defcustom org-export-odt-preferred-output-format nil
+ "Automatically post-process to this format after exporting to \"odt\".
+Interactive commands `org-export-as-odt' and
+`org-export-as-odt-and-open' export first to \"odt\" format and
+then use an external converter to convert the resulting document
+to this format.
+
+The converter used is that specified with CONVERT-METHOD option
+in `org-odt-get'. If the above option is unspecified then
+`org-lparse-convert-process' is used.
+
+The format specified here should be listed in OTHER-BACKENDS
+option of `org-odt-get' or `org-lparse-convert-capabilities' as
+appropriate."
+ :group 'org-odt
+ :type '(choice :convert-widget
+ (lambda (w)
+ (apply 'widget-convert (widget-type w)
+ (eval (car (widget-get w :args)))))
+ `((const :tag "None" nil)
+ ,@(mapcar (lambda (c)
+ `(const :tag ,(car c) ,(car c)))
+ (org-lparse-get-other-backends "odt")))))
+
;;;###autoload
(defun org-export-as-odt-and-open (arg)
"Export the outline as ODT and immediately open it with a browser.
@@ -273,7 +297,8 @@ If there is an active region, export only the region.
The prefix ARG specifies how many levels of the outline should become
headlines. The default is 3. Lower levels will become bulleted lists."
(interactive "P")
- (org-lparse-and-open "odt" "odt" arg))
+ (org-lparse-and-open
+ (or org-export-odt-preferred-output-format "odt") "odt" arg))
;;;###autoload
(defun org-export-as-odt-batch ()
@@ -338,7 +363,8 @@ the file header and footer, simply return the content of
<body>...</body>, without even the body tags themselves. When
PUB-DIR is set, use this as the publishing directory."
(interactive "P")
- (org-lparse "odt" "odt" arg hidden ext-plist to-buffer body-only pub-dir))
+ (org-lparse (or org-export-odt-preferred-output-format "odt")
+ "odt" arg hidden ext-plist to-buffer body-only pub-dir))
(defvar org-odt-entity-control-callbacks-alist
`((EXPORT
@@ -1436,11 +1462,8 @@ MAY-INLINE-P allows inlining it as an image."
(INIT-METHOD 'org-odt-init-outfile)
(FINAL-METHOD 'org-odt-finalize-outfile)
(SAVE-METHOD 'org-odt-save-as-outfile)
- (OTHER-BACKENDS
- '("bib" "doc" "doc6" "doc95" "html" "xhtml" "latex" "odt" "ott" "pdf" "rtf"
- "sdw" "sdw3" "sdw4" "stw " "sxw" "mediawiki" "text" "txt" "uot" "vor"
- "vor3" "vor4" "docbook" "ooxml" "ppt" "odp"))
- (CONVERT-METHOD org-lparse-convert-process)
+ ;; (OTHER-BACKENDS) ; see note in `org-xhtml-get'
+ ;; (CONVERT-METHOD) ; see note in `org-xhtml-get'
(TOPLEVEL-HLEVEL 1)
(SPECIAL-STRING-REGEXPS org-export-odt-special-string-regexps)
(INLINE-IMAGES 'maybe)
diff --git a/contrib/lisp/org-xhtml.el b/contrib/lisp/org-xhtml.el
index e491c78..bb34338 100644
--- a/contrib/lisp/org-xhtml.el
+++ b/contrib/lisp/org-xhtml.el
@@ -1659,10 +1659,17 @@ lang=\"%s\" xml:lang=\"%s\">
(INIT-METHOD nil)
(SAVE-METHOD nil)
(CLEANUP-METHOD nil)
- (OTHER-BACKENDS
- '("xhtml" "etext" "html" "html10" "mediawiki" "pdf" "sdw" "sdw3" "sdw4"
- "text" "text10" "odt" "vor" "vor4"))
- (CONVERT-METHOD org-lparse-convert-process)
+ ;; (OTHER-BACKENDS
+ ;; ;; There is a provision to register a per-backend converter and
+ ;; ;; output formats. Refer `org-lparse-get-converter' and
+ ;; ;; `org-lparse-get-other-backends'.
+
+ ;; ;; The default behaviour is to use `org-lparse-convert-process'
+ ;; ;; and `org-lparse-convert-capabilities'.
+ ;; )
+ ;; (CONVERT-METHOD
+ ;; ;; See note above
+ ;; )
(EXPORT-DIR (org-export-directory :html opt-plist))
(FILE-NAME-EXTENSION (plist-get opt-plist :html-extension))
(EXPORT-BUFFER-NAME "*Org HTML Export*")