From: Rasmus Date: Wed, 6 Dec 2017 14:02:15 +0000 (+0100) Subject: Backport: Update Org to v9.1.4 X-Git-Tag: emacs-26.0.91~186 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=445eefd;p=emacs.git Backport: Update Org to v9.1.4 Please note this is a bugfix release. See etc/ORG-NEWS for details. (cherry picked from commit 567b5efe1f338c10c574758fb968915c5c34c909) --- diff --git a/doc/misc/org.texi b/doc/misc/org.texi index 72fbbade59e..1f6e10287d1 100644 --- a/doc/misc/org.texi +++ b/doc/misc/org.texi @@ -4,7 +4,7 @@ @settitle The Org Manual @include docstyle.texi -@set VERSION 9.1.2 +@set VERSION 9.1.4 @set DATE 2017-09-17 @c Version and Contact Info @@ -1299,7 +1299,7 @@ level, all sibling headings. With a double prefix argument, also show the entire subtree of the parent. @cindex show branches, command @orgcmd{C-c C-k,outline-show-branches} -Expose all the headings of the subtree, CONTENT view for just one subtree. +Expose all the headings of the subtree, CONTENTS view for just one subtree. @cindex show children, command @orgcmd{C-c @key{TAB},outline-show-children} Expose all direct children of the subtree. With a numeric prefix argument N, @@ -1461,10 +1461,10 @@ Demote current heading by one level. Promote the current subtree by one level. @orgcmd{M-S-@key{right},org-demote-subtree} Demote the current subtree by one level. -@orgcmd{M-S-@key{up},org-move-subtree-up} +@orgcmd{M-@key{up},org-move-subtree-up} Move subtree up (swap with previous subtree of same level). -@orgcmd{M-S-@key{down},org-move-subtree-down} +@orgcmd{M-@key{down},org-move-subtree-down} Move subtree down (swap with next subtree of same level). @orgcmd{M-h,org-mark-element} Mark the element at point. Hitting repeatedly will mark subsequent elements @@ -5818,8 +5818,7 @@ The following commands insert or update the dynamic block: Insert a dynamic block capturing a column view. You will be prompted for the scope or ID of the view. @orgcmdkkc{C-c C-c,C-c C-x C-u,org-dblock-update} -Update dynamic block at point. The cursor needs to be in the -@code{#+BEGIN} line of the dynamic block. +Update dynamic block at point. @orgcmd{C-u C-c C-x C-u,org-update-all-dblocks} Update all dynamic blocks (@pxref{Dynamic blocks}). This is useful if you have several clock table blocks, column-capturing blocks or other dynamic @@ -6604,8 +6603,7 @@ argument, jump to the first clock report in the current document and update it. The clock table always includes also trees with @code{:ARCHIVE:} tag. @orgcmdkkc{C-c C-c,C-c C-x C-u,org-dblock-update} -Update dynamic block at point. The cursor needs to be in the -@code{#+BEGIN} line of the dynamic block. +Update dynamic block at point. @orgkey{C-u C-c C-x C-u} Update all dynamic blocks (@pxref{Dynamic blocks}). This is useful if you have several clock table blocks in a buffer. @@ -7352,6 +7350,7 @@ gnus | %:group, @r{for messages also all email fiel eww, w3, w3m | %:url info | %:file %:node calendar | %:date +org-protocol | %:link %:description %:annotation @end smallexample @noindent @@ -7593,22 +7592,15 @@ javascript:location.href='org-protocol://store-link?url='+ @cindex capture protocol @cindex protocol, capture -@cindex capture, %:url placeholder -@cindex %:url template expansion in capture -@cindex capture, %:title placeholder -@cindex %:title template expansion in capture Activating @code{capture} handler pops up a @samp{Capture} buffer and fills -the capture template associated to the @samp{X} key with them. The template -refers to the data through @code{%:url} and @code{%:title} placeholders. -Moreover, any selected text in the browser is appended to the body of the -entry. +the capture template associated to the @samp{X} key with them. @example emacsclient org-protocol://capture?template=X?url=URL?title=TITLE?body=BODY @end example -To use this feature, add a bookmark with an arbitrary name, e.g. -@samp{Org: capture} and enter this as @samp{Location}: +To use this feature, add a bookmark with an arbitrary name, e.g. @samp{Org: +capture} and enter this as @samp{Location}: @example javascript:location.href='org-protocol://template=x'+ @@ -7622,6 +7614,21 @@ The result depends on the capture template used, which is set in the bookmark itself, as in the example above, or in @code{org-protocol-default-template-key}. +@cindex capture, %:link placeholder +@cindex %:link template expansion in capture +@cindex capture, %:description placeholder +@cindex %:description template expansion in capture +@cindex capture, %:annotation placeholder +@cindex %:annotation template expansion in capture +The following template placeholders are available: + +@example +%:link The URL +%:description The webpage title +%:annotation Equivalent to [[%:link][%:description]] +%i The selected text +@end example + @node @code{open-source} protocol @subsection @code{open-source} protocol @cindex open-source protocol @@ -10782,8 +10789,9 @@ Toggle inclusion of inlinetasks (@code{org-export-with-inlinetasks}). @cindex property, UNNUMBERED Toggle section-numbers (@code{org-export-with-section-numbers}). When set to number @samp{n}, Org numbers only those headlines at level @samp{n} or above. -Set @code{UNNUMBERED} property to non-@code{nil} to disable numbering of -heading and subheadings entirely. +Setting @code{UNNUMBERED} property to non-@code{nil} disables numbering of +a heading. Since subheadings inherit from this property, it affects their +numbering, too. @item p: @vindex org-export-with-planning diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 19648cf17a8..7ed839a1847 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -492,9 +492,6 @@ It used to be ~@samp~ but ~@asis~ is neutral and, therefore, more suitable as a default value. *** Texinfo default process includes ~--no-split~ option *** New entities : ~\dollar~ and ~\USD~ -*** ~org-parse-time-string~ accepts a new optional argument -=ZONE= specifies the current time zone. -*** ~org-time-string-to-seconds~ now accepts an optional =ZONE= argument *** Support for date style URLs in =org-protocol://open-source= URLs like =https://cool-blog.com/2017/05/20/cool-post/= are covered by rewrite rules. diff --git a/etc/refcards/orgcard.tex b/etc/refcards/orgcard.tex index 99f90b8d31c..ad0d3bc13e5 100644 --- a/etc/refcards/orgcard.tex +++ b/etc/refcards/orgcard.tex @@ -1,5 +1,5 @@ % Reference Card for Org Mode -\def\orgversionnumber{9.1.2} +\def\orgversionnumber{9.1.4} \def\versionyear{2017} % latest update \input emacsver.tex diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el index c7c03845451..17aae68434a 100644 --- a/lisp/org/ob-core.el +++ b/lisp/org/ob-core.el @@ -1765,15 +1765,17 @@ to `org-babel-named-src-block-regexp'." (defun org-babel-src-block-names (&optional file) "Returns the names of source blocks in FILE or the current buffer." - (when file (find-file file)) - (save-excursion - (goto-char (point-min)) - (let* ((re (org-babel-named-src-block-regexp-for-name)) - (names (and (looking-at re) - (list (match-string-no-properties 9))))) - (while (ignore-errors (org-next-block 1 nil re)) - (push (match-string-no-properties 9) names)) - names))) + (with-current-buffer (if file (find-file-noselect file) (current-buffer)) + (org-with-point-at 1 + (let ((regexp "^[ \t]*#\\+begin_src ") + (case-fold-search t) + (names nil)) + (while (re-search-forward regexp nil t) + (let ((element (org-element-at-point))) + (when (eq 'src-block (org-element-type element)) + (let ((name (org-element-property :name element))) + (when name (push name names)))))) + names)))) ;;;###autoload (defun org-babel-goto-named-result (name) @@ -2416,8 +2418,11 @@ INFO may provide the values of these header arguments (in the (goto-char location) (when (looking-at (concat org-babel-result-regexp ".*$")) (delete-region - (if keep-keyword (1+ (match-end 0)) (1- (match-beginning 0))) - (progn (forward-line 1) (org-babel-result-end)))))))) + (if keep-keyword (line-beginning-position 2) + (save-excursion + (skip-chars-backward " \r\t\n") + (line-beginning-position 2))) + (progn (forward-line) (org-babel-result-end)))))))) (defun org-babel-remove-inline-result (&optional datum) "Remove the result of the current inline-src-block or babel call. @@ -2454,24 +2459,21 @@ in the buffer." (defun org-babel-result-end () "Return the point at the end of the current set of results." - (save-excursion - (cond - ((org-at-table-p) (progn (goto-char (org-table-end)) (point))) - ((org-at-item-p) (let* ((struct (org-list-struct)) - (prvs (org-list-prevs-alist struct))) - (org-list-get-list-end (point-at-bol) struct prvs))) - ((let ((case-fold-search t)) (looking-at "^\\([ \t]*\\):results:")) - (progn (re-search-forward (concat "^" (match-string 1) ":END:")) - (forward-char 1) (point))) - (t - (let ((case-fold-search t)) - (if (looking-at (concat "[ \t]*#\\+begin_\\([^ \t\n\r]+\\)")) - (progn (re-search-forward (concat "[ \t]*#\\+end_" (match-string 1)) - nil t) - (forward-char 1)) - (while (looking-at "[ \t]*\\(: \\|:$\\|\\[\\[\\)") - (forward-line 1)))) - (point))))) + (cond ((looking-at-p "^[ \t]*$") (point)) ;no result + ((looking-at-p (format "^[ \t]*%s[ \t]*$" org-bracket-link-regexp)) + (line-beginning-position 2)) + (t + (let ((element (org-element-at-point))) + (if (memq (org-element-type element) + ;; Possible results types. + '(drawer example-block export-block fixed-width item + plain-list src-block table)) + (save-excursion + (goto-char (min (point-max) ;for narrowed buffers + (org-element-property :end element))) + (skip-chars-backward " \r\t\n") + (line-beginning-position 2)) + (point)))))) (defun org-babel-result-to-file (result &optional description) "Convert RESULT into an `org-mode' link with optional DESCRIPTION. diff --git a/lisp/org/ob-gnuplot.el b/lisp/org/ob-gnuplot.el index 763386270d7..b0743f60475 100644 --- a/lisp/org/ob-gnuplot.el +++ b/lisp/org/ob-gnuplot.el @@ -40,7 +40,7 @@ ;;; Code: (require 'ob) -(declare-function org-time-string-to-time "org" (s &optional zone)) +(declare-function org-time-string-to-time "org" (s)) (declare-function org-combine-plists "org" (&rest plists)) (declare-function orgtbl-to-generic "org-table" (table params)) (declare-function gnuplot-mode "ext:gnuplot-mode" ()) diff --git a/lisp/org/ob-tangle.el b/lisp/org/ob-tangle.el index adc6806766d..09d011fc35e 100644 --- a/lisp/org/ob-tangle.el +++ b/lisp/org/ob-tangle.el @@ -494,10 +494,9 @@ non-nil, return the full association list to be used by link) source-name params - (org-unescape-code-in-string - (if org-src-preserve-indentation - (org-trim body t) - (org-trim (org-remove-indentation body)))) + (if org-src-preserve-indentation + (org-trim body t) + (org-trim (org-remove-indentation body))) comment))) (if only-this-block (list (cons src-lang (list result))) diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el index cf7a4dbf38b..ad811ce3193 100644 --- a/lisp/org/org-agenda.el +++ b/lisp/org/org-agenda.el @@ -606,8 +606,8 @@ subtree to see if any of the subtasks have project status. See also the variable `org-tags-match-list-sublevels' which applies to projects matched by this search as well. -After defining this variable, you may use `\\[org-agenda-list-stuck-projects]' -\(bound to `C-c a #') to produce the list." +After defining this variable, you may use `org-agenda-list-stuck-projects' +\(bound to `\\[org-agenda] #') to produce the list." :group 'org-agenda-custom-commands :type '(list (string :tag "Tags/TODO match to identify a project") @@ -2520,7 +2520,7 @@ The following commands are available: ("MobileOrg" ["Push Files and Views" org-mobile-push t] ["Get Captured and Flagged" org-mobile-pull t] - ["Find FLAGGED Tasks" (org-agenda nil "?") :active t :keys "C-c a ?"] + ["Find FLAGGED Tasks" (org-agenda nil "?") :active t :keys "\\[org-agenda] ?"] ["Show note / unflag" org-agenda-show-the-flagging-note t] "--" ["Setup" (progn (require 'org-mobile) (customize-group 'org-mobile)) t]) diff --git a/lisp/org/org-archive.el b/lisp/org/org-archive.el index 03376172a62..01514d75652 100644 --- a/lisp/org/org-archive.el +++ b/lisp/org/org-archive.el @@ -381,10 +381,7 @@ direct children of this heading." (point) (concat "ARCHIVE_" (upcase (symbol-name item))) value)))) - (widen) - ;; Save and kill the buffer, if it is not the same - ;; buffer. - (unless (eq this-buffer buffer) (save-buffer))))) + (widen)))) ;; Here we are back in the original buffer. Everything seems ;; to have worked. So now run hooks, cut the tree and finish ;; up. diff --git a/lisp/org/org-attach.el b/lisp/org/org-attach.el index 38b79cecfe4..cd6b4136233 100644 --- a/lisp/org/org-attach.el +++ b/lisp/org/org-attach.el @@ -507,7 +507,7 @@ This can be used after files have been added externally." (let ((attach-dir (org-attach-dir))) (when attach-dir (let ((files (org-attach-file-list attach-dir))) - (and files (org-attach-tag)) + (org-attach-tag (not files)) (when org-attach-file-list-property (dolist (file files) (unless (string-match "^\\.\\.?\\'" file) diff --git a/lisp/org/org-capture.el b/lisp/org/org-capture.el index 862cdb27623..03210210864 100644 --- a/lisp/org/org-capture.el +++ b/lisp/org/org-capture.el @@ -79,6 +79,12 @@ (defvar org-capture-is-refiling nil "Non-nil when capture process is refiling an entry.") +(defvar org-capture--prompt-history-table (make-hash-table :test #'equal) + "Hash table for all history lists per prompt.") + +(defvar org-capture--prompt-history nil + "History list for prompt placeholders.") + (defgroup org-capture nil "Options concerning capturing new entries." :tag "Org Capture" @@ -1311,8 +1317,8 @@ Of course, if exact position has been required, just put it there." (defun org-capture-mark-kill-region (beg end) "Mark the region that will have to be killed when aborting capture." - (let ((m1 (move-marker (make-marker) beg)) - (m2 (move-marker (make-marker) end))) + (let ((m1 (copy-marker beg)) + (m2 (copy-marker end t))) (org-capture-put :begin-marker m1) (org-capture-put :end-marker m2))) @@ -1792,19 +1798,25 @@ The template may still contain \"%?\" for cursor positioning." (let* ((upcase? (equal (upcase key) key)) (org-end-time-was-given nil) (time (org-read-date upcase? t nil prompt))) - (let ((org-time-was-given upcase?)) - (org-insert-time-stamp - time org-time-was-given - (member key '("u" "U")) - nil nil (list org-end-time-was-given))))) + (org-insert-time-stamp + time (or org-time-was-given upcase?) + (member key '("u" "U")) + nil nil (list org-end-time-was-given)))) (`nil + ;; Load history list for current prompt. + (setq org-capture--prompt-history + (gethash prompt org-capture--prompt-history-table)) (push (org-completing-read (concat (or prompt "Enter string") (and default (format " [%s]" default)) ": ") - completions nil nil nil nil default) + completions + nil nil nil 'org-capture--prompt-history default) strings) - (insert (car strings))) + (insert (car strings)) + ;; Save updated history list for current prompt. + (puthash prompt org-capture--prompt-history + org-capture--prompt-history-table)) (_ (error "Unknown template placeholder: \"%%^%s\"" key)))))))) diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el index 69e199ea27f..0e7eb214958 100644 --- a/lisp/org/org-clock.el +++ b/lisp/org/org-clock.el @@ -1467,7 +1467,7 @@ The time is always returned as UTC." (and (or (not cmt) (equal cmt "auto")) lr)) (setq org--msg-extra "showing task time since last repeat.") - (and lr (org-time-string-to-time lr t))) + (and lr (org-time-string-to-time lr))) (t nil)))) (defun org-clock-find-position (find-unclosed) @@ -1604,9 +1604,9 @@ to, overriding the existing value of `org-clock-out-switch-to-state'." (insert "--") (setq te (org-insert-time-stamp (or at-time now) 'with-hm 'inactive)) (setq s (- (float-time - (apply #'encode-time (org-parse-time-string te nil t))) + (apply #'encode-time (org-parse-time-string te))) (float-time - (apply #'encode-time (org-parse-time-string ts nil t)))) + (apply #'encode-time (org-parse-time-string ts)))) h (floor (/ s 3600)) s (- s (* 3600 h)) m (floor (/ s 60)) @@ -1711,8 +1711,8 @@ Optional argument N tells to change by that many units." (begts (if updatets1 begts1 begts2))) (setq tdiff (time-subtract - (org-time-string-to-time org-last-changed-timestamp t) - (org-time-string-to-time ts t))) + (org-time-string-to-time org-last-changed-timestamp) + (org-time-string-to-time ts))) (save-excursion (goto-char begts) (org-timestamp-change @@ -1820,10 +1820,10 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes." (lmax 30) (ltimes (make-vector lmax 0)) (level 0) - (tstart (cond ((stringp tstart) (org-time-string-to-seconds tstart t)) + (tstart (cond ((stringp tstart) (org-time-string-to-seconds tstart)) ((consp tstart) (float-time tstart)) (t tstart))) - (tend (cond ((stringp tend) (org-time-string-to-seconds tend t)) + (tend (cond ((stringp tend) (org-time-string-to-seconds tend)) ((consp tend) (float-time tend)) (t tend))) (t1 0) @@ -1840,11 +1840,10 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes." (let* ((ts (float-time (apply #'encode-time (save-match-data - (org-parse-time-string - (match-string 2) nil t))))) + (org-parse-time-string (match-string 2)))))) (te (float-time (apply #'encode-time - (org-parse-time-string (match-string 3) nil t)))) + (org-parse-time-string (match-string 3))))) (dt (- (if tend (min te tend) te) (if tstart (max ts tstart) ts)))) (when (> dt 0) (cl-incf t1 (floor (/ dt 60)))))) @@ -2725,7 +2724,9 @@ LEVEL is an integer. Indent by two spaces per level above 1." (setq te (float-time (apply #'encode-time (org-parse-time-string te)))))) (setq tsb (if (eq step0 'week) - (- ts (* 86400 (- (nth 6 (decode-time (seconds-to-time ts))) ws))) + (let ((dow (nth 6 (decode-time (seconds-to-time ts))))) + (if (< dow ws) ts + (- ts (* 86400 (- dow ws))))) ts)) (setq p1 (plist-put p1 :header "")) (setq p1 (plist-put p1 :step nil)) @@ -2735,9 +2736,14 @@ LEVEL is an integer. Indent by two spaces per level above 1." (setq p1 (plist-put p1 :tstart (format-time-string (org-time-stamp-format nil t) (seconds-to-time (max tsb ts))))) + (cl-incf tsb (let ((dow (nth 6 (decode-time (seconds-to-time tsb))))) + (if (or (eq step0 'day) + (= dow ws)) + step + (* 86400 (- ws dow))))) (setq p1 (plist-put p1 :tend (format-time-string (org-time-stamp-format nil t) - (seconds-to-time (min te (setq tsb (+ tsb step))))))) + (seconds-to-time (min te tsb))))) (insert "\n" (if (eq step0 'day) "Daily report: " "Weekly report starting on: ") (plist-get p1 :tstart) "\n") @@ -2895,9 +2901,9 @@ Otherwise, return nil." (setq ts (match-string 1) te (match-string 3)) (setq s (- (float-time - (apply #'encode-time (org-parse-time-string te nil t))) + (apply #'encode-time (org-parse-time-string te))) (float-time - (apply #'encode-time (org-parse-time-string ts nil t)))) + (apply #'encode-time (org-parse-time-string ts)))) neg (< s 0) s (abs s) h (floor (/ s 3600)) diff --git a/lisp/org/org-colview.el b/lisp/org/org-colview.el index eac29c50f65..649ca52c4f8 100644 --- a/lisp/org/org-colview.el +++ b/lisp/org/org-colview.el @@ -1070,7 +1070,7 @@ as a canonical duration, i.e., using units defined in (cond ((string-match-p org-ts-regexp s) (/ (- org-columns--time - (float-time (apply #'encode-time (org-parse-time-string s nil t)))) + (float-time (apply #'encode-time (org-parse-time-string s)))) 60)) ((org-duration-p s) (org-duration-to-minutes s t)) ;skip user units (t (user-error "Invalid age: %S" s)))) diff --git a/lisp/org/org-element.el b/lisp/org/org-element.el index f2b3002f1fd..c5f656e09ea 100644 --- a/lisp/org/org-element.el +++ b/lisp/org/org-element.el @@ -1308,23 +1308,19 @@ CONTENTS is the contents of the element." (inlinetask-re (and (featurep 'org-inlinetask) "^\\*+ ")) items struct) (save-excursion - (catch 'exit + (catch :exit (while t (cond ;; At limit: end all items. ((>= (point) limit) - (throw 'exit - (let ((end (progn (skip-chars-backward " \r\t\n") - (forward-line) - (point)))) - (dolist (item items (sort (nconc items struct) - 'car-less-than-car)) - (setcar (nthcdr 6 item) end))))) + (let ((end (progn (skip-chars-backward " \r\t\n") + (line-beginning-position 2)))) + (dolist (item items) (setcar (nthcdr 6 item) end))) + (throw :exit (sort (nconc items struct) #'car-less-than-car))) ;; At list end: end all items. ((looking-at org-list-end-re) - (throw 'exit (dolist (item items (sort (nconc items struct) - 'car-less-than-car)) - (setcar (nthcdr 6 item) (point))))) + (dolist (item items) (setcar (nthcdr 6 item) (point))) + (throw :exit (sort (nconc items struct) #'car-less-than-car))) ;; At a new item: end previous sibling. ((looking-at item-re) (let ((ind (save-excursion (skip-chars-forward " \t") @@ -1348,7 +1344,7 @@ CONTENTS is the contents of the element." ;; Ending position, unknown so far. nil))) items)) - (forward-line 1)) + (forward-line)) ;; Skip empty lines. ((looking-at "^[ \t]*$") (forward-line)) ;; Skip inline tasks and blank lines along the way. @@ -1360,17 +1356,18 @@ CONTENTS is the contents of the element." (goto-char origin))))) ;; At some text line. Check if it ends any previous item. (t - (let ((ind (save-excursion (skip-chars-forward " \t") - (current-column)))) - (when (<= ind top-ind) - (skip-chars-backward " \r\t\n") - (forward-line)) + (let ((ind (save-excursion + (skip-chars-forward " \t") + (current-column))) + (end (save-excursion + (skip-chars-backward " \r\t\n") + (line-beginning-position 2)))) (while (<= ind (nth 1 (car items))) (let ((item (pop items))) - (setcar (nthcdr 6 item) (line-beginning-position)) + (setcar (nthcdr 6 item) end) (push item struct) (unless items - (throw 'exit (sort struct #'car-less-than-car)))))) + (throw :exit (sort struct #'car-less-than-car)))))) ;; Skip blocks (any type) and drawers contents. (cond ((and (looking-at "[ \t]*#\\+BEGIN\\(:\\|_\\S-+\\)") diff --git a/lisp/org/org-feed.el b/lisp/org/org-feed.el index 0119864df9f..cd2e95f7ad2 100644 --- a/lisp/org/org-feed.el +++ b/lisp/org/org-feed.el @@ -624,7 +624,7 @@ containing the properties `:guid' and `:item-full-text'." end (and (re-search-forward "" nil t) (match-beginning 0))) (setq item (buffer-substring beg end) - guid (if (string-match ".*?>\\(.*?\\)" item) + guid (if (string-match ".*?>\\([^\000]*?\\)" item) (xml-substitute-special (match-string-no-properties 1 item)))) (setq entry (list :guid guid :item-full-text item)) (push entry entries) diff --git a/lisp/org/org-gnus.el b/lisp/org/org-gnus.el index 687bc08b16e..26bb8899d3b 100644 --- a/lisp/org/org-gnus.el +++ b/lisp/org/org-gnus.el @@ -31,15 +31,31 @@ ;;; Code: -(require 'org) +(require 'gnus-sum) (require 'gnus-util) +(require 'nnheader) +(require 'nnir) +(require 'org) ;;; Declare external functions and variables +(declare-function gnus-activate-group "gnus-start" (group &optional scan dont-check method dont-sub-check)) +(declare-function gnus-find-method-for-group "gnus" (group &optional info)) +(declare-function gnus-group-group-name "gnus-group") +(declare-function gnus-group-jump-to-group "gnus-group" (group &optional prompt)) +(declare-function gnus-group-read-group "gnus-group" (&optional all no-article group select-articles)) (declare-function message-fetch-field "message" (header &optional not-all)) +(declare-function message-generate-headers "message" (headers)) +(declare-function message-narrow-to-headers "message") +(declare-function message-tokenize-header "message" (header &optional separator)) +(declare-function message-unquote-tokens "message" (elems)) (declare-function nnvirtual-map-article "nnvirtual" (article)) +(defvar gnus-newsgroup-name) +(defvar gnus-summary-buffer) +(defvar gnus-other-frame-object) + ;;; Customization variables @@ -120,9 +136,11 @@ If `org-store-link' was called with a prefix arg the meaning of (let* ((group (pcase (gnus-find-method-for-group gnus-newsgroup-name) (`(nnvirtual . ,_) - (car (nnvirtual-map-article (gnus-summary-article-number)))) + (save-excursion + (car (nnvirtual-map-article (gnus-summary-article-number))))) (`(nnir . ,_) - (nnir-article-group (gnus-summary-article-number))) + (save-excursion + (nnir-article-group (gnus-summary-article-number)))) (_ gnus-newsgroup-name))) (header (with-current-buffer gnus-summary-buffer (gnus-summary-article-header))) diff --git a/lisp/org/org-id.el b/lisp/org/org-id.el index a508e761cb2..09b873c49d4 100644 --- a/lisp/org/org-id.el +++ b/lisp/org/org-id.el @@ -539,8 +539,7 @@ When FILES is given, scan these files instead." (with-temp-buffer (condition-case nil (progn - (insert-file-contents-literally org-id-locations-file) - (goto-char (point-min)) + (insert-file-contents org-id-locations-file) (setq org-id-locations (read (current-buffer)))) (error (message "Could not read org-id-values from %s. Setting it to nil." diff --git a/lisp/org/org-irc.el b/lisp/org/org-irc.el index 5889f6d2fec..3617ae92422 100644 --- a/lisp/org/org-irc.el +++ b/lisp/org/org-irc.el @@ -50,18 +50,20 @@ (require 'org) -;; Declare the function form ERC that we use. +(declare-function erc-buffer-filter "erc" (predicate &optional proc)) +(declare-function erc-channel-p "erc" (channel)) +(declare-function erc-cmd-JOIN "erc" (channel &optional key)) (declare-function erc-current-logfile "erc-log" (&optional buffer)) -(declare-function erc-prompt "erc" ()) (declare-function erc-default-target "erc" ()) -(declare-function erc-channel-p "erc" (channel)) -(declare-function erc-buffer-filter "erc" (predicate &optional proc)) -(declare-function erc-server-buffer "erc" ()) (declare-function erc-get-server-nickname-list "erc" ()) -(declare-function erc-cmd-JOIN "erc" (channel &optional key)) +(declare-function erc-logging-enabled "erc-log" (&optional buffer)) +(declare-function erc-prompt "erc" ()) +(declare-function erc-save-buffer-in-logs "erc-log" (&optional buffer)) +(declare-function erc-server-buffer "erc" ()) (defvar org-irc-client 'erc "The IRC client to act on.") + (defvar org-irc-link-to-logs nil "Non-nil will store a link to the logs, nil will store an irc: style link.") diff --git a/lisp/org/org-list.el b/lisp/org/org-list.el index 8ea569f99c8..5b292d0ca46 100644 --- a/lisp/org/org-list.el +++ b/lisp/org/org-list.el @@ -149,7 +149,7 @@ (declare-function org-remove-indentation "org" (code &optional n)) (declare-function org-show-subtree "org" ()) (declare-function org-sort-remove-invisible "org" (S)) -(declare-function org-time-string-to-seconds "org" (s &optional zone)) +(declare-function org-time-string-to-seconds "org" (s)) (declare-function org-timer-hms-to-secs "org-timer" (hms)) (declare-function org-timer-item "org-timer" (&optional arg)) (declare-function org-trim "org" (s &optional keep-lead)) diff --git a/lisp/org/org-macs.el b/lisp/org/org-macs.el index 1118214c4f1..ff6d8c41d4b 100644 --- a/lisp/org/org-macs.el +++ b/lisp/org/org-macs.el @@ -51,8 +51,8 @@ Otherwise, return nil." SEPARATORS is a regular expression. When nil, it defaults to \"[ \f\t\n\r\v]+\". -Unlike to `split-string', matching SEPARATORS at the beginning -and end of string are ignored." +Unlike `split-string', matching SEPARATORS at the beginning and +end of string are ignored." (let ((separators (or separators "[ \f\t\n\r\v]+"))) (when (string-match (concat "\\`" separators) string) (setq string (replace-match "" nil nil string))) @@ -108,16 +108,15 @@ text properties." (value (if (stringp display) display (cl-some #'stringp display)))) (when value - (apply - #'propertize - ;; Displayed string could contain - ;; invisible parts, but no nested display. - (funcall prune-invisible value) - (plist-put props - 'display - (and (not (stringp display)) - (cl-remove-if #'stringp - display))))))))))) + (apply #'propertize + ;; Displayed string could contain + ;; invisible parts, but no nested + ;; display. + (funcall prune-invisible value) + 'display + (and (not (stringp display)) + (cl-remove-if #'stringp display)) + props)))))))) ;; `display' property overrides `invisible' one. So we first ;; replace characters with `display' property. Then we remove ;; invisible characters. @@ -125,7 +124,7 @@ text properties." (defun org-string-width (string) "Return width of STRING when displayed in the current buffer. -Unlike to `string-width', this function takes into consideration +Unlike `string-width', this function takes into consideration `invisible' and `display' text properties." (string-width (org-string-display string))) diff --git a/lisp/org/org-src.el b/lisp/org/org-src.el index 99d7c6f7fda..4191d9aadcf 100644 --- a/lisp/org/org-src.el +++ b/lisp/org/org-src.el @@ -581,14 +581,15 @@ Escaping happens when a line starts with \"*\", \"#+\", \",*\" or (interactive "r") (save-excursion (goto-char end) - (while (re-search-backward "^[ \t]*,?\\(\\*\\|#\\+\\)" beg t) + (while (re-search-backward "^[ \t]*\\(,*\\(?:\\*\\|#\\+\\)\\)" beg t) (save-excursion (replace-match ",\\1" nil nil nil 1))))) (defun org-escape-code-in-string (s) "Escape lines in string S. Escaping happens when a line starts with \"*\", \"#+\", \",*\" or \",#+\" by appending a comma to it." - (replace-regexp-in-string "^[ \t]*,?\\(\\*\\|#\\+\\)" ",\\1" s nil nil 1)) + (replace-regexp-in-string "^[ \t]*\\(,*\\(?:\\*\\|#\\+\\)\\)" ",\\1" + s nil nil 1)) (defun org-unescape-code-in-region (beg end) "Un-escape lines between BEG and END. @@ -597,7 +598,7 @@ with \",*\", \",#+\", \",,*\" and \",,#+\"." (interactive "r") (save-excursion (goto-char end) - (while (re-search-backward "^[ \t]*,?\\(,\\)\\(?:\\*\\|#\\+\\)" beg t) + (while (re-search-backward "^[ \t]*,*\\(,\\)\\(?:\\*\\|#\\+\\)" beg t) (save-excursion (replace-match "" nil nil nil 1))))) (defun org-unescape-code-in-string (s) @@ -605,7 +606,7 @@ with \",*\", \",#+\", \",,*\" and \",,#+\"." Un-escaping happens by removing the first comma on lines starting with \",*\", \",#+\", \",,*\" and \",,#+\"." (replace-regexp-in-string - "^[ \t]*,?\\(,\\)\\(?:\\*\\|#\\+\\)" "" s nil nil 1)) + "^[ \t]*,*\\(,\\)\\(?:\\*\\|#\\+\\)" "" s nil nil 1)) diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index 8dc648eaecd..6ebd6da9d0a 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -1087,22 +1087,18 @@ Before doing so, re-align the table if necessary." (interactive) (org-table-maybe-eval-formula) (org-table-maybe-recalculate-line) - (if (or (looking-at "[ \t]*$") - (save-excursion (skip-chars-backward " \t") (bolp))) - (newline) - (if (and org-table-automatic-realign - org-table-may-need-update) - (org-table-align)) - (let ((col (org-table-current-column))) - (beginning-of-line 2) - (if (or (not (org-at-table-p)) + (if (and org-table-automatic-realign + org-table-may-need-update) + (org-table-align)) + (let ((col (org-table-current-column))) + (beginning-of-line 2) + (when (or (not (org-at-table-p)) (org-at-table-hline-p)) - (progn - (beginning-of-line 0) - (org-table-insert-row 'below))) - (org-table-goto-column col) - (skip-chars-backward "^|\n\r") - (if (looking-at " ") (forward-char 1))))) + (beginning-of-line 0) + (org-table-insert-row 'below)) + (org-table-goto-column col) + (skip-chars-backward "^|\n\r") + (when (looking-at " ") (forward-char)))) ;;;###autoload (defun org-table-copy-down (n) @@ -3242,7 +3238,7 @@ existing formula for column %s" (goto-char beg) ;; Mark named fields untouchable. Also check if several ;; field/range formulas try to set the same field. - (remove-text-properties beg end '(org-untouchable t)) + (remove-text-properties beg end '(:org-untouchable t)) (let ((current-line (count-lines org-table-current-begin-pos (line-beginning-position))) seen-fields) diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el index 30318ba92c8..749cbe063e8 100644 --- a/lisp/org/org-version.el +++ b/lisp/org/org-version.el @@ -5,13 +5,13 @@ (defun org-release () "The release version of Org. Inserted by installing Org mode or when a release is made." - (let ((org-release "9.1.2")) + (let ((org-release "9.1.4")) org-release)) ;;;###autoload (defun org-git-version () "The Git version of org-mode. Inserted by installing Org or when a release is made." - (let ((org-git-version "release_9.1.2-40-g6ca906")) + (let ((org-git-version "release_9.1.4-44-gfe7310")) org-git-version)) (provide 'org-version) diff --git a/lisp/org/org.el b/lisp/org/org.el index 35405b4bf81..07727f68c40 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -182,7 +182,8 @@ Stars are put in group 1 and the trimmed body in group 2.") (declare-function org-export-get-environment "ox" (&optional backend subtreep ext-plist)) (declare-function org-latex-make-preamble "ox-latex" (info &optional template snippet?)) -(defvar ffap-url-regexp) ;Silence byte-compiler +(defvar ffap-url-regexp) +(defvar org-element-paragraph-separate) (defsubst org-uniquify (list) "Non-destructively remove duplicate elements from LIST." @@ -1284,7 +1285,7 @@ star at the beginning of the headline, you can do this: This list will be checked before `org-speed-commands-default' when the variable `org-use-speed-commands' is non-nil and when the cursor is at the beginning of a headline. -The car if each entry is a string with a single letter, which must +The car of each entry is a string with a single letter, which must be assigned to `self-insert-command' in the global map. The cdr is either a command to be called interactively, a function to be called, or a form to be evaluated. @@ -5290,7 +5291,8 @@ is available. This option applies only if FILE is a URL." ;; Move point to after the url-retrieve header. (search-forward "\n\n" nil :move) ;; Search for the success code only in the url-retrieve header. - (if (save-excursion (re-search-backward "HTTP.*\\s-+200\\s-OK" nil :noerror)) + (if (save-excursion + (re-search-backward "HTTP.*\\s-+200\\s-OK" nil :noerror)) ;; Update the cache `org--file-cache' and return contents. (puthash file (buffer-substring-no-properties (point) (point-max)) @@ -5300,13 +5302,14 @@ is available. This option applies only if FILE is a URL." file)))) (t (with-temp-buffer - (condition-case err + (condition-case nil (progn (insert-file-contents file) (buffer-string)) (file-error (funcall (if noerror #'message #'user-error) - (error-message-string err))))))))) + "Unable to read file %S" + file)))))))) (defun org-extract-log-state-settings (x) "Extract the log state setting from a TODO keyword string. @@ -5750,18 +5753,27 @@ This should be called after the variable `org-link-parameters' has changed." (verbatim? (member marker '("~" "=")))) (when (save-excursion (goto-char (match-beginning 0)) - ;; Do not match headline stars. Do not consider - ;; stars of a headline as closing marker for bold - ;; markup either. Do not match table hlines. (and - (not (looking-at-p org-outline-regexp-bol)) + ;; Do not match table hlines. (not (and (equal marker "+") (org-match-line - "^[ \t]*\\(|[-+]+|?\\|\\+[-+]+\\+\\)[ \t]*$"))) + "[ \t]*\\(|[-+]+|?\\|\\+[-+]+\\+\\)[ \t]*$"))) + ;; Do not match headline stars. Do not consider + ;; stars of a headline as closing marker for bold + ;; markup either. + (not (and (equal marker "*") + (save-excursion + (forward-char) + (skip-chars-backward "*") + (looking-at-p org-outline-regexp-bol)))) + ;; Match full emphasis markup regexp. (looking-at (if verbatim? org-verbatim-re org-emph-re)) - (not (string-match-p - (concat org-outline-regexp-bol "\\'") - (match-string 0))))) + ;; Do not span over paragraph boundaries. + (not (string-match-p org-element-paragraph-separate + (match-string 2))) + ;; Do not span over cells in table rows. + (not (and (save-match-data (org-match-line "[ \t]*|")) + (string-match-p "|" (match-string 4)))))) (pcase-let ((`(,_ ,face ,_) (assoc marker org-emphasis-alist))) (font-lock-prepend-text-property (match-beginning 2) (match-end 2) 'face face) @@ -7945,8 +7957,7 @@ unchecked check box." (org-insert-heading (or (and (equal arg '(16)) '(16)) force-heading)) (save-excursion - (org-back-to-heading) - (outline-previous-heading) + (org-forward-heading-same-level -1) (let ((case-fold-search nil)) (looking-at org-todo-line-regexp))) (let* ((new-mark-x (if (or (equal arg '(4)) @@ -9636,28 +9647,37 @@ active region." (move-beginning-of-line 2) (set-mark (point))))) (setq org-store-link-plist nil) - (let (link cpltxt desc description search - txt custom-id agenda-link sfuns sfunsn) + (let (link cpltxt desc description search txt custom-id agenda-link) (cond - - ;; Store a link using an external link type + ;; Store a link using an external link type, if any function is + ;; available. If more than one can generate a link from current + ;; location, ask which one to use. ((and (not (equal arg '(16))) - (setq sfuns - (delq - nil (mapcar (lambda (f) - (let (fs) (if (funcall f) (push f fs)))) - (org-store-link-functions))) - sfunsn (mapcar (lambda (fu) (symbol-name (car fu))) sfuns)) - (or (and (cdr sfuns) - (funcall (intern - (completing-read - "Which function for creating the link? " - sfunsn nil t (car sfunsn))))) - (funcall (caar sfuns))) - (setq link (plist-get org-store-link-plist :link) - desc (or (plist-get org-store-link-plist - :description) - link)))) + (let ((results-alist nil)) + (dolist (f (org-store-link-functions)) + (when (funcall f) + ;; XXX: return value is not link's plist, so we + ;; store the new value before it is modified. It + ;; would be cleaner to ask store link functions to + ;; return the plist instead. + (push (cons f (copy-sequence org-store-link-plist)) + results-alist))) + (pcase results-alist + (`nil nil) + (`((,_ . ,_)) t) ;single choice: nothing to do + (`((,name . ,_) . ,_) + ;; Reinstate link plist associated to the chosen + ;; function. + (apply #'org-store-link-props + (cdr (assoc-string + (completing-read + "Which function for creating the link? " + (mapcar #'car results-alist) nil t name) + results-alist))) + t)))) + (setq link (plist-get org-store-link-plist :link)) + (setq desc (or (plist-get org-store-link-plist :description) + link))) ;; Store a link from a source code buffer. ((org-src-edit-buffer-p) @@ -9845,7 +9865,9 @@ active region." (car org-stored-links))))) (defun org-store-link-props (&rest plist) - "Store link properties, extract names, addresses and dates." + "Store link properties. +The properties are pre-processed by extracting names, addresses +and dates." (let ((x (plist-get plist :from))) (when x (let ((adr (mail-extract-address-components x))) @@ -14610,7 +14632,7 @@ it as a time string and apply `float-time' to it. If S is nil, just return 0." ((numberp s) s) ((stringp s) (condition-case nil - (float-time (apply #'encode-time (org-parse-time-string s nil t))) + (float-time (apply #'encode-time (org-parse-time-string s))) (error 0.))) (t 0.))) @@ -17369,8 +17391,8 @@ both scheduled and deadline timestamps." 'timestamp) (org-at-planning-p)) (time-less-p - (org-time-string-to-time match t) - (org-time-string-to-time d t))))))) + (org-time-string-to-time match) + (org-time-string-to-time d))))))) (message "%d entries before %s" (org-occur regexp nil callback) d))) @@ -17391,8 +17413,8 @@ both scheduled and deadline timestamps." 'timestamp) (org-at-planning-p)) (not (time-less-p - (org-time-string-to-time match t) - (org-time-string-to-time d t)))))))) + (org-time-string-to-time match) + (org-time-string-to-time d)))))))) (message "%d entries after %s" (org-occur regexp nil callback) d))) @@ -17415,11 +17437,11 @@ both scheduled and deadline timestamps." 'timestamp) (org-at-planning-p)) (not (time-less-p - (org-time-string-to-time match t) - (org-time-string-to-time start-date t))) + (org-time-string-to-time match) + (org-time-string-to-time start-date))) (time-less-p - (org-time-string-to-time match t) - (org-time-string-to-time end-date t)))))))) + (org-time-string-to-time match) + (org-time-string-to-time end-date)))))))) (message "%d entries between %s and %s" (org-occur regexp nil callback) start-date end-date))) @@ -17504,19 +17526,13 @@ days in order to avoid rounding problems." (push m l)) (apply 'format fmt (nreverse l)))) -(defun org-time-string-to-time (s &optional zone) - "Convert timestamp string S into internal time. -The optional ZONE is omitted or nil for Emacs local time, t for -Universal Time, ‘wall’ for system wall clock time, or a string as -in the TZ environment variable." - (apply #'encode-time (org-parse-time-string s nil zone))) +(defun org-time-string-to-time (s) + "Convert timestamp string S into internal time." + (apply #'encode-time (org-parse-time-string s))) -(defun org-time-string-to-seconds (s &optional zone) - "Convert a timestamp string S into a number of seconds. -The optional ZONE is omitted or nil for Emacs local time, t for -Universal Time, ‘wall’ for system wall clock time, or a string as -in the TZ environment variable." - (float-time (org-time-string-to-time s zone))) +(defun org-time-string-to-seconds (s) + "Convert a timestamp string S into a number of seconds." + (float-time (org-time-string-to-time s))) (org-define-error 'org-diary-sexp-no-match "Unable to match diary sexp") @@ -17733,17 +17749,13 @@ day number." (list (nth 4 d) (nth 3 d) (nth 5 d)))) ((listp d) (list (nth 4 d) (nth 3 d) (nth 5 d))))) -(defun org-parse-time-string (s &optional nodefault zone) +(defun org-parse-time-string (s &optional nodefault) "Parse the standard Org time string. This should be a lot faster than the normal `parse-time-string'. If time is not given, defaults to 0:00. However, with optional -NODEFAULT, hour and minute fields will be nil if not given. - -The optional ZONE is omitted or nil for Emacs local time, t for -Universal Time, ‘wall’ for system wall clock time, or a string as -in the TZ environment variable." +NODEFAULT, hour and minute fields will be nil if not given." (cond ((string-match org-ts-regexp0 s) (list 0 (when (or (match-beginning 8) (not nodefault)) @@ -17753,7 +17765,7 @@ in the TZ environment variable." (string-to-number (match-string 4 s)) (string-to-number (match-string 3 s)) (string-to-number (match-string 2 s)) - nil nil zone)) + nil nil nil)) ((string-match "^<[^>]+>$" s) ;; FIXME: `decode-time' needs to be called with ZONE as its ;; second argument. However, this requires at least Emacs @@ -19327,9 +19339,9 @@ boundaries." ;; "file:" links. Also check link abbreviations since ;; some might expand to "file" links. (file-types-re (format "[][]\\[\\(?:file\\|[./~]%s\\)" - (and link-abbrevs - (format "\\|\\(?:%s:\\)" - (regexp-opt link-abbrevs)))))) + (if (not link-abbrevs) "" + (format "\\|\\(?:%s:\\)" + (regexp-opt link-abbrevs)))))) (while (re-search-forward file-types-re end t) (let ((link (save-match-data (org-element-context)))) ;; Check if we're at an inline image, i.e., an image file @@ -20782,8 +20794,8 @@ This command does many different things, depending on context: '(babel-call clock dynamic-block footnote-definition footnote-reference inline-babel-call inline-src-block inlinetask item keyword node-property paragraph - plain-list property-drawer radio-target src-block - statistics-cookie table table-cell table-row + plain-list planning property-drawer radio-target + src-block statistics-cookie table table-cell table-row timestamp) t)) (type (org-element-type context))) @@ -20935,7 +20947,8 @@ Use `\\[org-edit-special]' to edit table.el tables")) (cond (arg (call-interactively #'org-table-recalculate)) ((org-table-maybe-recalculate-line)) (t (org-table-align)))))) - (`timestamp (org-timestamp-change 0 'day)) + ((or `timestamp (and `planning (guard (org-at-timestamp-p 'lax)))) + (org-timestamp-change 0 'day)) ((and `nil (guard (org-at-heading-p))) ;; When point is on an unsupported object type, we can miss ;; the fact that it also is at a heading. Handle it here. @@ -21027,13 +21040,17 @@ object (e.g., within a comment). In these case, you need to use (let ((context (if org-return-follows-link (org-element-context) (org-element-at-point)))) (cond - ;; In a table, call `org-table-next-row'. + ;; In a table, call `org-table-next-row'. However, before first + ;; column or after last one, split the table. ((or (and (eq (org-element-type context) 'table) (>= (point) (org-element-property :contents-begin context)) (< (point) (org-element-property :contents-end context))) (org-element-lineage context '(table-row table-cell) t)) - (org-table-justify-field-maybe) - (call-interactively #'org-table-next-row)) + (if (or (looking-at-p "[ \t]*$") + (save-excursion (skip-chars-backward " \t") (bolp))) + (insert "\n") + (org-table-justify-field-maybe) + (call-interactively #'org-table-next-row))) ;; On a link or a timestamp, call `org-open-at-point' if ;; `org-return-follows-link' allows it. Tolerate fuzzy ;; locations, e.g., in a comment, as `org-open-at-point'. @@ -21374,7 +21391,7 @@ an argument, unconditionally call `org-insert-heading'." ["Next keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-at-heading-p))] ["Previous keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-at-heading-p))]) ["Show TODO Tree" org-show-todo-tree :active t :keys "C-c / t"] - ["Global TODO list" org-todo-list :active t :keys "C-c a t"] + ["Global TODO list" org-todo-list :active t :keys "\\[org-agenda] t"] "--" ["Enforce dependencies" (customize-variable 'org-enforce-todo-dependencies) :selected org-enforce-todo-dependencies :style toggle :active t] @@ -21453,8 +21470,8 @@ an argument, unconditionally call `org-insert-heading'." "--" ["Export/Publish..." org-export-dispatch t] ("LaTeX" - ["Org CDLaTeX mode" org-cdlatex-mode :style toggle - :selected org-cdlatex-mode] + ["Org CDLaTeX mode" org-cdlatex-mode :active (require 'cdlatex nil t) + :style toggle :selected org-cdlatex-mode] ["Insert Environment" cdlatex-environment (fboundp 'cdlatex-environment)] ["Insert math symbol" cdlatex-math-symbol (fboundp 'cdlatex-math-symbol)] ["Modify math symbol" org-cdlatex-math-modify @@ -21464,7 +21481,7 @@ an argument, unconditionally call `org-insert-heading'." ("MobileOrg" ["Push Files and Views" org-mobile-push t] ["Get Captured and Flagged" org-mobile-pull t] - ["Find FLAGGED Tasks" (org-agenda nil "?") :active t :keys "C-c a ?"] + ["Find FLAGGED Tasks" (org-agenda nil "?") :active t :keys "\\[org-agenda] ?"] "--" ["Setup" (progn (require 'org-mobile) (customize-group 'org-mobile)) t]) "--" @@ -21568,7 +21585,9 @@ Your bug report will be posted to the Org mailing list. ["Cycle through agenda files" org-cycle-agenda-files t] ["Occur in all agenda files" org-occur-in-agenda-files t] "--") - (mapcar 'org-file-menu-entry (org-agenda-files t)))))))) + (mapcar 'org-file-menu-entry + ;; Prevent initialization from failing. + (ignore-errors (org-agenda-files t))))))))) ;;;; Documentation @@ -22764,7 +22783,6 @@ assumed to be significant there." ;; `org-setup-filling' installs filling and auto-filling related ;; variables during `org-mode' initialization. -(defvar org-element-paragraph-separate) ; org-element.el (defun org-setup-filling () (require 'org-element) ;; Prevent auto-fill from inserting unwanted new items. @@ -23617,7 +23635,9 @@ depending on context." (skip-chars-forward " \r\t\n")))) (narrow-to-region (org-element-property :contents-begin element) contents-end)) - (call-interactively #'forward-sentence)))))) + ;; End of heading is considered as the end of a sentence. + (let ((sentence-end (concat (sentence-end) "\\|^\\*+ .*$"))) + (call-interactively #'forward-sentence))))))) (define-key org-mode-map "\M-a" 'org-backward-sentence) (define-key org-mode-map "\M-e" 'org-forward-sentence) @@ -24230,10 +24250,11 @@ convenience: (backward-char) (org-backward-paragraph)) ((<= (point) post-affiliated) (goto-char begin)) + ;; Special behavior: on a table or a property drawer, move to + ;; its beginning. ((memq type '(node-property table-row)) (goto-char (org-element-property :post-affiliated (org-element-property :parent element)))) - ((memq type '(property-drawer table)) (goto-char begin)) (special? (if (<= (point) contents-begin) (goto-char post-affiliated) ;; Inside a verse block, see blank lines as paragraph @@ -24244,8 +24265,7 @@ convenience: (skip-chars-forward " \r\t\n" origin) (if (= (point) origin) (goto-char contents-begin) (beginning-of-line)))))) - ((eq type 'paragraph) - (goto-char contents-begin) + ((eq type 'paragraph) (goto-char contents-begin) ;; When at first paragraph in an item or a footnote definition, ;; move directly to beginning of line. (let ((parent-contents @@ -24253,9 +24273,9 @@ convenience: :contents-begin (org-element-property :parent element)))) (when (and parent-contents (= parent-contents contents-begin)) (beginning-of-line)))) - ;; At the end of a greater element, move to the beginning of the - ;; last element within. - ((>= (point) contents-end) + ;; At the end of a greater element, move to the beginning of + ;; the last element within. + ((and contents-end (>= (point) contents-end)) (goto-char (1- contents-end)) (org-backward-paragraph)) (t (goto-char (or post-affiliated begin)))) diff --git a/lisp/org/ox-ascii.el b/lisp/org/ox-ascii.el index 9e04387d9a2..e83eb197a82 100644 --- a/lisp/org/ox-ascii.el +++ b/lisp/org/ox-ascii.el @@ -177,7 +177,8 @@ Inner margin is applied between each headline." (defcustom org-ascii-quote-margin 6 "Width of margin used for quoting text, in characters. -This margin is applied on both sides of the text." +This margin is applied on both sides of the text. It is also +applied on the left side of contents in descriptive lists." :group 'org-export-ascii :version "24.4" :package-version '(Org . "8.0") @@ -551,79 +552,69 @@ INFO is a plist used as a communication channel." (`inlinetask (plist-get info :ascii-inlinetask-width)) (`headline (- (plist-get info :ascii-text-width) - (let ((low-level-rank (org-export-low-level-p element info))) - (if low-level-rank (* low-level-rank 2) - (plist-get info :ascii-global-margin))))) + (let ((low-level-rank (org-export-low-level-p element info))) + (if low-level-rank (* low-level-rank 2) + (plist-get info :ascii-global-margin))))) ;; Elements with a relative width: store maximum text width in ;; TOTAL-WIDTH. (_ (let* ((genealogy (org-element-lineage element nil t)) - ;; Total width is determined by the presence, or not, of an - ;; inline task among ELEMENT parents. - (total-width - (if (cl-some (lambda (parent) - (eq (org-element-type parent) 'inlinetask)) - genealogy) - (plist-get info :ascii-inlinetask-width) - ;; No inlinetask: Remove global margin from text width. - (- (plist-get info :ascii-text-width) - (plist-get info :ascii-global-margin) - (let ((parent (org-export-get-parent-headline element))) - ;; Inner margin doesn't apply to text before first - ;; headline. - (if (not parent) 0 - (let ((low-level-rank - (org-export-low-level-p parent info))) - ;; Inner margin doesn't apply to contents of - ;; low level headlines, since they've got their - ;; own indentation mechanism. - (if low-level-rank (* low-level-rank 2) - (plist-get info :ascii-inner-margin))))))))) + ;; Total width is determined by the presence, or not, of an + ;; inline task among ELEMENT parents. + (total-width + (if (cl-some (lambda (parent) + (eq (org-element-type parent) 'inlinetask)) + genealogy) + (plist-get info :ascii-inlinetask-width) + ;; No inlinetask: Remove global margin from text width. + (- (plist-get info :ascii-text-width) + (plist-get info :ascii-global-margin) + (let ((parent (org-export-get-parent-headline element))) + ;; Inner margin doesn't apply to text before first + ;; headline. + (if (not parent) 0 + (let ((low-level-rank + (org-export-low-level-p parent info))) + ;; Inner margin doesn't apply to contents of + ;; low level headlines, since they've got their + ;; own indentation mechanism. + (if low-level-rank (* low-level-rank 2) + (plist-get info :ascii-inner-margin))))))))) (- total-width - ;; Each `quote-block' and `verse-block' above narrows text - ;; width by twice the standard margin size. - (+ (* (cl-count-if (lambda (parent) - (memq (org-element-type parent) - '(quote-block verse-block))) - genealogy) - 2 - (plist-get info :ascii-quote-margin)) - ;; Apply list margin once per "top-level" plain-list - ;; containing current line - (* (cl-count-if - (lambda (e) - (and (eq (org-element-type e) 'plain-list) - (not (eq (org-element-type (org-export-get-parent e)) - 'item)))) - genealogy) - (plist-get info :ascii-list-margin)) - ;; Text width within a plain-list is restricted by - ;; indentation of current item. If that's the case, - ;; compute it with the help of `:structure' property from - ;; parent item, if any. - (let ((item - (if (eq (org-element-type element) 'item) element - (cl-find-if (lambda (parent) - (eq (org-element-type parent) 'item)) - genealogy)))) - (if (not item) 0 - ;; Compute indentation offset of the current item, - ;; that is the sum of the difference between its - ;; indentation and the indentation of the top item in - ;; the list and current item bullet's length. Also - ;; remove checkbox length, and tag length (for - ;; description lists) or bullet length. - (let ((struct (org-element-property :structure item)) - (beg-item (org-element-property :begin item))) - (+ (- (org-list-get-ind beg-item struct) - (org-list-get-ind - (org-list-get-top-point struct) struct)) - (string-width (or (org-ascii--checkbox item info) - "")) - (string-width - (let ((tag (org-element-property :tag item))) - (if tag (org-export-data tag info) - (org-element-property :bullet item)))))))))))))) + ;; Each `quote-block' and `verse-block' above narrows text + ;; width by twice the standard margin size. + (+ (* (cl-count-if (lambda (parent) + (memq (org-element-type parent) + '(quote-block verse-block))) + genealogy) + 2 + (plist-get info :ascii-quote-margin)) + ;; Apply list margin once per "top-level" plain-list + ;; containing current line + (* (cl-count-if + (lambda (e) + (and (eq (org-element-type e) 'plain-list) + (not (eq (org-element-type (org-export-get-parent e)) + 'item)))) + genealogy) + (plist-get info :ascii-list-margin)) + ;; Compute indentation offset due to current list. It is + ;; `org-ascii-quote-margin' per descriptive item in the + ;; genealogy, bullet's length otherwise. + (let ((indentation 0)) + (dolist (e genealogy) + (cond + ((not (eq 'item (org-element-type e)))) + ((eq (org-element-property :type (org-export-get-parent e)) + 'descriptive) + (cl-incf indentation org-ascii-quote-margin)) + (t + (cl-incf indentation + (+ (string-width + (or (org-ascii--checkbox e info) "")) + (string-width + (org-element-property :bullet e))))))) + indentation))))))) (defun org-ascii--current-justification (element) "Return expected justification for ELEMENT's contents. @@ -1458,40 +1449,54 @@ contextual information." (bullet ;; First parent of ITEM is always the plain-list. Get ;; `:type' property from it. - (org-list-bullet-string - (pcase list-type - (`descriptive - (concat checkbox - (org-export-data (org-element-property :tag item) info) - ": ")) - (`ordered - ;; Return correct number for ITEM, paying attention to - ;; counters. - (let* ((struct (org-element-property :structure item)) - (bul (org-element-property :bullet item)) - (num (number-to-string - (car (last (org-list-get-item-number - (org-element-property :begin item) - struct - (org-list-prevs-alist struct) - (org-list-parents-alist struct))))))) - (replace-regexp-in-string "[0-9]+" num bul))) - (_ (let ((bul (org-element-property :bullet item))) - ;; Change bullets into more visible form if UTF-8 is active. - (if (not utf8p) bul + (pcase list-type + (`descriptive + (concat checkbox + (org-export-data (org-element-property :tag item) + info))) + (`ordered + ;; Return correct number for ITEM, paying attention to + ;; counters. + (let* ((struct (org-element-property :structure item)) + (bul (org-list-bullet-string + (org-element-property :bullet item))) + (num (number-to-string + (car (last (org-list-get-item-number + (org-element-property :begin item) + struct + (org-list-prevs-alist struct) + (org-list-parents-alist struct))))))) + (replace-regexp-in-string "[0-9]+" num bul))) + (_ (let ((bul (org-list-bullet-string + (org-element-property :bullet item)))) + ;; Change bullets into more visible form if UTF-8 is active. + (if (not utf8p) bul + (replace-regexp-in-string + "-" "•" (replace-regexp-in-string - "-" "•" - (replace-regexp-in-string - "+" "⁃" - (replace-regexp-in-string "*" "‣" bul)))))))))) + "+" "⁃" + (replace-regexp-in-string "*" "‣" bul)))))))) + (indentation (if (eq list-type 'descriptive) org-ascii-quote-margin + (string-width bullet)))) (concat bullet - (unless (eq list-type 'descriptive) checkbox) + checkbox ;; Contents: Pay attention to indentation. Note: check-boxes are ;; already taken care of at the paragraph level so they don't ;; interfere with indentation. - (let ((contents (org-ascii--indent-string contents (string-width bullet)))) - (if (eq (org-element-type (car (org-element-contents item))) 'paragraph) + (let ((contents (org-ascii--indent-string contents indentation))) + ;; Determine if contents should follow the bullet or start + ;; a new line. Do the former when the first contributing + ;; element to contents is a paragraph. In descriptive lists + ;; however, contents always start a new line. + (if (and (not (eq list-type 'descriptive)) + (org-string-nw-p contents) + (eq 'paragraph + (org-element-type + (cl-some (lambda (e) + (and (org-string-nw-p (org-export-data e info)) + e)) + (org-element-contents item))))) (org-trim contents) (concat "\n" contents)))))) diff --git a/lisp/org/ox-html.el b/lisp/org/ox-html.el index 8ce4fb6adcd..bf08de10af7 100644 --- a/lisp/org/ox-html.el +++ b/lisp/org/ox-html.el @@ -2154,21 +2154,17 @@ CODE is a string representing the source code to colorize. LANG is the language used for CODE, as a string, or nil." (when code (cond - ;; Case 1: No lang. Possibly an example block. - ((not lang) - ;; Simple transcoding. - (org-html-encode-plain-text code)) - ;; Case 2: No htmlize or an inferior version of htmlize + ;; No language. Possibly an example block. + ((not lang) (org-html-encode-plain-text code)) + ;; Plain text explicitly set. + ((not org-html-htmlize-output-type) (org-html-encode-plain-text code)) + ;; No htmlize library or an inferior version of htmlize. ((not (and (or (require 'htmlize nil t) - (error "Please install htmlize from https://github.com/hniksic/emacs-htmlize")) + (error "Please install htmlize from \ +https://github.com/hniksic/emacs-htmlize")) (fboundp 'htmlize-region-for-paste))) ;; Emit a warning. (message "Cannot fontify src block (htmlize.el >= 1.34 required)") - ;; Simple transcoding. - (org-html-encode-plain-text code)) - ;; Case 3: plain text explicitly set - ((not org-html-htmlize-output-type) - ;; Simple transcoding. (org-html-encode-plain-text code)) (t ;; Map language @@ -2177,7 +2173,6 @@ is the language used for CODE, as a string, or nil." (cond ;; Case 1: Language is not associated with any Emacs mode ((not (functionp lang-mode)) - ;; Simple transcoding. (org-html-encode-plain-text code)) ;; Case 2: Default. Fontify code. (t @@ -2207,7 +2202,7 @@ is the language used for CODE, as a string, or nil." (org-html-htmlize-region-for-paste (point-min) (point-max)))))) ;; Strip any enclosing
 tags.
-	  (let* ((beg (and (string-match "\\`]*>\n*" code) (match-end 0)))
+	  (let* ((beg (and (string-match "\\`]*>\n?" code) (match-end 0)))
 		 (end (and beg (string-match "\\'" code))))
 	    (if (and beg end) (substring code beg end) code)))))))))
 
