Merge branch 'maint' into emacs-sync

This commit is contained in:
Kyle Meyer 2017-06-22 09:48:14 -04:00
commit 81eb4d7575
26 changed files with 711 additions and 453 deletions

View File

@ -1455,7 +1455,7 @@ How well did you do? %s"
;; (save-excursion
;; (org-map-entries
;; (lambda ()
;; (when (and (not (outline-invisible-p))
;; (when (and (not (org-invisible-p))
;; (> (org-current-level) drill-entry-level))
;; (setq drill-heading (org-get-heading t))
;; (unless (and (= (org-current-level) (1+ drill-entry-level))
@ -1480,7 +1480,7 @@ the current topic."
(save-excursion
(org-map-entries
(lambda ()
(when (and (not (outline-invisible-p))
(when (and (not (org-invisible-p))
(> (org-current-level) drill-entry-level))
(when (or (/= (org-current-level) (1+ drill-entry-level))
(funcall test))

View File

@ -647,7 +647,7 @@ Texinfo export
* Texinfo specific export settings:: Setting the environment.
* Texinfo file header:: Generating the header.
* Texinfo title and copyright page:: Creating preamble pages.
* Texinfo @samp{Top} node:: Installing a manual in Info Top node.
* Info directory file:: Installing a manual in Info file hierarchy.
* Headings and sectioning structure:: Building document structure.
* Indices:: Creating indices.
* Quoting Texinfo code:: Incorporating literal Texinfo code.
@ -3531,44 +3531,44 @@ string followed by a colon. There can be no space after the colon. The
following list shows examples for each link type.
@example
http://www.astro.uva.nl/~dominik @r{on the web}
doi:10.1000/182 @r{DOI for an electronic resource}
file:/home/dominik/images/jupiter.jpg @r{file, absolute path}
/home/dominik/images/jupiter.jpg @r{same as above}
file:papers/last.pdf @r{file, relative path}
./papers/last.pdf @r{same as above}
file:/myself@@some.where:papers/last.pdf @r{file, path on remote machine}
/myself@@some.where:papers/last.pdf @r{same as above}
file:sometextfile::NNN @r{file, jump to line number}
file:projects.org @r{another Org file}
file:projects.org::some words @r{text search in Org file}@footnote{
http://www.astro.uva.nl/~dominik @r{on the web}
doi:10.1000/182 @r{DOI for an electronic resource}
file:/home/dominik/images/jupiter.jpg @r{file, absolute path}
/home/dominik/images/jupiter.jpg @r{same as above}
file:papers/last.pdf @r{file, relative path}
./papers/last.pdf @r{same as above}
file:/ssh:myself@@some.where:papers/last.pdf @r{file, path on remote machine}
/ssh:myself@@some.where:papers/last.pdf @r{same as above}
file:sometextfile::NNN @r{file, jump to line number}
file:projects.org @r{another Org file}
file:projects.org::some words @r{text search in Org file}@footnote{
The actual behavior of the search will depend on the value of
the option @code{org-link-search-must-match-exact-headline}. If its value
is @code{nil}, then a fuzzy text search will be done. If it is t, then only the
exact headline will be matched, ignoring spaces and cookies. If the value is
@code{query-to-create}, then an exact headline will be searched; if it is not
found, then the user will be queried to create it.}
file:projects.org::*task title @r{heading search in Org
file}@footnote{Headline searches always match the exact headline, ignoring
is @code{nil}, then a fuzzy text search will be done. If it is @code{t}, then only
the exact headline will be matched, ignoring spaces and cookies. If the
value is @code{query-to-create}, then an exact headline will be searched; if
it is not found, then the user will be queried to create it.}
file:projects.org::*task title @r{heading search in Org file}@footnote{
Headline searches always match the exact headline, ignoring
spaces and cookies. If the headline is not found and the value of the option
@code{org-link-search-must-match-exact-headline} is @code{query-to-create},
then the user will be queried to create it.}
docview:papers/last.pdf::NNN @r{open in doc-view mode at page}
id:B7423F4D-2E8A-471B-8810-C40F074717E9 @r{Link to heading by ID}
news:comp.emacs @r{Usenet link}
mailto:adent@@galaxy.net @r{Mail link}
mhe:folder @r{MH-E folder link}
mhe:folder#id @r{MH-E message link}
rmail:folder @r{RMAIL folder link}
rmail:folder#id @r{RMAIL message link}
gnus:group @r{Gnus group link}
gnus:group#id @r{Gnus article link}
bbdb:R.*Stallman @r{BBDB link (with regexp)}
irc:/irc.com/#emacs/bob @r{IRC link}
info:org#External links @r{Info node or index link}
shell:ls *.org @r{A shell command}
elisp:org-agenda @r{Interactive Elisp command}
elisp:(find-file-other-frame "Elisp.org") @r{Elisp form to evaluate}
docview:papers/last.pdf::NNN @r{open in doc-view mode at page}
id:B7423F4D-2E8A-471B-8810-C40F074717E9 @r{Link to heading by ID}
news:comp.emacs @r{Usenet link}
mailto:adent@@galaxy.net @r{Mail link}
mhe:folder @r{MH-E folder link}
mhe:folder#id @r{MH-E message link}
rmail:folder @r{RMAIL folder link}
rmail:folder#id @r{RMAIL message link}
gnus:group @r{Gnus group link}
gnus:group#id @r{Gnus article link}
bbdb:R.*Stallman @r{BBDB link (with regexp)}
irc:/irc.com/#emacs/bob @r{IRC link}
info:org#External links @r{Info node or index link}
shell:ls *.org @r{A shell command}
elisp:org-agenda @r{Interactive Elisp command}
elisp:(find-file-other-frame "Elisp.org") @r{Elisp form to evaluate}
@end example
@cindex VM links
@ -3579,13 +3579,13 @@ to VM or Wanderlust messages are available when you load the corresponding
libraries from the @code{contrib/} directory:
@example
vm:folder @r{VM folder link}
vm:folder#id @r{VM message link}
vm://myself@@some.where.org/folder#id @r{VM on remote machine}
vm-imap:account:folder @r{VM IMAP folder link}
vm-imap:account:folder#id @r{VM IMAP message link}
wl:folder @r{WANDERLUST folder link}
wl:folder#id @r{WANDERLUST message link}
vm:folder @r{VM folder link}
vm:folder#id @r{VM message link}
vm://myself@@some.where.org/folder#id @r{VM on remote machine}
vm-imap:account:folder @r{VM IMAP folder link}
vm-imap:account:folder#id @r{VM IMAP message link}
wl:folder @r{WANDERLUST folder link}
wl:folder#id @r{WANDERLUST message link}
@end example
For customizing Org to add new link types @ref{Adding hyperlink types}.
@ -10752,7 +10752,7 @@ file, you could use:
@noindent
The first parameter is the file name to include. The optional second
parameter specifies the block type: @samp{example}, @samp{export} or
p@samp{src}). The option third parameter specifies the source code language
@samp{src}. The optional third parameter specifies the source code language
to use for formatting the contents. This is relevant to both @samp{export}
and @samp{src} block types.
@ -13462,7 +13462,7 @@ can compile to Info format.
* Texinfo specific export settings:: Setting the environment.
* Texinfo file header:: Generating the header.
* Texinfo title and copyright page:: Creating preamble pages.
* Texinfo @samp{Top} node:: Installing a manual in Info Top node.
* Info directory file:: Installing a manual in Info file hierarchy.
* Headings and sectioning structure:: Building document structure.
* Indices:: Creating indices.
* Quoting Texinfo code:: Incorporating literal Texinfo code.
@ -13600,8 +13600,14 @@ Copyright information is printed on the back of the title page.
Copyright \copy 2016 Free Software Foundation, Inc.
@end example
@node Texinfo @samp{Top} node
@subsection Texinfo @samp{Top} node
@node Info directory file
@subsection Info directory file
@cindex @samp{dir} file, in Texinfo export
@cindex Texinfo export, @samp{dir} file
@cindex Info directory file, in Texinfo export
@cindex Texinfo export, Info directory file
@cindex @code{install-info} parameters, in Texinfo export
@cindex Texinfo export, @code{install-info} parameters
@cindex #+TEXINFO_DIR_CATEGORY
@cindex #+TEXINFO_DIR_TITLE
@ -13612,7 +13618,7 @@ This Info file's metadata has variables for category, title, and description:
@code{#+TEXINFO_DIR_DESC} that establish where in the Info hierarchy the file
fits.
Here's an example that writes to the @samp{Top} node:
Here is an example that writes to the Info directory file:
@example
#+TEXINFO_DIR_CATEGORY: Emacs
@ -13661,20 +13667,39 @@ entry:
:END:
@end example
@cindex The Top node, in Texinfo export
@cindex Texinfo export, Top node
The text before the first headline belongs to the @samp{Top} node, i.e., the
node in which a reader enters an Info manual. As such, it is expected not to
appear in printed output generated from the @file{.texi} file. @inforef{The
Top Node,,texinfo}, for more information.
@node Indices
@subsection Indices
@cindex #+CINDEX
@cindex concept index, in Texinfo export
@cindex Texinfo export, index, concept
@cindex #+FINDEX
@cindex function index, in Texinfo export
@cindex Texinfo export, index, function
@cindex #+KINDEX
@cindex keystroke index, in Texinfo export
@cindex Texinfo export, keystroke index
@cindex #+PINDEX
@cindex program index, in Texinfo export
@cindex Texinfo export, program index
@cindex #+TINDEX
@cindex data type index, in Texinfo export
@cindex Texinfo export, data type index
@cindex #+VINDEX
@cindex variable index, in Texinfo export
@cindex Texinfo export, variable index
The Texinfo export back-end recognizes these indexing keywords if used in the
Org file: @code{#+CINDEX}, @code{#+FINDEX}, @code{#+KINDEX}, @code{#+PINDEX},
@code{#+TINDEX}, and @code{#+VINDEX}. The back-end also recognizes custom
index definitions that use raw Texinfo code in the Org file (@pxref{Quoting
Texinfo code}).
@code{#+TINDEX}, and @code{#+VINDEX}. Write their value as verbatim Texinfo
code; in particular, @samp{@{}, @samp{@}} and @samp{@@} characters need to be
escaped with @samp{@@} if they not belong to a Texinfo command.
@example
#+CINDEX: Defining indexing entries
@ -13771,7 +13796,7 @@ name. It also adds any @code{:options} attributes to the end of the command,
as shown in this example:
@example
#+attr_texinfo: :options org-org-export-to-org ...
#+ATTR_TEXINFO: :options org-org-export-to-org ...
#+begin_defun
A somewhat obsessive function.
#+end_defun
@ -13793,15 +13818,17 @@ Here is a more detailed example Org file. @inforef{GNU Sample
Texts,,texinfo} for an equivalent example using Texinfo code.
@example
#+MACRO: version 2.0
#+MACRO: updated last updated 4 March 2014
#+OPTIONS: ':t toc:t author:t email:t
#+TITLE: GNU Sample @{@{@{version@}@}@}
#+SUBTITLE: for version @{@{@{version@}@}@}, @{@{@{updated@}@}@}
#+AUTHOR: A.U. Thor
#+EMAIL: bug-sample@@gnu.org
#+OPTIONS: ':t toc:t author:t email:t
#+LANGUAGE: en
#+MACRO: version 2.0
#+MACRO: updated last updated 4 March 2014
#+TEXINFO_FILENAME: sample.info
#+TEXINFO_HEADER: @@syncodeindex pg cp
@ -13810,7 +13837,9 @@ Texts,,texinfo} for an equivalent example using Texinfo code.
#+TEXINFO_DIR_DESC: Invoking sample
#+TEXINFO_PRINTED_TITLE: GNU Sample
#+SUBTITLE: for version @{@{@{version@}@}@}, @{@{@{updated@}@}@}
This manual is for GNU Sample (version @{@{@{version@}@}@},
@{@{@{updated@}@}@}).
* Copying
:PROPERTIES:
@ -13820,8 +13849,7 @@ Texts,,texinfo} for an equivalent example using Texinfo code.
This manual is for GNU Sample (version @{@{@{version@}@}@},
@{@{@{updated@}@}@}), which is an example in the Texinfo documentation.
Copyright @@@@texinfo:@@copyright@{@}@@@@ 2013 Free Software Foundation,
Inc.
Copyright \copy 2016 Free Software Foundation, Inc.
#+BEGIN_QUOTE
Permission is granted to copy, distribute and/or modify this
@ -17018,8 +17046,6 @@ More templates can added by customizing the variable
@node Speed keys
@section Speed keys
@cindex speed keys
@vindex org-use-speed-commands
@vindex org-speed-commands-user
Single keystrokes can execute custom commands in an Org file when the cursor
is on a headline. Without the extra burden of a meta or modifier key, Speed
@ -17028,14 +17054,19 @@ navigation, Speed Keys may come in handy on small mobile devices that do not
have full keyboards. Speed Keys may also work on TTY devices known for their
problems when entering Emacs keychords.
By default, Org has Speed Keys disabled. To activate Speed Keys, configure
the variable @code{org-use-speed-commands}. To trigger a Speed Key, the
cursor must be at the beginning of an Org headline, before any of the stars.
@vindex org-use-speed-commands
By default, Org has Speed Keys disabled. To activate Speed Keys, set the
variable @code{org-use-speed-commands} to a non-@code{nil} value. To trigger
a Speed Key, the cursor must be at the beginning of an Org headline, before
any of the stars.
Org comes with a pre-defined list of Speed Keys; @kbd{?} shows currently
active Speed Keys. To add or modify Speed Keys, customize the variable,
@code{org-speed-commands-user}. For more details, see the variable's
docstring.
@vindex org-speed-commands-user
@findex org-speed-command-help
Org comes with a pre-defined list of Speed Keys. To add or modify Speed
Keys, customize the variable, @code{org-speed-commands-user}. For more
details, see the variable's docstring. With Speed Keys activated, @kbd{M-x
org-speed-command-help}, or @kbd{?} when cursor is at the beginning of an Org
headline, shows currently active Speed Keys, including the user-defined ones.
@node Code evaluation security
@ -18225,7 +18256,7 @@ no special formatting is applied.
@cindex translator function
Orgtbl mode has built-in translator functions: @code{orgtbl-to-csv}
(comma-separated values), @code{orgtbl-to-tsv} (TAB-separated values)
(comma-separated values), @code{orgtbl-to-tsv} (TAB-separated values),
@code{orgtbl-to-latex}, @code{orgtbl-to-html}, @code{orgtbl-to-texinfo},
@code{orgtbl-to-unicode} and @code{orgtbl-to-orgtbl}. They use the generic
translator, @code{orgtbl-to-generic}, which delegates translations to various

View File

@ -140,11 +140,13 @@ This function is called by `org-babel-execute-src-block'."
(defun org-babel--variable-assignments:bash (varname values &optional sep hline)
"Represents the parameters as useful Bash shell variables."
(if (listp values)
(if (and (listp (car values)) (= 1 (length (car values))))
(org-babel--variable-assignments:bash_array varname values sep hline)
(org-babel--variable-assignments:bash_assoc varname values sep hline))
(org-babel--variable-assignments:sh-generic varname values sep hline)))
(pcase values
(`((,_ ,_ . ,_) . ,_) ;two-dimensional array
(org-babel--variable-assignments:bash_assoc varname values sep hline))
(`(,_ . ,_) ;simple list
(org-babel--variable-assignments:bash_array varname values sep hline))
(_ ;scalar value
(org-babel--variable-assignments:sh-generic varname values sep hline))))
(defun org-babel-variable-assignments:shell (params)
"Return list of shell statements assigning the block's variables."

View File

@ -204,17 +204,19 @@ if LOCATION is not given, the value of `org-archive-location' is used."
;;;###autoload
(defun org-archive-subtree (&optional find-done)
"Move the current subtree to the archive.
The archive can be a certain top-level heading in the current file, or in
a different file. The tree will be moved to that location, the subtree
heading be marked DONE, and the current time will be added.
The archive can be a certain top-level heading in the current
file, or in a different file. The tree will be moved to that
location, the subtree heading be marked DONE, and the current
time will be added.
When called with a single prefix argument FIND-DONE, find whole trees without any
open TODO items and archive them (after getting confirmation from the user).
When called with a double prefix argument, find whole trees with timestamps before
today and archive them (after getting confirmation from the user).
If the cursor is not at a headline when these commands are called, try all level
1 trees. If the cursor is on a headline, only try the direct children of
this heading."
When called with a single prefix argument FIND-DONE, find whole
trees without any open TODO items and archive them (after getting
confirmation from the user). When called with a double prefix
argument, find whole trees with timestamps before today and
archive them (after getting confirmation from the user). If the
cursor is not at a headline when these commands are called, try
all level 1 trees. If the cursor is on a headline, only try the
direct children of this heading."
(interactive "P")
(if (and (org-region-active-p) org-loop-over-headlines-in-active-region)
(let ((cl (if (eq org-loop-over-headlines-in-active-region 'start-level)
@ -224,7 +226,7 @@ this heading."
`(progn (setq org-map-continue-from (progn (org-back-to-heading) (point)))
(org-archive-subtree ,find-done))
org-loop-over-headlines-in-active-region
cl (if (outline-invisible-p) (org-end-of-subtree nil t))))
cl (if (org-invisible-p) (org-end-of-subtree nil t))))
(cond
((equal find-done '(4)) (org-archive-all-done))
((equal find-done '(16)) (org-archive-all-old))
@ -416,7 +418,7 @@ Archiving time is retained in the ARCHIVE_TIME node property."
(when (org-at-heading-p)
(org-archive-to-archive-sibling)))
org-loop-over-headlines-in-active-region
cl (if (outline-invisible-p) (org-end-of-subtree nil t))))
cl (if (org-invisible-p) (org-end-of-subtree nil t))))
(save-restriction
(widen)
(let (b e pos leader level)
@ -564,7 +566,7 @@ the children that do not contain any open TODO items."
(org-map-entries
`(org-toggle-archive-tag ,find-done)
org-loop-over-headlines-in-active-region
cl (if (outline-invisible-p) (org-end-of-subtree nil t))))
cl (if (org-invisible-p) (org-end-of-subtree nil t))))
(if find-done
(org-archive-all-done 'tag)
(let (set)
@ -585,7 +587,7 @@ the children that do not contain any open TODO items."
(org-map-entries
'org-archive-set-tag
org-loop-over-headlines-in-active-region
cl (if (outline-invisible-p) (org-end-of-subtree nil t))))
cl (if (org-invisible-p) (org-end-of-subtree nil t))))
(org-toggle-tag org-archive-tag 'on)))
;;;###autoload

View File

@ -441,7 +441,8 @@ The attachment is created as an Emacs buffer."
(unless (file-exists-p file)
(error "No such attachment: %s" file))
(delete-file file)
(org-attach-commit)))
(when org-attach-commit
(org-attach-commit))))
(defun org-attach-delete-all (&optional force)
"Delete all attachments from the current task.
@ -457,14 +458,16 @@ A safer way is to open the directory in dired and delete from there."
(y-or-n-p "Are you sure you want to remove all attachments of this entry? ")))
(shell-command (format "rm -fr %s" attach-dir))
(message "Attachment directory removed")
(org-attach-commit)
(when org-attach-commit
(org-attach-commit))
(org-attach-untag))))
(defun org-attach-sync ()
"Synchronize the current tasks with its attachments.
This can be used after files have been added externally."
(interactive)
(org-attach-commit)
(when org-attach-commit
(org-attach-commit))
(when (and org-attach-file-list-property (not org-attach-inherited))
(org-entry-delete (point) org-attach-file-list-property))
(let ((attach-dir (org-attach-dir)))

View File

@ -1587,9 +1587,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)))
(apply #'encode-time (org-parse-time-string te nil t)))
(float-time
(apply #'encode-time (org-parse-time-string ts))))
(apply #'encode-time (org-parse-time-string ts nil t))))
h (floor (/ s 3600))
s (- s (* 3600 h))
m (floor (/ s 60))
@ -1823,9 +1823,9 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes."
(setq ts (match-string 2)
te (match-string 3)
ts (float-time
(apply #'encode-time (org-parse-time-string ts)))
(apply #'encode-time (org-parse-time-string ts nil t)))
te (float-time
(apply #'encode-time (org-parse-time-string te)))
(apply #'encode-time (org-parse-time-string te nil t)))
ts (if tstart (max ts tstart) ts)
te (if tend (min te tend) te)
dt (- te ts)
@ -2701,14 +2701,16 @@ LEVEL is an integer. Indent by two spaces per level above 1."
(pcase-let ((`(,month ,day ,year) (calendar-gregorian-from-absolute ts)))
(setq ts (float-time (encode-time 0 0 0 day month year)))))
(ts
(setq ts (float-time (apply #'encode-time (org-parse-time-string ts))))))
(setq ts (float-time
(apply #'encode-time (org-parse-time-string ts nil t))))))
(cond
((numberp te)
;; Likewise for te.
(pcase-let ((`(,month ,day ,year) (calendar-gregorian-from-absolute te)))
(setq te (float-time (encode-time 0 0 0 day month year)))))
(te
(setq te (float-time (apply #'encode-time (org-parse-time-string te))))))
(setq te (float-time
(apply #'encode-time (org-parse-time-string te nil t))))))
(setq tsb
(if (eq step0 'week)
(- ts (* 86400 (- (nth 6 (decode-time (seconds-to-time ts))) ws)))
@ -2885,9 +2887,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)))
(apply #'encode-time (org-parse-time-string te nil t)))
(float-time
(apply #'encode-time (org-parse-time-string ts))))
(apply #'encode-time (org-parse-time-string ts nil t))))
neg (< s 0)
s (abs s)
h (floor (/ s 3600))
@ -2964,7 +2966,7 @@ The details of what will be saved are regulated by the variable
(let ((org-clock-in-resume 'auto-restart)
(org-clock-auto-clock-resolution nil))
(org-clock-in)
(when (outline-invisible-p) (org-show-context))))))
(when (org-invisible-p) (org-show-context))))))
(_ nil)))))
;; Suggested bindings

View File

@ -1085,7 +1085,7 @@ as days/hours/minutes/seconds."
((string-match-p org-ts-regexp s)
(floor
(- org-columns--time
(float-time (apply #'encode-time (org-parse-time-string s))))))
(float-time (apply #'encode-time (org-parse-time-string s nil t))))))
;; Match own output for computations in upper levels.
((string-match "\\([0-9]+\\)d \\([0-9]+\\)h \\([0-9]+\\)m \\([0-9]+\\)s" s)
(+ (* 86400 (string-to-number (match-string 1 s)))

View File

@ -61,7 +61,7 @@
(defalias 'gui-get-selection 'x-get-selection))
;;; Obsolete aliases (remove them once the next major release is released).
;;; Obsolete aliases (remove them after the next major release).
;;;; XEmacs compatibility, now removed.
(define-obsolete-function-alias 'org-activate-mark 'activate-mark)
@ -191,6 +191,10 @@ Counting starts at 1."
(define-obsolete-variable-alias 'org-html-style 'org-html-head "24.4")
(define-obsolete-function-alias 'org-insert-columns-dblock
'org-columns-insert-dblock "Org 9.0")
(define-obsolete-function-alias 'org-activate-bracket-links
'org-activate-links "Org 9.0")
(define-obsolete-function-alias 'org-activate-plain-links 'ignore "Org 9.0")
(define-obsolete-function-alias 'org-activate-angle-links 'ignore "Org 9.0")
(defun org-in-fixed-width-region-p ()
"Non-nil if point in a fixed-width region."

View File

@ -176,7 +176,7 @@ See `org-crypt-disable-auto-save'."
(let ((start-heading (point)))
(org-end-of-meta-data)
(unless (looking-at-p "-----BEGIN PGP MESSAGE-----")
(let ((folded (outline-invisible-p))
(let ((folded (org-invisible-p))
(crypt-key (org-crypt-key-for-heading))
(beg (point)))
(goto-char start-heading)
@ -204,7 +204,7 @@ See `org-crypt-disable-auto-save'."
(heading-was-invisible-p
(save-excursion
(outline-end-of-heading)
(outline-invisible-p))))
(org-invisible-p))))
(org-end-of-meta-data)
(when (looking-at "-----BEGIN PGP MESSAGE-----")
(org-crypt-check-auto-save)

View File

@ -22,79 +22,21 @@
;;; Commentary:
;;
;; Org syntax can be divided into three categories: "Greater
;; elements", "Elements" and "Objects".
;; See <http://orgmode.org/worg/dev/org-syntax.html> for details about
;; Org syntax.
;;
;; Elements are related to the structure of the document. Indeed, all
;; elements are a cover for the document: each position within belongs
;; to at least one element.
;;
;; An element always starts and ends at the beginning of a line. With
;; a few exceptions (`clock', `headline', `inlinetask', `item',
;; `planning', `property-drawer', `node-property', `section' and
;; `table-row' types), it can also accept a fixed set of keywords as
;; attributes. Those are called "affiliated keywords" to distinguish
;; them from other keywords, which are full-fledged elements. Almost
;; all affiliated keywords are referenced in
;; `org-element-affiliated-keywords'; the others are export attributes
;; and start with "ATTR_" prefix.
;;
;; Element containing other elements (and only elements) are called
;; greater elements. Concerned types are: `center-block', `drawer',
;; `dynamic-block', `footnote-definition', `headline', `inlinetask',
;; `item', `plain-list', `property-drawer', `quote-block', `section'
;; and `special-block'.
;;
;; Other element types are: `babel-call', `clock', `comment',
;; `comment-block', `diary-sexp', `example-block', `export-block',
;; `fixed-width', `horizontal-rule', `keyword', `latex-environment',
;; `node-property', `paragraph', `planning', `src-block', `table',
;; `table-row' and `verse-block'. Among them, `paragraph' and
;; `verse-block' types can contain Org objects and plain text.
;;
;; Objects are related to document's contents. Some of them are
;; recursive. Associated types are of the following: `bold', `code',
;; `entity', `export-snippet', `footnote-reference',
;; `inline-babel-call', `inline-src-block', `italic',
;; `latex-fragment', `line-break', `link', `macro', `radio-target',
;; `statistics-cookie', `strike-through', `subscript', `superscript',
;; `table-cell', `target', `timestamp', `underline' and `verbatim'.
;;
;; Some elements also have special properties whose value can hold
;; objects themselves (e.g. an item tag or a headline name). Such
;; values are called "secondary strings". Any object belongs to
;; either an element or a secondary string.
;;
;; Notwithstanding affiliated keywords, each greater element, element
;; and object has a fixed set of properties attached to it. Among
;; them, four are shared by all types: `:begin' and `:end', which
;; refer to the beginning and ending buffer positions of the
;; considered element or object, `:post-blank', which holds the number
;; of blank lines, or white spaces, at its end and `:parent' which
;; refers to the element or object containing it. Greater elements,
;; elements and objects containing objects will also have
;; `:contents-begin' and `:contents-end' properties to delimit
;; contents. Eventually, All elements have a `:post-affiliated'
;; property referring to the buffer position after all affiliated
;; keywords, if any, or to their beginning position otherwise.
;;
;; At the lowest level, a `:parent' property is also attached to any
;; string, as a text property.
;;
;; Lisp-wise, an element or an object can be represented as a list.
;; Lisp-wise, a syntax object can be represented as a list.
;; It follows the pattern (TYPE PROPERTIES CONTENTS), where:
;; TYPE is a symbol describing the Org element or object.
;; TYPE is a symbol describing the object.
;; PROPERTIES is the property list attached to it. See docstring of
;; appropriate parsing function to get an exhaustive
;; list.
;; CONTENTS is a list of elements, objects or raw strings contained
;; in the current element or object, when applicable.
;; appropriate parsing function to get an exhaustive list.
;; CONTENTS is a list of syntax objects or raw strings contained
;; in the current object, when applicable.
;;
;; An Org buffer is a nested list of such elements and objects, whose
;; type is `org-data' and properties is nil.
;; For the whole document, TYPE is `org-data' and PROPERTIES is nil.
;;
;; The first part of this file defines Org syntax, while the second
;; one provide accessors and setters functions.
;; The first part of this file defines constants for the Org syntax,
;; while the second one provide accessors and setters functions.
;;
;; The next part implements a parser and an interpreter for each
;; element and object type in Org syntax.
@ -879,14 +821,14 @@ Assume point is at the beginning of the footnote definition."
(match-string-no-properties 1)))
(begin (car affiliated))
(post-affiliated (point))
(ending
(end
(save-excursion
(end-of-line)
(cond
((not
(re-search-forward org-element--footnote-separator limit t))
limit)
((eq (char-after (match-beginning 0)) ?\[)
((eq ?\[ (char-after (match-beginning 0)))
;; At a new footnote definition, make sure we end
;; before any affiliated keyword above.
(forward-line -1)
@ -894,26 +836,27 @@ Assume point is at the beginning of the footnote definition."
(looking-at-p org-element--affiliated-re))
(forward-line -1))
(line-beginning-position 2))
(t (match-beginning 0)))))
((eq ?* (char-after (match-beginning 0))) (match-beginning 0))
(t (skip-chars-forward " \r\t\n" limit)
(if (= limit (point)) limit (line-beginning-position))))))
(contents-begin
(progn
(search-forward "]")
(skip-chars-forward " \r\t\n" ending)
(cond ((= (point) ending) nil)
((= (line-beginning-position) post-affiliated) (point))
(t (line-beginning-position)))))
(contents-end (and contents-begin ending))
(end (progn (goto-char ending)
(skip-chars-forward " \r\t\n" limit)
(if (eobp) (point) (line-beginning-position)))))
(progn (search-forward "]")
(skip-chars-forward " \r\t\n" end)
(cond ((= (point) end) nil)
((= (line-beginning-position) post-affiliated) (point))
(t (line-beginning-position)))))
(contents-end
(progn (goto-char end)
(skip-chars-backward " \r\t\n")
(line-beginning-position 2))))
(list 'footnote-definition
(nconc
(list :label label
:begin begin
:end end
:contents-begin contents-begin
:contents-end contents-end
:post-blank (count-lines ending end)
:contents-end (and contents-begin contents-end)
:post-blank (count-lines contents-end end)
:post-affiliated post-affiliated)
(cdr affiliated))))))
@ -1695,30 +1638,37 @@ containing `:call', `:inside-header', `:arguments',
(save-excursion
(let* ((begin (car affiliated))
(post-affiliated (point))
(value (progn (search-forward ":" nil t)
(before-blank (line-beginning-position 2))
(value (progn (search-forward ":" before-blank t)
(skip-chars-forward " \t")
(org-trim
(buffer-substring-no-properties
(point) (line-end-position)))))
(pos-before-blank (progn (forward-line) (point)))
(end (progn (skip-chars-forward " \r\t\n" limit)
(if (eobp) (point) (line-beginning-position))))
(valid-value
(string-match
"\\([^()\n]+?\\)\\(?:\\[\\(.*?\\)\\]\\)?(\\(.*\\))[ \t]*\\(.*\\)"
value)))
(call
(or (org-string-nw-p
(buffer-substring-no-properties
(point) (progn (skip-chars-forward "^[]()" before-blank)
(point))))))
(inside-header (org-element--parse-paired-brackets ?\[))
(arguments (org-string-nw-p
(org-element--parse-paired-brackets ?\()))
(end-header
(org-string-nw-p
(org-trim
(buffer-substring-no-properties (point) (line-end-position)))))
(end (progn (forward-line)
(skip-chars-forward " \r\t\n" limit)
(if (eobp) (point) (line-beginning-position)))))
(list 'babel-call
(nconc
(list :call (and valid-value (match-string 1 value))
:inside-header (and valid-value
(org-string-nw-p (match-string 2 value)))
:arguments (and valid-value
(org-string-nw-p (match-string 3 value)))
:end-header (and valid-value
(org-string-nw-p (match-string 4 value)))
(list :call call
:inside-header inside-header
:arguments arguments
:end-header end-header
:begin begin
:end end
:value value
:post-blank (count-lines pos-before-blank end)
:post-blank (count-lines before-blank end)
:post-affiliated post-affiliated)
(cdr affiliated))))))

View File

@ -712,14 +712,18 @@ Return the number of footnotes removed."
(let ((def-re (format "^\\[fn:%s\\]" (regexp-quote label)))
(ndef 0))
(while (re-search-forward def-re nil t)
(let ((full-def (org-footnote-at-definition-p)))
(when full-def
;; Remove the footnote, and all blank lines before it.
(goto-char (nth 1 full-def))
(skip-chars-backward " \r\t\n")
(unless (bolp) (forward-line))
(delete-region (point) (nth 2 full-def))
(cl-incf ndef))))
(pcase (org-footnote-at-definition-p)
(`(,_ ,start ,end ,_)
;; Remove the footnote, and all blank lines before it.
(delete-region (progn
(goto-char start)
(skip-chars-backward " \r\t\n")
(if (bobp) (point) (line-beginning-position 2)))
(progn
(goto-char end)
(skip-chars-backward " \r\t\n")
(if (bobp) (point) (line-beginning-position 2))))
(cl-incf ndef))))
ndef)))
(defun org-footnote-delete (&optional label)

View File

@ -110,6 +110,51 @@ The default is to make it look like whitespace. But you may find it
useful to make it ever so slightly different."
:group 'org-faces)
(defvar org-indent--text-line-prefixes nil
"Vector containing line prefixes strings for regular text.")
(defvar org-indent--heading-line-prefixes nil
"Vector containing line prefix strings for headlines.")
(defvar org-indent--inlinetask-line-prefixes nil
"Vector containing line prefix strings for inline tasks.")
(defconst org-indent--deepest-level 50
"Maximum theoretical headline depth.")
(defun org-indent--compute-prefixes ()
"Compute prefix strings for regular text and headlines."
(setq org-indent--heading-line-prefixes
(make-vector org-indent--deepest-level nil))
(setq org-indent--inlinetask-line-prefixes
(make-vector org-indent--deepest-level nil))
(setq org-indent--text-line-prefixes
(make-vector org-indent--deepest-level nil))
(dotimes (n org-indent--deepest-level)
(let ((indentation (if (<= n 1) 0
(* (1- org-indent-indentation-per-level)
(1- n)))))
;; Headlines line prefixes.
(let ((heading-prefix (make-string indentation ?*)))
(aset org-indent--heading-line-prefixes
n
(org-add-props heading-prefix nil 'face 'org-indent))
;; Inline tasks line prefixes
(aset org-indent--inlinetask-line-prefixes
n
(org-add-props (if (bound-and-true-p org-inlinetask-show-first-star)
(concat org-indent-inlinetask-first-star
(substring heading-prefix 1))
heading-prefix)
nil 'face 'org-indent)))
;; Text line prefixes.
(aset org-indent--text-line-prefixes
n
(concat (org-add-props (make-string (+ n indentation) ?\s)
nil 'face 'org-indent)
(and (> n 0)
(char-to-string org-indent-boundary-char)))))))
(defsubst org-indent-remove-properties (beg end)
"Remove indentations between BEG and END."
(org-with-silent-modifications
@ -137,14 +182,15 @@ during idle time."
(setq-local org-hide-leading-stars-before-indent-mode
org-hide-leading-stars)
(setq-local org-hide-leading-stars t))
(org-indent--compute-prefixes)
(add-hook 'filter-buffer-substring-functions
(lambda (fun start end delete)
(org-indent-remove-properties-from-string
(funcall fun start end delete)))
nil t)
(lambda (fun start end delete)
(org-indent-remove-properties-from-string
(funcall fun start end delete)))
nil t)
(add-hook 'after-change-functions 'org-indent-refresh-maybe nil 'local)
(add-hook 'before-change-functions
'org-indent-notify-modified-headline nil 'local)
'org-indent-notify-modified-headline nil 'local)
(and font-lock-mode (org-restart-font-lock))
(org-indent-remove-properties (point-min) (point-max))
;; Submit current buffer to initialize agent. If it's the first
@ -247,27 +293,16 @@ expected indentation when wrapping line.
When optional argument HEADING is non-nil, assume line is at
a heading. Moreover, if is is `inlinetask', the first star will
have `org-warning' face."
(let* ((stars (if (<= level 1) ""
(make-string (* (1- org-indent-indentation-per-level)
(1- level))
?*)))
(line
(cond
((and (bound-and-true-p org-inlinetask-show-first-star)
(eq heading 'inlinetask))
(concat org-indent-inlinetask-first-star
(org-add-props (substring stars 1) nil 'face 'org-hide)))
(heading (org-add-props stars nil 'face 'org-hide))
(t (concat (org-add-props (concat stars (make-string level ?*))
nil 'face 'org-indent)
(and (> level 0)
(char-to-string org-indent-boundary-char))))))
(let* ((line (aref (pcase heading
(`nil org-indent--text-line-prefixes)
(`inlinetask org-indent--inlinetask-line-prefixes)
(_ org-indent--heading-line-prefixes))
level))
(wrap
(org-add-props
(concat stars
(make-string level ?*)
(if heading " "
(make-string (+ indentation (min level 1)) ?\s)))
(concat line
(if heading (concat (make-string level ?*) " ")
(make-string indentation ?\s)))
nil 'face 'org-indent)))
;; Add properties down to the next line to indent empty lines.
(add-text-properties (line-beginning-position) (line-beginning-position 2)

View File

@ -154,8 +154,8 @@
(declare-function org-timer-item "org-timer" (&optional arg))
(declare-function org-trim "org" (s &optional keep-lead))
(declare-function org-uniquify "org" (list))
(declare-function org-invisible-p "org" (&optional pos))
(declare-function outline-flag-region "outline" (from to flag))
(declare-function outline-invisible-p "outline" (&optional pos))
(declare-function outline-next-heading "outline" ())
(declare-function outline-previous-heading "outline" ())
@ -2256,7 +2256,7 @@ item is invisible."
(unless (or (not itemp)
(save-excursion
(goto-char itemp)
(outline-invisible-p)))
(org-invisible-p)))
(if (save-excursion
(goto-char itemp)
(org-at-item-timer-p))

View File

@ -53,6 +53,7 @@
(declare-function org-element-property "org-element" (property element))
(declare-function org-element-type "org-element" (element))
(declare-function org-file-contents "org" (file &optional noerror))
(declare-function org-in-commented-heading-p "org" (&optional no-inheritance))
(declare-function org-mode "org" ())
(declare-function vc-backend "vc-hooks" (f))
(declare-function vc-call "vc-hooks" (fun file &rest args) t)
@ -191,47 +192,50 @@ as strings, where macro expansion is allowed."
(format "\\`EXPORT_%s\\+?\\'" (regexp-opt keywords)))
record)
(while (re-search-forward "{{{[-A-Za-z0-9_]" nil t)
(let* ((datum (save-match-data (org-element-context)))
(type (org-element-type datum))
(macro
(cond
((eq type 'macro) datum)
;; In parsed keywords and associated node properties,
;; force macro recognition.
((or (and (eq type 'keyword)
(member (org-element-property :key datum) keywords))
(and (eq type 'node-property)
(string-match-p properties-regexp
(org-element-property :key datum))))
(save-excursion
(goto-char (match-beginning 0))
(org-element-macro-parser))))))
(when macro
(let* ((value (org-macro-expand macro templates))
(begin (org-element-property :begin macro))
(signature (list begin
macro
(org-element-property :args macro))))
;; Avoid circular dependencies by checking if the same
;; macro with the same arguments is expanded at the same
;; position twice.
(cond ((member signature record)
(error "Circular macro expansion: %s"
(org-element-property :key macro)))
(value
(push signature record)
(delete-region
begin
;; Preserve white spaces after the macro.
(progn (goto-char (org-element-property :end macro))
(skip-chars-backward " \t")
(point)))
;; Leave point before replacement in case of
;; recursive expansions.
(save-excursion (insert value)))
(finalize
(error "Undefined Org macro: %s; aborting"
(org-element-property :key macro)))))))))))
(unless (save-match-data (org-in-commented-heading-p))
(let* ((datum (save-match-data (org-element-context)))
(type (org-element-type datum))
(macro
(cond
((eq type 'macro) datum)
;; In parsed keywords and associated node
;; properties, force macro recognition.
((or (and (eq type 'keyword)
(member (org-element-property :key datum)
keywords))
(and (eq type 'node-property)
(string-match-p properties-regexp
(org-element-property :key
datum))))
(save-excursion
(goto-char (match-beginning 0))
(org-element-macro-parser))))))
(when macro
(let* ((value (org-macro-expand macro templates))
(begin (org-element-property :begin macro))
(signature (list begin
macro
(org-element-property :args macro))))
;; Avoid circular dependencies by checking if the same
;; macro with the same arguments is expanded at the
;; same position twice.
(cond ((member signature record)
(error "Circular macro expansion: %s"
(org-element-property :key macro)))
(value
(push signature record)
(delete-region
begin
;; Preserve white spaces after the macro.
(progn (goto-char (org-element-property :end macro))
(skip-chars-backward " \t")
(point)))
;; Leave point before replacement in case of
;; recursive expansions.
(save-excursion (insert value)))
(finalize
(error "Undefined Org macro: %s; aborting"
(org-element-property :key macro))))))))))))
(defun org-macro-escape-arguments (&rest args)
"Build macro's arguments string from ARGS.

View File

@ -810,45 +810,46 @@ A coderef format regexp can only match at the end of a line."
(org-footnote-goto-definition label)
(backward-char)
(org-element-context)))
(inline (eq (org-element-type definition) 'footnote-reference))
(inline? (eq 'footnote-reference (org-element-type definition)))
(contents
(let ((c (org-with-wide-buffer
(org-trim (buffer-substring-no-properties
(org-element-property :begin definition)
(org-element-property :end definition))))))
(add-text-properties
0
(progn (string-match (if inline "\\`\\[fn:.*?:" "\\`.*?\\]") c)
(match-end 0))
'(read-only "Cannot edit footnote label" front-sticky t
rear-nonsticky t)
c)
(when inline
(let ((l (length c)))
(add-text-properties
(1- l) l
'(read-only "Cannot edit past footnote reference"
front-sticky nil rear-nonsticky nil)
c)))
c)))
(org-with-wide-buffer
(buffer-substring-no-properties
(or (org-element-property :post-affiliated definition)
(org-element-property :begin definition))
(cond
(inline? (1+ (org-element-property :contents-end definition)))
((org-element-property :contents-end definition))
(t (goto-char (org-element-property :post-affiliated definition))
(line-end-position)))))))
(add-text-properties
0
(progn (string-match (if inline? "\\`\\[fn:.*?:" "\\`.*?\\]") contents)
(match-end 0))
'(read-only "Cannot edit footnote label" front-sticky t rear-nonsticky t)
contents)
(when inline?
(let ((l (length contents)))
(add-text-properties
(1- l) l
'(read-only "Cannot edit past footnote reference"
front-sticky nil rear-nonsticky nil)
contents)))
(org-src--edit-element
definition
(format "*Edit footnote [%s]*" label)
#'org-mode
`(lambda ()
(if ,(not inline) (delete-region (point) (search-forward "]"))
(delete-region (point) (search-forward ":" nil t 2))
(delete-region (1- (point-max)) (point-max))
(when (re-search-forward "\n[ \t]*\n" nil t)
(user-error "Inline definitions cannot contain blank lines"))
;; If footnote reference belongs to a table, make sure to
;; remove any newline characters in order to preserve
;; table's structure.
(when ,(org-element-lineage definition '(table-cell))
(while (search-forward "\n" nil t) (delete-char -1)))))
(concat contents
(and (not (org-element-property :contents-begin definition))
" "))
(lambda ()
(if (not inline?) (delete-region (point) (search-forward "]"))
(delete-region (point) (search-forward ":" nil t 2))
(delete-region (1- (point-max)) (point-max))
(when (re-search-forward "\n[ \t]*\n" nil t)
(user-error "Inline definitions cannot contain blank lines"))
;; If footnote reference belongs to a table, make sure to
;; remove any newline characters in order to preserve
;; table's structure.
(when (org-element-lineage definition '(table-cell))
(while (search-forward "\n" nil t) (replace-match "")))))
contents
'remote))
;; Report success.
t))
@ -1065,8 +1066,10 @@ Throw an error if there is no such buffer."
(code (and write-back (org-src--contents-for-write-back))))
(set-buffer-modified-p nil)
;; Switch to source buffer. Kill sub-editing buffer.
(let ((edit-buffer (current-buffer)))
(org-src-switch-to-buffer (marker-buffer beg) 'exit)
(let ((edit-buffer (current-buffer))
(source-buffer (marker-buffer beg)))
(unless source-buffer (error "Source buffer disappeared. Aborting"))
(org-src-switch-to-buffer source-buffer 'exit)
(kill-buffer edit-buffer))
;; Insert modified code. Ensure it ends with a newline character.
(org-with-wide-buffer
@ -1085,7 +1088,7 @@ Throw an error if there is no such buffer."
(cond
;; Block is hidden; move at start of block.
((cl-some (lambda (o) (eq (overlay-get o 'invisible) 'org-hide-block))
(overlays-at (point)))
(overlays-at (point)))
(beginning-of-line 0))
(write-back (org-src--goto-coordinates coordinates beg end))))
;; Clean up left-over markers and restore window configuration.

View File

@ -5964,12 +5964,12 @@ This includes angle, plain, and bracket links."
(while (re-search-forward org-any-link-re limit t)
(let* ((start (match-beginning 0))
(end (match-end 0))
(type (cond ((eq ?< (char-after start)) 'angle)
((eq ?\[ (char-after (1+ start))) 'bracket)
(t 'plain))))
(when (and (memq type org-highlight-links)
(style (cond ((eq ?< (char-after start)) 'angle)
((eq ?\[ (char-after (1+ start))) 'bracket)
(t 'plain))))
(when (and (memq style org-highlight-links)
;; Do not confuse plain links with tags.
(not (and (eq type 'plain)
(not (and (eq style 'plain)
(let ((face (get-text-property
(max (1- start) (point-min)) 'face)))
(if (consp face) (memq 'org-tag face)
@ -5978,6 +5978,7 @@ This includes angle, plain, and bracket links."
(goto-char start)
(save-match-data (org-element-link-parser))))
(link (org-element-property :raw-link link-object))
(type (org-element-property :type link-object))
(path (org-element-property :path link-object))
(properties ;for link's visible part
(list
@ -6001,7 +6002,7 @@ This includes angle, plain, and bracket links."
'font-lock-multiline t)))
(org-remove-flyspell-overlays-in start end)
(org-rear-nonsticky-at end)
(if (not (eq 'bracket type))
(if (not (eq 'bracket style))
(add-text-properties start end properties)
;; Handle invisible parts in bracket links.
(remove-text-properties start end '(invisible nil))
@ -6019,7 +6020,7 @@ This includes angle, plain, and bracket links."
(org-rear-nonsticky-at visible-end)))
(let ((f (org-link-get-parameter type :activate-func)))
(when (functionp f)
(funcall f start end path (eq type 'bracket))))
(funcall f start end path (eq style 'bracket))))
(throw :exit t))))) ;signal success
nil))
@ -6983,6 +6984,11 @@ Use `\\[org-edit-special]' to edit table.el tables"))
(defvar org-called-with-limited-levels nil
"Non-nil when `org-with-limited-levels' is currently active.")
(defun org-invisible-p (&optional pos)
"Non-nil if the character after POS is invisible.
If POS is nil, use `point' instead."
(get-char-property (or pos (point)) 'invisible))
(defun org-cycle-internal-local ()
"Do the local cycling action."
(let ((goal-column 0) eoh eol eos has-children children-skipped struct)
@ -7026,7 +7032,7 @@ Use `\\[org-edit-special]' to edit table.el tables"))
(save-excursion
(goto-char eos)
(outline-next-heading)
(when (outline-invisible-p) (org-flag-heading nil))))
(when (org-invisible-p) (org-flag-heading nil))))
((and (or (>= eol eos)
(not (string-match "\\S-" (buffer-substring eol eos))))
(or has-children
@ -7060,7 +7066,7 @@ Use `\\[org-edit-special]' to edit table.el tables"))
(save-excursion
(goto-char eos)
(outline-next-heading)
(when (outline-invisible-p) (org-flag-heading nil)))
(when (org-invisible-p) (org-flag-heading nil)))
(setq org-cycle-subtree-status 'children)
(unless (org-before-first-heading-p)
(run-hook-with-args 'org-cycle-hook 'children)))
@ -7234,9 +7240,9 @@ This function is the default value of the hook `org-cycle-hook'."
;; Properly fold already folded siblings
(goto-char (point-min))
(while (re-search-forward re nil t)
(when (and (not (outline-invisible-p))
(when (and (not (org-invisible-p))
(save-excursion
(goto-char (point-at-eol)) (outline-invisible-p)))
(goto-char (point-at-eol)) (org-invisible-p)))
(outline-hide-entry))))
(org-cycle-show-empty-lines 'overview)
(org-cycle-hide-drawers 'overview)))))
@ -7589,7 +7595,7 @@ With a prefix argument, use the alternative interface: e.g., if
(progn
(org-mark-ring-push org-goto-start-pos)
(goto-char selected-point)
(when (or (outline-invisible-p) (org-invisible-p2))
(when (or (org-invisible-p) (org-invisible-p2))
(org-show-context 'org-goto)))
(message "Quit"))))
@ -7630,7 +7636,7 @@ or nil."
(if (and (boundp 'org-goto-start-pos)
(integer-or-marker-p org-goto-start-pos))
(progn (goto-char org-goto-start-pos)
(when (outline-invisible-p)
(when (org-invisible-p)
(org-show-set-visibility 'lineage)))
(goto-char (point-min)))
(let (org-special-ctrl-a/e) (org-beginning-of-line))
@ -8542,7 +8548,7 @@ case."
(setq beg (point)))
(save-match-data
(save-excursion (outline-end-of-heading)
(setq folded (outline-invisible-p)))
(setq folded (org-invisible-p)))
(progn (org-end-of-subtree nil t)
(unless (eobp) (backward-char))))
(outline-next-heading)
@ -8638,7 +8644,7 @@ useful if the caller implements cut-and-paste as copy-then-paste-then-cut."
(if nosubtrees
(outline-next-heading)
(save-excursion (outline-end-of-heading)
(setq folded (outline-invisible-p)))
(setq folded (org-invisible-p)))
(ignore-errors (org-forward-heading-same-level (1- n) t))
(org-end-of-subtree t t)))
;; Include the end of an inlinetask
@ -8691,7 +8697,7 @@ When REMOVE is non-nil, remove the subtree from the clipboard."
(substitute-command-keys
"The kill is not a (set of) tree(s) - please use \\[yank] to yank anyway")))
(org-with-limited-levels
(let* ((visp (not (outline-invisible-p)))
(let* ((visp (not (org-invisible-p)))
(txt tree)
(^re_ "\\(\\*+\\)[ \t]*")
(old-level (if (string-match org-outline-regexp-bol txt)
@ -8748,7 +8754,7 @@ When REMOVE is non-nil, remove the subtree from the clipboard."
(goto-char beg)
(skip-chars-forward " \t\n\r")
(setq beg (point))
(when (and (outline-invisible-p) visp)
(when (and (org-invisible-p) visp)
(save-excursion (outline-show-heading)))
;; Shift if necessary
(unless (= shift 0)
@ -10600,7 +10606,7 @@ If the link is in hidden text, expose it."
(if (funcall srch-fun org-any-link-re nil t)
(progn
(goto-char (match-beginning 0))
(when (outline-invisible-p) (org-show-context)))
(when (org-invisible-p) (org-show-context)))
(goto-char pos)
(setq org-link-search-failed t)
(message "No further link found"))))
@ -11307,7 +11313,7 @@ or to another Org file, automatically push the old position onto the ring."
(setq m (car p))
(pop-to-buffer-same-window (marker-buffer m))
(goto-char m)
(when (or (outline-invisible-p) (org-invisible-p2)) (org-show-context 'mark-goto))))
(when (or (org-invisible-p) (org-invisible-p2)) (org-show-context 'mark-goto))))
(defun org-add-angle-brackets (s)
(unless (equal (substring s 0 1) "<") (setq s (concat "<" s)))
@ -12546,7 +12552,7 @@ When called through ELisp, arg is also interpreted in the following way:
(org-map-entries
`(org-todo ,arg)
org-loop-over-headlines-in-active-region
cl (when (outline-invisible-p) (org-end-of-subtree nil t))))
cl (when (org-invisible-p) (org-end-of-subtree nil t))))
(when (equal arg '(16)) (setq arg 'nextset))
(when (equal arg -1) (org-cancel-repeater) (setq arg nil))
(let ((org-blocker-hook org-blocker-hook)
@ -13457,7 +13463,7 @@ can either be an Org date like \"2011-07-24\" or a delta like \"+2d\"."
(if (eq org-loop-over-headlines-in-active-region 'start-level)
'region-start-level
'region)
(lambda () (when (outline-invisible-p) (org-end-of-subtree nil t))))
(lambda () (when (org-invisible-p) (org-end-of-subtree nil t))))
(org--deadline-or-schedule arg 'deadline time)))
(defun org-schedule (arg &optional time)
@ -13474,7 +13480,7 @@ either be an Org date like \"2011-07-24\" or a delta like \"+2d\"."
(if (eq org-loop-over-headlines-in-active-region 'start-level)
'region-start-level
'region)
(lambda () (when (outline-invisible-p) (org-end-of-subtree nil t))))
(lambda () (when (org-invisible-p) (org-end-of-subtree nil t))))
(org--deadline-or-schedule arg 'scheduled time)))
(defun org-get-scheduled-time (pom &optional inherit)
@ -15021,7 +15027,7 @@ When JUST-ALIGN is non-nil, only align tags."
#'org-set-tags
org-loop-over-headlines-in-active-region
cl
'(when (outline-invisible-p) (org-end-of-subtree nil t))))
'(when (org-invisible-p) (org-end-of-subtree nil t))))
(let ((org-setting-tags t))
(if arg
(save-excursion
@ -17937,11 +17943,17 @@ 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)
(defun org-parse-time-string (s &optional nodefault zone)
"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."
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."
(cond ((string-match org-ts-regexp0 s)
(list 0
(when (or (match-beginning 8) (not nodefault))
@ -17951,8 +17963,12 @@ hour and minute fields will be nil if not given."
(string-to-number (match-string 4 s))
(string-to-number (match-string 3 s))
(string-to-number (match-string 2 s))
nil nil nil))
nil nil zone))
((string-match "^<[^>]+>$" s)
;; FIXME: `decode-time' needs to be called with ZONE as its
;; second argument. However, this requires at least Emacs
;; 25.1. We can do it when we switch to this version as our
;; minimal requirement.
(decode-time (seconds-to-time (org-matcher-time s))))
(t (error "Not a standard Org time string: %s" s))))
@ -24026,16 +24042,18 @@ interactive command with similar behavior."
"Check if point is at a character currently not visible.
This version does not only check the character property, but also
`visible-mode'."
;; Early versions of noutline don't have `outline-invisible-p'.
(unless (bound-and-true-p visible-mode)
(outline-invisible-p)))
(org-invisible-p)))
(defun org-invisible-p2 ()
"Check if point is at a character currently not visible."
"Check if point is at a character currently not visible.
If the point is at EOL (and not at the beginning of a buffer too),
move it back by one char before doing this check."
(save-excursion
(when (and (eolp) (not (bobp))) (backward-char 1))
;; Early versions of noutline don't have `outline-invisible-p'.
(outline-invisible-p)))
(when (and (eolp) (not (bobp)))
(backward-char 1))
(org-invisible-p)))
(defun org-back-to-heading (&optional invisible-ok)
"Call `outline-back-to-heading', but provide a better error message."
@ -24305,7 +24323,7 @@ non-nil it will also look at invisible ones."
(cond ((< l level) (setq count 0))
((and (= l level)
(or invisible-ok
(not (outline-invisible-p
(not (org-invisible-p
(line-beginning-position)))))
(cl-decf count)
(when (= l level) (setq result (point)))))))
@ -24441,7 +24459,7 @@ item, etc. It also provides some special moves for convenience:
;; With no contents, just skip element.
((not contents-begin) (goto-char end))
;; If contents are invisible, skip the element altogether.
((outline-invisible-p (line-end-position))
((org-invisible-p (line-end-position))
(cl-case type
(headline
(org-with-limited-levels (outline-next-visible-heading 1)))
@ -24528,7 +24546,7 @@ convenience:
(org-backward-paragraph))
(t (goto-char (or post-affiliated begin))))
;; Ensure we never leave point invisible.
(when (outline-invisible-p (point)) (beginning-of-visual-line))))
(when (org-invisible-p (point)) (beginning-of-visual-line))))
(defun org-forward-element ()
"Move forward by one element.
@ -24605,7 +24623,7 @@ Move to the previous element at the same level, when possible."
(forward-char))
((memq (org-element-type element) org-element-greater-elements)
;; If contents are hidden, first disclose them.
(when (outline-invisible-p (line-end-position)) (org-cycle))
(when (org-invisible-p (line-end-position)) (org-cycle))
(goto-char (or (org-element-property :contents-begin element)
(user-error "No content for this element"))))
(t (user-error "No inner element")))))
@ -25086,15 +25104,15 @@ ELEMENT is the element at point."
(defun org-bookmark-jump-unhide ()
"Unhide the current position, to show the bookmark location."
(and (derived-mode-p 'org-mode)
(or (outline-invisible-p)
(or (org-invisible-p)
(save-excursion (goto-char (max (point-min) (1- (point))))
(outline-invisible-p)))
(org-invisible-p)))
(org-show-context 'bookmark-jump)))
(defun org-mark-jump-unhide ()
"Make the point visible with `org-show-context' after jumping to the mark."
(when (and (derived-mode-p 'org-mode)
(outline-invisible-p))
(org-invisible-p))
(org-show-context 'mark-goto)))
(eval-after-load "simple"

View File

@ -269,6 +269,7 @@ be placed after the end of the title."
(defcustom org-texinfo-table-scientific-notation "%s\\,(%s)"
"Format string to display numbers in scientific notation.
The format should have \"%s\" twice, for mantissa and exponent
\(i.e. \"%s\\\\times10^{%s}\").
@ -279,7 +280,12 @@ When nil, no transformation is made."
(const :tag "No formatting" nil)))
(defcustom org-texinfo-def-table-markup "@samp"
"Default setting for @table environments."
"Default markup for first column in two-column tables.
This should an indicating command, e.g., \"@code\", \"@kbd\" or
\"@asis\".
It can be overridden locally using the \":indic\" attribute."
:group 'org-export-texinfo
:type 'string)
@ -459,26 +465,42 @@ anchor name is unique."
(basename
(org-texinfo--sanitize-node
(if (eq (org-element-type datum) 'headline)
(org-export-data (org-export-get-alt-title datum info)
info)
(org-texinfo--sanitize-title
(org-export-get-alt-title datum info) info)
(org-export-get-reference datum info))))
(name basename))
;; Ensure NAME is unique and not reserved node name "Top".
(while (or (equal name "Top") (rassoc name cache))
(setq name (concat basename (number-to-string (cl-incf salt)))))
(setq name (concat basename (format " %d" (cl-incf salt)))))
(plist-put info :texinfo-node-cache (cons (cons datum name) cache))
name))))
(defun org-texinfo--sanitize-node (title)
"Bend string TITLE to node line requirements.
Trim string and collapse multiple whitespace characters as they
are not significant. Also remove the following characters: @
{ } ( ) : . ,"
(replace-regexp-in-string
"[:,.]" ""
are not significant. Replace leading left parenthesis, when
followed by a right parenthesis, with a square bracket. Remove
periods, commas and colons."
(org-trim
(replace-regexp-in-string
"\\`(\\(.*)\\)" "[\\1"
(org-trim (replace-regexp-in-string "[ \t]\\{2,\\}" " " title)))))
"[ \t]+" " "
(replace-regexp-in-string
"[:,.]" ""
(replace-regexp-in-string "\\`(\\(.*?)\\)" "[\\1" title)))))
(defun org-texinfo--sanitize-title (title info)
"Make TITLE suitable as a section name.
TITLE is a string or a secondary string. INFO is the current
export state, as a plist."
(org-export-data-with-backend
title
(org-export-create-backend
:parent 'texinfo
:transcoders '((footnote-reference . ignore)
(link . (lambda (object c i) c))
(radio-target . (lambda (object c i) c))
(target . ignore)))
info))
(defun org-texinfo--sanitize-content (text)
"Escape special characters in string TEXT.
@ -602,7 +624,8 @@ holding export options."
"@titlepage\n"
(when (plist-get info :with-title)
(concat
(format "@title %s\n" (or (plist-get info :texinfo-printed-title) title ""))
(format "@title %s\n"
(or (plist-get info :texinfo-printed-title) title ""))
(let ((subtitle (plist-get info :subtitle)))
(when subtitle
(format "@subtitle %s\n"
@ -628,11 +651,17 @@ holding export options."
"@end titlepage\n\n"
;; Table of contents.
(and (plist-get info :with-toc) "@contents\n\n")
;; Configure Top Node when not for Tex
;; Configure Top Node when not for TeX. Also include contents
;; from the first section of the document.
"@ifnottex\n"
"@node Top\n"
(format "@top %s\n" title)
(and copying "@insertcopying\n")
(let* ((first-section
(org-element-map (plist-get info :parse-tree) 'section
#'identity info t '(headline)))
(top-contents
(org-export-data (org-element-contents first-section) info)))
(and (org-string-nw-p top-contents) (concat "\n" top-contents)))
"@end ifnottex\n\n"
;; Menu.
(org-texinfo-make-menu (plist-get info :parse-tree) info 'master)
@ -710,11 +739,46 @@ holding contextual information."
;;;; Entity
(defun org-texinfo-entity (entity _contents _info)
"Transcode an ENTITY object from Org to Texinfo.
CONTENTS are the definition itself. INFO is a plist holding
contextual information."
(let ((ent (org-element-property :latex entity)))
(if (org-element-property :latex-math-p entity) (format "@math{%s}" ent) ent)))
"Transcode an ENTITY object from Org to Texinfo."
;; Since there is not specific Texinfo entry in entities, use
;; Texinfo-specific commands whenever possible, and fallback to
;; UTF-8 otherwise.
(pcase (org-element-property :name entity)
("AElig" "@AE{}")
("aelig" "@ae{}")
((or "bull" "bullet") "@bullet{}")
("copy" "@copyright{}")
("deg" "@textdegree{}")
((or "dots" "hellip") "@dots{}")
("equiv" "@equiv{}")
((or "euro" "EUR") "@euro{}")
((or "ge" "geq") "@geq{}")
("laquo" "@guillemetleft{}")
("iexcl" "@exclamdown{}")
("imath" "@dotless{i}")
("iquest" "@questiondown{}")
("jmath" "@dotless{j}")
((or "le" "leq") "@leq{}")
("lsaquo" "@guilsinglleft{}")
("mdash" "---")
("minus" "@minus{}")
("nbsp" "@tie{}")
("ndash" "--")
("OElig" "@OE{}")
("oelig" "@oe{}")
("ordf" "@ordf{}")
("ordm" "@ordm{}")
("pound" "@pound{}")
("raquo" "@guillemetright{}")
((or "rArr" "Rightarrow") "@result{}")
("reg" "@registeredsymbol{}")
((or "rightarrow" "to" "rarr") "@arrow{}")
("rsaquo" "@guilsinglright{}")
("thorn" "@th{}")
("THORN" "@TH{}")
((and (pred (string-prefix-p "_")) name) ;spacing entities
(format "@w{%s}" (substring name 1)))
(_ (org-element-property :utf-8 entity))))
;;;; Example Block
@ -746,7 +810,7 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(defun org-texinfo-fixed-width (fixed-width _contents _info)
"Transcode a FIXED-WIDTH element from Org to Texinfo.
CONTENTS is nil. INFO is a plist holding contextual information."
(format "@example\n%s\n@end example"
(format "@example\n%s@end example"
(org-remove-indentation
(org-texinfo--sanitize-content
(org-element-property :value fixed-width)))))
@ -804,7 +868,8 @@ holding contextual information."
(org-export-get-tags headline info)))
(priority (and (plist-get info :with-priority)
(org-element-property :priority headline)))
(text (org-export-data (org-element-property :title headline) info))
(text (org-texinfo--sanitize-title
(org-element-property :title headline) info))
(full-text (funcall (plist-get info :texinfo-format-headline-function)
todo todo-type priority text tags))
(contents (if (org-string-nw-p contents) (concat "\n" contents) "")))
@ -912,23 +977,22 @@ contextual information."
(defun org-texinfo-keyword (keyword _contents info)
"Transcode a KEYWORD element from Org to Texinfo.
CONTENTS is nil. INFO is a plist holding contextual information."
(let ((key (org-element-property :key keyword))
(value (org-element-property :value keyword)))
(cond
((string= key "TEXINFO") value)
((string= key "CINDEX") (format "@cindex %s" value))
((string= key "FINDEX") (format "@findex %s" value))
((string= key "KINDEX") (format "@kindex %s" value))
((string= key "PINDEX") (format "@pindex %s" value))
((string= key "TINDEX") (format "@tindex %s" value))
((string= key "VINDEX") (format "@vindex %s" value))
((string= key "TOC")
(cond ((string-match-p "\\<tables\\>" value)
(concat "@listoffloats "
(org-export-translate "Table" :utf-8 info)))
((string-match-p "\\<listings\\>" value)
(concat "@listoffloats "
(org-export-translate "Listing" :utf-8 info))))))))
(let ((value (org-element-property :value keyword)))
(pcase (org-element-property :key keyword)
("TEXINFO" value)
("CINDEX" (format "@cindex %s" value))
("FINDEX" (format "@findex %s" value))
("KINDEX" (format "@kindex %s" value))
("PINDEX" (format "@pindex %s" value))
("TINDEX" (format "@tindex %s" value))
("VINDEX" (format "@vindex %s" value))
("TOC"
(cond ((string-match-p "\\<tables\\>" value)
(concat "@listoffloats "
(org-export-translate "Table" :utf-8 info)))
((string-match-p "\\<listings\\>" value)
(concat "@listoffloats "
(org-export-translate "Listing" :utf-8 info))))))))
;;;; Line Break
@ -943,7 +1007,12 @@ CONTENTS is nil. INFO is a plist holding contextual information."
"Return @ref command for element or object DATUM.
DESCRIPTION is the name of the section to print, as a string."
(let ((node-name (org-texinfo--get-node datum info))
(title (org-texinfo--sanitize-node description)))
;; 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)
(format "@ref{%s}" node-name)
(format "@ref{%s, , %s}" node-name title))))
@ -983,13 +1052,20 @@ INFO is a plist holding contextual information. See
(`plain-text
(if desc (format "@uref{file://%s,%s}" destination desc)
(format "@uref{file://%s}" destination)))
(`headline
(org-texinfo--@ref
destination
(or desc
(org-export-data
(org-element-property :title destination) info))
info))
((or `headline
;; Targets within headlines cannot be turned into
;; @anchor{}, so we refer to the headline parent
;; directly.
(and `target
(guard (eq 'headline
(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
@ -1106,8 +1182,13 @@ a plist containing contextual information."
(org-element-normalize-string
(mapconcat
(lambda (h)
(let* ((title (org-export-data
(org-export-get-alt-title h info) info))
(let* ((title
;; Colons are used as a separator between title and node
;; name. Remove them.
(replace-regexp-in-string
"[ \t]+:+" ""
(org-texinfo--sanitize-title
(org-export-get-alt-title h info) info)))
(node (org-texinfo--get-node h info))
(entry (concat "* " title ":"
(if (string= title node) ":"
@ -1164,8 +1245,10 @@ the plist used as a communication channel."
CONTENTS is the contents of the list. INFO is a plist holding
contextual information."
(let* ((attr (org-export-read-attribute :attr_texinfo plain-list))
(indic (or (plist-get attr :indic)
(plist-get info :texinfo-def-table-markup)))
(indic (let ((i (or (plist-get attr :indic)
(plist-get info :texinfo-def-table-markup))))
;; Allow indicating commands with missing @ sign.
(if (string-prefix-p "@" i) i (concat "@" i))))
(table-type (plist-get attr :table-type))
(type (org-element-property :type plain-list))
(list-type (cond
@ -1192,16 +1275,14 @@ contextual information."
(setq output
(org-export-activate-smart-quotes output :texinfo info text)))
;; LaTeX into @LaTeX{} and TeX into @TeX{}
(let ((case-fold-search nil)
(start 0))
(while (string-match "\\(\\(?:La\\)?TeX\\)" output start)
(setq output (replace-match
(format "@%s{}" (match-string 1 output)) nil t output)
start (match-end 0))))
(let ((case-fold-search nil))
(setq output (replace-regexp-in-string "\\(?:La\\)?TeX" "@\\&{}" output)))
;; Convert special strings.
(when (plist-get info :with-special-strings)
(while (string-match (regexp-quote "...") output)
(setq output (replace-match "@dots{}" nil t output))))
(setq output
(replace-regexp-in-string
"\\.\\.\\." "@dots{}"
(replace-regexp-in-string "\\\\-" "@-" output))))
;; Handle break preservation if required.
(when (plist-get info :preserve-breaks)
(setq output (replace-regexp-in-string
@ -1279,11 +1360,10 @@ contextual information."
"Transcode a SECTION element from Org to Texinfo.
CONTENTS holds the contents of the section. INFO is a plist
holding contextual information."
(org-trim
(concat contents
"\n"
(let ((parent (org-export-get-parent-headline section)))
(and parent (org-texinfo-make-menu parent info))))))
(let ((parent (org-export-get-parent-headline section)))
(when parent ;ignore very first section
(org-trim
(concat contents "\n" (org-texinfo-make-menu parent info))))))
;;;; Special Block
@ -1295,7 +1375,7 @@ as a communication channel."
(type (org-element-property :type special-block)))
(format "@%s%s\n%s@end %s"
type
(if opt (concat " " opt) opt)
(if opt (concat " " opt) "")
(or contents "")
type)))

View File

@ -2844,7 +2844,8 @@ containing their first reference."
(org-element-create 'headline
(list :footnote-section-p t
:level 1
:title org-footnote-section)
:title org-footnote-section
:raw-value org-footnote-section)
(apply #'org-element-create
'section
nil

View File

@ -86,6 +86,20 @@ ob-comint.el, which was not previously tested."
(org-babel-next-src-block 2)
(should (equal "20 cm" (org-babel-execute-src-block)))))
(ert-deftest ob-shell/simple-list ()
"Test list variables in shell."
;; With bash, a list is turned into an array.
(should
(= 2
(org-test-with-temp-text
"#+BEGIN_SRC bash :var l='(1 2)\necho ${l[1]}\n#+END_SRC"
(org-babel-execute-src-block))))
;; On sh, it is a string containing all values.
(should
(equal "1 2"
(org-test-with-temp-text
"#+BEGIN_SRC sh :var l='(1 2)\necho ${l}\n#+END_SRC"
(org-babel-execute-src-block)))))
(provide 'test-ob-shell)

View File

@ -347,13 +347,13 @@ contents. The clocktable doesn't appear in the buffer."
(equal
"| Headline | Time | |
|--------------+-------------+-----|
| *Total time* | *704d 9:01* | foo |
| *Total time* | *704d 8:01* | foo |
|--------------+-------------+-----|
| Test | 704d 9:01 | foo |
| Test | 704d 8:01 | foo |
"
(org-test-with-temp-text-in-file
"* Test
CLOCK: [2012-03-29 Thu 16:40]--[2014-03-04 Thu 00:41] => 16905:01
CLOCK: [2012-03-29 Thu 16:40]--[2014-03-04 Thu 00:41] => 16904:01
#+BEGIN: clocktable :scope file-with-archives
#+TBLFM: $3=string(\"foo\")

View File

@ -513,7 +513,7 @@
(cl-letf (((symbol-function 'current-time)
(lambda ()
(apply #'encode-time
(org-parse-time-string "<2014-03-04 Tue>")))))
(org-parse-time-string "<2014-03-04 Tue>" nil t)))))
(org-test-with-temp-text
"* H
** S1
@ -528,11 +528,11 @@
(get-char-property (point) 'org-columns-value-modified)))))
(should
(equal
"705d 01h 0m 0s"
"705d 00h 0m 0s"
(cl-letf (((symbol-function 'current-time)
(lambda ()
(apply #'encode-time
(org-parse-time-string "<2014-03-04 Tue>")))))
(org-parse-time-string "<2014-03-04 Tue>" nil t)))))
(org-test-with-temp-text
"* H
** S1
@ -547,11 +547,11 @@
(get-char-property (point) 'org-columns-value-modified)))))
(should
(equal
"352d 12h 30m 0s"
"352d 12h 0m 0s"
(cl-letf (((symbol-function 'current-time)
(lambda ()
(apply #'encode-time
(org-parse-time-string "<2014-03-04 Tue>")))))
(org-parse-time-string "<2014-03-04 Tue>" nil t)))))
(org-test-with-temp-text
"* H
** S1

View File

@ -429,12 +429,18 @@ Some other text
(equal "test"
(org-test-with-temp-text "#+CALL: test()"
(org-element-property :call (org-element-at-point)))))
;; Parse inside header.
;; Parse inside header. It may contain paired square brackets.
(should
(equal ":results output"
(org-test-with-temp-text "#+CALL: test[:results output]()"
(org-element-property :inside-header (org-element-at-point)))))
;; Parse arguments, which can be nested.
(should
(equal ":results output, a=table[1:2], b=2"
(org-test-with-temp-text
"#+CALL: test[:results output, a=table[1:2], b=2]()"
(org-element-property :inside-header (org-element-at-point)))))
;; Parse arguments, which can be nested. However, stop at paired
;; parenthesis, even when, e.g.,end header contains some.
(should
(equal "n=4"
(org-test-with-temp-text "#+CALL: test(n=4)"
@ -443,6 +449,10 @@ Some other text
(equal "test()"
(org-test-with-temp-text "#+CALL: test(test())"
(org-element-property :arguments (org-element-at-point)))))
(should
(equal "a=1"
(org-test-with-temp-text "#+CALL: test(a=1) :post another-call()"
(org-element-property :arguments (org-element-at-point)))))
;; Parse end header.
(should
(equal ":results html"
@ -920,20 +930,21 @@ Some other text
"Test `footnote-definition' parser."
(should
(org-test-with-temp-text "[fn:1] Definition"
(org-element-map (org-element-parse-buffer) 'footnote-definition
'identity nil t)))
;; Footnote with more contents
(eq (org-element-type (org-element-at-point)) 'footnote-definition)))
;; Footnote with more contents.
(should
(= 29
(org-element-property
:end
(org-test-with-temp-text "[fn:1] Definition\n\n| a | b |"
(org-element-map (org-element-parse-buffer) 'footnote-definition
'identity nil t)))))
(= 29 (org-test-with-temp-text "[fn:1] Definition\n\n| a | b |"
(org-element-property :end (org-element-at-point)))))
;; Test difference between :contents-end and :end property
(should
(< (org-test-with-temp-text "[fn:1] Definition\n\n\n"
(org-element-property :contents-end (org-element-at-point)))
(org-test-with-temp-text "[fn:1] Definition\n\n\n"
(org-element-property :end (org-element-at-point)))))
;; Footnote starting with special syntax.
(should-not
(org-test-with-temp-text "[fn:1] - no item"
(org-element-map (org-element-parse-buffer) 'item 'identity)))
(org-test-with-temp-text "[fn:1] <point>- no item"
(eq (org-element-type (org-element-at-point)) 'item)))
;; Correctly handle footnote starting with an empty line.
(should
(= 9
@ -953,7 +964,13 @@ Some other text
(should
(org-test-with-temp-text "[fn:1] 1\n\n#+attr_latex: :offset 0in\n[fn:2] 2"
(goto-char (org-element-property :end (org-element-at-point)))
(looking-at "#"))))
(looking-at "#")))
;; An empty footnote has no contents.
(should-not
(org-test-with-temp-text "[fn:1]\n\n"
(let ((footnote (org-element-at-point)))
(or (org-element-property :contents-begin footnote)
(org-element-property :contents-end footnote))))))
;;;; Footnotes Reference.

View File

@ -166,7 +166,16 @@
(org-test-with-temp-text
"Para[fn:1]\n\n[fn:1] para1\n\npara2\n\n\nOutside footnote."
(org-footnote-delete "1")
(org-trim (buffer-string)))))))
(org-trim (buffer-string))))))
;; Remove blank lines above the footnote but preserve those after
;; it.
(should
(equal "Text\n\n\nOther text."
(let ((org-footnote-section nil))
(org-test-with-temp-text
"Text[fn:1]\n\n[fn:1] Definition.\n\n\nOther text."
(org-footnote-delete "1")
(buffer-string))))))
(ert-deftest test-org-footnote/goto-definition ()
"Test `org-footnote-goto-definition' specifications."

View File

@ -117,6 +117,23 @@
(narrow-to-region (point) (point-max))
(org-macro-initialize-templates)
(org-macro-replace-all org-macro-templates)
(org-with-wide-buffer (buffer-string)))))
;; Macros in a commented tree are not expanded.
(should
(string-match-p
"{{{macro}}}"
(org-test-with-temp-text
"#+MACRO: macro expansion\n* COMMENT H\n<point>{{{macro}}}"
(org-macro-initialize-templates)
(org-macro-replace-all org-macro-templates)
(org-with-wide-buffer (buffer-string)))))
(should
(string-match-p
"{{{macro}}}"
(org-test-with-temp-text
"#+MACRO: macro expansion\n* COMMENT H1\n** H2\n<point>{{{macro}}}"
(org-macro-initialize-templates)
(org-macro-replace-all org-macro-templates)
(org-with-wide-buffer (buffer-string))))))
(ert-deftest test-org-macro/escape-arguments ()

View File

@ -365,5 +365,76 @@ This is a tab:\t.
(org-edit-src-exit)
(buffer-string))))))
(ert-deftest test-org-src/footnote-references ()
"Test editing footnote references."
;; Error when there is no definition to edit.
(should-error
(org-test-with-temp-text "A footnote<point>[fn:1]"
(org-edit-special)))
;; Error when trying to edit an anonymous footnote.
(should-error
(org-test-with-temp-text "A footnote[fn::<point>edit me!]"
(org-edit-special)))
;; Edit a regular definition.
(should
(equal "[fn:1] Definition"
(org-test-with-temp-text "A footnote<point>[fn:1]\n[fn:1] Definition"
(org-edit-special)
(prog1 (buffer-string) (org-edit-src-exit)))))
;; Label should be protected against editing.
(should
(org-test-with-temp-text "A footnote<point>[fn:1]\n[fn:1] Definition"
(org-edit-special)
(prog1 (get-text-property 0 'read-only (buffer-string))
(org-edit-src-exit))))
(should
(org-test-with-temp-text "A footnote<point>[fn:1]\n[fn:1] Definition"
(org-edit-special)
(prog1 (get-text-property 5 'read-only (buffer-string))
(org-edit-src-exit))))
;; Edit a regular definition.
(should
(equal
"A footnote[fn:1][fn:2]\n[fn:1] D1\n\n[fn:2] D2"
(org-test-with-temp-text
"A footnote<point>[fn:1][fn:2]\n[fn:1] D1\n\n[fn:2] D2"
(org-edit-special)
(org-edit-src-exit)
(buffer-string))))
;; Edit an inline definition.
(should
(equal
"[fn:1:definition]"
(org-test-with-temp-text
"An inline<point>[fn:1] footnote[fn:1:definition]"
(org-edit-special)
(prog1 (buffer-string) (org-edit-src-exit)))))
;; Label and closing square bracket should be protected against
;; editing.
(should
(org-test-with-temp-text "An inline<point>[fn:1] footnote[fn:1:definition]"
(org-edit-special)
(prog1 (get-text-property 0 'read-only (buffer-string))
(org-edit-src-exit))))
(should
(org-test-with-temp-text "An inline<point>[fn:1] footnote[fn:1:definition]"
(org-edit-special)
(prog1 (get-text-property 5 'read-only (buffer-string))
(org-edit-src-exit))))
(should
(org-test-with-temp-text "An inline<point>[fn:1] footnote[fn:1:definition]"
(org-edit-special)
(prog1 (get-text-property 16 'read-only (buffer-string))
(org-edit-src-exit))))
;; Do not include trailing white spaces when displaying the inline
;; footnote definition.
(should
(equal
"[fn:1:definition]"
(org-test-with-temp-text
"An inline<point>[fn:1] footnote[fn:1:definition] and some text"
(org-edit-special)
(prog1 (buffer-string) (org-edit-src-exit))))))
(provide 'test-org-src)
;;; test-org-src.el ends here

View File

@ -1351,15 +1351,6 @@ Footnotes[fn:2], foot[fn:test] and [fn:inline:inline footnote]
;; Throw an error when a macro definition is missing.
(should-error
(org-test-with-temp-text "{{{missing}}}"
(org-export-as (org-test-default-backend))))
;; Macros defined in commented subtrees are ignored.
(should-error
(org-test-with-temp-text
"* COMMENT H\n#+MACRO: macro1\n* H2\nvalue\n{{{macro1}}}"
(org-export-as (org-test-default-backend))))
(should-error
(org-test-with-temp-text
"* COMMENT H\n** H2\n#+MACRO: macro1\n* H3\nvalue\n{{{macro1}}}"
(org-export-as (org-test-default-backend)))))
(ert-deftest test-org-export/before-processing-hook ()
@ -3261,8 +3252,8 @@ Another text. (ref:text)
(should (equal (concat (if (memq system-type '(windows-nt cygwin)) "file:///" "file://") (expand-file-name "/local.org"))
(org-export-file-uri "/local.org")))
;; Remote files start with "file://"
(should (equal "file://myself@some.where:papers/last.pdf"
(org-export-file-uri "/myself@some.where:papers/last.pdf")))
(should (equal "file://ssh:myself@some.where:papers/last.pdf"
(org-export-file-uri "/ssh:myself@some.where:papers/last.pdf")))
(should (equal "file://localhost/etc/fstab"
(org-export-file-uri "//localhost/etc/fstab")))
;; Expand filename starting with "~".