From: Rasmus Date: Tue, 29 Aug 2017 08:07:08 +0000 (+0200) Subject: Update Org to v9.0.10 X-Git-Tag: emacs-26.0.90~320 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=3ad8ca429bac5e1354881cf4411d6f41dab36b44;p=emacs.git Update Org to v9.0.10 Please see etc/ORG-NEWS for major changes. Note, this is a bugfix release. --- diff --git a/doc/misc/org.texi b/doc/misc/org.texi index 2d537946be0..067ae7bbc52 100644 --- a/doc/misc/org.texi +++ b/doc/misc/org.texi @@ -4,7 +4,8 @@ @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} @@ -499,6 +500,12 @@ Capture templates * 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 @@ -830,7 +837,7 @@ different formats such as HTML, @LaTeX{}, Open Document, and Markdown. New 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. @@ -7310,7 +7317,11 @@ dynamic insertion of content. The templates are expanded in the order given her @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 @@ -7505,16 +7516,202 @@ For more information, including how to read atom feeds, see @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 @@ -8081,7 +8278,7 @@ you can use the following instead: @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} @@ -11443,8 +11640,8 @@ The default is ``xhtml-strict''. 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 @@ -13590,7 +13787,7 @@ itself does not appear in the structure of the document. Copyright information is printed on the back of the title page. @example -* Copying +* Legalese :PROPERTIES: :COPYING: t :END: @@ -15142,8 +15339,8 @@ customization options for extracting source code. 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 @@ -15319,6 +15516,7 @@ Org supports the following languages for the @samp{src} code blocks: 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 @@ -16148,12 +16346,11 @@ Do not insert newlines to pad the tangled @samp{src} code blocks. 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} @@ -16182,42 +16379,56 @@ subsequent source code language blocks change session names. @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{<>}. This behavior is illustrated in the following example. -Because the @code{<>} 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{<>} 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 -- <> +#+END_SRC @end example expands to: @@ -16230,17 +16441,60 @@ 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: + <> +else: + <> +#+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 @@ -16300,8 +16554,8 @@ A note of warning: when @code{:cache} is used for a @code{:session}, caching 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}. @@ -16743,38 +16997,80 @@ prints ``2''. Results show that. @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 <> @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 <> @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{<>}. 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 +<> +#+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 +<> +#+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}. @@ -17004,12 +17300,9 @@ structural elements, such as @code{#+BEGIN_SRC} and @code{#+END_SRC}. Easy 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 @@ -17082,7 +17375,7 @@ Org evaluates code in the following circumstances: 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 diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index f8399dbf1e8..ff1000e78ef 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -157,7 +157,7 @@ should be written instead ,* 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 diff --git a/etc/refcards/orgcard.tex b/etc/refcards/orgcard.tex index 0170a18abce..1c4f4501c15 100644 --- a/etc/refcards/orgcard.tex +++ b/etc/refcards/orgcard.tex @@ -1,7 +1,7 @@ % 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 diff --git a/lisp/org/ob-comint.el b/lisp/org/ob-comint.el index cc60f4e4a73..7b218081fad 100644 --- a/lisp/org/ob-comint.el +++ b/lisp/org/ob-comint.el @@ -33,7 +33,6 @@ (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." @@ -148,10 +147,6 @@ FILE exists at end of evaluation." (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) diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el index c630b70f91f..527fb2204ad 100644 --- a/lisp/org/ob-core.el +++ b/lisp/org/ob-core.el @@ -1752,16 +1752,20 @@ NAME, or nil if no such block exists. Set match data according 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))) @@ -2269,21 +2273,22 @@ INFO may provide the values of these header arguments (in the ((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 @@ -2337,7 +2342,7 @@ INFO may provide the values of these header arguments (in the (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)) @@ -2374,11 +2379,12 @@ INFO may provide the values of these header arguments (in the ((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 @@ -2391,6 +2397,7 @@ INFO may provide the values of these header arguments (in the (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))))))) diff --git a/lisp/org/ob-emacs-lisp.el b/lisp/org/ob-emacs-lisp.el index c0bd12a8793..989561db7be 100644 --- a/lisp/org/ob-emacs-lisp.el +++ b/lisp/org/ob-emacs-lisp.el @@ -41,41 +41,38 @@ their value. It is used as the optional LEXICAL argument to (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 diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el index f90dd53bb05..598461874f6 100644 --- a/lisp/org/org-agenda.el +++ b/lisp/org/org-agenda.el @@ -6992,11 +6992,16 @@ The optional argument TYPE tells the agenda type." (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) @@ -7592,7 +7597,7 @@ also press `-' or `+' to switch between filtering and excluding." (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) diff --git a/lisp/org/org-capture.el b/lisp/org/org-capture.el index 63e23cc118b..43207308baf 100644 --- a/lisp/org/org-capture.el +++ b/lisp/org/org-capture.el @@ -242,8 +242,10 @@ be replaced with content and expanded: 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. @@ -261,7 +263,8 @@ be replaced with content and expanded: %^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'. @@ -1126,6 +1129,7 @@ may have been stored before." (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"))) @@ -1143,10 +1147,9 @@ may have been stored before." (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 "")))) @@ -1575,12 +1578,16 @@ The template may still contain \"%?\" for cursor positioning." (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 @@ -1744,24 +1751,27 @@ The template may still contain \"%?\" for cursor positioning." (_ (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)) @@ -1892,9 +1902,7 @@ Assume sexps have been marked with (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) diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el index cb6a6c9ad1d..aa5c375cef3 100644 --- a/lisp/org/org-clock.el +++ b/lisp/org/org-clock.el @@ -1418,11 +1418,13 @@ for a todo state to switch to, overriding the existing value (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"))) @@ -1432,13 +1434,13 @@ decides which time to use." (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))) @@ -1448,9 +1450,7 @@ decides which time to use." (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) @@ -1803,14 +1803,15 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes." "[ \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)) @@ -1819,26 +1820,27 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes." (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) @@ -2701,16 +2703,14 @@ 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 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))) diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el index e1d40369f19..68a1166c814 100644 --- a/lisp/org/org-compat.el +++ b/lisp/org/org-compat.el @@ -60,6 +60,12 @@ (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))) + ;;; Obsolete aliases (remove them after the next major release). @@ -293,6 +299,12 @@ See `org-link-parameters' for documentation on the other parameters." (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") + ;;;; Obsolete link types diff --git a/lisp/org/org-element.el b/lisp/org/org-element.el index 41b4a3ac78c..f4fe6447a68 100644 --- a/lisp/org/org-element.el +++ b/lisp/org/org-element.el @@ -2983,16 +2983,8 @@ Assume point is at the beginning of the LaTeX fragment." (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)) @@ -3000,10 +2992,23 @@ Assume point is at the beginning of the LaTeX fragment." ;; 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) diff --git a/lisp/org/org-indent.el b/lisp/org/org-indent.el index 10c96179b61..4a22b15050c 100644 --- a/lisp/org/org-indent.el +++ b/lisp/org/org-indent.el @@ -142,11 +142,11 @@ useful to make it ever so slightly different." ;; 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 diff --git a/lisp/org/org-irc.el b/lisp/org/org-irc.el index 3a6a7f4db06..92537fc2cc7 100644 --- a/lisp/org/org-irc.el +++ b/lisp/org/org-irc.el @@ -205,7 +205,8 @@ default." (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 diff --git a/lisp/org/org-lint.el b/lisp/org/org-lint.el index 5abda7c4a6b..9007bf8f958 100644 --- a/lisp/org/org-lint.el +++ b/lisp/org/org-lint.el @@ -724,7 +724,7 @@ Use \"export %s\" instead" (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]" diff --git a/lisp/org/org-macro.el b/lisp/org/org-macro.el index 3dc9c5450ed..3b8f8140c9c 100644 --- a/lisp/org/org-macro.el +++ b/lisp/org/org-macro.el @@ -186,56 +186,54 @@ found in the buffer with no definition in TEMPLATES. 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. diff --git a/lisp/org/org-macs.el b/lisp/org/org-macs.el index ca47e5a5a33..aae59d3c1f4 100644 --- a/lisp/org/org-macs.el +++ b/lisp/org/org-macs.el @@ -304,6 +304,43 @@ error when the user input is empty." (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 diff --git a/lisp/org/org-mobile.el b/lisp/org/org-mobile.el index 9fee09f38e4..192ccadfde6 100644 --- a/lisp/org/org-mobile.el +++ b/lisp/org/org-mobile.el @@ -693,7 +693,7 @@ encryption program does not understand them." (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)) @@ -702,7 +702,7 @@ encryption program does not understand them." (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)) diff --git a/lisp/org/org-protocol.el b/lisp/org/org-protocol.el index 82543567456..cd4b216aae9 100644 --- a/lisp/org/org-protocol.el +++ b/lisp/org/org-protocol.el @@ -520,7 +520,9 @@ The location for a browser's bookmark should look like this: ;; 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)) @@ -554,7 +556,7 @@ The location for a browser's bookmark should look like this: ;; 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 -- diff --git a/lisp/org/org-src.el b/lisp/org/org-src.el index 0e04d4b5a89..9a3ff53aa4d 100644 --- a/lisp/org/org-src.el +++ b/lisp/org/org-src.el @@ -424,11 +424,10 @@ Assume point is in the corresponding edit buffer." (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 @@ -489,12 +488,13 @@ Leave point in edit buffer." (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. @@ -837,7 +837,10 @@ A coderef format regexp can only match at the end of a line." (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)) diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index 357fdcfa441..6b4e21b6468 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -1335,7 +1335,7 @@ Only data lines count for this." (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)) @@ -1532,28 +1532,31 @@ non-nil, the one above is used." (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) diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el index 2db3eae2d8a..182290a707e 100644 --- a/lisp/org/org-version.el +++ b/lisp/org/org-version.el @@ -5,13 +5,13 @@ (defun org-release () "The release version of Org. Inserted by installing Org mode or when a release is made." - (let ((org-release "9.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)) (provide 'org-version) diff --git a/lisp/org/org.el b/lisp/org/org.el index 5d10eed1511..87758fdfdd0 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -128,6 +128,7 @@ Stars are put in group 1 and the trimmed body in group 2.") (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)) @@ -1119,8 +1120,8 @@ Or return the original if not disputed." (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 @@ -1128,10 +1129,10 @@ effective." :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." @@ -3573,8 +3574,10 @@ See also `org-tag-persistent-alist' to sidestep this behavior." :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)) @@ -3606,8 +3609,10 @@ on a per-file basis, insert anywhere in the file: :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)) @@ -4852,7 +4857,9 @@ Otherwise, these types are allowed: :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 @@ -5582,15 +5589,13 @@ The following commands are available: (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) @@ -6210,9 +6215,10 @@ by a #." '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 @@ -7318,12 +7324,13 @@ open and agenda-wise Org files." (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) @@ -9049,14 +9056,6 @@ A non-nil value for INTERACTIVE? is used to signal that this 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 @@ -9138,9 +9137,20 @@ function is being called interactively." (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 @@ -9222,14 +9232,14 @@ function is being called interactively." (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 @@ -9590,42 +9600,6 @@ Possible values in the list of contexts are `table', `headline', and `item'." (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. @@ -10780,9 +10754,10 @@ When optional argument REFERENCE-BUFFER is non-nil, it should 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) @@ -10795,38 +10770,51 @@ link in a property drawer line." ;; 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) @@ -10842,14 +10830,6 @@ link in a property drawer line." (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 @@ -10919,20 +10899,6 @@ link in a property drawer line." (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))) @@ -11985,7 +11951,9 @@ prefix argument (`C-u C-u C-u C-c C-w')." (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 @@ -12682,7 +12650,7 @@ When called through ELisp, arg is also interpreted in the following way: (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) @@ -13741,7 +13709,7 @@ EXTRA is additional text that will be inserted into the notes buffer." (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" @@ -13818,7 +13786,7 @@ EXTRA is additional text that will be inserted into the notes buffer." 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. @@ -14811,7 +14779,7 @@ it as a time string and apply `float-time' to it. If S is nil, just return 0." ((numberp s) s) ((stringp s) (condition-case nil - (float-time (apply 'encode-time (org-parse-time-string s))) + (float-time (apply #'encode-time (org-parse-time-string s nil t))) (error 0.))) (t 0.))) @@ -19030,9 +18998,7 @@ looks only before point, not after." (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 @@ -19466,7 +19432,7 @@ a HTML file." (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 @@ -20156,6 +20122,8 @@ overwritten, and the table is not marked as requiring realignment." (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 @@ -20169,7 +20137,6 @@ overwritten, and the table is not marked as requiring realignment." ;; 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)) @@ -20198,14 +20165,24 @@ The detailed reaction depends on the user option `org-catch-invisible-edits'." (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 @@ -20213,8 +20190,7 @@ The detailed reaction depends on the user option `org-catch-invisible-edits'." ;; (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 @@ -20223,9 +20199,17 @@ The detailed reaction depends on the user option `org-catch-invisible-edits'." ;; 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 @@ -20914,16 +20898,14 @@ this numeric value." (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. @@ -24416,74 +24398,74 @@ item, etc. It also provides some special moves for convenience: - 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. @@ -24498,55 +24480,55 @@ convenience: - 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. diff --git a/lisp/org/ox-html.el b/lisp/org/ox-html.el index 49562fa6918..aeb38ebc102 100644 --- a/lisp/org/ox-html.el +++ b/lisp/org/ox-html.el @@ -2034,7 +2034,8 @@ holding export options." (format (if html5-fancy "

