|
@@ -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.
|
|
|
|