@settitle The Org Manual
@include docstyle.texi
-@set VERSION 9.0.9
+@set VERSION 9.0.10
+@set DATE 2017-08-27
@c Version and Contact Info
@set MAINTAINERSITE @uref{http://orgmode.org,maintainers web page}
* Template expansion:: Filling in information about time and context
* Templates in contexts:: Only show a template in a specific context
+Protocols for external access
+
+* @code{store-link} protocol:: Store a link, push URL to kill-ring.
+* @code{capture} protocol:: Fill a buffer with external information.
+* @code{open-source} protocol:: Edit published contents.
+
Archiving
* Moving subtrees:: Moving a tree to an archive file
export backends can be derived from existing ones, or defined from scratch.
Org files can include source code blocks, which makes Org uniquely suited for
-authoring technical documents with code examples. Org source code blocks are
+authoring technical documents with code examples. Org source code blocks are
fully functional; they can be evaluated in place and their results can be
captured in the file. This makes it possible to create a single file
reproducible research compendium.
@r{%^@{prompt|default|completion2|completion3...@}.}
@r{The arrow keys access a prompt-specific history.}
%\1 @dots{} %\N @r{Insert the text entered at the Nth %^@{@var{prompt}@}, where @code{N} is}
- @r{a number, starting from 1.}
+ @r{a number, starting from 1.@footnote{As required in Emacs
+ Lisp, it is necessary to escape any backslash character in
+ a string with another backslash. So, in order to use
+ @samp{%\1} placeholder, you need to write @samp{%\\1} in
+ the template.}}
%? @r{After completing the template, position cursor here.}
@end smallexample
@node Protocols
@section Protocols for external access
@cindex protocols, for external access
-@cindex emacsserver
-You can set up Org for handling protocol calls from outside applications that
-are passed to Emacs through the @file{emacsserver}. For example, you can
+Org protocol is a mean to trigger custom actions in Emacs from external
+applications. Any application that supports calling external programs with
+an URL as argument may be used with this functionality. For example, you can
configure bookmarks in your web browser to send a link to the current page to
-Org and create a note from it using capture (@pxref{Capture}). Or you
-could create a bookmark that will tell Emacs to open the local source file of
-a remote website you are looking at with the browser. See
-@uref{http://orgmode.org/worg/org-contrib/org-protocol.php} for detailed
-documentation and setup instructions.
+Org and create a note from it using capture (@pxref{Capture}). You can also
+create a bookmark that tells Emacs to open the local source file of a remote
+website you are browsing.
+
+@cindex Org protocol, set-up
+@cindex Installing Org protocol
+In order to use Org protocol from an application, you need to register
+@samp{org-protocol://} as a valid scheme-handler. External calls are passed
+to Emacs through the @code{emacsclient} command, so you also need to ensure
+an Emacs server is running. More precisely, when the application calls
+
+@example
+emacsclient org-protocol://PROTOCOL?key1=val1&key2=val2
+@end example
+
+@noindent
+Emacs calls the handler associated to @samp{PROTOCOL} with argument
+@samp{(:key1 val1 :key2 val2)}.
+
+@cindex protocol, new protocol
+@cindex defining new protocols
+Org protocol comes with three predefined protocols, detailed in the following
+sections. Configure @code{org-protocol-protocol-alist} to define your own.
+
+@menu
+* @code{store-link} protocol:: Store a link, push URL to kill-ring.
+* @code{capture} protocol:: Fill a buffer with external information.
+* @code{open-source} protocol:: Edit published contents.
+@end menu
+
+@node @code{store-link} protocol
+@subsection @code{store-link} protocol
+@cindex store-link protocol
+@cindex protocol, store-link
+
+Using @code{store-link} handler, you can copy links, insertable through
+@kbd{M-x org-insert-link} or yanking thereafter. More precisely, the command
+
+@example
+emacsclient org-protocol://store-link?url=URL&title=TITLE
+@end example
+
+@noindent
+stores the following link:
+
+@example
+[[URL][TITLE]]
+@end example
+
+In addition, @samp{URL} is pushed on the kill-ring for yanking. You need to
+encode @samp{URL} and @samp{TITLE} if they contain slashes, and probably
+quote those for the shell.
+
+To use this feature from a browser, add a bookmark with an arbitrary name,
+e.g., @samp{Org: store-link} and enter this as @emph{Location}:
+
+@example
+javascript:location.href='org-protocol://store-link?url='+
+ encodeURIComponent(location.href);
+@end example
+
+@node @code{capture} protocol
+@subsection @code{capture} protocol
+@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.
+
+@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}:
+
+@example
+javascript:location.href='org-protocol://template=x'+
+ '&url='+encodeURIComponent(window.location.href)+
+ '&title='+encodeURIComponent(document.title)+
+ '&body='+encodeURIComponent(window.getSelection());
+@end example
+
+@vindex org-protocol-default-template-key
+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}.
+
+@node @code{open-source} protocol
+@subsection @code{open-source} protocol
+@cindex open-source protocol
+@cindex protocol, open-source
+
+The @code{open-source} handler is designed to help with editing local sources
+when reading a document. To that effect, you can use a bookmark with the
+following location:
+
+@example
+javascript:location.href='org-protocol://open-source?&url='+
+ encodeURIComponent(location.href)
+@end example
+
+@cindex protocol, open-source, :base-url property
+@cindex :base-url property in open-source protocol
+@cindex protocol, open-source, :working-directory property
+@cindex :working-directory property in open-source protocol
+@cindex protocol, open-source, :online-suffix property
+@cindex :online-suffix property in open-source protocol
+@cindex protocol, open-source, :working-suffix property
+@cindex :working-suffix property in open-source protocol
+@vindex org-protocol-project-alist
+The variable @code{org-protocol-project-alist} maps URLs to local file names,
+by stripping URL parameters from the end and replacing the @code{:base-url}
+with @code{:working-diretory} and @code{:online-suffix} with
+@code{:working-suffix}. For example, assuming you own a local copy of
+@url{http://orgmode.org/worg/} contents at @file{/home/user/worg}, you can
+set @code{org-protocol-project-alist} to the following
+
+@lisp
+(setq org-protocol-project-alist
+ '(("Worg"
+ :base-url "http://orgmode.org/worg/"
+ :working-directory "/home/user/worg/"
+ :online-suffix ".html"
+ :working-suffix ".org")))
+@end lisp
+
+@noindent
+If you are now browsing
+@url{http://orgmode.org/worg/org-contrib/org-protocol.html} and find a typo
+or have an idea about how to enhance the documentation, simply click the
+bookmark and start editing.
+
+@cindex handle rewritten URL in open-source protocol
+@cindex protocol, open-source rewritten URL
+However, such mapping may not yield the desired results. Suppose you
+maintain an online store located at @url{http://example.com/}. The local
+sources reside in @file{/home/user/example/}. It is common practice to serve
+all products in such a store through one file and rewrite URLs that do not
+match an existing file on the server. That way, a request to
+@url{http://example.com/print/posters.html} might be rewritten on the server
+to something like
+@url{http://example.com/shop/products.php/posters.html.php}. The
+@code{open-source} handler probably cannot find a file named
+@file{/home/user/example/print/posters.html.php} and fails.
+
+@cindex protocol, open-source, :rewrites property
+@cindex :rewrites property in open-source protocol
+Such an entry in @code{org-protocol-project-alist} may hold an additional
+property @code{:rewrites}. This property is a list of cons cells, each of
+which maps a regular expression to a path relative to the
+@code{:working-directory}.
+
+Now map the URL to the path @file{/home/user/example/products.php} by adding
+@code{:rewrites} rules like this:
+
+@lisp
+(setq org-protocol-project-alist
+ '(("example.com"
+ :base-url "http://example.com/"
+ :working-directory "/home/user/example/"
+ :online-suffix ".php"
+ :working-suffix ".php"
+ :rewrites (("example.com/print/" . "products.php")
+ ("example.com/$" . "index.php")))))
+@end lisp
+
+@noindent
+Since @samp{example.com/$} is used as a regular expression, it maps
+@url{http://example.com/}, @url{https://example.com},
+@url{http://www.example.com/} and similar to
+@file{/home/user/example/index.php}.
+
+The @code{:rewrites} rules are searched as a last resort if and only if no
+existing file name is matched.
+
+@cindex protocol, open-source, set-up mapping
+@cindex set-up mappings in open-source protocol
+@findex org-protocol-create
+@findex org-protocol-create-for-org
+Two functions can help you filling @code{org-protocol-project-alist} with
+valid contents: @code{org-protocol-create} and
+@code{org-protocol-create-for-org}. The latter is of use if you're editing
+an Org file that is part of a publishing project.
@node Refile and copy
@section Refile and copy
@end example
That will give you three days' warning: on the anniversary date itself and the
-two days prior. The argument is optional: if omitted, it defaults to 7.
+two days prior. The argument is optional: if omitted, it defaults to 7.
@subsubheading Appointment reminders
@cindex @file{appt.el}
Org's HTML exporter does not by default enable new block elements introduced
with the HTML5 standard. To enable them, set @code{org-html-html5-fancy} to
non-@code{nil}. Or use an @code{OPTIONS} line in the file to set
-@code{html5-fancy}. HTML5 documents can now have arbitrary #+BEGIN and #+END
-blocks. For example:
+@code{html5-fancy}. HTML5 documents can now have arbitrary @code{#+BEGIN}
+and @code{#+END} blocks. For example:
@example
#+BEGIN_aside
Copyright information is printed on the back of the title page.
@example
-* Copying
+* Legalese
:PROPERTIES:
:COPYING: t
:END:
When Org tangles @samp{src} code blocks, it expands, merges, and transforms
them. Then Org recomposes them into one or more separate files, as
configured through the options. During this @emph{tangling} process, Org
-expands variables in the source code, and resolves any ``noweb'' style
-references (@pxref{Noweb reference syntax}).
+expands variables in the source code, and resolves any Noweb style references
+(@pxref{Noweb reference syntax}).
@subsubheading Header arguments
Additional documentation for some languages are at
@uref{http://orgmode.org/worg/org-contrib/babel/languages.html}.
+@vindex org-babel-load-languages
By default, only @code{emacs-lisp} is enabled for evaluation. To enable or
disable other languages, customize the @code{org-babel-load-languages}
variable either through the Emacs customization interface, or by adding code
By default Org expands @samp{src} code blocks during tangling. The
@code{:no-expand} header argument turns off such expansions. Note that one
side-effect of expansion by @code{org-babel-expand-src-block} also assigns
-values to @code{:var} (@pxref{var}) variables. Expansions also replace
-``noweb'' references with their targets (@pxref{Noweb reference syntax}).
-Some of these expansions may cause premature assignment, hence this option.
-This option makes a difference only for tangling. It has no effect when
-exporting since @samp{src} code blocks for execution have to be expanded
-anyway.
+values to @code{:var} (@pxref{var}) variables. Expansions also replace Noweb
+references with their targets (@pxref{Noweb reference syntax}). Some of
+these expansions may cause premature assignment, hence this option. This
+option makes a difference only for tangling. It has no effect when exporting
+since @samp{src} code blocks for execution have to be expanded anyway.
@node session
@subsubsection @code{:session}
@subsubsection @code{:noweb}
@cindex @code{:noweb}, src header argument
-The @code{:noweb} header argument controls expansion of ``noweb'' syntax
+The @code{:noweb} header argument controls expansion of Noweb syntax
references (@pxref{Noweb reference syntax}). Expansions occur when source
code blocks are evaluated, tangled, or exported.
@itemize @bullet
@item @code{no}
-Default. No expansion of ``Noweb'' syntax references in the body of the code
+Default. No expansion of Noweb syntax references in the body of the code
when evaluating, tangling, or exporting.
@item @code{yes}
-Expansion of ``Noweb'' syntax references in the body of the @samp{src} code
-block when evaluating, tangling, or exporting.
+Expansion of Noweb syntax references in the body of the @samp{src} code block
+when evaluating, tangling, or exporting.
@item @code{tangle}
-Expansion of ``Noweb'' syntax references in the body of the @samp{src} code
-block when tangling. No expansion when evaluating or exporting.
+Expansion of Noweb syntax references in the body of the @samp{src} code block
+when tangling. No expansion when evaluating or exporting.
@item @code{no-export}
-Expansion of ``Noweb'' syntax references in the body of the @samp{src} code
-block when evaluating or tangling. No expansion when exporting.
+Expansion of Noweb syntax references in the body of the @samp{src} code block
+when evaluating or tangling. No expansion when exporting.
@item @code{strip-export}
-Expansion of ``Noweb'' syntax references in the body of the @samp{src} code
-block when expanding prior to evaluating or tangling. Removes ``noweb''
-syntax references when exporting.
+Expansion of Noweb syntax references in the body of the @samp{src} code block
+when expanding prior to evaluating or tangling. Removes Noweb syntax
+references when exporting.
@item @code{eval}
-Expansion of ``Noweb'' syntax references in the body of the @samp{src} code
-block only before evaluating.
+Expansion of Noweb syntax references in the body of the @samp{src} code block
+only before evaluating.
@end itemize
@subsubheading Noweb prefix lines
-Noweb insertions now honor prefix characters that appear before
-@code{<<reference>>}. This behavior is illustrated in the following example.
-Because the @code{<<example>>} noweb reference appears behind the SQL comment
-syntax, each line of the expanded noweb reference will be commented.
+Noweb insertions now honor prefix characters that appear before the Noweb
+syntax reference.
+
+This behavior is illustrated in the following example. Because the
+@code{<<example>>} noweb reference appears behind the SQL comment syntax,
+each line of the expanded noweb reference will be commented.
+
+With:
-This @samp{src} code block:
+@example
+#+NAME: example
+#+BEGIN_SRC text
+this is the
+multi-line body of example
+#+END_SRC
+@end example
+
+this @samp{src} code block:
@example
+#+BEGIN_SRC sql :noweb yes
-- <<example>>
+#+END_SRC
@end example
expands to:
Since this change will not affect noweb replacement text without newlines in
them, inline noweb references are acceptable.
+This feature can also be used for management of indentation in exported code snippets.
+
+With:
+
+@example
+#+NAME: if-true
+#+BEGIN_SRC python :exports none
+print('Do things when True')
+#+END_SRC
+
+#+NAME: if-false
+#+BEGIN_SRC python :exports none
+print('Do things when False')
+#+END_SRC
+@end example
+
+this @samp{src} code block:
+
+@example
+#+BEGIN_SRC python :noweb yes :results output
+if True:
+ <<if-true>>
+else:
+ <<if-false>>
+#+END_SRC
+@end example
+
+expands to:
+
+@example
+if True:
+ print('Do things when True')
+else:
+ print('Do things when False')
+@end example
+
+and evaluates to:
+
+@example
+Do things when True
+@end example
+
@node noweb-ref
@subsubsection @code{:noweb-ref}
@cindex @code{:noweb-ref}, src header argument
-When expanding ``noweb'' style references, Org concatenates @samp{src} code
-blocks by matching the reference name to either the block name or the
+When expanding Noweb style references, Org concatenates @samp{src} code
+blocks by matching the reference name to either the code block name or the
@code{:noweb-ref} header argument.
For simple concatenation, set this @code{:noweb-ref} header argument at the
sub-tree or file level. In the example Org file shown next, the body of the
-source code in each block is extracted for concatenation to a pure code file.
+source code in each block is extracted for concatenation to a pure code file
+when tangled.
@example
#+BEGIN_SRC sh :tangle yes :noweb yes :shebang #!/bin/sh
may cause unexpected results.
When the caching mechanism tests for any source code changes, it will not
-expand ``noweb'' style references (@pxref{Noweb reference syntax}). For
-reasons why, see @uref{http://thread.gmane.org/gmane.emacs.orgmode/79046}.
+expand Noweb style references (@pxref{Noweb reference syntax}). For reasons
+why, see @uref{http://thread.gmane.org/gmane.emacs.orgmode/79046}.
The @code{:cache} header argument can have one of two values: @code{yes} or
@code{no}.
@cindex syntax, noweb
@cindex source code, noweb reference
-Org supports named blocks in ``noweb'' style syntax. For ``noweb'' literate
+Org supports named blocks in Noweb style syntax. For Noweb literate
programming details, see @uref{http://www.cs.tufts.edu/~nr/noweb/}).
@example
<<code-block-name>>
@end example
-For the header argument @code{:noweb yes}, Org expands ``noweb'' style
-references in the @samp{src} code block before evaluation.
+For the header argument @code{:noweb yes}, Org expands Noweb style references
+in the @samp{src} code block before evaluation.
-For the header argument @code{:noweb no}, Org does not expand ``noweb'' style
+For the header argument @code{:noweb no}, Org does not expand Noweb style
references in the @samp{src} code block before evaluation.
-The default is @code{:noweb no}.
+The default is @code{:noweb no}. Org defaults to @code{:noweb no} so as not
+to cause errors in languages where Noweb syntax is ambiguous. Change Org's
+default to @code{:noweb yes} for languages where there is no risk of
+confusion.
-Org offers a more flexible way to resolve ``noweb'' style references
+Org offers a more flexible way to resolve Noweb style references
(@pxref{noweb-ref}).
-Org can handle naming of @emph{results} block, rather than the body of the
-@samp{src} code block, using ``noweb'' style references.
-
-For ``noweb'' style reference, append parenthesis to the code block name for
-arguments, as shown in this example:
+Org can include the @emph{results} of a code block rather than its body. To
+that effect, append parentheses, possibly including arguments, to the code
+block name, as show below.
@example
<<code-block-name(optional arguments)>>
@end example
-Note: Org defaults to @code{:noweb no} so as not to cause errors in languages
-such as @samp{Ruby} where ``noweb'' syntax is equally valid characters. For
-example, @code{<<arg>>}. Change Org's default to @code{:noweb yes} for
-languages where there is no risk of confusion.
+Note that when using the above approach to a code block's results, the code
+block name set by @code{#+NAME} keyword is required; the reference set by
+@code{:noweb-ref} will not work.
+
+Here is an example that demonstrates how the exported content changes when
+Noweb style references are used with parentheses versus without.
+
+With:
+
+@example
+#+NAME: some-code
+#+BEGIN_SRC python :var num=0 :results output :exports none
+print(num*10)
+#+END_SRC
+@end example
+
+this code block:
+
+@example
+#+BEGIN_SRC text :noweb yes
+<<some-code>>
+#+END_SRC
+@end example
+
+expands to:
+
+@example
+print(num*10)
+@end example
+
+Below, a similar Noweb style reference is used, but with parentheses, while
+setting a variable @code{num} to 10:
+
+@example
+#+BEGIN_SRC text :noweb yes
+<<some-code(num=10)>>
+#+END_SRC
+@end example
+
+Note that now the expansion contains the @emph{results} of the code block
+@code{some-code}, not the code block itself:
+
+@example
+100
+@end example
For faster tangling of large Org mode files, set
@code{org-babel-use-quick-and-dirty-noweb-expansion} variable to @code{t}.
templates use an expansion mechanism, which is native to Org, in a process
similar to @file{yasnippet} and other Emacs template expansion packages.
-@kbd{@key{<}} @kbd{@key{s}} @kbd{@key{TAB}} completes the @samp{src} code
-block.
-
-@kbd{<} @kbd{l} @kbd{@key{TAB}}
+@kbd{<} @kbd{s} @kbd{@key{TAB}} expands to a @samp{src} code block.
-expands to:
+@kbd{<} @kbd{l} @kbd{@key{TAB}} expands to:
#+BEGIN_EXPORT latex
Org evaluates @samp{src} code blocks in an Org file during export. Org also
evaluates a @samp{src} code block with the @kbd{C-c C-c} key chord. Users
exporting or running code blocks must load files only from trusted sources.
-Be weary of customizing variables that remove or alter default security
+Be wary of customizing variables that remove or alter default security
measures.
@defopt org-confirm-babel-evaluate
,* Headline
:PROPERTIES:
:header-args: :exports code
-:header-args: :var a=1 b=2
+:header-args+: :var a=1 b=2
:header-args+: :var c=3
:END:
#+END_EXAMPLE
% Reference Card for Org Mode
-\def\orgversionnumber{9.0.9}
+\def\orgversionnumber{9.0.10}
\def\versionyear{2017} % latest update
-\input emacsver.tex
+\def\year{2017} % latest copyright year
%**start of header
\newcount\columnsperpage
(require 'ob-core)
(require 'org-compat)
(require 'comint)
-(require 'tramp)
(defun org-babel-comint-buffer-livep (buffer)
"Check if BUFFER is a comint buffer with a live process."
(process-send-string
(get-buffer-process buffer)
(if (= (aref string (1- (length string))) ?\n) string (concat string "\n")))
- ;; From Tramp 2.1.19 the following cache flush is not necessary
- (when (file-remote-p default-directory)
- (with-parsed-tramp-file-name default-directory nil
- (tramp-flush-directory-property v "")))
(while (not (file-exists-p file)) (sit-for (or period 0.25))))
(provide 'ob-comint)
to `org-babel-named-src-block-regexp'."
(save-excursion
(goto-char (point-min))
- (ignore-errors
- (org-next-block 1 nil (org-babel-named-src-block-regexp-for-name name)))))
+ (let ((regexp (org-babel-named-src-block-regexp-for-name name)))
+ (or (and (looking-at regexp)
+ (progn (goto-char (match-beginning 1))
+ (line-beginning-position)))
+ (ignore-errors (org-next-block 1 nil regexp))))))
(defun org-babel-src-block-names (&optional file)
"Returns the names of source blocks in FILE or the current buffer."
(when file (find-file file))
(save-excursion
(goto-char (point-min))
- (let ((re (org-babel-named-src-block-regexp-for-name))
- names)
+ (let* ((re (org-babel-named-src-block-regexp-for-name))
+ (names (and (looking-at re)
+ (list (match-string-no-properties 9)))))
(while (ignore-errors (org-next-block 1 nil re))
(push (match-string-no-properties 9) names))
names)))
((member "prepend" result-params))) ; already there
(setq results-switches
(if results-switches (concat " " results-switches) ""))
- (let ((wrap (lambda (start finish &optional no-escape no-newlines
- inline-start inline-finish)
- (when inline
- (setq start inline-start)
- (setq finish inline-finish)
- (setq no-newlines t))
- (goto-char end)
- (insert (concat finish (unless no-newlines "\n")))
- (goto-char beg)
- (insert (concat start (unless no-newlines "\n")))
- (unless no-escape
- (org-escape-code-in-region (min (point) end) end))
- (goto-char end)
- (unless no-newlines (goto-char (point-at-eol)))
- (setq end (point-marker))))
+ (let ((wrap
+ (lambda (start finish &optional no-escape no-newlines
+ inline-start inline-finish)
+ (when inline
+ (setq start inline-start)
+ (setq finish inline-finish)
+ (setq no-newlines t))
+ (let ((before-finish (marker-position end)))
+ (goto-char end)
+ (insert (concat finish (unless no-newlines "\n")))
+ (goto-char beg)
+ (insert (concat start (unless no-newlines "\n")))
+ (unless no-escape
+ (org-escape-code-in-region
+ (min (point) before-finish) before-finish))
+ (goto-char end))))
(tabulablep
(lambda (r)
;; Non-nil when result R can be turned into
(insert (org-macro-escape-arguments
(org-babel-chomp result "\n"))))
(t (goto-char beg) (insert result)))
- (setq end (point-marker))
+ (setq end (copy-marker (point) t))
;; possibly wrap result
(cond
((assq :wrap (nth 2 info))
((and (not (funcall tabulablep result))
(not (member "file" result-params)))
(let ((org-babel-inline-result-wrap
- ;; Hard code {{{results(...)}}} on top of customization.
+ ;; Hard code {{{results(...)}}} on top of
+ ;; customization.
(format "{{{results(%s)}}}"
org-babel-inline-result-wrap)))
- (org-babel-examplify-region beg end results-switches inline)
- (setq end (point))))))
+ (org-babel-examplify-region
+ beg end results-switches inline)))))
;; Possibly indent results in par with #+results line.
(when (and (not inline) (numberp indent) (> indent 0)
;; In this case `table-align' does the work
(message "Code block returned no value.")
(message "Code block produced no output."))
(message "Code block evaluation complete.")))
+ (set-marker end nil)
(when outside-scope (narrow-to-region visible-beg visible-end))
(set-marker visible-beg nil)
(set-marker visible-end nil)))))))
(defun org-babel-expand-body:emacs-lisp (body params)
"Expand BODY according to PARAMS, return the expanded body."
- (let* ((vars (org-babel--get-vars params))
- (result-params (cdr (assq :result-params params)))
- (print-level nil) (print-length nil)
- (body (if (> (length vars) 0)
- (concat "(let ("
- (mapconcat
- (lambda (var)
- (format "%S" (print `(,(car var) ',(cdr var)))))
- vars "\n ")
- ")\n" body "\n)")
- (concat body "\n"))))
- (if (or (member "code" result-params)
- (member "pp" result-params))
- (concat "(pp " body ")") body)))
+ (let ((vars (org-babel--get-vars params))
+ (print-level nil)
+ (print-length nil))
+ (if (null vars) (concat body "\n")
+ (format "(let (%s)\n%s\n)"
+ (mapconcat
+ (lambda (var)
+ (format "%S" (print `(,(car var) ',(cdr var)))))
+ vars "\n ")
+ body))))
(defun org-babel-execute:emacs-lisp (body params)
"Execute a block of emacs-lisp code with Babel."
(save-window-excursion
(let* ((lexical (cdr (assq :lexical params)))
- (result
- (eval (read (format (if (member "output"
- (cdr (assq :result-params params)))
- "(with-output-to-string %s)"
- "(progn %s)")
- (org-babel-expand-body:emacs-lisp
- body params)))
-
- (if (listp lexical)
- lexical
- (member lexical '("yes" "t"))))))
- (org-babel-result-cond (cdr (assq :result-params params))
+ (result-params (cdr (assq :result-params params)))
+ (body (format (if (member "output" result-params)
+ "(with-output-to-string %s\n)"
+ "(progn %s\n)")
+ (org-babel-expand-body:emacs-lisp body params)))
+ (result (eval (read (if (or (member "code" result-params)
+ (member "pp" result-params))
+ (concat "(pp " body ")")
+ body))
+ (if (listp lexical)
+ lexical
+ (member lexical '("yes" "t"))))))
+ (org-babel-result-cond result-params
(let ((print-level nil)
(print-length nil))
- (if (or (member "scalar" (cdr (assq :result-params params)))
- (member "verbatim" (cdr (assq :result-params params))))
+ (if (or (member "scalar" result-params)
+ (member "verbatim" result-params))
(format "%S" result)
(format "%s" result)))
(org-babel-reassemble-table
(list 'face (org-get-todo-face (match-string 2 x)))
x)
(when (match-end 1)
- (setq x (concat (substring x 0 (match-end 1))
- (format org-agenda-todo-keyword-format
- (match-string 2 x))
- (org-add-props " " (text-properties-at 0 x))
- (substring x (match-end 3)))))))
+ (setq x
+ (concat
+ (substring x 0 (match-end 1))
+ (format org-agenda-todo-keyword-format
+ (match-string 2 x))
+ ;; Remove `display' property as the icon could leak
+ ;; on the white space.
+ (org-add-props " " (org-plist-delete (text-properties-at 0 x)
+ 'display))
+ (substring x (match-end 3)))))))
x)))
(defsubst org-cmp-values (a b property)
(org-global-tags-completion-table)))
(let ((completion-ignore-case t))
(setq tag (completing-read
- "Tag: " org-global-tags-completion-table))))
+ "Tag: " org-global-tags-completion-table nil t))))
(cond
((eq char ?\r)
(org-agenda-filter-show-all-tag)
happens after expanding non-interactive %-escapes, those can
be used to fill the expression.
%<...> The result of format-time-string on the ... format specification.
- %t Time stamp, date only.
- %T Time stamp with date and time.
+ %t Time stamp, date only. The time stamp is the current time,
+ except when called from agendas with `\\[org-agenda-capture]' or
+ with `org-capture-use-agenda-date' set.
+ %T Time stamp as above, with date and time.
%u, %U Like the above, but inactive time stamps.
%i Initial content, copied from the active region. If %i is
indented, the entire inserted text will be indented as well.
%^g Prompt for tags, with completion on tags in target file.
%^G Prompt for tags, with completion on all tags in all agenda files.
%^t Like %t, but prompt for date. Similarly %^T, %^u, %^U.
- You may define a prompt like: %^{Please specify birthday}t
+ You may define a prompt like: %^{Please specify birthday}t.
+ The default date is that of %t, see above.
%^C Interactive selection of which kill or clip to use.
%^L Like %^C, but insert as link.
%^{prop}p Prompt the user for a value for property `prop'.
(mapconcat 'identity (split-string txt "\n")
"\n "))))
;; Prepare surrounding empty lines.
+ (unless (bolp) (insert "\n"))
(org-capture-empty-lines-before)
(setq beg (point))
(unless (eolp) (save-excursion (insert "\n")))
(insert txt)
(org-capture-empty-lines-after)
(org-capture-position-for-last-stored beg)
- (forward-char 1)
(setq end (point))
- (org-capture-mark-kill-region beg (1- end))
- (org-capture-narrow beg (1- end))
+ (org-capture-mark-kill-region beg end)
+ (org-capture-narrow beg end)
(if (or (re-search-backward "%\\?" beg t)
(re-search-forward "%\\?" end t))
(replace-match ""))))
(replace-match "\\1" nil nil v-a)
v-a))
(v-n user-full-name)
- (v-k (and (marker-buffer org-clock-marker)
- (org-no-properties org-clock-heading)))
+ (v-k (if (marker-buffer org-clock-marker)
+ (org-no-properties org-clock-heading)
+ ""))
(v-K (if (marker-buffer org-clock-marker)
(org-make-link-string
- (buffer-file-name (marker-buffer org-clock-marker))
- org-clock-heading)))
+ (format "%s::*%s"
+ (buffer-file-name (marker-buffer org-clock-marker))
+ v-k)
+ v-k)
+ ""))
(v-f (or (org-capture-get :original-file-nondirectory) ""))
(v-F (or (org-capture-get :original-file) ""))
(org-capture--clipboards
(_ (error "Invalid `org-capture--clipboards' value: %S"
org-capture--clipboards)))))
("p" (org-set-property prompt nil))
- ((guard key)
+ ((or "t" "T" "u" "U")
;; These are the date/time related ones.
(let* ((upcase? (equal (upcase key) key))
- (org-time-was-given upcase?)
- (org-end-time-was-given)
+ (org-end-time-was-given nil)
(time (org-read-date upcase? t nil prompt)))
- (org-insert-time-stamp
- time org-time-was-given
- (member key '("u" "U"))
- nil nil (list org-end-time-was-given))))
- (_
+ (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)))))
+ (`nil
(push (org-completing-read
(concat (or prompt "Enter string")
(and default (format " [%s]" default))
": ")
completions nil nil nil nil default)
strings)
- (insert (car strings)))))))))
+ (insert (car strings)))
+ (_
+ (error "Unknown template placeholder: \"%%^%s\""
+ key))))))))
;; Replace %n escapes with nth %^{...} string.
(setq strings (nreverse strings))
(if jump-to-captured '(:jump-to-captured t)))))
org-remember-templates))))
-;;; The function was made obsolete by commit 65399674d5 of
-;;; 2013-02-22. This make-obsolete call was added 2016-09-01.
-(make-obsolete 'org-capture-import-remember-templates "use the `org-capture-templates' variable instead." "Org 9.0")
+
(provide 'org-capture)
(defun org-clock-get-sum-start ()
"Return the time from which clock times should be counted.
-This is for the currently running clock as it is displayed
-in the mode line. This function looks at the properties
-LAST_REPEAT and in particular CLOCK_MODELINE_TOTAL and the
-corresponding variable `org-clock-mode-line-total' and then
-decides which time to use."
+
+This is for the currently running clock as it is displayed in the
+mode line. This function looks at the properties LAST_REPEAT and
+in particular CLOCK_MODELINE_TOTAL and the corresponding variable
+`org-clock-mode-line-total' and then decides which time to use.
+
+The time is always returned as UTC."
(let ((cmt (or (org-entry-get nil "CLOCK_MODELINE_TOTAL")
(symbol-name org-clock-mode-line-total)))
(lr (org-entry-get nil "LAST_REPEAT")))
(current-time))
((equal cmt "today")
(setq org--msg-extra "showing today's task time.")
- (let* ((dt (decode-time))
+ (let* ((dt (org-decode-time nil t))
(hour (nth 2 dt))
(day (nth 3 dt)))
(if (< hour org-extend-today-until) (setf (nth 3 dt) (1- day)))
(setf (nth 2 dt) org-extend-today-until)
- (setq dt (append (list 0 0) (nthcdr 2 dt)))
- (apply 'encode-time dt)))
+ (setq dt (append (list 0 0) (nthcdr 2 dt) '(t)))
+ (apply #'encode-time dt)))
((or (equal cmt "all")
(and (or (not cmt) (equal cmt "auto"))
(not lr)))
(and (or (not cmt) (equal cmt "auto"))
lr))
(setq org--msg-extra "showing task time since last repeat.")
- (if (not lr)
- nil
- (org-time-string-to-time lr)))
+ (and lr (org-time-string-to-time lr t)))
(t nil))))
(defun org-clock-find-position (find-unclosed)
"[ \t]*\\(?:\\(\\[.*?\\]\\)-+\\(\\[.*?\\]\\)\\|=>[ \t]+\\([0-9]+\\):\\([0-9]+\\)\\)"))
(lmax 30)
(ltimes (make-vector lmax 0))
- (t1 0)
(level 0)
- ts te dt
+ (tstart (cond ((stringp tstart) (org-time-string-to-seconds tstart t))
+ ((consp tstart) (float-time tstart))
+ (t tstart)))
+ (tend (cond ((stringp tend) (org-time-string-to-seconds tend t))
+ ((consp tend) (float-time tend))
+ (t tend)))
+ (t1 0)
time)
- (if (stringp tstart) (setq tstart (org-time-string-to-seconds tstart)))
- (if (stringp tend) (setq tend (org-time-string-to-seconds tend)))
- (if (consp tstart) (setq tstart (float-time tstart)))
- (if (consp tend) (setq tend (float-time tend)))
(remove-text-properties (point-min) (point-max)
`(,(or propname :org-clock-minutes) t
:org-clock-force-headline-inclusion t))
(while (re-search-backward re nil t)
(cond
((match-end 2)
- ;; Two time stamps
- (setq ts (match-string 2)
- te (match-string 3)
- ts (float-time
- (apply #'encode-time (org-parse-time-string ts nil t)))
- te (float-time
- (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)
- t1 (if (> dt 0) (+ t1 (floor (/ dt 60))) t1)))
+ ;; Two time stamps.
+ (let* ((ts (float-time
+ (apply #'encode-time
+ (save-match-data
+ (org-parse-time-string
+ (match-string 2) nil t)))))
+ (te (float-time
+ (apply #'encode-time
+ (org-parse-time-string (match-string 3) nil t))))
+ (dt (- (if tend (min te tend) te)
+ (if tstart (max ts tstart) ts))))
+ (when (> dt 0) (cl-incf t1 (floor (/ dt 60))))))
((match-end 4)
- ;; A naked time
+ ;; A naked time.
(setq t1 (+ t1 (string-to-number (match-string 5))
(* 60 (string-to-number (match-string 4))))))
- (t ;; A headline
- ;; Add the currently clocking item time to the total
+ (t ;A headline
+ ;; Add the currently clocking item time to the total.
(when (and org-clock-report-include-clocking-task
- (equal (org-clocking-buffer) (current-buffer))
- (equal (marker-position org-clock-hd-marker) (point))
+ (eq (org-clocking-buffer) (current-buffer))
+ (eq (marker-position org-clock-hd-marker) (point))
tstart
tend
(>= (float-time org-clock-start-time) tstart)
(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 nil t))))))
+ (setq ts (float-time (apply #'encode-time (org-parse-time-string ts))))))
(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 nil t))))))
+ (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)))
(defalias 'format-message 'format)
(defalias 'gui-get-selection 'x-get-selection))
+(defun org-decode-time (&optional time zone)
+ "Backward-compatible function for `decode-time'."
+ (if (< emacs-major-version 25)
+ (decode-time time)
+ (decode-time time zone)))
+
\f
;;; Obsolete aliases (remove them after the next major release).
(define-obsolete-function-alias 'org-babel-number-p
'org-babel--string-to-number "Org 9.0")
+;;; The function was made obsolete by commit 65399674d5 of 2013-02-22.
+;;; This make-obsolete call was added 2016-09-01.
+(make-obsolete 'org-capture-import-remember-templates
+ "use the `org-capture-templates' variable instead."
+ "Org 9.0")
+
\f
;;;; Obsolete link types
(save-excursion
(let* ((begin (point))
(after-fragment
- (if (eq (char-after) ?$)
- (if (eq (char-after (1+ (point))) ?$)
- (search-forward "$$" nil t 2)
- (and (not (eq (char-before) ?$))
- (search-forward "$" nil t 2)
- (not (memq (char-before (match-beginning 0))
- '(?\s ?\t ?\n ?, ?.)))
- (looking-at-p
- "\\(\\s.\\|\\s-\\|\\s(\\|\\s)\\|\\s\"\\|'\\|$\\)")
- (point)))
+ (cond
+ ((not (eq ?$ (char-after)))
(pcase (char-after (1+ (point)))
(?\( (search-forward "\\)" nil t))
(?\[ (search-forward "\\]" nil t))
;; Macro.
(and (looking-at "\\\\[a-zA-Z]+\\*?\\(\\(\\[[^][\n{}]*\\]\\)\
\\|\\({[^{}\n]*}\\)\\)*")
- (match-end 0))))))
- (post-blank (if (not after-fragment) (throw 'no-object nil)
- (goto-char after-fragment)
- (skip-chars-forward " \t")))
+ (match-end 0)))))
+ ((eq ?$ (char-after (1+ (point))))
+ (search-forward "$$" nil t 2))
+ (t
+ (and (not (eq ?$ (char-before)))
+ (not (memq (char-after (1+ (point)))
+ '(?\s ?\t ?\n ?, ?. ?\;)))
+ (search-forward "$" nil t 2)
+ (not (memq (char-before (match-beginning 0))
+ '(?\s ?\t ?\n ?, ?.)))
+ (looking-at-p
+ "\\(\\s.\\|\\s-\\|\\s(\\|\\s)\\|\\s\"\\|'\\|$\\)")
+ (point)))))
+ (post-blank
+ (if (not after-fragment) (throw 'no-object nil)
+ (goto-char after-fragment)
+ (skip-chars-forward " \t")))
(end (point)))
(list 'latex-fragment
(list :value (buffer-substring-no-properties begin after-fragment)
;; 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)))
+ (cond ((<= n 1) "")
+ ((bound-and-true-p org-inlinetask-show-first-star)
+ (concat org-indent-inlinetask-first-star
+ (substring heading-prefix 1)))
+ (t (org-add-props heading-prefix nil 'face 'org-indent)))))
;; Text line prefixes.
(aset org-indent--text-line-prefixes
n
(require 'erc)
(require 'erc-log)
(let* ((server (car (car link)))
- (port (or (string-to-number (cadr (pop link))) erc-default-port))
+ (port (let ((p (cadr (pop link))))
+ (if p (string-to-number p) erc-default-port)))
(server-buffer)
(buffer-list
(erc-buffer-filter
(org-element-map ast 'footnote-reference
(lambda (f)
(let ((label (org-element-property :label f)))
- (and label
+ (and (eq 'standard (org-element-property :type f))
(not (member label definitions))
(list (org-element-property :begin f)
(format "Missing definition for footnote [%s]"
Optional argument KEYWORDS, when non-nil is a list of keywords,
as strings, where macro expansion is allowed."
- (save-excursion
- (goto-char (point-min))
- (let ((properties-regexp
- (format "\\`EXPORT_%s\\+?\\'" (regexp-opt keywords)))
- record)
- (while (re-search-forward "{{{[-A-Za-z0-9_]" nil t)
- (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))))))))))))
+ (org-with-wide-buffer
+ (goto-char (point-min))
+ (let ((properties-regexp (format "\\`EXPORT_%s\\+?\\'"
+ (regexp-opt keywords)))
+ record)
+ (while (re-search-forward "{{{[-A-Za-z0-9_]" nil t)
+ (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.
(allow-empty? nil)
(t (user-error "Empty input is not valid")))))
+(defconst org-unique-local-variables
+ '(org-element--cache
+ org-element--cache-objects
+ org-element--cache-sync-keys
+ org-element--cache-sync-requests
+ org-element--cache-sync-timer)
+ "List of local variables that cannot be transferred to another buffer.")
+
+(defun org-get-local-variables ()
+ "Return a list of all local variables in an Org mode buffer."
+ (delq nil
+ (mapcar
+ (lambda (x)
+ (let* ((binding (if (symbolp x) (list x) (list (car x) (cdr x))))
+ (name (car binding)))
+ (and (not (get name 'org-state))
+ (not (memq name org-unique-local-variables))
+ (string-match-p
+ "\\`\\(org-\\|orgtbl-\\|outline-\\|comment-\\|paragraph-\\|\
+auto-fill\\|normal-auto-fill\\|fill-paragraph\\|indent-\\)"
+ (symbol-name name))
+ binding)))
+ (with-temp-buffer
+ (org-mode)
+ (buffer-local-variables)))))
+
+(defun org-clone-local-variables (from-buffer &optional regexp)
+ "Clone local variables from FROM-BUFFER.
+Optional argument REGEXP selects variables to clone."
+ (dolist (pair (buffer-local-variables from-buffer))
+ (pcase pair
+ (`(,name . ,value) ;ignore unbound variables
+ (when (and (not (memq name org-unique-local-variables))
+ (or (null regexp) (string-match-p regexp (symbol-name name))))
+ (ignore-errors (set (make-local-variable name) value)))))))
+
+
(provide 'org-macs)
;;; org-macs.el ends here
(defun org-mobile-encrypt-file (infile outfile)
"Encrypt INFILE to OUTFILE, using `org-mobile-encryption-password'."
(shell-command
- (format "openssl enc -aes-256-cbc -salt -pass %s -in %s -out %s"
+ (format "openssl enc -md md5 -aes-256-cbc -salt -pass %s -in %s -out %s"
(shell-quote-argument (concat "pass:"
(org-mobile-encryption-password)))
(shell-quote-argument (expand-file-name infile))
(defun org-mobile-decrypt-file (infile outfile)
"Decrypt INFILE to OUTFILE, using `org-mobile-encryption-password'."
(shell-command
- (format "openssl enc -d -aes-256-cbc -salt -pass %s -in %s -out %s"
+ (format "openssl enc -md md5 -d -aes-256-cbc -salt -pass %s -in %s -out %s"
(shell-quote-argument (concat "pass:"
(org-mobile-encryption-password)))
(shell-quote-argument (expand-file-name infile))
;; As we enter this function for a match on our protocol, the return value
;; defaults to nil.
(let ((result nil)
- (f (plist-get (org-protocol-parse-parameters fname nil '(:url)) :url)))
+ (f (org-protocol-sanitize-uri
+ (plist-get (org-protocol-parse-parameters fname nil '(:url))
+ :url))))
(catch 'result
(dolist (prolist org-protocol-project-alist)
(let* ((base-url (plist-get (cdr prolist) :base-url))
;; Try to match a rewritten URL and map it to
;; a real file. Compare redirects without
;; suffix.
- (when (string-match-p (car rewrite) f2)
+ (when (string-match-p (car rewrite) f1)
(throw 'result (concat wdir (cdr rewrite))))))))
;; -- end of redirects --
(buffer-string))))
(defun org-src--edit-element
- (datum name &optional major write-back contents remote)
+ (datum name &optional initialize write-back contents remote)
"Edit DATUM contents in a dedicated buffer NAME.
-MAJOR is the major mode used in the edit buffer. A nil value is
-equivalent to `fundamental-mode'.
+INITIALIZE is a function to call upon creating the buffer.
When WRITE-BACK is non-nil, assume contents will replace original
region. Moreover, if it is a function, apply it in the edit
(unless preserve-ind (org-do-remove-indentation))
(set-buffer-modified-p nil)
(setq buffer-file-name nil)
- ;; Start major mode.
- (if (not major) (fundamental-mode)
+ ;; Initialize buffer.
+ (when (functionp initialize)
(let ((org-inhibit-startup t))
- (condition-case e (funcall major)
- (error (message "Language mode `%s' fails with: %S"
- major (nth 1 e))))))
+ (condition-case e
+ (funcall initialize)
+ (error (message "Initialization fails with: %S"
+ (error-message-string e))))))
;; Transmit buffer-local variables for exit function. It must
;; be done after initializing major mode, as this operation
;; may reset them otherwise.
(org-src--edit-element
definition
(format "*Edit footnote [%s]*" label)
- #'org-mode
+ (let ((source (current-buffer)))
+ (lambda ()
+ (org-mode)
+ (org-clone-local-variables source)))
(lambda ()
(if (not inline?) (delete-region (point) (search-forward "]"))
(delete-region (point) (search-forward ":" nil t 2))
(org-table-check-inside-data-field))
(save-excursion
(let ((c 0)
- (pos (point)))
+ (pos (line-beginning-position)))
(goto-char (org-table-begin))
(while (<= (point) pos)
(when (looking-at org-table-dataline-regexp) (cl-incf c))
(dline1 (org-table-current-dline))
(dline2 (+ dline1 (if up -1 1)))
(tonew (if up 0 2))
- txt hline2p)
+ hline2p)
+ (when (and up (= (point-min) (line-beginning-position)))
+ (user-error "Cannot move row further"))
(beginning-of-line tonew)
- (unless (org-at-table-p)
+ (when (or (and (not up) (eobp)) (not (org-at-table-p)))
(goto-char pos)
(user-error "Cannot move row further"))
(setq hline2p (looking-at org-table-hline-regexp))
(goto-char pos)
- (beginning-of-line 1)
- (setq pos (point))
- (setq txt (buffer-substring (point) (1+ (point-at-eol))))
- (delete-region (point) (1+ (point-at-eol)))
- (beginning-of-line tonew)
- (insert txt)
- (beginning-of-line 0)
- (org-move-to-column col)
- (unless (or hline1p hline2p
- (not (or (not org-table-fix-formulas-confirm)
- (funcall org-table-fix-formulas-confirm
- "Fix formulas? "))))
- (org-table-fix-formulas
- "@" (list (cons (number-to-string dline1) (number-to-string dline2))
- (cons (number-to-string dline2) (number-to-string dline1)))))))
+ (let ((row (delete-and-extract-region (line-beginning-position)
+ (line-beginning-position 2))))
+ (beginning-of-line tonew)
+ (unless (bolp) (insert "\n")) ;at eob without a newline
+ (insert row)
+ (unless (bolp) (insert "\n")) ;missing final newline in ROW
+ (beginning-of-line 0)
+ (org-move-to-column col)
+ (unless (or hline1p hline2p
+ (not (or (not org-table-fix-formulas-confirm)
+ (funcall org-table-fix-formulas-confirm
+ "Fix formulas? "))))
+ (org-table-fix-formulas
+ "@" (list
+ (cons (number-to-string dline1) (number-to-string dline2))
+ (cons (number-to-string dline2) (number-to-string dline1))))))))
;;;###autoload
(defun org-table-insert-row (&optional arg)
(defun org-release ()
"The release version of Org.
Inserted by installing Org mode or when a release is made."
- (let ((org-release "9.0.9"))
+ (let ((org-release "9.0.10"))
org-release))
;;;###autoload
(defun org-git-version ()
"The Git version of org-mode.
Inserted by installing Org or when a release is made."
- (let ((org-git-version "release_9.0.9"))
+ (let ((org-git-version "release_9.0.10"))
org-git-version))
\f
(provide 'org-version)
(declare-function org-clock-timestamps-down "org-clock" (&optional n))
(declare-function org-clock-timestamps-up "org-clock" (&optional n))
(declare-function org-clock-update-time-maybe "org-clock" ())
+(declare-function org-clocking-buffer "org-clock" ())
(declare-function org-clocktable-shift "org-clock" (dir n))
(declare-function org-element-at-point "org-element" ())
(declare-function org-element-cache-refresh "org-element" (pos))
(defcustom org-ellipsis nil
"The ellipsis to use in the Org mode outline.
-When nil, just use the standard three dots.
-When a string, use that string instead.
+When nil, just use the standard three dots. When a non-empty string,
+use that string instead.
The change affects only Org mode (which will then use its own display table).
Changing this requires executing `\\[org-mode]' in a buffer to become
:group 'org-startup
:type '(choice (const :tag "Default" nil)
(string :tag "String" :value "...#"))
- :safe #'string-or-null-p)
+ :safe (lambda (v) (and (string-or-null-p v) (not (equal "" v)))))
(defvar org-display-table nil
- "The display table for org-mode, in case `org-ellipsis' is non-nil.")
+ "The display table for Org mode, in case `org-ellipsis' is non-nil.")
(defgroup org-keywords nil
"Keywords in Org mode."
:group 'org-tags
:type '(repeat
(choice
- (cons (string :tag "Tag name")
- (character :tag "Access char"))
+ (cons :tag "Tag with key"
+ (string :tag "Tag name")
+ (character :tag "Access char"))
+ (list :tag "Tag" (string :tag "Tag name"))
(const :tag "Start radio group" (:startgroup))
(const :tag "Start tag group, non distinct" (:startgrouptag))
(const :tag "Group tags delimiter" (:grouptags))
:group 'org-tags
:type '(repeat
(choice
- (cons (string :tag "Tag name")
+ (cons :tag "Tag with key"
+ (string :tag "Tag name")
(character :tag "Access char"))
+ (list :tag "Tag" (string :tag "Tag name"))
(const :tag "Start radio group" (:startgroup))
(const :tag "Start tag group, non distinct" (:startgrouptag))
(const :tag "Group tags delimiter" (:grouptags))
:group 'org-sparse-trees)
(defun org-cycle-hide-archived-subtrees (state)
- "Re-hide all archived subtrees after a visibility state change."
+ "Re-hide all archived subtrees after a visibility state change.
+STATE should be one of the symbols listed in the docstring of
+`org-cycle-hook'."
(when (and (not org-cycle-open-archived-trees)
(not (memq state '(overview folded))))
(save-excursion
(setq-local outline-regexp org-outline-regexp)
(setq-local outline-level 'org-outline-level)
(setq bidi-paragraph-direction 'left-to-right)
- (when (and org-ellipsis
- (fboundp 'set-display-table-slot) (boundp 'buffer-display-table)
- (fboundp 'make-glyph-code))
+ (when (and (stringp org-ellipsis) (not (equal "" org-ellipsis)))
(unless org-display-table
(setq org-display-table (make-display-table)))
(set-display-table-slot
org-display-table 4
(vconcat (mapcar (lambda (c) (make-glyph-code c 'org-ellipsis))
- (if (stringp org-ellipsis) org-ellipsis "..."))))
+ org-ellipsis)))
(setq buffer-display-table org-display-table))
(org-set-regexps-and-options)
(org-set-font-lock-defaults)
'keymap org-mouse-map))
(org-rear-nonsticky-at (match-end 0))
(when org-display-custom-times
- (if (match-end 3)
- (org-display-custom-time (match-beginning 3) (match-end 3))
- (org-display-custom-time (match-beginning 1) (match-end 1))))
+ ;; If it's a date range, activate custom time for second date.
+ (when (match-end 3)
+ (org-display-custom-time (match-beginning 3) (match-end 3)))
+ (org-display-custom-time (match-beginning 1) (match-end 1)))
t))
(defvar-local org-target-link-regexp nil
(defun org-cycle-hide-drawers (state &optional exceptions)
"Re-hide all drawers after a visibility state change.
-When non-nil, optional argument EXCEPTIONS is a list of strings
-specifying which drawers should not be hidden."
+STATE should be one of the symbols listed in the docstring of
+`org-cycle-hook'. When non-nil, optional argument EXCEPTIONS is
+a list of strings specifying which drawers should not be hidden."
(when (and (derived-mode-p 'org-mode)
(not (memq state '(overview folded contents))))
(save-excursion
- (let* ((globalp (memq state '(contents all)))
+ (let* ((globalp (eq state 'all))
(beg (if globalp (point-min) (point)))
(end (if globalp (point-max)
(if (eq state 'children)
function is being called interactively."
(interactive (list current-prefix-arg nil nil nil nil t))
(let ((case-func (if with-case 'identity 'downcase))
- (cmstr
- ;; The clock marker is lost when using `sort-subr', let's
- ;; store the clocking string.
- (when (equal (marker-buffer org-clock-marker) (current-buffer))
- (save-excursion
- (goto-char org-clock-marker)
- (buffer-substring-no-properties (line-beginning-position)
- (point)))))
start beg end stars re re2
txt what tmp)
;; Find beginning and end of region to sort
(save-restriction
(narrow-to-region start end)
- (let ((dcst (downcase sorting-type))
+ (let ((restore-clock?
+ ;; The clock marker is lost when using `sort-subr'; mark
+ ;; the clock with temporary `:org-clock-marker-backup'
+ ;; text property.
+ (when (and (eq (org-clocking-buffer) (current-buffer))
+ (<= start (marker-position org-clock-marker))
+ (>= end (marker-position org-clock-marker)))
+ (org-with-silent-modifications
+ (put-text-property (1- org-clock-marker) org-clock-marker
+ :org-clock-marker-backup t))
+ t))
+ (dcst (downcase sorting-type))
(case-fold-search nil)
- (now (current-time)))
+ (now (current-time)))
(sort-subr
(/= dcst sorting-type)
;; This function moves to the beginning character of the "record" to
(concat "Function for comparing keys "
"(empty for default `sort-subr' predicate): ")
'allow-empty))))
- ((member dcst '(?p ?t ?s ?d ?c ?k)) '<)))))
+ ((member dcst '(?p ?t ?s ?d ?c ?k)) '<)))
+ (when restore-clock?
+ (move-marker org-clock-marker
+ (1+ (next-single-property-change
+ start :org-clock-marker-backup)))
+ (remove-text-properties (1- org-clock-marker) org-clock-marker
+ '(:org-clock-marker-backup t)))))
(run-hooks 'org-after-sorting-entries-or-items-hook)
- ;; Reset the clock marker if needed
- (when cmstr
- (save-excursion
- (goto-char start)
- (search-forward cmstr nil t)
- (move-marker org-clock-marker (point))))
(message "Sorting entries...done")))
;;; The orgstruct minor mode
(org-in-item-p)))
(goto-char pos))))
-(defconst org-unique-local-variables
- '(org-element--cache
- org-element--cache-objects
- org-element--cache-sync-keys
- org-element--cache-sync-requests
- org-element--cache-sync-timer)
- "List of local variables that cannot be transferred to another buffer.")
-
-(defun org-get-local-variables ()
- "Return a list of all local variables in an Org mode buffer."
- (delq nil
- (mapcar
- (lambda (x)
- (let* ((binding (if (symbolp x) (list x) (list (car x) (cdr x))))
- (name (car binding)))
- (and (not (get name 'org-state))
- (not (memq name org-unique-local-variables))
- (string-match-p
- "\\`\\(org-\\|orgtbl-\\|outline-\\|comment-\\|paragraph-\\|\
-auto-fill\\|normal-auto-fill\\|fill-paragraph\\|indent-\\)"
- (symbol-name name))
- binding)))
- (with-temp-buffer
- (org-mode)
- (buffer-local-variables)))))
-
-(defun org-clone-local-variables (from-buffer &optional regexp)
- "Clone local variables from FROM-BUFFER.
-Optional argument REGEXP selects variables to clone."
- (dolist (pair (buffer-local-variables from-buffer))
- (pcase pair
- (`(,name . ,value) ;ignore unbound variables
- (when (and (not (memq name org-unique-local-variables))
- (or (null regexp) (string-match-p regexp (symbol-name name))))
- (set (make-local-variable name) value))))))
-
;;;###autoload
(defun org-run-like-in-org-mode (cmd)
"Run a command, pretending that the current buffer is in Org mode.
specify a buffer from where the link search should happen. This
is used internally by `org-open-link-from-string'.
-On top of syntactically correct links, this function will open
-the link at point in comments or comment blocks and the first
-link in a property drawer line."
+On top of syntactically correct links, this function will also
+try to open links and time-stamps in comments, example
+blocks... i.e., whenever point is on something looking like
+a timestamp or a link."
(interactive "P")
;; On a code block, open block's results.
(unless (call-interactively 'org-babel-open-src-block-result)
;; the closest one.
(org-element-lineage
(org-element-context)
- '(clock comment comment-block footnote-definition
- footnote-reference headline inlinetask keyword link
- node-property timestamp)
+ '(clock footnote-definition footnote-reference headline
+ inlinetask link timestamp)
t))
(type (org-element-type context))
(value (org-element-property :value context)))
(cond
- ((not context) (user-error "No link found"))
- ;; Exception: open timestamps and links in properties
- ;; drawers, keywords and comments.
- ((memq type '(comment comment-block keyword node-property))
- (call-interactively #'org-open-at-point-global))
;; On a headline or an inlinetask, but not on a timestamp,
- ;; a link, a footnote reference or on tags.
- ((and (memq type '(headline inlinetask))
- ;; Not on tags.
- (let ((case-fold-search nil))
- (save-excursion
- (beginning-of-line)
- (looking-at org-complex-heading-regexp))
- (or (not (match-beginning 5))
- (< (point) (match-beginning 5)))))
- (let* ((data (org-offer-links-in-entry (current-buffer) (point) arg))
- (links (car data))
- (links-end (cdr data)))
- (if links
- (dolist (link (if (stringp links) (list links) links))
- (search-forward link nil links-end)
- (goto-char (match-beginning 0))
- (org-open-at-point))
- (require 'org-attach)
- (org-attach-reveal 'if-exists))))
+ ;; a link, a footnote reference.
+ ((memq type '(headline inlinetask))
+ (org-match-line org-complex-heading-regexp)
+ (if (and (match-beginning 5)
+ (>= (point) (match-beginning 5))
+ (< (point) (match-end 5)))
+ ;; On tags.
+ (org-tags-view arg (substring (match-string 5) 0 -1))
+ ;; Not on tags.
+ (pcase (org-offer-links-in-entry (current-buffer) (point) arg)
+ (`(nil . ,_)
+ (require 'org-attach)
+ (org-attach-reveal 'if-exists))
+ (`(,links . ,links-end)
+ (dolist (link (if (stringp links) (list links) links))
+ (search-forward link nil links-end)
+ (goto-char (match-beginning 0))
+ (org-open-at-point))))))
+ ;; On a footnote reference or at definition's label.
+ ((or (eq type 'footnote-reference)
+ (and (eq type 'footnote-definition)
+ (save-excursion
+ ;; Do not validate action when point is on the
+ ;; spaces right after the footnote label, in
+ ;; order to be on par with behaviour on links.
+ (skip-chars-forward " \t")
+ (let ((begin
+ (org-element-property :contents-begin context)))
+ (if begin (< (point) begin)
+ (= (org-element-property :post-affiliated context)
+ (line-beginning-position)))))))
+ (org-footnote-action))
+ ;; No valid context. Ignore catch-all types like `headline'.
+ ;; If point is on something looking like a link or
+ ;; a time-stamp, try opening it. It may be useful in
+ ;; comments, example blocks...
+ ((memq type '(footnote-definition headline inlinetask nil))
+ (call-interactively #'org-open-at-point-global))
;; On a clock line, make sure point is on the timestamp
;; before opening it.
((and (eq type 'clock)
(point)))
(user-error "No link found"))
((eq type 'timestamp) (org-follow-timestamp-link))
- ;; On tags within a headline or an inlinetask.
- ((and (memq type '(headline inlinetask))
- (let ((case-fold-search nil))
- (save-excursion (beginning-of-line)
- (looking-at org-complex-heading-regexp))
- (and (match-beginning 5)
- (>= (point) (match-beginning 5)))))
- (org-tags-view arg (substring (match-string 5) 0 -1)))
((eq type 'link)
;; When link is located within the description of another
;; link (e.g., an inline image), always open the parent
(widen))
(goto-char destination))))
(t (browse-url-at-point))))))
- ;; On a footnote reference or at a footnote definition's label.
- ((or (eq type 'footnote-reference)
- (and (eq type 'footnote-definition)
- (save-excursion
- ;; Do not validate action when point is on the
- ;; spaces right after the footnote label, in
- ;; order to be on par with behaviour on links.
- (skip-chars-forward " \t")
- (let ((begin
- (org-element-property :contents-begin context)))
- (if begin (< (point) begin)
- (= (org-element-property :post-affiliated context)
- (line-beginning-position)))))))
- (org-footnote-action))
(t (user-error "No link found")))))
(run-hook-with-args 'org-follow-link-hook)))
(if (and arg (not (equal arg 3)))
(progn
(pop-to-buffer-same-window nbuf)
- (goto-char pos)
+ (goto-char (cond (pos)
+ ((org-notes-order-reversed-p) (point-min))
+ (t (point-max))))
(org-show-context 'org-goto))
(if regionp
(progn
(replace-match next t t)
(cond ((equal this org-state)
(message "TODO state was already %s" (org-trim next)))
- ((pos-visible-in-window-p hl-pos)
+ ((not (pos-visible-in-window-p hl-pos))
(message "TODO state changed to %s" (org-trim next))))
(unless head
(setq head (org-get-todo-sequence-head org-state)
(org-switch-to-buffer-other-window "*Org Note*")
(erase-buffer)
(if (memq org-log-note-how '(time state))
- (let (current-prefix-arg) (org-store-log-note))
+ (org-store-log-note)
(let ((org-inhibit-startup t)) (org-mode))
(insert (format "# Insert note for %s.
# Finish with C-c C-c, or cancel with C-c C-k.\n\n"
org-log-note-previous-state)))))))
(when lines (setq note (concat note " \\\\")))
(push note lines))
- (when (and lines (not (or current-prefix-arg org-note-abort)))
+ (when (and lines (not org-note-abort))
(with-current-buffer (marker-buffer org-log-note-marker)
(org-with-wide-buffer
;; Find location for the new note.
((numberp s) s)
((stringp s)
(condition-case nil
- (float-time (apply 'encode-time (org-parse-time-string s)))
+ (float-time (apply #'encode-time (org-parse-time-string s nil t)))
(error 0.)))
(t 0.)))
(catch 'exit
(let ((pos (point))
(dodollar (member "$" (plist-get org-format-latex-options :matchers)))
- (lim (progn
- (re-search-backward (concat "^\\(" paragraph-start "\\)") nil t)
- (point)))
+ (lim (save-excursion (org-backward-paragraph) (point)))
dd-on str (start 0) m re)
(goto-char pos)
(when dodollar
(insert latex-header)
(insert "\n\\begin{document}\n" string "\n\\end{document}\n")))
- (let* ((err-msg (format "Please adjust '%s' part of \
+ (let* ((err-msg (format "Please adjust `%s' part of \
`org-preview-latex-process-alist'."
processing-type))
(image-input-file
(call-interactively 'org-self-insert-command)))))
((and
(org-at-table-p)
+ (eq N 1)
+ (not (org-region-active-p))
(progn
;; Check if we blank the field, and if that triggers align.
(and (featurep 'org-table) org-table-auto-blank-field
;; width.
(org-table-blank-field)))
t)
- (eq N 1)
(looking-at "[^|\n]* \\( \\)|"))
;; There is room for insertion without re-aligning the table.
(delete-region (match-beginning 1) (match-end 1))
(or (not (boundp 'visible-mode)) (not visible-mode))
(or (get-char-property (point) 'invisible)
(get-char-property (max (point-min) (1- (point))) 'invisible)))
- ;; OK, we need to take a closer look
- (let* ((invisible-at-point (get-char-property (point) 'invisible))
- (invisible-before-point (unless (bobp) (get-char-property
- (1- (point)) 'invisible)))
+ ;; OK, we need to take a closer look. Do not consider
+ ;; invisibility obtained through text properties (e.g., link
+ ;; fontification), as it cannot be toggled.
+ (let* ((invisible-at-point
+ (pcase (get-char-property-and-overlay (point) 'invisible)
+ (`(,_ . ,(and (pred overlayp) o)) o)))
+ ;; Assume that point cannot land in the middle of an
+ ;; overlay, or between two overlays.
+ (invisible-before-point
+ (and (not invisible-at-point)
+ (not (bobp))
+ (pcase (get-char-property-and-overlay (1- (point)) 'invisible)
+ (`(,_ . ,(and (pred overlayp) o)) o))))
(border-and-ok-direction
(or
- ;; Check if we are acting predictably before invisible text
- (and invisible-at-point (not invisible-before-point)
+ ;; Check if we are acting predictably before invisible
+ ;; text.
+ (and invisible-at-point
(memq kind '(insert delete-backward)))
;; Check if we are acting predictably after invisible text
;; This works not well, and I have turned it off. It seems
;; (and (not invisible-at-point) invisible-before-point
;; (memq kind '(insert delete)))
)))
- (when (or (memq invisible-at-point '(outline org-hide-block t))
- (memq invisible-before-point '(outline org-hide-block t)))
+ (when (or invisible-at-point invisible-before-point)
(when (eq org-catch-invisible-edits 'error)
(user-error "Editing in invisible areas is prohibited, make them visible first"))
(if (and org-custom-properties-overlays
;; Make the area visible
(save-excursion
(when invisible-before-point
- (goto-char (previous-single-char-property-change
- (point) 'invisible)))
- (outline-show-subtree))
+ (goto-char
+ (previous-single-char-property-change (point) 'invisible)))
+ ;; Remove whatever overlay is currently making yet-to-be
+ ;; edited text invisible. Also remove nested invisibility
+ ;; related overlays.
+ (delete-overlay (or invisible-at-point invisible-before-point))
+ (let ((origin (if invisible-at-point (point) (1- (point)))))
+ (while (pcase (get-char-property-and-overlay origin 'invisible)
+ (`(,_ . ,(and (pred overlayp) o))
+ (delete-overlay o)
+ t)))))
(cond
((eq org-catch-invisible-edits 'show)
;; That's it, we do the edit after showing
(defun org-copy-visible (beg end)
"Copy the visible parts of the region."
(interactive "r")
- (let (snippets s)
- (save-excursion
- (save-restriction
- (narrow-to-region beg end)
- (setq s (goto-char (point-min)))
- (while (not (= (point) (point-max)))
- (goto-char (org-find-invisible))
- (push (buffer-substring s (point)) snippets)
- (setq s (goto-char (org-find-visible))))))
- (kill-new (apply 'concat (nreverse snippets)))))
+ (let ((result ""))
+ (while (/= beg end)
+ (when (get-char-property beg 'invisible)
+ (setq beg (next-single-char-property-change beg 'invisible nil end)))
+ (let ((next (next-single-char-property-change beg 'invisible nil end)))
+ (setq result (concat result (buffer-substring beg next)))
+ (setq beg next)))
+ (kill-new result)))
(defun org-copy-special ()
"Copy region in table or copy current subtree.
- On a table or a property drawer, jump after it.
- On a verse or source block, stop after blank lines."
(interactive)
- (when (eobp) (user-error "Cannot move further down"))
- (let* ((deactivate-mark nil)
- (element (org-element-at-point))
- (type (org-element-type element))
- (post-affiliated (org-element-property :post-affiliated element))
- (contents-begin (org-element-property :contents-begin element))
- (contents-end (org-element-property :contents-end element))
- (end (let ((end (org-element-property :end element)) (parent element))
- (while (and (setq parent (org-element-property :parent parent))
- (= (org-element-property :contents-end parent) end))
- (setq end (org-element-property :end parent)))
- end)))
- (cond ((not element)
- (skip-chars-forward " \r\t\n")
- (or (eobp) (beginning-of-line)))
- ;; On affiliated keywords, move to element's beginning.
- ((< (point) post-affiliated)
- (goto-char post-affiliated))
- ;; At a table row, move to the end of the table. Similarly,
- ;; at a node property, move to the end of the property
- ;; drawer.
- ((memq type '(node-property table-row))
- (goto-char (org-element-property
- :end (org-element-property :parent element))))
- ((memq type '(property-drawer table)) (goto-char end))
- ;; Consider blank lines as separators in verse and source
- ;; blocks to ease editing.
- ((memq type '(src-block verse-block))
- (when (eq type 'src-block)
- (setq contents-end
- (save-excursion (goto-char end)
- (skip-chars-backward " \r\t\n")
- (line-beginning-position))))
- (beginning-of-line)
- (when (looking-at "[ \t]*$") (skip-chars-forward " \r\t\n"))
- (if (not (re-search-forward "^[ \t]*$" contents-end t))
- (goto-char end)
- (skip-chars-forward " \r\t\n")
- (if (= (point) contents-end) (goto-char end)
- (beginning-of-line))))
- ;; With no contents, just skip element.
- ((not contents-begin) (goto-char end))
- ;; If contents are invisible, skip the element altogether.
- ((org-invisible-p (line-end-position))
- (cl-case type
- (headline
- (org-with-limited-levels (outline-next-visible-heading 1)))
- ;; At a plain list, make sure we move to the next item
- ;; instead of skipping the whole list.
- (plain-list (forward-char)
- (org-forward-paragraph))
- (otherwise (goto-char end))))
- ((>= (point) contents-end) (goto-char end))
- ((>= (point) contents-begin)
- ;; This can only happen on paragraphs and plain lists.
- (cl-case type
- (paragraph (goto-char end))
- ;; At a plain list, try to move to second element in
- ;; first item, if possible.
- (plain-list (end-of-line)
- (org-forward-paragraph))))
- ;; When contents start on the middle of a line (e.g. in
- ;; items and footnote definitions), try to reach first
- ;; element starting after current line.
- ((> (line-end-position) contents-begin)
- (end-of-line)
- (org-forward-paragraph))
- (t (goto-char contents-begin)))))
+ (unless (eobp)
+ (let* ((deactivate-mark nil)
+ (element (org-element-at-point))
+ (type (org-element-type element))
+ (post-affiliated (org-element-property :post-affiliated element))
+ (contents-begin (org-element-property :contents-begin element))
+ (contents-end (org-element-property :contents-end element))
+ (end (let ((end (org-element-property :end element)) (parent element))
+ (while (and (setq parent (org-element-property :parent parent))
+ (= (org-element-property :contents-end parent) end))
+ (setq end (org-element-property :end parent)))
+ end)))
+ (cond ((not element)
+ (skip-chars-forward " \r\t\n")
+ (or (eobp) (beginning-of-line)))
+ ;; On affiliated keywords, move to element's beginning.
+ ((< (point) post-affiliated)
+ (goto-char post-affiliated))
+ ;; At a table row, move to the end of the table. Similarly,
+ ;; at a node property, move to the end of the property
+ ;; drawer.
+ ((memq type '(node-property table-row))
+ (goto-char (org-element-property
+ :end (org-element-property :parent element))))
+ ((memq type '(property-drawer table)) (goto-char end))
+ ;; Consider blank lines as separators in verse and source
+ ;; blocks to ease editing.
+ ((memq type '(src-block verse-block))
+ (when (eq type 'src-block)
+ (setq contents-end
+ (save-excursion (goto-char end)
+ (skip-chars-backward " \r\t\n")
+ (line-beginning-position))))
+ (beginning-of-line)
+ (when (looking-at "[ \t]*$") (skip-chars-forward " \r\t\n"))
+ (if (not (re-search-forward "^[ \t]*$" contents-end t))
+ (goto-char end)
+ (skip-chars-forward " \r\t\n")
+ (if (= (point) contents-end) (goto-char end)
+ (beginning-of-line))))
+ ;; With no contents, just skip element.
+ ((not contents-begin) (goto-char end))
+ ;; If contents are invisible, skip the element altogether.
+ ((org-invisible-p (line-end-position))
+ (cl-case type
+ (headline
+ (org-with-limited-levels (outline-next-visible-heading 1)))
+ ;; At a plain list, make sure we move to the next item
+ ;; instead of skipping the whole list.
+ (plain-list (forward-char)
+ (org-forward-paragraph))
+ (otherwise (goto-char end))))
+ ((>= (point) contents-end) (goto-char end))
+ ((>= (point) contents-begin)
+ ;; This can only happen on paragraphs and plain lists.
+ (cl-case type
+ (paragraph (goto-char end))
+ ;; At a plain list, try to move to second element in
+ ;; first item, if possible.
+ (plain-list (end-of-line)
+ (org-forward-paragraph))))
+ ;; When contents start on the middle of a line (e.g. in
+ ;; items and footnote definitions), try to reach first
+ ;; element starting after current line.
+ ((> (line-end-position) contents-begin)
+ (end-of-line)
+ (org-forward-paragraph))
+ (t (goto-char contents-begin))))))
(defun org-backward-paragraph ()
"Move backward to start of previous paragraph or equivalent.
- On a table or a property drawer, move to its beginning.
- On a verse or source block, stop before blank lines."
(interactive)
- (when (bobp) (user-error "Cannot move further up"))
- (let* ((deactivate-mark nil)
- (element (org-element-at-point))
- (type (org-element-type element))
- (contents-begin (org-element-property :contents-begin element))
- (contents-end (org-element-property :contents-end element))
- (post-affiliated (org-element-property :post-affiliated element))
- (begin (org-element-property :begin element)))
- (cond
- ((not element) (goto-char (point-min)))
- ((= (point) begin)
- (backward-char)
- (org-backward-paragraph))
- ((<= (point) post-affiliated) (goto-char begin))
- ((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))
- ((memq type '(src-block verse-block))
- (when (eq type 'src-block)
- (setq contents-begin
- (save-excursion (goto-char begin) (forward-line) (point))))
- (if (= (point) contents-begin) (goto-char post-affiliated)
- ;; Inside a verse block, see blank lines as paragraph
- ;; separators.
- (let ((origin (point)))
- (skip-chars-backward " \r\t\n" contents-begin)
- (when (re-search-backward "^[ \t]*$" contents-begin 'move)
- (skip-chars-forward " \r\t\n" origin)
- (if (= (point) origin) (goto-char contents-begin)
- (beginning-of-line))))))
- ((not contents-begin) (goto-char (or post-affiliated 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
- (org-element-property
- :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)
- (goto-char (1- contents-end))
- (org-backward-paragraph))
- (t (goto-char (or post-affiliated begin))))
- ;; Ensure we never leave point invisible.
- (when (org-invisible-p (point)) (beginning-of-visual-line))))
+ (unless (bobp)
+ (let* ((deactivate-mark nil)
+ (element (org-element-at-point))
+ (type (org-element-type element))
+ (contents-begin (org-element-property :contents-begin element))
+ (contents-end (org-element-property :contents-end element))
+ (post-affiliated (org-element-property :post-affiliated element))
+ (begin (org-element-property :begin element)))
+ (cond
+ ((not element) (goto-char (point-min)))
+ ((= (point) begin)
+ (backward-char)
+ (org-backward-paragraph))
+ ((<= (point) post-affiliated) (goto-char begin))
+ ((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))
+ ((memq type '(src-block verse-block))
+ (when (eq type 'src-block)
+ (setq contents-begin
+ (save-excursion (goto-char begin) (forward-line) (point))))
+ (if (= (point) contents-begin) (goto-char post-affiliated)
+ ;; Inside a verse block, see blank lines as paragraph
+ ;; separators.
+ (let ((origin (point)))
+ (skip-chars-backward " \r\t\n" contents-begin)
+ (when (re-search-backward "^[ \t]*$" contents-begin 'move)
+ (skip-chars-forward " \r\t\n" origin)
+ (if (= (point) origin) (goto-char contents-begin)
+ (beginning-of-line))))))
+ ((not contents-begin) (goto-char (or post-affiliated 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
+ (org-element-property
+ :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)
+ (goto-char (1- contents-end))
+ (org-backward-paragraph))
+ (t (goto-char (or post-affiliated begin))))
+ ;; Ensure we never leave point invisible.
+ (when (org-invisible-p (point)) (beginning-of-visual-line)))))
(defun org-forward-element ()
"Move forward by one element.
(format
(if html5-fancy
"<p class=\"subtitle\">%s</p>\n"
- "\n<br>\n<span class=\"subtitle\">%s</span>\n")
+ (concat "\n" (org-html-close-tag "br" nil info) "\n"
+ "<span class=\"subtitle\">%s</span>\n"))
(org-export-data subtitle info))
"")))))
contents
"Export current agenda view to an iCalendar FILE.
This function assumes major mode for current buffer is
`org-agenda-mode'."
- (let* ((org-export-babel-evaluate) ; Don't evaluate Babel block.
+ (let* ((org-export-babel-evaluate) ;don't evaluate Babel blocks
(contents
(org-export-string-as
(with-output-to-string
(save-excursion
- (let ((p (point-min)))
+ (let ((p (point-min))
+ (seen nil)) ;prevent duplicates
(while (setq p (next-single-property-change p 'org-hd-marker))
(let ((m (get-text-property p 'org-hd-marker)))
- (when m
+ (when (and m (not (member m seen)))
+ (push m seen)
(with-current-buffer (marker-buffer m)
(org-with-wide-buffer
(goto-char (marker-position m))
(princ
(org-element-normalize-string
- (buffer-substring
- (point) (progn (outline-next-heading) (point)))))))))
+ (buffer-substring (point)
+ (org-entry-end-position))))))))
(forward-line)))))
'icalendar t
'(:ascii-charset utf-8 :ascii-links-to-notes nil
specified in `org-latex-default-packages-alist' or
`org-latex-packages-alist'."
(let* ((class (plist-get info :latex-class))
- (class-options (plist-get info :latex-class-options))
- (header (nth 1 (assoc class (plist-get info :latex-classes))))
(class-template
(or template
- (and (stringp header)
- (if (not class-options) header
- (replace-regexp-in-string
- "^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)"
- class-options header t nil 1)))
+ (let* ((class-options (plist-get info :latex-class-options))
+ (header (nth 1 (assoc class (plist-get info :latex-classes)))))
+ (and (stringp header)
+ (if (not class-options) header
+ (replace-regexp-in-string
+ "^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)"
+ class-options header t nil 1))))
(user-error "Unknown LaTeX class `%s'" class))))
(org-latex-guess-polyglossia-language
(org-latex-guess-babel-language
snippet?
(mapconcat #'org-element-normalize-string
(list (plist-get info :latex-header)
- (plist-get info :latex-header-extra)) ""))))
+ (and (not snippet?)
+ (plist-get info :latex-header-extra)))
+ ""))))
info)
info)))
(org-export-get-reference destination info))))))))
((org-export-inline-image-p link org-html-inline-image-rules)
(let ((path (let ((raw-path (org-element-property :path link)))
- (if (not (file-name-absolute-p raw-path)) raw-path
- (expand-file-name raw-path))))
+ (cond ((not (equal "file" type)) (concat type ":" raw-path))
+ ((not (file-name-absolute-p raw-path)) raw-path)
+ (t (expand-file-name raw-path)))))
(caption (org-export-data
(org-export-get-caption
(org-export-get-parent-element link)) info)))
(t (let* ((raw-path (org-element-property :path link))
(path
(cond
- ((member type '("http" "https" "ftp"))
+ ((member type '("http" "https" "ftp" "mailto" "irc"))
(concat type ":" raw-path))
((string= type "file")
(org-export-file-uri (funcall link-org-files-as-md raw-path)))
(:odt-table-styles nil nil org-odt-table-styles)
(:odt-use-date-fields nil nil org-odt-use-date-fields)
;; Redefine regular option.
- (:with-latex nil "tex" org-odt-with-latex)))
+ (:with-latex nil "tex" org-odt-with-latex)
+ ;; Retrieve LaTeX header for fragments.
+ (:latex-header "LATEX_HEADER" nil nil newline)))
;;; Dependencies
(mathml (format "Creating MathML snippet %d..." count))))
;; Get an Org-style link to PNG image or the MathML
;; file.
- (org-link
- (let ((link (with-temp-buffer
- (insert latex-frag)
- (org-format-latex cache-subdir nil nil cache-dir
- nil display-msg nil
- processing-type)
- (buffer-substring-no-properties
- (point-min) (point-max)))))
- (if (string-match-p "file:\\([^]]*\\)" link) link
- (message "LaTeX Conversion failed.")
- nil))))
- (when org-link
+ (link
+ (with-temp-buffer
+ (insert latex-frag)
+ ;; When converting to a PNG image, make sure to
+ ;; copy all LaTeX header specifications from the
+ ;; Org source.
+ (unless (eq processing-type 'mathml)
+ (let ((h (plist-get info :latex-header)))
+ (when h
+ (insert "\n"
+ (replace-regexp-in-string
+ "^" "#+LATEX_HEADER: " h)))))
+ (org-format-latex cache-subdir nil nil cache-dir
+ nil display-msg nil
+ processing-type)
+ (goto-char (point-min))
+ (org-element-link-parser))))
+ (if (not (eq 'link (org-element-type link)))
+ (message "LaTeX Conversion failed.")
;; Conversion succeeded. Parse above Org-style link to
;; a `link' object.
- (let* ((link
- (org-element-map
- (org-element-parse-secondary-string org-link '(link))
- 'link #'identity info t))
- (replacement
- (cl-case (org-element-type latex-*)
- ;; Case 1: LaTeX environment. Mimic
- ;; a "standalone image or formula" by
- ;; enclosing the `link' in a `paragraph'.
- ;; Copy over original attributes, captions to
- ;; the enclosing paragraph.
- (latex-environment
- (org-element-adopt-elements
- (list 'paragraph
- (list :style "OrgFormula"
- :name
- (org-element-property :name latex-*)
- :caption
- (org-element-property :caption latex-*)))
- link))
- ;; Case 2: LaTeX fragment. No special action.
- (latex-fragment link))))
+ (let ((replacement
+ (cl-case (org-element-type latex-*)
+ ;;LaTeX environment. Mimic a "standalone image
+ ;; or formula" by enclosing the `link' in
+ ;; a `paragraph'. Copy over original
+ ;; attributes, captions to the enclosing
+ ;; paragraph.
+ (latex-environment
+ (org-element-adopt-elements
+ (list 'paragraph
+ (list :style "OrgFormula"
+ :name
+ (org-element-property :name latex-*)
+ :caption
+ (org-element-property :caption latex-*)))
+ link))
+ ;; LaTeX fragment. No special action.
+ (latex-fragment link))))
;; Note down the object that link replaces.
(org-element-put-property replacement :replaces
(list (org-element-type latex-*)
(org-element-map data '(footnote-definition footnote-reference)
(lambda (f)
(cond
- ((eq (org-element-type f) 'footnote-definition) f)
- ((eq (org-element-property :type f) 'standard) nil)
- (t (let ((label (org-element-property :label f)))
- (when label ;Skip anonymous references.
- (apply
- #'org-element-create
- 'footnote-definition `(:label ,label :post-blank 1)
- (org-element-contents f))))))))))
+ ((eq 'footnote-definition (org-element-type f)) f)
+ ((and (eq 'inline (org-element-property :type f))
+ (org-element-property :label f))
+ f)
+ (t nil))))))
;; If a select tag is active, also ignore the section before the
;; first headline, if any.
(when selected