@@ -2220,7 +2215,7 @@ alist between line numbers and references (as returned by
 `org-export-unravel-code'), a boolean specifying if labels should
 appear in the source code, and the number associated to the first
 line of code."
-  (let* ((code-lines (org-split-string code "\n"))
+  (let* ((code-lines (split-string code "\n"))
 	 (code-length (length code-lines))
 	 (num-fmt
 	  (and num-start
@@ -2328,15 +2323,7 @@ INFO is a plist used as a communication channel."
 			(org-element-property :priority headline)))
 	 (text (org-export-data-with-backend
 		(org-export-get-alt-title headline info)
-		;; Create an anonymous back-end that will ignore any
-		;; footnote-reference, link, radio-target and target
-		;; in table of contents.
-		(org-export-create-backend
-		 :parent 'html
-		 :transcoders '((footnote-reference . ignore)
-				(link . (lambda (object c i) c))
-				(radio-target . (lambda (object c i) c))
-				(target . ignore)))
+		(org-export-toc-entry-backend 'html)
 		info))
 	 (tags (and (eq (plist-get info :with-tags) t)
 		    (org-export-get-tags headline info))))
@@ -2966,10 +2953,7 @@ images, set it to:
 DESC is the description part of the link, or the empty string.
 INFO is a plist holding contextual information.  See
 `org-export-data'."
-  (let* ((home (when (plist-get info :html-link-home)
-		 (org-trim (plist-get info :html-link-home))))
-	 (use-abs-url (plist-get info :html-link-use-abs-url))
-	 (link-org-files-as-html-maybe
+  (let* ((link-org-files-as-html-maybe
 	  (lambda (raw-path info)
 	    ;; Treat links to `file.org' as links to `file.html', if
 	    ;; needed.  See `org-html-link-org-files-as-html'.
@@ -2989,16 +2973,22 @@ INFO is a plist holding contextual information.  See
 	   ((member type '("http" "https" "ftp" "mailto" "news"))
 	    (url-encode-url (org-link-unescape (concat type ":" raw-path))))
 	   ((string= type "file")
-	    ;; Treat links to ".org" files as ".html", if needed.
+	    ;; During publishing, turn absolute file names belonging
+	    ;; to base directory into relative file names.  Otherwise,
+	    ;; append "file" protocol to absolute file name.
 	    (setq raw-path
-		  (funcall link-org-files-as-html-maybe raw-path info))
-	    ;; If file path is absolute, prepend it with protocol
-	    ;; component - "file://".
-	    (cond
-	     ((file-name-absolute-p raw-path)
-	      (setq raw-path (org-export-file-uri raw-path)))
-	     ((and home use-abs-url)
-	      (setq raw-path (concat (file-name-as-directory home) raw-path))))
+		  (org-export-file-uri
+		   (org-publish-file-relative-name raw-path info)))
+	    ;; Possibly append `:html-link-home' to relative file
+	    ;; name.
+	    (let ((home (and (plist-get info :html-link-home)
+			     (org-trim (plist-get info :html-link-home)))))
+	      (when (and home
+			 (plist-get info :html-link-use-abs-url)
+			 (file-name-absolute-p raw-path))
+		(setq raw-path (concat (file-name-as-directory home) raw-path))))
+	    ;; Maybe turn ".org" into ".html".
+	    (setq raw-path (funcall link-org-files-as-html-maybe raw-path info))
 	    ;; Add search option, if any.  A search option can be
 	    ;; relative to a custom-id, a headline title, a name or
 	    ;; a target.
diff --git a/lisp/org/ox-man.el b/lisp/org/ox-man.el
index fb8f7be087f..6fb3041d587 100644
--- a/lisp/org/ox-man.el
+++ b/lisp/org/ox-man.el
@@ -285,6 +285,10 @@ This function shouldn't be used for floats.  See
         output
       (concat (format "%s\n.br\n" label) output))))
 
+(defun org-man--protect-text (text)
+  "Protect minus and backslash characters in string TEXT."
+  (replace-regexp-in-string "-" "\\-" text nil t))
+
 
 
 ;;; Template
@@ -350,10 +354,9 @@ holding contextual information."
 ;;; Code
 
 (defun org-man-code (code _contents _info)
-  "Transcode a CODE object from Org to Man.
-CONTENTS is nil.  INFO is a plist used as a communication
-channel."
-  (format "\\fC%s\\fP" code))
+  "Transcode a CODE object from Org to Man."
+  (format "\\fC%s\\fP"
+	  (org-man--protect-text (org-element-property :value code))))
 
 
 ;;; Drawer
@@ -1029,11 +1032,10 @@ holding contextual information."
 
 ;;; Verbatim
 
-(defun org-man-verbatim (_verbatim contents _info)
-  "Transcode a VERBATIM object from Org to Man.
-CONTENTS is nil.  INFO is a plist used as a communication
-channel."
-  (format ".nf\n%s\n.fi" contents))
+(defun org-man-verbatim (verbatim _contents _info)
+  "Transcode a VERBATIM object from Org to Man."
+  (format "\\fI%s\\fP"
+	  (org-man--protect-text (org-element-property :value verbatim))))
 
 
 ;;; Verse Block
diff --git a/lisp/org/ox-md.el b/lisp/org/ox-md.el
index 5ba52e7faf3..12188387355 100644
--- a/lisp/org/ox-md.el
+++ b/lisp/org/ox-md.el
@@ -240,7 +240,7 @@ a communication channel."
 		    (format ""
 			    (or (org-element-property :CUSTOM_ID headline)
 				(org-export-get-reference headline info))))))
-	  (concat (org-md--headline-title style level title anchor tags)
+	  (concat (org-md--headline-title style level heading anchor tags)
 		  contents)))))))
 
 