%s

\n" - "\n
\n%s\n") + (concat "\n" (org-html-close-tag "br" nil info) "\n" + "%s\n")) (org-export-data subtitle info)) ""))))) contents diff --git a/lisp/org/ox-icalendar.el b/lisp/org/ox-icalendar.el index 9ccbb272448..e1956ccdcf3 100644 --- a/lisp/org/ox-icalendar.el +++ b/lisp/org/ox-icalendar.el @@ -879,22 +879,24 @@ The file is stored under the name chosen in "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 diff --git a/lisp/org/ox-latex.el b/lisp/org/ox-latex.el index f11a8a63a2a..ec4b49585f8 100644 --- a/lisp/org/ox-latex.el +++ b/lisp/org/ox-latex.el @@ -1623,15 +1623,15 @@ non-nil, only includes packages relevant to image generation, as 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 @@ -1644,7 +1644,9 @@ specified in `org-latex-default-packages-alist' or 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))) diff --git a/lisp/org/ox-md.el b/lisp/org/ox-md.el index c8ea1fa045e..2478cc6ab8f 100644 --- a/lisp/org/ox-md.el +++ b/lisp/org/ox-md.el @@ -395,8 +395,9 @@ a communication channel." (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))) @@ -411,7 +412,7 @@ a communication channel." (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))) diff --git a/lisp/org/ox-odt.el b/lisp/org/ox-odt.el index 943a6be0310..75554689aaf 100644 --- a/lisp/org/ox-odt.el +++ b/lisp/org/ox-odt.el @@ -112,7 +112,9 @@ (: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 @@ -3731,42 +3733,45 @@ contextual information." (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-*) diff --git a/lisp/org/ox.el b/lisp/org/ox.el index f39a3952e76..7d2f3d1714a 100644 --- a/lisp/org/ox.el +++ b/lisp/org/ox.el @@ -2712,14 +2712,11 @@ from tree." (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