> On Jul 25, 2026, at 11:08, Ihor Radchenko <[email protected]> wrote:
> 
> Derek Chen-Becker <[email protected]> writes:
> 
>> Subject: [PATCH] Add new after-includes hook for org export
> 
> The commit message is a bit off. We usually do something like
> 
> org-export: Add new org-export-after-includes-functions hook
> 
>> Provide a new hook that runs after include keywords, but before macros and
>> Babel code.
>> 
>> * doc/org-manual.org: Update the org-export hooks section to describe the
>> new hook in relation to the other existing hooks.
> 
> ORG-NEWS should be updated as well.
> 
>> * lisp/org-table.el (orgtbl-to-generic): Disable the new hook during table
>> export just as we do with other hooks.
> 
> This leads to compiler warning that should be suppressed.
> 
>> +(defvar org-export-after-includes-functions nil
>> +  "Abnormal hook run after includes but before macros.
>> +
>> +This is run after include keywords but before macros have been
>> +expanded and Babel code blocks executed, on a copy of the original
>> +buffer being exported.  Visibility and narrowing are preserved.  Point
>> +is at the beginning of the buffer.")
> 
> The docstring should explain the arguments passed to the abnormal hook.

I took a crack at the ORG-NEWS update and fix the two issues.  I don’t know how 
to
do a pull request or the commit message.

> diff --git a/doc/org-manual.org b/doc/org-manual.org
> index bda84c49c..5706380b1 100644
> --- a/doc/org-manual.org
> +++ b/doc/org-manual.org
> @@ -16964,12 +16964,15 @@ for usage and configuration details.
>  
>  #+vindex: org-export-before-processing-hook
>  #+vindex: org-export-before-processing-functions
> +#+vindex: org-export-after-includes-functions
>  #+vindex: org-export-before-parsing-hook
>  #+vindex: org-export-before-parsing-functions
> -The export process executes two hooks before the actual exporting
> +The export process executes three hooks before the actual exporting
>  begins.  The first hook, ~org-export-before-processing-functions~,
>  runs before any expansions of macros, Babel code, and include keywords
>  in the buffer.  The second hook,
> +~org-export-after-includes-functions~, runs after the include keywords
> +but before the macros and Babel code.  The last hook,
>  ~org-export-before-parsing-functions~, runs before the buffer is
>  parsed.
>  
> @@ -17109,10 +17112,12 @@ export keywords, does not contribute to the export 
> output.]:
>  3. Remove commented subtrees in the whole buffer (see [[*Comment
>     Lines]]);
>  
> -4. Replace macros in the whole buffer (see [[*Macro Replacement]]),
> +4. Execute ~org-export-after-includes-functions~ (see [[*Export hooks]]);
> +
> +5. Replace macros in the whole buffer (see [[*Macro Replacement]]),
>     unless ~org-export-replace-macros~ is nil;
>  
> -5. When ~org-export-use-babel~ is non-nil (default), process code
> +6. When ~org-export-use-babel~ is non-nil (default), process code
>     blocks:
>  
>     - Leave code blocks inside archived subtrees (see [[*Internal
> diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
> index 5f5168e33..7d4875e6b 100644
> --- a/etc/ORG-NEWS
> +++ b/etc/ORG-NEWS
> @@ -319,6 +319,13 @@ entry, or displays it in another window if filtered out.
>  # require user action for most Org mode users.
>  # Sorted from most important to least important.
>  
> +*** Abnormal hook added: org-export-after-includes-functions
> +
> +This is run after include keywords but before macros have been
> +expanded and Babel code blocks executed, on a copy of the original
> +buffer being exported.  Visibility and narrowing are preserved.  Point
> +is at the beginning of the buffer.
> +
>  *** You may need to update =org-protocol= bookmarklets for browsers
>  
>  In Firefox 133 and Firefox 128.5 ESR, the previously suggested
> diff --git a/lisp/org-table.el b/lisp/org-table.el
> index 9aeb53822..3920b573e 100644
> --- a/lisp/org-table.el
> +++ b/lisp/org-table.el
> @@ -5853,6 +5853,7 @@ This may be either a string or a function of two 
> arguments:
>                (princ "\n")))))
>        (let ((org-inhibit-startup t)) (org-mode))
>        (defvar org-export-before-processing-functions) ; ox.el
> +      (defvar org-export-after-includes-functions) ; ox.el
>        (defvar org-export-process-citations) ; ox.el
>        (defvar org-export-expand-links) ; ox.el
>        (defvar org-export-filter-parse-tree-functions) ; ox.el
> @@ -5867,6 +5868,7 @@ This may be either a string or a function of two 
> arguments:
>        ;; We _do not_ disable `org-export-filter-parse-tree-functions'
>        ;; (historically).
>        (let ((org-export-before-processing-functions nil)
> +            (org-export-after-includes-functions nil)
>              (org-export-replace-macros nil)
>              (org-export-use-babel nil)
>              (org-export-before-parsing-functions nil)
> diff --git a/lisp/ox.el b/lisp/ox.el
> index 90c853d76..c3993ec9b 100644
> --- a/lisp/ox.el
> +++ b/lisp/ox.el
> @@ -2175,10 +2175,11 @@ keywords before output."
>  ;; Filters properties are installed in communication channel with
>  ;; `org-export-install-filters' function.
>  ;;
> -;; Eventually, two hooks (`org-export-before-processing-functions' and
> -;; `org-export-before-parsing-functions') are run at the beginning of the
> -;; export process and just before parsing to allow for heavy structure
> -;; modifications.
> +;; Eventually, three hooks (`org-export-before-processing-functions',
> +;; `org-export-after-includes-functions' and
> +;; `org-export-before-parsing-functions') are run at the beginning of
> +;; the export process and just before parsing to allow for heavy
> +;; structure modifications.
>  
>  
>  ;;;; Hooks
> @@ -2194,6 +2195,17 @@ is at the beginning of the buffer.
>  Every function in this hook will be called with one argument: the
>  backend currently used, as a symbol.")
>  
> +(defvar org-export-after-includes-functions nil
> +  "Abnormal hook run after includes but before macros.
> +
> +This is run after include keywords but before macros have been
> +expanded and Babel code blocks executed, on a copy of the original
> +buffer being exported.  Visibility and narrowing are preserved.  Point
> +is at the beginning of the buffer.
> +
> +Every function in this hook will be called with one argument: the
> +backend currently used, as a symbol.")
> +
>  (defvar org-export-before-parsing-functions nil
>    "Abnormal hook run before parsing an export buffer.
>  
> @@ -3104,6 +3116,10 @@ still inferior to file-local settings."
>                          (org-export-backend-name backend))
>      (org-export-expand-include-keyword nil nil nil nil (plist-get info 
> :expand-links))
>      (org-export--delete-comment-trees)
> +    (save-excursion
> +      (goto-char (point-min))
> +      (run-hook-with-args 'org-export-after-includes-functions
> +                          (org-export-backend-name backend)))
>      (when org-export-replace-macros
>        (org-macro-initialize-templates org-export-global-macros)
>        (org-macro-replace-all org-macro-templates parsed-keywords))
> diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
> index 79365ad29..e58c776e9 100644
> --- a/testing/lisp/test-ox.el
> +++ b/testing/lisp/test-ox.el
> @@ -1879,6 +1879,24 @@ Footnotes[fn:2], foot[fn:test] and [fn:inline:inline 
> footnote]
>                       (org-element-property :end object)))))))))
>       (org-export-as (org-test-default-backend)))))))
>  
> +(ert-deftest test-org-export/after-includes-hook ()
> +  "Test `org-export-after-includes-functions'."
> +  (should
> +   (equal "success\n"
> +          (org-test-with-temp-text
> +           (format "#+INCLUDE: \"%s/examples/macro-templates.org\"\n" 
> org-test-dir)
> +           (let* ((org-export-after-includes-functions
> +                  '((lambda (backend)
> +                      (goto-char (point-min))
> +                      ;; will fail if hook done before the include
> +                      (if (search-forward "Macro templates")
> +                          (progn
> +                            (goto-char (point-max))
> +                            ;; will not expand if hook executes after macros
> +                            (insert "{{{included-macro}}}"))))))
> +                 (output (org-export-as (org-test-default-backend))))
> +             (substring output (string-match ".*\n\\'" output)))))))
> +
>  (ert-deftest test-org-export/before-parsing-functions ()
>    "Test `org-export-before-parsing-functions'."
>    (should




Reply via email to