@@ -582,16 +582,7 @@ contents according to the current headline."
 	      (format "[%s](#%s)"
 		      (org-export-data-with-backend
 		       (org-export-get-alt-title headline info)
-		       ;; Create an anonymous back-end that will
-		       ;; ignore any footnote-reference, link,
-		       ;; radio-target and target in table of
-		       ;; contents.
-		       (org-export-create-backend
-			:parent 'md
-			:transcoders '((footnote-reference . ignore)
-				       (link . (lambda (object c i) c))
-				       (radio-target . (lambda (object c i) c))
-				       (target . ignore)))
+		       (org-export-toc-entry-backend 'md)
 		       info)
 		      (or (org-element-property :CUSTOM_ID headline)
 			  (org-export-get-reference headline info))))
diff --git a/lisp/org/ox-odt.el b/lisp/org/ox-odt.el
index 7355eaab6de..a19bab29c16 100644
--- a/lisp/org/ox-odt.el
+++ b/lisp/org/ox-odt.el
@@ -1159,12 +1159,8 @@ table of contents as a string, or nil."
   ;; Likewise, links, footnote references and regular targets are also
   ;; suppressed.
   (let* ((headlines (org-export-collect-headlines info depth scope))
-	 (backend (org-export-create-backend
-		   :parent (org-export-backend-name (plist-get info :back-end))
-		   :transcoders '((footnote-reference . ignore)
-				  (link . (lambda (object c i) c))
-				  (radio-target . (lambda (object c i) c))
-				  (target . ignore)))))
+	 (backend (org-export-toc-entry-backend
+		      (org-export-backend-name (plist-get info :back-end)))))
     (when headlines
       (org-odt--format-toc
        (and (not scope) (org-export-translate "Table of Contents" :utf-8 info))
diff --git a/lisp/org/ox-publish.el b/lisp/org/ox-publish.el
index 957b0da7c59..c2416dba381 100644
--- a/lisp/org/ox-publish.el
+++ b/lisp/org/ox-publish.el
@@ -349,7 +349,6 @@ You can overwrite this default per project in your
 
 
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Timestamp-related functions
 
 (defun org-publish-timestamp-filename (filename &optional pub-dir pub-func)
@@ -392,7 +391,6 @@ If there is no timestamp, create one."
 
 
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Getting project information out of `org-publish-project-alist'
 
 (defun org-publish-property (property project &optional default)
@@ -525,7 +523,6 @@ publishing FILENAME."
 
 
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Tools for publishing functions in back-ends
 
 (defun org-publish-org-to (backend filename extension plist &optional pub-dir)
@@ -899,7 +896,6 @@ representation for the files to include, as returned by
 	  (org-list-to-org list)))
 
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Interactive publishing functions
 
 ;;;###autoload
@@ -1154,7 +1150,8 @@ references with `org-export-get-reference'."
     (let* ((filename (file-truename file))
 	   (crossrefs
 	    (org-publish-cache-get-file-property filename :crossrefs nil t))
-	   (cells (org-export-string-to-search-cell search)))
+	   (cells
+	    (org-export-string-to-search-cell (org-link-unescape search))))
       (or
        ;; Look for reference associated to search cells triggered by
        ;; LINK.  It can match when targeted file has been published
@@ -1169,6 +1166,17 @@ references with `org-export-get-reference'."
 	 (org-publish-cache-set-file-property filename :crossrefs crossrefs)
 	 (org-export-format-reference new))))))
 
+(defun org-publish-file-relative-name (filename info)
+  "Convert FILENAME to be relative to current project's base directory.
+INFO is the plist containing the current export state.  The
+function does not change relative file names."
+  (let ((base (plist-get info :base-directory)))
+    (if (and base
+	     (file-name-absolute-p filename)
+	     (file-in-directory-p filename base))
+	(file-relative-name filename base)
+      filename)))
+
 
 
 ;;; Caching functions
diff --git a/lisp/org/ox-texinfo.el b/lisp/org/ox-texinfo.el
index b5903a52160..60618c1c30e 100644
--- a/lisp/org/ox-texinfo.el
+++ b/lisp/org/ox-texinfo.el
@@ -83,7 +83,8 @@
   :filters-alist
   '((:filter-headline . org-texinfo--filter-section-blank-lines)
     (:filter-parse-tree . org-texinfo--normalize-headlines)
-    (:filter-section . org-texinfo--filter-section-blank-lines))
+    (:filter-section . org-texinfo--filter-section-blank-lines)
+    (:filter-final-output . org-texinfo--untabify))
   :menu-entry
   '(?i "Export to Texinfo"
        ((?t "As TEXI file" org-texinfo-export-to-texinfo)
@@ -405,6 +406,10 @@ If two strings share the same prefix (e.g. \"ISO-8859-1\" and
 
 ;;; Internal Functions
 
+(defun org-texinfo--untabify (s _backend _info)
+  "Remove TAB characters in string S."
+  (replace-regexp-in-string "\t" (make-string tab-width ?\s) s))
+
 (defun org-texinfo--filter-section-blank-lines (headline _backend _info)
   "Filter controlling number of blank lines after a section."
   (replace-regexp-in-string "\n\\(?:\n[ \t]*\\)*\\'" "\n\n" headline))
@@ -499,8 +504,12 @@ export state, as a plist."
    (org-export-create-backend
     :parent 'texinfo
     :transcoders '((footnote-reference . ignore)
-		   (link . (lambda (object c i) c))
-		   (radio-target . (lambda (object c i) c))
+		   (link . (lambda (l c i)
+			     (or c
+				 (org-export-data
+				  (org-element-property :raw-link l)
+				  i))))
+		   (radio-target . (lambda (_r c _i) c))
 		   (target . ignore)))
    info))
 
@@ -519,18 +528,27 @@ strings (e.g., returned by `org-export-get-caption')."
   (let* ((backend
 	  (org-export-create-backend
 	   :parent 'texinfo
-	   :transcoders '((link . (lambda (object c i) c))
-			  (radio-target . (lambda (object c i) c))
+	   :transcoders '((link . (lambda (l c i)
+				    (or c
+					(org-export-data
+					 (org-element-property :raw-link l)
+					 i))))
+			  (radio-target . (lambda (_r c _i) c))
 			  (target . ignore))))
 	 (short-backend
 	  (org-export-create-backend
 	   :parent 'texinfo
-	   :transcoders '((footnote-reference . ignore)
-			  (inline-src-block . ignore)
-			  (link . (lambda (object c i) c))
-			  (radio-target . (lambda (object c i) c))
-			  (target . ignore)
-			  (verbatim . ignore))))
+	   :transcoders
+	   '((footnote-reference . ignore)
+	     (inline-src-block . ignore)
+	     (link . (lambda (l c i)
+		       (or c
+			   (org-export-data
+			    (org-element-property :raw-link l)
+			    i))))
+	     (radio-target . (lambda (_r c _i) c))
+	     (target . ignore)
+	     (verbatim . ignore))))
 	 (short-str
 	  (if (and short caption)
 	      (format "@shortcaption{%s}\n"
@@ -1017,15 +1035,17 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 
 (defun org-texinfo--@ref (datum description info)
   "Return @ref command for element or object DATUM.
-DESCRIPTION is the name of the section to print, as a string."
+DESCRIPTION is the printed name of the section, as a string, or
+nil."
   (let ((node-name (org-texinfo--get-node datum info))
 	;; Sanitize DESCRIPTION for cross-reference use.  In
-	;; particular, remove colons as they seem to cause (even
-	;; within @asis{...} to the Texinfo reader.
-	(title (replace-regexp-in-string
-		"[ \t]*:+" ""
-		(replace-regexp-in-string "," "@comma{}" description))))
-    (if (equal title node-name)
+	;; particular, remove colons as they seem to cause pain (even
+	;; within @asis{...}) to the Texinfo reader.
+	(title (and description
+		    (replace-regexp-in-string
+		     "[ \t]*:+" ""
+		     (replace-regexp-in-string "," "@comma{}" description)))))
+    (if (or (not title) (equal title node-name))
 	(format "@ref{%s}" node-name)
       (format "@ref{%s, , %s}" node-name title))))
 
@@ -1073,20 +1093,8 @@ INFO is a plist holding contextual information.  See
 			       (org-element-type
 				(org-element-property :parent destination))))))
 	   (let ((headline (org-element-lineage destination '(headline) t)))
-	     (org-texinfo--@ref
-	      headline
-	      (or desc (org-texinfo--sanitize-title
-			(org-element-property :title headline) info))
-	      info)))
-	  (_
-	   (org-texinfo--@ref
-	    destination
-	    (or desc
-		(pcase (org-export-get-ordinal destination info)
-		  ((and (pred integerp) n) (number-to-string n))
-		  ((and (pred consp) n) (mapconcat #'number-to-string n "."))
-		  (_ "???")))		;cannot guess the description
-	    info)))))
+	     (org-texinfo--@ref headline desc info)))
+	  (_ (org-texinfo--@ref destination desc info)))))
      ((string= type "mailto")
       (format "@email{%s}"
 	      (concat (org-texinfo--sanitize-content path)
@@ -1167,19 +1175,19 @@ is an integer, build the menu recursively, down to this depth."
   (cond
    ((not level)
     (org-texinfo--format-entries (org-texinfo--menu-entries scope info) info))
-   ((zerop level) nil)
+   ((zerop level) "\n")
    (t
-    (org-element-normalize-string
-     (mapconcat
-      (lambda (h)
-	(let ((entries (org-texinfo--menu-entries h info)))
-	  (when entries
-	    (concat
-	     (format "%s\n\n%s\n"
-		     (org-export-data (org-export-get-alt-title h info) info)
-		     (org-texinfo--format-entries entries info))
-	     (org-texinfo--build-menu h info (1- level))))))
-      (org-texinfo--menu-entries scope info) "\n")))))
+    (mapconcat
+     (lambda (h)
+       (let ((entries (org-texinfo--menu-entries h info)))
+	 (when entries
+	   (concat
+	    (format "%s\n\n%s\n"
+		    (org-export-data (org-export-get-alt-title h info) info)
+		    (org-texinfo--format-entries entries info))
+	    (org-texinfo--build-menu h info (1- level))))))
+     (org-texinfo--menu-entries scope info)
+     ""))))
 
 (defun org-texinfo--format-entries (entries info)
   "Format all direct menu entries in SCOPE, as a string.
diff --git a/lisp/org/ox.el b/lisp/org/ox.el
index 1c43577cddf..8ea47d8ba6d 100644
--- a/lisp/org/ox.el
+++ b/lisp/org/ox.el
@@ -3954,9 +3954,7 @@ INFO is a plist holding contextual information."
 (defun org-export-numbered-headline-p (headline info)
   "Return a non-nil value if HEADLINE element should be numbered.
 INFO is a plist used as a communication channel."
-  (unless (cl-some
-	   (lambda (head) (org-not-nil (org-element-property :UNNUMBERED head)))
-	   (org-element-lineage headline nil t))
+  (unless (org-not-nil (org-export-get-node-property :UNNUMBERED headline t))
     (let ((sec-num (plist-get info :section-numbers))
 	  (level (org-export-get-relative-level headline info)))
       (if (wholenump sec-num) (<= level sec-num) sec-num))))
@@ -4055,11 +4053,15 @@ used as a communication channel."
   (memq (org-element-type (org-export-get-previous-element blob info))
 	'(nil section)))
 
-(defun org-export-last-sibling-p (blob info)
-  "Non-nil when BLOB is the last sibling in its parent.
-BLOB is an element or an object.  INFO is a plist used as
+(defun org-export-last-sibling-p (datum info)
+  "Non-nil when DATUM is the last sibling in its parent.
+DATUM is an element or an object.  INFO is a plist used as
 a communication channel."
-  (not (org-export-get-next-element blob info)))
+  (let ((next (org-export-get-next-element datum info)))
+    (or (not next)
+	(and (eq 'headline (org-element-type datum))
+	     (> (org-element-property :level datum)
+		(org-element-property :level next))))))
 
 
 ;;;; For Keywords
@@ -5176,7 +5178,7 @@ return nil."
       info 'first-match)))
 
 
-;;;; For Tables Of Contents
+;;;; For Tables of Contents
 ;;
 ;; `org-export-collect-headlines' builds a list of all exportable
 ;; headline elements, maybe limited to a certain depth.  One can then
@@ -5186,6 +5188,9 @@ return nil."
 ;; Once the generic function `org-export-collect-elements' is defined,
 ;; `org-export-collect-tables', `org-export-collect-figures' and
 ;; `org-export-collect-listings' can be derived from it.
+;;
+;; `org-export-toc-entry-backend' builds a special anonymous back-end
+;; useful to export table of contents' entries.
 
 (defun org-export-collect-headlines (info &optional n scope)
   "Collect headlines in order to build a table of contents.
@@ -5271,6 +5276,32 @@ INFO is a plist used as a communication channel.
 Return a list of src-block elements with a caption."
   (org-export-collect-elements 'src-block info))
 
+(defun org-export-toc-entry-backend (parent &rest transcoders)
+  "Return an export back-end appropriate for table of contents entries.
+
+PARENT is an export back-end the returned back-end should inherit
+from.
+
+By default, the back-end removes footnote references and targets.
+It also changes links and radio targets into regular text.
+TRANSCODERS optional argument, when non-nil, specifies additional
+transcoders.  A transcoder follows the pattern (TYPE . FUNCTION)
+where type is an element or object type and FUNCTION the function
+transcoding it."
+  (declare (indent 1))
+  (org-export-create-backend
+   :parent parent
+   :transcoders
+   (append transcoders
+	   `((footnote-reference . ,#'ignore)
+	     (link . ,(lambda (l c i)
+			(or c
+			    (org-export-data
+			     (org-element-property :raw-link l)
+			     i))))
+	     (radio-target . ,(lambda (_r c _) c))
+	     (target . ,#'ignore)))))
+
 
 ;;;; Smart Quotes
 ;;
@@ -5657,6 +5688,7 @@ them."
      ("zh-TW" :html "作者" :utf-8 "作者"))
     ("Continued from previous page"
      ("ar" :default "تتمة الصفحة السابقة")
+     ("cs" :default "Pokračování z předchozí strany")
      ("de" :default "Fortsetzung von vorheriger Seite")
      ("es" :html "Continúa de la página anterior" :ascii "Continua de la pagina anterior" :default "Continúa de la página anterior")
      ("fr" :default "Suite de la page précédente")
@@ -5669,6 +5701,7 @@ them."
      ("sl" :default "Nadaljevanje s prejšnje strani"))
     ("Continued on next page"
      ("ar" :default "التتمة في الصفحة التالية")
+     ("cs" :default "Pokračuje na další stránce")
      ("de" :default "Fortsetzung nächste Seite")
      ("es" :html "Continúa en la siguiente página" :ascii "Continua en la siguiente pagina" :default "Continúa en la siguiente página")
      ("fr" :default "Suite page suivante")
@@ -5680,6 +5713,7 @@ them."
       :utf-8 "(Продолжение следует)")
      ("sl" :default "Nadaljevanje na naslednji strani"))
     ("Created"
+     ("cs" :default "Vytvořeno")
      ("sl" :default "Ustvarjeno"))
     ("Date"
      ("ar" :default "بتاريخ")
@@ -5709,6 +5743,7 @@ them."
      ("zh-TW" :html "日期" :utf-8 "日期"))
     ("Equation"
      ("ar" :default "معادلة")
+     ("cs" :default "Rovnice")
      ("da" :default "Ligning")
      ("de" :default "Gleichung")
      ("es" :ascii "Ecuacion" :html "Ecuación" :default "Ecuación")
@@ -5727,6 +5762,7 @@ them."
      ("zh-CN" :html "方程" :utf-8 "方程"))
     ("Figure"
      ("ar" :default "شكل")
+     ("cs" :default "Obrázek")
      ("da" :default "Figur")
      ("de" :default "Abbildung")
      ("es" :default "Figura")
@@ -5742,6 +5778,7 @@ them."
      ("zh-CN" :html "图" :utf-8 "图"))
     ("Figure %d:"
      ("ar" :default "شكل %d:")
+     ("cs" :default "Obrázek %d:")
      ("da" :default "Figur %d")
      ("de" :default "Abbildung %d:")
      ("es" :default "Figura %d:")
@@ -5760,7 +5797,7 @@ them."
     ("Footnotes"
      ("ar" :default "الهوامش")
      ("ca" :html "Peus de pàgina")
-     ("cs" :default "Pozn\xe1mky pod carou")
+     ("cs" :default "Poznámky pod čarou")
      ("da" :default "Fodnoter")
      ("de" :html "Fußnoten" :default "Fußnoten")
      ("eo" :default "Piednotoj")
@@ -5787,6 +5824,7 @@ them."
      ("zh-TW" :html "腳註" :utf-8 "腳註"))
     ("List of Listings"
      ("ar" :default "قائمة بالبرامج")
+     ("cs" :default "Seznam programů")
      ("da" :default "Programmer")
      ("de" :default "Programmauflistungsverzeichnis")
      ("es" :ascii "Indice de Listados de programas" :html "Índice de Listados de programas" :default "Índice de Listados de programas")
@@ -5801,6 +5839,7 @@ them."
      ("zh-CN" :html "代码目录" :utf-8 "代码目录"))
     ("List of Tables"
      ("ar" :default "قائمة بالجداول")
+     ("cs" :default "Seznam tabulek")
      ("da" :default "Tabeller")
      ("de" :default "Tabellenverzeichnis")
      ("es" :ascii "Indice de tablas" :html "Índice de tablas" :default "Índice de tablas")
@@ -5819,6 +5858,7 @@ them."
      ("zh-CN" :html "表格目录" :utf-8 "表格目录"))
     ("Listing"
      ("ar" :default "برنامج")
+     ("cs" :default "Program")
      ("da" :default "Program")
      ("de" :default "Programmlisting")
      ("es" :default "Listado de programa")
@@ -5834,6 +5874,7 @@ them."
      ("zh-CN" :html "代码" :utf-8 "代码"))
     ("Listing %d:"
      ("ar" :default "برنامج %d:")
+     ("cs" :default "Program %d:")
      ("da" :default "Program %d")
      ("de" :default "Programmlisting %d")
      ("es" :default "Listado de programa %d")
@@ -5849,20 +5890,24 @@ them."
      ("zh-CN" :html "代码%d " :utf-8 "代码%d "))
     ("References"
      ("ar" :default "المراجع")
+     ("cs" :default "Reference")
      ("fr" :ascii "References" :default "Références")
      ("de" :default "Quellen")
      ("es" :default "Referencias")
      ("sl" :default "Reference"))
     ("See figure %s"
+     ("cs" :default "Viz obrázek %s")
      ("fr" :default "cf. figure %s"
       :html "cf. figure %s" :latex "cf.~figure~%s")
      ("sl" :default "Glej sliko %s"))
     ("See listing %s"
+     ("cs" :default "Viz program %s")
      ("fr" :default "cf. programme %s"
       :html "cf. programme %s" :latex "cf.~programme~%s")
      ("sl" :default "Glej izpis programa %s"))
     ("See section %s"
      ("ar" :default "انظر قسم %s")
+     ("cs" :default "Viz sekce %s")
      ("da" :default "jævnfør afsnit %s")
      ("de" :default "siehe Abschnitt %s")
      ("es" :ascii "Vea seccion %s" :html "Vea sección %s" :default "Vea sección %s")
@@ -5876,11 +5921,13 @@ them."
      ("sl" :default "Glej poglavje %d")
      ("zh-CN" :html "参见第%s节" :utf-8 "参见第%s节"))
     ("See table %s"
+     ("cs" :default "Viz tabulka %s")
      ("fr" :default "cf. tableau %s"
       :html "cf. tableau %s" :latex "cf.~tableau~%s")
      ("sl" :default "Glej tabelo %s"))
     ("Table"
      ("ar" :default "جدول")
+     ("cs" :default "Tabulka")
      ("de" :default "Tabelle")
      ("es" :default "Tabla")
      ("et" :default "Tabel")
@@ -5893,6 +5940,7 @@ them."
      ("zh-CN" :html "表" :utf-8 "表"))
     ("Table %d:"
      ("ar" :default "جدول %d:")
+     ("cs" :default "Tabulka %d:")
      ("da" :default "Tabel %d")
      ("de" :default "Tabelle %d")
      ("es" :default "Tabla %d")