update packages

This commit is contained in:
2025-06-22 17:08:08 +02:00
parent 54e5633369
commit 16a0a6db93
558 changed files with 68349 additions and 26568 deletions

View File

@@ -1,9 +1,8 @@
;;; ox-publish.el --- Publish Related Org Mode Files as a Website -*- lexical-binding: t; -*-
;; Copyright (C) 2006-2023 Free Software Foundation, Inc.
;; Copyright (C) 2006-2025 Free Software Foundation, Inc.
;; Author: David O'Toole <dto@gnu.org>
;; Maintainer: Nicolas Goaziou <mail@nicolasgoaziou.fr>
;; Keywords: hypermedia, outlines, wp
;; Keywords: hypermedia, outlines, text
;; This file is part of GNU Emacs.
;;
@@ -27,7 +26,7 @@
;;
;; ox-publish.el can do the following:
;;
;; + Publish all one's Org files to a given export back-end
;; + Publish all one's Org files to a given export backend
;; + Upload HTML, images, attachments and other files to a web server
;; + Exclude selected private pages from publishing
;; + Publish a clickable sitemap of pages
@@ -57,6 +56,9 @@
"This will cache timestamps and titles for files in publishing projects.
Blocks could hash sha1 values here.")
(defvar org-publish-transient-cache nil
"This will cache information during publishing process.")
(defvar org-publish-after-publishing-hook nil
"Hook run each time a file is published.
Every function in this hook will be called with two arguments:
@@ -86,7 +88,7 @@ cdr of each element is in one of the following forms:
(:components (\"project-1\" \"project-2\" ...))
When the CDR of an element of org-publish-project-alist is in
When the CDR of an element of `org-publish-project-alist' is in
this second form, the elements of the list after `:components'
are taken to be components of the project, which group together
files requiring different publishing options. When you publish
@@ -129,14 +131,14 @@ considered relative to the base directory.
When both `:include' and `:exclude' properties are given values,
the exclusion step happens first.
One special property controls which back-end function to use for
One special property controls which backend function to use for
publishing files in the project. This can be used to extend the
set of file types publishable by `org-publish', as well as the
set of output formats.
`:publishing-function'
Function to publish file. Each back-end may define its
Function to publish file. Each backend may define its
own (i.e. `org-latex-publish-to-pdf',
`org-html-publish-to-html'). May be a list of functions, in
which case each function in the list is invoked in turn.
@@ -162,10 +164,10 @@ date.
Some properties control details of the Org publishing process,
and are equivalent to the corresponding user variables listed in
the right column. Back-end specific properties may also be
included. See the back-end documentation for more information.
the right column. Backend specific properties may also be
included. See the backend documentation for more information.
:author `user-full-name'
:author variable `user-full-name'
:creator `org-export-creator-string'
:email `user-mail-address'
:exclude-tags `org-export-exclude-tags'
@@ -174,7 +176,7 @@ included. See the back-end documentation for more information.
:preserve-breaks `org-export-preserve-breaks'
:section-numbers `org-export-with-section-numbers'
:select-tags `org-export-select-tags'
:time-stamp-file `org-export-time-stamp-file'
:time-stamp-file `org-export-timestamp-file'
:with-archived-trees `org-export-with-archived-trees'
:with-author `org-export-with-author'
:with-creator `org-export-with-creator'
@@ -358,7 +360,9 @@ You can overwrite this default per project in your
;;; Timestamp-related functions
(defun org-publish-timestamp-filename (filename &optional pub-dir pub-func)
"Return path to timestamp file for filename FILENAME."
"Return path to timestamp file for filename FILENAME.
The timestamp file name is constructed using FILENAME, publishing
directory PUB-DIR, and PUB-FUNC publishing function."
(setq filename (concat filename "::" (or pub-dir "") "::"
(format "%s" (or pub-func ""))))
(concat "X" (if (fboundp 'sha1) (sha1 filename) (md5 filename))))
@@ -547,12 +551,12 @@ publishing FILENAME."
;;; Tools for publishing functions in back-ends
;;; Tools for publishing functions in backends
(defun org-publish-org-to (backend filename extension plist &optional pub-dir)
"Publish an Org file to a specified back-end.
"Publish an Org file to a specified backend.
BACKEND is a symbol representing the back-end used for
BACKEND is a symbol representing the backend used for
transcoding. FILENAME is the filename of the Org file to be
published. EXTENSION is the extension used for the output
string, with the leading dot. PLIST is the property list for the
@@ -564,30 +568,25 @@ directory.
Return output file name."
(unless (or (not pub-dir) (file-exists-p pub-dir)) (make-directory pub-dir t))
;; Check if a buffer visiting FILENAME is already open.
(let* ((org-inhibit-startup t)
(visiting (find-buffer-visiting filename))
(work-buffer (or visiting (find-file-noselect filename))))
(unwind-protect
(with-current-buffer work-buffer
(let ((output (org-export-output-file-name extension nil pub-dir)))
(org-export-to-file backend output
nil nil nil (plist-get plist :body-only)
;; Add `org-publish--store-crossrefs' and
;; `org-publish-collect-index' to final output filters.
;; The latter isn't dependent on `:makeindex', since we
;; want to keep it up-to-date in cache anyway.
(org-combine-plists
plist
`(:crossrefs
,(org-publish-cache-get-file-property
;; Normalize file names in cache.
(file-truename filename) :crossrefs nil t)
:filter-final-output
(org-publish--store-crossrefs
org-publish-collect-index
,@(plist-get plist :filter-final-output)))))))
;; Remove opened buffer in the process.
(unless visiting (kill-buffer work-buffer)))))
(let* ((org-inhibit-startup t))
(org-with-file-buffer filename
(let ((output (org-export-output-file-name extension nil pub-dir)))
(org-export-to-file backend output
nil nil nil (plist-get plist :body-only)
;; Add `org-publish--store-crossrefs' and
;; `org-publish-collect-index' to final output filters.
;; The latter isn't dependent on `:makeindex', since we
;; want to keep it up-to-date in cache anyway.
(org-combine-plists
plist
`(:crossrefs
,(org-publish-cache-get-file-property
;; Normalize file names in cache.
(file-truename filename) :crossrefs nil t)
:filter-final-output
(org-publish--store-crossrefs
org-publish-collect-index
,@(plist-get plist :filter-final-output)))))))))
(defun org-publish-attachment (_plist filename pub-dir)
"Publish a file with no transformation of any kind.
@@ -795,17 +794,14 @@ Default for SITEMAP-FILENAME is `sitemap.org'."
(concat (file-name-directory b)
(org-publish-find-title b project))
b)))
(setq retval
(if ignore-case
(not (string-lessp (upcase B) (upcase A)))
(not (string-lessp B A))))))
(setq retval (org-string<= A B nil ignore-case))))
((or `anti-chronologically `chronologically)
(let* ((adate (org-publish-find-date a project))
(bdate (org-publish-find-date b project)))
(setq retval
(not (if (eq sort-files 'chronologically)
(time-less-p bdate adate)
(time-less-p adate bdate))))))
(time-less-p bdate adate)
(time-less-p adate bdate))))))
(`nil nil)
(_ (user-error "Invalid sort value %s" sort-files)))
;; Directory-wise wins:
@@ -830,7 +826,7 @@ Default for SITEMAP-FILENAME is `sitemap.org'."
(mapcar #'file-name-directory files)))
files)))
;; Eventually sort all entries.
(when (or sort-files (not (memq sort-folders 'ignore)))
(when (or sort-files (not (eq sort-folders 'ignore)))
(setq files (sort files sort-predicate)))
(funcall sitemap-builder
title
@@ -841,9 +837,9 @@ Default for SITEMAP-FILENAME is `sitemap.org'."
"Find the PROPERTY of FILE in project.
PROPERTY is a keyword referring to an export option, as defined
in `org-export-options-alist' or in export back-ends. In the
in `org-export-options-alist' or in export backends. In the
latter case, optional argument BACKEND has to be set to the
back-end where the option is defined, e.g.,
backend where the option is defined, e.g.,
(org-publish-find-property file :subtitle \\='latex)
@@ -851,17 +847,13 @@ Return value may be a string or a list, depending on the type of
PROPERTY, i.e. \"behavior\" parameter from `org-export-options-alist'."
(let ((file (org-publish--expand-file-name file project)))
(when (and (file-readable-p file) (not (directory-name-p file)))
(let* ((org-inhibit-startup t)
(visiting (find-buffer-visiting file))
(buffer (or visiting (find-file-noselect file))))
(unwind-protect
(plist-get (with-current-buffer buffer
(if (not visiting) (org-export-get-environment backend)
;; Protect local variables in open buffers.
(org-export-with-buffer-copy
(org-export-get-environment backend))))
property)
(unless visiting (kill-buffer buffer)))))))
(let* ((org-inhibit-startup t))
(plist-get (org-with-file-buffer file
(if (not org-file-buffer-created) (org-export-get-environment backend)
;; Protect local variables in open buffers.
(org-export-with-buffer-copy
(org-export-get-environment backend))))
property)))))
(defun org-publish-find-title (file project)
"Find the title of FILE in PROJECT."
@@ -875,7 +867,7 @@ PROPERTY, i.e. \"behavior\" parameter from `org-export-options-alist'."
(org-no-properties
(org-element-interpret-data parsed-title))
(file-name-nondirectory (file-name-sans-extension file)))))
(org-publish-cache-set-file-property file :title title)))))
(org-publish-cache-set-file-property file :title title nil 'transient)))))
(defun org-publish-find-date (file project)
"Find the date of FILE in PROJECT.
@@ -891,7 +883,7 @@ time in `current-time' format."
(file-attribute-modification-time (file-attributes file))
(let ((date (org-publish-find-property file :date project)))
;; DATE is a secondary string. If it contains
;; a time-stamp, convert it to internal format.
;; a timestamp, convert it to internal format.
;; Otherwise, use FILE modification time.
(cond ((let ((ts (and (consp date) (assq 'timestamp date))))
(and ts
@@ -900,7 +892,8 @@ time in `current-time' format."
(org-time-string-to-time value))))))
((file-exists-p file)
(file-attribute-modification-time (file-attributes file)))
(t (error "No such file: \"%s\"" file)))))))))
(t (error "No such file: \"%s\"" file)))))
nil 'transient))))
(defun org-publish-sitemap-default-entry (entry style project)
"Default format for site map ENTRY, as a string.
@@ -1024,7 +1017,7 @@ the project."
"Update index for a file in cache.
OUTPUT is the output from transcoding current file. BACKEND is
the back-end that was used for transcoding. INFO is a plist
the backend that was used for transcoding. INFO is a plist
containing publishing and export options.
The index relative to current file is stored as an alist. An
@@ -1042,7 +1035,7 @@ its CDR is a string."
(org-element-map (plist-get info :parse-tree) 'keyword
(lambda (k)
(when (equal (org-element-property :key k) "INDEX")
(let ((parent (org-export-get-parent-headline k)))
(let ((parent (org-element-lineage k 'headline)))
(list (org-element-property :value k)
file
(cond
@@ -1056,7 +1049,8 @@ its CDR is a string."
(replace-regexp-in-string
"\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" ""
(org-element-property :raw-value parent)))))))))
info))))
info))
nil 'transient))
;; Return output unchanged.
output)
@@ -1138,7 +1132,7 @@ publishing directory."
"Store cross-references for current published file.
OUTPUT is the produced output, as a string. BACKEND is the export
back-end used, as a symbol. INFO is the final export state, as
backend used, as a symbol. INFO is the final export state, as
a plist.
This function is meant to be used as a final output filter. See
@@ -1170,7 +1164,7 @@ option, e.g.,
When PREFER-CUSTOM is non-nil, and SEARCH targets a headline in
FILE, return its custom ID, if any.
It only makes sense to use this if export back-end builds
It only makes sense to use this if export backend builds
references with `org-export-get-reference'."
(cond
((and prefer-custom
@@ -1259,6 +1253,9 @@ If FREE-CACHE, empty the cache."
(error "Org publish timestamp: %s is not a directory"
org-publish-timestamp-directory))
(unless org-publish-transient-cache
(setq org-publish-transient-cache (make-hash-table :test #'equal)))
(unless (and org-publish-cache
(string= (org-publish-cache-get ":project:") project-name))
(let* ((cache-file
@@ -1282,6 +1279,8 @@ If FREE-CACHE, empty the cache."
(message "%s" "Resetting org-publish-cache")
(when (hash-table-p org-publish-cache)
(clrhash org-publish-cache))
(when (hash-table-p org-publish-transient-cache)
(clrhash org-publish-transient-cache))
(setq org-publish-cache nil))
(defun org-publish-cache-file-needs-publishing
@@ -1306,7 +1305,7 @@ the file including them will be republished as well."
(goto-char (point-min))
(while (re-search-forward "^[ \t]*#\\+INCLUDE:" nil t)
(let ((element (org-element-at-point)))
(when (eq 'keyword (org-element-type element))
(when (org-element-type-p element 'keyword)
(let* ((value (org-element-property :value element))
(include-filename
(and (string-match "\\`\\(\".+?\"\\|\\S-+\\)" value)
@@ -1327,16 +1326,22 @@ the file including them will be republished as well."
included-files-mtime))))))
(defun org-publish-cache-set-file-property
(filename property value &optional project-name)
(filename property value &optional project-name transient)
"Set the VALUE for a PROPERTY of file FILENAME in publishing cache to VALUE.
Use cache file of PROJECT-NAME. If the entry does not exist, it
will be created. Return VALUE."
will be created. Return VALUE.
When TRANSIENT is non-nil, store value in transient cache that is only
maintained during the current publish process."
;; Evtl. load the requested cache file:
(when project-name (org-publish-initialize-cache project-name))
(let ((pl (org-publish-cache-get filename)))
(if pl (progn (plist-put pl property value) value)
(org-publish-cache-get-file-property
filename property value nil project-name))))
(if transient
(puthash (cons filename property) value
org-publish-transient-cache)
(let ((pl (org-publish-cache-get filename)))
(if pl (progn (plist-put pl property value) value)
(org-publish-cache-get-file-property
filename property value nil project-name)))))
(defun org-publish-cache-get-file-property
(filename property &optional default no-create project-name)
@@ -1345,13 +1350,14 @@ Use cache file of PROJECT-NAME. Return the value of that PROPERTY,
or DEFAULT, if the value does not yet exist. Create the entry,
if necessary, unless NO-CREATE is non-nil."
(when project-name (org-publish-initialize-cache project-name))
(let ((properties (org-publish-cache-get filename)))
(cond ((null properties)
(unless no-create
(org-publish-cache-set filename (list property default)))
default)
((plist-member properties property) (plist-get properties property))
(t default))))
(or (gethash (cons filename property) org-publish-transient-cache)
(let ((properties (org-publish-cache-get filename)))
(cond ((null properties)
(unless no-create
(org-publish-cache-set filename (list property default)))
default)
((plist-member properties property) (plist-get properties property))
(t default)))))
(defun org-publish-cache-get (key)
"Return the value stored in `org-publish-cache' for key KEY.