summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Meyer <kyle@kyleam.com>2017-11-16 22:11:28 -0500
committerKyle Meyer <kyle@kyleam.com>2017-11-16 22:11:28 -0500
commit594201d414e53136b4e6b5531156881ea864cc65 (patch)
treeb100101188ef9a742bb7573b9b5ed21bfe550146
parent6ca9068b6f71bfdc4a4f64b1eff55ca5f3f9589b (diff)
parent946f76d7070f8fbcf5c1072b7f53cea599f2e110 (diff)
downloadorg-mode-594201d414e53136b4e6b5531156881ea864cc65.tar.gz
Merge branch 'maint' into emacs-sync
-rw-r--r--contrib/lisp/ox-koma-letter.el4
-rw-r--r--contrib/lisp/ox-s5.el3
-rw-r--r--doc/org.texi33
-rw-r--r--lisp/ob-tangle.el7
-rw-r--r--lisp/org-attach.el2
-rw-r--r--lisp/org-capture.el13
-rw-r--r--lisp/org-clock.el13
-rw-r--r--lisp/org-element.el35
-rw-r--r--lisp/org-faces.el2
-rw-r--r--lisp/org-id.el3
-rw-r--r--lisp/org-inlinetask.el2
-rw-r--r--lisp/org-macs.el25
-rw-r--r--lisp/org-src.el9
-rw-r--r--lisp/org-table.el2
-rw-r--r--lisp/org.el69
-rw-r--r--lisp/ox-ascii.el199
-rw-r--r--lisp/ox-html.el29
-rw-r--r--lisp/ox-man.el20
-rw-r--r--lisp/ox-md.el13
-rw-r--r--lisp/ox-odt.el8
-rw-r--r--lisp/ox-texinfo.el96
-rw-r--r--lisp/ox.el50
-rw-r--r--testing/lisp/test-ob-tangle.el25
-rw-r--r--testing/lisp/test-org-capture.el16
-rw-r--r--testing/lisp/test-org-clock.el105
-rw-r--r--testing/lisp/test-org-element.el28
-rw-r--r--testing/lisp/test-org-macs.el8
-rw-r--r--testing/lisp/test-org-src.el38
-rw-r--r--testing/lisp/test-org-table.el21
-rw-r--r--testing/lisp/test-org.el22
-rw-r--r--testing/lisp/test-ox.el70
31 files changed, 673 insertions, 297 deletions
diff --git a/contrib/lisp/ox-koma-letter.el b/contrib/lisp/ox-koma-letter.el
index e029811..24ed38b 100644
--- a/contrib/lisp/ox-koma-letter.el
+++ b/contrib/lisp/ox-koma-letter.el
@@ -705,7 +705,7 @@ holding export options."
(or (if (plist-get info :special-headings)
(or heading-val keyword-val)
(or keyword-val heading-val))
- "\\\\mbox{}"))))
+ "\\mbox{}"))))
;; Opening.
(format "\\opening{%s}\n\n"
(org-koma-letter--keyword-or-headline
@@ -717,7 +717,7 @@ holding export options."
(format "\\closing{%s}\n"
(org-koma-letter--keyword-or-headline
:closing (lambda (h i) (eq (org-koma-letter--special-tag h i)
- 'closing))
+ 'closing))
info))
(org-koma-letter--special-contents-inline
(plist-get info :special-tags-after-closing) info)
diff --git a/contrib/lisp/ox-s5.el b/contrib/lisp/ox-s5.el
index 8f95010..0496aae 100644
--- a/contrib/lisp/ox-s5.el
+++ b/contrib/lisp/ox-s5.el
@@ -292,7 +292,8 @@ which will make the list into a \"build\"."
"<%s class='org-%s%s'>" tag tag
(if (org-export-get-node-property :INCREMENTAL plain-list t)
" incremental" ""))
- contents (org-html-end-plain-list type))))
+ contents
+ (format "</%s>" tag))))
(defun org-s5-inner-template (contents info)
"Return body of document string after HTML conversion.
diff --git a/doc/org.texi b/doc/org.texi
index 72fbbad..e84ce64 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -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
@@ -7352,6 +7352,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 +7594,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 +7616,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
diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el
index adc6806..09d011f 100644
--- a/lisp/ob-tangle.el
+++ b/lisp/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-attach.el b/lisp/org-attach.el
index 38b79ce..cd6b413 100644
--- a/lisp/org-attach.el
+++ b/lisp/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-capture.el b/lisp/org-capture.el
index 862cdb2..2222bf4 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -1311,8 +1311,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,11 +1792,10 @@ 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
(push (org-completing-read
(concat (or prompt "Enter string")
diff --git a/lisp/org-clock.el b/lisp/org-clock.el
index 9dc5015..83d0e12 100644
--- a/lisp/org-clock.el
+++ b/lisp/org-clock.el
@@ -487,7 +487,7 @@ to add an effort property.")
"10\\.6\\.[[:digit:]]"
(shell-command-to-string
"sw_vers -productVersion"))
- (<= m -1034058203136))
+ (<= m -1034058203135))
(ignore-errors (decode-time (list m 0)))))))
(low
(funcall dichotomy
@@ -2725,7 +2725,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 +2737,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")
diff --git a/lisp/org-element.el b/lisp/org-element.el
index f2b3002..c5f656e 100644
--- a/lisp/org-element.el
+++ b/lisp/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-faces.el b/lisp/org-faces.el
index 53538e6..eab9f3e 100644
--- a/lisp/org-faces.el
+++ b/lisp/org-faces.el
@@ -291,7 +291,7 @@ determines if it is a foreground or a background color."
(defcustom org-priority-faces nil
"Faces for specific Priorities.
This is a list of cons cells, with priority character in the car
-and faces in the cdr. The face can be a symbol, a color as
+and faces in the cdr. The face can be a symbol, a color
as a string, or a property list of attributes, like
(:foreground \"blue\" :weight bold :underline t).
If it is a color string, the variable `org-faces-easy-properties'
diff --git a/lisp/org-id.el b/lisp/org-id.el
index a508e76..09b873c 100644
--- a/lisp/org-id.el
+++ b/lisp/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-inlinetask.el b/lisp/org-inlinetask.el
index 360b1bc..4a8e43d 100644
--- a/lisp/org-inlinetask.el
+++ b/lisp/org-inlinetask.el
@@ -114,7 +114,7 @@ When nil, the first star is not shown."
(defcustom org-inlinetask-default-state nil
"Non-nil means make inline tasks have a TODO keyword initially.
This should be the state `org-inlinetask-insert-task' should use by
-default, or nil of no state should be assigned."
+default, or nil if no state should be assigned."
:group 'org-inlinetask
:version "24.1"
:type '(choice
diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 1118214..ff6d8c4 100644
--- a/lisp/org-macs.el
+++ b/lisp/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-src.el b/lisp/org-src.el
index 99d7c6f..4191d9a 100644
--- a/lisp/org-src.el
+++ b/lisp/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-table.el b/lisp/org-table.el
index 8dc648e..d51750f 100644
--- a/lisp/org-table.el
+++ b/lisp/org-table.el
@@ -3242,7 +3242,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.el b/lisp/org.el
index 35405b4..571a311 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -1284,7 +1284,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 +5290,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 +5301,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 +5752,23 @@ 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 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))))
+ ;; Do not match table hlines.
(not (and (equal marker "+")
(org-match-line
"^[ \t]*\\(|[-+]+|?\\|\\+[-+]+\\+\\)[ \t]*$")))
(looking-at (if verbatim? org-verbatim-re org-emph-re))
- (not (string-match-p
- (concat org-outline-regexp-bol "\\'")
- (match-string 0)))))
+ ;; At a table row, do not cross cell boundaries.
+ (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 +7952,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))
@@ -9845,7 +9851,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)))
@@ -19327,9 +19335,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 +20790,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 +20943,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.
@@ -21568,7 +21577,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
@@ -23617,7 +23628,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 +24243,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 +24258,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 +24266,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/ox-ascii.el b/lisp/ox-ascii.el
index 9e04387..e83eb19 100644
--- a/lisp/ox-ascii.el
+++ b/lisp/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/ox-html.el b/lisp/ox-html.el
index 8ce4fb6..3073727 100644
--- a/lisp/ox-html.el
+++ b/lisp/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
@@ -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))))
diff --git a/lisp/ox-man.el b/lisp/ox-man.el
index fb8f7be..6fb3041 100644
--- a/lisp/ox-man.el
+++ b/lisp/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/ox-md.el b/lisp/ox-md.el
index 5ba52e7..1218838 100644
--- a/lisp/ox-md.el
+++ b/lisp/ox-md.el
@@ -240,7 +240,7 @@ a communication channel."
(format "<a id=\"%s\"></a>"
(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/ox-odt.el b/lisp/ox-odt.el
index f00fd99..d585636 100644
--- a/lisp/ox-odt.el
+++ b/lisp/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/ox-texinfo.el b/lisp/ox-texinfo.el
index b5903a5..60618c1 100644
--- a/lisp/ox-texinfo.el
+++ b/lisp/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/ox.el b/lisp/ox.el
index 1c43577..af16868 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -5176,7 +5176,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 +5186,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 +5274,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 +5686,7 @@ them."
("zh-TW" :html "&#20316;&#32773;" :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&uacute;a de la p&aacute;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 +5699,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&uacute;a en la siguiente p&aacute;gina" :ascii "Continua en la siguiente pagina" :default "Continúa en la siguiente página")
("fr" :default "Suite page suivante")
@@ -5680,6 +5711,7 @@ them."
:utf-8 "(Продолжение следует)")
("sl" :default "Nadaljevanje na naslednji strani"))
("Created"
+ ("cs" :default "Vytvořeno")
("sl" :default "Ustvarjeno"))
("Date"
("ar" :default "بتاريخ")
@@ -5709,6 +5741,7 @@ them."
("zh-TW" :html "&#26085;&#26399;" :utf-8 "日期"))
("Equation"
("ar" :default "معادلة")
+ ("cs" :default "Rovnice")
("da" :default "Ligning")
("de" :default "Gleichung")
("es" :ascii "Ecuacion" :html "Ecuaci&oacute;n" :default "Ecuación")
@@ -5727,6 +5760,7 @@ them."
("zh-CN" :html "&#26041;&#31243;" :utf-8 "方程"))
("Figure"
("ar" :default "شكل")
+ ("cs" :default "Obrázek")
("da" :default "Figur")
("de" :default "Abbildung")
("es" :default "Figura")
@@ -5742,6 +5776,7 @@ them."
("zh-CN" :html "&#22270;" :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 +5795,7 @@ them."
("Footnotes"
("ar" :default "الهوامش")
("ca" :html "Peus de p&agrave;gina")
- ("cs" :default "Pozn\xe1mky pod carou")
+ ("cs" :default "Poznámky pod čarou")
("da" :default "Fodnoter")
("de" :html "Fu&szlig;noten" :default "Fußnoten")
("eo" :default "Piednotoj")
@@ -5787,6 +5822,7 @@ them."
("zh-TW" :html "&#33139;&#35387;" :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 "&Iacute;ndice de Listados de programas" :default "Índice de Listados de programas")
@@ -5801,6 +5837,7 @@ them."
("zh-CN" :html "&#20195;&#30721;&#30446;&#24405;" :utf-8 "代码目录"))
("List of Tables"
("ar" :default "قائمة بالجداول")
+ ("cs" :default "Seznam tabulek")
("da" :default "Tabeller")
("de" :default "Tabellenverzeichnis")
("es" :ascii "Indice de tablas" :html "&Iacute;ndice de tablas" :default "Índice de tablas")
@@ -5819,6 +5856,7 @@ them."
("zh-CN" :html "&#34920;&#26684;&#30446;&#24405;" :utf-8 "表格目录"))
("Listing"
("ar" :default "برنامج")
+ ("cs" :default "Program")
("da" :default "Program")
("de" :default "Programmlisting")
("es" :default "Listado de programa")
@@ -5834,6 +5872,7 @@ them."
("zh-CN" :html "&#20195;&#30721;" :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 +5888,24 @@ them."
("zh-CN" :html "&#20195;&#30721;%d&nbsp;" :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.&nbsp;figure&nbsp;%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.&nbsp;programme&nbsp;%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&oacute;n %s" :default "Vea sección %s")
@@ -5876,11 +5919,13 @@ them."
("sl" :default "Glej poglavje %d")
("zh-CN" :html "&#21442;&#35265;&#31532;%s&#33410;" :utf-8 "参见第%s节"))
("See table %s"
+ ("cs" :default "Viz tabulka %s")
("fr" :default "cf. tableau %s"
:html "cf.&nbsp;tableau&nbsp;%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 +5938,7 @@ them."
("zh-CN" :html "&#34920;" :utf-8 "表"))
("Table %d:"
("ar" :default "جدول %d:")
+ ("cs" :default "Tabulka %d:")
("da" :default "Tabel %d")
("de" :default "Tabelle %d")
("es" :default "Tabla %d")
diff --git a/testing/lisp/test-ob-tangle.el b/testing/lisp/test-ob-tangle.el
index 06a73f0..73b7532 100644
--- a/testing/lisp/test-ob-tangle.el
+++ b/testing/lisp/test-ob-tangle.el
@@ -197,6 +197,31 @@ another block
(org-babel-tangle-jump-to-org)
(buffer-string)))))))
+(ert-deftest ob-tangle/nested-block ()
+ "Test tangling of org file with nested block."
+ (should
+ (string=
+ "#+begin_src org
+,#+begin_src emacs-lisp
+1
+,#+end_src
+#+end_src
+"
+ (org-test-with-temp-text-in-file
+ "#+header: :tangle \"test-ob-tangle.org\"
+#+begin_src org
+,#+begin_src org
+,,#+begin_src emacs-lisp
+1
+,,#+end_src
+,#+end_src
+#+end_src"
+ (unwind-protect
+ (progn (org-babel-tangle)
+ (with-temp-buffer (insert-file-contents "test-ob-tangle.org")
+ (buffer-string)))
+ (delete-file "test-ob-tangle.org"))))))
+
(provide 'test-ob-tangle)
;;; test-ob-tangle.el ends here
diff --git a/testing/lisp/test-org-capture.el b/testing/lisp/test-org-capture.el
index 4d5dfb7..b98166a 100644
--- a/testing/lisp/test-org-capture.el
+++ b/testing/lisp/test-org-capture.el
@@ -146,5 +146,21 @@
(list file1 file2 (buffer-file-name)))))))))
+(ert-deftest test-org-capture/insert-at-end-abort ()
+ "Test that capture can be aborted after inserting at end of capture buffer."
+ (should
+ (equal
+ "* A\n* B\n"
+ (org-test-with-temp-text-in-file "* A\n* B\n"
+ (let* ((file (buffer-file-name))
+ (org-capture-templates
+ `(("t" "Todo" entry (file+headline ,file "A") "** H1 %?"))))
+ (org-capture nil "t")
+ (goto-char (point-max))
+ (insert "Capture text")
+ (org-capture-kill))
+ (buffer-string)))))
+
+
(provide 'test-org-capture)
;;; test-org-capture.el ends here
diff --git a/testing/lisp/test-org-clock.el b/testing/lisp/test-org-clock.el
index 30a69ea..98dab5b 100644
--- a/testing/lisp/test-org-clock.el
+++ b/testing/lisp/test-org-clock.el
@@ -828,5 +828,110 @@ CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 11:09] => 0:00
CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 13:09] => 0:00"
(test-org-clock-clocktable-contents ":tcolumns 2")))))
+(ert-deftest test-org-clock/clocktable/step ()
+ "Test \":step\" parameter in Clock table."
+ ;; Regression test: week crossing month boundary before :wstart
+ ;; day-of-week.
+ (should
+ (equal "
+Weekly report starting on: [2017-09-25 Mon]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *1:00* |
+|--------------+--------|
+| Foo | 1:00 |"
+ (org-test-with-temp-text
+ "* Foo
+CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
+CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00
+CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00"
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step week :block 2017-09 :stepskip0 t")))))
+ (should
+ (equal "
+Weekly report starting on: [2017-10-01 Sun]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *2:00* |
+|--------------+--------|
+| Foo | 2:00 |
+
+Weekly report starting on: [2017-10-02 Mon]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *7:00* |
+|--------------+--------|
+| Foo | 7:00 |
+
+Weekly report starting on: [2017-10-09 Mon]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *5:00* |
+|--------------+--------|
+| Foo | 5:00 |
+"
+ (org-test-with-temp-text
+ "* Foo
+CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
+CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00
+CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00
+CLOCK: [2017-10-08 Sun 09:00]--[2017-10-08 Sun 13:00] => 4:00
+CLOCK: [2017-10-09 Mon 09:00]--[2017-10-09 Mon 14:00] => 5:00"
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step week :block 2017-10 :stepskip0 t")))))
+ ;; :step day
+ (should
+ (equal "
+Daily report: [2017-10-02 Mon]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *3:00* |
+|--------------+--------|
+| Foo | 3:00 |
+
+Daily report: [2017-10-03 Tue]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *0:00* |
+
+Daily report: [2017-10-04 Wed]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *0:00* |
+
+Daily report: [2017-10-05 Thu]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *0:00* |
+
+Daily report: [2017-10-06 Fri]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *0:00* |
+
+Daily report: [2017-10-07 Sat]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *0:00* |
+
+Daily report: [2017-10-08 Sun]
+| Headline | Time |
+|--------------+--------|
+| *Total time* | *4:00* |
+|--------------+--------|
+| Foo | 4:00 |"
+ (org-test-with-temp-text
+ "* Foo
+CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
+CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00
+CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00
+CLOCK: [2017-10-08 Sun 09:00]--[2017-10-08 Sun 13:00] => 4:00
+CLOCK: [2017-10-09 Mon 09:00]--[2017-10-09 Mon 14:00] => 5:00"
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step day :block 2017-W40"))))))
+
(provide 'test-org-clock)
;;; test-org-clock.el end here
diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index 7d1c55f..7c359aa 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -1444,9 +1444,19 @@ DEADLINE: <2012-03-29 thu.>"
'org-element-contents))))
;; Block in an item: ignore indentation within the block.
(should
- (org-test-with-temp-text "- item\n #+begin_src emacs-lisp\n(+ 1 1)\n #+end_src"
- (forward-char)
- (= (org-element-property :end (org-element-at-point)) (point-max)))))
+ (org-test-with-temp-text
+ "-<point> item\n #+begin_src emacs-lisp\n(+ 1 1)\n #+end_src"
+ (= (org-element-property :end (org-element-at-point)) (point-max))))
+ ;; Last item in a list or sub-list has no `:post-blank' lines, since
+ ;; those belong to the plain-list.
+ (should
+ (= 0
+ (org-test-with-temp-text "- A\n\n- <point>B\n\nEnd list"
+ (org-element-property :post-blank (org-element-at-point)))))
+ (should
+ (= 0
+ (org-test-with-temp-text "- A\n\n - B\n\n<point> - C\n\n End sub-list"
+ (org-element-property :post-blank (org-element-at-point))))))
;;;; Keyword
@@ -1962,7 +1972,17 @@ e^{i\\pi}+1=0
"Test `plain-list' parser."
(org-test-with-temp-text "- item"
(should (org-element-map (org-element-parse-buffer) 'plain-list 'identity)))
- ;; Blank lines after the list only belong to outer plain list.
+ ;; Blank lines after a list or sub-list belongs to that list.
+ (should
+ (= 1
+ (org-test-with-temp-text "- A\n\n- B\n\nEnd list"
+ (org-element-property :post-blank (org-element-at-point)))))
+ (should
+ (= 1
+ (org-test-with-temp-text "- A\n\n<point> - B\n\n - C\n\n End sub-list"
+ (org-element-property :post-blank (org-element-at-point)))))
+ ;; Blank lines after the list only belong to outer plain list,
+ ;; however.
(should
(equal
'(t t)
diff --git a/testing/lisp/test-org-macs.el b/testing/lisp/test-org-macs.el
index 7c54761..79a39f1 100644
--- a/testing/lisp/test-org-macs.el
+++ b/testing/lisp/test-org-macs.el
@@ -68,7 +68,13 @@
(eq 'foo
(get-text-property 1 'face
(org-string-display
- #("123" 1 2 (display "abc" face foo)))))))
+ #("123" 1 2 (display "abc" face foo))))))
+ ;; Also preserve `display' property in original string.
+ (should
+ (equal "abc"
+ (let ((s #("123" 1 2 (display "abc" face foo))))
+ (org-string-display s)
+ (get-text-property 1 'display s)))))
(provide 'test-org-macs)
diff --git a/testing/lisp/test-org-src.el b/testing/lisp/test-org-src.el
index 1d683ec..86f08ec 100644
--- a/testing/lisp/test-org-src.el
+++ b/testing/lisp/test-org-src.el
@@ -443,5 +443,43 @@ This is a tab:\t.
(org-edit-special)
(prog1 foo (org-edit-src-exit))))))
+;;; Code escaping
+
+(ert-deftest test-org-src/escape-code-in-string ()
+ "Test `org-escape-code-in-string' specifications."
+ ;; Escape lines starting with "*" or "#+".
+ (should (equal ",*" (org-escape-code-in-string "*")))
+ (should (equal ",#+" (org-escape-code-in-string "#+")))
+ ;; Escape lines starting with ",*" and ",#+". Number of leading
+ ;; commas does not matter.
+ (should (equal ",,*" (org-escape-code-in-string ",*")))
+ (should (equal ",,#+" (org-escape-code-in-string ",#+")))
+ (should (equal ",,,*" (org-escape-code-in-string ",,*")))
+ (should (equal ",,,#+" (org-escape-code-in-string ",,#+")))
+ ;; Indentation does not matter.
+ (should (equal " ,*" (org-escape-code-in-string " *")))
+ (should (equal " ,#+" (org-escape-code-in-string " #+")))
+ ;; Do nothing on other cases.
+ (should (equal "a" (org-escape-code-in-string "a")))
+ (should (equal "#" (org-escape-code-in-string "#")))
+ (should (equal "," (org-escape-code-in-string ","))))
+
+(ert-deftest test-org-src/unescape-code-in-string ()
+ "Test `org-unescape-code-in-string' specifications."
+ ;; Unescape lines starting with ",*" or ",#+". Number of leading
+ ;; commas does not matter.
+ (should (equal "*" (org-unescape-code-in-string ",*")))
+ (should (equal "#+" (org-unescape-code-in-string ",#+")))
+ (should (equal ",*" (org-unescape-code-in-string ",,*")))
+ (should (equal ",#+" (org-unescape-code-in-string ",,#+")))
+ ;; Indentation does not matter.
+ (should (equal " *" (org-unescape-code-in-string " ,*")))
+ (should (equal " #+" (org-unescape-code-in-string " ,#+")))
+ ;; Do nothing on other cases.
+ (should (equal "a" (org-unescape-code-in-string "a")))
+ (should (equal "#" (org-unescape-code-in-string "#")))
+ (should (equal "," (org-unescape-code-in-string ","))))
+
+
(provide 'test-org-src)
;;; test-org-src.el ends here
diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el
index 63234e3..92960da 100644
--- a/testing/lisp/test-org-table.el
+++ b/testing/lisp/test-org-table.el
@@ -1906,6 +1906,27 @@ is t, then new columns should be added as needed"
(org-table-calc-current-TBLFM)
(buffer-string)))))
+(ert-deftest test-org-table/formula-priority ()
+ "Test field formula priority over column formula."
+ ;; Field formulas bind stronger than column formulas.
+ (should
+ (equal
+ "| 1 | 3 |\n| 2 | 99 |\n"
+ (org-test-with-temp-text
+ "| 1 | |\n| 2 | |\n<point>#+tblfm: $2=3*$1::@2$2=99"
+ (org-table-calc-current-TBLFM)
+ (buffer-substring-no-properties (point-min) (point)))))
+ ;; When field formula is removed, table formulas is applied again.
+ (should
+ (equal
+ "| 1 | 3 |\n| 2 | 6 |\n"
+ (org-test-with-temp-text
+ "| 1 | |\n| 2 | |\n#+tblfm: $2=3*$1<point>::@2$2=99"
+ (org-table-calc-current-TBLFM)
+ (delete-region (point) (line-end-position))
+ (org-table-calc-current-TBLFM)
+ (buffer-substring-no-properties (point-min) (line-beginning-position))))))
+
(ert-deftest test-org-table/tab-indent ()
"Test named fields with tab indentation."
(should
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 4023ec4..d067c04 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -1416,6 +1416,13 @@
(org-test-with-temp-text "* H\n- an item\n- another one"
(search-forward "an ")
(org-insert-todo-heading-respect-content)
+ (buffer-substring-no-properties (line-beginning-position) (point-max)))))
+ ;; Use the same TODO keyword as current heading.
+ (should
+ (equal
+ "* TODO \n"
+ (org-test-with-temp-text "* TODO\n** WAITING\n"
+ (org-insert-todo-heading-respect-content)
(buffer-substring-no-properties (line-beginning-position) (point-max))))))
(ert-deftest test-org/clone-with-time-shift ()
@@ -3414,8 +3421,8 @@ SCHEDULED: <2017-05-06 Sat>
(org-test-with-temp-text "Paragraph 1.<point>\n\nParagraph 2."
(org-forward-sentence)
(eobp)))
- ;; On a headline, stop at the end of the line, unless point is
- ;; already there.
+ ;; Headlines are considered to be sentences by themselves, even if
+ ;; they do not end with a full stop.
(should
(equal
"* Headline"
@@ -3425,7 +3432,11 @@ SCHEDULED: <2017-05-06 Sat>
(should
(org-test-with-temp-text "* Headline<point>\nSentence."
(org-forward-sentence)
- (eobp))))
+ (eobp)))
+ (should
+ (org-test-with-temp-text "Sentence.<point>\n\n* Headline\n\nSentence 2."
+ (org-forward-sentence)
+ (and (org-at-heading-p) (eolp)))))
(ert-deftest test-org/backward-sentence ()
"Test `org-backward-sentence' specifications."
@@ -3607,6 +3618,11 @@ SCHEDULED: <2017-05-06 Sat>
(should
(org-test-with-temp-text "#+BEGIN_<point>EXAMPLE\nL1\n#+END_EXAMPLE"
(org-backward-paragraph)
+ (bobp)))
+ ;; Pathological case: on an empty heading, move to its beginning.
+ (should
+ (org-test-with-temp-text "* <point>H"
+ (org-backward-paragraph)
(bobp))))
(ert-deftest test-org/forward-element ()
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 72b6c8c..6b5e3a3 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -4320,6 +4320,76 @@ Another text. (ref:text)
(let ((scope (org-element-map tree 'headline #'identity info t)))
(length (org-export-collect-headlines info 1 scope)))))))
+(ert-deftest test-org-export/toc-entry-backend ()
+ "Test `org-export-toc-entry-backend' specifications."
+ ;; Ignore targets.
+ (should
+ (equal "H \n"
+ (org-test-with-temp-text "* H <<target>>"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test)
+ i)))))
+ (org-export-as 'test)))))
+ ;; Ignore footnote references.
+ (should
+ (equal "H \n"
+ (org-test-with-temp-text "[fn:1] Definition\n* H [fn:1]"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test)
+ i)))))
+ (org-export-as 'test)))))
+ ;; Replace plain links with contents, or with path.
+ (should
+ (equal "H Org mode\n"
+ (org-test-with-temp-text "* H [[http://orgmode.org][Org mode]]"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test)
+ i)))))
+ (org-export-as 'test)))))
+ (should
+ (equal "H http://orgmode.org\n"
+ (org-test-with-temp-text "* H [[http://orgmode.org]]"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test)
+ i)))))
+ (org-export-as 'test)))))
+ ;; Replace radio targets with contents.
+ (should
+ (equal "H radio\n"
+ (org-test-with-temp-text "* H <<<radio>>>"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test)
+ i)))))
+ (org-export-as 'test)))))
+ ;; With optional argument TRANSCODERS, specify other
+ ;; transformations.
+ (should
+ (equal "H bold\n"
+ (org-test-with-temp-text "* H *bold*"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test
+ '(bold . (lambda (_b c _i) c)))
+ i)))))
+ (org-export-as 'test))))))
+
;;; Templates