emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [BUG] EXPORT_FILE_NAME keyword is used by `org-export-output-file-na


From: Ihor Radchenko
Subject: Re: [BUG] EXPORT_FILE_NAME keyword is used by `org-export-output-file-name' before macro expansion/INCLUDEs/removing COMMENTed trees (was: Confused about what the COMMENT keyword means)
Date: Thu, 10 Nov 2022 01:51:05 +0000

Ihor Radchenko <yantar92@gmail.com> writes:

> There should be no other buffer setting that is taken into account
> in COMMENTed subtrees. EXPORT_FILE_NAME is the only one.
>
> I think that we should not really change the manual unless we have to.
> It will be better to fix the bug instead.

I am attaching a tentative change to ox.el machinery that will allow
calculating EXPORT_FILE_NAME dynamically inside the processed export
buffer.

The change is not yet fixing the bug. I just want to hear feedback
on the approach I used.

Let me know if you see any issues or have better ideas.

>From 57aa366e9d5596741c256688c9b8ef07a9b24e17 Mon Sep 17 00:00:00 2001
Message-Id: 
<57aa366e9d5596741c256688c9b8ef07a9b24e17.1668044888.git.yantar92@posteo.net>
From: Ihor Radchenko <yantar92@posteo.net>
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

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

reply via email to

[Prev in Thread] Current Thread [Next in Thread]