From 57aa366e9d5596741c256688c9b8ef07a9b24e17 Mon Sep 17 00:00:00 2001 Message-Id: <57aa366e9d5596741c256688c9b8ef07a9b24e17.1668044888.git.yantar92@posteo.net> From: Ihor Radchenko Date: Thu, 10 Nov 2022 09:39:20 +0800 Subject: [PATCH] org-export: Allow export file name to be determined after export processing * lisp/ox.el (org-export-as): When :output-file info property is set to a list, calculate :output-file after expanding macros, removing uninterpreted data, and other processing. Use the list value is used as argument list for `org-export-output-file-name'. Add new optional argument WITH-INFO to return the info channel in addition to the export string. (org-export-to-file): Allow FILE argument to be an argument list to be passed to `org-export-output-file-name' in the processed export buffer. This patch allows calculating the output file name after expanding all the macros, cleaning up commented trees, and other export processing. In particular, #+EXPORT_FILE_NAME keywords inside commented trees can be ignored in contrast to what `org-export-output-file-name' returns on the original Org file. This patch is not changing any existing behavior and not fixing the reported byg. The callers of `org-export-to-file' still need to change FILE argument to make use of the changes herein. Reported-by: Alain.Cochard@unistra.fr Link: https://orgmode.org/list/25422.27044.980916.495348@gargle.gargle.HOWL --- lisp/ox.el | 59 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/lisp/ox.el b/lisp/ox.el index 770f86740..82cf0d166 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -2994,7 +2994,8 @@ (defun org-export--remove-uninterpreted-data (data info) ;;;###autoload (defun org-export-as - (backend &optional subtreep visible-only body-only ext-plist) + (backend + &optional subtreep visible-only body-only ext-plist with-info) "Transcode current Org buffer into BACKEND code. BACKEND is either an export back-end, as returned by, e.g., @@ -3020,7 +3021,10 @@ (defun org-export-as with external parameters overriding Org default settings, but still inferior to file-local settings. -Return code as a string." +Return code as a string. + +When optional argument WITH-INFO is non-nil, return a cons cell with car +containing return code string and cdr containing the info channel." (when (symbolp backend) (setq backend (org-export-get-backend backend))) (org-export-barf-if-invalid-backend backend) (org-fold-core-ignore-modifications @@ -3106,6 +3110,14 @@ (defun org-export-as p (org-export--remove-uninterpreted-data value info)))) (_ nil))) + ;; Update `:output-file' option if needed. + (let ((output-file (plist-get info :output-file))) + (when (and output-file (listp output-file)) + (plist-put + info :output-file + (apply #'org-export-output-file-name + ;; `:output-file' contains argument list. + output-file)))) ;; Install user's and developer's filters. (setq info (org-export-install-filters info)) ;; Call options filters and update export options. We do not @@ -3155,10 +3167,13 @@ (defun org-export-as ;; Remove all text properties since they cannot be ;; retrieved from an external process. Finally call ;; final-output filter and return result. - (org-no-properties - (org-export-filter-apply-functions - (plist-get info :filter-final-output) - output info))))))))) + (let ((final-output + (org-no-properties + (org-export-filter-apply-functions + (plist-get info :filter-final-output) + output info)))) + (if with-info (cons final-output info) + final-output))))))))) ;;;###autoload (defun org-export-string-as (string backend &optional body-only ext-plist) @@ -6637,7 +6652,10 @@ (defun org-export-to-file BACKEND is either an export back-end, as returned by, e.g., `org-export-create-backend', or a symbol referring to a registered back-end. FILE is the name of the output file, as -a string. +a string. FILE can also be a list of options to determine file name +automatically. The options will be used as arguments of +`org-export-output-file-name', which will be called right before +:filter-options filter inside the cleaned buffer to be exported. A non-nil optional argument ASYNC means the process should happen asynchronously. The resulting buffer will then be accessible @@ -6664,26 +6682,33 @@ (defun org-latex-export-to-latex POST-PROCESS needs to be quoted. The function returns either a file name returned by POST-PROCESS, -or FILE." +or FILE written." (declare (indent 2)) - (if (not (file-writable-p file)) (error "Output file not writable") + (if (and (stringp file) (not (file-writable-p file))) + (error "Output file not writable") (let ((ext-plist (org-combine-plists `(:output-file ,file) ext-plist)) (encoding (or org-export-coding-system buffer-file-coding-system))) (if async (org-export-async-start (lambda (file) (org-export-add-to-stack (expand-file-name file) backend)) - `(let ((output - (org-export-as - ',backend ,subtreep ,visible-only ,body-only - ',ext-plist))) + `(let* ((output + (org-export-as + ',backend ,subtreep ,visible-only ,body-only + ',ext-plist ,(when (listp file) 'with-info))) + (file ,(if (listp file) '(cdr output) file))) + (when (consp output) (setq output (car output))) (with-temp-buffer (insert output) (let ((coding-system-for-write ',encoding)) - (write-region (point-min) (point-max) ,file))) - (or (ignore-errors (funcall ',post-process ,file)) ,file))) - (let ((output (org-export-as - backend subtreep visible-only body-only ext-plist))) + (write-region (point-min) (point-max) file))) + (or (ignore-errors (funcall ',post-process file)) file))) + (let* ((output (org-export-as + backend subtreep visible-only + body-only ext-plist + (when (listp file) 'with-info))) + (file (if (listp file) (cdr output) file))) + (when (consp output) (setq output (car output))) (with-temp-buffer (insert output) (let ((coding-system-for-write encoding)) -- 2.35.1