update packages
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user