# HG changeset patch # User Carsten Dominik # Date 1289535019 21600 # Node ID 5cb272c831e850020cdc06115bd9242221a445a9 # Parent 62aa3653746a8434e1f5b702535b2b56562a1446 Install org-mode version 7.3 diff -r 62aa3653746a -r 5cb272c831e8 doc/misc/ChangeLog --- a/doc/misc/ChangeLog Thu Nov 11 19:23:58 2010 -0800 +++ b/doc/misc/ChangeLog Thu Nov 11 22:10:19 2010 -0600 @@ -1,3 +1,144 @@ +2010-11-11 Noorul Islam + + * org.texi: Fix typo + +2010-11-11 Carsten Dominik + + * org.texi (Using capture): Explain that refiling is + sensitive to cursor position. + +2010-11-11 Carsten Dominik + + * org.texi (Images and tables): Add cross reference to + link section. + +2010-11-11 Carsten Dominik + + * org.texi: Document the cookie. + +2010-11-11 Eric Schulte + + * multi-line header arguments :PROPERTIES: :ID: + b77c8857-6c76-4ea9-8a61-ddc2648d96c4 :END: + +2010-11-11 Carsten Dominik + + * org.texi (CSS support): Document :HTML_CONTAINER_CLASS: + property + +2010-11-11 Carsten Dominik + + * org.texi (Project alist): Mention that this is a + property list + +2010-11-11 Carsten Dominik + + * org.texi (Setting up the staging area): Document that + file names remain visible when encrypting the MobileOrg files. + +2010-11-11 Carsten Dominik + + * org.texi (Setting up the staging area): Document which + versions are needed for encryption. + +2010-11-11 Eric Schulte + + * org.texi (noweb): updating :noweb documentation to + reflect the new "tangle" argument + +2010-11-11 Sebastian Rose, Hannover, Germany + + * org-test-which-func: New function. Find name of defun + around point. + +2010-11-11 Eric Schulte + + * org.texi (Batch execution): improved tangling script in + documentation + +2010-11-11 Carsten Dominik + + * org.texi (Handling links): + (In-buffer settings): Document inlining images on startup. + +2010-11-11 Carsten Dominik + + * org.texi (Setting up the staging area): Document use of + crypt password. + +2010-11-11 David Maus + + * org.texi (Template expansion): Add date related link + type escapes + +2010-11-11 David Maus + + * org.texi (Template expansion): Add mew in table for + link type escapes. + +2010-11-11 David Maus + + * org.texi (Template expansion): Fix typo in link type + escapes. + +2010-11-11 Eric Schulte + + * org.texi (Structure of code blocks): another + documentation tweak + +2010-11-11 Eric Schulte + + * org.texi (Structure of code blocks): documentation + tweak + +2010-11-11 Eric Schulte + + * org.texi (Structure of code blocks): updating + documentation to mention inline code block syntax + +2010-11-11 Eric Schulte + + * org.texi (comments): improved wording + +2010-11-11 Eric Schulte + + * org.texi (comments): documenting the new :comments + header arguments + +2010-11-11 Carsten Dominik + + * org.texi (Installation): Remove the special + installation instructions for XEmacs. + +2010-11-11 Jambunathan K (tiny change) + + * org.texi (Easy Templates): New section. Documents quick + insertion of empty structural elements. + +2010-11-11 Noorul Islam + + * org.texi: Fix doc + +2010-11-11 Jambunathan K (tiny change) + + * org.texi (The date/time prompt): Document specification + of time ranges. + +2010-11-11 Carsten Dominik + + * org.texi (Internal links): Document the changes in + internal links. + +2010-11-11 Carsten Dominik + + * org.texi (Agenda commands): Document the limitation for + the filter preset - it can only be used for an entire agenda + view, not in an individual block in a block agenda. + +2010-11-11 Eric S Fraga + + * org.texi (iCalendar export): Document alarm creation. + 2010-11-10 Michael Albinus * dbus.texi (Type Conversion): Introduce `:unix-fd' type mapping. diff -r 62aa3653746a -r 5cb272c831e8 doc/misc/org.texi --- a/doc/misc/org.texi Thu Nov 11 19:23:58 2010 -0800 +++ b/doc/misc/org.texi Thu Nov 11 22:10:19 2010 -0600 @@ -4,8 +4,8 @@ @setfilename ../../info/org @settitle The Org Manual -@set VERSION 7.01 -@set DATE July 2010 +@set VERSION 7.3 +@set DATE November 2010 @c Use proper quote and backtick for code sections in PDF output @c Cf. Texinfo manual 14.2 @@ -22,6 +22,24 @@ @finalout @c Macro definitions +@macro orgcmd{key,command} +@iftex +@kindex \key\ +@findex \command\ +@item @kbd{\key\} @hskip 0pt plus 1filll @code{\command\} +@end iftex +@ifnottex +@kindex \key\ +@findex \command\ +@item @kbd{\key\} @tie{}@tie{}@tie{}@tie{}(@code{\command\}) +@end ifnottex +@end macro + +@macro orgkey{key} +@kindex \key\ +@item @kbd{\key\} +@end macro + @iftex @c @hyphenation{time-stamp time-stamps time-stamp-ing time-stamp-ed} @end iftex @@ -122,6 +140,7 @@ * History and Acknowledgments:: How Org came into being * Main Index:: An index of Org's concepts and features * Key Index:: Key bindings and where they are described +* Command and Function Index:: Command names and some internal functions * Variable Index:: Variables mentioned in the manual @detailmenu @@ -244,6 +263,7 @@ * Resolving idle time:: Resolving time if you've been idle * Effort estimates:: Planning work effort in advance * Relative timer:: Notes with a running timer +* Countdown timer:: Starting a countdown timer for a task Creating timestamps @@ -364,6 +384,7 @@ * Links in HTML export:: How links will be interpreted and formatted * Tables in HTML export:: How to modify the formatting of tables * Images in HTML export:: How to insert figures into HTML output +* Math formatting in HTML export:: Beautiful math also on the web * Text areas in HTML export:: An alternative way to show an example * CSS support:: Changing the appearance of the output * JavaScript support:: Info and Folding in a web browser @@ -436,16 +457,22 @@ * Buffer-wide header arguments:: Set default values for a specific buffer * Header arguments in Org-mode properties:: Set default values for a buffer or heading * Code block specific header arguments:: The most common way to set values +* Header arguments in function calls:: The most specific level Specific header arguments * var:: Pass arguments to code blocks -* results:: Specify the type of results and how they will be collected and handled +* results:: Specify the type of results and how they will + be collected and handled * file:: Specify a path for file output -* dir:: Specify the default directory for code block execution +* dir:: Specify the default (possibly remote) + directory for code block execution * exports:: Export code and/or results * tangle:: Toggle tangling and specify file name -* no-expand:: Turn off variable assignment and noweb expansion during tangling +* comments:: Toggle insertion of comments in tangled + code files +* no-expand:: Turn off variable assignment and noweb + expansion during tangling * session:: Preserve the state of code evaluation * noweb:: Toggle expansion of noweb references * cache:: Avoid re-evaluating unchanged code blocks @@ -453,10 +480,12 @@ * colnames:: Handle column names in tables * rownames:: Handle row names in tables * shebang:: Make tangled files executable +* eval:: Limit evaluation of specific code blocks Miscellaneous * Completion:: M-TAB knows what you need +* Easy Templates:: Quick insertion of structural elements * Speed keys:: Electric commands at the beginning of a headline * Code evaluation security:: Org mode files evaluate inline code * Customization:: Adapting Org to your taste @@ -608,18 +637,6 @@ (setq load-path (cons "~/path/to/orgdir/contrib/lisp" load-path)) @end example -@sp 2 -@cartouche -XEmacs users now need to install the file @file{noutline.el} from -the @file{xemacs} sub-directory of the Org distribution. Use the -command: - -@example - make install-noutline -@end example -@end cartouche -@sp 2 - @noindent Now byte-compile the Lisp files with the shell command: @example @@ -720,10 +737,15 @@ If you find problems with Org, or if you have questions, remarks, or ideas about it, please mail to the Org mailing list @email{emacs-orgmode@@gnu.org}. If you are not a member of the mailing list, your mail will be passed to the -list after a moderator has approved it. - -For bug reports, please provide as much information as possible, including -the version information of Emacs (@kbd{M-x emacs-version @key{RET}}) and Org +list after a moderator has approved it@footnote{Please consider subscribing +to the mailing list, in order to minimize the work the mailing list +moderators have to do.}. + +For bug reports, please first try to reproduce the bug with the latest +version of Org available - if you are running an outdated version, it is +quite possible that the bug has been fixed already. If the bug persists, +prepare a report and provide as much information as possible, including the +version information of Emacs (@kbd{M-x emacs-version @key{RET}}) and Org (@kbd{M-x org-version @key{RET}}), as well as the Org related setup in @file{.emacs}. The easiest way to do this is to use the command @example @@ -742,7 +764,7 @@ @item What did you expect to happen? @item What happened instead? @end enumerate -@noindent Thank you for helping to improve this mode. +@noindent Thank you for helping to improve this program. @subsubheading How to create a useful backtrace @@ -886,9 +908,8 @@ @cindex folded, subtree visibility state @cindex children, subtree visibility state @cindex subtree, subtree visibility state -@table @kbd -@kindex @key{TAB} -@item @key{TAB} +@table @asis +@orgcmd{@key{TAB},org-cycle} @emph{Subtree cycling}: Rotate current subtree among the states @example @@ -910,8 +931,7 @@ @cindex overview, global visibility state @cindex contents, global visibility state @cindex show all, global visibility state -@kindex S-@key{TAB} -@item S-@key{TAB} +@orgcmd{S-@key{TAB},org-global-cycle} @itemx C-u @key{TAB} @emph{Global cycling}: Rotate the entire buffer among the states @@ -925,22 +945,18 @@ tables, @kbd{S-@key{TAB}} jumps to the previous field. @cindex show all, command -@kindex C-u C-u C-u @key{TAB} -@item C-u C-u C-u @key{TAB} +@orgcmd{C-u C-u C-u @key{TAB},show-all} Show all, including drawers. -@kindex C-c C-r -@item C-c C-r +@orgcmd{C-c C-r,org-reveal} Reveal context around point, showing the current entry, the following heading and the hierarchy above. Useful for working near a location that has been exposed by a sparse tree command (@pxref{Sparse trees}) or an agenda command (@pxref{Agenda commands}). With a prefix argument show, on each level, all sibling headings. With double prefix arg, also show the entire subtree of the parent. -@kindex C-c C-k -@item C-c C-k +@orgcmd{C-c C-k,show-branches} Expose all the headings of the subtree, CONTENT view for just one subtree. -@kindex C-c C-x b -@item C-c C-x b +@orgcmd{C-c C-x b,org-tree-to-indirect-buffer} Show the current subtree in an indirect buffer@footnote{The indirect buffer @ifinfo @@ -982,9 +998,8 @@ and Columns}) will get their visibility adapted accordingly. Allowed values for this property are @code{folded}, @code{children}, @code{content}, and @code{all}. -@table @kbd -@kindex C-u C-u @key{TAB} -@item C-u C-u @key{TAB} +@table @asis +@orgcmd{C-u C-u @key{TAB},org-set-startup-visibility} Switch back to the startup visibility of the buffer, i.e. whatever is requested by startup options and @samp{VISIBILITY} properties in individual entries. @@ -997,24 +1012,18 @@ @cindex headline navigation The following commands jump to other headlines in the buffer. -@table @kbd -@kindex C-c C-n -@item C-c C-n +@table @asis +@orgcmd{C-c C-n,outline-next-visible-heading} Next heading. -@kindex C-c C-p -@item C-c C-p +@orgcmd{C-c C-p,outline-previous-visible-heading} Previous heading. -@kindex C-c C-f -@item C-c C-f +@orgcmd{C-c C-f,org-forward-same-level} Next heading same level. -@kindex C-c C-b -@item C-c C-b +@orgcmd{C-c C-b,org-backward-same-level} Previous heading same level. -@kindex C-c C-u -@item C-c C-u +@orgcmd{C-c C-u,outline-up-heading} Backward to higher level heading. -@kindex C-c C-j -@item C-c C-j +@orgcmd{C-c C-j,org-goto} Jump to a different place without changing the current outline visibility. Shows the document structure in a temporary buffer, where you can use the following keys to find your destination: @@ -1049,9 +1058,8 @@ @cindex sorting, of subtrees @cindex subtrees, cut and paste -@table @kbd -@kindex M-@key{RET} -@item M-@key{RET} +@table @asis +@orgcmd{M-@key{RET},org-insert-heading} @vindex org-M-RET-may-split-line Insert new heading with same level as current. If the cursor is in a plain list item, a new item is created (@pxref{Plain lists}). To force @@ -1066,62 +1074,48 @@ used at the end of a folded subtree (i.e. behind the ellipses at the end of a headline), then a headline like the current one will be inserted after the end of the subtree. -@kindex C-@key{RET} -@item C-@key{RET} +@orgcmd{C-@key{RET},org-insert-heading-respect-content} Just like @kbd{M-@key{RET}}, except when adding a new heading below the current heading, the new heading is placed after the body instead of before it. This command works from anywhere in the entry. -@kindex M-S-@key{RET} -@item M-S-@key{RET} +@orgcmd{M-S-@key{RET},org-insert-todo-heading} @vindex org-treat-insert-todo-heading-as-state-change Insert new TODO entry with same level as current heading. See also the variable @code{org-treat-insert-todo-heading-as-state-change}. -@kindex C-S-@key{RET} -@item C-S-@key{RET} +@orgcmd{C-S-@key{RET},org-insert-todo-heading-respect-content} Insert new TODO entry with same level as current heading. Like @kbd{C-@key{RET}}, the new headline will be inserted after the current subtree. -@kindex @key{TAB} -@item @key{TAB} @r{in new, empty entry} +@orgcmd{@key{TAB},org-cycle} In a new entry with no text yet, the first @key{TAB} demotes the entry to become a child of the previous one. The next @key{TAB} makes it a parent, and so on, all the way to top level. Yet another @key{TAB}, and you are back to the initial level. -@kindex M-@key{left} -@item M-@key{left} +@orgcmd{M-@key{left},org-do-promote} Promote current heading by one level. -@kindex M-@key{right} -@item M-@key{right} +@orgcmd{M-@key{right},org-do-demote} Demote current heading by one level. -@kindex M-S-@key{left} -@item M-S-@key{left} +@orgcmd{M-S-@key{left},org-promote-subtree} Promote the current subtree by one level. -@kindex M-S-@key{right} -@item M-S-@key{right} +@orgcmd{M-S-@key{right},org-demote-subtree} Demote the current subtree by one level. -@kindex M-S-@key{up} -@item M-S-@key{up} +@orgcmd{M-S-@key{up},org-move-subtree-up} Move subtree up (swap with previous subtree of same level). -@kindex M-S-@key{down} -@item M-S-@key{down} +@orgcmd{M-S-@key{down},org-move-subtree-down} Move subtree down (swap with next subtree of same level). -@kindex C-c C-x C-w -@item C-c C-x C-w +@orgcmd{C-c C-x C-w,org-cut-subtree} Kill subtree, i.e. remove it from buffer but save in kill ring. With a numeric prefix argument N, kill N sequential subtrees. -@kindex C-c C-x M-w -@item C-c C-x M-w +@orgcmd{C-c C-x M-w,org-copy-subtree} Copy subtree to kill ring. With a numeric prefix argument N, copy the N sequential subtrees. -@kindex C-c C-x C-y -@item C-c C-x C-y +@orgcmd{C-c C-x C-y,org-paste-subtree} Yank subtree from kill ring. This does modify the level of the subtree to make sure the tree fits in nicely at the yank position. The yank level can also be specified with a numeric prefix argument, or by yanking after a headline marker like @samp{****}. -@kindex C-y -@item C-y +@orgcmd{C-y,org-yank} @vindex org-yank-adjusted-subtrees @vindex org-yank-folded-subtrees Depending on the variables @code{org-yank-adjusted-subtrees} and @@ -1134,19 +1128,16 @@ force a normal yank is @kbd{C-u C-y}. If you use @code{yank-pop} after a yank, it will yank previous kill items plainly, without adjustment and folding. -@kindex C-c C-x c -@item C-c C-x c +@orgcmd{C-c C-x c,org-clone-subtree-with-time-shift} Clone a subtree by making a number of sibling copies of it. You will be prompted for the number of copies to make, and you can also specify if any timestamps in the entry should be shifted. This can be useful, for example, to create a number of tasks related to a series of lectures to prepare. For more details, see the docstring of the command @code{org-clone-subtree-with-time-shift}. -@kindex C-c C-w -@item C-c C-w +@orgcmd{C-c C-w,org-refile} Refile entry or region to a different location. @xref{Refiling notes}. -@kindex C-c ^ -@item C-c ^ +@orgcmd{C-c ^,org-sort-entries-or-items} Sort same-level entries. When there is an active region, all entries in the region will be sorted. Otherwise the children of the current headline are sorted. The command prompts for the sorting method, which can be @@ -1157,14 +1148,11 @@ your own function to extract the sorting key. With a @kbd{C-u} prefix, sorting will be case-sensitive. With two @kbd{C-u C-u} prefixes, duplicate entries will also be removed. -@kindex C-x n s -@item C-x n s +@orgcmd{C-x n s,org-narrow-to-subtree} Narrow buffer to current subtree. -@kindex C-x n w -@item C-x n w +@orgcmd{C-x n w,widen} Widen buffer to remove narrowing. -@kindex C-c * -@item C-c * +@orgcmd{C-c *,org-toggle-heading} Turn a normal line or plain list item into a headline (so that it becomes a subheading at its location). Also turn a headline into a normal line by removing the stars. If there is an active region, turn all lines in the @@ -1208,9 +1196,8 @@ Org-mode contains several commands creating such trees, all these commands can be accessed through a dispatcher: -@table @kbd -@kindex C-c / -@item C-c / +@table @asis +@orgcmd{C-c /,org-sparse-tree} This prompts for an extra key to select a sparse-tree creating command. @kindex C-c / r @item C-c / r @@ -1264,9 +1251,9 @@ @cindex ordered lists Within an entry of the outline tree, hand-formatted lists can provide -additional structure. They also provide a way to create lists of -checkboxes (@pxref{Checkboxes}). Org supports editing such lists, -and the HTML exporter (@pxref{Exporting}) parses and formats them. +additional structure. They also provide a way to create lists of checkboxes +(@pxref{Checkboxes}). Org supports editing such lists, and every exporter +(@pxref{Exporting}) can parse and format them. Org knows ordered lists, unordered lists, and description lists. @itemize @bullet @@ -1279,26 +1266,39 @@ @samp{*} is supported, it may be better to not use it for plain list items.} as bullets. @item +@vindex org-plain-list-ordered-item-terminator @emph{Ordered} list items start with a numeral followed by either a period or -a right parenthesis, such as @samp{1.} or @samp{1)}. If you want a list to -start a different value (e.g. 20), start the text of the item with -@code{[@@start:20]}. +a right parenthesis@footnote{You can filter out any of them by configuring +@code{org-plain-list-ordered-item-terminator}.}, such as @samp{1.} or +@samp{1)}. If you want a list to start a different value (e.g. 20), start +the text of the item with @code{[@@20]}@footnote{If there's a checkbox in the +item, the cookie must be put @emph{before} the checkbox.}. Those constructs +can be used in any item of the list in order to enforce a particular +numbering. @item @emph{Description} list items are unordered list items, and contain the separator @samp{ :: } to separate the description @emph{term} from the description. @end itemize -@vindex org-empty-line-terminates-plain-lists Items belonging to the same list must have the same indentation on the first line. In particular, if an ordered list reaches number @samp{10.}, then the 2--digit numbers must be written left-aligned with the other numbers in the -list. Indentation also determines the end of a list item. It ends before -the next line that is indented like the bullet/number, or less. Empty lines -are part of the previous item, so you can have several paragraphs in one -item. If you would like an empty line to terminate all currently open plain -lists, configure the variable @code{org-empty-line-terminates-plain-lists}. -Here is an example: +list. + +@vindex org-list-ending-method +@vindex org-list-end-regexp +@vindex org-empty-line-terminates-plain-lists +Two methods@footnote{To disable either of them, configure +@code{org-list-ending-method}.} are provided to terminate lists. A list ends +before the next line that is indented like the bullet/number or less, or it +ends before two blank lines@footnote{See also +@code{org-empty-line-terminates-plain-lists}.}. In both cases, all levels of +the list are closed@footnote{So you cannot have a sublist, some text and then +another sublist while still in the same top-level list item. This used to be +possible, but it was only supported in the HTML exporter and difficult to +manage with automatic indentation.}. For finer control, you can end lists +with any pattern set in @code{org-list-end-regexp}. Here is an example: @example @group @@ -1309,8 +1309,8 @@ + this was already my favorite scene in the book + I really like Miranda Otto. 3. Peter Jackson being shot by Legolas - - on DVD only He makes a really funny face when it happens. + - on DVD only But in the end, no individual scenes matter but the film as a whole. Important actors in this film are: - @b{Elijah Wood} :: He plays Frodo @@ -1325,19 +1325,23 @@ put into @file{.emacs}: @code{(require 'filladapt)}}, and by exporting them properly (@pxref{Exporting}). Since indentation is what governs the structure of these lists, many structural constructs like @code{#+BEGIN_...} -blocks can be indented to signal that they should be part of a list item. +blocks can be indented to signal that they should be considered of a list +item. @vindex org-list-demote-modify-bullet If you find that using a different bullet for a sub-list (than that used for the current list-level) improves readability, customize the variable @code{org-list-demote-modify-bullet}. -The following commands act on items when the cursor is in the first line -of an item (the line with the bullet or number). - -@table @kbd -@kindex @key{TAB} -@item @key{TAB} +@vindex org-list-automatic-rules +The following commands act on items when the cursor is in the first line of +an item (the line with the bullet or number). Some of them imply the +application of automatic rules to keep list structure in tact. If some of +these actions get in your way, configure @code{org-list-automatic-rules} +to disable them individually. + +@table @asis +@orgcmd{@key{TAB},org-cycle} @vindex org-cycle-include-plain-lists Items can be folded just like headline levels. Normally this works only if the cursor is on a plain list item. For more details, see the variable @@ -1345,31 +1349,29 @@ will be treated like low-level. The level of an item is then given by the indentation of the bullet/number. Items are always subordinate to real headlines, however; the hierarchies remain completely separated. - -If @code{org-cycle-include-plain-lists} has not been set, @key{TAB} -fixes the indentation of the current line in a heuristic way. -@kindex M-@key{RET} -@item M-@key{RET} +@orgcmd{M-@key{RET},org-insert-heading} @vindex org-M-RET-may-split-line +@vindex org-list-automatic-rules Insert new item at current level. With a prefix argument, force a new heading (@pxref{Structure editing}). If this command is used in the middle of a line, the line is @emph{split} and the rest of the line becomes the new item@footnote{If you do not want the line to be split, customize the variable -@code{org-M-RET-may-split-line}.}. If this command is executed in the -@emph{whitespace before a bullet or number}, the new item is created -@emph{before} the current item. If the command is executed in the white -space before the text that is part of an item but does not contain the -bullet, a bullet is added to the current line. +@code{org-M-RET-may-split-line}.}. If this command is executed @emph{before +item's body}, the new item is created @emph{before} the current item. If the +command is executed in the white space before the text that is part of an +item but does not contain the bullet, a bullet is added to the current line. + +As a new item cannot be inserted in a structural construct (like an example +or source code block) within a list, Org will instead insert it right before +the structure, or return an error. @kindex M-S-@key{RET} @item M-S-@key{RET} Insert a new item with a checkbox (@pxref{Checkboxes}). -@kindex @key{TAB} -@item @key{TAB} @r{in new, empty item} +@orgcmd{@key{TAB},org-cycle} In a new item with no text yet, the first @key{TAB} demotes the item to -become a child of the previous one. The next @key{TAB} makes it a parent, -and so on, all the way to the left margin. Yet another @key{TAB}, and you -are back to the initial level. -@kindex S-@key{up} +become a child of the previous one. Subsequents @key{TAB} move the item to +meaningful levels in the list and eventually get it back to its initial +position. @kindex S-@key{down} @item S-@key{up} @itemx S-@key{down} @@ -1396,25 +1398,35 @@ @item M-S-@key{left} @itemx M-S-@key{right} Decrease/increase the indentation of the item, including subitems. -Initially, the item tree is selected based on current indentation. -When these commands are executed several times in direct succession, -the initially selected region is used, even if the new indentation -would imply a different hierarchy. To use the new hierarchy, break -the command chain with a cursor motion or so. +Initially, the item tree is selected based on current indentation. When +these commands are executed several times in direct succession, the initially +selected region is used, even if the new indentation would imply a different +hierarchy. To use the new hierarchy, break the command chain with a cursor +motion or so. + +As a special case, using this command on the very first item of a list will +move the whole list. This behavior can be disabled by configuring +@code{org-list-automatic-rules}. The global indentation of a list has no +influence on the text @emph{after} the list. @kindex C-c C-c @item C-c C-c If there is a checkbox (@pxref{Checkboxes}) in the item line, toggle the -state of the checkbox. If not, this command makes sure that all the -items on this list level use the same bullet. Furthermore, if this is -an ordered list, make sure the numbering is OK. +state of the checkbox. Also, makes sure that all the +items on this list level use the same bullet and that the numbering of list +items (if applicable) is correct. @kindex C-c - +@vindex org-plain-list-ordered-item-terminator +@vindex org-list-automatic-rules @item C-c - Cycle the entire list level through the different itemize/enumerate bullets -(@samp{-}, @samp{+}, @samp{*}, @samp{1.}, @samp{1)}). With a numeric prefix -argument N, select the Nth bullet from this list. If there is an active -region when calling this, all lines will be converted to list items. If the -first line already was a list item, any item markers will be removed from the -list. Finally, even without an active region, a normal line will be +(@samp{-}, @samp{+}, @samp{*}, @samp{1.}, @samp{1)}) or a subset of them, +depending on @code{org-plain-list-ordered-item-terminator}, the type of list, +and its position@footnote{See @code{bullet} rule in +@code{org-list-automatic-rules} for more information.}. With a numeric +prefix argument N, select the Nth bullet from this list. If there is an +active region when calling this, all lines will be converted to list items. +If the first line already was a list item, any item markers will be removed +from the list. Finally, even without an active region, a normal line will be converted into a list item. @kindex C-c * @item C-c * @@ -1696,8 +1708,7 @@ @table @kbd @tsubheading{Creation and conversion} -@kindex C-c | -@item C-c | +@orgcmd{C-c |,org-table-create-or-convert-from-region} Convert the active region to table. If every line contains at least one TAB character, the function assumes that the material is tab separated. If every line contains a comma, comma-separated values (CSV) are assumed. @@ -1711,21 +1722,17 @@ @kbd{|Name|Phone|Age @key{RET} |- @key{TAB}}. @tsubheading{Re-aligning and field motion} -@kindex C-c C-c -@item C-c C-c +@orgcmd{C-c C-c,org-ctrl-c-ctrl-c} Re-align the table without moving the cursor. @c -@kindex @key{TAB} -@item @key{TAB} +@orgcmd{,org-cycle} Re-align the table, move to the next field. Creates a new row if necessary. @c -@kindex S-@key{TAB} -@item S-@key{TAB} +@orgcmd{S-@key{TAB},org-shifttab} Re-align, move to previous field. @c -@kindex @key{RET} -@item @key{RET} +@orgcmd{@key{RET},org-return} Re-align the table and move down to next row. Creates a new row if necessary. At the beginning or end of a line, @key{RET} still does NEWLINE, so it can be used to split a table. @@ -1940,9 +1947,10 @@ @end example If you would like to overrule the automatic alignment of number-rich columns -to the right and of string-rich column to the left, you and use @samp{} or -@samp{} in a similar fashion. You may also combine alignment and field -width like this: @samp{}. +to the right and of string-rich column to the left, you and use @samp{}, +@samp{c}@footnote{Centering does not work inside Emacs, but it does have an +effect when exporting to HTML.} or @samp{} in a similar fashion. You may +also combine alignment and field width like this: @samp{}. Lines which only contain these formatting cookies will be removed automatically when exporting the document. @@ -2807,23 +2815,13 @@ target should be after the first headline, or in the line directly before the first headline.}. -If no dedicated target exists, Org will search for the words in the link. In -the above example the search would be for @samp{my target}. Links starting -with a star like @samp{*My Target} restrict the search to -headlines@footnote{To insert a link targeting a headline, in-buffer -completion can be used. Just type a star followed by a few optional letters -into the buffer and press @kbd{M-@key{TAB}}. All headlines in the current -buffer will be offered as completions. @xref{Handling links}, for more -commands creating links.}. When searching, Org-mode will first try an -exact match, but then move on to more and more lenient searches. For -example, the link @samp{[[*My Targets]]} will find any of the following: - -@example -** My targets -** TODO my targets are bright -** my 20 targets are -@end example - +If no dedicated target exists, Org will search for a headline that is exactly +the link text but may also include a TODO keyword and tags@footnote{To insert +a link targeting a headline, in-buffer completion can be used. Just type a +star followed by a few optional letters into the buffer and press +@kbd{M-@key{TAB}}. All headlines in the current buffer will be offered as +completions.}. In non-Org files, the search will look for the words in the +link text, in the above example the search would be for @samp{my target}. Following a link pushes a mark onto Org's own mark ring. You can return to the previous position with @kbd{C-c &}. Using this command @@ -3087,11 +3085,17 @@ @cindex inlining images @cindex images, inlining @kindex C-c C-x C-v +@vindex org-startup-with-inline-images +@cindex @code{inlineimages}, STARTUP keyword +@cindex @code{noinlineimages}, STARTUP keyword @item C-c C-x C-v Toggle the inline display of linked images. Normally this will only inline images that have no description part in the link, i.e. images that will also be inlined during export. When called with a prefix argument, also display -images that do have a link description. +images that do have a link description. You can ask for inline images to be +displayed at startup by configuring the variable +@code{org-startup-with-inline-images}@footnote{with corresponding +@code{#+STARTUP} keywords @code{inlineimages} and @code{inlineimages}}. @cindex mark ring @kindex C-c % @item C-c % @@ -3157,15 +3161,16 @@ according to the information in the variable @code{org-link-abbrev-alist} that relates the linkwords to replacement text. Here is an example: -@lisp +@smalllisp @group (setq org-link-abbrev-alist '(("bugzilla" . "http://10.1.2.9/bugzilla/show_bug.cgi?id=") ("google" . "http://www.google.com/search?q=") - ("ads" . "http://adsabs.harvard.edu/cgi-bin/ - nph-abs_connect?author=%s&db_key=AST"))) + ("gmap" . "http://maps.google.com/maps?q=%s") + ("omap" . "http://nominatim.openstreetmap.org/search?q=%s&polygon=1") + ("ads" . "http://adsabs.harvard.edu/cgi-bin/nph-abs_connect?author=%s&db_key=AST"))) @end group -@end lisp +@end smalllisp If the replacement text contains the string @samp{%s}, it will be replaced with the tag. Otherwise the tag will be appended to the string @@ -3174,8 +3179,11 @@ With the above setting, you could link to a specific bug with @code{[[bugzilla:129]]}, search the web for @samp{OrgMode} with -@code{[[google:OrgMode]]} and find out what the Org author is -doing besides Emacs hacking with @code{[[ads:Dominik,C]]}. +@code{[[google:OrgMode]]}, show the map location of the Free Software +Foundation @code{[[gmap:51 Franklin Street, Boston]]} or of Carsten office +@code{[[omap:Science Park 904, Amsterdam, The Netherlands]]} and find out +what the Org author is doing besides Emacs hacking with +@code{[[ads:Dominik,C]]}. If you need special abbreviations just for a single Org buffer, you can define them in the file with @@ -3810,7 +3818,10 @@ @item The property @code{STYLE} is set to the value @code{habit}. @item -The TODO has a scheduled date, with a @code{.+} style repeat interval. +The TODO has a scheduled date, usually with a @code{.+} style repeat +interval. A @code{++} style may be appropriate for habits with time +constraints, e.g., must be done on weekends, or a @code{+} style for an +unusual habit that can have a backlog, e.g., weekly reports. @item The TODO may also have minimum and maximum ranges specified by using the syntax @samp{.+2d/3d}, which says that you want to do the task at least every @@ -3908,13 +3919,13 @@ @vindex org-priority-faces By default, Org-mode supports three priorities: @samp{A}, @samp{B}, and @samp{C}. @samp{A} is the highest priority. An entry without a cookie is -treated as priority @samp{B}. Priorities make a difference only in the -agenda (@pxref{Weekly/daily agenda}); outside the agenda, they have no -inherent meaning to Org-mode. The cookies can be highlighted with special -faces by customizing the variable @code{org-priority-faces}. - -Priorities can be attached to any outline tree entries; they do not need -to be TODO items. +treated just like priority @samp{B}. Priorities make a difference only for +sorting in the agenda (@pxref{Weekly/daily agenda}); outside the agenda, they +have no inherent meaning to Org-mode. The cookies can be highlighted with +special faces by customizing the variable @code{org-priority-faces}. + +Priorities can be attached to any outline node; they do not need to be TODO +items. @table @kbd @kindex @kbd{C-c ,} @@ -4017,13 +4028,16 @@ @section Checkboxes @cindex checkboxes -Every item in a plain list (@pxref{Plain lists}) can be made into a -checkbox by starting it with the string @samp{[ ]}. This feature is -similar to TODO items (@pxref{TODO Items}), but is more lightweight. -Checkboxes are not included into the global TODO list, so they are often -great to split a task into a number of simple steps. Or you can use -them in a shopping list. To toggle a checkbox, use @kbd{C-c C-c}, or -use the mouse (thanks to Piotr Zielinski's @file{org-mouse.el}). +@vindex org-list-automatic-rules +Every item in a plain list@footnote{With the exception of description +lists. But you can allow it by modifying @code{org-list-automatic-rules} +accordingly.} (@pxref{Plain lists}) can be made into a checkbox by starting +it with the string @samp{[ ]}. This feature is similar to TODO items +(@pxref{TODO Items}), but is more lightweight. Checkboxes are not included +into the global TODO list, so they are often great to split a task into a +number of simple steps. Or you can use them in a shopping list. To toggle a +checkbox, use @kbd{C-c C-c}, or use the mouse (thanks to Piotr Zielinski's +@file{org-mouse.el}). Here is an example of a checkbox list. @@ -4738,8 +4752,8 @@ @var{property} @r{The property that should be edited in this column.} @r{Special properties representing meta data are allowed here} @r{as well (@pxref{Special properties})} -(title) @r{The header text for the column. If omitted, the} - @r{property name is used.} +@var{title} @r{The header text for the column. If omitted, the property} + @r{name is used.} @{@var{summary-type}@} @r{The summary type. If specified, the column values for} @r{parent nodes are computed from the children.} @r{Supported summary types are:} @@ -4756,9 +4770,10 @@ @{:min@} @r{Smallest time value in column.} @{:max@} @r{Largest time value.} @{:mean@} @r{Arithmetic mean of time values.} - @{@@min@} @r{Minimum age (in days/hours/mins/seconds).} - @{@@max@} @r{Maximum age (in days/hours/mins/seconds).} - @{@@mean@} @r{Arithmetic mean of ages (in days/hours/mins/seconds).} + @{@@min@} @r{Minimum age (in days/hours/mins/seconds).} + @{@@max@} @r{Maximum age (in days/hours/mins/seconds).} + @{@@mean@} @r{Arithmetic mean of ages (in days/hours/mins/seconds).} + @{est+@} @r{Add low-high estimates.} @end example @noindent @@ -4766,6 +4781,22 @@ include. Subsequent columns referencing the same property will all display the same summary information. +The @code{est+} summary type requires further explanation. It is used for +combining estimates, expressed as low-high ranges. For example, instead +of estimating a particular task will take 5 days, you might estimate it as +5-6 days if you're fairly confident you know how much woark is required, or +1-10 days if you don't really know what needs to be done. Both ranges +average at 5.5 days, but the first represents a more predictable delivery. + +When combining a set of such estimates, simply adding the lows and highs +produces an unrealistically wide result. Instead, @code{est+} adds the +statistical mean and variance of the sub-tasks, generating a final estimate +from the sum. For example, suppose you had ten tasks, each of which was +estimated at 0.5 to 2 days of work. Straight addition produces an estimate +of 5 to 20 days, representing what to expect if everything goes either +extremely well or extremely poorly. In contrast, @code{est+} estimates the +full job more realistically, at 10-15 days. + Here is an example for a complete columns definition, along with allowed values. @@ -4978,6 +5009,7 @@ * Resolving idle time:: Resolving time if you've been idle * Effort estimates:: Planning work effort in advance * Relative timer:: Notes with a running timer +* Countdown timer:: Starting a countdown timer for a task @end menu @@ -5067,15 +5099,13 @@ format. @table @kbd -@kindex C-c . -@item C-c . +@orgcmd{C-c .,org-time-stamp} Prompt for a date and insert a corresponding timestamp. When the cursor is at an existing timestamp in the buffer, the command is used to modify this timestamp instead of inserting a new one. When this command is used twice in succession, a time range is inserted. @c -@kindex C-c ! -@item C-c ! +@orgcmd{C-c !,org-time-stamp-inactive} Like @kbd{C-c .}, but insert an inactive timestamp that will not cause an agenda entry. @c @@ -5088,18 +5118,15 @@ contains date and time. The default time can be rounded to multiples of 5 minutes, see the option @code{org-time-stamp-rounding-minutes}. @c -@kindex C-c < -@item C-c < +@orgcmd{C-c <,org-date-from-calendar} Insert a timestamp corresponding to the cursor date in the Calendar. @c -@kindex C-c > -@item C-c > +@orgcmd{C-c >,org-goto-calendar} Access the Emacs calendar for the current date. If there is a timestamp in the current line, go to the corresponding date instead. @c -@kindex C-c C-o -@item C-c C-o +@orgcmd{C-c C-o,org-open-at-point} Access the agenda for the date given by the timestamp or -range at point (@pxref{Weekly/daily agenda}). @c @@ -5206,6 +5233,16 @@ you want to use unabbreviated names and/or other languages, configure the variables @code{parse-time-months} and @code{parse-time-weekdays}. +You can specify a time range by giving start and end times or by giving a +start time and a duration (in HH:MM format). Use '-' or '--' as the separator +in the former case and use '+' as the separator in the latter case. E.g. + +@example +11am-1:15pm --> 11:00-13:15 +11am--1:15pm --> same as above +11am+2:15 --> same as above +@end example + @cindex calendar, for selecting date @vindex org-popup-calendar-for-date-prompt Parallel to the minibuffer prompt, a calendar is popped up@footnote{If @@ -5593,9 +5630,8 @@ mistake, or if you ended up working on something else. @kindex C-c C-x C-j @item C-c C-x C-j -Jump to the entry that contains the currently running clock. With a -@kbd{C-u} prefix arg, select the target task from a list of recently clocked -tasks. +Jump to the headline of the currently clocked in task. With a @kbd{C-u} +prefix arg, select the target task from a list of recently clocked tasks. @kindex C-c C-x C-d @item C-c C-x C-d @vindex org-remove-highlights-with-change @@ -5835,7 +5871,7 @@ these estimates defined consistently, two or three key presses will narrow down the list to stuff that fits into an available time slot. -@node Relative timer, , Effort estimates, Dates and Times +@node Relative timer, Countdown timer, Effort estimates, Dates and Times @section Taking notes with a relative timer @cindex relative timer @@ -5877,6 +5913,20 @@ not started at exactly the right moment. @end table +@node Countdown timer, , Relative timer, Dates and Times +@section Countdown timer +@cindex Countdown timer +@kindex C-c C-x ; +@kindex ; + +Calling @code{org-timer-set-timer} from an Org-mode buffer runs a countdown +timer. Use @key{;} from agenda buffers, @key{C-c C-x ;} everwhere else. + +@code{org-timer-set-timer} prompts the user for a duration and displays a +countdown timer in the modeline. @code{org-timer-default-timer} sets the +default countdown value. Giving a prefix numeric argument overrides this +default value. + @node Capture - Refile - Archive, Agenda Views, Dates and Times, Top @chapter Capture - Refile - Archive @cindex capture @@ -5934,6 +5984,7 @@ a global key@footnote{Please select your own key, @kbd{C-c c} is only a suggestion.} for capturing new material. +@vindex org-default-notes-file @example (setq org-default-notes-file (concat org-directory "/notes.org")) (define-key global-map "\C-cc" 'org-capture) @@ -5960,7 +6011,10 @@ @kindex C-c C-w @item C-c C-w Finalize the capture process by refiling (@pxref{Refiling notes}) the note to -a different place. +a different place. Please realize that this is a normal refiling command +that will be executed - so the cursor position at the moment you run this +command is important. If you have inserted a tree with a parent and +children, first move the cursor back to the parent. @kindex C-c C-k @item C-c C-k @@ -6067,10 +6121,12 @@ @end table @item target -Specification of where the captured item should be placed. -In Org-mode files, targets usually define a node. Entries will become -children of this node, other types will be added to the table or list in the -body of this node. +@vindex org-default-notes-file +Specification of where the captured item should be placed. In Org-mode +files, targets usually define a node. Entries will become children of this +node, other types will be added to the table or list in the body of this +node. Most target specifications contain a file name. If that file name is +the empty string, it defaults to @code{org-default-notes-file}. Valid values are: @table @code @@ -6139,6 +6195,10 @@ @item :unnarrowed Do not narrow the target buffer, simply show the full buffer. Default is to narrow it so that you only see the new material. + +@item :kill-buffer +If the target file was not yet visited when capture was invoked, kill the +buffer again after capture is completed. @end table @end table @@ -6191,16 +6251,19 @@ @smallexample Link type | Available keywords -------------------+---------------------------------------------- -bbdb | %:name %:company -bbdb | %::server %:port %:nick -vm, wl, mh, rmail | %:type %:subject %:message-id - | %:from %:fromname %:fromaddress - | %:to %:toname %:toaddress - | %:fromto @r{(either "to NAME" or "from NAME")@footnote{This will always be the other, not the user. See the variable @code{org-from-is-user-regexp}.}} -gnus | %:group, @r{for messages also all email fields} -w3, w3m | %:url -info | %:file %:node -calendar | %:date +bbdb | %:name %:company +irc | %:server %:port %:nick +vm, wl, mh, mew, rmail | %:type %:subject %:message-id + | %:from %:fromname %:fromaddress + | %:to %:toname %:toaddress + | %:date @r{(message date header field)} + | %:date-timestamp @r{(date as active timestamp)} + | %:date-timestamp-inactive @r{(date as inactive timestamp)} + | %:fromto @r{(either "to NAME" or "from NAME")@footnote{This will always be the other, not the user. See the variable @code{org-from-is-user-regexp}.}} +gnus | %:group, @r{for messages also all email fields} +w3, w3m | %:url +info | %:file %:node +calendar | %:date @end smallexample @noindent @@ -7247,6 +7310,7 @@ @subsection Categories @cindex category +@cindex #+CATEGORY The category is a broad label assigned to each agenda item. By default, the category is simply derived from the file name, but you can also specify it with a special line in the buffer, like this@footnote{For @@ -7474,6 +7538,10 @@ @item j Prompt for a date and go there. @c +@kindex J +@item J +Go to the currently clocked in task in the agenda buffer. +@c @kindex D @item D Toggle the inclusion of diary entries. See @ref{Weekly/daily agenda}. @@ -7584,7 +7652,9 @@ having to recreate the agenda@footnote{Custom commands can preset a filter by binding the variable @code{org-agenda-filter-preset} as an option. This filter will then be applied to the view and persist as a basic filter through -refreshes and more secondary filtering.} +refreshes and more secondary filtering. The filter is a global property of +the entire agenda view - in a block agenda, you should only set this in the +global options section, not in the section of an individual block.} You will be prompted for a tag selection letter, SPC will mean any tag at all. Pressing @key{TAB} at that prompt will offer use completion to select a @@ -8600,6 +8670,7 @@ backend-specific, see the sections about the individual backends for more information. +@xref{Handling links,the discussion of image links}. @node Literal examples, Include files, Images and tables, Markup @section Literal examples @@ -8631,13 +8702,24 @@ @cindex formatting source code, markup rules If the example is source code from a programming language, or any other text that can be marked up by font-lock in Emacs, you can ask for the example to -look like the fontified Emacs buffer@footnote{Currently this works for the -HTML backend, and requires the @file{htmlize.el} package version 1.34 or -later. It also works for LaTeX with the listings package, if you turn on the -option @code{org-export-latex-listings} and make sure that the listings -package is included by the LaTeX header.}. This is done with the @samp{src} -block, where you also need to specify the name of the major mode that should -be used to fontify the example: +look like the fontified Emacs buffer@footnote{This works automatically for +the HTML backend (it requires version 1.34 of the @file{htmlize.el} package, +which is distributed with Org.) Fontified code chunks in LaTeX can be +achieved using either the listings or the +@url{http://code.google.com/p/minted, minted,} package. To use listings, turn +on the variable @code{org-export-latex-listings} and ensure that the listings +package is included by the LaTeX header (e.g. by configuring +@code{org-export-latex-packages-alist}). See the listings documentation for +configuration options, including obtaining colored output. For minted it is +necessary to install the program @url{http://pygments.org, pygments}, in +addition to setting @code{org-export-latex-minted}, ensuring that the minted +package is included by the LaTeX header, and ensuring that the +@code{-shell-escape} option is passed to @file{pdflatex} (see +@code{org-latex-to-pdf-process}). See the documentation of the variables +@code{org-export-latex-listings} and @code{org-export-latex-minted} for +further details.}. This is done with the @samp{src} block, where you also +need to specify the name of the major mode that should be used to fontify the +example: @cindex #+BEGIN_SRC @example @@ -8794,12 +8876,9 @@ features described here as ``La@TeX{}'' are really from @TeX{}, but for simplicity I am blurring this distinction.} is widely used to typeset scientific documents. Org-mode supports embedding La@TeX{} code into its -files, because many academics are used to reading La@TeX{} source code, and -because it can be readily processed into images for HTML production. - -It is not necessary to mark La@TeX{} macros and code in any special way. -If you observe a few conventions, Org-mode knows how to find it and what -to do with it. +files, because many academics are used to writing and reading La@TeX{} source +code, and because it can be readily processed to produce pretty output for a +number of export backends. @menu * Special symbols:: Greek letters and other symbols @@ -8843,7 +8922,7 @@ @samp{...} are all converted into special commands creating hyphens of different lengths or a compact set of dots. -If you would like to see entities displayed as utf8 characters, use the +If you would like to see entities displayed as UTF8 characters, use the following command@footnote{You can turn this on by default by setting the variable @code{org-pretty-entities}, or on a per-file base with the @code{#+STARTUP} option @code{entitiespretty}.}: @@ -8884,6 +8963,9 @@ #+OPTIONS: ^:@{@} @end example +@noindent With this setting, @samp{a_b} will not be interpreted as a +subscript, but @samp{a_@{b@}} will. + @table @kbd @kindex C-c C-x \ @item C-c C-x \ @@ -8896,31 +8978,31 @@ @cindex La@TeX{} fragments @vindex org-format-latex-header -With symbols, sub- and superscripts, HTML is pretty much at its end when -it comes to representing mathematical formulas@footnote{Yes, there is -MathML, but that is not yet fully supported by many browsers, and there -is no decent converter for turning La@TeX{} or ASCII representations of -formulas into MathML. So for the time being, converting formulas into -images seems the way to go.}. More complex expressions need a dedicated -formula processor. To this end, Org-mode can contain arbitrary La@TeX{} -fragments. It provides commands to preview the typeset result of these -fragments, and upon export to HTML, all fragments will be converted to -images and inlined into the HTML document@footnote{The La@TeX{} export -will not use images for displaying La@TeX{} fragments but include these -fragments directly into the La@TeX{} code.}. For this to work you -need to be on a system with a working La@TeX{} installation. You also -need the @file{dvipng} program, available at -@url{http://sourceforge.net/projects/dvipng/}. The La@TeX{} header that -will be used when processing a fragment can be configured with the -variable @code{org-format-latex-header}. +Going beyond symbols and sub- and superscripts, a full formula language is +needed. Org-mode can contain La@TeX{} math fragments, and it supports ways +to process these for several export backends. When exporting to La@TeX{}, +the code is obviously left as it is. When exporting to HTML, Org invokes the +@uref{http://www.mathjax.org, MathJax library} (@pxref{Math formatting in +HTML export}) to process and display the math@footnote{If you plan to use +this regularly or on pages with significant page views, you should install +@file{MathJax} on your own server in order to limit the load of our server.}. +Finally, it can also process the mathematical expressions into +images@footnote{For this to work you need to be on a system with a working +La@TeX{} installation. You also need the @file{dvipng} program, available at +@url{http://sourceforge.net/projects/dvipng/}. The La@TeX{} header that will +be used when processing a fragment can be configured with the variable +@code{org-format-latex-header}.} that can be displayed in a browser or in +DocBook documents. La@TeX{} fragments don't need any special marking at all. The following snippets will be identified as La@TeX{} source code: @itemize @bullet @item -Environments of any kind. The only requirement is that the -@code{\begin} statement appears on a new line, preceded by only -whitespace. +Environments of any kind@footnote{When @file{MathJax} is used, only the +environment recognized by @file{MathJax} will be processed. When dvipng is +used to create images, any La@TeX{} environments will be handled.}. The only +requirement is that the @code{\begin} statement appears on a new line, +preceded by only whitespace. @item Text within the usual La@TeX{} math delimiters. To avoid conflicts with currency specifications, single @samp{$} characters are only recognized as @@ -8948,12 +9030,26 @@ can configure the option @code{org-format-latex-options} to deselect the ones you do not wish to have interpreted by the La@TeX{} converter. +@vindex org-export-with-LaTeX-fragments +LaTeX processing can be configured with the variable +@code{org-export-with-LaTeX-fragments}. The default setting is @code{t} +which means @file{MathJax} for HTML, and no processing for DocBook, ASCII and +LaTeX backends. You can also set this variable on a per-file basis using one +of these lines: + +@example +#+OPTIONS: LaTeX:t @r{Do the right thing automatically (MathJax)} +#+OPTIONS: LaTeX:dvipng @r{Force using dvipng images} +#+OPTIONS: LaTeX:nil @r{Do not process La@TeX{} fragments at all} +#+OPTIONS: LaTeX:verbatim @r{Verbatim export, for jsMath or so} +@end example + @node Previewing LaTeX fragments, CDLaTeX mode, LaTeX fragments, Embedded LaTeX @subsection Previewing LaTeX fragments @cindex LaTeX fragments, preview -La@TeX{} fragments can be processed to produce preview images of the -typeset expressions: +If you have @file{dvipng} installed, La@TeX{} fragments can be processed to +produce preview images of the typeset expressions: @table @kbd @kindex C-c C-x C-l @@ -8975,14 +9071,6 @@ export, @code{:html-scale}) property can be used to adjust the size of the preview images. -During HTML export (@pxref{HTML export}), all La@TeX{} fragments are -converted into images and inlined into the document if the following -setting is active: - -@lisp -(setq org-export-with-LaTeX-fragments t) -@end lisp - @node CDLaTeX mode, , Previewing LaTeX fragments, Embedded LaTeX @subsection Using CDLa@TeX{} to enter math @cindex CDLa@TeX{} @@ -9200,7 +9288,7 @@ <: @r{turn on/off inclusion of any time/date stamps like DEADLINES} *: @r{turn on/off emphasized text (bold, italic, underlined)} TeX: @r{turn on/off simple @TeX{} macros in plain text} -LaTeX: @r{turn on/off La@TeX{} fragments} +LaTeX: @r{configure export of La@TeX{} fragments. Default @code{auto}} skip: @r{turn on/off skipping the text before the first heading} author: @r{turn on/off inclusion of author name/email into exported file} email: @r{turn on/off inclusion of author email into exported file} @@ -9333,6 +9421,7 @@ * Links in HTML export:: How links will be interpreted and formatted * Tables in HTML export:: How to modify the formatting of tables * Images in HTML export:: How to insert figures into HTML output +* Math formatting in HTML export:: Beautiful math also on the web * Text areas in HTML export:: An alternative way to show an example * CSS support:: Changing the appearance of the output * JavaScript support:: Info and Folding in a web browser @@ -9468,7 +9557,7 @@ #+ATTR_HTML: border="2" rules="all" frame="all" @end example -@node Images in HTML export, Text areas in HTML export, Tables in HTML export, HTML export +@node Images in HTML export, Math formatting in HTML export, Tables in HTML export, HTML export @subsection Images in HTML export @cindex images, inline in HTML @@ -9505,7 +9594,41 @@ @noindent and you could use @code{http} addresses just as well. -@node Text areas in HTML export, CSS support, Images in HTML export, HTML export +@node Math formatting in HTML export, Text areas in HTML export, Images in HTML export, HTML export +@subsection Math formatting in HTML export +@cindex MathJax +@cindex dvipng + +La@TeX{} math snippets (@pxref{LaTeX fragments}) can be displayed in two +different ways on HTML pages. The default is to use the +@uref{http://www.mathjax.org, MathJax system} which should work out of the +box with Org mode installation because @code{http://orgmode.org} serves +@file{MathJax} for Org-mode users for small applications and for testing +purposes. @b{If you plan to use this regularly or on pages with significant +page views, you should install MathJax on your own server in order to limit +the load of our server.} To configure @file{MathJax}, use the variable +@code{org-export-html-mathjax-options} or insert something like the following +into the buffer: + +@example +#+MATHJAX: align:"left" mathml:t path:"/MathJax/MathJax.js" +@end example + +@noindent See the docstring of the variable +@code{org-export-html-mathjax-options} for the meaning of the parameters in +this line. + +If you prefer, you can also request that La@TeX{} are processed into small +images that will be inserted into the browser page. Before the availability +of MathJax, this was the default method for Org files. This method requires +that the @file{dvipng} program is available on your system. You can still +get this processing with + +@example +#+OPTIONS: LaTeX:dvipng +@end example + +@node Text areas in HTML export, CSS support, Math formatting in HTML export, HTML export @subsection Text areas in HTML export @cindex text areas, in HTML @@ -9595,6 +9718,11 @@ directly write a @code{} section in this way, without referring to an external file. +In order to add styles to a subtree, use the @code{:HTML_CONTAINER_CLASS:} +property to assign a class to the tree. In order to specify CSS styles for a +particular headline, you can use the id specified in a @code{:CUSTOM_ID:} +property. + @c FIXME: More about header and footer styles @c FIXME: Talk about links and targets. @@ -9890,9 +10018,9 @@ structure of the presentation. A template for useful in-buffer settings or properties can be inserted into -the buffer with @kbd{M-x org-beamer-settings-template}. Among other things, -this will install a column view format which is very handy for editing -special properties used by beamer. +the buffer with @kbd{M-x org-insert-beamer-options-template}. Among other +things, this will install a column view format which is very handy for +editing special properties used by beamer. You can influence the structure of the presentation using the following properties: @@ -9957,7 +10085,7 @@ Column view provides a great way to set the environment of a node and other important parameters. Make sure you are using a COLUMN format that is geared toward this special purpose. The command @kbd{M-x -org-beamer-settings-template} defines such a format. +org-insert-beamer-options-template} defines such a format. Here is a simple example Org document that is intended for beamer export. @@ -10366,6 +10494,7 @@ @vindex org-icalendar-use-deadline @vindex org-icalendar-use-scheduled @vindex org-icalendar-categories +@vindex org-icalendar-alarm-time Some people use Org-mode for keeping track of projects, but still prefer a standard calendar application for anniversaries and appointments. In this case it can be useful to show deadlines and other time-stamped items in Org @@ -10379,7 +10508,9 @@ @code{org-icalendar-use-deadline} and @code{org-icalendar-use-scheduled}.}. As categories, it will use the tags locally defined in the heading, and the file/tree category@footnote{To add inherited tags or the TODO state, -configure the variable @code{org-icalendar-categories}.}. +configure the variable @code{org-icalendar-categories}.}. See the variable +@code{org-icalendar-alarm-time} for a way to assign alarms to entries with a +time. @vindex org-icalendar-store-UID @cindex property, ID @@ -10477,7 +10608,8 @@ configures one project, and may be in one of the two following forms: @lisp - ("project-name" :property value :property value ...) + ("project-name" :property value :property value ...) + @r{i.e. a well-formed property list with alternating keys and values} @r{or} ("project-name" :components ("project-name" "project-name" ...)) @@ -10553,20 +10685,20 @@ Org files as HTML files, and this is done by the function @code{org-publish-org-to-html} which calls the HTML exporter (@pxref{HTML export}). But you also can publish your content as PDF files using -@code{org-publish-org-to-pdf}. If you want to publish the Org file itself, -but with @i{archived}, @i{commented}, and @i{tag-excluded} trees removed, use -@code{org-publish-org-to-org} and set the parameters @code{:plain-source} -and/or @code{:htmlized-source}. This will produce @file{file.org} and -@file{file.org.html} in the publishing +@code{org-publish-org-to-pdf}, or as @code{ascii}, @code{latin1} or +@code{utf8} encoded files using the corresponding functions. If you want to +publish the Org file itself, but with @i{archived}, @i{commented}, and +@i{tag-excluded} trees removed, use @code{org-publish-org-to-org} and set the +parameters @code{:plain-source} and/or @code{:htmlized-source}. This will +produce @file{file.org} and @file{file.org.html} in the publishing directory@footnote{@file{file-source.org} and @file{file-source.org.html} if source and publishing directories are equal. Note that with this kind of setup, you need to add @code{:exclude "-source\\.org"} to the project definition in @code{org-publish-project-alist} to avoid that the published source files will be considered as new org files the next time the project is -published.}. Other files like images only -need to be copied to the publishing destination, for this you may use -@code{org-publish-attachment}. For non-Org files, you always need to -specify the publishing function: +published.}. Other files like images only need to be copied to the +publishing destination, for this you may use @code{org-publish-attachment}. +For non-Org files, you always need to specify the publishing function: @multitable @columnfractions 0.3 0.7 @item @code{:publishing-function} @@ -10960,9 +11092,9 @@ Org-mode provides a number of features for working with live source code, including editing of code blocks in their native major-mode, evaluation of -code blocks, tangling of code blocks, and exporting code blocks and -their results in several formats. This functionality was contributed by Dan -Davison and Eric Schulte, and was originally named Org-babel. +code blocks, tangling of code blocks, and exporting code blocks and their +results in several formats. This functionality was contributed by Eric +Schulte and Dan Davison, and was originally named Org-babel. The following sections describe Org-mode's code block handling facilities. @@ -10998,6 +11130,18 @@ #+end_src @end example +code blocks can also be embedded in text as so called inline code blocks as + +@example +src_@{@} +@end example + +or + +@example +src_[
]@{@} +@end example + @table @code @item This name is associated with the code block. This is similar to the @@ -11124,10 +11268,10 @@ @kindex C-c C-v t @subsubheading Functions @table @code -@item org-babel-tangle @kbd{C-c C-v t} -Tangle the current file. +@item org-babel-tangle +Tangle the current file. Bound to @kbd{C-c C-v t}. @item org-babel-tangle-file -Choose a file to tangle. +Choose a file to tangle. Bound to @kbd{C-c C-v f}. @end table @subsubheading Hooks @@ -11200,10 +11344,10 @@ they were in the current Org-mode buffer (see @ref{Evaluating code blocks} for information on the syntax of remote code block evaluation). -@kindex C-c C-v l +@kindex C-c C-v i Code blocks located in any Org-mode file can be loaded into the ``Library of Babel'' with the @code{org-babel-lob-ingest} function, bound to @kbd{C-c C-v -l}. +i}. @node Languages, Header arguments, Library of Babel, Working With Source Code @section Languages @@ -11279,7 +11423,7 @@ @node Using header arguments, Specific header arguments, Header arguments, Header arguments @subsection Using header arguments -The values of header arguments can be set in five different ways, each more +The values of header arguments can be set in six different ways, each more specific (and having higher priority) than the last. @menu * System-wide header arguments:: Set global default values @@ -11287,6 +11431,7 @@ * Buffer-wide header arguments:: Set default values for a specific buffer * Header arguments in Org-mode properties:: Set default values for a buffer or heading * Code block specific header arguments:: The most common way to set values +* Header arguments in function calls:: The most specific level @end menu @@ -11381,7 +11526,7 @@ @code{org-set-property} function bound to @kbd{C-c C-x p} to set properties in Org-mode documents. -@node Code block specific header arguments, , Header arguments in Org-mode properties, Using header arguments +@node Code block specific header arguments, Header arguments in function calls, Header arguments in Org-mode properties, Using header arguments @subsubheading Code block specific header arguments The most common way to assign values to header arguments is at the @@ -11402,14 +11547,18 @@ fac n = n * fac (n-1) #+end_src @end example - Similarly, it is possible to set header arguments for inline code blocks: @example src_haskell[:exports both]@{fac 5@} @end example -Header arguments for ``Library of Babel'' or function call lines can be set as shown below: +@node Header arguments in function calls, , Code block specific header arguments, Using header arguments +@comment node-name, next, previous, up +@subsubheading Header arguments in function calls + +At the most specific level, header arguments for ``Library of Babel'' or +function call lines can be set as shown below: @example #+call: factorial(n=5) :exports results @@ -11428,10 +11577,10 @@ directory for code block execution * exports:: Export code and/or results * tangle:: Toggle tangling and specify file name +* comments:: Toggle insertion of comments in tangled + code files * no-expand:: Turn off variable assignment and noweb expansion during tangling -* comments:: Toggle insertion of comments in tangled - code files * session:: Preserve the state of code evaluation * noweb:: Toggle expansion of noweb references * cache:: Avoid re-evaluating unchanged code blocks @@ -11842,10 +11991,25 @@ @subsubsection @code{:comments} By default code blocks are tangled to source-code files without any insertion of comments beyond those which may already exist in the body of the code -block. The @code{:comments} header argument can be set to ``yes'' -e.g. @code{:comments yes} to enable the insertion of comments around code -blocks during tangling. The inserted comments contain pointers back to the -original Org file from which the comment was tangled. +block. The @code{:comments} header argument can be set as follows to control +the insertion of extra comments into the tangled code file. + +@itemize @bullet +@item @code{no} +The default. No extra comments are inserted during tangling. +@item @code{link} +The code block is wrapped in comments which contain pointers back to the +original Org file from which the code was tangled. +@item @code{yes} +A synonym for ``link'' to maintain backwards compatibility. +@item @code{org} +Include text from the org-mode file as a comment. + +The text is picked from the leading context of the tangled code and is +limited by the nearest headline or source block as the case may be. +@item @code{both} +Turns on both the ``link'' and ``org'' comment options. +@end itemize @node no-expand, session, comments, Specific header arguments @subsubsection @code{:no-expand} @@ -11873,16 +12037,20 @@ The @code{:noweb} header argument controls expansion of ``noweb'' style (see @ref{Noweb reference syntax}) references in a code block. This header -argument can have one of two values: @code{yes} or @code{no}. +argument can have one of three values: @code{yes} @code{no} or @code{tangle}. @itemize @bullet +@item @code{yes} +All ``noweb'' syntax references in the body of the code block will be +expanded before the block is evaluated, tangled or exported. @item @code{no} The default. No ``noweb'' syntax specific action is taken on evaluating code blocks, However, noweb references will still be expanded during tangling. @item @code{yes} All ``noweb'' syntax references in the body of the code block will be -expanded before the block is evaluated. +expanded before the block is tangled, however ``noweb'' references will not +be expanded when the block is evaluated or exported. @end itemize @subsubheading Noweb prefix lines @@ -12067,7 +12235,7 @@ first line of any tangled file holding the code block, and the file permissions of the tangled file are set to make it executable. -@node eval, , shebang, Specific header arguments +@node eval, , shebang, Specific header arguments @subsubsection @code{:eval} The @code{:eval} header argument can be used to limit the evaluation of specific code blocks. @code{:eval} accepts two arguments ``never'' and @@ -12268,17 +12436,18 @@ #!/bin/sh # -*- mode: shell-script -*- # -# tangle a file with org-mode +# tangle files with org-mode # DIR=`pwd` FILES="" +ORGINSTALL="~/src/org/lisp/org-install.el" # wrap each argument in the code required to call tangle on it for i in $@@; do -FILES="$FILES \"$i\"" + FILES="$FILES \"$i\"" done -emacsclient \ +emacs -Q --batch -l $ORGINSTALL \ --eval "(progn (add-to-list 'load-path (expand-file-name \"~/src/org/lisp/\")) (add-to-list 'load-path (expand-file-name \"~/src/org/contrib/lisp/\")) @@ -12286,7 +12455,7 @@ (mapc (lambda (file) (find-file (expand-file-name file \"$DIR\")) (org-babel-tangle) - (kill-buffer)) '($FILES)))" + (kill-buffer)) '($FILES)))" 2>&1 |grep tangled @end example @node Miscellaneous, Hacking, Working With Source Code, Top @@ -12294,6 +12463,7 @@ @menu * Completion:: M-TAB knows what you need +* Easy Templates:: Quick insertion of structural elements * Speed keys:: Electric commands at the beginning of a headline * Code evaluation security:: Org mode files evaluate inline code * Customization:: Adapting Org to your taste @@ -12305,7 +12475,7 @@ @end menu -@node Completion, Speed keys, Miscellaneous, Miscellaneous +@node Completion, Easy Templates, Miscellaneous, Miscellaneous @section Completion @cindex completion, of @TeX{} symbols @cindex completion, of TODO keywords @@ -12367,7 +12537,46 @@ @end itemize @end table -@node Speed keys, Code evaluation security, Completion, Miscellaneous +@node Easy Templates, Speed keys, Completion, Miscellaneous +@section Easy Templates +@cindex template insertion +@cindex insertion, of templates + +Org-mode supports insertion of empty structural elements (like +@code{#+BEGIN_SRC} and @code{#+END_SRC} pairs) with just a few key +strokes. This is achieved through a native template expansion mechanism. +Note that Emacs has several other template mechanisms which could be used in +a similar way, for example @file{yasnippet}. + +To insert a structural element, type a @samp{<}, followed by a template +selector and @kbd{@key{TAB}}. Completion takes effect only when the above +keystrokes are typed on a line by itself. + +The following template selectors are currently supported. + +@multitable @columnfractions 0.1 0.9 +@item @kbd{s} @tab @code{#+begin_src ... #+end_src} +@item @kbd{e} @tab @code{#+begin_example ... #+end_example} +@item @kbd{q} @tab @code{#+begin_quote ... #+end_quote} +@item @kbd{v} @tab @code{#+begin_verse ... #+end_verse} +@item @kbd{c} @tab @code{#+begin_center ... #+end_center} +@item @kbd{l} @tab @code{#+begin_latex ... #+end_latex} +@item @kbd{L} @tab @code{#+latex:} +@item @kbd{h} @tab @code{#+begin_html ... #+end_html} +@item @kbd{H} @tab @code{#+html:} +@item @kbd{a} @tab @code{#+begin_ascii ... #+end_ascii} +@item @kbd{A} @tab @code{#+ascii:} +@item @kbd{i} @tab @code{#+include:} line +@end multitable + +For example, on an empty line, typing " + + * refcards/orgcard.tex: adding new Babel key sequences to the + org refcard + 2010-10-26 Glenn Morris * images/README: Add (un)checked.xpm diff -r 62aa3653746a -r 5cb272c831e8 etc/refcards/orgcard.tex --- a/etc/refcards/orgcard.tex Thu Nov 11 19:23:58 2010 -0800 +++ b/etc/refcards/orgcard.tex Thu Nov 11 22:10:19 2010 -0600 @@ -1,5 +1,5 @@ % Reference Card for Org Mode -\def\orgversionnumber{7.01} +\def\orgversionnumber{7.3} \def\versionyear{2010} % latest update \def\year{2010} % latest copyright year @@ -480,14 +480,18 @@ \key{view expanded body of code block at point}{C-c C-v v} \key{go to named code block}{C-c C-v g} \key{go to named result}{C-c C-v r} +\key{go to the head of the current code block}{C-c C-v u} \key{go to the next code block}{C-c C-v n} \key{go to the previous code block}{C-c C-v p} +\key{demarcate a code block}{C-c C-v d} +\key{execute the next key sequence in the code edit buffer}{C-c C-v x} \key{execute all code blocks in current buffer}{C-c C-v b} \key{execute all code blocks in current subtree}{C-c C-v s} \key{tangle code blocks in current file}{C-c C-v t} \key{tangle code blocks in supplied file}{C-c C-v f} -\key{ingest all code blocks in supplied file into the Library of Babel}{C-c C-v l} +\key{ingest all code blocks in supplied file into the Library of Babel}{C-c C-v i} \key{switch to the session of the current code block}{C-c C-v z} +\key{load expanded body of the current code block into a session}{C-c C-v l} \key{view sha1 hash of the current code block}{C-c C-v a} % \section{Remember-mode Integration} diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ChangeLog --- a/lisp/org/ChangeLog Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ChangeLog Thu Nov 11 22:10:19 2010 -0600 @@ -1,3 +1,3336 @@ +2010-11-11 Dan Davison + + * ob.el: `copy-sequence' suffices to copy alist; no need for + `copy-tree'. + +2010-11-11 Dan Davison + + * ob.el (org-babel-execute-src-block): If ":results file" is in + effect, then ensure that the value of :file is returned as the + result; don't rely on language files for this. + +2010-11-11 Dan Davison + + * ob.el (org-babel-sha1-hash): Avoid corrupting `info' data + structure by side-effects of `sort'. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-bottom-point-with-indent): Do not check + indentation of a non-empty blank line. + + * org-list.el (org-sort-list): Sort a list with point anywhere + inside it. + +2010-11-11 Eric Schulte + + * ob-calc.el (org-babel-execute:calc): Safer evaluation and + hopefully better error messages. + +2010-11-11 Eric Schulte + + * org.el (org-babel-load-languages): Adding calc. + +2010-11-11 Dan Davison + + * ob.el (org-babel-initiate-session): Don't resolve variable + references unless prefix arg is supplied. + +2010-11-11 Eric Schulte + + * ob-calc.el (org-babel-execute:calc): Ensure that calc stack + refers to the correct stack. + +2010-11-11 Eric Schulte + + * ob-calc.el: Adding the beginnings of support for calc code + blocks. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-update-block-body): Declaring function + for updating code block bodies. + (org-babel-spec-to-string): + (org-babel-detangle): Detangle all tangled and commented code + blocks in the current file back to org. + (org-babel-tangle-jump-to-org): Jump from a tangled and commented + file back to the originating org-mode code block ob-tangle: + detangle changes in code files back to the original org files. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-tangle-comment-format-beg): Fix typo. + (org-babel-tangle-comment-format-end): Fix typo. + +2010-11-11 Dan Davison + + * org-exp.el (org-export-format-source-code-or-example): Use + minted for latex source code export if `org-export-latex-listings' + has the value 'minted + + * org-latex.el (org-export-latex-listings): Document special value + 'minted + + * org-latex.el (org-export-latex-minted): Delete variable. + +2010-11-11 Dan Davison + + * ob.el (org-babel-get-src-block-info): Retrieve contents of + parentheses, excluding parentheses themselves. + +2010-11-11 Eric Schulte + + * ob-gnuplot.el (org-babel-variable-assignments:gnuplot): Fixed + bug in gnuplot data file assignment using user variables. + +2010-11-11 Eric Schulte + + * ob-latex.el (org-babel-execute:latex): Adding new :headers + header argument for latex code blocks. + +2010-11-11 Carsten Dominik + + * org-capture.el (org-capture-templates): New capture property + `:kill-buffer'. (org-capture-finalize): Kill target buffer if that + is desired. + (org-capture-target-buffer): Remember if we have to make the + buffer. + +2010-11-11 Carsten Dominik + + * org-clock.el (org-dblock-write:clocktable): Fix bug when + computing clock tables. + +2010-11-11 Carsten Dominik + + * org-clock.el (org-dblock-write:clocktable): Pass file minutes up + to caller even if no table is generated. + +2010-11-11 Åukasz Stelmach + + * org-agenda.el (org-agenda-get-sexps): Handle lists as return + values from diary entries + + * org-bbdb.el (org-bbdb-anniversaries): Handle lists of + anniversaries + + * org.el (org-diary-sexp-entry): Handle lists as return values + from diary entries. + +2010-11-11 Carsten Dominik + + * org-capture.el (org-capture-empty-lines-before): + (org-capture-empty-lines-after): Make sure the n=0 does not insert + any newlines. + +2010-11-11 Eric Schulte + + * ob-clojure.el (org-babel-clojure-babel-clojure-cmd): Fixed error + message when clojure binary is not found. + +2010-11-11 Carsten Dominik + + * org-html.el (org-format-table-html): New argument DOCBOOK. + (org-format-org-table-html): New argument DOCBOOK. When set, use + align instead of class to align table fields. + + * org-docbook.el (org-export-as-docbook): Specify the docbook + argument for the table converter. + +2010-11-11 Carsten Dominik + + * org-macs.el (org-called-interactively-p): New macro. + + * org-freemind.el: No longer require 'rx. + (org-freemind): New customization group, use it for all the + variables. + (org-export-as-freemind): Add docstring. + (org-freemind-show): Improve filen naming. + (org-freemind-convert-links-helper): New function. + (org-freemind-bol-helper-base-indent): New variable. + (org-freemind-bol-helper): New function. + (org-freemind-node-css-style): New option. + (org-freemind-node-pattern): New variable. + (org-freemind-from-org-mode): Better docstring. + +2010-11-11 David Maus + + * ob-haskell.el (org-babel-variable-assignments:haskell): Don't + pass more than two arguments to mapc. + +2010-11-11 David Maus + + * ob.el (org-babel-ref-resolve): Declare to silence byte compiler. + +2010-11-11 David Maus + + * org-footnote.el (message-signature-separator): Defvar to silence + byte compiler. + +2010-11-11 David Maus + + * org-exp.el (org-export-string): Fix reference to wrong symbol. + +2010-11-11 Jambunathan K + + * org.el (org-link-search): Return 'dedicated on successful match + when org-link-search-must-match-exact-headline is set to t. + +2010-11-11 Daniel Clemente + + * org-html.el (org-html-make-link): Append fragment to file: links + if present. + +2010-11-11 Tassilo Horn + + * org-footnote.el (org-footnote-create-definition) + (org-footnote-goto-local-insertion-point): Add footnotes before + signature when in message-mode. + +2010-11-11 Carsten Dominik + + * org.el (org-display-inline-images): Improve regexp. + +2010-11-11 Carsten Dominik + + * org.el (org-cycle): Make sure resetting to startup visibility + works after another cycle command. + +2010-11-11 Eric Schulte + + * org-exp.el (org-export-string): New function org-export-string + can be used to convert a string of test in org-mode markup to a + specified format. + +2010-11-11 Carsten Dominik + + * org.el (org-display-inline-images): Allow non-ASCII characters + in image file names. Save match data. + +2010-11-11 Carsten Dominik + + * org.el (org-auto-repeat-maybe): Fix shifting multiple time + stamps. + +2010-11-11 Carsten Dominik + + * org-exp.el (org-store-forced-table-alignment): + (org-export-remove-special-table-lines): Allow the "c" cookie for + table alignment. + + * org-html.el (org-export-table-header-tags): + (org-export-table-data-tags): Add another %s format for the + alignment. + (org-export-html-table-align-individual-fields): New option. + (org-format-org-table-html): Implement field-by-field alignment + and support centering. + (org-format-table-table-html): Make sure the new table tag formats + don't break this function. + + * org-table.el (org-table-cookie-line-p): + (org-table-align): Allow for the cookie. + + * org.el (org-set-font-lock-defaults): Allow for the cookie. + +2010-11-11 David Maus + + * org-exp.el (org-export-normalize-links): Skip normalization of + plain links that are part of another link. + +2010-11-11 Dan Davison + + * ob-R.el (org-babel-expand-body:R): Fix bug in let binding. + +2010-11-11 Carsten Dominik + + * org-indent.el: (org-indent-add-properties): Use + `with-silent-modificaitons'. + (org-indent-remove-properties): Use `with-silent-modificaitons'. + +2010-11-11 Carsten Dominik + + * org-table.el (org-table-cookie-line-p): Fix indentation. + + * org-exp.el (org-store-forced-table-alignment): New function. + (org-export-preprocess-string): Call + `org-store-forced-table-alignment'. + + * org-html.el (org-format-org-table-html): Use stored alignment + information. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-execute-src-block): Respects prefix argument + (which forces re-calculation). + +2010-11-11 Eric Schulte + + * ob.el (org-babel-execute-src-block): Removed needless param + sorting from ob-execute-src-block, the params are sorted already + by ob-sha1-hash. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-sha1-hash): Ensure that info is sorted at the + header argument level. + +2010-11-11 Dan Davison + + * ob.el (org-babel-sha1-hash): Consider words in different order + as different input. + +2010-11-11 Dan Davison + + * ob.el (org-babel-sha1-hash): Fix check for zero length sequences. + +2010-11-11 Dan Davison + + * ob-sh.el (org-babel-sh-var-to-sh): Ensure value has the + structure of an Org-mode table (list of lists). + +2010-11-11 Dan Davison + + * ob-tangle.el (org-babel-tangle-collect-blocks): Fix bug + (reference to unassigned variable `src-lang' and avoid calling + org-babel-get-src-block-info twice. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-demarcate-block): Updated to reflect the new + info list contents. + +2010-11-11 Dan Davison + + * org-src.el (org-edit-src-code): Supply non-nil argument to + `org-babel-get-src-block-info' to avoid resolving variable + references. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-map-src-blocks): Fixed minor bug in and + improved efficiency of org-babel-map-src-blocks. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-tangle-collect-blocks): Now explicitly + checks that a code block will actually be tangled before + collecting it's full information (a process which could involve + the execution of other code blocks). + +2010-11-11 Dan Davison + + * ob.el (org-babel-demarcate-block): Use light version of + `org-babel-get-src-block-info'. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-sha1-hash): Now handles more complex types in + params. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-execute-src-block): Generally using the new + more informative params + (org-babel-process-params): Don't forget the :var portion of + variable assignments. + +2010-11-11 Eric Schulte + + * ob-table.el (sbe): Simplified to reflect to var resolution. + +2010-11-11 Eric Schulte + + * ob-ref.el (org-babel-ref-resolve): Bringing the referent + arguments back to their params before evaluation. + +2010-11-11 Eric Schulte + + * ob-ref.el (org-babel-ref-resolve): Cleanup of variable usage and + indentation. + +2010-11-11 Dan Davison + + * ob-table.el (sbe): Use `org-babel-process-params params' instead + of `org-babel-expand-variables'. + +2010-11-11 Dan Davison + + * ob-C.el (org-babel-C-execute): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-R.el (org-babel-execute:R): Remove call to + org-babel-process-params which should no longer be called from + within a language file + (org-babel-R-variable-assignments): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-asymptote.el (org-babel-execute:asymptote): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-clojure.el (org-babel-execute:clojure): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-dot.el (org-babel-execute:dot): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-emacs-lisp.el (org-babel-expand-body:emacs-lisp): Remove + call to org-babel-process-params which should no longer be called + from within a language file + (org-babel-execute:emacs-lisp): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-haskell.el (org-babel-execute:haskell): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-js.el (org-babel-execute:js): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-lisp.el (org-babel-execute:lisp): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-ocaml.el (org-babel-execute:ocaml): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-octave.el (org-babel-execute:octave): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-perl.el (org-babel-execute:perl): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-python.el (org-babel-execute:python): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-ruby.el (org-babel-execute:ruby): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-scheme.el (org-babel-execute:scheme): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-screen.el (org-babel-execute:screen): Remove call to + org-babel-process-params which should no longer be called from + within a language file + (org-babel-prep-session:screen): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-sh.el (org-babel-execute:sh): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-sql.el (org-babel-execute:sql): Remove call to + org-babel-process-params which should no longer be called from + within a language file + + * ob-haskell.el (org-babel-execute:haskell): Remove reference to + processed params + + * ob-clojure.el (org-babel-execute:clojure): Remove reference to + processed params + + * ob-R.el (org-babel-execute:R): Remove reference to processed + params. + +2010-11-11 Dan Davison + + * ob-sql.el (org-babel-execute:sql): Use generic expansion + function + (org-babel-expand-body:sql): Delete function. + +2010-11-11 Dan Davison + + * ob-sh.el (org-babel-execute:sh): Use generic expansion function + (org-babel-expand-body:sh): Delete function + (org-babel-prep-session:sh): Change name of called function + (org-babel-variable-assignments:sh): Change function name. + +2010-11-11 Dan Davison + + * ob-screen.el (org-babel-execute:screen): Use generic expansion + function + (org-babel-expand-body:screen): Delete function + (org-babel-prep-session:screen): Remove references to processed + params. + +2010-11-11 Dan Davison + + * ob-sass.el (org-babel-execute:sass): Use generic expansion + function + (org-babel-expand-body:sass): Delete function. + +2010-11-11 Dan Davison + + * ob-ruby.el (org-babel-execute:ruby): Use generic expansion + function + (org-babel-prep-session:ruby): Use new variable assignment + function + (org-babel-variable-assignments:ruby): New function + (org-babel-expand-body:ruby): Delete function. + +2010-11-11 Dan Davison + + * ob-python.el (org-babel-execute:python): Use generic expansion + function + (org-babel-prep-session:python): Change name of called function + (org-babel-variable-assignments:python): Change function name + (org-babel-expand-body:python): Delete function. + +2010-11-11 Dan Davison + + * ob-plantuml.el (org-babel-expand-body:plantuml): Delete function + (automatically handled by generic version). + +2010-11-11 Dan Davison + + * ob-perl.el (org-babel-execute:perl): Use generic expansion + function + (org-babel-expand-body:perl): Delete function + (org-babel-variable-assignments:perl): New function. + +2010-11-11 Dan Davison + + * ob-org.el (org-babel-expand-body:org): Delete function + (automatically handled by generic version). + +2010-11-11 Dan Davison + + * ob-octave.el (org-babel-execute:octave): Use generic expansion + function + (org-babel-variable-assignments:octave): Change name of function + (org-babel-variable-assignments:matlab): New defalias + (org-babel-prep-session:octave): Change name of function + (org-babel-expand-body:matlab): Delete function + (org-babel-expand-body:octave): Delete function. + +2010-11-11 Dan Davison + + * ob-ocaml.el (org-babel-execute:ocaml): Use generic expansion + function + (org-babel-variable-assignments:ocaml): New function + (org-babel-expand-body:ocaml): Delete function. + +2010-11-11 Dan Davison + + * ob-mscgen.el (org-babel-expand-body:mscgen): Delete function + (automatically handled by generic version). + +2010-11-11 Dan Davison + + * ob-js.el (org-babel-execute:js): Use new variable assignment + function + (org-babel-expand-body:js): Delete function + (org-babel-prep-session:js): Use new variable assignment function + (org-babel-variable-assignments:js): New function. + +2010-11-11 Dan Davison + + * ob-haskell.el (org-babel-execute:haskell): Use generic expansion + function + (org-babel-expand-body:haskell): Delete function + (org-babel-prep-session:haskell): Use variable assignment function + (org-babel-variable-assignments:haskell): New function. + +2010-11-11 Dan Davison + + * ob-gnuplot.el (org-babel-expand-body:gnuplot): Use variable + assignment function + (org-babel-prep-session:gnuplot): Use variable assignment function + (org-babel-variable-assignments:gnuplot): New function. + +2010-11-11 Dan Davison + + * ob-ditaa.el (org-babel-expand-body:ditaa): Delete function + (automatically handled by generic version). + +2010-11-11 Dan Davison + + * ob-css.el (org-babel-expand-body:css): Delete function + (automatically handled by generic version). + +2010-11-11 Dan Davison + + * ob-asymptote.el (org-babel-execute:asymptote): Use generic + expansion function + (org-babel-expand-body:asymptote): Delete function + (org-babel-variable-assignments:asymptote): New function. + +2010-11-11 Dan Davison + + * ob-R.el (org-babel-expand-body:R): Use new function + `org-babel-variable-assignments:R'; don't trim body. + (org-babel-execute:R): Respond to changes in + `org-babel-expand-body:R' + (org-babel-prep-session:R): Called function is now named + `org-babel-variable-assignments:R' + (org-babel-variable-assignments:R): Receives processed-params as + new optional argument. + +2010-11-11 Dan Davison + + * ob-C.el (org-babel-C-expand): Don't trim body. + +2010-11-11 Dan Davison + + * ob-scheme.el (org-babel-expand-body:scheme): Fix bug in + obtaining variable references. + +2010-11-11 Dan Davison + + * ob-tangle.el (org-babel-tangle-collect-blocks): Supply variable + assignment lines to generic expansion command. + +2010-11-11 Dan Davison + + * ob.el (org-babel-expand-src-block): Supply variable assignment + lines to generic expansion function + (org-babel-expand-body:generic): Prepend body with optional + variable assignment lines. + +2010-11-11 Eric Schulte + + * ob-exp.el (org-babel-exp-results): Replaced old function call. + +2010-11-11 Eric Schulte + + * ob-lob.el (org-babel-lob-execute): Now expanding variable + references before execution. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-execute-src-block): Only sort parameters if + it's required for caching. + +2010-11-11 Eric Schulte + + * ob-table.el (sbe): Reworking for better indentation and to + integrate the new variable resolution. + +2010-11-11 Eric Schulte + + * ob-ref.el (org-babel-ref-resolve-reference): Now expanding + variables when resolving references. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-merge-params): Fixed order or precedence for + variables. + +2010-11-11 Eric Schulte + + * ob-C.el (org-babel-expand-body:c++): Remove obsoleted optional + third argument + (org-babel-expand-body:c++): Remove obsoleted optional third + argument + (org-babel-C-expand): Remove obsoleted optional third argument + + * ob-R.el: + (org-babel-expand-body:R): Remove obsoleted optional third + argument + (org-babel-execute:R): Remove obsoleted optional third argument + (org-babel-R-variable-assignments): Remove obsoleted optional + third argument + + * ob-asymptote.el: + (org-babel-expand-body:asymptote): Remove obsoleted optional + third argument + (org-babel-execute:asymptote): Remove obsoleted optional third + argument + + * ob-clojure.el: + (org-babel-expand-body:clojure): Remove obsoleted optional third + argument + (org-babel-execute:clojure): Remove obsoleted optional third + argument + + * ob-css.el: + (org-babel-expand-body:css): Remove obsoleted optional third + argument + + * ob-ditaa.el: + (org-babel-expand-body:ditaa): Remove obsoleted optional third + argument + + * ob-dot.el: + (org-babel-expand-body:dot): Remove obsoleted optional third + argument + (org-babel-execute:dot): Remove obsoleted optional third + argument + + * ob-emacs-lisp.el: + (org-babel-expand-body:emacs-lisp): Remove obsoleted optional + third argument + (org-babel-execute:emacs-lisp): Remove obsoleted optional third + argument + + * ob-gnuplot.el: + (org-babel-expand-body:gnuplot): Remove obsoleted optional third + argument + + * ob-haskell.el: + (org-babel-expand-body:haskell): Remove obsoleted optional third + argument + (org-babel-execute:haskell): Remove obsoleted optional third + argument + (org-babel-load-session:haskell): Remove obsoleted optional + third + (org-babel-prep-session:haskell): Remove obsoleted optional + third + + * ob-js.el: + (org-babel-expand-body:js): Remove obsoleted optional third + argument + (org-babel-execute:js): Remove obsoleted optional third argument + + * ob-latex.el: + (org-babel-expand-body:latex): Remove obsoleted optional third + argument + + * ob-lisp.el: + (org-babel-expand-body:lisp): Remove obsoleted optional third + argument + (org-babel-execute:lisp): Remove obsoleted optional third + argument + + * ob-mscgen.el: + (org-babel-expand-body:mscgen): Remove obsoleted optional third + argument + + * ob-ocaml.el: + (org-babel-expand-body:ocaml): Remove obsoleted optional third + argument + (org-babel-execute:ocaml): Remove obsoleted optional third + argument + + * ob-octave.el: + (org-babel-expand-body:matlab): Remove obsoleted optional third + argument + (org-babel-expand-body:octave): Remove obsoleted optional third + argument + (org-babel-execute:octave): Remove obsoleted optional third + argument + (org-babel-octave-variable-assignments): Remove obsoleted + optional third + + * ob-org.el: + (org-babel-expand-body:org): Remove obsoleted optional third + argument + + * ob-perl.el: + (org-babel-expand-body:perl): Remove obsoleted optional third + argument + (org-babel-execute:perl): Remove obsoleted optional third + argument + + * ob-plantuml.el: + (org-babel-expand-body:plantuml): Remove obsoleted optional + third argument + + * ob-python.el: + (org-babel-expand-body:python): Remove obsoleted optional third + argument + (org-babel-execute:python): Remove obsoleted optional third + argument + (org-babel-python-variable-assignments): Remove obsoleted + optional third + + * ob-ruby.el: + (org-babel-expand-body:ruby): Remove obsoleted optional third + argument + (org-babel-execute:ruby): Remove obsoleted optional third + argument + + * ob-sass.el: + (org-babel-expand-body:sass): Remove obsoleted optional third + argument + + * ob-scheme.el: + (org-babel-expand-body:scheme): Remove obsoleted optional third + argument + (org-babel-execute:scheme): Remove obsoleted optional third + argument + + * ob-screen.el: + (org-babel-expand-body:screen): Remove obsoleted optional third + argument + + * ob-sh.el: + (org-babel-expand-body:sh): Remove obsoleted optional third + argument + (org-babel-execute:sh): Remove obsoleted optional third argument + (org-babel-sh-variable-assignments): Remove obsoleted optional + third + + * ob-sql.el: + (org-babel-expand-body:sql): Remove obsoleted optional third + argument + + * ob-sqlite.el: + (org-babel-expand-body:sqlite): Remove obsoleted optional third + argument + (org-babel-execute:sqlite): Remove obsoleted optional third + argument + + * ob.el: + (org-babel-expand-body:generic): Remove obsoleted optional third + argument. + +2010-11-11 Eric Schulte + + * ob-clojure.el (org-babel-prep-session:clojure): Purging all + calls to removed org-babel-ref-variables. + +2010-11-11 Eric Schulte + + * ob-lob.el (org-babel-lob-ingest): Now returns the count of + ingested code blocks. + +2010-11-11 Eric Schulte + + * ob-exp.el (org-babel-exp-in-export-file): Wrapper for collecting + information from within the original export file. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-get-src-block-info): Small but crucial fix) + (this should return nil if not match found. + +2010-11-11 Eric Schulte + + * ob-emacs-lisp.el (org-babel-expand-body:emacs-lisp): Whitespace + (org-babel-execute:emacs-lisp): Whitespace. + +2010-11-11 Dan Davison + + * ob-sh.el (org-babel-sh-variable-assignments): Provide missing + docstring + + * ob-python.el (org-babel-python-variable-assignments): Provide + missing docstring. + +2010-11-11 Dan Davison + + * ob-octave.el (org-babel-expand-body:octave): Refactor: break + variable assignment part out into a separate function + (org-babel-octave-variable-assignments): New function constructing + list of variable assignment statements + (org-babel-prep-session:octave): Use new function + `org-babel-octave-variable-assignments' instead of previous + (incorrect) variable assignment code. + +2010-11-11 Dan Davison + + * ob-sh.el (org-babel-expand-body:sh): Refactor: break variable + assignment part out into a separate function + (org-babel-sh-variable-assignments): New function constructing + list of variable assignment statements + (org-babel-prep-session:sh): Use new function + `org-babel-sh-variable-assignments' instead of previous + (incorrect) variable assignment code. + +2010-11-11 Dan Davison + + * ob-python.el (org-babel-expand-body:python): Refactor: break + variable assignment part out into a separate function + (org-babel-python-variable-assignments): New function constructing + list of variable assignment statements + (org-babel-prep-session:python): Use new function + `org-babel-python-variable-assignments' instead of previous + (incorrect) variable assignment code. + +2010-11-11 Dan Davison + + * ob-R.el (org-babel-expand-body:R): Refactor: break variable + assignment part out into a separate function + (org-babel-R-variable-assignments): New function constructing list + of variable assignment statements + (org-babel-prep-session:R): Use new function + `org-babel-R-variable-assignments' instead of previous + (incorrect) variable assignment code. + +2010-11-11 Dan Davison + + * ob.el (org-babel-initiate-session): Better variable names. + +2010-11-11 Eric Schulte + + * ob.el (org-number-sequence): Declared + + * ob-R.el (org-number-sequence): Declared. + +2010-11-11 Dan Davison + + * ob.el (org-babel-map-src-blocks): Store correct value of + `end-block'. + +2010-11-11 Dan Davison + + * ob.el (org-babel-mark-block): New function to mark the body of a + src block in the style of `mark-defun'. + +2010-11-11 Carsten Dominik + + * org-compat.el (org-number-sequence): New function. + + * ob-R.el (org-babel-expand-body:R): Use `org-number-sequence'. + + * ob.el (org-babel-where-is-src-block-result): Use + `org-number-sequence'. + (org-babel-current-buffer-properties): Fix variable definition. + + * ob-ref.el (org-babel-ref-index-list): Use `org-number-sequence'. + + * ob-latex.el (org-babel-latex-tex-to-pdf): Use the 2-argument + version of `shell-command'. + + * org-latex.el (org-export-as-pdf): Use the 2-argument version of + `shell-command'. + +2010-11-11 Carsten Dominik + + * org-list.el (org-list-search-unenclosed-generic): Replace call + to booleanp. + +2010-11-11 Carsten Dominik + + * org.el (org-agenda-jump-prefer-future): New option. + + * org-agenda.el (org-agenda-goto-date): Use + `org-agenda-jump-prefer-future'. + +2010-11-11 Noorul Islam + + * org-latex.el (org-export-latex-links) : Replaced hard coded + hyperref format with custom variable + `org-export-latex-hyperref-format'. + +2010-11-11 Carsten Dominik + + * org.el (org-insert-heading): Fix docstring. + +2010-11-11 Carsten Dominik (tiny change) + + * org-capture.el (org-capture-place-entry): If the first line is + already a headline, just stay there. + +2010-11-11 Eric Schulte + + * ob-sh.el (org-babel-sh-evaluate): No longer assumes that results + are non-nil. + +2010-11-11 Carsten Dominik + + * org-ascii.el (org-ascii-replace-entities): Match an optional {} + after an entity. + +2010-11-11 Carsten Dominik + + * org-table.el (orgtbl-to-html): Apply `org-html-expand' to the + table fields. + +2010-11-11 Carsten Dominik + + * org.el (org-insert-heading): When on the headline of an inline + task, insert another inline tasks. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-tangle-collect-blocks): Only create + links for blocks that will actually tangle. + +2010-11-11 Eric Schulte + + * ob-sh.el (org-babel-expand-body:sh): Don't insert extra newlines + in expanded shell bodies. + +2010-11-11 Dan Davison + + * ob-sh.el (org-babel-expand-body:sh): Avoid inserting extra + newline characters. + +2010-11-11 Dan Davison + + * ob-sh.el (org-babel-expand-body:sh): Align code. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-params-from-properties): Max line with at <=80 + +2010-11-11 Eric Schulte + + * org-latex.el (org-export-latex-listings-langs): Clojure is now + recognized as a lisp. + +2010-11-11 Dan Davison + + * ob.el (org-babel-params-from-properties): Use `org-babel-read' + to interpret property as header argument value. + +2010-11-11 Dan Davison + + * ob.el (org-babel-parse-header-arguments): Simplify reading of + header arg value. + +2010-11-11 Carsten Dominik + + * org-publish.el (org-publish-org-to-ascii): + (org-publish-org-to-latin1): + (org-publish-org-to-utf8): New functions. + +2010-11-11 Carsten Dominik + + * org.el (org-insert-heading): Skip inline tasks when trying to + insert a new heading after the end of the subtree. + +2010-11-11 Carsten Dominik + + * org-inlinetask.el (org-inlinetask-min-level): Set customization + type to integer or nil. + + * org.el (org-insert-heading): When after an inline task, do not + use level but go back to headline level before the inline task. + +2010-11-11 Carsten Dominik + + * org-inlinetask.el (org-inlinetask-in-task-p): New function. + + * org.el (org-indent-line-function): Fix indentation of inline + tasks. + +2010-11-11 Carsten Dominik + + * org.el (org-activate-links): Fix customize type. + +2010-11-11 Carsten Dominik + + * org-latex.el (org-latex-to-pdf-process): Add rubber as another + default option. + +2010-11-11 Dan Davison + + * org-latex.el (org-export-latex-minted): Document pygments + dependency. + +2010-11-11 Carsten Dominik + + * org-mobile.el (org-mobile-create-index-file): Encrypt the index + file if encryption has been turned on. + (org-mobile-copy-agenda-files): Avoid double encryption of + `mobileorg.org'. + +2010-11-11 Dan Davison + + * org-exp.el (org-export-latex-minted-with-line-numbers): Ensure + that variable is declared. + +2010-11-11 Eric Schulte + + * ob-python.el (org-src-preserve-indentation): Fixed compiler + warning. + +2010-11-11 Dan Davison + + * org-exp.el (org-export-format-source-code-or-example): Latex + formatting of source code blocks using the minted package + (org-export-plist-vars): Add :latex-minted property + (org-export-latex-minted): Ensure variable is defined + (org-export-latex-minted-langs): Ensure variable is defined. + +2010-11-11 Carsten Dominik + + * org-src.el (org-edit-src-code): Use `org-region-active-p'. + +2010-11-11 Dan Davison + + * ob-tangle.el (org-babel-spec-to-string): Whitespace changes. + +2010-11-11 Dan Davison + + * ob-tangle.el (org-babel-spec-to-string): Don't trim whitespace + when `org-src-preserve-indentation' is non-nil. + +2010-11-11 Dan Davison + + * ob-lob.el (org-babel-lob-ingest): Provide message stating number + of blocks added to Library of Babel. + +2010-11-11 Dan Davison + + * ob-lob.el (org-babel-lob-ingest): Check for nil source block + name. + +2010-11-11 Carsten Dominik + + * org-beamer.el (org-beamer-place-default-actions-for-lists): Fix + typo in regexp. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-toggle-checkbox): Avoid some boundary error + when inserting a checkbox in an empty last item of a list. + +2010-11-11 David Maus + + * org-gnus.el (org-gnus-nnimap-query-article-no-from-file): Query + article number from file is nil by default. + +2010-11-11 Stephen Eglen + + * org-beamer.el (org-beamer-amend-header): Fix typo in docstring. + +2010-11-11 Carsten Dominik + + * org-capture.el (org-capture-place-entry): Move to `beg' before + searching for `%?'. + +2010-11-11 Carsten Dominik + + * org.el (org-format-latex): Fix mathjax treatment of single + letters in between dollars. + +2010-11-11 Sébastien Vauban + + * org-latex.el (org-latex-to-pdf-process): Add a third pdflatex + run. + +2010-11-11 Carsten Dominik + + * org.el (org-blank-before-new-entry): Improve docstring. + +2010-11-11 Carsten Dominik + + * org-mobile.el (org-mobile-force-id-on-agenda-items): Fix + docstring. + (org-mobile-write-agenda-for-mobile): Use outline path if we do + not have an ID and are not allowed to make one. + (org-mobile-get-outline-path-link): New function. + +2010-11-11 Carsten Dominik + + * org-mobile.el (org-mobile-copy-agenda-files): Encrypt the empty + file. + (org-mobile-write-agenda-for-mobile): Use the right name, even if + the file get encrypted. + (org-mobile-move-capture): Only delete tempfile if it does exist. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-number-p): Fixed documentation string. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-tangle-collect-blocks): Accepting + "tangle" as a positive argument for the :noweb header argument + during tangling. + +2010-11-11 Eric Schulte + + * ob-exp.el (org-babel-exp-src-blocks): Fixed export when headings + have links, with tests. + +2010-11-11 Sebastian Rose, Hannover, Germany + + * org-test-which-func: New function. Find name of defun around + point. + +2010-11-11 Carsten Dominik + + * org-latex.el (org-latex-to-pdf-process): Use texi2dvi if + available. + (org-export-latex-get-error): New function. + (org-export-as-pdf): Give an indication of the errors that + happened during processing. + +2010-11-11 Åukasz Stelmach + + * org-exp.el (org-export-language-setup): Fix Polish entries. + +2010-11-11 Carsten Dominik + + * org.el (org-set-tags): Allow comma as a separator when + specifying tags at the completion interface. + (org-tags-completion-function): Allow comma as a separator when + specifying tags at the completion interface. + +2010-11-11 Eric Schulte + + * ob-exp.el (org-babel-exp-src-blocks): Don't jump back to + export-file if exporting from a buffer which is not visiting a + file. + +2010-11-11 Eric Schulte + + * ob-exp.el (org-babel-exp-src-blocks): Only append "::" to a file + name in link construction if there is a heading to follow it. + +2010-11-11 Carsten Dominik + + * org-html.el (org-export-html-inline-image-extensions): Add "svg" + as an allowed extension. + +2010-11-11 Sébastien Vauban + + * org-agenda.el (org-agenda-add-time-grid-maybe): Pad clock times + with zeros. Start applying face earlier. + +2010-11-11 Eric Schulte + + * ob.el (or): Don't create org-babel-temporary-directory in batch + as it won't be removed by emacs-kill-hook + (org-babel-remove-temporary-directory): Only try to remove this + directory if it exists. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-temporary-directory): Fixing byte-compilation + warning in ob.el. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-tangle): Now sharing the file name in + the tangling message. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-load-languages): Fixes compiler warning. + +2010-11-11 Eric Schulte + + * ob-plantuml.el (org-babel-execute:plantuml): Fixes bug with svg + output. + +2010-11-11 Carsten Dominik + + * org-ascii.el (org-export-as-ascii): Use the correct match group. + +2010-11-11 Eric Schulte + + * ob.el (boundp): Uncommenting defvar form for + org-babel-temporary-directory + (org-babel-temp-file): Now using the org-babel-temporary-directory + for holding new babel temporary files + (org-babel-remove-temporary-directory): Removes the babel temp dir + when Emacs shutsdown + (kill-emacs-hook): Now removing the babel temp dir on Emacs + shutdown. + +2010-11-11 Carsten Dominik + + * org-capture.el (org-capture-fill-template): Initialize history + variable. + +2010-11-11 Dan Davison + + * org-src.el (org-edit-src-code): Don't move point when generating + edit buffer. + +2010-11-11 Dan Davison + + * org-src.el (org-edit-src-code): Deal with point being in + #+end_src line. + +2010-11-11 Carsten Dominik + + * org-table.el (org-table-current-column): Add interactive to turn + this into a command. + +2010-11-11 Bernt Hansen + + * org.el (org-insert-heading): Run org-insert-heading-hook when + creating the first heading in a file. + +2010-11-11 Carsten Dominik + + * org.el (org-startup-with-inline-images): New option. + (org-startup-options): Add new keywords inlineimages and + noinlineimages. + (org-mode): Inline images when this has been configured. + +2010-11-11 Dan Davison + + * ob.el (org-babel-get-src-block-info): Remove optional + HEADER-VARS-ONLY argument; further simplification. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-confirm-evaluate): Fixed bug causing extra + prompt in ob-confirm-evaluate in some cases. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-demarcate-block): Visible region and completion + during language selection. + +2010-11-11 Dan Davison + + * ob.el (org-babel-get-src-block-info): Remove comment. + +2010-11-11 Dan Davison + + * ob.el (org-babel-get-src-block-info): Simplify function. + +2010-11-11 Dan Davison + + * ob.el (org-babel-get-src-block-info): Form info list correctly + when parenthesised arguments are missing. + +2010-11-11 Dan Davison + + * ob-exp.el (org-export-babel-evaluate): Docstring typo + (org-babel-exp-code): Docstring typo. + +2010-11-11 Carsten Dominik + + * org-mobile.el (org-mobile-encryption-password): Improve + docstring. + (org-mobile-encryption-password-session): New variable. + (org-mobile-encryption-password): New function. + (org-mobile-check-setup): + (org-mobile-encrypt-file): + (org-mobile-decrypt-file): Use the new function. + +2010-11-11 David Maus + + * org-capture.el (org-capture-place-template): Widen to remove + possible restrictions in target buffer. + +2010-11-11 Jambunathan K + + * org.el (org-speed-command-hook): Added org-speed-command-hook + (org-babel-speed-command-hook): Hook for Babel's speed commands. + +2010-11-11 Dan Davison + + * ob.el (org-babel-execute-buffer): Re-implement using + `org-babel-map-src-blocks'. + +2010-11-11 David Maus + + * org-capture.el (org-capture-templates): Update doc string with + new message date related escapes. + +2010-11-11 David Maus + + * org-wl.el (org-wl-store-link-message): Define properties %:date) + (%:date-timestamp, and %:date-timestamp-inactive. + + * org-mew.el (org-mew-store-link): Dto. + + * org-mhe.el (org-mhe-store-link): Dto. + + * org-rmail.el (org-rmail-store-link): Dto. + + * org-vm.el (org-vm-store-link): Dto. + +2010-11-11 David Maus + + * org-wl.el (org-wl-message-field): Always get literal content of + header fields. + +2010-11-11 David Maus + + * org-gnus.el (org-gnus-store-link): Define properties + %:date-timestamp and %:date-timestamp-inactive. + +2010-11-11 David Maus + + * org-gnus.el (org-gnus-store-link): Handle empty date header + field. + +2010-11-11 Jambunathan K (tiny change) + + * org.el (org-speed-command-hook): New. Hook for installing + additional speed commands. Use this for enabling speed commands on + src blocks. + (org-speed-command-default-hook): The default hook for + org-speed-command-hook. Factored out from org-self-insert-command + and mimics existing behaviour. + (org-self-insert-command): Modified to use org-speed-command-hook. + +2010-11-11 Carsten Dominik + + * org-agenda.el (org-search-view): Recover spaces in search words + if they were escaped with \ or inside a regexp. + +2010-11-11 Carsten Dominik + + * org.el (org-additional-option-like-keywords): Add PROPERTIES to + the list of completable meta line words. + (org-complete): Complete property names after #+PROPERTY. + +2010-11-11 Dan Davison + + * ob-python.el (org-babel-python-evaluate-session): Make temp file + names consistent. + +2010-11-11 Dan Davison + + * ob-clojure.el (org-babel-clojure-evaluate-external-process): + Delete extra format argument. + +2010-11-11 Dan Davison + + * ob-org.el (org-babel-org-export): Typo in docstring. + +2010-11-11 Dan Davison + + * ob-sh.el (org-babel-sh-evaluate): Remove unused temporary file + variable. + +2010-11-11 Dan Davison + + * ob-scheme.el (org-babel-execute:scheme): Alter temp file name. + +2010-11-11 Dan Davison + + * ob.el (org-babel-process-file-name): New function + (org-babel-maybe-remote-file): Delete function. + +2010-11-11 Dan Davison + + * ob-C.el (org-babel-C-execute): Remove unused variable. + +2010-11-11 David Maus + + * org.el (org-make-link-string): Prevent superfluous colon. + +2010-11-11 David Maus + + * org.el (org-make-org-heading-search-string): Leave headline + intact. + +2010-11-11 David Maus + + * org.el (org-make-link-string): Don't escape characters in link + type. + +2010-11-11 Bastien Guerry + + * org-capture.el (org-capture-templates): Update docstring to + advertize %:org-date. + +2010-11-11 Eric Schulte + + * ob-dot.el (org-babel-execute:dot): Automatically specifies + "-T" based on file name extension. + +2010-11-11 Eric Schulte + + * ob-org.el (org-babel-org-export): Raise error on nested export + call. + +2010-11-11 Eric Schulte + + * ob-plantuml.el (org-babel-execute:plantuml): Support for svg + output files. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-demarcate-block): Better initialization of + stars. + +2010-11-11 Dan Davison + + * org-src.el (org-src-tab-acts-natively): Add customize interface. + +2010-11-11 Dan Davison + + * org-src.el (org-src-strip-leading-and-trailing-blank-lines): New + variable allowing prevention of automatic stripping of leading and + trailing blank lines when exiting edit buffer. + (org-edit-src-exit): Respect value of + `org-src-strip-leading-and-trailing-blank-lines' + (org-src-native-tab-command-maybe): Bind + `org-src-strip-leading-and-trailing-blank-lines' to nil during + this function. + +2010-11-11 Dan Davison + + * org-src.el (org-edit-src-code): If mark was inside code block + then code edit buffer inherits mark with active region. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-demarcate-block): Fix compiler warnings. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-demarcate-block): Better handling of empty + space around demarcated area. + +2010-11-11 Carsten Dominik + + * org-agenda.el (org-agenda-goto-date): Turn off prefer future for + this command. + +2010-11-11 David Maus + + * org-gnus.el (org-gnus-open-nntp): New function. + +2010-11-11 David Maus + + * org-wl.el (org-wl-open-nntp): New function. + +2010-11-11 David Maus + + * org-wl.el (org-wl-open): Open message by numeric reference if + article part is not a message id. + +2010-11-11 Carsten Dominik + + * org-agenda.el (org-agenda-filter-apply): Move cursor to a + visible line. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-demarcate-block): Interactive demarcation of + code blocks + + * ob-keys.el (org-babel-key-bindings): Key bindings for block + demarcation. + +2010-11-11 Bastien Guerry + + * org.el (org-link-types): Add the "message" link type. + +2010-11-11 David Maus + + * org.el (org-link-types): Add 'message:' link type to default + link types. + +2010-11-11 Bastien Guerry + + * org-gnus.el (org-gnus-store-link): Add the :date property to + gnus links, allowing the use of %:date in capture templates. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-cycle-list-bullet): Follow order of bullets + indicated in doc-string. + + * org-list.el (org-list-bottom-point-with-indent): List is ended + when a line is less indented that the last item, not the less + indented item. + +2010-11-11 Eric Schulte + + * ob-exp.el (org-babel-exp-src-blocks): Now switching back to the + original file before resolving code block parameters to ensure + headline and buffer wide parameters are taken into consideration + when only a narrowed portion of the file is exported. + +2010-11-11 Carsten Dominik + + * org.el (org-forward-same-level): Fix docstring. + +2010-11-11 Sebastian Rose + + * org-publish.el (org-publish-attachment): Put the attachment into + the right directory. + +2010-11-11 Jambunathan K (tiny change) + + * org.el (org-goto-first-child): New command. + +2010-11-11 Matt Lundin + + * org-agenda.el (org-prepare-agenda): If the agenda is called from + within the agenda via an elisp link, such as + [[elisp:(org-agenda-list)]], org-prepare-agenda erases the buffer + of the file containing the link, since that buffer is current + during org-prepare agenda (due to a with-current-buffer in + org-agenda-open-link). An additional test now ensures that the + agenda buffer is in fact current when the buffer is erased and + local variables for the agenda are set. + +2010-11-11 David Maus (tiny change) + + * org-exp.el (org-infile-export-plist): Define property macro. + +2010-11-11 David Maus + + * org-mhe.el (org-mhe-get-header): Remove possible folding white + space in message header field. + +2010-11-11 David Maus + + * org-feed.el (org-feed): Fix typo in customization group :tag + property. + +2010-11-11 Carsten Dominik + + * org-latex.el (org-export-latex-tag-markup): New option. + (org-export-latex-keywords-maybe): Use + `org-export-latex-tag-markup'. + +2010-11-11 Rémi Vanicat + + * org-icalendar.el (org-icalendar-use-UTC-date-time): New option. + (org-ical-ts-to-string): Use UTC time when requested. + +2010-11-11 Noorul Islam (tiny change) + + * org-html.el (org-html-cvt-org-as-html): Do not convert protocol + from 'file' to 'http'. + +2010-11-11 David Maus + + * org.el (org-store-log-note): Fix wrong usage + of`org-adapt-indentation'. + +2010-11-11 Nicolas Goaziou + + * org.el (org-skip-over-state-notes): Do not compute bottom point + at each item. + + * org-mouse.el (org-mouse-for-each-item): Use `org-apply-on-list' + instead of moving to each item. + +2010-11-11 David Maus + + * org-capture.el (org-capture-templates): Small fix in doc string. + +2010-11-11 aaa bbb + + * org-archive.el (org-get-local-archive-location): Use + `org-carchive-location' as default. + +2010-11-11 Eric Schulte + + * ob-C.el (org): No longer requires org + + * ob-ledger.el (org): No longer requires org. + +2010-11-11 David Maus + + * org.el (org-priority): Save match data before call to + `read-char-exclusive'. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-to-generic): Descriptions labels can be + any suit of symbols, and will end at double colons. + +2010-11-11 Nicolas Goaziou + + * org.el (org-indent-line-function): Indent past [@num] and + [@start:num], consistently with what is already done with + checkboxes. + +2010-11-11 Nicolas Goaziou + + * org.el (org-store-log-note): Indent new notes to the right + column. Also take `org-list-two-spaces-after-bullet-regexp' into + consideration when creating the note. + +2010-11-11 David Maus + + * org-gnus.el (nnimap-group-overview-filename): Declare function + to silence byte compiler. + +2010-11-11 David Maus + + * org-gnus.el (org-gnus-nnimap-query-article-no-from-file): New + customization variable. + (org-gnus-nnimap-cached-article-number): New function. + (org-gnus-follow-link): Try to fetch cached article number of + message-id. + +2010-11-11 Eric Schulte + + * ob-org.el (org-babel-org-default-header): Used to insert a dummy + first line into code blocks before export so that the first line + is not interpreted as a title + (org-babel-org-export): Use new dummy code block prefix. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-insert-result): No longer throws error when + inserting an empty result. + +2010-11-11 Eric Schulte + + * ob-tangle.el: autoload org-babel-tangle-lang-exts from ob-tangle. + +2010-11-11 Dan Davison + + * ob.el (org-babel-do-in-edit-buffer): Use + `org-babel-where-is-src-block-head' to test for source block at + point. + +2010-11-11 Eric Schulte + + * ob-keys.el (org-babel-key-bindings): Adding key-binding for + `org-babel-goto-src-block-head' + + * ob.el (org-babel-goto-src-block-head): Jump to the head of the + current code block. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-next-src-block): Now raising more informative + error when no further code blocks can be found + (org-babel-previous-src-block): Now raising more informative error + when no previous code blocks can be found. + +2010-11-11 Eric Schulte + + * org-exp-blocks.el + (org-export-preprocess-after-include-files-hook): Now using this + hook instead of `org-export-preprocess-hook'. + +2010-11-11 Eric Schulte + + * ob-plantuml.el (org-babel-execute:plantuml): + +2010-11-11 Dan Davison + + * ob-python.el (org-babel-python-evaluate): Refactor as call to + either `org-babel-python-evaluate-external-process' or + `org-babel-python-evaluate-session'. + (org-babel-python-evaluate-external-process): New function to + handle evaluation in external process. + (org-babel-python-evaluate-session): New function to handle + evaluation in emacs inferior process. + +2010-11-11 Eric Schulte + + * ob-org.el (org-babel-execute:org): Evaluates body to latex ascii + or html respecting :results header arg + (org-babel-org-export): Exports a string of text to an output + format. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-insert-result): Remove existing results when + nil results are returned. + +2010-11-11 David Maus + + * org-ascii.el (org-export-as-ascii): Bind and set link path for + link type specific markup function. + +2010-11-11 David Maus + + * org-clock.el (notifications-notify): Properly declare function + to silence byte compiler. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-insert-item): Check invisibility of point at a + meaningful location. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-insert-item-generic): Updating checkboxes + can modifiy bottom point of a list, so make it a marker before + calling `org-update-checkbox-count-maybe'. + +2010-11-11 Dan Davison + + * org.el (org-src-fontify-natively): Set to nil by default. + Supply cutomize interface. + +2010-11-11 Bastien Guerry + + * org-ascii.el (org-export-as-ascii): Fix bug in ASCII export: use + `org-bracket-link-analytic-regexp++' to match the link type. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-tangle-collect-blocks): Rename `lang' to + `language'. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-tangle-comment-format-beg): Format + string specifying the link-comment preceding a code block + (org-babel-tangle-comment-format-end): Format string specifying + the link-comment following a code block + (org-babel-tangle-collect-blocks): Storing more information in the + spec of a tangling code block + (org-babel-spec-to-string): Now makes use of customizable + link-comment formats. + +2010-11-11 Achim Gratz (tiny change) + + * org.el (org-delete-backward-char): Check for nil overwrite-mode + before inserting spaces. + +2010-11-11 David Maus + + * org-icalendar.el (org-print-icalendar-entries): Exclude tags + from summary of non-TODO ical entries. + (org-print-icalendar-entries): Use `org-complex-heading-regexp' to + exclude tags from summary of TODO ical entries. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-map-src-blocks): Now exposes much information + about the code block in the form of let-bound local variables. + +2010-11-11 David Maus + + * org-list.el (org-outline-regexp, org-ts-regexp) + (org-ts-regexp-both, org-in-regexps-block-p) + (org-level-increment, org-at-heading-p) + (outline-previous-heading, org-icompleting-read) + (org-time-string-to-seconds): Declare to fix compiler warning. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-toggle-checkbox): Ignore items in drawers when + used from an heading. Send an error when no item is in region. + +2010-11-11 Dan Davison + + * ob.el (org-babel-do-in-edit-buffer): Use unwind-protect to + ensure that edit buffer is exited. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-tangle-pad-newline): Can be used to + control the amount of extra newlines inserted into tangled code + (org-babel-tangle-collect-blocks): Now conditionally collects + information to be used for "org" style comments + (org-babel-spec-to-string): Now inserts "org" style comments, and + obeys the newline configuration variable when inserting whitespace. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-pre-tangle-hook): Defines new tangle + hook + (org-babel-tangle): Calls new tangle hook. + +2010-11-11 Carsten Dominik + + * org-capture.el (org-capture): Compute the length of the correct + string when removing properties. + +2010-11-11 Eric Schulte + + * ob-plantuml.el (org-babel-execute:plantuml): Now expanding file + names before shell quoting. + +2010-11-11 Dan Davison + + * org-src.el (org-src-tab-indents-natively): New variable + controlling whether language-native TAB action should be performed + (org-src-native-tab-command-maybe): New function to perform + language-native TAB action. + (org-tab-first-hook): Add `org-src-native-tab-command-maybe'. + +2010-11-11 Eric Schulte + + * ob-plantuml.el (org-babel-execute:plantuml): Explicitly check + `org-plantuml-jar-path' before use. + +2010-11-11 Dan Davison + + * org-src.el (org-src-font-lock-fontify-block): Re-use hidden + language major mode buffers during fontification. + +2010-11-11 Dan Davison + + * org.el (org-fontify-meta-lines-and-blocks): Alter main regexp to + match code blocks with switches and header args. Call + `org-src-font-lock-fontify-block' for automatic fontification of + code in code blocks, controlled by variable + `org-src-fontify-natively'. + (org-src-fontify-natively): New variable. + +2010-11-11 Eric Schulte + + * ob-ruby.el (org-babel-expand-body:ruby): Removed requirement of + inf-ruby. + +2010-11-11 Noorul Islam (tiny change) + + * org-html.el (org-html-make-link): (Expand-file-name ) removes + one "/" from "///path-to-file", so add one. Anything other than + 'file' type should be exported along with the type. + +2010-11-11 Noorul Islam (tiny change) + + * org.el (org-insert-subheading) : Fix compiler warning + (org-insert-todo-subheading) : Fix compiler warning. + +2010-11-11 Carsten Dominik + + * org-capture.el (org-capture): Remove read-only text properties + from capture text. + (org-capture-set-target-location): Throw an error if file+headline + target does not point into a file which is in Org mode. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-map-src-blocks): Prefer `when' to `if'. + +2010-11-11 Dan Davison + + * org-src.el (org-edit-src-code): Improve docstring. + +2010-11-11 Dan Davison + + * ob.el (org-babel-execute-src-block): Document prefix argument in + docstring. + +2010-11-11 Eric Schulte + + * ob-ditaa.el (org-babel-execute:ditaa): Now expanding + org-ditaa-jar-path with expand-file-name. + +2010-11-11 Dan Davison + + * ob.el (org-babel-execute-subtree): Pass prefix arg through to + `org-babel-execute-src-block'. + +2010-11-11 Nicolas Goaziou + + * org-ascii.el (org-export-ascii-preprocess): Allow [@start:x] and + [@x] syntax for list numbering. + +2010-11-11 Nicolas Goaziou + + * org.el (org-indent-line-function): Indentation of source block + is left to `org-edit-src-exit' and shouldn't be modified by + `org-indent-line-function'. Indentation of others blocks should be + the same as the #+begin line. + +2010-11-11 Dan Davison + + * ob.el (org-babel-map-src-blocks): If FILE is nil evaluate BODY + forms on source blocks in current buffer; restore point in current + buffer. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-struct): Accept list boundaries as an + argument in order to avoid computing `org-list-top-point' and + `org-list-bottom-point' twice when indenting. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-ending-method): Default value is now + `both', to ensure maximum compatibility before previous + implementation. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-in-item-p-with-indent): Test if first line + is the item beginning. + + * org-list.el (org-list-top-point-with-indent): Test if first line + is a valid list beginning. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-ending-method): New customizable variable + to tell Org Mode how lists end. See docstring. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-indent-item-tree): Shifting step of top-level + item depends on `org-level-increment'. + +2010-11-11 Nicolas Goaziou + + * org.el (org-indent-line-function): Indent first non blank line + after a list according to current heading level. + +2010-11-11 Nicolas Goaziou + + * org-docbook.el (org-export-as-docbook): Removed check for + indentation on lines that do not start with a list bullet. + + * org-html.el (org-export-as-html): Same thing. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-bottom-point): Take into consideration + that bound of search can be before true ending of the list. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-struct-apply-struct): No longer shift + item's body twice: one after replacing bullet and one after + changing indentation. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-struct-indent): Added code to replace + bullets if needed when indenting. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-insert-item-generic): A single item + already counting blank lines in his body should be separated with + the next one by a blank line. Moreover, if user already provided + blank lines, follow his wishes. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-indent-item-tree): When moving top item of a + *-list to column 0, only the first item had its bullet changed to + -. It now changes all items of the top-level list, as expected. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-toggle-checkbox): Go to beginning of line + before processing. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-struct-apply-struct): Check if ancestor + exists. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-renumber-ordered-list): Check for [@start:x] is + done at each item. + +2010-11-11 Nicolas Goaziou + + * org-list.el : Removed unused variable + `org-suppress-item-indentation'. + + * org-list.el (org-renumber-ordered-list): Skip item if bullet + number is already good. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-automatic-rules): Doc-string reflects this + change. + + * org-list.el (org-indent-item-tree): Prevent whole list from + being moved when user is not moving subtree. Thus) + (`org-cycle-item-indentation' will not allow to move the list. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-indent-item-tree): Removed region code. It was + prone to errors and undocumented. + + * org-list.el (org-item-indent-positions): Better heuristics to + determine what bullet the item will have when demoted. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-bullet-string): First check if + `org-list-two-spaces-after-bullet-regexp' isn't nil. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-bullet-string): Do not modify match-data. + + * org.el (org-toggle-item): Now working again when changing list + items into plain text. Moreover take into consideration + `org-list-two-spaces-after-bullet-regexp'. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-indent-item-tree): Removed unnecessary bullets + fix, and improved heuristics to determine bullet when indenting. + + * org-list.el (org-item-indent-positions): Function now returns + sane results when there are two lists separated with blank lines + only. + +2010-11-11 Nicolas Goaziou + + * org-docbook.el (org-export-as-docbook): Use override="num" in + any listitem matching [@start:num] + + * org-html.el (org-export-as-html): Use value="num" in any li + matching + [@start:num] + +2010-11-11 Nicolas Goaziou + + * org.el (org-set-font-lock-defaults): Correct fontification for + checkboxes found after [@start:?]. + + * org-list.el (org-list-at-regexp-after-bullet-p): Skip any + [@start:?] when looking at a regex after a bullet. + + * org-list.el (org-toggle-checkbox): Correct insertion of + checkboxes when there is already a [@start:?] in the item. + + * org-list.el (org-checkbox-blocked-p): Properly check if there's + an unchecked item before. + + * org-list.el (org-list-parse-list): Function handles items having + both a counter and a checkbox. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-cycle-item-indentation): Org-tab-ind-state + stores both indentation and bullet when cycle started. + +2010-11-11 Nicolas Goaziou + + * org-list.el: `org-at-description-p' renamed to + `org-at-item-description-p', `org-first-list-item-p' renamed to + `org-list-first-item-p', `org-end-of-item-text-before-children' + renamed to `org-end-of-item-or-at-child'. + +2010-11-11 Nicolas Goaziou + + * org.el (org-ctrl-c-ctrl-c): Call `org-fix-bullet-type' instead + of `org-maybe-renumber-ordered-list' and `org-fix-bullet-type' + before toggling a checkbox. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-bullet-string): New function returning + bullet concatenated with an appropriate number of white spaces. + + * org-list.el (org-list-insert-item-generic): Insert the right + bullet, with help of `org-list-bullet-string'. + + * org-list.el (org-indent-item-tree): Use + `org-list-bullet-string'. + + * org-list.el (org-fix-bullet-type): Use `org-list-bullet-string'. + + * org-list.el (org-toggle-checkbox): Send an error when + `org-toggle-checkbox' is trying to insert a checkbox at a + description item. + + * org-list.el (org-item-re): Modified regexp so it can catch + correct number of white space before item body. + + * org-list.el (org-list-at-regexp-after-bullet-p): Take into + consideration new `org-item-re'. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-insert-item-generic): The second item in a + list will be separated from its predecessor with the number of + blank lines separating the first item from its parent, if any, or + no blank line. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-indent-item-tree): Fix and reorder every list + and sublist, from parent of list that has moved if indenting, or + from list at point if outdenting. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-indent-item-tree): Try to keep relative + position on line. It can't if point is in white spaces before + bullet because mixed tabs and spaces make some columns + unattainable. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-cycle-item-indentation): Cycle when the whole + item only contains bullet and maybe a checkbox. Previously, TAB + would cycle when the first line of the item was blank. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-cycle-item-indentation): Allow a point just + after a description item or a checkboxed item to start cycling. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-cycle-list-bullet): Check + `org-plain-list-ordered-item-terminator' before allowing 1. or 1) + as valid bullets when cycling. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-cycle-item-indentation): Do return t if and + only if cycling is possible and succeded. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-indent-item-tree): When outdenting a subtree, + the last item shouldn't have a children. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-cycle-item-indentation): Cycling should play + nicely with indent rule in `org-list-automatic-rules'. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-indent-item-tree): If indent rule is activated, + it should be impossible to outdent an item having children without + moving its subtree. Improved reordering of lists modified by + cycling indentation. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-maybe-renumber-ordered-list): Removed call for + `org-fix-bullet-type' to prevent infinite loop, and some checks + already done in `org-renumber-ordered-list'. + + * org-list.el (org-fix-bullet-type): Remove a check and call + directly `org-maybe-renumber-ordered-list'. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-indent-item-tree): It shouldn't be possible to + indent the first item of a sublist (though outdent is possible) as + it would break list's structure. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-insert-item-generic): When local search + doesn't help, search the list globally for blank lines. Moreover, + don't bother with new lists, and add 1 blank line. + +2010-11-11 Nicolas Goaziou + + * org-capture.el (org-capture-place-item): Use + `org-search-forward-unenclosed' and + `org-search-backward-unenclosed' and new variable + `org-item-beginning-re'. + + * org-list.el (org-item-beginning-re): Regexp matching beginning + of an item. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-cycle-list-bullet): Put back support for + 'previous argument. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-in-item-p): Handle case when point is at an + heading. + + * org-list.el (org-list-make-subtree): Add protection when used + outside of list + + * org-list.el (org-insert-item): Removed useless hack now + `org-in-item-p' is fixed. + + * org-timer.el (org-timer-item): Removed useless hack now + `org-in-item-p' is fixed. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-cycle-list-bullet): Prevent description items + from being numbered. String argument is also recognized now, as + long as it is a valid bullet. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-indent-item-tree): Moving indentation of top + list item will make the whole list move. + + * org-list.el (org-apply-on-list): Function is less sensitive to + changes of indentation. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-at-item-checkbox-p): Add whitespaces at the end + of the regexp. + + * org-list.el (org-checkbox-blocked-p): Use new checkbox regexp. + + * org-list.el (org-cycle-item-indentation): Allow cycling + description items and checkbox items. + + * org-list.el (org-toggle-checkbox): Use new checkbox regexp. + + * org-list.el (org-reset-checkbox-state-subtree): Use new checkbox + regexp. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-insert-item-internal): Guessing of blank lines + number is made by looking at neighbours items, if any. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-sort-list): Add the possibility to sort timer + lists with the ?t or ?T options. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-search-unenclosed-internal): New function to + handle both `org-search-forward-unenclosed' and + `org-search-backward-unenclosed'. + + * org-list.el (org-search-backward-unenclosed): Can send errors + now. Removed useless usage of COUNT. + + * org-list.el (org-search-forward-unenclosed): Can send errors + now. Removed useless usage of COUNT. + + * org-list.el (org-update-checkbox-count): Use + `org-search-forward-unenclosed' and + `org-search-backward-unenclosed' instead of `re-search-forward' + and `re-search-backward'. + + * org-list.el (org-sort-list): Use `org-search-forward-unenclosed' + and `org-search-backward-unenclosed' instead of + `re-search-forward' and `re-search-backward'. + + * org-list.el (org-list-make-subtree): Use + `org-search-forward-unenclosed' and + `org-search-backward-unenclosed' instead of `re-search-forward' + and `re-search-backward'. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-insert-item-internal): Fixes the problem when + point was before the first char of the item's body. + +2010-11-11 Nicolas Goaziou + + * org-timer.el (org-timer-item): Refactoring. Compute timer string + before inserting it in the buffer + + * org-timer.el (org-timer): Added an optional argument to return + timer string instead of inserting it. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-insert-item-internal): New function to handle + positionning and contents of an item being inserted at a specific + pos. It is not possible anymore to split a term in a description + list or a checkbox when inserting a new item. + + * org-list.el (org-insert-item): Refactored by using the new + `org-insert-item-internal' function. + + * org-timer.el (org-timer-item): Refactored by using the new + `org-insert-item-internal' function. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-bottom-point): Be sure to check real + ORG-OUTLINE-REGEXP and not outline-regexp, that might be modified. + + * org.el (org-cycle-internal-local): Cycle up to end of subtree or + end of item if we are in a list. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-insert-item): Move before any special block in + a list prior to add a new item. + + * org-timer.el (org-timer-item): When in a timer list, insert a + new timer item like `org-insert-item'. If in another list, send an + error. Otherwise, start a new timer list. + +2010-11-11 Nicolas Goaziou + + * org-list.el: Minor refactoring. + +2010-11-11 Nicolas Goaziou + + * org-timer.el (org-timer-item): Insert description list item at + the right column. + + * org-list.el (org-insert-item): Insert the right number of blank + lines before a relative timer. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-insert-item): Remove restriction on latex + blocks. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-search-backward-unenclosed): Do not stop in + protected places. + + * org-list.el (org-search-forward-unenclosed): Do not stop in + protected places. + + * org-latex.el (org-export-latex-lists): Use the fact that + org-search-forward do not stop anymore at protected places. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-search-backward-unenclosed): Do not prevent + list items from being inside LaTeX blocks. + + * org-list.el (org-search-forward-unenclosed): Do not prevent list + items from being inside LaTeX blocks. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-in-item-p): Do not widen before checking if we + are in item. + + * org-list.el (org-list-send-list): We cannot count on + `org-list-top-point' and `org-list-bottom-point' before buffer is + narrowed. Find bounds of list otherwise. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-end-regexp): By default, list ending is + exactly 2 blank lines. + +2010-11-11 Nicolas Goaziou + + * org-docbook.el (org-export-as-docbook): When we find an empty + line, we do not need to check for + `org-empty-line-terminates-plain-lists' because we would have + found end-list marker before. + + * org-html.el (org-export-as-html): Same. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-insert-item): Simplify count of blank lines to + insert. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-end-regexp): New customizable variable to + define what string should end lists. + + * org-list.el (org-list-end-re): Function is now aware of + `org-list-end-regexp'. + +2010-11-11 Nicolas Goaziou + + * org-html.el (org-export-as-html): Code cleanup. + +2010-11-11 Nicolas Goaziou + + * org-docbook.el (org-export-as-docbook): Properly close any open + list when seeing ORG-LIST-END. Removed any reference to now + unneeded DIDCLOSE variable. + +2010-11-11 Nicolas Goaziou + + * org-exp.el (org-export-mark-list-ending): Fix number of blank + lines inserted after a list. + + * org-list.el (org-list-parse-list): Fix case when + `org-list-end-re' would have an indentation greater than current + list. + +2010-11-11 Nicolas Goaziou + + * org-exp.el (org-export-mark-list-ending): Differentiate between + export backends, and replace `org-list-end-re' by a blank line + upon exporting. + +2010-11-11 Nicolas Goaziou + + * org-html.el (org-export-as-html): Delete didclose and everything + related to it, as it is no longer needed. + +2010-11-11 Nicolas Goaziou + + * org-html.el (org-export-html-preprocess): Remove unneeded + insertion of list end marker, as it is now handled by + `org-export-mark-list-ending'. + + * org-html.el (org-export-as-html): Cleaner termination of lists. + + * org-exp.el (org-export-mark-list-ending): New function to insert + specific markers at the end of lists when exporting to a backend + not using `org-list-parse-list'. This function is called early in + `org-export-preprocess-string', while it is still able to + recognize lists. + + * org-latex.el (org-export-latex-lists): Better search for + lists. It now only finds items not enclosed and not protected. + +2010-11-11 Nicolas Goaziou + + * org-list.el: Replaced `re-search-forward' by + `org-search-forward-unenclosed' where it made sense. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-apply-to-list): Now a return value is handed at + each new call of the function applied. + + * org-list.el (org-fix-bullet-type): Use the new + `org-apply-to-list' format. + + * org-list.el (org-renumber-ordered-list): Use the new + `org-apply-to-list' format. + +2010-11-11 Nicolas Goaziou + + * org.el (org-in-regexps-block-p): Minor fix: limit wasn't + correctly used. + + * org-list.el (org-search-forward-unenclosed): Better regexp used. + + * org-list.el (org-search-backward-unenclosed): Better regexp + used. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-sort-list): End-rec function was ill-defined. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-search-forward-unenclosed): Fix behavior when + last occurence was enclosed. + + * org-list.el (org-search-backward-unenclosed): Fix behavior when + last occurence was enclosed. + +2010-11-11 Nicolas Goaziou + + * org.el (org-in-regexps-block-p): Fix documentation. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-search-backward-unenclosed): Fix block regexp. + + * org-list.el (org-search-forward-unenclosed): Fix block regexp. + + * org-list.el (org-list-parse-list): Minor fix. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-parse-list): Delete `org-list-end-re' when + called with t argument. + +2010-11-11 Nicolas Goaziou + + * org-html.el (org-export-html-preprocess): Replace + `org-list-end-re' by a blank line during pre-process. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-bottom-point): No need for square brackets + for `skip-chars-backward'. + +2010-11-11 Nicolas Goaziou + + * org-html.el: Do not delete space between end of list and + beginning of the following. + +2010-11-11 Nicolas Goaziou + + * org-html.el: preprocess buffer string and add ORG-LIST-END where + needed. Lists should not end before seeing this. + +2010-11-11 Nicolas Goaziou + + * org-html.el: Notice end of lists. + +2010-11-11 Nicolas Goaziou + + * org-list.el (org-list-parse-list): Better handling of + restrictions when function is called on a list with sublists. + + * org-list.el (org-list-send-list): Find the true ending of the + list being sent. + + * org-list.el (org-list-radio-list-templates): Templates are more + specific to lists. + +2010-11-11 Eric Schulte + + * ob-js.el (org-babel-js-eoe): Indicate end of input + (org-babel-execute:js): Support for session evaluation + (org-babel-prep-session:js): Fleshed out definition + (org-babel-js-initiate-session): Can initiate a session using + mozrepl. + +2010-11-11 David Maus + + * org.el (org-set-regexps-and-options): Protect escape char in + `org-complex-heading-regexp-format'. + +2010-11-11 Eric Schulte + + * ob-scheme.el (org-babel-scheme-eoe): For marking the end of + session-based evaluation + (org-babel-execute:scheme): Now supports session-based evaluation + (org-babel-prep-session:scheme): Now works and defines variables + (org-babel-scheme-initiate-session): Now works using run-scheme + from cmuscheme. + +2010-11-11 Carsten Dominik + + * org.el (org-export-latex-default-packages-alist): Remove the + t1enc package - this is already covered by fontenc. + +2010-11-11 Dan Davison + + * ob.el (with-parsed-tramp-file-name): Declared + (org-babel-tramp-localname): Ensure variable name exists locally. + +2010-11-11 Dan Davison + + * ob.el (org-babel-temp-file): Don't use babel temporary directory + in remote case; use make-temp-file with remote file name so that + temp file is guaranteed not to exist previously on remote machine. + (org-babel-tramp-localname): New function to return local name + portion of possibly remote file specification. + +2010-11-11 Dan Davison + + * ob-R.el (org-babel-R-write-object-command): New unified R + command for writing results to file + (org-babel-R-wrapper-method): Remove variable + (org-babel-R-wrapper-lastvar): Remove variable + (org-babel-R-evaluate-external-process): Use new R command + (org-babel-R-evaluate-session): Use new R command. + +2010-11-11 Dan Davison + + * ob-comint.el + (org-babel-comint-eval-invisibly-and-wait-for-file): New function + to evaluate code invisibly and block until output file exists. + + * ob-R.el (org-babel-R-evaluate-session): Use `ess-eval-buffer' to + evaluate R code in session for :results value. Write result to + file invisibly using new function + `org-babel-comint-eval-invisibly-and-wait-for-file'. + +2010-11-11 Carsten Dominik + + * org-capture.el (org-capture-fill-template): Align tags after + insertion. + +2010-11-11 Carsten Dominik + + * org-exp.el (org-export-concatenate-multiline-emphasis): Ignore + matches that start in a headline. + +2010-11-11 Eric Schulte + + * ob-plantuml.el (org-babel-execute:plantuml): Wrapping in-file + and out-file in shell-quote-argument. + +2010-11-11 David Maus + + * org-docview.el (org-docview-store-link): Use expanded macro to + get current page. + (doc-view-goto-page, image-mode-window-get): Declare functions for + byte compiler. + +2010-11-11 Eric Schulte + + * ob-scheme.el: very preliminary support for evaluating scheme + code blocks + + * org.el (org-babel-load-languages): Adding scheme. + +2010-11-11 Eric Schulte + + * ob.el (require): Remove circular (require 'org). + +2010-11-11 Eric Schulte + + * ob-R.el (ess-make-buffer-current): Declared + (ess-ask-for-ess-directory): Declared + (ess-local-process-name): Declared + + * ob-latex.el (org-babel-latex-tex-to-pdf): Capturing free + variable + + * ob.el (org-edit-src-code): Fixing arguments + (org-edit-src-exit): Declared + (org-outline-overlay-data): Declared + (org-set-outline-overlay-data): Declared. + +2010-11-11 Glenn Morris + + * ob.el: Require org when compiling. + (org-save-outline-visibility): Remove macro declaration. + + * ob-emacs-lisp.el: Require ob-comint when compiling, for macros. + Remove unnecessary/macro declarations. + + * org-docview.el: Require doc-view when compiling. + (doc-view-goto-page): Autoload rather than declaring. + (doc-view-current-page): Remove macro declaration. + + * ob.el (tramp-compat-make-temp-file, org-edit-src-code) + (org-entry-get, org-table-import): Fix declarations. + (org-match-string-no-properties): Remove declaration. + + * ob-sh.el (org-babel-comint-in-buffer) + (org-babel-comint-wait-for-output, org-babel-comint-buffer-livep) + (org-babel-comint-with-output): Remove unnecessary declarations. + + * ob-R.el (orgtbl-to-tsv): Fix declaration. + + * org-list.el (org-entry-get): Fix declaration. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-remove-temporary-directory): Removed explicit + second argument. + +2010-11-11 Magnus Henoch (tiny change) + + * org-clock.el (org-clocktable-steps): Allow ts and te to be day + numbers. + +2010-11-11 Eric Schulte + + * org-macs.el (org-save-outline-visibility): Moved from org.el. + +2010-11-11 Eric Schulte + + * ob-org.el (org-babel-default-header-args:org): Additional + ":results silent" default header argument for org code blocks. + +2010-11-11 Eric Schulte + + * ob-exp.el (org-babel-exp-do-export): Remove hacky ":noeval", + which is now an alias to ":eval no" + +2010-11-11 Eric Schulte + + * ob.el (org-babel-remove-temporary-directory): The version of + `delete-directory' found in files.el can not be assumed to be + present on all versions, so this copies the recursive behavior of + that command in such a way that all calls to delete-directory will + also work with the built-in internal C implementation of that + function. This is not overly difficult as all elements of the + directory can be assumed to be files. + +2010-11-11 Eric Schulte + + * ob-C.el (org-babel-C-execute): Corrected arguments to + org-babel-temp-file. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-temporary-directory): Variable to hold the + value of the Babel temporary directory. + +2010-11-11 Aditya Siram + + * ob.el (org-babel-load-in-session): Expanding noweb references + when appropriate. + +2010-11-11 Nicolas Goaziou + + * org.el (org-make-link-regexps): Modified regexp of + org-plain-link-re. + +2010-11-11 Noorul Islam (tiny change) + + * org-habit.el (org-habit-parse-todo): Find sr-days only if + scheduled-repeat is non nil. Use 4th element of the list returned + by (org-heading-components) as habit-entry. Modify the error + message to be more meaningful. + +2010-11-11 Eric Schulte + + * ob-latex.el (org-babel-execute:latex): Adding new ":fit" and + ":border" header arguments which both use the "preview" latex + package to fit the resulting pdf image to the figure. + +2010-11-11 David Maus + + * org-wl.el (org-wl-store-link): Don't try to store link if point + is at end of buffer. + +2010-11-11 Harri Kiiskinen + + * org-publish.el (org-publish-project-alist): Document the new + body-only property. + (org-publish-org-to): Use the body-only property. + +2010-11-11 Jambunathan K (tiny change) + + * org.el (org-store-link): Return link when invoked + non-interactively from an agenda buffer. + +2010-11-11 Jambunathan K (tiny change) + + * org.el (org-store-link): Storing of links to headlines in + indirect buffers was broken. Fix it. + +2010-11-11 Aidan Kehoe + + * ob-tangle.el (org-babel-tangle): Change the MODE argument to + #'set-file-modes to use integer, not character syntax, avoiding + compile problems with recent XEmacs. + +2010-11-11 Carsten Dominik + + * org-agenda.el (org-agenda-add-entry-text): Make sure we move + forward even if there is no text to be added. + +2010-11-11 Carsten Dominik + + * org.el (org-make-tags-matcher): Read "\\-" as "-" in the + tags/property matcher. + +2010-11-11 Carsten Dominik + + * org-exp.el (org-infile-export-plist): Bind case-fold-search to + t. + +2010-11-11 Carsten Dominik + + * org-agenda.el (org-agenda-with-point-at-orig-entry): New macro. + +2010-11-11 Carsten Dominik + + * org-latex.el (org-export-latex-set-initial-vars): Bind + `case-fold-search' to t around the search for special LaTeX setup. + + * org-beamer.el (org-beamer-after-initial-vars): Bind + `case-fold-search' to t around the search for special BEAMER + setup. + +2010-11-11 David Maus + + * org-agenda.el (org-write-agenda): Delete postscript file after + creating conversion to pdf. + +2010-11-11 David Maus + + * org-agenda.el (org-write-agenda): Move require statements to + proper place in evaluated lisp expression. + +2010-11-11 David Maus + + * org-agenda.el (org-write-agenda): Rename temporary buffer to + remove dependency of `flet' macro. + +2010-11-11 Dan Davison + + * ob-lob.el (org-babel-lob-get-info): Edit docstring. + +2010-11-11 Dan Davison + + * ob-exp.el (org-babel-exp-lob-one-liners): Get parameter values + from all standard sources when executing #+lob/#+call lines. + +2010-11-11 Dan Davison + + * ob-R.el (org-babel-R-evaluate): Break the two branches into two + separate functions + (org-babel-R-evaluate-external-process): New function to handle + external process evaluation + (org-babel-R-evaluate-session): New function to handle session + evaluation. + +2010-11-11 Dan Davison + + * ob.el (org-babel-initiate-session): New function derived from + previous `org-babel-switch-to-session' + (org-babel-switch-to-session): Refactored to use new + `org-babel-initiate-session'. + +2010-11-11 Dan Davison + + * ob.el (org-babel-switch-to-session): Supply missing "P" argument + to (interactive). + +2010-11-11 David Maus + + * org-feed.el (org-feed-format-entry): Decode entry according to + its character encoding. + +2010-11-11 David Maus (tiny change) + + * org-feed.el (xml-substitute-special): Declare function for byte + compiler. + (org-feed-unescape): Removed. + (org-feed-parse-rss-entry, org-feed-parse-atom-entry): Use + `xml-substitute-special' to unescape XML entities. + +2010-11-11 Dan Davison + + * ob.el (org-babel-switch-to-session): Throw error if block if + :session not in effect for the block. + +2010-11-11 Carsten Dominik + + * org-table.el (org-table-create-with-table.el): Align table + before converting. + +2010-11-11 Dan Davison + + * ob.el (org-babel-do-in-edit-buffer): Suppress message and check + that org-src buffer is current before attempting exit. + +2010-11-11 Dan Davison + + * org-src.el (ob-comint): Require 'ob-comint + (org-src-babel-info): Define variable. + +2010-11-11 Dan Davison + + * ob.el (org-babel-do-in-edit-buffer): New macro to evaluate lisp + in the language major mode edit buffer. + (org-babel-do-key-sequence-in-edit-buffer): New function to call + an arbitrary key sequence in the language major mode edit buffer + + * org-src.el (org-src-switch-to-buffer): Add new allowed value + 'switch-invisibly for `org-src-window-setup'. + +2010-11-11 Dan Davison + + * org-src.el (ob-keys): Require ob-keys, because `org-babel-map' + is used. + (org-src-do-at-code-block): New macro to evaluate lisp with point + at the start of the Org code block containing the code in this + edit buffer. + (org-src-do-key-sequence-at-code-block): New function to execute + command bound to key at the Org code block containing the code in + this edit buffer. + +2010-11-11 Dan Davison + + * ob-R.el (org-babel-R-associate-session): New function to + associate R code edit buffers with ESS comint session. + +2010-11-11 Dan Davison + + * org-src.el (org-edit-src-code): If at src block, store babel + info as buffer local variable. + (org-src-associate-babel-session): New function to associate code + edit buffer with comint session. Does nothing unless a + language-specific function named + `org-babel-LANG-associate-session' exists. + (org-src-babel-configure-edit-buffer): New function to be called + in `org-src-mode-hook'. + (org-src-mode-hook): Add `org-src-babel-configure-edit-buffer' to + hook. + +2010-11-11 Dan Davison + + * ob.el (org-babel-switch-to-session-with-code): New function to + generate split frame displaying edit buffer and session. + +2010-11-11 Carsten Dominik + + * org.el (org-set-tags): Consider org-indent-mode when computing + the tags column. + +2010-11-11 Carsten Dominik + + * org-compat.el (org-looking-at-p): Only use looking-at-p when + defined. + +2010-11-11 David Maus + + * org-agenda.el (org-finalize-agenda-entries): Delete excluded + lines directly after call to sorting filter function. + +2010-11-11 Carsten Dominik + + * org.el (org-complex-heading-regexp-format): Document the + variable. + (org-get-refile-targets): Use `org-complex-heading-regexp-format' + to make the regular expression for matching the headline. + +2010-11-11 Carsten Dominik + + * org.el (org-refile-check-position): New function. + (org-goto): + (org-refile-get-location): Call `org-refile-check-position'. + +2010-11-11 Dan Davison + + * ob-python.el (org-babel-python-initiate-session-by-key): Use eq + instead of equal to compare symbols. + +2010-11-11 Carsten Dominik + + * org-agenda.el (org-agenda-before-sorting-filter-function): New + hook function. + (org-finalize-agenda-entries): Apply + `org-agenda-before-sorting-filter-function'. + +2010-11-11 Carsten Dominik + + * org-latex.el (org-export-latex-first-lines): Do not protect meta + lines that have nothing to do with babel. + +2010-11-11 Carsten Dominik + + * org-capture.el (org-capture-place-template): Handle the + checkitem case. + (org-capture-place-item): Provide boundaries for the search to + make sure we do not get a match in a different tree. + +2010-11-11 Carsten Dominik + + * org-exp.el (org-export-preprocess-apply-macros): Fix the macro + argument parser. + +2010-11-11 Noorul Islam + + * org-latex.el (org-latex-to-pdf-process): Add output-directory + option for the command pdflatex. + (org-export-as-pdf): Respect directory in path of + EXPORT_FILE_NAME. + +2010-11-11 Carsten Dominik + + * org-exp.el (org-export-with-LaTeX-fragments): New default t, + which now means to use MathJax processing for HTML. Also allow + new value `dvipng' to force the old image processing. + (org-infile-export-plist): Parse for MATHJAX setup line. + + * org-html.el (org-export-html-mathjax-options): New option. + (org-export-html-mathjax-config): New function. + (org-export-html-mathjax-template): New option. + (org-export-html-preprocess): Call the LaTeX snippet processor + with an additional argument to declare special ways of processing. + (org-export-as-html): Bind the dynamical variable + `org-export-have-math'. Insert the MathJax script template when + it is needed by the document. + + * org.el (org-preview-latex-fragment): Call `org-format-latex' + with the additional processing argument. + (org-export-have-math): New variable, for dynamic scoping. + (org-format-latex): Implement specific ways of processing. New + function argument for processing type. + (org-org-menu): Remove the entry to configure LaTeX snippet + processing. + +2010-11-11 Bastien Guerry + + * org-agenda.el (org-agenda-clock-goto): Use `\C-c\C-x\C-j' for + `org-clock-goto' and `J' for `org-agenda-clock-goto'. If the + heading currently clocked in is not listed in the agenda, display + this entry in another buffer. If there is no running clock, + display a help message. + +2010-11-11 Nicolas Goaziou + + * org-latex.el (org-export-latex-tables): Return "" instead of nil + when no label is attached. + +2010-11-11 Carsten Dominik + + * org-agenda.el (org-agenda-menu-show-match): New option. + (org-agenda-menu-two-column): New option. + (org-agenda-get-restriction-and-command): Implement dispatch menu + without showing the matcher, and with two-column display. + +2010-11-11 Bernt Hansen + + * org-indent.el (org-indent-mode): Fix grammar for message when + mode is refused. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-insert-result): Ensures `beg' is set, even if + no previous result exists. + +2010-11-11 Noorul Islam + + * ob.el Declare org-babel-lob-execute-maybe() to avoid compiler + warning. + +2010-11-11 Noorul Islam + + * org.el: org-set-visibility-according-to-property () Use backward + search instead of forward, so that top hierarchy gets priority. + +2010-11-11 Carsten Dominik + + * org-agenda.el (org-timeline): Allow indirect buffer. + +2010-11-11 Carsten Dominik + + * org-exp.el (org-export-preprocess-after-radio-targets-hook): + (org-export-define-heading-targets-headline-hook): New hooks. + + * org.el (org-modules): Add entry for org-wikinodes.el. + (org-font-lock-set-keywords-hook): New hook. + (org-open-at-point-functions): New hook. + (org-find-exact-headling-in-buffer): + (org-find-exact-heading-in-directory): New functions. + (org-mode-flyspell-verify): Better cursor position for checking if + flyspell should ignore a word. + +2010-11-11 Carsten Dominik + + * org-indent.el (org-indent-remove-properties): + (org-indent-add-properties): Make sure changing these properties + does not trigger modification hooks. + +2010-11-11 Carsten Dominik + + * org.el (org-link-search-must-match-exact-headline): New option. + (org-link-search-inhibit-query): New variable. + (org-link-search): Search for exact headline match in Org files. + +2010-11-11 Dan Davison + + * ob.el (org-babel-execute-src-block-maybe): Remove check for + `org-babel-no-eval-on-ctrl-c-ctrl-c'; this is done in the new + function `org-babel-execute-safely-maybe'. + +2010-11-11 Dan Davison + + * ob.el (org-babel-load-in-session): Set directory in case :dir + arg is in effect. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-tangle-collect-blocks): Don't throw + errors when we're not under of a headline. + +2010-11-11 Dan Davison + + * ob-octave.el (org-babel-octave-wrapper-method): Use dlmwrite to + write delimited text instead of save -ascii + (org-babel-octave-import-elisp-from-file): Specify that data + written to file is tab-delimited. + +2010-11-11 Dan Davison + + * ob-R.el (org-babel-R-evaluate): Specify that tabular data is + tab-delimited. + +2010-11-11 Dan Davison + + * ob.el (org-babel-import-elisp-from-file): Allow separator to be + specified. + +2010-11-11 Dan Davison + + * ob-python.el (org-babel-python-table-or-string): Fix recognition + of lists and tuples. + +2010-11-11 Dan Davison + + * ob-octave.el (org-babel-octave-evaluate-external-process): Allow + remote files. + +2010-11-11 Juan Pechiar + + * ob-octave.el (org-babel-octave-evaluate-external-process): Use + `org-babel-octave-import-elisp-from-file' instead of + `org-babel-eval-read-file'. + (org-babel-octave-var-to-octave): Separate matrix rows with ';', + and use '%s' as format specifier instead of '%S'. + +2010-11-11 Dan Davison + + * ob-octave.el only (require 'matlab) when necessary + (org-babel-octave-initiate-session) (require) octave-inf or matlab + as appropriate + (org-babel-execute:matlab): Remove (require) + (org-babel-prep-session:matlab): Remove (require) + (org-babel-matlab-initiate-session): Remove (require). + +2010-11-11 Dan Davison + + * ob-octave.el (org-babel-octave-evaluate): Fix formal argument + list. + +2010-11-11 Eric Schulte + + * ob-python.el (org-babel-python-table-or-string): Can now handle + VERY long result lines. + +2010-11-11 Nicolas Goaziou + + * org-latex.el (org-export-latex-tables): Add label if any + + * org-latex.el (org-export-latex-convert-table.el-table): Fix + little mistake when inserting label. + +2010-11-11 Nicolas Goaziou + + * org.el (org-cycle-internal-local): Removed an unnecessary call + to `org-back-to-heading' that was preventing point to stay at its + column when cycling visibility. + +2010-11-11 Noorul Islam + + * org-capture.el (org-capture-finalize): Make messages consistent. + +2010-11-11 Noorul Islam + + * org-gnus.el: Suppress compiler warning by declaring outside + function nnimap-retrieve-headers-from-file. + +2010-11-11 Noorul Islam + + * org-colview.el Use org-beamer-select-environment instead of + org-beamer-set-environment-tag. + +2010-11-11 Matt Lundin + + * org.el (org-insert-time-stamp): Fix org-insert-time-stamp so + that the value of org-last-inserted-timestamp includes time range. + +2010-11-11 David Maus + + * org-wl.el (org-wl-store-link-message): Provide link property for + message-id without angle brackets. + +2010-11-11 Eric Schulte + + * ob-R.el (org-babel-R-evaluate): Improved prompt-stripping regexp. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-find-file-noselect-refresh): Finds a + file ensuing that the latest changes on disk are represented. + +2010-11-11 Eric Schulte + + * ob-sqlite.el (org-babel-sqlite-expand-vars): Now inserts string + arguments w/o quotes. + +2010-11-11 Bernt Hansen + + * org-capture.el (org-capture-finalize): Fix clock in of + interrupted task during capture finalize. + +2010-11-11 Eric Schulte + + * ob-R.el (org-babel-R-evaluate): Clean up extra prompts in + session output. + +2010-11-11 Eric Schulte + + * ob-C.el (org-babel-C-ensure-main-wrap): More generous regular + expression for matching main function. + +2010-11-11 Eric Schulte + + * ob-lob.el (org-babel-lob-one-liner-regexp): Fixed error in lob + regexp -- it wasn't matching lob lines w/o indices. + +2010-11-11 Eric Schulte + + * org-exp.el (org-export-latex-listings-w-names): Fix compiler + warning in org-exp.el. + +2010-11-11 Carsten Dominik + + * org-publish.el (org-publish-file): Better error message if + base-directory or publishing-directory are not defined. + +2010-11-11 Carsten Dominik + + * org-colview.el (org-columns-display-here): Use overlays to + overrule line prefix properties during column view. + +2010-11-11 Carsten Dominik + + * org-agenda.el (org-agenda-filter-preset): Document the + limitation for the filter preset - it can only be used for an + entire agenda view, not in an individual block in a block agenda. + +2010-11-11 Eric Schulte + + * ob-table.el (sbe): Now able to accept range references from + tables. + +2010-11-11 Eric Schulte + + * ob.el (org-babel-pick-name): If colnames or rownames contain a + list of names, then use those directly. + +2010-11-11 Eric Schulte + + * org-exp.el (org-export-format-source-code-or-example): Escape + underscores in code block names on latex listings export. + +2010-11-11 Eric Schulte + + * ob-tangle.el (org-babel-with-temp-filebuffer): Use + find-file-noselect to avoid excess buffer movement. + +2010-11-11 Carsten Dominik + + * org-html.el (org-html-should-inline-p): Only inline images if + they should be. + +2010-11-11 Carsten Dominik + + * org-id.el (org-id-store-link): Autoload. + + * org.el ("org-id"): Autoload `org-id-store-link'. + +2010-11-11 Carsten Dominik + + * org-html.el (org-html-should-inline-p): Only inline images if + they should be. + +2010-11-11 Eric S Fraga + + * org-icalendar.el (org-icalendar-alarm-time): New option. + + * org-icalendar.el (org-print-icalendar-entries): Timed events are + exported with alarm events, a.k.a. reminders. + +2010-11-11 Carsten Dominik + + * org-capture.el (org-capture-target-buffer): Throw an error if we + have no target file. + (org-capture-select-template): Use a default template if the user + has not specified any. + +2010-11-11 Carsten Dominik + + * org.el (org-modules): Add entry for org-velocity. + +2010-11-11 Eric Schulte + + * ob-lob.el (org-babel-lob-execute): Changing indentation to + improve line length. + +2010-11-11 Carsten Dominik + + * org-exp.el (org-export-handle-table-metalines): Choose a better + position for checking protectedness. + +2010-11-11 Eric Schulte + + * org-table.el (org-table-convert-region): Don't continue csv + importation which the point catches the end, this fixes an + infinite loop which was caused by the (point) never catching up + with the "end" marker. + +2010-11-11 Carsten Dominik + + * org-macs.el (org-string-nw-p): New function. + + * org-capture.el (org-capture-import-remember-templates): + Interpret an empty string as request to use + `org-default-notes-file'. + (org-capture-target-buffer): If the FILE is not a (non-empty) + string, use `org-default-notes-file'. + +2010-11-11 Carsten Dominik + + * org-capture.el (org-capture-templates): Fix customize type. + +2010-11-11 Carsten Dominik + + * org-colview-xemacs.el (org-columns-compile-map): + (org-columns-number-to-string): + (org-columns-string-to-number): Handle estimate ranges. + (org-estimate-mean-and-var): New function. + (org-estimate-combine): New function. + (org-estimate-print): New function. + (org-string-to-estimate): New function. + 2010-09-25 Juanma Barranquero * org.el (org-refile-targets): diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-C.el --- a/lisp/org/ob-C.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-C.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -33,7 +33,6 @@ ;;; Code: (require 'ob) (require 'ob-eval) -(require 'org) (require 'cc-mode) (declare-function org-entry-get "org" @@ -65,31 +64,30 @@ called by `org-babel-execute-src-block'." (let ((org-babel-c-variant 'cpp)) (org-babel-C-execute body params))) -(defun org-babel-expand-body:c++ (body params &optional processed-params) +(defun org-babel-expand-body:c++ (body params) "Expand a block of C++ code with org-babel according to it's header arguments (calls `org-babel-C-expand')." - (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params processed-params))) + (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params))) (defun org-babel-execute:C (body params) "Execute a block of C code with org-babel. This function is called by `org-babel-execute-src-block'." (let ((org-babel-c-variant 'c)) (org-babel-C-execute body params))) -(defun org-babel-expand-body:c (body params &optional processed-params) +(defun org-babel-expand-body:c (body params) "Expand a block of C code with org-babel according to it's header arguments (calls `org-babel-C-expand')." - (let ((org-babel-c-variant 'c)) (org-babel-C-expand body params processed-params))) + (let ((org-babel-c-variant 'c)) (org-babel-C-expand body params))) (defun org-babel-C-execute (body params) "This function should only be called by `org-babel-execute:C' or `org-babel-execute:c++'." - (let* ((processed-params (org-babel-process-params params)) - (tmp-src-file (make-temp-file "org-babel-C-src" nil - (cond - ((equal org-babel-c-variant 'c) ".c") - ((equal org-babel-c-variant 'cpp) ".cpp")))) - (tmp-bin-file (make-temp-file "org-babel-C-bin")) - (tmp-out-file (make-temp-file "org-babel-C-out")) + (let* ((tmp-src-file (org-babel-temp-file + "C-src-" + (cond + ((equal org-babel-c-variant 'c) ".c") + ((equal org-babel-c-variant 'cpp) ".cpp")))) + (tmp-bin-file (org-babel-temp-file "C-bin-")) (cmdline (cdr (assoc :cmdline params))) (flags (cdr (assoc :flags params))) (full-body (org-babel-C-expand body params)) @@ -101,37 +99,35 @@ (cond ((equal org-babel-c-variant 'c) org-babel-C-compiler) ((equal org-babel-c-variant 'cpp) org-babel-c++-compiler)) - tmp-bin-file + (org-babel-process-file-name tmp-bin-file) (mapconcat 'identity (if (listp flags) flags (list flags)) " ") - tmp-src-file) "")))) + (org-babel-process-file-name tmp-src-file)) "")))) ((lambda (results) (org-babel-reassemble-table - (if (member "vector" (nth 2 processed-params)) - (let ((tmp-file (make-temp-file "ob-c"))) + (if (member "vector" (cdr (assoc :result-params params))) + (let ((tmp-file (org-babel-temp-file "c-"))) (with-temp-file tmp-file (insert results)) (org-babel-import-elisp-from-file tmp-file)) (org-babel-read results)) (org-babel-pick-name - (nth 4 processed-params) (cdr (assoc :colnames params))) + (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name - (nth 5 processed-params) (cdr (assoc :rownames params))))) + (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))) (org-babel-trim (org-babel-eval (concat tmp-bin-file (if cmdline (concat " " cmdline) "")) ""))))) -(defun org-babel-C-expand (body params &optional processed-params) +(defun org-babel-C-expand (body params) "Expand a block of C or C++ code with org-babel according to it's header arguments." - (let ((vars (nth 1 (or processed-params - (org-babel-process-params params)))) + (let ((vars (mapcar #'cdr (org-babel-get-header params :var))) (main-p (not (string= (cdr (assoc :main params)) "no"))) (includes (or (cdr (assoc :includes params)) (org-babel-read (org-entry-get nil "includes" t)))) (defines (org-babel-read (or (cdr (assoc :defines params)) (org-babel-read (org-entry-get nil "defines" t)))))) - (org-babel-trim (mapconcat 'identity (list ;; includes @@ -147,11 +143,11 @@ ;; body (if main-p (org-babel-C-ensure-main-wrap body) - body) "\n") "\n")))) + body) "\n") "\n"))) (defun org-babel-C-ensure-main-wrap (body) "Wrap body in a \"main\" function call if none exists." - (if (string-match "^[ \t]*[intvod]+[ \t]*main[ \t]*(.*)" body) + (if (string-match "^[ \t]*[intvod]+[ \t\n\r]*main[ \t]*(.*)" body) body (format "int main() {\n%s\n}\n" body))) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-R.el --- a/lisp/org/ob-R.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-R.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte, Dan Davison ;; Keywords: literate programming, reproducible research, R, statistics ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -36,6 +36,9 @@ (declare-function orgtbl-to-tsv "org-table" (table params)) (declare-function R "ext:essd-r" (&optional start-args)) (declare-function inferior-ess-send-input "ext:ess-inf" ()) +(declare-function ess-make-buffer-current "ext:ess-inf" ()) +(declare-function ess-eval-buffer "ext:ess-inf" (vis)) +(declare-function org-number-sequence "org-compat" (from &optional to inc)) (defconst org-babel-header-arg-names:R '(width height bg units pointsize antialias quality compression @@ -48,21 +51,11 @@ (defvar org-babel-R-command "R --slave --no-save" "Name of command to use for executing R code.") -(defun org-babel-expand-body:R (body params &optional processed-params) +(defun org-babel-expand-body:R (body params) "Expand BODY according to PARAMS, return the expanded body." - (let* ((processed-params (or processed-params - (org-babel-process-params params))) - (vars (mapcar - (lambda (i) - (cons (car (nth i (nth 1 processed-params))) - (org-babel-reassemble-table - (cdr (nth i (nth 1 processed-params))) - (cdr (nth i (nth 4 processed-params))) - (cdr (nth i (nth 5 processed-params)))))) - (number-sequence 0 (1- (length (nth 1 processed-params)))))) - (out-file (cdr (assoc :file params)))) - (mapconcat ;; define any variables - #'org-babel-trim + (let ((out-file (cdr (assoc :file params)))) + (mapconcat + #'identity ((lambda (inside) (if out-file (append @@ -70,49 +63,36 @@ inside (list "dev.off()")) inside)) - (append - (mapcar - (lambda (pair) - (org-babel-R-assign-elisp - (car pair) (cdr pair) - (equal "yes" (cdr (assoc :colnames params))) - (equal "yes" (cdr (assoc :rownames params))))) - vars) - (list body))) "\n"))) + (append (org-babel-variable-assignments:R params) + (list body))) "\n"))) (defun org-babel-execute:R (body params) "Execute a block of R code. This function is called by `org-babel-execute-src-block'." (save-excursion - (let* ((processed-params (org-babel-process-params params)) - (result-type (nth 3 processed-params)) + (let* ((result-type (cdr (assoc :result-type params))) (session (org-babel-R-initiate-session - (first processed-params) params)) + (cdr (assoc :session params)) params)) (colnames-p (cdr (assoc :colnames params))) (rownames-p (cdr (assoc :rownames params))) (out-file (cdr (assoc :file params))) - (full-body (org-babel-expand-body:R body params processed-params)) + (full-body (org-babel-expand-body:R body params)) (result (org-babel-R-evaluate session full-body result-type (or (equal "yes" colnames-p) - (org-babel-pick-name (nth 4 processed-params) colnames-p)) + (org-babel-pick-name + (cdr (assoc :colname-names params)) colnames-p)) (or (equal "yes" rownames-p) - (org-babel-pick-name (nth 5 processed-params) rownames-p))))) + (org-babel-pick-name + (cdr (assoc :rowname-names params)) rownames-p))))) (message "result is %S" result) (or out-file result)))) (defun org-babel-prep-session:R (session params) "Prepare SESSION according to the header arguments specified in PARAMS." (let* ((session (org-babel-R-initiate-session session params)) - (vars (org-babel-ref-variables params)) - (var-lines - (mapcar - (lambda (pair) (org-babel-R-assign-elisp - (car pair) (cdr pair) - (equal (cdr (assoc :colnames params)) "yes") - (equal (cdr (assoc :rownames params)) "yes"))) - vars))) + (var-lines (org-babel-variable-assignments:R params))) (org-babel-comint-in-buffer session (mapc (lambda (var) (end-of-line 1) (insert var) (comint-send-input nil t) @@ -130,6 +110,24 @@ ;; helper functions +(defun org-babel-variable-assignments:R (params) + "Return list of R statements assigning the block's variables" + (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))) + (mapcar + (lambda (pair) + (org-babel-R-assign-elisp + (car pair) (cdr pair) + (equal "yes" (cdr (assoc :colnames params))) + (equal "yes" (cdr (assoc :rownames params))))) + (mapcar + (lambda (i) + (cons (car (nth i vars)) + (org-babel-reassemble-table + (cdr (nth i vars)) + (cdr (nth i (cdr (assoc :colname-names params)))) + (cdr (nth i (cdr (assoc :rowname-names params))))))) + (org-number-sequence 0 (1- (length vars))))))) + (defun org-babel-R-quote-tsv-field (s) "Quote field S for export to R." (if (stringp s) @@ -139,23 +137,25 @@ (defun org-babel-R-assign-elisp (name value colnames-p rownames-p) "Construct R code assigning the elisp VALUE to a variable named NAME." (if (listp value) - (let ((transition-file (make-temp-file "org-babel-R-import"))) + (let ((transition-file (org-babel-temp-file "R-import-"))) ;; ensure VALUE has an orgtbl structure (depth of at least 2) (unless (listp (car value)) (setq value (list value))) - (with-temp-file (org-babel-maybe-remote-file transition-file) + (with-temp-file transition-file (insert (orgtbl-to-tsv value '(:fmt org-babel-R-quote-tsv-field))) (insert "\n")) (format "%s <- read.table(\"%s\", header=%s, row.names=%s, sep=\"\\t\", as.is=TRUE)" - name transition-file + name (org-babel-process-file-name transition-file 'noquote) (if (or (eq (nth 1 value) 'hline) colnames-p) "TRUE" "FALSE") (if rownames-p "1" "NULL"))) (format "%s <- %s" name (org-babel-R-quote-tsv-field value)))) +(defvar ess-ask-for-ess-directory nil) (defun org-babel-R-initiate-session (session params) "If there is not a current R process then create one." (unless (string= session "none") (let ((session (or session "*R*")) - (ess-ask-for-ess-directory (not (cdr (assoc :dir params))))) + (ess-ask-for-ess-directory + (and ess-ask-for-ess-directory (not (cdr (assoc :dir params)))))) (if (org-babel-comint-buffer-livep session) session (save-window-excursion @@ -168,6 +168,15 @@ (buffer-name)))) (current-buffer)))))) +(defvar ess-local-process-name nil) +(defun org-babel-R-associate-session (session) + "Associate R code buffer with an R session. +Make SESSION be the inferior ESS process associated with the +current code buffer." + (setq ess-local-process-name + (process-name (get-buffer-process session))) + (ess-make-buffer-current)) + (defun org-babel-R-construct-graphics-device-call (out-file params) "Construct the call to the graphics device." (let ((devices @@ -205,65 +214,78 @@ (defvar org-babel-R-eoe-indicator "'org_babel_R_eoe'") (defvar org-babel-R-eoe-output "[1] \"org_babel_R_eoe\"") -(defvar org-babel-R-wrapper-method "main <- function ()\n{\n%s\n} -write.table(main(), file=\"%s\", sep=\"\\t\", na=\"nil\",row.names=%s, col.names=%s, quote=FALSE)") -(defvar org-babel-R-wrapper-lastvar "write.table(.Last.value, file=\"%s\", sep=\"\\t\", na=\"nil\",row.names=%s, col.names=%s, quote=FALSE)") +(defvar org-babel-R-write-object-command "{function(object, transfer.file) {invisible(if(inherits(try(write.table(object, file=transfer.file, sep=\"\\t\", na=\"nil\",row.names=%s, col.names=%s, quote=FALSE), silent=TRUE),\"try-error\")) {if(!file.exists(transfer.file)) file.create(transfer.file)})}}(object=%s, transfer.file=\"%s\")") (defun org-babel-R-evaluate (session body result-type column-names-p row-names-p) - "Pass BODY to the R process in SESSION. -If RESULT-TYPE equals 'output then return a list of the outputs -of the statements in BODY, if RESULT-TYPE equals 'value then -return the value of the last statement in BODY, as elisp." - (if (not session) - ;; external process evaluation - (case result-type - (output (org-babel-eval org-babel-R-command body)) - (value - (let ((tmp-file (make-temp-file "org-babel-R-results-"))) - (org-babel-eval org-babel-R-command - (format org-babel-R-wrapper-method - body tmp-file - (if row-names-p "TRUE" "FALSE") - (if column-names-p - (if row-names-p "NA" "TRUE") - "FALSE"))) - (org-babel-R-process-value-result - (org-babel-import-elisp-from-file - (org-babel-maybe-remote-file tmp-file)) column-names-p)))) - ;; comint session evaluation - (case result-type - (value - (let ((tmp-file (make-temp-file "org-babel-R")) - broke) - (org-babel-comint-with-output (session org-babel-R-eoe-output) - (insert (mapconcat - #'org-babel-chomp - (list - body - (format org-babel-R-wrapper-lastvar - tmp-file - (if row-names-p "TRUE" "FALSE") - (if column-names-p - (if row-names-p "NA" "TRUE") - "FALSE")) - org-babel-R-eoe-indicator) "\n")) - (inferior-ess-send-input)) - (org-babel-R-process-value-result - (org-babel-import-elisp-from-file - (org-babel-maybe-remote-file tmp-file)) column-names-p))) - (output - (mapconcat - #'org-babel-chomp - (butlast - (delq nil - (mapcar - #'identity - (org-babel-comint-with-output (session org-babel-R-eoe-output) - (insert (mapconcat #'org-babel-chomp - (list body org-babel-R-eoe-indicator) - "\n")) - (inferior-ess-send-input)))) 2) "\n"))))) + "Evaluate R code in BODY." + (if session + (org-babel-R-evaluate-session + session body result-type column-names-p row-names-p) + (org-babel-R-evaluate-external-process + body result-type column-names-p row-names-p))) + +(defun org-babel-R-evaluate-external-process + (body result-type column-names-p row-names-p) + "Evaluate BODY in external R process. +If RESULT-TYPE equals 'output then return standard output as a +string. If RESULT-TYPE equals 'value then return the value of the +last statement in BODY, as elisp." + (case result-type + (value + (let ((tmp-file (org-babel-temp-file "R-"))) + (org-babel-eval org-babel-R-command + (format org-babel-R-write-object-command + (if row-names-p "TRUE" "FALSE") + (if column-names-p + (if row-names-p "NA" "TRUE") + "FALSE") + (format "{function ()\n{\n%s\n}}()" body) + (org-babel-process-file-name tmp-file 'noquote))) + (org-babel-R-process-value-result + (org-babel-import-elisp-from-file tmp-file '(16)) column-names-p))) + (output (org-babel-eval org-babel-R-command body)))) + +(defun org-babel-R-evaluate-session + (session body result-type column-names-p row-names-p) + "Evaluate BODY in SESSION. +If RESULT-TYPE equals 'output then return standard output as a +string. If RESULT-TYPE equals 'value then return the value of the +last statement in BODY, as elisp." + (case result-type + (value + (with-temp-buffer + (insert (org-babel-chomp body)) + (let ((ess-local-process-name + (process-name (get-buffer-process session)))) + (ess-eval-buffer nil))) + (let ((tmp-file (org-babel-temp-file "R-"))) + (org-babel-comint-eval-invisibly-and-wait-for-file + session tmp-file + (format org-babel-R-write-object-command + (if row-names-p "TRUE" "FALSE") + (if column-names-p + (if row-names-p "NA" "TRUE") + "FALSE") + ".Last.value" (org-babel-process-file-name tmp-file 'noquote))) + (org-babel-R-process-value-result + (org-babel-import-elisp-from-file tmp-file '(16)) column-names-p))) + (output + (mapconcat + #'org-babel-chomp + (butlast + (delq nil + (mapcar + (lambda (line) ;; cleanup extra prompts left in output + (if (string-match + "^\\([ ]*[>+][ ]?\\)+\\([[0-9]+\\|[ ]\\)" line) + (substring line (match-end 1)) + line)) + (org-babel-comint-with-output (session org-babel-R-eoe-output) + (insert (mapconcat #'org-babel-chomp + (list body org-babel-R-eoe-indicator) + "\n")) + (inferior-ess-send-input)))) 2) "\n")))) (defun org-babel-R-process-value-result (result column-names-p) "R-specific processing of return value. diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-asymptote.el --- a/lisp/org/ob-asymptote.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-asymptote.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -55,32 +55,30 @@ '((:results . "file") (:exports . "results")) "Default arguments when evaluating an Asymptote source block.") -(defun org-babel-expand-body:asymptote (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." - (let ((vars (nth 1 (or processed-params - (org-babel-process-params params))))) - (concat (mapconcat 'org-babel-asymptote-var-to-asymptote vars "\n") - "\n" body "\n"))) - (defun org-babel-execute:asymptote (body params) "Execute a block of Asymptote code. This function is called by `org-babel-execute-src-block'." - (let* ((processed-params (org-babel-process-params params)) - (result-params (split-string (or (cdr (assoc :results params)) ""))) + (let* ((result-params (split-string (or (cdr (assoc :results params)) ""))) (out-file (cdr (assoc :file params))) (format (or (and out-file (string-match ".+\\.\\(.+\\)" out-file) (match-string 1 out-file)) "pdf")) (cmdline (cdr (assoc :cmdline params))) - (in-file (make-temp-file "org-babel-asymptote")) - (cmd (concat "asy " - (if out-file - (concat "-globalwrite -f " format " -o " out-file) - "-V") - " " cmdline " " in-file))) + (in-file (org-babel-temp-file "asymptote-")) + (cmd + (concat "asy " + (if out-file + (concat + "-globalwrite -f " format + " -o " (org-babel-process-file-name out-file)) + "-V") + " " cmdline + " " (org-babel-process-file-name in-file)))) (with-temp-file in-file - (insert (org-babel-expand-body:asymptote body params processed-params))) + (insert (org-babel-expand-body:generic + body params + (org-babel-variable-assignments:asymptote params)))) (message cmd) (shell-command cmd) out-file)) @@ -89,6 +87,11 @@ Asymptote does not support sessions" (error "Asymptote does not support sessions")) +(defun org-babel-variable-assignments:asymptote (params) + "Return list of asymptote statements assigning the block's variables" + (mapcar #'org-babel-asymptote-var-to-asymptote + (mapcar #'cdr (org-babel-get-header params :var)))) + (defun org-babel-asymptote-var-to-asymptote (pair) "Convert an elisp value into an Asymptote variable. The elisp value PAIR is converted into Asymptote code specifying diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-calc.el --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/org/ob-calc.el Thu Nov 11 22:10:19 2010 -0600 @@ -0,0 +1,67 @@ +;;; ob-calc.el --- org-babel functions for calc code evaluation + +;; Copyright (C) 2010 Free Software Foundation, Inc + +;; Author: Eric Schulte +;; Keywords: literate programming, reproducible research +;; Homepage: http://orgmode.org +;; Version: 7.3 + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Org-Babel support for evaluating calc code + +;;; Code: +(require 'ob) +(require 'calc) +(require 'calc-trail) +(eval-when-compile (require 'ob-comint)) + +(defvar org-babel-default-header-args:calc nil + "Default arguments for evaluating an calc source block.") + +(defun org-babel-expand-body:calc (body params) + "Expand BODY according to PARAMS, return the expanded body." body) + +(defun org-babel-execute:calc (body params) + "Execute a block of calc code with Babel." + (mapcar + (lambda (line) + (when (> (length line) 0) + (if (string= "'" (substring line 0 1)) + (funcall (lookup-key calc-mode-map (substring line 1)) nil) + (calc-push-list + (list ((lambda (res) + (cond + ((numberp res) res) + ((listp res) (error "calc error \"%s\" on input \"%s\"" + (cadr res) line)) + (t res)) + (if (numberp res) res (math-read-number res))) + (calc-eval line))))))) + (mapcar #'org-babel-trim + (split-string (org-babel-expand-body:calc body params) "[\n\r]"))) + (save-excursion + (set-buffer (get-buffer "*Calculator*")) + (calc-eval (calc-top 1)))) + +(provide 'ob-calc) + +;; arch-tag: 5c57a3b7-5818-4c6c-acda-7a94831a6449 + +;;; ob-calc.el ends here diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-clojure.el --- a/lisp/org/ob-clojure.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-clojure.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Joel Boehland ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -45,7 +45,6 @@ (declare-function slime-eval-async "ext:slime" (sexp &optional cont package)) (declare-function slime-eval "ext:slime" (sexp &optional package)) (declare-function swank-clojure-concat-paths "ext:slime" (paths)) -(declare-function org-babel-ref-variables "ext:slime" (params)) (declare-function slime "ext:slime" (&optional command coding-system)) (declare-function slime-output-buffer "ext:slime" (&optional noprompt)) (declare-function slime-filter-buffers "ext:slime" (predicate)) @@ -92,28 +91,28 @@ (defvar swank-clojure-extra-classpaths) (defun org-babel-clojure-babel-clojure-cmd () "Create the command to start clojure according to current settings." - (if (and (not swank-clojure-binary) (not swank-clojure-classpath)) + (or (when swank-clojure-binary + (if (listp swank-clojure-binary) + swank-clojure-binary + (list swank-clojure-binary))) + (when swank-clojure-classpath + (delq + nil + (append + (list swank-clojure-java-path) + swank-clojure-extra-vm-args + (list + (when swank-clojure-library-paths + (concat "-Djava.library.path=" + (swank-clojure-concat-paths swank-clojure-library-paths))) + "-classpath" + (swank-clojure-concat-paths + (append + swank-clojure-classpath + swank-clojure-extra-classpaths)) + "clojure.main")))) (error "%s" (concat "You must specifiy either a `swank-clojure-binary' " - "or a `swank-clojure-jar-path'")) - (if swank-clojure-binary - (if (listp swank-clojure-binary) - swank-clojure-binary - (list swank-clojure-binary)) - (delq - nil - (append - (list swank-clojure-java-path) - swank-clojure-extra-vm-args - (list - (when swank-clojure-library-paths - (concat "-Djava.library.path=" - (swank-clojure-concat-paths swank-clojure-library-paths))) - "-classpath" - (swank-clojure-concat-paths - (append - swank-clojure-classpath - swank-clojure-extra-classpaths)) - "clojure.main")))))) + "or a `swank-clojure-classpath'")))) (defun org-babel-clojure-table-or-string (results) "Convert RESULTS to an elisp value. @@ -155,7 +154,7 @@ "Prepare SESSION according to the header arguments specified in PARAMS." (require 'slime) (require 'swank-clojure) (let* ((session-buf (org-babel-clojure-initiate-session session)) - (vars (org-babel-ref-variables params)) + (vars (mapcar #'cdr (org-babel-get-header params :var))) (var-lines (mapcar ;; define any top level session variables (lambda (pair) (format "(def %s %s)\n" (car pair) @@ -261,9 +260,13 @@ " ")))) (case result-type (output (org-babel-eval cmd body)) - (value (let* ((tmp-file (make-temp-file "org-babel-clojure-results-"))) - (org-babel-eval cmd (format org-babel-clojure-wrapper-method - body tmp-file tmp-file)) + (value (let* ((tmp-file (org-babel-temp-file "clojure-"))) + (org-babel-eval + cmd + (format + org-babel-clojure-wrapper-method + body + (org-babel-process-file-name tmp-file 'noquote))) (org-babel-clojure-table-or-string (org-babel-eval-read-file tmp-file))))))) @@ -290,24 +293,23 @@ (org-babel-clojure-evaluate-session buffer body result-type) (org-babel-clojure-evaluate-external-process buffer body result-type))) -(defun org-babel-expand-body:clojure (body params &optional processed-params) +(defun org-babel-expand-body:clojure (body params) "Expand BODY according to PARAMS, return the expanded body." (org-babel-clojure-build-full-form - body (nth 1 (or processed-params (org-babel-process-params params))))) + body (mapcar #'cdr (org-babel-get-header params :var)))) (defun org-babel-execute:clojure (body params) "Execute a block of Clojure code." (require 'slime) (require 'swank-clojure) - (let* ((processed-params (org-babel-process-params params)) - (body (org-babel-expand-body:clojure body params processed-params)) + (let* ((body (org-babel-expand-body:clojure body params)) (session (org-babel-clojure-initiate-session - (first processed-params)))) + (cdr (assoc :session params))))) (org-babel-reassemble-table - (org-babel-clojure-evaluate session body (nth 3 processed-params)) + (org-babel-clojure-evaluate session body (cdr (assoc :result-type params))) (org-babel-pick-name - (nth 4 processed-params) (cdr (assoc :colnames params))) + (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name - (nth 5 processed-params) (cdr (assoc :rownames params)))))) + (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))) (provide 'ob-clojure) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-comint.el --- a/lisp/org/ob-comint.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-comint.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research, comint ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -34,6 +34,8 @@ (require 'ob) (require 'comint) (eval-when-compile (require 'cl)) +(declare-function with-parsed-tramp-file-name "tramp" (filename var &rest body)) +(declare-function tramp-flush-directory-property "tramp" (vec directory)) (defun org-babel-comint-buffer-livep (buffer) "Check if BUFFER is a comint buffer with a live process." @@ -43,7 +45,7 @@ (defmacro org-babel-comint-in-buffer (buffer &rest body) "Check BUFFER and execute BODY. BUFFER is checked with `org-babel-comint-buffer-livep'. BODY is -executed inside the protection of `save-window-excursion' and +executed inside the protection of `save-excursion' and `save-match-data'." (declare (indent 1)) `(save-excursion @@ -136,6 +138,24 @@ "comint-highlight-prompt")))) (accept-process-output (get-buffer-process buffer))))) +(defun org-babel-comint-eval-invisibly-and-wait-for-file + (buffer file string &optional period) + "Evaluate STRING in BUFFER invisibly. +Don't return until FILE exists. Code in STRING must ensure that +FILE exists at end of evaluation." + (unless (org-babel-comint-buffer-livep buffer) + (error "buffer %s doesn't exist or has no process" buffer)) + (if (file-exists-p file) (delete-file file)) + (process-send-string + (get-buffer-process buffer) + (if (string-match "\n$" string) string (concat string "\n"))) + ;; From Tramp 2.1.19 the following cache flush is not necessary + (if (file-remote-p default-directory) + (let (v) + (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) ;; arch-tag: 9adddce6-0864-4be3-b0b5-6c5157dc7889 diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-css.el --- a/lisp/org/ob-css.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-css.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -32,9 +32,6 @@ (defvar org-babel-default-header-args:css '()) -(defun org-babel-expand-body:css (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." body) - (defun org-babel-execute:css (body params) "Execute a block of CSS code. This function is called by `org-babel-execute-src-block'." diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-ditaa.el --- a/lisp/org/ob-ditaa.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-ditaa.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -43,22 +43,24 @@ '((:results . "file") (:exports . "results")) "Default arguments for evaluating a ditaa source block.") -(defun org-babel-expand-body:ditaa (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." body) - (defvar org-ditaa-jar-path) (defun org-babel-execute:ditaa (body params) "Execute a block of Ditaa code with org-babel. This function is called by `org-babel-execute-src-block'." - (let ((result-params (split-string (or (cdr (assoc :results params)) ""))) - (out-file (cdr (assoc :file params))) - (cmdline (cdr (assoc :cmdline params))) - (in-file (make-temp-file "org-babel-ditaa"))) + (let* ((result-params (split-string (or (cdr (assoc :results params)) ""))) + (out-file (cdr (assoc :file params))) + (cmdline (cdr (assoc :cmdline params))) + (in-file (org-babel-temp-file "ditaa-")) + (cmd (concat "java -jar " + (shell-quote-argument + (expand-file-name org-ditaa-jar-path)) + " " cmdline + " " (org-babel-process-file-name in-file) + " " (org-babel-process-file-name out-file)))) (unless (file-exists-p org-ditaa-jar-path) (error "Could not find ditaa.jar at %s" org-ditaa-jar-path)) (with-temp-file in-file (insert body)) - (message (concat "java -jar " org-ditaa-jar-path " " cmdline " " in-file " " out-file)) - (shell-command (concat "java -jar " (shell-quote-argument org-ditaa-jar-path) " " cmdline " " in-file " " out-file)) + (message cmd) (shell-command cmd) out-file)) (defun org-babel-prep-session:ditaa (session params) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-dot.el --- a/lisp/org/ob-dot.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-dot.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -46,10 +46,9 @@ '((:results . "file") (:exports . "results")) "Default arguments to use when evaluating a dot source block.") -(defun org-babel-expand-body:dot (body params &optional processed-params) +(defun org-babel-expand-body:dot (body params) "Expand BODY according to PARAMS, return the expanded body." - (let ((vars (nth 1 (or processed-params - (org-babel-process-params params))))) + (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))) (mapc (lambda (pair) (let ((name (symbol-name (car pair))) @@ -65,15 +64,19 @@ (defun org-babel-execute:dot (body params) "Execute a block of Dot code with org-babel. This function is called by `org-babel-execute-src-block'." - (let ((processed-params (org-babel-process-params params)) - (result-params (split-string (or (cdr (assoc :results params)) ""))) - (out-file (cdr (assoc :file params))) - (cmdline (cdr (assoc :cmdline params))) - (cmd (or (cdr (assoc :cmd params)) "dot")) - (in-file (make-temp-file "org-babel-dot"))) + (let* ((result-params (cdr (assoc :result-params params))) + (out-file (cdr (assoc :file params))) + (cmdline (or (cdr (assoc :cmdline params)) + (format "-T%s" (file-name-extension out-file)))) + (cmd (or (cdr (assoc :cmd params)) "dot")) + (in-file (org-babel-temp-file "dot-"))) (with-temp-file in-file - (insert (org-babel-expand-body:dot body params processed-params))) - (org-babel-eval (concat cmd " " in-file " " cmdline " -o " out-file) "") + (insert (org-babel-expand-body:dot body params))) + (org-babel-eval + (concat cmd + " " (org-babel-process-file-name in-file) + " " cmdline + " -o " (org-babel-process-file-name out-file)) "") out-file)) (defun org-babel-prep-session:dot (session params) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-emacs-lisp.el --- a/lisp/org/ob-emacs-lisp.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-emacs-lisp.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -36,16 +36,16 @@ (declare-function orgtbl-to-generic "org-table" (table params)) -(defun org-babel-expand-body:emacs-lisp (body params &optional processed-params) +(defun org-babel-expand-body:emacs-lisp (body params) "Expand BODY according to PARAMS, return the expanded body." - (let* ((processed-params (or processed-params (org-babel-process-params params))) - (vars (nth 1 processed-params)) - (result-params (nth 2 processed-params)) + (let* ((vars (mapcar #'cdr (org-babel-get-header params :var))) + (result-params (cdr (assoc :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))))) + (lambda (var) + (format "%S" (print `(,(car var) ',(cdr var))))) vars "\n ") ")\n" body ")") body))) @@ -56,13 +56,13 @@ (defun org-babel-execute:emacs-lisp (body params) "Execute a block of emacs-lisp code with Babel." (save-window-excursion - (let ((processed-params (org-babel-process-params params))) - (org-babel-reassemble-table - (eval (read (format "(progn %s)" - (org-babel-expand-body:emacs-lisp - body params processed-params)))) - (org-babel-pick-name (nth 4 processed-params) (cdr (assoc :colnames params))) - (org-babel-pick-name (nth 5 processed-params) (cdr (assoc :rownames params))))))) + (org-babel-reassemble-table + (eval (read (format "(progn %s)" + (org-babel-expand-body:emacs-lisp body params)))) + (org-babel-pick-name (cdr (assoc :colname-names params)) + (cdr (assoc :colnames params))) + (org-babel-pick-name (cdr (assoc :rowname-names params)) + (cdr (assoc :rownames params)))))) (provide 'ob-emacs-lisp) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-eval.el --- a/lisp/org/ob-eval.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-eval.el Thu Nov 11 22:10:19 2010 -0600 @@ -1,11 +1,11 @@ -;;; ob-run.el --- org-babel functions for external code evaluation +;;; ob-eval.el --- org-babel functions for external code evaluation ;; Copyright (C) 2009, 2010 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research, comint ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -42,7 +42,7 @@ (defun org-babel-eval (cmd body) "Run CMD on BODY. -If CMD succeeds then return it's results, otherwise display +If CMD succeeds then return its results, otherwise display STDERR with `org-babel-eval-error-notify'." (let ((err-buff (get-buffer-create "*Org-Babel Error*")) exit-code) (with-current-buffer err-buff (erase-buffer)) @@ -60,8 +60,7 @@ (defun org-babel-eval-read-file (file) "Return the contents of FILE as a string." - (with-temp-buffer (insert-file-contents - (org-babel-maybe-remote-file file)) + (with-temp-buffer (insert-file-contents file) (buffer-string))) (defun org-babel-shell-command-on-region (start end command @@ -252,4 +251,4 @@ ;; arch-tag: 5328b17f-957d-42d9-94da-a2952682d04d -;;; ob-comint.el ends here +;;; ob-eval.el ends here diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-exp.el --- a/lisp/org/ob-exp.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-exp.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte, Dan Davison ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -49,7 +49,7 @@ (defcustom org-export-babel-evaluate t "Switch controlling code evaluation during export. -When set to nil no code will be exported as part of the export +When set to nil no code will be evaluated as part of the export process." :group 'org-babel :type 'boolean) @@ -77,6 +77,30 @@ `org-babel-function-def-export-name' for the definition of a source block function.") +(defmacro org-babel-exp-in-export-file (&rest body) + `(let* ((lang-headers (intern (concat "org-babel-default-header-args:" lang))) + (heading (nth 4 (ignore-errors (org-heading-components)))) + (link (when org-current-export-file + (org-make-link-string + (if heading + (concat org-current-export-file "::" heading) + org-current-export-file)))) + (export-buffer (current-buffer)) results) + (when link + ;; resolve parameters in the original file so that + ;; headline and file-wide parameters are included, attempt + ;; to go to the same heading in the original file + (set-buffer (get-file-buffer org-current-export-file)) + (save-restriction + (condition-case nil + (org-open-link-from-string link) + (error (when heading + (goto-char (point-min)) + (re-search-forward (regexp-quote heading) nil t)))) + (setq results ,@body)) + (set-buffer export-buffer) + results))) + (defun org-babel-exp-src-blocks (body &rest headers) "Process source block for export. Depending on the 'export' headers argument in replace the source @@ -95,18 +119,27 @@ (message "org-babel-exp processing...") (save-excursion (goto-char (match-beginning 0)) - (let* ((info (org-babel-get-src-block-info)) - (params (nth 2 info))) + (let* ((info (org-babel-get-src-block-info 'light)) + (lang (nth 0 info)) + (raw-params (nth 2 info))) ;; bail if we couldn't get any info from the block (when info + (org-babel-exp-in-export-file + (setf (nth 2 info) + (org-babel-merge-params + org-babel-default-header-args + (org-babel-params-from-buffer) + (org-babel-params-from-properties lang) + (if (boundp lang-headers) (eval lang-headers) nil) + raw-params))) ;; expand noweb references in the original file (setf (nth 1 info) - (if (and (cdr (assoc :noweb params)) - (string= "yes" (cdr (assoc :noweb params)))) + (if (and (cdr (assoc :noweb (nth 2 info))) + (string= "yes" (cdr (assoc :noweb (nth 2 info))))) (org-babel-expand-noweb-references info (get-file-buffer org-current-export-file)) - (nth 1 info)))) - (org-babel-exp-do-export info 'block)))) + (nth 1 info))) + (org-babel-exp-do-export info 'block))))) (defun org-babel-exp-inline-src-blocks (start end) "Process inline source blocks between START and END for export. @@ -178,6 +211,8 @@ (list "emacs-lisp" "results" (org-babel-merge-params org-babel-default-header-args + (org-babel-params-from-buffer) + (org-babel-params-from-properties) (org-babel-parse-header-arguments (org-babel-clean-text-properties (concat ":var results=" @@ -193,8 +228,7 @@ The function respects the value of the :exports header argument." (flet ((silently () (let ((session (cdr (assoc :session (nth 2 info))))) (when (and session - (not (equal "none" session)) - (not (assoc :noeval (nth 2 info)))) + (not (equal "none" session))) (org-babel-exp-results info type 'silent)))) (clean () (org-babel-remove-result info))) (case (intern (or (cdr (assoc :exports (nth 2 info))) "code")) @@ -208,16 +242,14 @@ (defvar backend) (defun org-babel-exp-code (info type) "Prepare and return code in the current code block for export. -Code is prepared in a manner suitable for exportat by +Code is prepared in a manner suitable for export by org-mode. This function is called by `org-babel-exp-do-export'. The code block is not evaluated." (let ((lang (nth 0 info)) (body (nth 1 info)) (switches (nth 3 info)) (name (nth 4 info)) - (args (mapcar - #'cdr - (org-remove-if-not (lambda (el) (eq :var (car el))) (nth 2 info))))) + (args (mapcar #'cdr (org-babel-get-header (nth 2 info) :var)))) (case type ('inline (format "=%s=" body)) ('block @@ -249,62 +281,45 @@ This function is called by `org-babel-exp-do-export'. The code block will be evaluated. Optional argument SILENT can be used to inhibit insertion of results into the buffer." - (if org-export-babel-evaluate - (let ((lang (nth 0 info)) - (body (nth 1 info)) - (params - ;; lets ensure that we lookup references in the original file - (mapcar - (lambda (pair) - (if (and org-current-export-file - (eq (car pair) :var) - (string-match org-babel-ref-split-regexp (cdr pair)) - (equal :ob-must-be-reference - (org-babel-ref-literal - (match-string 2 (cdr pair))))) - `(:var . ,(concat (match-string 1 (cdr pair)) - "=" org-current-export-file - ":" (match-string 2 (cdr pair)))) - pair)) - (nth 2 info)))) - ;; skip code blocks which we can't evaluate - (if (fboundp (intern (concat "org-babel-execute:" lang))) - (case type - ('inline - (let ((raw (org-babel-execute-src-block - nil info '((:results . "silent")))) - (result-params (split-string - (cdr (assoc :results params))))) - (unless silent - (cond ;; respect the value of the :results header argument - ((member "file" result-params) - (org-babel-result-to-file raw)) - ((or (member "raw" result-params) - (member "org" result-params)) - (format "%s" raw)) - ((member "code" result-params) - (format "src_%s{%s}" lang raw)) - (t - (if (stringp raw) - (if (= 0 (length raw)) "=(no results)=" - (format "%s" raw)) - (format "%S" raw))))))) - ('block - (org-babel-execute-src-block - nil info (org-babel-merge-params - params - `((:results . ,(if silent "silent" "replace"))))) - "") - ('lob + (or + (when org-export-babel-evaluate + (let ((lang (nth 0 info)) + (body (nth 1 info))) + (setf (nth 2 info) (org-babel-exp-in-export-file + (org-babel-process-params (nth 2 info)))) + ;; skip code blocks which we can't evaluate + (when (fboundp (intern (concat "org-babel-execute:" lang))) + (if (equal type 'inline) + (let ((raw (org-babel-execute-src-block + nil info '((:results . "silent")))) + (result-params (split-string + (cdr (assoc :results (nth 2 info)))))) + (unless silent + (cond ;; respect the value of the :results header argument + ((member "file" result-params) + (org-babel-result-to-file raw)) + ((or (member "raw" result-params) + (member "org" result-params)) + (format "%s" raw)) + ((member "code" result-params) + (format "src_%s{%s}" lang raw)) + (t + (if (stringp raw) + (if (= 0 (length raw)) "=(no results)=" + (format "%s" raw)) + (format "%S" raw)))))) + (prog1 nil + (setf (nth 2 info) + (org-babel-merge-params + (nth 2 info) + `((:results . ,(if silent "silent" "replace"))))) + (cond + ((equal type 'block) (org-babel-execute-src-block nil info)) + ((equal type 'lob) (save-excursion (re-search-backward org-babel-lob-one-liner-regexp nil t) - (org-babel-execute-src-block - nil info (org-babel-merge-params - params - `((:results . ,(if silent "silent" "replace"))))) - ""))) - "")) - "")) + (org-babel-execute-src-block nil info))))))))) + "")) (provide 'ob-exp) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-gnuplot.el --- a/lisp/org/ob-gnuplot.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-gnuplot.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -68,11 +68,11 @@ (car pair) ;; variable name (if (listp (cdr pair)) ;; variable value (org-babel-gnuplot-table-to-data - (cdr pair) (make-temp-file "org-babel-gnuplot") params) + (cdr pair) (org-babel-temp-file "gnuplot-") params) (cdr pair)))) - (org-babel-ref-variables params))) + (mapcar #'cdr (org-babel-get-header params :var)))) -(defun org-babel-expand-body:gnuplot (body params &optional processed-params) +(defun org-babel-expand-body:gnuplot (body params) "Expand BODY according to PARAMS, return the expanded body." (save-window-excursion (let* ((vars (org-babel-gnuplot-process-vars params)) @@ -118,9 +118,9 @@ ;; insert variables into code body: this should happen last ;; placing the variables at the *top* of the code in case their ;; values are used later - (add-to-body (mapconcat - (lambda (pair) (format "%s = \"%s\"" (car pair) (cdr pair))) - vars "\n")) + (add-to-body (mapconcat #'identity + (org-babel-variable-assignments:gnuplot params) + "\n")) ;; replace any variable names preceded by '$' with the actual ;; value of the variable (mapc (lambda (pair) @@ -141,12 +141,15 @@ (save-window-excursion ;; evaluate the code body with gnuplot (if (string= session "none") - (let ((script-file (make-temp-file "org-babel-gnuplot-script"))) + (let ((script-file (org-babel-temp-file "gnuplot-script-"))) (with-temp-file script-file (insert (concat body "\n"))) (message "gnuplot \"%s\"" script-file) (setq output - (shell-command-to-string (format "gnuplot \"%s\"" script-file))) + (shell-command-to-string + (format + "gnuplot \"%s\"" + (org-babel-process-file-name script-file)))) (message output)) (with-temp-buffer (insert (concat body "\n")) @@ -159,10 +162,7 @@ (defun org-babel-prep-session:gnuplot (session params) "Prepare SESSION according to the header arguments in PARAMS." (let* ((session (org-babel-gnuplot-initiate-session session)) - (vars (org-babel-ref-variables params)) - (var-lines (mapcar - (lambda (pair) (format "%s = \"%s\"" (car pair) (cdr pair))) - vars))) + (var-lines (org-babel-variable-assignments:gnuplot params))) (message "%S" session) (org-babel-comint-in-buffer session (mapc (lambda (var-line) @@ -180,6 +180,12 @@ (insert (org-babel-chomp body))) buffer))) +(defun org-babel-variable-assignments:gnuplot (params) + "Return list of gnuplot statements assigning the block's variables" + (mapcar + (lambda (pair) (format "%s = \"%s\"" (car pair) (cdr pair))) + (org-babel-gnuplot-process-vars params))) + (defvar gnuplot-buffer) (defun org-babel-gnuplot-initiate-session (&optional session params) "Initiate a gnuplot session. diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-haskell.el --- a/lisp/org/ob-haskell.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-haskell.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -59,23 +59,14 @@ (defvar org-babel-haskell-eoe "\"org-babel-haskell-eoe\"") -(defun org-babel-expand-body:haskell (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." - (let ((vars (nth 1 (or processed-params (org-babel-process-params params))))) - (concat - (mapconcat - (lambda (pair) (format "let %s = %s" - (car pair) - (org-babel-haskell-var-to-haskell (cdr pair)))) - vars "\n") "\n" body "\n"))) - (defun org-babel-execute:haskell (body params) "Execute a block of Haskell code." - (let* ((processed-params (org-babel-process-params params)) - (session (nth 0 processed-params)) - (vars (nth 1 processed-params)) - (result-type (nth 3 processed-params)) - (full-body (org-babel-expand-body:haskell body params processed-params)) + (let* ((session (cdr (assoc :session params))) + (vars (mapcar #'cdr (org-babel-get-header params :var))) + (result-type (cdr (assoc :result-type params))) + (full-body (org-babel-expand-body:generic + body params + (org-babel-variable-assignments:haskell params))) (session (org-babel-haskell-initiate-session session params)) (raw (org-babel-comint-with-output (session org-babel-haskell-eoe t full-body) @@ -93,8 +84,10 @@ (mapconcat #'identity (reverse (cdr results)) "\n")) ((equal result-type 'value) (org-babel-haskell-table-or-string (car results)))) - (org-babel-pick-name (nth 4 processed-params) (cdr (assoc :colnames params))) - (org-babel-pick-name (nth 5 processed-params) (cdr (assoc :rownames params)))))) + (org-babel-pick-name (cdr (assoc :colname-names params)) + (cdr (assoc :colname-names params))) + (org-babel-pick-name (cdr (assoc :rowname-names params)) + (cdr (assoc :rowname-names params)))))) (defun org-babel-haskell-read-string (string) "Strip \\\"s from around a haskell string." @@ -110,34 +103,35 @@ (or (get-buffer "*haskell*") (save-window-excursion (run-haskell) (sleep-for 0.25) (current-buffer)))) -(defun org-babel-load-session:haskell - (session body params &optional processed-params) +(defun org-babel-load-session:haskell (session body params) "Load BODY into SESSION." (save-window-excursion - (let* ((buffer (org-babel-prep-session:haskell - session params processed-params)) - (load-file (concat (make-temp-file "org-babel-haskell-load") ".hs"))) + (let* ((buffer (org-babel-prep-session:haskell session params)) + (load-file (concat (org-babel-temp-file "haskell-load-") ".hs"))) (with-temp-buffer (insert body) (write-file load-file) (haskell-mode) (inferior-haskell-load-file)) buffer))) -(defun org-babel-prep-session:haskell - (session params &optional processed-params) +(defun org-babel-prep-session:haskell (session params) "Prepare SESSION according to the header arguments in PARAMS." (save-window-excursion - (let ((pp (or processed-params (org-babel-process-params params))) - (buffer (org-babel-haskell-initiate-session session))) + (let ((buffer (org-babel-haskell-initiate-session session))) (org-babel-comint-in-buffer buffer - (mapc - (lambda (pair) - (insert (format "let %s = %s" - (car pair) - (org-babel-haskell-var-to-haskell (cdr pair)))) - (comint-send-input nil t)) - (nth 1 pp))) + (mapc (lambda (line) + (insert line) + (comint-send-input nil t)) + (org-babel-variable-assignments:haskell params))) (current-buffer)))) +(defun org-babel-variable-assignments:haskell (params) + "Return list of haskell statements assigning the block's variables" + (mapcar (lambda (pair) + (format "let %s = %s" + (car pair) + (org-babel-haskell-var-to-haskell (cdr pair)))) + (mapcar #'cdr (org-babel-get-header params :var)))) + (defun org-babel-haskell-table-or-string (results) "Convert RESULTS to an Emacs-lisp table or string. If RESULTS look like a table, then convert them into an @@ -177,12 +171,14 @@ (concat "^\\([ \t]*\\)#\\+begin_src[ \t]haskell*\\(.*\\)?[\r\n]" "\\([^\000]*?\\)[\r\n][ \t]*#\\+end_src.*")) (base-name (file-name-sans-extension (buffer-file-name))) - (tmp-file (make-temp-file "ob-haskell")) + (tmp-file (org-babel-temp-file "haskell-")) (tmp-org-file (concat tmp-file ".org")) (tmp-tex-file (concat tmp-file ".tex")) (lhs-file (concat base-name ".lhs")) (tex-file (concat base-name ".tex")) - (command (concat org-babel-haskell-lhs2tex-command " " lhs-file " > " tex-file)) + (command (concat org-babel-haskell-lhs2tex-command + " " (org-babel-process-file-name lhs-file) + " > " (org-babel-process-file-name tex-file))) (preserve-indentp org-src-preserve-indentation) indentation) ;; escape haskell source-code blocks diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-js.el --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/org/ob-js.el Thu Nov 11 22:10:19 2010 -0600 @@ -0,0 +1,165 @@ +;;; ob-js.el --- org-babel functions for Javascript + +;; Copyright (C) 2010 Free Software Foundation + +;; Author: Eric Schulte +;; Keywords: literate programming, reproducible research, js +;; Homepage: http://orgmode.org +;; Version: 7.3 + +;;; License: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Now working with SBCL for both session and external evaluation. +;; +;; This certainly isn't optimally robust, but it seems to be working +;; for the basic use cases. + +;;; Requirements: + +;; - a non-browser javascript engine such as node.js http://nodejs.org/ +;; or mozrepl http://wiki.github.com/bard/mozrepl/ +;; +;; - for session based evaluation mozrepl and moz.el are required see +;; http://wiki.github.com/bard/mozrepl/emacs-integration for +;; configuration instructions + +;;; Code: +(require 'ob) +(require 'ob-ref) +(require 'ob-comint) +(require 'ob-eval) +(eval-when-compile (require 'cl)) + +(declare-function run-mozilla "ext:moz" (arg)) + +(defvar org-babel-default-header-args:js '() + "Default header arguments for js code blocks.") + +(defvar org-babel-js-eoe "org-babel-js-eoe" + "String to indicate that evaluation has completed.") + +(defcustom org-babel-js-cmd "node" + "Name of command used to evaluate js blocks." + :group 'org-babel + :type 'string) + +(defvar org-babel-js-function-wrapper + "require('sys').print(require('sys').inspect(function(){%s}()));" + "Javascript code to print value of body.") + +(defun org-babel-execute:js (body params) + "Execute a block of Javascript code with org-babel. +This function is called by `org-babel-execute-src-block'" + (let* ((org-babel-js-cmd (or (cdr (assoc :cmd params)) org-babel-js-cmd)) + (result-type (cdr (assoc :result-type params))) + (full-body (org-babel-expand-body:generic + body params (org-babel-variable-assignments:js params)))) + (org-babel-js-read + (if (not (string= (cdr (assoc :session params)) "none")) + ;; session evaluation + (let ((session (org-babel-prep-session:js + (cdr (assoc :session params)) params))) + (nth 1 + (org-babel-comint-with-output + (session (format "%S" org-babel-js-eoe) t body) + (mapc + (lambda (line) + (insert (org-babel-chomp line)) (comint-send-input nil t)) + (list body (format "%S" org-babel-js-eoe)))))) + ;; external evaluation + (let ((script-file (org-babel-temp-file "js-script-"))) + (with-temp-file script-file + (insert + ;; return the value or the output + (if (string= result-type "value") + (format org-babel-js-function-wrapper full-body) + full-body))) + (org-babel-eval + (format "%s %s" org-babel-js-cmd + (org-babel-process-file-name script-file)) "")))))) + +(defun org-babel-js-read (results) + "Convert RESULTS into an appropriate elisp value. +If RESULTS look like a table, then convert them into an +Emacs-lisp table, otherwise return the results as a string." + (org-babel-read + (if (and (stringp results) (string-match "^\\[.+\\]$" results)) + (org-babel-read + (concat "'" + (replace-regexp-in-string + "\\[" "(" (replace-regexp-in-string + "\\]" ")" (replace-regexp-in-string + ", " " " (replace-regexp-in-string + "'" "\"" results)))))) + results))) + +(defun org-babel-js-var-to-js (var) + "Convert VAR into a js variable. +Convert an elisp value into a string of js source code +specifying a variable of the same value." + (if (listp var) + (concat "[" (mapconcat #'org-babel-js-var-to-js var ", ") "]") + (format "%S" var))) + +(defun org-babel-prep-session:js (session params) + "Prepare SESSION according to the header arguments specified in PARAMS." + (let* ((session (org-babel-js-initiate-session session)) + (var-lines (org-babel-variable-assignments:js params))) + (when session + (org-babel-comint-in-buffer session + (sit-for .5) (goto-char (point-max)) + (mapc (lambda (var) + (insert var) (comint-send-input nil t) + (org-babel-comint-wait-for-output session) + (sit-for .1) (goto-char (point-max))) var-lines))) + session)) + +(defun org-babel-variable-assignments:js (params) + "Return list of Javascript statements assigning the block's variables" + (mapcar + (lambda (pair) (format "var %s=%s;" + (car pair) (org-babel-js-var-to-js (cdr pair)))) + (mapcar #'cdr (org-babel-get-header params :var)))) + +(defun org-babel-js-initiate-session (&optional session) + "If there is not a current inferior-process-buffer in SESSION +then create. Return the initialized session." + (unless (string= session "none") + (cond + ((string= "mozrepl" org-babel-js-cmd) + (require 'moz) + (let ((session-buffer (save-window-excursion + (run-mozilla nil) + (rename-buffer session) + (current-buffer)))) + (if (org-babel-comint-buffer-livep session-buffer) + (progn (sit-for .25) session-buffer) + (sit-for .5) + (org-babel-js-initiate-session session)))) + ((string= "node" org-babel-js-cmd ) + (error "session evaluation with node.js is not supported")) + (t + (error "sessions are only supported with mozrepl add \":cmd mozrepl\""))))) + +(provide 'ob-js) + +;; arch-tag: 84401fb3-b8d9-4bb6-9a90-cbe2d103d494 + +;;; ob-js.el ends here diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-keys.el --- a/lisp/org/ob-keys.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-keys.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -52,12 +52,14 @@ ("\C-p" . org-babel-previous-src-block) ("n" . org-babel-next-src-block) ("\C-n" . org-babel-next-src-block) - ("e" . org-babel-execute-src-block) - ("\C-e" . org-babel-execute-src-block) + ("e" . org-babel-execute-maybe) + ("\C-e" . org-babel-execute-maybe) ("o" . org-babel-open-src-block-result) ("\C-o" . org-babel-open-src-block-result) ("\C-v" . org-babel-expand-src-block) ("v" . org-babel-expand-src-block) + ("u" . org-babel-goto-src-block-head) + ("\C-u" . org-babel-goto-src-block-head) ("g" . org-babel-goto-named-src-block) ("r" . org-babel-goto-named-result) ("\C-r" . org-babel-goto-named-result) @@ -65,17 +67,24 @@ ("b" . org-babel-execute-buffer) ("\C-s" . org-babel-execute-subtree) ("s" . org-babel-execute-subtree) + ("\C-d" . org-babel-demarcate-block) + ("d" . org-babel-demarcate-block) ("\C-t" . org-babel-tangle) ("t" . org-babel-tangle) ("\C-f" . org-babel-tangle-file) ("f" . org-babel-tangle-file) - ("\C-l" . org-babel-lob-ingest) - ("l" . org-babel-lob-ingest) + ("\C-l" . org-babel-load-in-session) + ("l" . org-babel-load-in-session) + ("\C-i" . org-babel-lob-ingest) + ("i" . org-babel-lob-ingest) ("\C-z" . org-babel-switch-to-session) - ("z" . org-babel-switch-to-session) + ("z" . org-babel-switch-to-session-with-code) ("\C-a" . org-babel-sha1-hash) ("a" . org-babel-sha1-hash) - ("h" . org-babel-describe-bindings)) + ("h" . org-babel-describe-bindings) + ("\C-x" . org-babel-do-key-sequence-in-edit-buffer) + ("x" . org-babel-do-key-sequence-in-edit-buffer) + ("\C-\M-h" . org-babel-mark-block)) "Alist of key bindings and interactive Babel functions. This list associates interactive Babel functions with keys. Each element of this list will add an entry to the diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-latex.el --- a/lisp/org/ob-latex.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-latex.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -37,14 +37,23 @@ (declare-function org-splice-latex-header "org" (tpl def-pkg pkg snippets-p &optional extra)) (declare-function org-export-latex-fix-inputenc "org-latex" ()) +(add-to-list 'org-babel-tangle-lang-exts '("latex" . "tex")) -(add-to-list 'org-babel-tangle-lang-exts '("latex" . "tex")) +(defvar org-format-latex-header) +(defvar org-format-latex-header-extra) +(defvar org-export-latex-packages-alist) +(defvar org-export-latex-default-packages-alist) +(defvar org-export-pdf-logfiles) +(defvar org-latex-to-pdf-process) +(defvar org-export-pdf-remove-logfiles) +(defvar org-format-latex-options) +(defvar org-export-latex-packages-alist) (defvar org-babel-default-header-args:latex '((:results . "latex") (:exports . "results")) "Default arguments to use when evaluating a LaTeX source block.") -(defun org-babel-expand-body:latex (body params &optional processed-params) +(defun org-babel-expand-body:latex (body params) "Expand BODY according to PARAMS, return the expanded body." (mapc (lambda (pair) ;; replace variables (setq body @@ -52,30 +61,62 @@ (regexp-quote (format "%S" (car pair))) (if (stringp (cdr pair)) (cdr pair) (format "%S" (cdr pair))) - body))) (nth 1 (org-babel-process-params params))) - body) + body))) (mapcar #'cdr (org-babel-get-header params :var))) + (org-babel-trim body)) -(defvar org-format-latex-options) -(defvar org-export-latex-packages-alist) (defun org-babel-execute:latex (body params) "Execute a block of Latex code with Babel. This function is called by `org-babel-execute-src-block'." (setq body (org-babel-expand-body:latex body params)) (if (cdr (assoc :file params)) - (let ((out-file (cdr (assoc :file params))) - (tex-file (make-temp-file "org-babel-latex" nil ".tex")) - (pdfheight (cdr (assoc :pdfheight params))) - (pdfwidth (cdr (assoc :pdfwidth params))) - (in-buffer (not (string= "no" (cdr (assoc :buffer params))))) - (org-export-latex-packages-alist - (append (cdr (assoc :packages params)) - org-export-latex-packages-alist))) + (let* ((out-file (cdr (assoc :file params))) + (tex-file (org-babel-temp-file "latex-" ".tex")) + (border (cdr (assoc :border params))) + (fit (or (cdr (assoc :fit params)) border)) + (height (and fit (cdr (assoc :pdfheight params)))) + (width (and fit (cdr (assoc :pdfwidth params)))) + (headers (cdr (assoc :headers params))) + (in-buffer (not (string= "no" (cdr (assoc :buffer params))))) + (org-export-latex-packages-alist + (append (cdr (assoc :packages params)) + org-export-latex-packages-alist))) (cond ((string-match "\\.png$" out-file) (org-create-formula-image body out-file org-format-latex-options in-buffer)) ((string-match "\\.pdf$" out-file) - (org-babel-latex-body-to-tex-file tex-file body pdfheight pdfwidth) + (require 'org-latex) + (with-temp-file tex-file + (insert + (org-splice-latex-header + org-format-latex-header + (delq + nil + (mapcar + (lambda (el) + (unless (and (listp el) (string= "hyperref" (cadr el))) + el)) + org-export-latex-default-packages-alist)) + org-export-latex-packages-alist + org-format-latex-header-extra) + (if fit "\n\\usepackage[active, tightpage]{preview}\n" "") + (if border (format "\\setlength{\\PreviewBorder}{%s}" border) "") + (if height (concat "\n" (format "\\pdfpageheight %s" height)) "") + (if width (concat "\n" (format "\\pdfpagewidth %s" width)) "") + (if headers + (concat "\n" + (if (listp headers) + (mapconcat #'identity headers "\n") + headers) "\n") + "") + (if org-format-latex-header-extra + (concat "\n" org-format-latex-header-extra) + "") + (if fit + (concat "\n\\begin{document}\n\\begin{preview}\n" body + "\n\\end{preview}\n\\end{document}\n") + (concat "\n\\begin{document}\n" body "\n\\end{document}\n"))) + (org-export-latex-fix-inputenc)) (when (file-exists-p out-file) (delete-file out-file)) (rename-file (org-babel-latex-tex-to-pdf tex-file) out-file)) ((string-match "\\.\\([^\\.]+\\)$" out-file) @@ -84,67 +125,48 @@ out-file) body)) -(defvar org-format-latex-header) -(defvar org-format-latex-header-extra) -(defvar org-export-latex-packages-alist) -(defvar org-export-latex-default-packages-alist) -(defun org-babel-latex-body-to-tex-file (tex-file body &optional height width) - "Place the contents of BODY into TEX-FILE. -Extracted from `org-create-formula-image' in org.el." - (with-temp-file tex-file - (insert (org-splice-latex-header - org-format-latex-header - (delq - nil - (mapcar - (lambda (el) (unless (and (listp el) (string= "hyperref" (cadr el))) - el)) - org-export-latex-default-packages-alist)) - org-export-latex-packages-alist - org-format-latex-header-extra) - (if height (concat "\n" (format "\\pdfpageheight %s" height)) "") - (if width (concat "\n" (format "\\pdfpagewidth %s" width)) "") - (if org-format-latex-header-extra - (concat "\n" org-format-latex-header-extra) - "") - "\n\\begin{document}\n" body "\n\\end{document}\n") - (org-export-latex-fix-inputenc))) - -(defvar org-export-pdf-logfiles) -(defvar org-latex-to-pdf-process) -(defvar org-export-pdf-remove-logfiles) -(defun org-babel-latex-tex-to-pdf (tex-file) - "Generate a pdf file according to the contents TEX-FILE. +(defun org-babel-latex-tex-to-pdf (file) + "Generate a pdf file according to the contents FILE. Extracted from `org-export-as-pdf' in org-latex.el." (let* ((wconfig (current-window-configuration)) - (default-directory (file-name-directory tex-file)) - (base (file-name-sans-extension tex-file)) + (default-directory (file-name-directory file)) + (base (file-name-sans-extension file)) (pdffile (concat base ".pdf")) (cmds org-latex-to-pdf-process) (outbuf (get-buffer-create "*Org PDF LaTeX Output*")) - cmd) + output-dir cmd) + (with-current-buffer outbuf (erase-buffer)) + (message (concat "Processing LaTeX file " file "...")) + (setq output-dir (file-name-directory file)) (if (and cmds (symbolp cmds)) - (funcall cmds tex-file) + (funcall cmds (shell-quote-argument file)) (while cmds - (setq cmd (pop cmds)) - (while (string-match "%b" cmd) - (setq cmd (replace-match - (save-match-data - (shell-quote-argument base)) - t t cmd))) - (while (string-match "%s" cmd) - (setq cmd (replace-match - (save-match-data - (shell-quote-argument tex-file)) - t t cmd))) - (shell-command cmd outbuf outbuf))) + (setq cmd (pop cmds)) + (while (string-match "%b" cmd) + (setq cmd (replace-match + (save-match-data + (shell-quote-argument base)) + t t cmd))) + (while (string-match "%f" cmd) + (setq cmd (replace-match + (save-match-data + (shell-quote-argument file)) + t t cmd))) + (while (string-match "%o" cmd) + (setq cmd (replace-match + (save-match-data + (shell-quote-argument output-dir)) + t t cmd))) + (shell-command cmd outbuf))) + (message (concat "Processing LaTeX file " file "...done")) (if (not (file-exists-p pdffile)) - (error "PDF file was not produced from %s" tex-file) + (error (concat "PDF file " pdffile " was not produced")) (set-window-configuration wconfig) (when org-export-pdf-remove-logfiles - (dolist (ext org-export-pdf-logfiles) - (setq tex-file (concat base "." ext)) - (and (file-exists-p tex-file) (delete-file tex-file)))) + (dolist (ext org-export-pdf-logfiles) + (setq file (concat base "." ext)) + (and (file-exists-p file) (delete-file file)))) + (message "Exporting to PDF...done") pdffile))) (defun org-babel-prep-session:latex (session params) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-ledger.el --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/org/ob-ledger.el Thu Nov 11 22:10:19 2010 -0600 @@ -0,0 +1,72 @@ +;;; ob-ledger.el --- org-babel functions for ledger evaluation + +;; Copyright (C) 2010 Free Software Foundation, Inc. + +;; Author: Eric S Fraga +;; Keywords: literate programming, reproducible research, accounting +;; Homepage: http://orgmode.org +;; Version: 7.3 + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Org-Babel support for evaluating ledger entries. +;; +;; This differs from most standard languages in that +;; +;; 1) there is no such thing as a "session" in ledger +;; +;; 2) we are generally only going to return output from the leger program +;; +;; 3) we are adding the "cmdline" header argument +;; +;; 4) there are no variables + +;;; Code: +(require 'ob) + +(defvar org-babel-default-header-args:ledger + '((:results . "output") (:cmdline . "bal")) + "Default arguments to use when evaluating a ledger source block.") + +(defun org-babel-execute:ledger (body params) + "Execute a block of Ledger entries with org-babel. This function is +called by `org-babel-execute-src-block'." + (message "executing Ledger source code block") + (let ((result-params (split-string (or (cdr (assoc :results params)) ""))) + (cmdline (cdr (assoc :cmdline params))) + (in-file (org-babel-temp-file "ledger-")) + (out-file (org-babel-temp-file "ledger-output-"))) + (with-temp-file in-file (insert body)) + (message (concat "ledger" + " -f " (org-babel-process-file-name in-file) + " " cmdline)) + (with-output-to-string + (shell-command (concat "ledger" + " -f " (org-babel-process-file-name in-file) + " " cmdline + " > " (org-babel-process-file-name out-file)))) + (with-temp-buffer (insert-file-contents out-file) (buffer-string)))) + +(defun org-babel-prep-session:ledger (session params) + (error "Ledger does not support sessions")) + +(provide 'ob-ledger) + +;; arch-tag: 7bbb529e-95a1-4236-9d29-b0000b918c7c + +;;; ob-ledger.el ends here diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-lisp.el --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/org/ob-lisp.el Thu Nov 11 22:10:19 2010 -0600 @@ -0,0 +1,106 @@ +;;; ob-lisp.el --- org-babel functions for Common Lisp + +;; Copyright (C) 2010 Free Software Foundation + +;; Author: David T. O'Toole , Eric Schulte +;; Keywords: literate programming, reproducible research, lisp +;; Homepage: http://orgmode.org +;; Version: 7.3 + +;;; License: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Now working with SBCL for both session and external evaluation. +;; +;; This certainly isn't optimally robust, but it seems to be working +;; for the basic use cases. + +;;; Requirements: + +;; Requires SLIME (Superior Lisp Interaction Mode for Emacs.) +;; See http://common-lisp.net/project/slime/ + +;;; Code: +(require 'ob) +(require 'ob-ref) +(require 'ob-comint) +(require 'ob-eval) +(require 'slime) + +(defvar org-babel-default-header-args:lisp '() + "Default header arguments for lisp code blocks.") + +(defcustom org-babel-lisp-cmd "sbcl --script" + "Name of command used to evaluate lisp blocks.") + +(defun org-babel-expand-body:lisp (body params) + "Expand BODY according to PARAMS, return the expanded body." + (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))) + (if (> (length vars) 0) + (concat "(let (" + (mapconcat + (lambda (var) (format "%S" (print `(,(car var) ',(cdr var))))) + vars "\n ") + ")\n" body ")") + body))) + +(defun org-babel-execute:lisp (body params) + "Execute a block of Lisp code with org-babel. +This function is called by `org-babel-execute-src-block'" + (message "executing Lisp source code block") + (let* ((session (org-babel-lisp-initiate-session + (cdr (assoc :session params)))) + (result-type (cdr (assoc :result-type params))) + (full-body (org-babel-expand-body:lisp body params))) + (read + (if session + ;; session evaluation + (save-window-excursion + (cadr (slime-eval `(swank:eval-and-grab-output ,full-body)))) + ;; external evaluation + (let ((script-file (org-babel-temp-file "lisp-script-"))) + (with-temp-file script-file + (insert + ;; return the value or the output + (if (string= result-type "value") + (format "(print %s)" full-body) + full-body))) + (org-babel-eval + (format "%s %s" org-babel-lisp-cmd + (org-babel-process-file-name script-file)) "")))))) + +;; This function should be used to assign any variables in params in +;; the context of the session environment. +(defun org-babel-prep-session:lisp (session params) + "Prepare SESSION according to the header arguments specified in PARAMS." + (error "not yet implemented")) + +(defun org-babel-lisp-initiate-session (&optional session) + "If there is not a current inferior-process-buffer in SESSION +then create. Return the initialized session." + (unless (string= session "none") + (save-window-excursion + (or (slime-connected-p) + (slime-process))))) + +(provide 'ob-lisp) + +;; arch-tag: 18086168-009f-4947-bbb5-3532375d851d + +;;; ob-lisp.el ends here diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-lob.el --- a/lisp/org/ob-lob.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-lob.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte, Dan Davison ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -45,15 +45,22 @@ ;;;###autoload (defun org-babel-lob-ingest (&optional file) - "Add all source-blocks defined in FILE to `org-babel-library-of-babel'." + "Add all named source-blocks defined in FILE to +`org-babel-library-of-babel'." (interactive "f") - (org-babel-map-src-blocks file - (let* ((info (org-babel-get-src-block-info)) - (source-name (intern (nth 4 info)))) - (when source-name - (setq org-babel-library-of-babel - (cons (cons source-name info) - (assq-delete-all source-name org-babel-library-of-babel))))))) + (let ((lob-ingest-count 0)) + (org-babel-map-src-blocks file + (let* ((info (org-babel-get-src-block-info 'light)) + (source-name (nth 4 info))) + (when source-name + (setq source-name (intern source-name) + org-babel-library-of-babel + (cons (cons source-name info) + (assq-delete-all source-name org-babel-library-of-babel)) + lob-ingest-count (1+ lob-ingest-count))))) + (message "%d src block%s added to Library of Babel" + lob-ingest-count (if (> lob-ingest-count 1) "s" "")) + lob-ingest-count)) (defconst org-babel-lob-call-aliases '("lob" "call") "Aliases to call a source block function. @@ -61,9 +68,10 @@ become unusable by other org-babel users, and vice versa.") (defconst org-babel-lob-one-liner-regexp - (concat "^\\([ \t]*\\)#\\+\\(?:" - (mapconcat #'regexp-quote org-babel-lob-call-aliases "\\|") - "\\):[ \t]+\\([^\(\)\n]+\\)\(\\([^\n]*\\)\)[ \t]*\\([^\n]*\\)") + (concat + "^\\([ \t]*\\)#\\+\\(?:" + (mapconcat #'regexp-quote org-babel-lob-call-aliases "\\|") + "\\):[ \t]+\\([^\(\)\n]+\\)\(\\([^\n]*\\)\)\\(\\[.+\\]\\|\\)[ \t]*\\([^\n]*\\)") "Regexp to match calls to predefined source block functions.") ;; functions for executing lob one-liners @@ -76,36 +84,32 @@ (let ((info (org-babel-lob-get-info))) (if (nth 0 info) (progn (org-babel-lob-execute info) t) nil))) -(add-hook 'org-ctrl-c-ctrl-c-hook 'org-babel-lob-execute-maybe) - ;;;###autoload (defun org-babel-lob-get-info () - "Return a Library of Babel function call as a string. - -This function is analogous to org-babel-get-src-block-name. For -both functions, after they are called, (match-string 1) matches -the function name, and (match-string 2) matches the function -arguments inside the parentheses. I think perhaps these functions -should be renamed to bring out this similarity, perhaps involving -the word 'call'." + "Return a Library of Babel function call as a string." (let ((case-fold-search t)) (save-excursion (beginning-of-line 1) (if (looking-at org-babel-lob-one-liner-regexp) - (append (mapcar #'org-babel-clean-text-properties - (list (format "%s(%s)" (match-string 2) (match-string 3)) - (match-string 4))) - (list (length (match-string 1)))))))) + (append + (mapcar #'org-babel-clean-text-properties + (list + (format "%s(%s)%s" + (match-string 2) (match-string 3) (match-string 4)) + (match-string 5))) + (list (length (match-string 1)))))))) (defun org-babel-lob-execute (info) "Execute the lob call specified by INFO." - (let ((params (org-babel-merge-params - org-babel-default-header-args - (org-babel-params-from-buffer) - (org-babel-params-from-properties) - (org-babel-parse-header-arguments - (org-babel-clean-text-properties - (concat ":var results=" (mapconcat #'identity (butlast info) " "))))))) + (let ((params (org-babel-process-params + (org-babel-merge-params + org-babel-default-header-args + (org-babel-params-from-buffer) + (org-babel-params-from-properties) + (org-babel-parse-header-arguments + (org-babel-clean-text-properties + (concat ":var results=" + (mapconcat #'identity (butlast info) " ")))))))) (org-babel-execute-src-block nil (list "emacs-lisp" "results" params nil nil (nth 2 info))))) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-matlab.el --- a/lisp/org/ob-matlab.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-matlab.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Dan Davison ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-mscgen.el --- a/lisp/org/ob-mscgen.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-mscgen.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Juan Pechiar ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -62,9 +62,6 @@ '((:results . "file") (:exports . "results")) "Default arguments to use when evaluating a mscgen source block.") -(defun org-babel-expand-body:mscgen (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." body) - (defun org-babel-execute:mscgen (body params) "Execute a block of Mscgen code with Babel. This function is called by `org-babel-execute-src-block'. diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-ocaml.el --- a/lisp/org/ob-ocaml.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-ocaml.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -51,20 +51,12 @@ (defvar org-babel-ocaml-eoe-indicator "\"org-babel-ocaml-eoe\";;") (defvar org-babel-ocaml-eoe-output "org-babel-ocaml-eoe") -(defun org-babel-expand-body:ocaml (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." - (let ((vars (nth 1 (or processed-params (org-babel-process-params params))))) - (concat - (mapconcat - (lambda (pair) (format "let %s = %s;;" (car pair) - (org-babel-ocaml-elisp-to-ocaml (cdr pair)))) - vars "\n") "\n" body "\n"))) - (defun org-babel-execute:ocaml (body params) "Execute a block of Ocaml code with Babel." - (let* ((processed-params (org-babel-process-params params)) - (vars (nth 1 processed-params)) - (full-body (org-babel-expand-body:ocaml body params processed-params)) + (let* ((vars (mapcar #'cdr (org-babel-get-header params :var))) + (full-body (org-babel-expand-body:generic + body params + (org-babel-variable-assignments:ocaml params))) (session (org-babel-prep-session:ocaml (cdr (assoc :session params)) params)) (raw (org-babel-comint-with-output @@ -84,9 +76,9 @@ (org-babel-reassemble-table (org-babel-ocaml-parse-output (org-babel-trim clean)) (org-babel-pick-name - (nth 4 processed-params) (cdr (assoc :colnames params))) + (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name - (nth 5 processed-params) (cdr (assoc :rownames params)))))) + (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))) (defvar tuareg-interactive-buffer-name) (defun org-babel-prep-session:ocaml (session params) @@ -100,6 +92,13 @@ (save-window-excursion (tuareg-run-caml) (get-buffer tuareg-interactive-buffer-name)))) +(defun org-babel-variable-assignments:ocaml (params) + "Return list of ocaml statements assigning the block's variables" + (mapcar + (lambda (pair) (format "let %s = %s;;" (car pair) + (org-babel-ocaml-elisp-to-ocaml (cdr pair)))) + (mapcar #'cdr (org-babel-get-header params :var)))) + (defun org-babel-ocaml-elisp-to-ocaml (val) "Return a string of ocaml code which evaluates to VAL." (if (listp val) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-octave.el --- a/lisp/org/ob-octave.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-octave.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Dan Davison ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -47,20 +47,6 @@ (defvar org-babel-octave-shell-command "octave -q" "Shell command to run octave as an external process.") -(defun org-babel-expand-body:matlab (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." - (org-babel-expand-body:octave body params processed-params)) -(defun org-babel-expand-body:octave (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." - (let ((vars (nth 1 (or processed-params (org-babel-process-params params))))) - (concat - (mapconcat - (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-octave-var-to-octave (cdr pair)))) - vars "\n") "\n" body "\n"))) - (defvar org-babel-matlab-with-emacs-link nil "If non-nil use matlab-shell-run-region for session evaluation. This will use EmacsLink if (matlab-with-emacs-link) evaluates @@ -76,7 +62,7 @@ (defvar org-babel-octave-wrapper-method "%s if ischar(ans), fid = fopen('%s', 'w'); fprintf(fid, '%%s\\n', ans); fclose(fid); -else, save -ascii %s ans +else, dlmwrite('%s', ans, '\\t') end") (defvar org-babel-octave-eoe-indicator "\'org_babel_eoe\'") @@ -85,53 +71,60 @@ (defun org-babel-execute:matlab (body params) "Execute a block of matlab code with Babel." - (require 'matlab) (org-babel-execute:octave body params 'matlab)) + (defun org-babel-execute:octave (body params &optional matlabp) "Execute a block of octave code with Babel." - (let* ((processed-params (org-babel-process-params params)) - (session + (let* ((session (funcall (intern (format "org-babel-%s-initiate-session" (if matlabp "matlab" "octave"))) - (nth 0 processed-params) params)) - (vars (nth 1 processed-params)) - (result-params (nth 2 processed-params)) - (result-type (nth 3 processed-params)) + (cdr (assoc :session params)) params)) + (vars (mapcar #'cdr (org-babel-get-header params :var))) + (result-params (cdr (assoc :result-params params))) + (result-type (cdr (assoc :result-type params))) (out-file (cdr (assoc :file params))) - (augmented-body - (org-babel-expand-body:octave body params processed-params)) + (full-body + (org-babel-expand-body:generic + body params (org-babel-variable-assignments:octave params))) (result (org-babel-octave-evaluate - session augmented-body result-type matlabp))) + session full-body result-type matlabp))) (or out-file (org-babel-reassemble-table result (org-babel-pick-name - (nth 4 processed-params) (cdr (assoc :colnames params))) + (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name - (nth 5 processed-params) (cdr (assoc :rownames params))))))) + (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))))) (defun org-babel-prep-session:matlab (session params) "Prepare SESSION according to PARAMS." - (require 'matlab) (org-babel-prep-session:octave session params 'matlab)) + +(defun org-babel-variable-assignments:octave (params) + "Return list of octave statements assigning the block's variables" + (mapcar + (lambda (pair) + (format "%s=%s" + (car pair) + (org-babel-octave-var-to-octave (cdr pair)))) + (mapcar #'cdr (org-babel-get-header params :var)))) + +(defalias 'org-babel-variable-assignments:matlab + 'org-babel-variable-assignments:octave) + (defun org-babel-octave-var-to-octave (var) "Convert an emacs-lisp value into an octave variable. Converts an emacs-lisp variable into a string of octave code specifying a variable of the same value." (if (listp var) - (concat "[" (mapconcat #'org-babel-octave-var-to-octave var ", ") "]") - (format "%S" var))) + (concat "[" (mapconcat #'org-babel-octave-var-to-octave var + (if (listp (car var)) "; " ",")) "]") + (format "%s" (or var "nil")))) (defun org-babel-prep-session:octave (session params &optional matlabp) "Prepare SESSION according to the header arguments specified in PARAMS." (let* ((session (org-babel-octave-initiate-session session params matlabp)) - (vars (org-babel-ref-variables params)) - (var-lines (mapcar - (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-octave-var-to-octave (cdr pair)))) - vars))) + (var-lines (org-babel-variable-assignments:octave params))) (org-babel-comint-in-buffer session (mapc (lambda (var) (end-of-line 1) (insert var) (comint-send-input nil t) @@ -142,13 +135,13 @@ "Create a matlab inferior process buffer. If there is not a current inferior-process-buffer in SESSION then create. Return the initialized session." - (require 'matlab) (org-babel-octave-initiate-session session params 'matlab)) + (defun org-babel-octave-initiate-session (&optional session params matlabp) "Create an octave inferior process buffer. If there is not a current inferior-process-buffer in SESSION then create. Return the initialized session." - (require 'octave-inf) + (if matlabp (require 'matlab) (require 'octave-inf)) (unless (string= session "none") (let ((session (or session (if matlabp "*Inferior Matlab*" "*Inferior Octave*")))) @@ -161,7 +154,7 @@ (current-buffer)))))) (defun org-babel-octave-evaluate - (session body result-type lang &optional matlabp) + (session body result-type &optional matlabp) "Pass BODY to the octave process in SESSION. If RESULT-TYPE equals 'output then return the outputs of the statements in BODY, if RESULT-TYPE equals 'value then return the @@ -177,17 +170,19 @@ org-babel-octave-shell-command))) (case result-type (output (org-babel-eval cmd body)) - (value (let ((tmp-file (make-temp-file "org-babel-results-"))) + (value (let ((tmp-file (org-babel-temp-file "octave-"))) (org-babel-eval cmd - (format org-babel-octave-wrapper-method body tmp-file tmp-file)) - (org-babel-eval-read-file tmp-file)))))) + (format org-babel-octave-wrapper-method body + (org-babel-process-file-name tmp-file 'noquote) + (org-babel-process-file-name tmp-file 'noquote))) + (org-babel-octave-import-elisp-from-file tmp-file)))))) (defun org-babel-octave-evaluate-session (session body result-type &optional matlabp) "Evaluate BODY in SESSION." - (let* ((tmp-file (make-temp-file "org-babel-results-")) - (wait-file (make-temp-file "org-babel-matlab-emacs-link-wait-signal-")) + (let* ((tmp-file (org-babel-temp-file (if matlabp "matlab-" "octave-"))) + (wait-file (org-babel-temp-file "matlab-emacs-link-wait-signal-")) (full-body (case result-type (output @@ -198,11 +193,15 @@ (if (and matlabp org-babel-matlab-with-emacs-link) (concat (format org-babel-matlab-emacs-link-wrapper-method - body tmp-file tmp-file wait-file) "\n") + body + (org-babel-process-file-name tmp-file 'noquote) + (org-babel-process-file-name tmp-file 'noquote) wait-file) "\n") (mapconcat #'org-babel-chomp (list (format org-babel-octave-wrapper-method - body tmp-file tmp-file) + body + (org-babel-process-file-name tmp-file 'noquote) + (org-babel-process-file-name tmp-file 'noquote)) org-babel-octave-eoe-indicator) "\n"))))) (raw (if (and matlabp org-babel-matlab-with-emacs-link) (save-window-excursion @@ -225,8 +224,7 @@ (insert full-body) (comint-send-input nil t)))) results) (case result-type (value - (org-babel-octave-import-elisp-from-file - (org-babel-maybe-remote-file tmp-file))) + (org-babel-octave-import-elisp-from-file tmp-file)) (output (progn (setq results @@ -244,14 +242,14 @@ "Import data from FILE-NAME. This removes initial blank and comment lines and then calls `org-babel-import-elisp-from-file'." - (let ((temp-file (make-temp-file "org-babel-results-")) beg end) + (let ((temp-file (org-babel-temp-file "octave-matlab-")) beg end) (with-temp-file temp-file (insert-file-contents file-name) (re-search-forward "^[ \t]*[^# \t]" nil t) (if (< (setq beg (point-min)) (setq end (point-at-bol))) (delete-region beg end))) - (org-babel-import-elisp-from-file temp-file))) + (org-babel-import-elisp-from-file temp-file '(16)))) (defun org-babel-octave-read-string (string) "Strip \\\"s from around octave string" diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-org.el --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/org/ob-org.el Thu Nov 11 22:10:19 2010 -0600 @@ -0,0 +1,62 @@ +;;; ob-org.el --- org-babel functions for org code block evaluation + +;; Copyright (C) 2010 Free Software Foundation, Inc. + +;; Author: Eric Schulte +;; Keywords: literate programming, reproducible research +;; Homepage: http://orgmode.org +;; Version: 7.3 + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; This is the simplest of code blocks, where upon evaluation the +;; contents of the code block are returned in a raw result. + +;;; Code: +(require 'ob) + +(declare-function org-export-string "org-exp" (string fmt &optional dir)) + +(defvar org-babel-default-header-args:org + '((:results . "raw silent") (:exports . "results")) + "Default arguments for evaluating a org source block.") + +(defvar org-babel-org-default-header + "#+TITLE: default empty header\n" + "Default header inserted during export of org blocks.") + +(defun org-babel-execute:org (body params) + "Execute a block of Org code with. +This function is called by `org-babel-execute-src-block'." + (let ((result-params (split-string (or (cdr (assoc :results params)) ""))) + (body (replace-regexp-in-string "^," "" body))) + (cond + ((member "latex" result-params) (org-export-string body "latex")) + ((member "html" result-params) (org-export-string body "html")) + ((member "ascii" result-params) (org-export-string body "ascii")) + (t body)))) + +(defun org-babel-prep-session:org (session params) + "Return an error because org does not support sessions." + (error "Org does not support sessions")) + +(provide 'ob-org) + +;; arch-tag: 130af5fe-cc56-46bd-9508-fa0ebd94cb1f + +;;; ob-org.el ends here diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-perl.el --- a/lisp/org/ob-perl.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-perl.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Dan Davison, Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -38,39 +38,35 @@ (defvar org-babel-perl-command "perl" "Name of command to use for executing perl code.") -(defun org-babel-expand-body:perl (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." - (let ((vars (nth 1 (or processed-params (org-babel-process-params params))))) - (concat - (mapconcat ;; define any variables - (lambda (pair) - (format "$%s=%s;" - (car pair) - (org-babel-perl-var-to-perl (cdr pair)))) - vars "\n") "\n" (org-babel-trim body) "\n"))) - (defun org-babel-execute:perl (body params) "Execute a block of Perl code with Babel. This function is called by `org-babel-execute-src-block'." - (let* ((processed-params (org-babel-process-params params)) - (session (nth 0 processed-params)) - (vars (nth 1 processed-params)) - (result-params (nth 2 processed-params)) - (result-type (nth 3 processed-params)) - (full-body (org-babel-expand-body:perl - body params processed-params)) + (let* ((session (cdr (assoc :session params))) + (result-params (cdr (assoc :result-params params))) + (result-type (cdr (assoc :result-type params))) + (full-body (org-babel-expand-body:generic + body params (org-babel-variable-assignments:perl params))) (session (org-babel-perl-initiate-session session))) (org-babel-reassemble-table (org-babel-perl-evaluate session full-body result-type) (org-babel-pick-name - (nth 4 processed-params) (cdr (assoc :colnames params))) + (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name - (nth 5 processed-params) (cdr (assoc :rownames params)))))) + (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))) (defun org-babel-prep-session:perl (session params) "Prepare SESSION according to the header arguments in PARAMS." (error "Sessions are not supported for Perl.")) +(defun org-babel-variable-assignments:perl (params) + "Return list of perl statements assigning the block's variables" + (mapcar + (lambda (pair) + (format "$%s=%s;" + (car pair) + (org-babel-perl-var-to-perl (cdr pair)))) + (mapcar #'cdr (org-babel-get-header params :var)))) + ;; helper functions (defun org-babel-perl-var-to-perl (var) @@ -107,10 +103,11 @@ (when session (error "Sessions are not supported for Perl.")) (case result-type (output (org-babel-eval org-babel-perl-command body)) - (value (let ((tmp-file (make-temp-file "org-babel-perl-results-"))) + (value (let ((tmp-file (org-babel-temp-file "perl-"))) (org-babel-eval org-babel-perl-command - (format org-babel-perl-wrapper-method body tmp-file)) + (format org-babel-perl-wrapper-method body + (org-babel-process-file-name tmp-file 'noquote))) (org-babel-eval-read-file tmp-file))))) (provide 'ob-perl) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-plantuml.el --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/org/ob-plantuml.el Thu Nov 11 22:10:19 2010 -0600 @@ -0,0 +1,83 @@ +;;; ob-plantuml.el --- org-babel functions for plantuml evaluation + +;; Copyright (C) 2010 Free Software Foundation, Inc. + +;; Author: Zhang Weize +;; Keywords: literate programming, reproducible research +;; Homepage: http://orgmode.org +;; Version: 7.3 + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Org-Babel support for evaluating plantuml script. +;; +;; Inspired by Ian Yang's org-export-blocks-format-plantuml +;; http://www.emacswiki.org/emacs/org-export-blocks-format-plantuml.el + +;;; Requirements: + +;; plantuml | http://plantuml.sourceforge.net/ +;; plantuml.jar | `org-plantuml-jar-path' should point to the jar file + +;;; Code: +(require 'ob) +(require 'ob-eval) + +(defvar org-babel-default-header-args:plantuml + '((:results . "file") (:exports . "results")) + "Default arguments for evaluating a plantuml source block.") + +(defcustom org-plantuml-jar-path nil + "Path to the plantuml.jar file." + :group 'org-babel + :type 'string) + +(defun org-babel-execute:plantuml (body params) + "Execute a block of plantuml code with org-babel. +This function is called by `org-babel-execute-src-block'." + (let* ((result-params (split-string (or (cdr (assoc :results params)) ""))) + (out-file (or (cdr (assoc :file params)) + (error "plantuml requires a \":file\" header argument"))) + (cmdline (cdr (assoc :cmdline params))) + (in-file (org-babel-temp-file "plantuml-")) + (cmd (if (not org-plantuml-jar-path) + (error "`org-plantuml-jar-path' is not set") + (concat "java -jar " + (shell-quote-argument + (expand-file-name org-plantuml-jar-path)) + (if (string= (file-name-extension out-file) "svg") + " -tsvg" "") + " -p " cmdline " < " + (org-babel-process-file-name in-file) + " > " + (org-babel-process-file-name out-file))))) + (unless (file-exists-p org-plantuml-jar-path) + (error "Could not find plantuml.jar at %s" org-plantuml-jar-path)) + (with-temp-file in-file (insert (concat "@startuml\n" body "\n@enduml"))) + (message "%s" cmd) (org-babel-eval cmd "") + out-file)) + +(defun org-babel-prep-session:plantuml (session params) + "Return an error because plantuml does not support sessions." + (error "Plantuml does not support sessions")) + +(provide 'ob-plantuml) + +;; arch-tag: 451f50c5-e779-407e-ad64-70e0e8f161d1 + +;;; ob-plantuml.el ends here diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-python.el --- a/lisp/org/ob-python.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-python.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte, Dan Davison ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -47,46 +47,34 @@ (defvar org-babel-python-mode (if (featurep 'xemacs) 'python-mode 'python) "Preferred python mode for use in running python interactively.") -(defun org-babel-expand-body:python (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." - (concat - (mapconcat ;; define any variables - (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-python-var-to-python (cdr pair)))) - (nth 1 (or processed-params (org-babel-process-params params))) "\n") - "\n" (org-babel-trim body) "\n")) +(defvar org-src-preserve-indentation) (defun org-babel-execute:python (body params) "Execute a block of Python code with Babel. This function is called by `org-babel-execute-src-block'." - (let* ((processed-params (org-babel-process-params params)) - (session (org-babel-python-initiate-session (first processed-params))) - (result-params (nth 2 processed-params)) - (result-type (nth 3 processed-params)) - (full-body (org-babel-expand-body:python - body params processed-params)) + (let* ((session (org-babel-python-initiate-session + (cdr (assoc :session params)))) + (result-params (cdr (assoc :result-params params))) + (result-type (cdr (assoc :result-type params))) + (full-body + (org-babel-expand-body:generic + body params (org-babel-variable-assignments:python params))) (result (org-babel-python-evaluate session full-body result-type result-params))) (or (cdr (assoc :file params)) (org-babel-reassemble-table result - (org-babel-pick-name (nth 4 processed-params) + (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) - (org-babel-pick-name (nth 5 processed-params) + (org-babel-pick-name (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))))) (defun org-babel-prep-session:python (session params) - "Prepare SESSION according to the header arguments in PARAMS." + "Prepare SESSION according to the header arguments in PARAMS. +VARS contains resolved variable references" (let* ((session (org-babel-python-initiate-session session)) - (vars (org-babel-ref-variables params)) - (var-lines (mapcar ;; define any variables - (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-python-var-to-python (cdr pair)))) - vars))) + (var-lines + (org-babel-variable-assignments:python params))) (org-babel-comint-in-buffer session (mapc (lambda (var) (end-of-line 1) (insert var) (comint-send-input) @@ -104,6 +92,15 @@ ;; helper functions +(defun org-babel-variable-assignments:python (params) + "Return list of python statements assigning the block's variables" + (mapcar + (lambda (pair) + (format "%s=%s" + (car pair) + (org-babel-python-var-to-python (cdr pair)))) + (mapcar #'cdr (org-babel-get-header params :var)))) + (defun org-babel-python-var-to-python (var) "Convert an elisp value to a python variable. Convert an elisp value, VAR, into a string of python source code @@ -125,8 +122,7 @@ (mapcar (lambda (el) (if (equal el 'None) 'hline el)) res) res)) (org-babel-read - (if (or (string-match "^\\[.+\\]$" results) - (string-match "^(.+)$" results)) + (if (and (stringp results) (string-match "^[([].+[])]$" results)) (org-babel-read (concat "'" (replace-regexp-in-string @@ -151,10 +147,10 @@ (let* ((session (if session (intern session) :default)) (python-buffer (org-babel-python-session-buffer session))) (cond - ((and (equal 'python org-babel-python-mode) + ((and (eq 'python org-babel-python-mode) (fboundp 'run-python)) ; python.el (run-python)) - ((and (equal 'python-mode org-babel-python-mode) + ((and (eq 'python-mode org-babel-python-mode) (fboundp 'py-shell)) ; python-mode.el ;; `py-shell' creates a buffer whose name is the value of ;; `py-which-bufname' with '*'s at the beginning and end @@ -195,73 +191,89 @@ open('%s', 'w').write( pprint.pformat(main()) )") (defun org-babel-python-evaluate - (buffer body &optional result-type result-params) - "Pass BODY to the Python process in BUFFER. -If RESULT-TYPE equals 'output then return a list of the outputs -of the statements in BODY, if RESULT-TYPE equals 'value then -return the value of the last statement in BODY, as elisp." - (if (not buffer) - ;; external process evaluation - (case result-type - (output (org-babel-eval org-babel-python-command body)) - (value (let ((tmp-file (make-temp-file "org-babel-python-results-"))) - (org-babel-eval org-babel-python-command - (format - (if (member "pp" result-params) - org-babel-python-pp-wrapper-method - org-babel-python-wrapper-method) - (mapconcat - (lambda (line) (format "\t%s" line)) - (split-string - (org-remove-indentation - (org-babel-trim body)) - "[\r\n]") "\n") - tmp-file)) - ((lambda (raw) - (if (or (member "code" result-params) - (member "pp" result-params)) - raw - (org-babel-python-table-or-string raw))) - (org-babel-eval-read-file tmp-file))))) - ;; comint session evaluation - (flet ((dump-last-value (tmp-file pp) - (mapc - (lambda (statement) (insert statement) (comint-send-input)) - (if pp - (list - "import pp" - (format "open('%s', 'w').write(pprint.pformat(_))" tmp-file)) - (list (format "open('%s', 'w').write(str(_))" tmp-file))))) - (input-body (body) - (mapc (lambda (statement) (insert statement) (comint-send-input)) - (split-string (org-babel-trim body) "[\r\n]+")) - (comint-send-input) (comint-send-input))) - (case result-type - (output - (mapconcat - #'org-babel-trim - (butlast - (org-babel-comint-with-output - (buffer org-babel-python-eoe-indicator t body) - (let ((comint-process-echoes nil)) - (input-body body) - (insert org-babel-python-eoe-indicator) - (comint-send-input))) 2) "\n")) - (value - ((lambda (results) - (if (or (member "code" result-params) (member "pp" result-params)) - results - (org-babel-python-table-or-string results))) - (let ((tmp-file (make-temp-file "org-babel-python-results-"))) - (org-babel-comint-with-output - (buffer org-babel-python-eoe-indicator t body) - (let ((comint-process-echoes nil)) - (input-body body) - (dump-last-value tmp-file (member "pp" result-params)) - (comint-send-input) (comint-send-input) - (insert org-babel-python-eoe-indicator) - (comint-send-input))) - (org-babel-eval-read-file tmp-file)))))))) + (session body &optional result-type result-params) + "Evaluate BODY as python code." + (if session + (org-babel-python-evaluate-session + session body result-type result-params) + (org-babel-python-evaluate-external-process + body result-type result-params))) + +(defun org-babel-python-evaluate-external-process + (body &optional result-type result-params) + "Evaluate BODY in external python process. +If RESULT-TYPE equals 'output then return standard output as a +string. If RESULT-TYPE equals 'value then return the value of the +last statement in BODY, as elisp." + (case result-type + (output (org-babel-eval org-babel-python-command body)) + (value (let ((tmp-file (org-babel-temp-file "python-"))) + (org-babel-eval org-babel-python-command + (format + (if (member "pp" result-params) + org-babel-python-pp-wrapper-method + org-babel-python-wrapper-method) + (mapconcat + (lambda (line) (format "\t%s" line)) + (split-string + (org-remove-indentation + (org-babel-trim body)) + "[\r\n]") "\n") + (org-babel-process-file-name tmp-file 'noquote))) + ((lambda (raw) + (if (or (member "code" result-params) + (member "pp" result-params)) + raw + (org-babel-python-table-or-string raw))) + (org-babel-eval-read-file tmp-file)))))) + +(defun org-babel-python-evaluate-session + (session body &optional result-type result-params) + "Pass BODY to the Python process in SESSION. +If RESULT-TYPE equals 'output then return standard output as a +string. If RESULT-TYPE equals 'value then return the value of the +last statement in BODY, as elisp." + (flet ((dump-last-value + (tmp-file pp) + (mapc + (lambda (statement) (insert statement) (comint-send-input)) + (if pp + (list + "import pp" + (format "open('%s', 'w').write(pprint.pformat(_))" + (org-babel-process-file-name tmp-file 'noquote))) + (list (format "open('%s', 'w').write(str(_))" + (org-babel-process-file-name tmp-file 'noquote)))))) + (input-body (body) + (mapc (lambda (statement) (insert statement) (comint-send-input)) + (split-string (org-babel-trim body) "[\r\n]+")) + (comint-send-input) (comint-send-input))) + (case result-type + (output + (mapconcat + #'org-babel-trim + (butlast + (org-babel-comint-with-output + (session org-babel-python-eoe-indicator t body) + (let ((comint-process-echoes nil)) + (input-body body) + (insert org-babel-python-eoe-indicator) + (comint-send-input))) 2) "\n")) + (value + ((lambda (results) + (if (or (member "code" result-params) (member "pp" result-params)) + results + (org-babel-python-table-or-string results))) + (let ((tmp-file (org-babel-temp-file "python-"))) + (org-babel-comint-with-output + (session org-babel-python-eoe-indicator t body) + (let ((comint-process-echoes nil)) + (input-body body) + (dump-last-value tmp-file (member "pp" result-params)) + (comint-send-input) (comint-send-input) + (insert org-babel-python-eoe-indicator) + (comint-send-input))) + (org-babel-eval-read-file tmp-file))))))) (defun org-babel-python-read-string (string) "Strip 's from around python string" diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-ref.el --- a/lisp/org/ob-ref.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-ref.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte, Dan Davison ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -57,36 +57,26 @@ (declare-function org-at-table-p "org" (&optional table-type)) (declare-function org-count "org" (CL-ITEM CL-SEQ)) -(defun org-babel-ref-variables (params) - "Convert PARAMS to variable names and values. -Takes a parameter alist, and return an alist of variable names, -and the emacs-lisp representation of the related value." - (let ((assignments - (delq nil (mapcar (lambda (pair) (if (eq (car pair) :var) (cdr pair))) params))) - (others - (delq nil (mapcar (lambda (pair) (unless (eq :var (car pair)) pair)) params)))) - (mapcar (lambda (assignment) (org-babel-ref-parse assignment)) assignments))) - (defvar org-babel-ref-split-regexp "[ \f\t\n\r\v]*\\(.+?\\)[ \f\t\n\r\v]*=[ \f\t\n\r\v]*\\(.+\\)[ \f\t\n\r\v]*") -(defun org-babel-ref-parse (assignment &optional params) +(defun org-babel-ref-parse (assignment) "Parse a variable ASSIGNMENT in a header argument. If the right hand side of the assignment has a literal value return that value, otherwise interpret as a reference to an external resource and find it's value using -`org-babel-ref-resolve-reference'. Return a list with two -elements. The first element of the list will be the name of the -variable, and the second will be an emacs-lisp representation of -the value of the variable." - (if (string-match org-babel-ref-split-regexp assignment) - (let ((var (match-string 1 assignment)) - (ref (match-string 2 assignment))) - (cons (intern var) - ((lambda (val) - (if (equal :ob-must-be-reference val) - (org-babel-ref-resolve-reference ref params) - val)) (org-babel-ref-literal ref)))))) +`org-babel-ref-resolve'. Return a list with two elements. The +first element of the list will be the name of the variable, and +the second will be an emacs-lisp representation of the value of +the variable." + (when (string-match org-babel-ref-split-regexp assignment) + (let ((var (match-string 1 assignment)) + (ref (match-string 2 assignment))) + (cons (intern var) + ((lambda (val) + (if (equal :ob-must-be-reference val) + (org-babel-ref-resolve ref) val)) + (org-babel-ref-literal ref)))))) (defun org-babel-ref-literal (ref) "Return the value of REF if it is a literal value. @@ -103,7 +93,7 @@ out))) (defvar org-babel-library-of-babel) -(defun org-babel-ref-resolve-reference (ref &optional params) +(defun org-babel-ref-resolve (ref) "Resolve the reference REF and return its value." (save-excursion (let ((case-fold-search t) @@ -119,12 +109,10 @@ (when (string-match "^\\(.+?\\)\(\\(.*\\)\)$" ref) (setq new-refere (match-string 1 ref)) (setq new-referent (match-string 2 ref)) - ;; (message "new-refere=%S, new-referent=%S" new-refere new-referent) ;; debugging (when (> (length new-refere) 0) (if (> (length new-referent) 0) (setq args (mapcar (lambda (ref) (cons :var ref)) (org-babel-ref-split-args new-referent)))) - ;; (message "args=%S" args) ;; debugging (setq ref new-refere))) (when (string-match "^\\(.+\\):\\(.+\\)$" ref) (setq split-file (match-string 1 ref)) @@ -133,7 +121,8 @@ (save-restriction (widen) (goto-char (point-min)) - (if (let ((result_regexp (concat "^[ \t]*#\\+\\(TBLNAME\\|RESNAME\\|RESULTS\\):[ \t]*" + (if (let ((result_regexp (concat "^[ \t]*#\\+\\(TBLNAME\\|RESNAME" + "\\|RESULTS\\):[ \t]*" (regexp-quote ref) "[ \t]*$")) (regexp (concat org-babel-src-name-regexp (regexp-quote ref) "\\(\(.*\)\\)?" "[ \t]*$"))) @@ -144,7 +133,8 @@ (re-search-forward regexp nil t) (re-search-backward regexp nil t) ;; check the Library of Babel - (setq lob-info (cdr (assoc (intern ref) org-babel-library-of-babel))))) + (setq lob-info (cdr (assoc (intern ref) + org-babel-library-of-babel))))) (unless lob-info (goto-char (match-beginning 0))) ;; ;; TODO: allow searching for names in other buffers ;; (setq id-loc (org-id-find ref 'marker) @@ -159,14 +149,14 @@ (beginning-of-line) (if (or (= (point) (point-min)) (= (point) (point-max))) (error "reference not found")))) - (setq params (org-babel-merge-params params args '((:results . "silent")))) - (setq result - (case type - ('results-line (org-babel-read-result)) - ('table (org-babel-read-table)) - ('file (org-babel-read-link)) - ('source-block (org-babel-execute-src-block nil nil params)) - ('lob (org-babel-execute-src-block nil lob-info params)))) + (let ((params (append args '((:results . "silent"))))) + (setq result + (case type + ('results-line (org-babel-read-result)) + ('table (org-babel-read-table)) + ('file (org-babel-read-link)) + ('source-block (org-babel-execute-src-block nil nil params)) + ('lob (org-babel-execute-src-block nil lob-info params))))) (if (symbolp result) (format "%S" result) (if (and index (listp result)) @@ -199,7 +189,7 @@ (if (or (= 0 (length portion)) (string-match ind-re portion)) (mapcar (lambda (n) (nth n lis)) - (apply 'number-sequence + (apply 'org-number-sequence (if (and (> (length portion) 0) (match-string 2 portion)) (list (wrap (string-to-number (match-string 2 portion))) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-ruby.el --- a/lisp/org/ob-ruby.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-ruby.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -52,48 +52,30 @@ (defvar org-babel-ruby-command "ruby" "Name of command to use for executing ruby code.") -(defun org-babel-expand-body:ruby (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." - (require 'inf-ruby) - (let ((vars (nth 1 (or processed-params (org-babel-process-params params))))) - (concat - (mapconcat ;; define any variables - (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-ruby-var-to-ruby (cdr pair)))) - vars "\n") "\n" body "\n"))) - (defun org-babel-execute:ruby (body params) "Execute a block of Ruby code with Babel. This function is called by `org-babel-execute-src-block'." - (let* ((processed-params (org-babel-process-params params)) - (session (org-babel-ruby-initiate-session (first processed-params))) - (result-params (nth 2 processed-params)) - (result-type (nth 3 processed-params)) - (full-body (org-babel-expand-body:ruby - body params processed-params)) + (let* ((session (org-babel-ruby-initiate-session + (cdr (assoc :session params)))) + (result-params (cdr (assoc :result-params params))) + (result-type (cdr (assoc :result-type params))) + (full-body (org-babel-expand-body:generic + body params (org-babel-variable-assignments:ruby params))) (result (org-babel-ruby-evaluate session full-body result-type result-params))) (or (cdr (assoc :file params)) (org-babel-reassemble-table result - (org-babel-pick-name (nth 4 processed-params) + (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) - (org-babel-pick-name (nth 5 processed-params) + (org-babel-pick-name (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))))) (defun org-babel-prep-session:ruby (session params) "Prepare SESSION according to the header arguments specified in PARAMS." ;; (message "params=%S" params) ;; debugging (let* ((session (org-babel-ruby-initiate-session session)) - (vars (org-babel-ref-variables params)) - (var-lines (mapcar ;; define any variables - (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-ruby-var-to-ruby (cdr pair)))) - vars))) + (var-lines (org-babel-variable-assignments:ruby params))) (org-babel-comint-in-buffer session (sit-for .5) (goto-char (point-max)) (mapc (lambda (var) @@ -113,6 +95,15 @@ ;; helper functions +(defun org-babel-variable-assignments:ruby (params) + "Return list of ruby statements assigning the block's variables" + (mapcar + (lambda (pair) + (format "%s=%s" + (car pair) + (org-babel-ruby-var-to-ruby (cdr pair)))) + (mapcar #'cdr (org-babel-get-header params :var)))) + (defun org-babel-ruby-var-to-ruby (var) "Convert VAR into a ruby variable. Convert an elisp value into a string of ruby source code @@ -186,12 +177,13 @@ ;; external process evaluation (case result-type (output (org-babel-eval org-babel-ruby-command body)) - (value (let ((tmp-file (make-temp-file "org-babel-ruby-results-"))) - (org-babel-eval org-babel-ruby-command - (format (if (member "pp" result-params) - org-babel-ruby-pp-wrapper-method - org-babel-ruby-wrapper-method) - body tmp-file)) + (value (let ((tmp-file (org-babel-temp-file "ruby-"))) + (org-babel-eval + org-babel-ruby-command + (format (if (member "pp" result-params) + org-babel-ruby-pp-wrapper-method + org-babel-ruby-wrapper-method) + body (org-babel-process-file-name tmp-file 'noquote))) ((lambda (raw) (if (or (member "code" result-params) (member "pp" result-params)) @@ -221,7 +213,7 @@ (if (or (member "code" result-params) (member "pp" result-params)) results (org-babel-ruby-table-or-string results))) - (let* ((tmp-file (make-temp-file "org-babel-ruby-results-")) + (let* ((tmp-file (org-babel-temp-file "ruby-")) (ppp (or (member "code" result-params) (member "pp" result-params)))) (org-babel-comint-with-output @@ -233,10 +225,12 @@ (append (list body) (if (not ppp) - (list (format org-babel-ruby-f-write tmp-file)) + (list (format org-babel-ruby-f-write + (org-babel-process-file-name tmp-file 'noquote))) (list "results=_" "require 'pp'" "orig_out = $stdout" - (format org-babel-ruby-pp-f-write tmp-file))) + (format org-babel-ruby-pp-f-write + (org-babel-process-file-name tmp-file 'noquote)))) (list org-babel-ruby-eoe-indicator))) (comint-send-input nil t)) (org-babel-eval-read-file tmp-file))))))) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-sass.el --- a/lisp/org/ob-sass.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-sass.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -43,20 +43,19 @@ (defvar org-babel-default-header-args:sass '()) -(defun org-babel-expand-body:sass (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." body) - (defun org-babel-execute:sass (body params) "Execute a block of Sass code with Babel. This function is called by `org-babel-execute-src-block'." (let* ((result-params (split-string (or (cdr (assoc :results params)) ""))) (file (cdr (assoc :file params))) - (out-file (or file (make-temp-file "org-babel-sass-out"))) + (out-file (or file (org-babel-temp-file "sass-out-"))) (cmdline (cdr (assoc :cmdline params))) - (in-file (make-temp-file "org-babel-sass-in")) - (cmd (concat "sass " (or cmdline "") in-file " " out-file))) + (in-file (org-babel-temp-file "sass-in-")) + (cmd (concat "sass " (or cmdline "") + " " (org-babel-process-file-name in-file) + " " (org-babel-process-file-name out-file)))) (with-temp-file in-file - (insert (org-babel-expand-body:sass body params))) (shell-command cmd) + (insert (org-babel-expand-body:generic body params))) (shell-command cmd) (or file (with-temp-buffer (insert-file-contents out-file) (buffer-string))))) (defun org-babel-prep-session:sass (session params) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-scheme.el --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/org/ob-scheme.el Thu Nov 11 22:10:19 2010 -0600 @@ -0,0 +1,139 @@ +;;; ob-scheme.el --- org-babel functions for Scheme + +;; Copyright (C) 2010 Free Software Foundation + +;; Author: Eric Schulte +;; Keywords: literate programming, reproducible research, scheme +;; Homepage: http://orgmode.org +;; Version: 7.3 + +;;; License: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Now working with SBCL for both session and external evaluation. +;; +;; This certainly isn't optimally robust, but it seems to be working +;; for the basic use cases. + +;;; Requirements: + +;; - a working scheme implementation +;; (e.g. guile http://www.gnu.org/software/guile/guile.html) +;; +;; - for session based evaluation cmuscheme.el is required which is +;; included in Emacs + +;;; Code: +(require 'ob) +(require 'ob-ref) +(require 'ob-comint) +(require 'ob-eval) +(eval-when-compile (require 'cl)) + +(declare-function run-scheme "ext:cmuscheme" (cmd)) + +(defvar org-babel-default-header-args:scheme '() + "Default header arguments for scheme code blocks.") + +(defvar org-babel-scheme-eoe "org-babel-scheme-eoe" + "String to indicate that evaluation has completed.") + +(defcustom org-babel-scheme-cmd "guile" + "Name of command used to evaluate scheme blocks." + :group 'org-babel + :type 'string) + +(defun org-babel-expand-body:scheme (body params) + "Expand BODY according to PARAMS, return the expanded body." + (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))) + (if (> (length vars) 0) + (concat "(let (" + (mapconcat + (lambda (var) (format "%S" (print `(,(car var) ',(cdr var))))) + vars "\n ") + ")\n" body ")") + body))) + +(defvar scheme-program-name) +(defun org-babel-execute:scheme (body params) + "Execute a block of Scheme code with org-babel. +This function is called by `org-babel-execute-src-block'" + (let* ((result-type (cdr (assoc :result-type params))) + (org-babel-scheme-cmd (or (cdr (assoc :scheme params)) + org-babel-scheme-cmd)) + (full-body (org-babel-expand-body:scheme body params))) + (read + (if (not (string= (cdr (assoc :session params)) "none")) + ;; session evaluation + (let ((session (org-babel-prep-session:scheme + (cdr (assoc :session params)) params))) + (org-babel-comint-with-output + (session (format "%S" org-babel-scheme-eoe) t body) + (mapc + (lambda (line) + (insert (org-babel-chomp line)) (comint-send-input nil t)) + (list body (format "%S" org-babel-scheme-eoe))))) + ;; external evaluation + (let ((script-file (org-babel-temp-file "scheme-script-"))) + (with-temp-file script-file + (insert + ;; return the value or the output + (if (string= result-type "value") + (format "(display %s)" full-body) + full-body))) + (org-babel-eval + (format "%s %s" org-babel-scheme-cmd + (org-babel-process-file-name script-file)) "")))))) + +(defun org-babel-prep-session:scheme (session params) + "Prepare SESSION according to the header arguments specified in PARAMS." + (let* ((session (org-babel-scheme-initiate-session session)) + (vars (mapcar #'cdr (org-babel-get-header params :var))) + (var-lines + (mapcar + (lambda (var) (format "%S" (print `(define ,(car var) ',(cdr var))))) + vars))) + (when session + (org-babel-comint-in-buffer session + (sit-for .5) (goto-char (point-max)) + (mapc (lambda (var) + (insert var) (comint-send-input nil t) + (org-babel-comint-wait-for-output session) + (sit-for .1) (goto-char (point-max))) var-lines))) + session)) + +(defun org-babel-scheme-initiate-session (&optional session) + "If there is not a current inferior-process-buffer in SESSION +then create. Return the initialized session." + (require 'cmuscheme) + (unless (string= session "none") + (let ((session-buffer (save-window-excursion + (run-scheme org-babel-scheme-cmd) + (rename-buffer session) + (current-buffer)))) + (if (org-babel-comint-buffer-livep session-buffer) + (progn (sit-for .25) session-buffer) + (sit-for .5) + (org-babel-scheme-initiate-session session))))) + +(provide 'ob-scheme) + +;; arch-tag: 6b2fe76f-4b25-4e87-ad1c-225b2f282a71 + +;;; ob-scheme.el ends here diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-screen.el --- a/lisp/org/ob-screen.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-screen.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Benjamin Andresen ;; Keywords: literate programming, interactive shell ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -45,28 +45,21 @@ '((:results . "silent") (:session . "default") (:cmd . "sh") (:terminal . "xterm")) "Default arguments to use when running screen source blocks.") -(defun org-babel-expand-body:screen (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." body) - (defun org-babel-execute:screen (body params) "Send a block of code via screen to a terminal using Babel. -\"default\" session is be used when none is specified." +\"default\" session is used when none is specified." (message "Sending source code block to interactive terminal session...") (save-window-excursion - (let* ((processed-params (org-babel-process-params params)) - (session (nth 0 processed-params)) + (let* ((session (cdr (assoc :session params))) (socket (org-babel-screen-session-socketname session))) (unless socket (org-babel-prep-session:screen session params)) (org-babel-screen-session-execute-string - session (org-babel-expand-body:screen body params))))) + session (org-babel-expand-body:generic body params))))) (defun org-babel-prep-session:screen (session params) "Prepare SESSION according to the header arguments specified in PARAMS." - (let* ((processed-params (org-babel-process-params params)) - (session (nth 0 processed-params)) - (vars (nth 1 processed-params)) + (let* ((session (cdr (assoc :session params))) (socket (org-babel-screen-session-socketname session)) - (vars (org-babel-ref-variables params)) (cmd (cdr (assoc :cmd params))) (terminal (cdr (assoc :terminal params))) (process-name (concat "org-babel: terminal (" session ")"))) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-sh.el --- a/lisp/org/ob-sh.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-sh.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -33,7 +33,10 @@ (require 'shell) (eval-when-compile (require 'cl)) -(declare-function org-babel-ref-variables "ob-ref" (params)) +(declare-function org-babel-comint-in-buffer "ob-comint" (buffer &rest body)) +(declare-function org-babel-comint-wait-for-output "ob-comint" (buffer)) +(declare-function org-babel-comint-buffer-livep "ob-comint" (buffer)) +(declare-function org-babel-comint-with-output "ob-comint" (meta &rest body)) (declare-function orgtbl-to-generic "org-table" (table params)) (defvar org-babel-default-header-args:sh '()) @@ -42,44 +45,25 @@ "Command used to invoke a shell. This will be passed to `shell-command-on-region'") -(defun org-babel-expand-body:sh (body params &optional processed-params) - "Expand BODY according to PARAMS, return the expanded body." - (let ((vars (nth 1 (or processed-params (org-babel-process-params params)))) - (sep (cdr (assoc :separator params)))) - (concat - (mapconcat ;; define any variables - (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-sh-var-to-sh (cdr pair) sep))) - vars "\n") "\n" body "\n\n"))) - (defun org-babel-execute:sh (body params) "Execute a block of Shell commands with Babel. This function is called by `org-babel-execute-src-block'." - (let* ((processed-params (org-babel-process-params params)) - (session (org-babel-sh-initiate-session (nth 0 processed-params))) - (result-params (nth 2 processed-params)) - (full-body (org-babel-expand-body:sh - body params processed-params))) + (let* ((session (org-babel-sh-initiate-session + (cdr (assoc :session params)))) + (result-params (cdr (assoc :result-params params))) + (full-body (org-babel-expand-body:generic + body params (org-babel-variable-assignments:sh params)))) (org-babel-reassemble-table (org-babel-sh-evaluate session full-body result-params) (org-babel-pick-name - (nth 4 processed-params) (cdr (assoc :colnames params))) + (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name - (nth 5 processed-params) (cdr (assoc :rownames params)))))) + (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))) (defun org-babel-prep-session:sh (session params) "Prepare SESSION according to the header arguments specified in PARAMS." (let* ((session (org-babel-sh-initiate-session session)) - (vars (org-babel-ref-variables params)) - (sep (cdr (assoc :separator params))) - (var-lines (mapcar ;; define any variables - (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-sh-var-to-sh (cdr pair) sep))) - vars))) + (var-lines (org-babel-variable-assignments:sh params))) (org-babel-comint-in-buffer session (mapc (lambda (var) (insert var) (comint-send-input nil t) @@ -97,6 +81,16 @@ ;; helper functions +(defun org-babel-variable-assignments:sh (params) + "Return list of shell statements assigning the block's variables" + (let ((sep (cdr (assoc :separator params)))) + (mapcar + (lambda (pair) + (format "%s=%s" + (car pair) + (org-babel-sh-var-to-sh (cdr pair) sep))) + (mapcar #'cdr (org-babel-get-header params :var))))) + (defun org-babel-sh-var-to-sh (var &optional sep) "Convert an elisp value to a shell variable. Convert an elisp var into a string of shell commands specifying a @@ -108,7 +102,8 @@ (org-babel-sh-var-to-sh el sep)))) (format "$(cat < %s" - (or cmdline "") in-file out-file)) + (or cmdline "") + (org-babel-process-file-name in-file) + (org-babel-process-file-name out-file))) + ('postgresql (format "psql -A -P footer=off -F \"\t\" -f %s -o %s %s" + (org-babel-process-file-name in-file) + (org-babel-process-file-name out-file) + (or cmdline ""))) (t (error "no support for the %s sql engine" engine))))) (with-temp-file in-file - (insert (org-babel-expand-body:sql body params))) + (insert (org-babel-expand-body:generic body params))) (message command) (shell-command command) (with-temp-buffer (org-table-import out-file nil) (org-babel-reassemble-table (org-table-to-lisp) - (org-babel-pick-name (nth 4 processed-params) (cdr (assoc :colnames params))) - (org-babel-pick-name (nth 5 processed-params) (cdr (assoc :rownames params))))))) + (org-babel-pick-name (cdr (assoc :colname-names params)) + (cdr (assoc :colnames params))) + (org-babel-pick-name (cdr (assoc :rowname-names params)) + (cdr (assoc :rownames params))))))) (defun org-babel-prep-session:sql (session params) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-sqlite.el --- a/lisp/org/ob-sqlite.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-sqlite.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -41,9 +41,10 @@ '(db header echo bail csv column html line list separator nullvalue) "Sqlite specific header args.") -(defun org-babel-expand-body:sqlite (body params &optional processed-params) +(defun org-babel-expand-body:sqlite (body params) + "Expand BODY according to the values of PARAMS." (org-babel-sqlite-expand-vars - body (or (nth 1 processed-params) (org-babel-ref-variables params)))) + body (mapcar #'cdr (org-babel-get-header params :var)))) (defvar org-babel-sqlite3-command "sqlite3") @@ -51,7 +52,7 @@ "Execute a block of Sqlite code with Babel. This function is called by `org-babel-execute-src-block'." (let ((result-params (split-string (or (cdr (assoc :results params)) ""))) - (vars (org-babel-ref-variables params)) + (vars (org-babel-get-header params :var)) (db (cdr (assoc :db params))) (separator (cdr (assoc :separator params))) (nullvalue (cdr (assoc :nullvalue params))) @@ -70,10 +71,9 @@ (list (cons "body" ((lambda (sql-file) (with-temp-file sql-file - (insert (org-babel-expand-body:sqlite - body nil (list nil vars)))) + (insert (org-babel-expand-body:sqlite body params))) sql-file) - (make-temp-file "ob-sqlite-sql"))) + (org-babel-temp-file "sqlite-sql-"))) (cons "cmd" org-babel-sqlite3-command) (cons "header" (if headers-p "-header" "-noheader")) (cons "separator" @@ -117,8 +117,8 @@ el (format "%S" el))))))) data-file) - (make-temp-file "ob-sqlite-data")) - (format "%S" val))) + (org-babel-temp-file "sqlite-data-")) + (if (stringp val) val (format "%S" val)))) (cdr pair)) body))) vars) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-table.el --- a/lisp/org/ob-table.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-table.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -79,13 +79,24 @@ cell's value as a string, prefix the identifier with two \"$\"s rather than a single \"$\" (i.e. \"$$2\" instead of \"$2\" in the example above." - (let ((variables (mapcar - (lambda (var) - (if (and (= 3 (length var)) (eq (nth 1 var) '$)) - (list (car var) (format "\"%s\"" (last var))) - var)) - variables))) - (unless (stringp source-block) (setq source-block (symbol-name source-block))) + (let* (quote + (variables + (mapcar + (lambda (var) + ;; ensure that all cells prefixed with $'s are strings + (cons (car var) + (delq nil (mapcar + (lambda (el) + (if (eq '$ el) + (setq quote t) + (prog1 (if quote + (format "\"%s\"" el) + (org-babel-clean-text-properties el)) + (setq quote nil)))) + (cdr var))))) + variables))) + (unless (stringp source-block) + (setq source-block (symbol-name source-block))) (org-babel-table-truncate-at-newline ;; org-table cells can't be multi-line (if (and source-block (> (length source-block) 0)) (let ((params @@ -93,13 +104,18 @@ (concat ":var results=" ,source-block "(" - (mapconcat (lambda (var-spec) - (format "%S=%s" (nth 0 var-spec) (nth 1 var-spec))) - ',variables ", ") + (mapconcat + (lambda (var-spec) + (if (> (length (cdr var-spec)) 1) + (format "%S='%S" + (car var-spec) + (mapcar #'read (cdr var-spec))) + (format "%S=%s" + (car var-spec) (cadr var-spec)))) + ',variables ", ") ")"))))) (org-babel-execute-src-block - nil (list "emacs-lisp" "results" - (org-babel-merge-params '((:results . "silent")) params)))) + nil (list "emacs-lisp" "results" params) '((:results . "silent")))) "")))) (provide 'ob-table) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob-tangle.el --- a/lisp/org/ob-tangle.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob-tangle.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -34,7 +34,11 @@ (declare-function org-link-escape "org" (text &optional table)) (declare-function org-heading-components "org" ()) +(declare-function org-back-to-heading "org" (invisible-ok)) +(declare-function org-fill-template "org" (template alist)) +(declare-function org-babel-update-block-body "org" (new-body)) +;;;###autoload (defcustom org-babel-tangle-lang-exts '(("emacs-lisp" . "el")) "Alist mapping languages to their file extensions. @@ -53,18 +57,66 @@ :group 'org-babel :type 'hook) +(defcustom org-babel-pre-tangle-hook '(save-buffer) + "Hook run at the beginning of `org-babel-tangle'." + :group 'org-babel + :type 'hook) + +(defcustom org-babel-tangle-pad-newline t + "Switch indicating whether to pad tangled code with newlines." + :group 'org-babel + :type 'boolean) + +(defcustom org-babel-tangle-comment-format-beg "[[%link][%source-name]]" + "Format of inserted comments in tangled code files. +The following format strings can be used to insert special +information into the output using `org-fill-template'. +%start-line --- the line number at the start of the code block +%file --------- the file from which the code block was tangled +%link --------- Org-mode style link to the code block +%source-name -- name of the code block + +Whether or not comments are inserted during tangling is +controlled by the :comments header argument." + :group 'org-babel + :type 'string) + +(defcustom org-babel-tangle-comment-format-end "%source-name ends here" + "Format of inserted comments in tangled code files. +The following format strings can be used to insert special +information into the output using `org-fill-template'. +%start-line --- the line number at the start of the code block +%file --------- the file from which the code block was tangled +%link --------- Org-mode style link to the code block +%source-name -- name of the code block + +Whether or not comments are inserted during tangling is +controlled by the :comments header argument." + :group 'org-babel + :type 'string) + +(defun org-babel-find-file-noselect-refresh (file) + "Find file ensuring that the latest changes on disk are +represented in the file." + (find-file-noselect file) + (with-current-buffer (get-file-buffer file) + (revert-buffer t t t))) + (defmacro org-babel-with-temp-filebuffer (file &rest body) "Open FILE into a temporary buffer execute BODY there like `progn', then kill the FILE buffer returning the result of evaluating BODY." (declare (indent 1)) (let ((temp-result (make-symbol "temp-result")) - (temp-file (make-symbol "temp-file"))) - `(let (,temp-result ,temp-file) - (find-file ,file) - (setf ,temp-file (current-buffer)) - (setf ,temp-result (progn ,@body)) - (kill-buffer ,temp-file) + (temp-file (make-symbol "temp-file")) + (visited-p (make-symbol "visited-p"))) + `(let (,temp-result ,temp-file + (,visited-p (get-file-buffer ,file))) + (org-babel-find-file-noselect-refresh ,file) + (setf ,temp-file (get-file-buffer ,file)) + (with-current-buffer ,temp-file + (setf ,temp-result (progn ,@body))) + (unless ,visited-p (kill-buffer ,temp-file)) ,temp-result))) ;;;###autoload @@ -117,7 +169,7 @@ source blocks. Optional argument LANG can be used to limit the exported source code blocks by language." (interactive) - (save-buffer) + (run-hooks 'org-babel-pre-tangle-hook) (save-excursion (let ((block-counter 0) (org-babel-default-header-args @@ -142,7 +194,7 @@ (mapc (lambda (spec) (flet ((get-spec (name) - (cdr (assoc name (nth 2 spec))))) + (cdr (assoc name (nth 4 spec))))) (let* ((tangle (get-spec :tangle)) (she-bang ((lambda (sheb) (when (> (length sheb) 0) sheb)) (get-spec :shebang))) @@ -177,14 +229,15 @@ (insert content) (write-region nil nil file-name)))) ;; if files contain she-bangs, then make the executable - (when she-bang (set-file-modes file-name ?\755)) + (when she-bang (set-file-modes file-name #o755)) ;; update counter (setq block-counter (+ 1 block-counter)) (add-to-list 'path-collector file-name))))) specs))) (org-babel-tangle-collect-blocks lang)) - (message "tangled %d code block%s" block-counter - (if (= block-counter 1) "" "s")) + (message "tangled %d code block%s from %s" block-counter + (if (= block-counter 1) "" "s") + (file-name-nondirectory (buffer-file-name (current-buffer)))) ;; run `org-babel-post-tangle-hook' in all tangled files (when org-babel-post-tangle-hook (mapc @@ -209,7 +262,7 @@ (save-excursion (end-of-line 1) (forward-char 1) (point))))) (defvar org-stored-links) -(defun org-babel-tangle-collect-blocks (&optional lang) +(defun org-babel-tangle-collect-blocks (&optional language) "Collect source blocks in the current Org-mode file. Return an association list of source-code block specifications of the form used by `org-babel-spec-to-string' grouped by language. @@ -224,44 +277,69 @@ (setq current-heading new-heading)) (setq block-counter (+ 1 block-counter)))) (replace-regexp-in-string "[ \t]" "-" - (nth 4 (org-heading-components)))) - (let* ((link (progn (call-interactively 'org-store-link) - (org-babel-clean-text-properties - (car (pop org-stored-links))))) - (info (org-babel-get-src-block-info)) - (source-name (intern (or (nth 4 info) - (format "%s:%d" - current-heading block-counter)))) - (src-lang (nth 0 info)) - (expand-cmd (intern (concat "org-babel-expand-body:" src-lang))) - (params (nth 2 info)) - by-lang) - (unless (string= (cdr (assoc :tangle params)) "no") ;; skip - (unless (and lang (not (string= lang src-lang))) ;; limit by language - ;; add the spec for this block to blocks under it's language - (setq by-lang (cdr (assoc src-lang blocks))) - (setq blocks (delq (assoc src-lang blocks) blocks)) - (setq blocks - (cons - (cons src-lang - (cons (list link source-name params - ((lambda (body) - (if (assoc :no-expand params) - body - (funcall - (if (fboundp expand-cmd) - expand-cmd - 'org-babel-expand-body:generic) - body - params))) - (if (and (cdr (assoc :noweb params)) - (string= - "yes" - (cdr (assoc :noweb params)))) - (org-babel-expand-noweb-references - info) - (nth 1 info)))) - by-lang)) blocks)))))) + (condition-case nil + (nth 4 (org-heading-components)) + (error (buffer-file-name))))) + (let* ((start-line (save-restriction (widen) + (+ 1 (line-number-at-pos (point))))) + (file (buffer-file-name)) + (info (org-babel-get-src-block-info 'light)) + (src-lang (nth 0 info))) + (unless (string= (cdr (assoc :tangle (nth 2 info))) "no") + (unless (and language (not (string= language src-lang))) + (let* ((info (org-babel-get-src-block-info)) + (params (nth 2 info)) + (link (progn (call-interactively 'org-store-link) + (org-babel-clean-text-properties + (car (pop org-stored-links))))) + (source-name + (intern (or (nth 4 info) + (format "%s:%d" + current-heading block-counter)))) + (expand-cmd + (intern (concat "org-babel-expand-body:" src-lang))) + (assignments-cmd + (intern (concat "org-babel-variable-assignments:" src-lang))) + (body + ((lambda (body) + (if (assoc :no-expand params) + body + (if (fboundp expand-cmd) + (funcall expand-cmd body params) + (org-babel-expand-body:generic + body params + (and (fboundp assignments-cmd) + (funcall assignments-cmd params)))))) + (if (and (cdr (assoc :noweb params)) + (let ((nowebs (split-string + (cdr (assoc :noweb params))))) + (or (member "yes" nowebs) + (member "tangle" nowebs)))) + (org-babel-expand-noweb-references info) + (nth 1 info)))) + (comment + (when (or (string= "both" (cdr (assoc :comments params))) + (string= "org" (cdr (assoc :comments params)))) + ;; from the previous heading or code-block end + (buffer-substring + (max (condition-case nil + (save-excursion + (org-back-to-heading t) (point)) + (error 0)) + (save-excursion + (re-search-backward + org-babel-src-block-regexp nil t) + (match-end 0))) + (point)))) + by-lang) + ;; add the spec for this block to blocks under it's language + (setq by-lang (cdr (assoc src-lang blocks))) + (setq blocks (delq (assoc src-lang blocks) blocks)) + (setq blocks (cons + (cons src-lang + (cons (list start-line file link + source-name params body comment) + by-lang)) blocks))))))) ;; ensure blocks in the correct order (setq blocks (mapcar @@ -276,22 +354,97 @@ assumes that the appropriate major-mode is set. SPEC has the form - (link source-name params body)" - (let ((link (nth 0 spec)) - (source-name (nth 1 spec)) - (body (nth 3 spec)) - (commentable (string= (cdr (assoc :comments (nth 2 spec))) "yes"))) + (start-line file link source-name params body comment)" + (let* ((start-line (nth 0 spec)) + (file (nth 1 spec)) + (link (org-link-escape (nth 2 spec))) + (source-name (nth 3 spec)) + (body (nth 5 spec)) + (comment (nth 6 spec)) + (comments (cdr (assoc :comments (nth 4 spec)))) + (link-p (or (string= comments "both") (string= comments "link") + (string= comments "yes"))) + (link-data (mapcar (lambda (el) + (cons (symbol-name el) + ((lambda (le) + (if (stringp le) le (format "%S" le))) + (eval el)))) + '(start-line file link source-name)))) (flet ((insert-comment (text) - (when commentable - (insert "\n") - (comment-region (point) - (progn (insert text) (point))) - (end-of-line nil) - (insert "\n")))) - (insert-comment (format "[[%s][%s]]" (org-link-escape link) source-name)) - (insert (format "\n%s\n" (replace-regexp-in-string - "^," "" (org-babel-chomp body)))) - (insert-comment (format "%s ends here" source-name))))) + (let ((text (org-babel-trim text))) + (when (and comments (not (string= comments "no")) + (> (length text) 0)) + (when org-babel-tangle-pad-newline (insert "\n")) + (comment-region (point) (progn (insert text) (point))) + (end-of-line nil) (insert "\n"))))) + (when comment (insert-comment comment)) + (when link-p + (insert-comment + (org-fill-template org-babel-tangle-comment-format-beg link-data))) + (when org-babel-tangle-pad-newline (insert "\n")) + (insert + (format + "%s\n" + (replace-regexp-in-string + "^," "" + (org-babel-trim body (if org-src-preserve-indentation "[\f\n\r\v]"))))) + (when link-p + (insert-comment + (org-fill-template org-babel-tangle-comment-format-end link-data)))))) + +;; detangling functions +(defvar org-bracket-link-analytic-regexp) +(defun org-babel-detangle (&optional source-code-file) + "Propagate changes in source file back original to Org-mode file. +This requires that code blocks were tangled with link comments +which enable the original code blocks to be found." + (interactive) + (save-excursion + (when source-code-file (find-file source-code-file)) + (goto-char (point-min)) + (let ((counter 0) new-body end) + (while (re-search-forward org-bracket-link-analytic-regexp nil t) + (when (re-search-forward + (concat " " (regexp-quote (match-string 5)) " ends here")) + (setq end (match-end 0)) + (forward-line -1) + (save-excursion + (when (setq new-body (org-babel-tangle-jump-to-org)) + (org-babel-update-block-body new-body))) + (setq counter (+ 1 counter))) + (goto-char end)) + (prog1 counter (message "detangled %d code blocks" counter))))) + +(defun org-babel-tangle-jump-to-org () + "Jump from a tangled code file to the related Org-mode file." + (interactive) + (let ((mid (point)) + target-buffer target-char + start end link path block-name body) + (save-window-excursion + (save-excursion + (unless (and (re-search-backward org-bracket-link-analytic-regexp nil t) + (setq start (point-at-eol)) + (setq link (match-string 0)) + (setq path (match-string 3)) + (setq block-name (match-string 5)) + (re-search-forward + (concat " " (regexp-quote block-name) " ends here") nil t) + (setq end (point-at-bol)) + (< start mid) (< mid end)) + (error "not in tangled code")) + (setq body (org-babel-trim (buffer-substring start end)))) + (when (string-match "::" path) + (setq path (substring path 0 (match-beginning 0)))) + (find-file path) (setq target-buffer (current-buffer)) + (goto-char start) (org-open-link-from-string link) + (if (string-match "[^ \t\n\r]:\\([[:digit:]]+\\)" block-name) + (org-babel-next-src-block + (string-to-number (match-string 1 block-name))) + (org-babel-goto-named-src-block block-name)) + (setq target-char (point))) + (pop-to-buffer target-buffer) + (prog1 body (goto-char target-char)))) (provide 'ob-tangle) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/ob.el --- a/lisp/org/ob.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/ob.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte, Dan Davison ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -40,28 +40,38 @@ (declare-function tramp-dissect-file-name "tramp" (name &optional nodefault)) (declare-function tramp-file-name-user "tramp" (vec)) (declare-function tramp-file-name-host "tramp" (vec)) +(declare-function with-parsed-tramp-file-name "tramp" (filename var &rest body)) (declare-function org-icompleting-read "org" (&rest args)) -(declare-function org-edit-src-code "org-src" - (&optional context code edit-buffer-name)) +(declare-function org-edit-src-code "org-src" + (&optional context code edit-buffer-name quietp)) +(declare-function org-edit-src-exit "org-src" (&optional context)) (declare-function org-open-at-point "org" (&optional in-emacs reference-buffer)) +(declare-function org-save-outline-visibility "org" (use-markers &rest body)) +(declare-function org-outline-overlay-data "org" (&optional use-markers)) +(declare-function org-set-outline-overlay-data "org" (data)) (declare-function org-narrow-to-subtree "org" ()) -(declare-function org-entry-get "org" (pom property &optional inherit literal-nil)) +(declare-function org-entry-get "org" + (pom property &optional inherit literal-nil)) (declare-function org-make-options-regexp "org" (kwds &optional extra)) (declare-function org-do-remove-indentation "org" (&optional n)) (declare-function org-show-context "org" (&optional key)) (declare-function org-at-table-p "org" (&optional table-type)) (declare-function org-cycle "org" (&optional arg)) (declare-function org-uniquify "org" (list)) +(declare-function org-current-level "org" ()) (declare-function org-table-import "org-table" (file arg)) -(declare-function org-add-hook "org-compat" (hook function &optional append local)) +(declare-function org-add-hook "org-compat" + (hook function &optional append local)) (declare-function org-table-align "org-table" ()) (declare-function org-table-end "org-table" (&optional table-type)) (declare-function orgtbl-to-generic "org-table" (table params)) (declare-function orgtbl-to-orgtbl "org-table" (table params)) (declare-function org-babel-lob-get-info "ob-lob" nil) (declare-function org-babel-ref-split-args "ob-ref" (arg-string)) -(declare-function org-babel-ref-variables "ob-ref" (params)) -(declare-function org-babel-ref-resolve-reference "ob-ref" (ref &optional params)) +(declare-function org-babel-ref-parse "ob-ref" (assignment)) +(declare-function org-babel-ref-resolve "ob-ref" (ref)) +(declare-function org-babel-lob-execute-maybe "ob-lob" ()) +(declare-function org-number-sequence "org-compat" (from &optional to inc)) (defgroup org-babel nil "Code block evaluation and management in `org-mode' documents." @@ -100,8 +110,15 @@ "^[ \t]*#\\+\\(srcname\\|source\\|function\\):[ \t]*" "Regular expression used to match a source name line.") +(defvar org-babel-multi-line-header-regexp + "^[ \t]*#\\+headers?:[ \t]*\\([^\n]*\\)$" + "Regular expression used to match multi-line header arguments.") + (defvar org-babel-src-name-w-name-regexp (concat org-babel-src-name-regexp + "\\(" + org-babel-multi-line-header-regexp + "\\)*" "\\([^ ()\f\t\n\r\v]+\\)\\(\(\\(.*\\)\)\\|\\)") "Regular expression matching source name lines with a name.") @@ -127,51 +144,54 @@ "{\\([^\f\n\r\v]+?\\)}\\)") "Regexp used to identify inline src-blocks.") -(defun org-babel-get-src-block-info (&optional header-vars-only) +(defun org-babel-get-header (params key &optional others) + "Select only header argument of type KEY from a list. +Optional argument OTHERS indicates that only the header that do +not match KEY should be returned." + (delq nil + (mapcar + (lambda (p) (when (funcall (if others #'not #'identity) (eq (car p) key)) p)) + params))) + +(defun org-babel-get-src-block-info (&optional light) "Get information on the current source block. +Optional argument LIGHT does not resolve remote variable +references; a process which could likely result in the execution +of other code blocks. + Returns a list - (language body header-arguments-alist switches name function-args indent). -Unless HEADER-VARS-ONLY is non-nil, any variable -references provided in 'function call style' (i.e. in a -parenthesised argument list following the src block name) are -added to the header-arguments-alist." - (let ((case-fold-search t) head info args indent) + (language body header-arguments-alist switches name indent)." + (let ((case-fold-search t) head info name indent) + ;; full code block (if (setq head (org-babel-where-is-src-block-head)) - (save-excursion + (save-excursion (goto-char head) (setq info (org-babel-parse-src-block-match)) (setq indent (car (last info))) (setq info (butlast info)) - (forward-line -1) - (if (and (looking-at org-babel-src-name-w-name-regexp) - (match-string 2)) - (progn - (setq info (append info (list (org-babel-clean-text-properties - (match-string 2))))) - ;; Note that e.g. "name()" and "name( )" result in - ;; ((:var . "")). We maintain that behaviour, and the - ;; resulting non-nil sixth element is relied upon in - ;; org-babel-exp-code to detect a functional-style - ;; block in those cases. However, "name" without any - ;; parentheses would result in the same thing, so we - ;; explicitly avoid that. - (if (setq args (match-string 4)) - (setq info - (append info (list - (mapcar - (lambda (ref) (cons :var ref)) - (org-babel-ref-split-args args)))))) - (unless header-vars-only - (setf (nth 2 info) - (org-babel-merge-params (nth 5 info) (nth 2 info))))) - (setq info (append info (list nil nil)))) - (append info (list indent))) - (if (save-excursion ;; inline source block - (re-search-backward "[ \f\t\n\r\v]" nil t) - (looking-at org-babel-inline-src-block-regexp)) - (org-babel-parse-inline-src-block-match) - nil)))) + (while (and (forward-line -1) + (looking-at org-babel-multi-line-header-regexp)) + (setf (nth 2 info) + (org-babel-merge-params + (org-babel-parse-header-arguments (match-string 1)) + (nth 2 info)))) + (when (looking-at org-babel-src-name-w-name-regexp) + (setq name (org-babel-clean-text-properties (match-string 4))) + (when (match-string 6) + (setf (nth 2 info) ;; merge functional-syntax vars and header-args + (org-babel-merge-params + (mapcar (lambda (ref) (cons :var ref)) + (org-babel-ref-split-args (match-string 6))) + (nth 2 info)))))) + ;; inline source block + (when (save-excursion (re-search-backward "[ \f\t\n\r\v]" nil t) + (looking-at org-babel-inline-src-block-regexp)) + (setq info (org-babel-parse-inline-src-block-match)))) + ;; resolve variable references and add summary parameters + (when (and info (not light)) + (setf (nth 2 info) (org-babel-process-params (nth 2 info)))) + (when info (append info (list name indent))))) (defun org-babel-confirm-evaluate (info) "Confirm evaluation of the code block INFO. @@ -182,31 +202,42 @@ Note disabling confirmation may result in accidental evaluation of potentially harmful code." - (let* ((eval (cdr (assoc :eval (nth 2 info)))) + (let* ((eval (or (cdr (assoc :eval (nth 2 info))) + (when (assoc :noeval (nth 2 info)) "no"))) (query (or (equal eval "query") - (and (functionp org-confirm-babel-evaluate) - (funcall org-confirm-babel-evaluate - (nth 0 info) (nth 1 info))) - org-confirm-babel-evaluate))) - (when (or (equal eval "never") - (and query - (not (yes-or-no-p - (format "Evaluate this%scode on your system? " - (if info (format " %s " (nth 0 info)) " ")))))) - (error "evaluation aborted")))) + (if (functionp org-confirm-babel-evaluate) + (funcall org-confirm-babel-evaluate + (nth 0 info) (nth 1 info)) + org-confirm-babel-evaluate)))) + (if (or (equal eval "never") (equal eval "no") + (and query + (not (yes-or-no-p + (format "Evaluate this%scode on your system? " + (if info (format " %s " (nth 0 info)) " ")))))) + (prog1 nil (message "evaluation aborted")) + t))) ;;;###autoload +(defun org-babel-execute-safely-maybe () + (unless org-babel-no-eval-on-ctrl-c-ctrl-c + (org-babel-execute-maybe))) + +(add-hook 'org-ctrl-c-ctrl-c-hook 'org-babel-execute-safely-maybe) + +;;;###autoload +(defun org-babel-execute-maybe () + (interactive) + (or (org-babel-execute-src-block-maybe) + (org-babel-lob-execute-maybe))) + (defun org-babel-execute-src-block-maybe () "Conditionally execute a source block. Detect if this is context for a Babel src-block and if so then run `org-babel-execute-src-block'." (interactive) - (if (not org-babel-no-eval-on-ctrl-c-ctrl-c) - (let ((info (org-babel-get-src-block-info))) - (if info - (progn (org-babel-execute-src-block current-prefix-arg info) t) nil)) - nil)) -(add-hook 'org-ctrl-c-ctrl-c-hook 'org-babel-execute-src-block-maybe) + (let ((info (org-babel-get-src-block-info))) + (if info + (progn (org-babel-execute-src-block current-prefix-arg info) t) nil))) ;;;###autoload (defun org-babel-expand-src-block-maybe () @@ -245,7 +276,7 @@ (defconst org-babel-header-arg-names '(cache cmdline colnames dir exports file noweb results - session tangle var noeval comments) + session tangle var eval noeval comments) "Common header arguments used by org-babel. Note that individual languages may define their own language specific header arguments as well.") @@ -259,7 +290,8 @@ '((:session . "none") (:results . "silent") (:exports . "results")) "Default arguments to use when evaluating an inline source block.") -(defvar org-babel-current-buffer-properties) +(defvar org-babel-current-buffer-properties nil + "Local cache for buffer properties.") (make-variable-buffer-local 'org-babel-current-buffer-properties) (defvar org-babel-result-regexp @@ -299,12 +331,17 @@ ;;; functions (defvar call-process-region) ;;;###autoload + (defun org-babel-execute-src-block (&optional arg info params) "Execute the current source code block. Insert the results of execution into the buffer. Source code execution and the collection and formatting of results can be controlled through a variety of header arguments. +With prefix argument ARG, force re-execution even if a an +existing result cached in the buffer would otherwise have been +returned. + Optionally supply a value for INFO in the form returned by `org-babel-get-src-block-info'. @@ -312,73 +349,73 @@ the header arguments specified at the front of the source code block." (interactive) - (let* ((info (or info (org-babel-get-src-block-info))) - ;; note the `evaluation-confirmed' variable is currently not - ;; used, but could be used later to avoid the need for - ;; chaining confirmations - (evaluation-confirmed (org-babel-confirm-evaluate info)) - (lang (nth 0 info)) - (params (setf (nth 2 info) - (sort (org-babel-merge-params (nth 2 info) params) - (lambda (el1 el2) (string< (symbol-name (car el1)) - (symbol-name (car el2))))))) - (new-hash - (if (and (cdr (assoc :cache params)) - (string= "yes" (cdr (assoc :cache params)))) - (org-babel-sha1-hash info))) - (old-hash (org-babel-result-hash info)) - (body (setf (nth 1 info) - (if (and (cdr (assoc :noweb params)) - (string= "yes" (cdr (assoc :noweb params)))) - (org-babel-expand-noweb-references info) - (nth 1 info)))) - (result-params (split-string (or (cdr (assoc :results params)) ""))) - (result-type (cond ((member "output" result-params) 'output) - ((member "value" result-params) 'value) - (t 'value))) - (cmd (intern (concat "org-babel-execute:" lang))) - (dir (cdr (assoc :dir params))) - (default-directory - (or (and dir (file-name-as-directory dir)) default-directory)) - (org-babel-call-process-region-original - (if (boundp 'org-babel-call-process-region-original) org-babel-call-process-region-original - (symbol-function 'call-process-region))) - (indent (car (last info))) - result) - (unwind-protect - (flet ((call-process-region (&rest args) - (apply 'org-babel-tramp-handle-call-process-region args))) - (unless (fboundp cmd) - (error "No org-babel-execute function for %s!" lang)) - (if (and (not arg) new-hash (equal new-hash old-hash)) - (save-excursion ;; return cached result - (goto-char (org-babel-where-is-src-block-result nil info)) - (end-of-line 1) (forward-char 1) - (setq result (org-babel-read-result)) - (message (replace-regexp-in-string "%" "%%" - (format "%S" result))) result) - (message "executing %s code block%s..." - (capitalize lang) - (if (nth 4 info) (format " (%s)" (nth 4 info)) "")) - (setq result (funcall cmd body params)) - (if (eq result-type 'value) - (setq result (if (and (or (member "vector" result-params) - (member "table" result-params)) - (not (listp result))) - (list (list result)) - result))) - (org-babel-insert-result - result result-params info new-hash indent lang) - (run-hooks 'org-babel-after-execute-hook) - result)) - (setq call-process-region 'org-babel-call-process-region-original)))) + (let ((info (or info (org-babel-get-src-block-info)))) + (when (org-babel-confirm-evaluate info) + (let* ((lang (nth 0 info)) + (params (if params + (org-babel-process-params + (org-babel-merge-params (nth 2 info) params)) + (nth 2 info))) + (cache? (and (not arg) (cdr (assoc :cache params)) + (string= "yes" (cdr (assoc :cache params))))) + (result-params (cdr (assoc :result-params params))) + (new-hash (when cache? (org-babel-sha1-hash info))) + (old-hash (when cache? (org-babel-result-hash info))) + (body (setf (nth 1 info) + (if (and (cdr (assoc :noweb params)) + (string= "yes" (cdr (assoc :noweb params)))) + (org-babel-expand-noweb-references info) + (nth 1 info)))) + (cmd (intern (concat "org-babel-execute:" lang))) + (dir (cdr (assoc :dir params))) + (default-directory + (or (and dir (file-name-as-directory dir)) default-directory)) + (org-babel-call-process-region-original + (if (boundp 'org-babel-call-process-region-original) + org-babel-call-process-region-original + (symbol-function 'call-process-region))) + (indent (car (last info))) + result) + (unwind-protect + (flet ((call-process-region (&rest args) + (apply 'org-babel-tramp-handle-call-process-region args))) + (unless (fboundp cmd) + (error "No org-babel-execute function for %s!" lang)) + (if (and (not arg) new-hash (equal new-hash old-hash)) + (save-excursion ;; return cached result + (goto-char (org-babel-where-is-src-block-result nil info)) + (end-of-line 1) (forward-char 1) + (setq result (org-babel-read-result)) + (message (replace-regexp-in-string + "%" "%%" (format "%S" result))) result) + (message "executing %s code block%s..." + (capitalize lang) + (if (nth 4 info) (format " (%s)" (nth 4 info)) "")) + (setq result + ((lambda (result) + (cond + ((member "file" result-params) + (cdr (assoc :file params))) + ((and (eq (cdr (assoc :result-type params)) 'value) + (or (member "vector" result-params) + (member "table" result-params)) + (not (listp result))) + (list (list result))) + (t result))) + (funcall cmd body params))) + (org-babel-insert-result + result result-params info new-hash indent lang) + (run-hooks 'org-babel-after-execute-hook) + result)) + (setq call-process-region 'org-babel-call-process-region-original)))))) -(defun org-babel-expand-body:generic (body params &optional processed-params) +(defun org-babel-expand-body:generic (body params &optional var-lines) "Expand BODY with PARAMS. Expand a block of code with org-babel according to it's header arguments. This generic implementation of body expansion is called for languages which have not defined their own specific -org-babel-expand-body:lang function." body) +org-babel-expand-body:lang function." + (mapconcat #'identity (append var-lines (list body)) "\n")) ;;;###autoload (defun org-babel-expand-src-block (&optional arg info params) @@ -391,14 +428,17 @@ (params (setf (nth 2 info) (sort (org-babel-merge-params (nth 2 info) params) (lambda (el1 el2) (string< (symbol-name (car el1)) - (symbol-name (car el2))))))) + (symbol-name (car el2))))))) (body (setf (nth 1 info) (if (and (cdr (assoc :noweb params)) (string= "yes" (cdr (assoc :noweb params)))) (org-babel-expand-noweb-references info) (nth 1 info)))) - (cmd (intern (concat "org-babel-expand-body:" lang))) - (expanded (funcall (if (fboundp cmd) cmd 'org-babel-expand-body:generic) - body params))) + (expand-cmd (intern (concat "org-babel-expand-body:" lang))) + (assignments-cmd (intern (concat "org-babel-variable-assignments:" lang))) + (expanded + (if (fboundp expand-cmd) (funcall expand-cmd body params) + (org-babel-expand-body:generic + body params (and (fboundp assignments-cmd) (funcall assignments-cmd params)))))) (org-edit-src-code nil expanded (concat "*Org-Babel Preview " (buffer-name) "[ " lang " ]*")))) @@ -411,9 +451,16 @@ (interactive) (let* ((info (or info (org-babel-get-src-block-info))) (lang (nth 0 info)) - (body (nth 1 info)) (params (nth 2 info)) + (body (setf (nth 1 info) + (if (and (cdr (assoc :noweb params)) + (string= "yes" (cdr (assoc :noweb params)))) + (org-babel-expand-noweb-references info) + (nth 1 info)))) (session (cdr (assoc :session params))) + (dir (cdr (assoc :dir params))) + (default-directory + (or (and dir (file-name-as-directory dir)) default-directory)) (cmd (intern (concat "org-babel-load-session:" lang)))) (unless (fboundp cmd) (error "No org-babel-load-session function for %s!" lang)) @@ -421,13 +468,13 @@ (end-of-line 1))) ;;;###autoload -(defun org-babel-switch-to-session (&optional arg info) - "Switch to the session of the current source-code block. -If called with a prefix argument then evaluate the header arguments -for the source block before entering the session. Copy the body -of the source block to the kill ring." - (interactive) - (let* ((info (or info (org-babel-get-src-block-info))) +(defun org-babel-initiate-session (&optional arg info) + "Initiate session for current code block. +If called with a prefix argument then resolve any variable +references in the header arguments and assign these variables in +the session. Copy the body of the code block to the kill ring." + (interactive "P") + (let* ((info (or info (org-babel-get-src-block-info (not arg)))) (lang (nth 0 info)) (body (nth 1 info)) (params (nth 2 info)) @@ -435,23 +482,74 @@ (dir (cdr (assoc :dir params))) (default-directory (or (and dir (file-name-as-directory dir)) default-directory)) - (cmd (intern (format "org-babel-%s-initiate-session" lang))) - (cmd2 (intern (concat "org-babel-prep-session:" lang)))) - (unless (fboundp cmd) + (init-cmd (intern (format "org-babel-%s-initiate-session" lang))) + (prep-cmd (intern (concat "org-babel-prep-session:" lang)))) + (if (and (stringp session) (string= session "none")) + (error "This block is not using a session!")) + (unless (fboundp init-cmd) (error "No org-babel-initiate-session function for %s!" lang)) - ;; copy body to the kill ring (with-temp-buffer (insert (org-babel-trim body)) (copy-region-as-kill (point-min) (point-max))) - ;; if called with a prefix argument, then process header arguments - (unless (fboundp cmd2) - (error "No org-babel-prep-session function for %s!" lang)) - (when arg (funcall cmd2 session params)) - ;; just to the session using pop-to-buffer - (pop-to-buffer (funcall cmd session params)) - (end-of-line 1))) + (when arg + (unless (fboundp prep-cmd) + (error "No org-babel-prep-session function for %s!" lang)) + (funcall prep-cmd session params)) + (funcall init-cmd session params))) + +;;;###autoload +(defun org-babel-switch-to-session (&optional arg info) + "Switch to the session of the current code block. +Uses `org-babel-initiate-session' to start the session. If called +with a prefix argument then this is passed on to +`org-babel-initiate-session'." + (interactive "P") + (pop-to-buffer (org-babel-initiate-session arg info)) + (end-of-line 1)) (defalias 'org-babel-pop-to-session 'org-babel-switch-to-session) +;;;###autoload +(defun org-babel-switch-to-session-with-code (&optional arg info) + "Switch to code buffer and display session." + (interactive "P") + (flet ((swap-windows + () + (let ((other-window-buffer (window-buffer (next-window)))) + (set-window-buffer (next-window) (current-buffer)) + (set-window-buffer (selected-window) other-window-buffer)) + (other-window 1))) + (let ((info (org-babel-get-src-block-info)) + (org-src-window-setup 'reorganize-frame)) + (save-excursion + (org-babel-switch-to-session arg info)) + (org-edit-src-code)) + (swap-windows))) + +(defmacro org-babel-do-in-edit-buffer (&rest body) + "Evaluate BODY in edit buffer if there is a code block at point. +Return t if a code block was found at point, nil otherwise." + `(let ((org-src-window-setup 'switch-invisibly)) + (when (and (org-babel-where-is-src-block-head) + (org-edit-src-code nil nil nil 'quietly)) + (unwind-protect (progn ,@body) + (if (org-bound-and-true-p org-edit-src-from-org-mode) + (org-edit-src-exit))) + t))) + +(defun org-babel-do-key-sequence-in-edit-buffer (key) + "Read key sequence and execute the command in edit buffer. +Enter a key sequence to be executed in the language major-mode +edit buffer. For example, TAB will alter the contents of the +Org-mode code block according to the effect of TAB in the +language major-mode buffer. For languages that support +interactive sessions, this can be used to send code from the Org +buffer to the session for evaluation using the native major-mode +evaluation mechanisms." + (interactive "kEnter key-sequence to execute in edit buffer: ") + (org-babel-do-in-edit-buffer + (call-interactively + (key-binding (or key (read-key-sequence nil)))))) + (defvar org-bracket-link-regexp) ;;;###autoload (defun org-babel-open-src-block-result (&optional re-run) @@ -490,15 +588,9 @@ Call `org-babel-execute-src-block' on every source block in the current buffer." (interactive "P") - (save-excursion - (org-save-outline-visibility t - (goto-char (point-min)) - (show-all) - (while (re-search-forward org-babel-src-block-regexp nil t) - (let ((pos-end (match-end 0))) - (goto-char (match-beginning 0)) - (org-babel-execute-src-block arg) - (goto-char pos-end)))))) + (org-save-outline-visibility t + (org-babel-map-src-blocks nil + (org-babel-execute-src-block arg)))) ;;;###autoload (defun org-babel-execute-subtree (&optional arg) @@ -509,19 +601,34 @@ (save-restriction (save-excursion (org-narrow-to-subtree) - (org-babel-execute-buffer) + (org-babel-execute-buffer arg) (widen)))) ;;;###autoload (defun org-babel-sha1-hash (&optional info) "Generate an sha1 hash based on the value of info." (interactive) - (let* ((info (or info (org-babel-get-src-block-info))) - (hash (sha1 (format "%s-%s" (mapconcat (lambda (arg) (format "%S" arg)) - (nth 2 info) ":") - (nth 1 info))))) - (when (interactive-p) (message hash)) - hash)) + (let ((print-level nil) + (info (or info (org-babel-get-src-block-info)))) + (setf (nth 2 info) + (sort (copy-sequence (nth 2 info)) + (lambda (a b) (string< (car a) (car b))))) + (let ((hash (sha1 + (format "%s-%s" + (mapconcat + #'identity + (delq nil + (mapcar + (lambda (arg) + (let ((v (cdr arg))) + (when (and v (not (and (sequencep v) + (not (consp v)) + (= (length v) 0)))) + (format "%S" v)))) + (nth 2 info))) ":") + (nth 1 info))))) + (when (interactive-p) (message hash)) + hash))) (defun org-babel-result-hash (&optional info) "Return the in-buffer hash associated with INFO." @@ -647,23 +754,58 @@ ;; Remove overlays when changing major mode (add-hook 'org-mode-hook (lambda () (org-add-hook 'change-major-mode-hook - 'org-babel-show-result-all 'append 'local))) + 'org-babel-show-result-all 'append 'local))) (defmacro org-babel-map-src-blocks (file &rest body) - "Evaluate BODY forms on each source-block in FILE." + "Evaluate BODY forms on each source-block in FILE. +If FILE is nil evaluate BODY forms on source blocks in current +buffer. During evaluation of BODY the following local variables +are set relative to the currently matched code block. + +full-block ------- string holding the entirety of the code block +beg-block -------- point at the beginning of the code block +end-block -------- point at the end of the matched code block +lang ------------- string holding the language of the code block +beg-lang --------- point at the beginning of the lang +end-lang --------- point at the end of the lang +switches --------- string holding the switches +beg-switches ----- point at the beginning of the switches +end-switches ----- point at the end of the switches +header-args ------ string holding the header-args +beg-header-args -- point at the beginning of the header-args +end-header-args -- point at the end of the header-args +body ------------- string holding the body of the code block +beg-body --------- point at the beginning of the body +end-body --------- point at the end of the body" (declare (indent 1)) - `(let ((visited-p (get-file-buffer (expand-file-name ,file))) - to-be-removed) + `(let ((visited-p (or (null ,file) + (get-file-buffer (expand-file-name ,file)))) + (point (point)) to-be-removed) (save-window-excursion - (find-file ,file) + (when ,file (find-file ,file)) (setq to-be-removed (current-buffer)) (goto-char (point-min)) (while (re-search-forward org-babel-src-block-regexp nil t) (goto-char (match-beginning 0)) - (save-match-data ,@body) - (goto-char (match-end 0)))) - (unless visited-p - (kill-buffer to-be-removed)))) + (let ((full-block (match-string 0)) + (beg-block (match-beginning 0)) + (end-block (match-end 0)) + (lang (match-string 2)) + (beg-lang (match-beginning 2)) + (end-lang (match-end 2)) + (switches (match-string 3)) + (beg-switches (match-beginning 3)) + (end-switches (match-end 3)) + (header-args (match-string 4)) + (beg-header-args (match-beginning 4)) + (end-header-args (match-end 4)) + (body (match-string 5)) + (beg-body (match-beginning 5)) + (end-body (match-end 5))) + ,@body + (goto-char end-block)))) + (unless visited-p (kill-buffer to-be-removed)) + (goto-char point))) (defvar org-file-properties) (defun org-babel-params-from-properties (&optional lang) @@ -680,7 +822,8 @@ (org-entry-get (point) header-arg t) (error nil)) (cdr (assoc header-arg org-file-properties)))) - (cons (intern (concat ":" header-arg)) val))) + (cons (intern (concat ":" header-arg)) + (org-babel-read val)))) (mapcar 'symbol-name (append @@ -757,30 +900,33 @@ "\\([^ \f\t\n\r\v]+\\)[ \f\t\n\r\v]+\\([^ \f\t\n\r\v]+.*\\)" arg) (cons (intern (concat ":" (match-string 1 arg))) - (let ((raw (org-babel-chomp (match-string 2 arg)))) - (if (org-babel-number-p raw) - raw (org-babel-read raw)))) + (org-babel-read (org-babel-chomp (match-string 2 arg)))) (cons (intern (concat ":" arg)) nil))) (split-string (concat " " arg-string) "[ \f\t\n\r\v]+:" t))))) (defun org-babel-process-params (params) - "Parse params and resolve references. - -Return a list (session vars result-params result-type colnames rownames)." - (let* ((session (cdr (assoc :session params))) - (vars-and-names (org-babel-disassemble-tables - (org-babel-ref-variables params) - (cdr (assoc :hlines params)) - (cdr (assoc :colnames params)) - (cdr (assoc :rownames params)))) - (vars (car vars-and-names)) - (colnames (cadr vars-and-names)) - (rownames (caddr vars-and-names)) - (result-params (split-string (or (cdr (assoc :results params)) ""))) - (result-type (cond ((member "output" result-params) 'output) - ((member "value" result-params) 'value) - (t 'value)))) - (list session vars result-params result-type colnames rownames))) + "Expand variables in PARAMS and add summary parameters." + (let* ((vars-and-names (org-babel-disassemble-tables + (mapcar (lambda (el) + (if (consp (cdr el)) + (cdr el) (org-babel-ref-parse (cdr el)))) + (org-babel-get-header params :var)) + (cdr (assoc :hlines params)) + (cdr (assoc :colnames params)) + (cdr (assoc :rownames params)))) + (result-params (append + (split-string (or (cdr (assoc :results params)) "")) + (cdr (assoc :result-params params))))) + (append + (mapcar (lambda (var) (cons :var var)) (car vars-and-names)) + (list + (cons :colname-names (cadr vars-and-names)) + (cons :rowname-names (caddr vars-and-names)) + (cons :result-params result-params) + (cons :result-type (cond ((member "output" result-params) 'output) + ((member "value" result-params) 'value) + (t 'value)))) + (org-babel-get-header params :var 'other)))) ;; row and column names (defun org-babel-del-hlines (table) @@ -802,12 +948,14 @@ colnames, and the `cdr' of which contains a list of the column names. Note: this function removes any hlines in TABLE." (flet ((trans (table) (apply #'mapcar* #'list table))) - (let* ((width (apply 'max (mapcar (lambda (el) (if (listp el) (length el) 0)) table))) + (let* ((width (apply 'max + (mapcar (lambda (el) (if (listp el) (length el) 0)) table))) (table (trans (mapcar (lambda (row) (if (not (equal row 'hline)) row (setq row '()) - (dotimes (n width) (setq row (cons 'hline row))) + (dotimes (n width) + (setq row (cons 'hline row))) row)) table)))) (cons (mapcar (lambda (row) (if (equal (car row) 'hline) 'hline row)) @@ -828,13 +976,18 @@ table)) (defun org-babel-pick-name (names selector) - "Select one out of an alist of row or column names." - (when names - (if (and selector (symbolp selector) (not (equal t selector))) - (cdr (assoc selector names)) - (if (integerp selector) - (nth (- selector 1) names) - (cdr (car (last names))))))) + "Select one out of an alist of row or column names. +SELECTOR can be either a list of names in which case those names +will be returned directly, or an index into the list NAMES in +which case the indexed names will be return." + (if (listp selector) + selector + (when names + (if (and selector (symbolp selector) (not (equal t selector))) + (cdr (assoc selector names)) + (if (integerp selector) + (nth (- selector 1) names) + (cdr (car (last names)))))))) (defun org-babel-disassemble-tables (vars hlines colnames rownames) "Parse tables for further processing. @@ -903,6 +1056,14 @@ (point)))))) ;;;###autoload +(defun org-babel-goto-src-block-head () + "Go to the beginning of the current code block." + (interactive) + ((lambda (head) + (if head (goto-char head) (error "not currently in a code block"))) + (org-babel-where-is-src-block-head))) + +;;;###autoload (defun org-babel-goto-named-src-block (name) "Go to a named source-code block." (interactive @@ -934,7 +1095,7 @@ (when file (find-file file)) (goto-char (point-min)) (let (names) (while (re-search-forward org-babel-src-name-w-name-regexp nil t) - (setq names (cons (org-babel-clean-text-properties (match-string 2)) + (setq names (cons (org-babel-clean-text-properties (match-string 3)) names))) names))) @@ -978,7 +1139,9 @@ With optional prefix argument ARG, jump forward ARG many source blocks." (interactive "P") (when (looking-at org-babel-src-block-regexp) (forward-char 1)) - (re-search-forward org-babel-src-block-regexp nil nil (or arg 1)) + (condition-case nil + (re-search-forward org-babel-src-block-regexp nil nil (or arg 1)) + (error (error "No further code blocks"))) (goto-char (match-beginning 0)) (org-show-context)) ;;;###autoload @@ -986,9 +1149,68 @@ "Jump to the previous source block. With optional prefix argument ARG, jump backward ARG many source blocks." (interactive "P") - (re-search-backward org-babel-src-block-regexp nil nil (or arg 1)) + (condition-case nil + (re-search-backward org-babel-src-block-regexp nil nil (or arg 1)) + (error (error "No previous code blocks"))) (goto-char (match-beginning 0)) (org-show-context)) +(defvar org-babel-load-languages) + +;;;###autoload +(defun org-babel-mark-block () + "Mark current src block" + (interactive) + ((lambda (head) + (when head + (save-excursion + (goto-char head) + (looking-at org-babel-src-block-regexp)) + (push-mark (match-end 5) nil t) + (goto-char (match-beginning 5)))) + (org-babel-where-is-src-block-head))) + +(defun org-babel-demarcate-block (&optional arg) + "Wrap or split the code in the region or on the point. +When called from inside of a code block the current block is +split. When called from outside of a code block a new code block +is created. In both cases if the region is demarcated and if the +region is not active then the point is demarcated." + (interactive "P") + (let ((info (org-babel-get-src-block-info 'light)) + (stars (concat (make-string (or (org-current-level) 1) ?*) " "))) + (if info + (mapc + (lambda (place) + (save-excursion + (goto-char place) + (let ((lang (nth 0 info)) + (indent (make-string (nth 5 info) ? ))) + (when (string-match "^[[:space:]]*$" + (buffer-substring (point-at-bol) + (point-at-eol))) + (delete-region (point-at-bol) (point-at-eol))) + (insert (concat (if (looking-at "^") "" "\n") + indent "#+end_src\n" + (if arg stars indent) "\n" + indent "#+begin_src " lang + (if (looking-at "[\n\r]") "" "\n"))))) + (move-end-of-line 2)) + (sort (if (region-active-p) (list (mark) (point)) (list (point))) #'>)) + (let ((start (point)) + (lang (org-icompleting-read "Lang: " + (mapcar (lambda (el) (symbol-name (car el))) + org-babel-load-languages))) + (body (delete-and-extract-region + (if (region-active-p) (mark) (point)) (point)))) + (insert (concat (if (looking-at "^") "" "\n") + (if arg (concat stars "\n") "") + "#+begin_src " lang "\n" + body + (if (or (= (length body) 0) + (string-match "[\r\n]$" body)) "" "\n") + "#+end_src\n")) + (goto-char start) (move-end-of-line 1))))) + (defvar org-babel-lob-one-liner-regexp) (defun org-babel-where-is-src-block-result (&optional insert info hash indent) "Find where the current source block results begin. @@ -1050,7 +1272,7 @@ (if indent (mapconcat (lambda (el) " ") - (number-sequence 1 indent) "") + (org-number-sequence 1 indent) "") "") "#+results" (when hash (concat "["hash"]")) @@ -1130,7 +1352,12 @@ is a good option if you code block will output org-mode formatted text. -org ----- this is the same as the 'raw' option +org ----- similar in effect to raw, only the results are wrapped + in an org code block. Similar to the raw option, on + export the results will be interpreted as org-formatted + text, however by wrapping the results in an org code + block they can be replaced upon re-execution of the + code block. html ---- results are added inside of a #+BEGIN_HTML block. This is a good option if you code block will output html @@ -1151,73 +1378,79 @@ (when (member "file" result-params) (setq result (org-babel-result-to-file result)))) (unless (listp result) (setq result (format "%S" result)))) - (if (= (length result) 0) - (if (member "value" result-params) - (message "No result returned by source block") - (message "Source block produced no output")) - (if (and result-params (member "silent" result-params)) - (progn - (message (replace-regexp-in-string "%" "%%" (format "%S" result))) - result) - (when (and (stringp result) ;; ensure results end in a newline - (not (or (string-equal (substring result -1) "\n") - (string-equal (substring result -1) "\r")))) - (setq result (concat result "\n"))) - (save-excursion - (let ((existing-result (org-babel-where-is-src-block-result - t info hash indent)) - (results-switches - (cdr (assoc :results_switches (nth 2 info)))) - beg end) - (when existing-result - (goto-char existing-result) - (save-excursion - (re-search-forward "#" nil t) - (setq indent (- (current-column) 1))) - (forward-line 1) + (if (and result-params (member "silent" result-params)) + (progn + (message (replace-regexp-in-string "%" "%%" (format "%S" result))) + result) + (when (and (stringp result) ;; ensure results end in a newline + (> (length result) 0) + (not (or (string-equal (substring result -1) "\n") + (string-equal (substring result -1) "\r")))) + (setq result (concat result "\n"))) + (save-excursion + (let ((existing-result (org-babel-where-is-src-block-result + t info hash indent)) + (results-switches + (cdr (assoc :results_switches (nth 2 info)))) + beg end) + (if (not existing-result) (setq beg (point)) - (cond - ((member "replace" result-params) - (delete-region (point) (org-babel-result-end))) - ((member "append" result-params) - (goto-char (org-babel-result-end)) (setq beg (point))) - ((member "prepend" result-params) ;; already there - ))) - (setq results-switches - (if results-switches (concat " " results-switches) "")) + (goto-char existing-result) + (save-excursion + (re-search-forward "#" nil t) + (setq indent (- (current-column) 1))) + (forward-line 1) + (setq beg (point)) (cond - ;; assume the result is a table if it's not a string - ((not (stringp result)) - (insert (concat (orgtbl-to-orgtbl - (if (or (eq 'hline (car result)) - (and (listp (car result)) - (listp (cdr (car result))))) - result (list result)) - '(:fmt (lambda (cell) (format "%s" cell)))) "\n")) - (goto-char beg) (when (org-at-table-p) (org-table-align))) - ((member "file" result-params) - (insert result)) - ((member "html" result-params) - (insert (format "#+BEGIN_HTML%s\n%s#+END_HTML\n" - results-switches result))) - ((member "latex" result-params) - (insert (format "#+BEGIN_LaTeX%s\n%s#+END_LaTeX\n" - results-switches result))) - ((member "code" result-params) - (insert (format "#+BEGIN_SRC %s%s\n%s#+END_SRC\n" - (or lang "none") results-switches result))) - ((or (member "raw" result-params) (member "org" result-params)) - (save-excursion (insert result)) (if (org-at-table-p) (org-cycle))) - (t - (org-babel-examplize-region - (point) (progn (insert result) (point)) results-switches))) - ;; possibly indent the results to match the #+results line - (setq end (if (listp result) (org-table-end) (point))) - (when (and indent (> indent 0) - ;; in this case `table-align' does the work for us - (not (and (listp result) - (member "append" result-params)))) - (indent-rigidly beg end indent)))) + ((member "replace" result-params) + (delete-region (point) (org-babel-result-end))) + ((member "append" result-params) + (goto-char (org-babel-result-end)) (setq beg (point))) + ((member "prepend" result-params) ;; already there + ))) + (setq results-switches + (if results-switches (concat " " results-switches) "")) + (cond + ;; do nothing for an empty result + ((= (length result) 0)) + ;; assume the result is a table if it's not a string + ((not (stringp result)) + (insert (concat (orgtbl-to-orgtbl + (if (or (eq 'hline (car result)) + (and (listp (car result)) + (listp (cdr (car result))))) + result (list result)) + '(:fmt (lambda (cell) (format "%s" cell)))) "\n")) + (goto-char beg) (when (org-at-table-p) (org-table-align))) + ((member "file" result-params) + (insert result)) + ((member "html" result-params) + (insert (format "#+BEGIN_HTML%s\n%s#+END_HTML\n" + results-switches result))) + ((member "latex" result-params) + (insert (format "#+BEGIN_LaTeX%s\n%s#+END_LaTeX\n" + results-switches result))) + ((member "code" result-params) + (insert (format "#+BEGIN_SRC %s%s\n%s#+END_SRC\n" + (or lang "none") results-switches result))) + ((member "org" result-params) + (insert (format "#+BEGIN_SRC org\n%s#+END_SRC\n" result))) + ((member "raw" result-params) + (save-excursion (insert result)) (if (org-at-table-p) (org-cycle))) + (t + (org-babel-examplize-region + (point) (progn (insert result) (point)) results-switches))) + ;; possibly indent the results to match the #+results line + (setq end (if (listp result) (org-table-end) (point))) + (when (and indent (> indent 0) + ;; in this case `table-align' does the work for us + (not (and (listp result) + (member "append" result-params)))) + (indent-rigidly beg end indent)))) + (if (= (length result) 0) + (if (member "value" result-params) + (message "No result returned by source block") + (message "Source block produced no output")) (message "finished")))) (defun org-babel-remove-result (&optional info) @@ -1272,7 +1505,7 @@ (let ((size (count-lines beg end))) (save-excursion (cond ((= size 0) - (error (concat "This should be impossible:" + (error (concat "This should not be impossible:" "a newline was appended to result if missing"))) ((< size org-babel-min-lines-for-block-output) (goto-char beg) @@ -1286,6 +1519,14 @@ (forward-char (- end beg)) (insert "#+end_example\n")))))) +(defun org-babel-update-block-body (new-body) + "Update the body of the current code block to NEW-BODY." + (if (not (org-babel-where-is-src-block-head)) + (error "not in source block") + (save-match-data + (replace-match (concat (org-babel-trim new-body) "\n") nil nil nil 5)) + (indent-rigidly (match-beginning 5) (match-end 5) 2))) + (defun org-babel-merge-params (&rest plists) "Combine all parameter association lists in PLISTS. Later elements of PLISTS override the values of previous element. @@ -1298,7 +1539,7 @@ ("output" "value"))) (exports-exclusive-groups '(("code" "results" "both" "none"))) - params results exports tangle noweb cache vars var ref shebang comments) + params results exports tangle noweb cache vars shebang comments) (flet ((e-merge (exclusive-groups &rest result-params) ;; maintain exclusivity of mutually exclusive parameters (let (output) @@ -1318,63 +1559,60 @@ new-params)) result-params) output))) - (mapc (lambda (plist) - (mapc (lambda (pair) - (case (car pair) - (:var - ;; we want only one specification per variable - (when (string-match - (concat "^\\([^= \f\t\n\r\v]+\\)[ \t]*=" - "[ \t]*\\([^\f\n\r\v]+\\)$") (cdr pair)) - ;; TODO: When is this not true? - (setq var (intern (match-string 1 (cdr pair))) - ref (match-string 2 (cdr pair)) - vars (cons (cons var ref) - (assq-delete-all var vars))))) - (:results - (setq results - (e-merge results-exclusive-groups - results (split-string (cdr pair))))) - (:file - (when (cdr pair) - (setq results (e-merge results-exclusive-groups - results '("file"))) - (unless (or (member "both" exports) - (member "none" exports) - (member "code" exports)) - (setq exports (e-merge exports-exclusive-groups - exports '("results")))) - (setq params - (cons pair - (assq-delete-all (car pair) params))))) - (:exports - (setq exports - (e-merge exports-exclusive-groups - exports (split-string (cdr pair))))) - (:tangle ;; take the latest -- always overwrite - (setq tangle (or (list (cdr pair)) tangle))) - (:noweb - (setq noweb - (e-merge '(("yes" "no")) noweb - (split-string (or (cdr pair) ""))))) - (:cache - (setq cache - (e-merge '(("yes" "no")) cache - (split-string (or (cdr pair) ""))))) - (:shebang ;; take the latest -- always overwrite - (setq shebang (or (list (cdr pair)) shebang))) - (:comments - (setq comments - (e-merge '(("yes" "no")) comments - (split-string (or (cdr pair) ""))))) - (t ;; replace: this covers e.g. :session - (setq params - (cons pair - (assq-delete-all (car pair) params)))))) - plist)) - plists)) - (setq vars (mapcar (lambda (pair) (format "%s=%s" (car pair) (cdr pair))) vars)) - (while vars (setq params (cons (cons :var (pop vars)) params))) + (mapc + (lambda (plist) + (mapc + (lambda (pair) + (case (car pair) + (:var + (let ((name (if (listp (cdr pair)) + (cadr pair) + (and (string-match "^\\([^= \f\t\n\r\v]+\\)[ \t]*=" + (cdr pair)) + (intern (match-string 1 (cdr pair))))))) + (when name + (setq vars + (cons (cons name pair) + (if (member name (mapcar #'car vars)) + (delq nil + (mapcar + (lambda (p) (unless (equal (car p) name) p)) + vars)) + vars)))))) + (:results + (setq results (e-merge results-exclusive-groups + results (split-string (cdr pair))))) + (:file + (when (cdr pair) + (setq results (e-merge results-exclusive-groups + results '("file"))) + (unless (or (member "both" exports) + (member "none" exports) + (member "code" exports)) + (setq exports (e-merge exports-exclusive-groups + exports '("results")))) + (setq params (cons pair (assq-delete-all (car pair) params))))) + (:exports + (setq exports (e-merge exports-exclusive-groups + exports (split-string (cdr pair))))) + (:tangle ;; take the latest -- always overwrite + (setq tangle (or (list (cdr pair)) tangle))) + (:noweb + (setq noweb (e-merge '(("yes" "no")) noweb + (split-string (or (cdr pair) ""))))) + (:cache + (setq cache (e-merge '(("yes" "no")) cache + (split-string (or (cdr pair) ""))))) + (:shebang ;; take the latest -- always overwrite + (setq shebang (or (list (cdr pair)) shebang))) + (:comments + (setq comments (e-merge '(("yes" "no")) comments + (split-string (or (cdr pair) ""))))) + (t ;; replace: this covers e.g. :session + (setq params (cons pair (assq-delete-all (car pair) params)))))) + plist)) + plists)) + (while vars (setq params (cons (cons :var (cddr (pop vars))) params))) (cons (cons :comments (mapconcat 'identity comments " ")) (cons (cons :shebang (mapconcat 'identity shebang " ")) (cons (cons :cache (mapconcat 'identity cache " ")) @@ -1445,8 +1683,7 @@ #'identity (split-string (if evaluate - (let ((raw (org-babel-ref-resolve-reference - source-name nil))) + (let ((raw (org-babel-ref-resolve source-name))) (if (stringp raw) raw (format "%S" raw))) (save-restriction (widen) @@ -1497,14 +1734,14 @@ cell)) (defun org-babel-number-p (string) - "Return t if STRING represents a number." + "If STRING represents a number return it's value." (if (and (string-match "^-?[0-9]*\\.?[0-9]*$" string) (= (length (substring string (match-beginning 0) (match-end 0))) (length string))) (string-to-number string))) -(defun org-babel-import-elisp-from-file (file-name) +(defun org-babel-import-elisp-from-file (file-name &optional separator) "Read the results located at FILE-NAME into an elisp table. If the table is trivial, then return it as a scalar." (let (result) @@ -1512,7 +1749,7 @@ (with-temp-buffer (condition-case nil (progn - (org-table-import file-name nil) + (org-table-import file-name separator) (delete-file file-name) (setq result (mapcar (lambda (row) (mapcar #'org-babel-string-read row)) @@ -1569,21 +1806,77 @@ ;; bug in tramp (apply 'process-file program tmpfile buffer display args) (delete-file tmpfile))) - ;; org-babel-call-process-region-original is the original emacs definition. It - ;; is in scope from the let binding in org-babel-execute-src-block + ;; org-babel-call-process-region-original is the original emacs + ;; definition. It is in scope from the let binding in + ;; org-babel-execute-src-block (apply org-babel-call-process-region-original start end program delete buffer display args))) -(defun org-babel-maybe-remote-file (file) - "Conditionally parse information on a remote connnection. -If FILE specifies a remove file, then parse the information on -the remote connection." +(defun org-babel-local-file-name (file) + "Return the local name component of FILE." + (if (file-remote-p file) + (let (localname) + (with-parsed-tramp-file-name file nil + localname)) + file)) + +(defun org-babel-process-file-name (name &optional no-quote-p) + "Prepare NAME to be used in an external process. +If NAME specifies a remote location, the remote portion of the +name is removed, since in that case the process will be executing +remotely. The file name is then processed by +`expand-file-name'. Unless second argument NO-QUOTE-P is non-nil, +the file name is additionally processed by +`shell-quote-argument'" + ((lambda (f) (if no-quote-p f (shell-quote-argument f))) + (expand-file-name (org-babel-local-file-name name)))) + +(defvar org-babel-temporary-directory) +(unless (or noninteractive (boundp 'org-babel-temporary-directory)) + (defvar org-babel-temporary-directory + (or (and (boundp 'org-babel-temporary-directory) + (file-exists-p org-babel-temporary-directory) + org-babel-temporary-directory) + (make-temp-file "babel-" t)) + "Directory to hold temporary files created to execute code blocks. +Used by `org-babel-temp-file'. This directory will be removed on +Emacs shutdown.")) + +(defun org-babel-temp-file (prefix &optional suffix) + "Create a temporary file in the `org-babel-temporary-directory'. +Passes PREFIX and SUFFIX directly to `make-temp-file' with the +value of `temporary-file-directory' temporarily set to the value +of `org-babel-temporary-directory'." (if (file-remote-p default-directory) - (let* ((vec (tramp-dissect-file-name default-directory)) - (user (tramp-file-name-user vec)) - (host (tramp-file-name-host vec))) - (concat "/" user (when user "@") host ":" file)) - file)) + (make-temp-file + (concat (file-remote-p default-directory) + (expand-file-name + prefix temporary-file-directory) + nil suffix)) + (let ((temporary-file-directory + (or (and (file-exists-p org-babel-temporary-directory) + org-babel-temporary-directory) + temporary-file-directory))) + (make-temp-file prefix nil suffix)))) + +(defun org-babel-remove-temporary-directory () + "Remove `org-babel-temporary-directory' on Emacs shutdown." + (when (and (boundp 'org-babel-temporary-directory) + (file-exists-p org-babel-temporary-directory)) + ;; taken from `delete-directory' in files.el + (mapc (lambda (file) + ;; This test is equivalent to + ;; (and (file-directory-p fn) (not (file-symlink-p fn))) + ;; but more efficient + (if (eq t (car (file-attributes file))) + (delete-directory file) + (delete-file file))) + ;; We do not want to delete "." and "..". + (directory-files org-babel-temporary-directory 'full + "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*")) + (delete-directory org-babel-temporary-directory))) + +(add-hook 'kill-emacs-hook 'org-babel-remove-temporary-directory) (provide 'ob) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-agenda.el --- a/lisp/org/org-agenda.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-agenda.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -62,6 +62,7 @@ (declare-function org-habit-parse-todo "org-habit" (&optional pom)) (declare-function org-habit-get-priority "org-habit" (habit &optional moment)) (defvar calendar-mode-map) +(defvar org-clock-current-task) ; defined in org-clock.el (defvar org-mobile-force-id-on-agenda-items) ; defined in org-mobile.el (defvar org-habit-show-habits) (defvar org-habit-show-habits-only-for-today) @@ -749,6 +750,22 @@ :tag "Org Agenda Startup" :group 'org-agenda) +(defcustom org-agenda-menu-show-matcher t + "Non-nil menas show the match string in the agenda dispatcher menu. +When nil, the matcher string is not shown, but is put into the help-echo +property so than moving the mouse over the command shows it. +Setting it to nil is good if matcher strings are very long and/or if +you wnat to use two-column display (see `org-agenda-menu-two-column')." + :group 'org-agenda + :type 'boolean) + +(defcustom org-agenda-menu-two-column nil + "Non-nil means, use two columns to show custom commands in the dispatcher. +If you use this, you probably want to set `org-agenda-menu-show-matcher' +to nil." + :group 'org-agenda + :type 'boolean) + (defcustom org-finalize-agenda-hook nil "Hook run just before displaying an agenda buffer." :group 'org-agenda-startup @@ -1359,7 +1376,7 @@ "Regular expression used to filter away specific tags in agenda views. This means that these tags will be present, but not be shown in the agenda line. Secondary filtering will still work on the hidden tags. -The value nil means don't hide any tags." +Nil means don't hide any tags." :group 'org-agenda-line-format :type '(choice (const :tag "Hide none" nil) @@ -1471,6 +1488,18 @@ (require 'cl)) (require 'org) +(defmacro org-agenda-with-point-at-orig-entry (string &rest body) + "Execute BODY with point at location given by `org-hd-marker' property. +If STRING is non-nil, the text property will be fetched from position 0 +in that string. If STRING is nil, it will be fetched from the beginning +of the current line." + `(let ((marker (get-text-property (if string 0 (point-at-bol)) + 'org-hd-marker string))) + (with-current-buffer (marker-buffer marker) + (save-excursion + (goto-char marker) + ,@body)))) + (defun org-add-agenda-custom-command (entry) "Replace or add a command in `org-agenda-custom-commands'. This is mostly for hacking and trying a new command - once the command @@ -1651,7 +1680,7 @@ (org-defkey org-agenda-mode-map "\C-c\C-x\C-x" 'org-agenda-clock-cancel) (org-defkey org-agenda-mode-map "X" 'org-agenda-clock-cancel) (org-defkey org-agenda-mode-map "\C-c\C-x\C-j" 'org-clock-goto) -(org-defkey org-agenda-mode-map "J" 'org-clock-goto) +(org-defkey org-agenda-mode-map "J" 'org-agenda-clock-goto) (org-defkey org-agenda-mode-map "+" 'org-agenda-priority-up) (org-defkey org-agenda-mode-map "-" 'org-agenda-priority-down) (org-defkey org-agenda-mode-map [(shift up)] 'org-agenda-priority-up) @@ -2073,7 +2102,8 @@ (custom org-agenda-custom-commands) (selstring "") restriction second-time - c entry key type match prefixes rmheader header-end custom1 desc) + c entry key type match prefixes rmheader header-end custom1 desc + line lines left right n n1) (save-window-excursion (delete-other-windows) (org-switch-to-buffer-other-window " *Agenda Commands*") @@ -2111,56 +2141,91 @@ (move-marker header-end (match-end 0))) (goto-char header-end) (delete-region (point) (point-max)) + + ;; Produce all the lines that describe custom commands and prefixes + (setq lines nil) (while (setq entry (pop custom1)) (setq key (car entry) desc (nth 1 entry) type (nth 2 entry) match (nth 3 entry)) (if (> (length key) 1) (add-to-list 'prefixes (string-to-char key)) - (insert - (format - "\n%-4s%-14s: %s" - (org-add-props (copy-sequence key) - '(face bold)) - (cond - ((string-match "\\S-" desc) desc) - ((eq type 'agenda) "Agenda for current week or day") - ((eq type 'alltodo) "List of all TODO entries") - ((eq type 'search) "Word search") - ((eq type 'stuck) "List of stuck projects") - ((eq type 'todo) "TODO keyword") - ((eq type 'tags) "Tags query") - ((eq type 'tags-todo) "Tags (TODO)") - ((eq type 'tags-tree) "Tags tree") - ((eq type 'todo-tree) "TODO kwd tree") - ((eq type 'occur-tree) "Occur tree") - ((functionp type) (if (symbolp type) - (symbol-name type) - "Lambda expression")) - (t "???")) - (cond - ((stringp match) - (setq match (copy-sequence match)) - (org-add-props match nil 'face 'org-warning)) - (match - (format "set of %d commands" (length match))) - (t "")))))) + (setq line + (format + "%-4s%-14s" + (org-add-props (copy-sequence key) + '(face bold)) + (cond + ((string-match "\\S-" desc) desc) + ((eq type 'agenda) "Agenda for current week or day") + ((eq type 'alltodo) "List of all TODO entries") + ((eq type 'search) "Word search") + ((eq type 'stuck) "List of stuck projects") + ((eq type 'todo) "TODO keyword") + ((eq type 'tags) "Tags query") + ((eq type 'tags-todo) "Tags (TODO)") + ((eq type 'tags-tree) "Tags tree") + ((eq type 'todo-tree) "TODO kwd tree") + ((eq type 'occur-tree) "Occur tree") + ((functionp type) (if (symbolp type) + (symbol-name type) + "Lambda expression")) + (t "???")))) + (if org-agenda-menu-show-matcher + (setq line + (concat line ": " + (cond + ((stringp match) + (setq match (copy-sequence match)) + (org-add-props match nil 'face 'org-warning)) + (match + (format "set of %d commands" (length match))) + (t "")))) + (if (org-string-nw-p match) + (add-text-properties + 0 (length line) (list 'help-echo + (concat "Matcher: "match)) line))) + (push line lines))) + (setq lines (nreverse lines)) (when prefixes (mapc (lambda (x) - (insert - (format "\n%s %s" + (push + (format "%s %s" (org-add-props (char-to-string x) - nil 'face 'bold) - (or (cdr (assoc (concat selstring (char-to-string x)) + nil 'face 'bold) + (or (cdr (assoc (concat selstring + (char-to-string x)) prefix-descriptions)) - "Prefix key")))) + "Prefix key")) + lines)) prefixes)) + + ;; Check if we should display in two columns + (if org-agenda-menu-two-column + (progn + (setq n (length lines) + n1 (+ (/ n 2) (mod n 2)) + right (nthcdr n1 lines) + left (copy-sequence lines)) + (setcdr (nthcdr (1- n1) left) nil)) + (setq left lines right nil)) + (while left + (insert "\n" (pop left)) + (when right + (if (< (current-column) 40) + (move-to-column 40 t) + (insert " ")) + (insert (pop right)))) + + ;; Make the window the right size (goto-char (point-min)) (if second-time (if (not (pos-visible-in-window-p (point-max))) (org-fit-window-to-buffer)) (setq second-time t) (org-fit-window-to-buffer)) + + ;; Ask for selection (message "Press key for agenda command%s:" (if (or restrict-ok org-agenda-overriding-restriction) (if org-agenda-overriding-restriction @@ -2450,16 +2515,15 @@ (interactive "FWrite agenda to file: \nP") (if (not (file-writable-p file)) (error "Cannot write agenda to file %s" file)) - (cond - ((string-match "\\.html?\\'" file) (require 'htmlize)) - ((string-match "\\.ps\\'" file) (require 'ps-print))) (org-let (if nosettings nil org-agenda-exporter-settings) - `(save-excursion + '(save-excursion (save-window-excursion (org-agenda-mark-filtered-text) (let ((bs (copy-sequence (buffer-string))) beg) (org-agenda-unmark-filtered-text) (with-temp-buffer + (rename-buffer "Agenda View" t) + (set-buffer-modified-p nil) (insert bs) (org-agenda-remove-marked-text 'org-filtered) (while (setq beg (text-property-any (point-min) (point-max) @@ -2472,6 +2536,7 @@ ((org-bound-and-true-p org-mobile-creating-agendas) (org-mobile-write-agenda-for-mobile file)) ((string-match "\\.html?\\'" file) + (require 'htmlize) (set-buffer (htmlize-buffer (current-buffer))) (when (and org-agenda-export-html-style @@ -2486,18 +2551,17 @@ (message "HTML written to %s" file)) ((string-match "\\.ps\\'" file) (require 'ps-print) - ,(flet ((ps-get-buffer-name () "Agenda View")) - (ps-print-buffer-with-faces file)) + (ps-print-buffer-with-faces file) (message "Postscript written to %s" file)) ((string-match "\\.pdf\\'" file) (require 'ps-print) - ,(flet ((ps-get-buffer-name () "Agenda View")) - (ps-print-buffer-with-faces - (concat (file-name-sans-extension file) ".ps"))) + (ps-print-buffer-with-faces + (concat (file-name-sans-extension file) ".ps")) (call-process "ps2pdf" nil nil nil (expand-file-name (concat (file-name-sans-extension file) ".ps")) (expand-file-name file)) + (delete-file (concat (file-name-sans-extension file) ".ps")) (message "PDF written to %s" file)) ((string-match "\\.ics\\'" file) (require 'org-icalendar) @@ -2563,7 +2627,9 @@ (setq txt (org-agenda-get-some-entry-text m org-agenda-add-entry-text-maxlines " > ")) (end-of-line 1) - (if (string-match "\\S-" txt) (insert "\n" txt))))))) + (if (string-match "\\S-" txt) + (insert "\n" txt) + (or (eobp) (forward-char 1)))))))) (defun org-agenda-get-some-entry-text (marker n-lines &optional indent &rest keep) @@ -2717,7 +2783,10 @@ This must be a list of strings, each string must be a single tag preceded by \"+\" or \"-\". This variable should not be set directly, but agenda custom commands can -bind it in the options section.") +bind it in the options section. The preset filter is a global property of +the entire agenda view. In a block agenda, it will not work reliably to +define a filter for one of the individual blocks. You need to set it in +the global options and expect it to be applied to the entire view.") (defun org-prepare-agenda (&optional name) (setq org-todo-keywords-for-agenda nil) @@ -2760,7 +2829,11 @@ (switch-to-buffer-other-frame abuf)) ((equal org-agenda-window-setup 'reorganize-frame) (delete-other-windows) - (org-switch-to-buffer-other-window abuf)))) + (org-switch-to-buffer-other-window abuf))) + ;; additional test in case agenda is invoked from within agenda + ;; buffer via elisp link + (unless (equal (current-buffer) abuf) + (switch-to-buffer abuf))) (setq buffer-read-only nil) (let ((inhibit-read-only t)) (erase-buffer)) (org-agenda-mode) @@ -3009,7 +3082,8 @@ (let* ((dopast t) (dotodo include-all) (doclosed org-agenda-show-log) - (entry buffer-file-name) + (entry (buffer-file-name (or (buffer-base-buffer (current-buffer)) + (current-buffer)))) (date (calendar-current-date)) (beg (if (org-region-active-p) (region-beginning) (point-min))) (end (if (org-region-active-p) (region-end) (point-max))) @@ -3031,8 +3105,7 @@ (setq day-numbers (delq nil (mapcar (lambda(x) (if (>= x today) x nil)) day-numbers)))) - (org-prepare-agenda (concat "Timeline " - (file-name-nondirectory buffer-file-name))) + (org-prepare-agenda (concat "Timeline " (file-name-nondirectory entry))) (if doclosed (push :closed args)) (push :timestamp args) (push :deadline args) @@ -3483,6 +3556,20 @@ (member (string-to-char words) '(?- ?+ ?\{))) (setq boolean t)) (setq words (org-split-string words)) + (let (www w) + (while (setq w (pop words)) + (while (and (string-match "\\\\\\'" w) words) + (setq w (concat (substring w 0 -1) " " (pop words)))) + (push w www)) + (setq words (nreverse www) www nil) + (while (setq w (pop words)) + (when (and (string-match "\\`[-+]?{" w) + (not (string-match "}\\'" w))) + (while (and words (not (string-match "}\\'" (car words)))) + (setq w (concat w " " (pop words)))) + (setq w (concat w " " (pop words)))) + (push w www)) + (setq words (nreverse www))) (setq org-agenda-last-search-view-search-was-boolean boolean) (when boolean (let (wds w) @@ -3933,8 +4020,7 @@ "Create agenda view for projects that are stuck. Stuck projects are project that have no next actions. For the definitions of what a project is and how to check if it stuck, customize the variable -`org-stuck-projects'. -MATCH is being ignored." +`org-stuck-projects'." (interactive) (let* ((org-agenda-skip-function 'org-agenda-skip-entry-when-regexp-matches-in-subtree) @@ -3956,11 +4042,11 @@ "\\)\\>")) (tags (nth 2 org-stuck-projects)) (tags-re (if (member "*" tags) - (org-re "^\\*+ .*:[[:alnum:]_@]+:[ \t]*$") + (org-re "^\\*+ .*:[[:alnum:]_@#%]+:[ \t]*$") (if tags (concat "^\\*+ .*:\\(" (mapconcat 'identity tags "\\|") - (org-re "\\):[[:alnum:]_@:]*[ \t]*$"))))) + (org-re "\\):[[:alnum:]_@#%:]*[ \t]*$"))))) (gen-re (nth 3 org-stuck-projects)) (re-list (delq nil @@ -4413,17 +4499,20 @@ category (org-get-category beg) todo-state (org-get-todo-state)) - (if (string-match "\\S-" result) - (setq txt result) - (setq txt "SEXP entry returned empty string")) - - (setq txt (org-format-agenda-item - "" txt category tags 'time)) - (org-add-props txt props 'org-marker marker) - (org-add-props txt nil - 'org-category category 'date date 'todo-state todo-state - 'type "sexp") - (push txt ee)))) + (dolist (r (if (stringp result) + (list result) + result)) ;; we expect a list here + (if (string-match "\\S-" r) + (setq txt r) + (setq txt "SEXP entry returned empty string")) + + (setq txt (org-format-agenda-item + "" txt category tags 'time)) + (org-add-props txt props 'org-marker marker) + (org-add-props txt nil + 'org-category category 'date date 'todo-state todo-state + 'type "sexp") + (push txt ee))))) (nreverse ee))) (defun org-diary-class (m1 d1 y1 m2 d2 y2 dayname &rest skip-weeks) @@ -4919,7 +5008,7 @@ (setq h (/ m 60) m (- m (* h 60))) (setq s2 (format "%02d:%02d" h m)))) - (when (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$") + (when (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") txt) ;; Tags are in the string (if (or (eq org-agenda-remove-tags t) @@ -4993,7 +5082,7 @@ The modified list may contain inherited tags, and tags matched by `org-agenda-hide-tags-regexp' will be removed." (when (or add-inherited hide-re) - (if (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$") txt) + (if (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") txt) (setq txt (substring txt 0 (match-beginning 0)))) (setq tags (delq nil @@ -5049,13 +5138,13 @@ (throw 'exit list)) (while (setq time (pop gridtimes)) (unless (and remove (member time have)) - (setq time (int-to-string time)) + (setq time (replace-regexp-in-string " " "0" (format "%04s" time))) (push (org-format-agenda-item nil string "" nil (concat (substring time 0 -2) ":" (substring time -2))) new) (put-text-property - 1 (length (car new)) 'face 'org-time-grid (car new)))) + 2 (length (car new)) 'face 'org-time-grid (car new)))) (if (member 'time-up org-agenda-sorting-strategy-selected) (append new list) (append list new))))) @@ -5142,11 +5231,33 @@ (int-to-string t0)))) (if string (concat (substring t1 -4 -2) ":" (substring t1 -2)) t0))))) +(defvar org-agenda-before-sorting-filter-function nil + "Function to be applied to agenda items prior to sorting. +Prior to sorting also means just before they are inserted into the agenda. + +To aid sorting, you may revisit the original entries and add more text +properties which will later be used by the sorting functions. + +The function should take a string argument, an agenda line. +It has access to the text properties in that line, which contain among +other things, the property `org-hd-marker' that points to the entry +where the line comes from. Note that not all lines going into the agenda +have this property, only most. + +The function should return the modified string. It is probably best +to ONLY change text properties. + +You can also use this function as a filter, by returning nil for lines +you don't want to have in the agenda at all. For this application, you +could bind the variable in the options section of a custom command.") + (defun org-finalize-agenda-entries (list &optional nosort) "Sort and concatenate the agenda items." (setq list (mapcar 'org-agenda-highlight-todo list)) (if nosort list + (when org-agenda-before-sorting-filter-function + (setq list (delq nil (mapcar org-agenda-before-sorting-filter-function list)))) (mapconcat 'identity (sort list 'org-entries-lessp) "\n"))) (defun org-agenda-highlight-todo (x) @@ -5312,8 +5423,9 @@ (alpha-up (and (org-em 'alpha-up 'alpha-down ss) (org-cmp-alpha a b))) (alpha-down (if alpha-up (- alpha-up) nil)) + (need-user-cmp (org-em 'user-defined-up 'user-defined-down ss)) user-defined-up user-defined-down) - (if (and org-agenda-cmp-user-defined + (if (and need-user-cmp org-agenda-cmp-user-defined (functionp org-agenda-cmp-user-defined)) (setq user-defined-up (funcall org-agenda-cmp-user-defined a b) @@ -5635,7 +5747,9 @@ (if (not (eval org-agenda-filter-form)) (org-agenda-filter-by-tag-hide-line)) (beginning-of-line 2)) - (beginning-of-line 2)))))) + (beginning-of-line 2)))) + (if (get-char-property (point) 'invisible) + (org-agenda-previous-line)))) (defun org-agenda-filter-by-tag-hide-line () (let (ov) @@ -5712,7 +5826,9 @@ (defun org-agenda-goto-date (date) "Jump to DATE in agenda." - (interactive (list (org-read-date))) + (interactive (list (let ((org-read-date-prefer-future + (eval org-agenda-jump-prefer-future))) + (org-read-date)))) (org-agenda-list nil date)) (defun org-agenda-goto-today () @@ -6636,7 +6752,7 @@ (let ((inhibit-read-only t) l c) (save-excursion (goto-char (if line (point-at-bol) (point-min))) - (while (re-search-forward (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$") + (while (re-search-forward (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") (if line (point-at-eol) nil) t) (add-text-properties (match-beginning 2) (match-end 2) @@ -7059,9 +7175,9 @@ (setq newhead (org-get-heading))) (org-agenda-change-all-lines newhead hdmarker))))) -(defun org-agenda-clock-out (&optional arg) +(defun org-agenda-clock-out () "Stop the currently running clock." - (interactive "P") + (interactive) (unless (marker-buffer org-clock-marker) (error "No running clock")) (let ((marker (make-marker)) newhead) @@ -7086,6 +7202,23 @@ (org-with-remote-undo (marker-buffer org-clock-marker) (org-clock-cancel))) +(defun org-agenda-clock-goto () + "Jump to the currently clocked in task within the agenda. +If the currently clocked in task is not listed in the agenda +buffer, display it in another window." + (interactive) + (let (pos) + (mapc (lambda (o) + (if (eq (overlay-get o 'type) 'org-agenda-clocking) + (setq pos (overlay-start o)))) + (overlays-in (point-min) (point-max))) + (cond (pos (goto-char pos)) + ;; If the currently clocked entry is not in the agenda + ;; buffer, we visit it in another window: + (org-clock-current-task + (org-switch-to-buffer-other-window (org-clock-goto))) + (t (message "No running clock, use `C-c C-x C-j' to jump to the most recent one"))))) + (defun org-agenda-diary-entry-in-org-file () "Make a diary entry in the file `org-agenda-diary-file'." (let (d1 d2 char (text "") dp1 dp2) @@ -7171,7 +7304,8 @@ (let ((calendar-date-display-form (if (if (boundp 'calendar-date-style) (eq calendar-date-style 'european) - (org-bound-and-true-p european-calendar-style)) ; Emacs 22 + (with-no-warnings ;; european-calendar-style is obsolete as of version 23.1 + (org-bound-and-true-p european-calendar-style))) ; Emacs 22 '(day " " month " " year) '(month " " day " " year)))) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-archive.el --- a/lisp/org/org-archive.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-archive.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -115,7 +115,7 @@ ((or (re-search-backward re nil t) (re-search-forward re nil t)) (match-string 1)) - (t org-archive-location (match-string 1))))))) + (t org-archive-location)))))) (defun org-add-archive-files (files) "Splice the archive files into the list of files. @@ -268,7 +268,7 @@ (progn (if (re-search-forward (concat "^" (regexp-quote heading) - (org-re "[ \t]*\\(:[[:alnum:]_@:]+:\\)?[ \t]*\\($\\|\r\\)")) + (org-re "[ \t]*\\(:[[:alnum:]_@#%:]+:\\)?[ \t]*\\($\\|\r\\)")) nil t) (goto-char (match-end 0)) ;; Heading not found, just insert it at the end diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-ascii.el --- a/lisp/org/org-ascii.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-ascii.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -311,7 +311,7 @@ :add-text (plist-get opt-plist :text)) "\n")) thetoc have-headings first-heading-pos - table-open table-buffer link-buffer link desc desc0 rpl wrap) + table-open table-buffer link-buffer link type path desc desc0 rpl wrap fnc) (let ((inhibit-read-only t)) (org-unmodified (remove-text-properties (point-min) (point-max) @@ -347,7 +347,7 @@ (if (and (or author email) org-export-author-info) - (insert(concat (nth 1 lang-words) ": " (or author "") + (insert (concat (nth 1 lang-words) ": " (or author "") (if (and org-export-email-info email (string-match "\\S-" email)) (concat " <" email ">") "") @@ -400,7 +400,7 @@ (if (and (memq org-export-with-tags '(not-in-toc nil)) (string-match - (org-re "[ \t]+:[[:alnum:]_@:]+:[ \t]*$") + (org-re "[ \t]+:[[:alnum:]_@#%:]+:[ \t]*$") txt)) (setq txt (replace-match "" t t txt))) (if (string-match quote-re0 txt) @@ -431,10 +431,12 @@ ;; Remove the quoted HTML tags. (setq line (org-html-expand-for-ascii line)) ;; Replace links with the description when possible - (while (string-match org-bracket-link-regexp line) - (setq link (match-string 1 line) - desc0 (match-string 3 line) - desc (or desc0 (match-string 1 line))) + (while (string-match org-bracket-link-analytic-regexp++ line) + (setq path (match-string 3 line) + link (concat (match-string 1 line) path) + type (match-string 2 line) + desc0 (match-string 5 line) + desc (or desc0 link)) (if (and (> (length link) 8) (equal (substring link 0 8) "coderef:")) (setq line (replace-match @@ -443,15 +445,18 @@ (substring link 8) org-export-code-refs))) t t line)) - (setq rpl (concat "[" - (or (match-string 3 line) (match-string 1 line)) - "]")) - (when (and desc0 (not (equal desc0 link))) - (if org-export-ascii-links-to-notes - (push (cons desc0 link) link-buffer) - (setq rpl (concat rpl " (" link ")") - wrap (+ (length line) (- (length (match-string 0 line))) - (length desc))))) + (setq rpl (concat "[" desc "]")) + (if (functionp (setq fnc (nth 2 (assoc type org-link-protocols)))) + (setq rpl (or (save-match-data + (funcall fnc (org-link-unescape path) + desc0 'ascii)) + rpl)) + (when (and desc0 (not (equal desc0 link))) + (if org-export-ascii-links-to-notes + (push (cons desc0 link) link-buffer) + (setq rpl (concat rpl " (" link ")") + wrap (+ (length line) (- (length (match-string 0 line))) + (length desc)))))) (setq line (replace-match rpl t t line)))) (when custom-times (setq line (org-translate-time line))) @@ -482,7 +487,8 @@ (org-format-table-ascii table-buffer) "\n") "\n"))) (t - (if (string-match "^\\([ \t]*\\)\\([-+*][ \t]+\\)\\(.*?\\)\\( ::\\)" line) + (if (string-match "^\\([ \t]*\\)\\([-+*][ \t]+\\)\\(.*?\\)\\( ::\\)" + line) (setq line (replace-match "\\1\\3:" t nil line))) (setq line (org-fix-indentation line org-ascii-current-indentation)) ;; Remove forced line breaks @@ -571,9 +577,12 @@ (replace-match "\\1\\2"))) ;; Remove list start counters (goto-char (point-min)) - (while (re-search-forward "\\[@start:[0-9]+\\] ?" nil t) - (org-if-unprotected - (replace-match "")))) + (while (org-search-forward-unenclosed + "\\[@\\(?:start:\\)?[0-9]+\\][ \t]*" nil t) + (replace-match "")) + (remove-text-properties + (point-min) (point-max) + '(face nil font-lock-fontified nil font-lock-multiline nil line-prefix nil wrap-prefix nil))) (defun org-html-expand-for-ascii (line) "Handle quoted HTML for ASCII export." @@ -586,7 +595,7 @@ (defun org-ascii-replace-entities () "Replace entities with the ASCII representation." (let (e) - (while (re-search-forward "\\\\\\([a-zA-Z]+[0-9]*\\)" nil t) + (while (re-search-forward "\\\\\\([a-zA-Z]+[0-9]*\\)\\({}\\)?" nil t) (org-if-unprotected-at (match-beginning 1) (setq e (org-entity-get-representation (match-string 1) org-export-ascii-entities)) @@ -645,7 +654,7 @@ (insert "\n")) (setq char (nth (- umax level) (reverse org-export-ascii-underline))) (unless org-export-with-tags - (if (string-match (org-re "[ \t]+\\(:[[:alnum:]_@:]+:\\)[ \t]*$") title) + (if (string-match (org-re "[ \t]+\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") title) (setq title (replace-match "" t t title)))) (if org-export-with-section-numbers (setq title (concat (org-section-number level) " " title))) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-attach.el --- a/lisp/org/org-attach.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-attach.el Thu Nov 11 22:10:19 2010 -0600 @@ -4,7 +4,7 @@ ;; Author: John Wiegley ;; Keywords: org data task -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-bbdb.el --- a/lisp/org/org-bbdb.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-bbdb.el Thu Nov 11 22:10:19 2010 -0600 @@ -7,7 +7,7 @@ ;; Thomas Baumann ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -322,8 +322,8 @@ (when rec (let* ((class (or (nth 2 rec) org-bbdb-default-anniversary-format)) - (form (or (cdr (assoc class - org-bbdb-anniversary-format-alist)) + (form (or (cdr (assoc-string + class org-bbdb-anniversary-format-alist t)) class)) ; (as format string) (name (nth 1 rec)) (years (- y (car rec))) @@ -338,8 +338,7 @@ (setq text (append text (list tmp))) (setq text (list tmp))))) )) - (when text - (mapconcat 'identity text "; ")))) + text)) (defun org-bbdb-complete-link () "Read a bbdb link with name completion." diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-beamer.el --- a/lisp/org/org-beamer.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-beamer.el Thu Nov 11 22:10:19 2010 -0600 @@ -2,7 +2,7 @@ ;; ;; Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. ;; -;; Version: 7.01 +;; Version: 7.3 ;; Author: Carsten Dominik ;; Maintainer: Carsten Dominik ;; Keywords: org, wp, tex @@ -373,7 +373,7 @@ (let (dovl) (goto-char (point-min)) (while (re-search-forward - "^[ \t]*\\\\begin{\\(itemize\\|enumerate\\|desctiption\\)}[ \t\n]*\\\\item\\>\\( ?\\(<[^<>\n]*>\\|\\[[^][\n*]\\]\\)\\)?[ \t]*\\S-" nil t) + "^[ \t]*\\\\begin{\\(itemize\\|enumerate\\|description\\)}[ \t\n]*\\\\item\\>\\( ?\\(<[^<>\n]*>\\|\\[[^][\n*]\\]\\)\\)?[ \t]*\\S-" nil t) (if (setq dovl (cdr (assoc "BEAMER_dovl" (get-text-property (match-end 0) 'org-props)))) @@ -382,7 +382,7 @@ (insert dovl))))))) (defun org-beamer-amend-header () - "Add `org-beamer-header-extra' to the LaTeX herder. + "Add `org-beamer-header-extra' to the LaTeX header. If the file contains the string BEAMER-HEADER-EXTRA-HERE on a line by itself, it will be replaced with `org-beamer-header-extra'. If not, the value will be inserted right after the documentclass statement." diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-bibtex.el --- a/lisp/org/org-bibtex.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-bibtex.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Bastien Guerry ;; Carsten Dominik ;; Keywords: org, wp, remember -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-capture.el --- a/lisp/org/org-capture.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-capture.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -76,6 +76,7 @@ :tag "Org Capture" :group 'org) +;;;###autoload (defcustom org-capture-templates nil "Templates for the creation of new entries. @@ -185,6 +186,10 @@ which means that the new line should become the third line before the second horizontal separator line. + :kill-buffer If the target file was not yet visited by a buffer when + capture was invoked, kill the buffer again after capture + is finalized. + The template defines the text to be inserted. Often this is an org-mode entry (so the first line should start with a star) that will be filed as a child of the target headline. It can also be freely formatted text. @@ -220,20 +225,23 @@ Apart from these general escapes, you can access information specific to the link type that is created. For example, calling `org-capture' in emails or gnus will record the author and the subject of the message, which you -can access with \"%:author\" and \"%:subject\", respectively. Here is a +can access with \"%:from\" and \"%:subject\", respectively. Here is a complete list of what is recorded for each link type. -Link type | Available information --------------------+------------------------------------------------------ -bbdb | %:type %:name %:company -vm, wl, mh, rmail | %:type %:subject %:message-id - | %:from %:fromname %:fromaddress - | %:to %:toname %:toaddress - | %:fromto (either \"to NAME\" or \"from NAME\") -gnus | %:group, for messages also all email fields -w3, w3m | %:type %:url -info | %:type %:file %:node -calendar | %:type %:date" +Link type | Available information +------------------------+------------------------------------------------------ +bbdb | %:type %:name %:company +vm, wl, mh, mew, rmail | %:type %:subject %:message-id + | %:from %:fromname %:fromaddress + | %:to %:toname %:toaddress + | %:fromto (either \"to NAME\" or \"from NAME\") + | %:date + | %:date-timestamp (as active timestamp) + | %:date-timestamp-inactive (as inactive timestamp) +gnus | %:group, for messages also all email fields +w3, w3m | %:type %:url +info | %:type %:file %:node +calendar | %:type %:date" :group 'org-capture :type '(repeat @@ -289,7 +297,7 @@ (file :tag "Template file")) (list :tag "Function" (const :format "" function) - (file :tag "Template function"))) + (function :tag "Template function"))) (plist :inline t ;; Give the most common options as checkboxes :options (((const :format "%v " :prepend) (const t)) @@ -297,7 +305,8 @@ ((const :format "%v " :empty-lines) (const 1)) ((const :format "%v " :clock-in) (const t)) ((const :format "%v " :clock-resume) (const t)) - ((const :format "%v " :unnarrowed) (const t)))))))) + ((const :format "%v " :unnarrowed) (const t)) + ((const :format "%v " :kill-buffer) (const t)))))))) (defcustom org-capture-before-finalize-hook nil "Hook that is run right before a remember process is finalized. @@ -382,6 +391,11 @@ (initial (and (org-region-active-p) (buffer-substring (point) (mark)))) (entry (org-capture-select-template keys))) + (when (stringp initial) + (remove-text-properties 0 (length initial) '(read-only t) initial)) + (when (stringp annotation) + (remove-text-properties 0 (length annotation) + '(read-only t) annotation)) (cond ((equal entry "C") (customize-variable 'org-capture-templates)) @@ -467,8 +481,9 @@ (markerp (org-capture-get :interrupted-clock 'local)) (buffer-live-p (marker-buffer (org-capture-get :interrupted-clock 'local)))) - (org-with-point-at (org-capture-get :interrupted-clock 'local) - (org-clock-in)) + (let ((clock-in-task (org-capture-get :interrupted-clock 'local))) + (org-with-point-at clock-in-task + (org-clock-in))) (message "Interrupted clock has been resumed"))) (let ((beg (point-min)) @@ -519,14 +534,25 @@ ;; Kill the indirect buffer (save-buffer) - (let ((return-wconf (org-capture-get :return-to-wconf 'local))) + (let ((return-wconf (org-capture-get :return-to-wconf 'local)) + (new-buffer (org-capture-get :new-buffer 'local)) + (kill-buffer (org-capture-get :kill-buffer 'local)) + (base-buffer (buffer-base-buffer (current-buffer)))) + + ;; Kill the indiret buffer (kill-buffer (current-buffer)) + + ;; Kill the target buffer if that is desired + (when (and base-buffer new-buffer kill-buffer) + (with-current-buffer base-buffer (save-buffer)) + (kill-buffer base-buffer)) + ;; Restore the window configuration before capture (set-window-configuration return-wconf)) (when abort-note (cond ((equal abort-note 'clean) - (message "Capture process aborted and target file cleaned up")) + (message "Capture process aborted and target buffer cleaned up")) ((equal abort-note 'dirty) (error "Capture process aborted, but target buffer could not be cleaned up correctly")))))) @@ -588,6 +614,8 @@ (set-buffer (org-capture-target-buffer (nth 1 target))) (let ((hd (nth 2 target))) (goto-char (point-min)) + (unless (org-mode-p) + (error "Target buffer for file+headline should be in Org mode")) (if (re-search-forward (format org-complex-heading-regexp-format (regexp-quote hd)) nil t) @@ -651,8 +679,12 @@ (defun org-capture-target-buffer (file) "Get a buffer for FILE." + (setq file (or (org-string-nw-p file) + org-default-notes-file + (error "No notes file specified, and no default available"))) (or (org-find-base-buffer-visiting file) - (find-file-noselect (expand-file-name file org-directory)))) + (progn (org-capture-put :new-buffer t) + (find-file-noselect (expand-file-name file org-directory))))) (defun org-capture-steal-local-variables (buffer) "Install Org-mode local variables." @@ -666,6 +698,7 @@ (delete-other-windows) (org-switch-to-buffer-other-window (org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE")) + (widen) (show-all) (goto-char (org-capture-get :pos)) (org-set-local 'org-capture-target-marker @@ -676,7 +709,8 @@ ((nil entry) (org-capture-place-entry)) (table-line (org-capture-place-table-line)) (plain (org-capture-place-plain-text)) - (item (org-capture-place-item)))) + (item (org-capture-place-item)) + (checkitem (org-capture-place-item)))) (org-capture-mode 1) (org-set-local 'org-capture-current-plist org-capture-plist)) @@ -695,7 +729,8 @@ (setq level 1) (if reversed (progn (goto-char (point-min)) - (outline-next-heading)) + (or (org-at-heading-p) + (outline-next-heading))) (goto-char (point-max)) (or (bolp) (insert "\n")))) (t @@ -718,6 +753,7 @@ (setq end (point)) (org-capture-mark-kill-region beg (1- end)) (org-capture-narrow beg (1- end)) + (goto-char beg) (if (re-search-forward "%\\?" end t) (replace-match "")))) (defun org-capture-place-item () @@ -738,14 +774,14 @@ (if (org-capture-get :prepend) (progn (goto-char beg) - (if (re-search-forward (concat "^" (org-item-re)) nil t) + (if (org-search-forward-unenclosed org-item-beginning-re end t) (progn (goto-char (match-beginning 0)) (setq ind (org-get-indentation))) (goto-char end) (setq ind 0))) (goto-char end) - (if (re-search-backward (concat "^" (org-item-re)) nil t) + (if (org-search-backward-unenclosed org-item-beginning-re beg t) (progn (setq ind (org-get-indentation)) (org-end-of-item)) @@ -929,7 +965,7 @@ (let ((pos (point))) (org-back-over-empty-lines) (delete-region (point) pos) - (newline n))) + (if (> n 0) (newline n)))) (defun org-capture-empty-lines-after (&optional n) "Arrange for the correct number of empty lines after the inserted string. @@ -938,7 +974,7 @@ (org-back-over-empty-lines) (while (looking-at "[ \t]*\n") (replace-match "")) (let ((pos (point))) - (newline n) + (if (> n 0) (newline n)) (goto-char pos))) (defvar org-clock-marker) ; Defined in org.el @@ -967,7 +1003,7 @@ (insert template) (org-capture-empty-lines-after) (goto-char beg) - (org-maybe-renumber-ordered-list) + (org-list-repair) (org-end-of-item) (setq end (point))) (t (insert template))) @@ -1023,17 +1059,19 @@ (defun org-capture-select-template (&optional keys) "Select a capture template. Lisp programs can force the template by setting KEYS to a string." - (when org-capture-templates - (if keys - (or (assoc keys org-capture-templates) - (error "No capture template referred to by \"%s\" keys" keys)) - (if (= 1 (length org-capture-templates)) - (car org-capture-templates) - (org-mks org-capture-templates - "Select a capture template\n=========================" - "Template key: " - '(("C" "Customize org-capture-templates") - ("q" "Abort"))))))) + (if org-capture-templates + (if keys + (or (assoc keys org-capture-templates) + (error "No capture template referred to by \"%s\" keys" keys)) + (if (= 1 (length org-capture-templates)) + (car org-capture-templates) + (org-mks org-capture-templates + "Select a capture template\n=========================" + "Template key: " + '(("C" "Customize org-capture-templates") + ("q" "Abort"))))) + ;; Use an arbitrary default template + '("t" "Task" entry (file+headline "" "Tasks") "* TODO %?\n %u\n %a"))) (defun org-capture-fill-template (&optional template initial annotation) "Fill a template and return the filled template as a string. @@ -1098,6 +1136,7 @@ (plist-put org-store-link-plist :annotation v-a) org-store-link-plist (plist-put org-store-link-plist :initial v-i)) + (setq initial v-i) (unless template (setq template "") (message "No template") (ding) (sit-for 1)) @@ -1138,6 +1177,7 @@ (insert result))))) ;; Simple %-escapes + (goto-char (point-min)) (while (re-search-forward "%\\([tTuUaiAcxkKI]\\)" nil t) (unless (org-capture-escaped-%) (when (and initial (equal (match-string 0) "%i")) @@ -1181,6 +1221,7 @@ "org-capture-template-prompt-history::" (or prompt ""))) completions (mapcar 'list completions))) + (unless (boundp histvar) (set histvar nil)) (cond ((member char '("G" "g")) (let* ((org-last-tags-completion-table @@ -1195,12 +1236,13 @@ 'org-tags-history))) (setq ins (mapconcat 'identity (org-split-string - ins (org-re "[^[:alnum:]_@]+")) + ins (org-re "[^[:alnum:]_@#%]+")) ":")) (when (string-match "\\S-" ins) (or (equal (char-before) ?:) (insert ":")) (insert ins) - (or (equal (char-after) ?:) (insert ":"))))) + (or (equal (char-after) ?:) (insert ":")) + (and (org-on-heading-p) (org-set-tags nil 'align))))) ((equal char "C") (cond ((= (length clipboards) 1) (insert (car clipboards))) ((> (length clipboards) 1) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-clock.el --- a/lisp/org/org-clock.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-clock.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -35,6 +35,7 @@ (require 'cl)) (declare-function calendar-absolute-from-iso "cal-iso" (&optional date)) +(declare-function notifications-notify "notifications" (&rest params)) (defvar org-time-stamp-formats) (defgroup org-clock nil @@ -557,6 +558,14 @@ ((stringp org-show-notification-handler) (start-process "emacs-timer-notification" nil org-show-notification-handler notification)) + ((featurep 'notifications) + (require 'notifications) + (notifications-notify + :title "Org-mode message" + :body notification + ;; FIXME how to link to the Org icon? + ;; :app-icon "~/.emacs.d/icons/mail.png" + :urgency 'low)) ((org-program-exists "notify-send") (start-process "emacs-timer-notification" nil "notify-send" notification)) @@ -950,7 +959,7 @@ ;; We are interrupting the clocking of a different task. ;; Save a marker to this task, so that we can go back. ;; First check if we are trying to clock into the same task! - (if (save-excursion + (when (save-excursion (unless selected-task (org-back-to-heading t)) (and (equal (marker-buffer org-clock-hd-marker) @@ -961,13 +970,13 @@ (if selected-task (marker-position selected-task) (point))))) - (message "Clock continues in \"%s\"" org-clock-heading) - (progn - (move-marker org-clock-interrupted-task - (marker-position org-clock-marker) - (org-clocking-buffer)) - (let ((org-clock-clocking-in t)) - (org-clock-out t))))) + (message "Clock continues in \"%s\"" org-clock-heading) + (throw 'abort nil)) + (move-marker org-clock-interrupted-task + (marker-position org-clock-marker) + (marker-buffer org-clock-marker)) + (let ((org-clock-clocking-in t)) + (org-clock-out t))) (when (equal select '(16)) ;; Mark as default clocking task @@ -1098,6 +1107,7 @@ (defun org-clock-set-current () "Set `org-clock-current-task' to the task currently clocked in." (setq org-clock-current-task (nth 4 (org-heading-components)))) + (defun org-clock-delete-current () "Reset `org-clock-current-task' to nil." (setq org-clock-current-task nil)) @@ -1830,6 +1840,7 @@ (org-prepare-agenda-buffers files) (while (setq file (pop files)) (with-current-buffer (find-buffer-visiting file) + (setq org-clock-file-total-minutes 0) (setq tbl1 (org-dblock-write:clocktable p1)) (when tbl1 (push (org-clocktable-add-file @@ -1862,7 +1873,7 @@ (when (setq time (get-text-property p :org-clock-minutes)) (save-excursion (beginning-of-line 1) - (when (and (looking-at (org-re "\\(\\*+\\)[ \t]+\\(.*?\\)\\([ \t]+:[[:alnum:]_@:]+:\\)?[ \t]*$")) + (when (and (looking-at (org-re "\\(\\*+\\)[ \t]+\\(.*?\\)\\([ \t]+:[[:alnum:]_@#%:]+:\\)?[ \t]*$")) (setq level (org-reduced-level (- (match-end 1) (match-beginning 1)))) (<= level maxlevel)) @@ -1970,10 +1981,22 @@ (when block (setq cc (org-clock-special-range block nil t) ts (car cc) te (nth 1 cc) range-text (nth 2 cc))) - (if ts (setq ts (org-float-time - (apply 'encode-time (org-parse-time-string ts))))) - (if te (setq te (org-float-time - (apply 'encode-time (org-parse-time-string te))))) + (cond + ((numberp ts) + ;; If ts is a number, it's an absolute day number from org-agenda. + (destructuring-bind (month day year) (calendar-gregorian-from-absolute ts) + (setq ts (org-float-time (encode-time 0 0 0 day month year))))) + (ts + (setq ts (org-float-time + (apply 'encode-time (org-parse-time-string ts)))))) + (cond + ((numberp te) + ;; Likewise for te. + (destructuring-bind (month day year) (calendar-gregorian-from-absolute te) + (setq te (org-float-time (encode-time 0 0 0 day month year))))) + (te + (setq te (org-float-time + (apply 'encode-time (org-parse-time-string te)))))) (setq p1 (plist-put p1 :header "")) (setq p1 (plist-put p1 :step nil)) (setq p1 (plist-put p1 :block nil)) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-colview.el --- a/lisp/org/org-colview.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-colview.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -228,7 +228,9 @@ (overlay-put ov 'org-columns-value (cdr ass)) (overlay-put ov 'org-columns-value-modified modval) (overlay-put ov 'org-columns-pom pom) - (overlay-put ov 'org-columns-format f)) + (overlay-put ov 'org-columns-format f) + (overlay-put ov 'line-prefix "") + (overlay-put ov 'wrap-prefix "")) (if (or (not (char-after beg)) (equal (char-after beg) ?\n)) (let ((inhibit-read-only t)) @@ -241,6 +243,8 @@ (overlay-put ov 'invisible t) (overlay-put ov 'keymap org-columns-map) (overlay-put ov 'intangible t) + (overlay-put ov 'line-prefix "") + (overlay-put ov 'wrap-prefix "") (push ov org-columns-overlays) (setq ov (make-overlay (1- (point-at-eol)) (1+ (point-at-eol)))) (overlay-put ov 'keymap org-columns-map) @@ -464,7 +468,7 @@ (call-interactively 'org-schedule)))) ((equal key "BEAMER_env") (setq eval '(org-with-point-at pom - (call-interactively 'org-beamer-set-environment-tag)))) + (call-interactively 'org-beamer-select-environment)))) (t (setq allowed (org-property-get-allowed-values pom key 'table)) (if allowed @@ -515,7 +519,7 @@ (txt (match-string 3)) (post "") txt2) - (if (string-match (org-re "[ \t]+:[[:alnum:]:_@]+:[ \t]*$") txt) + (if (string-match (org-re "[ \t]+:[[:alnum:]:_@#%]+:[ \t]*$") txt) (setq post (match-string 0 txt) txt (substring txt 0 (match-beginning 0)))) (setq txt2 (read-string "Edit: " txt)) @@ -746,7 +750,8 @@ ("@max" max_age max (lambda (x) (- org-columns-time x))) ("@mean" mean_age (lambda (&rest x) (/ (apply '+ x) (float (length x)))) - (lambda (x) (- org-columns-time x)))) + (lambda (x) (- org-columns-time x))) + ("est+" estimate org-estimate-combine)) "Operator <-> format,function,calc map. Used to compile/uncompile columns format and completing read in interactive function `org-columns-new'. @@ -1031,6 +1036,7 @@ (defun org-columns-number-to-string (n fmt &optional printf) "Convert a computed column number to a string value, according to FMT." (cond + ((memq fmt '(estimate)) (org-estimate-print n printf)) ((not (numberp n)) "") ((memq fmt '(add_times max_times min_times mean_times)) (let* ((h (floor n)) (m (floor (+ 0.5 (* 60 (- n h)))))) @@ -1054,28 +1060,30 @@ (format "[%d/%d]" n m) (format "[%d%%]"(floor (+ 0.5 (* 100. (/ (* 1.0 n) m))))))) + (defun org-columns-string-to-number (s fmt) "Convert a column value to a number that can be used for column computing." (if s (cond ((memq fmt '(min_age max_age mean_age)) - (cond ((string= s "") org-columns-time) - ((string-match - "\\([0-9]+\\)d \\([0-9]+\\)h \\([0-9]+\\)m \\([0-9]+\\)s" - s) - (+ (* 60 (+ (* 60 (+ (* 24 (string-to-number (match-string 1 s))) - (string-to-number (match-string 2 s)))) - (string-to-number (match-string 3 s)))) - (string-to-number (match-string 4 s)))) - (t (time-to-number-of-days (apply 'encode-time - (org-parse-time-string s t)))))) + (cond ((string= s "") org-columns-time) + ((string-match + "\\([0-9]+\\)d \\([0-9]+\\)h \\([0-9]+\\)m \\([0-9]+\\)s" + s) + (+ (* 60 (+ (* 60 (+ (* 24 (string-to-number (match-string 1 s))) + (string-to-number (match-string 2 s)))) + (string-to-number (match-string 3 s)))) + (string-to-number (match-string 4 s)))) + (t (time-to-number-of-days (apply 'encode-time + (org-parse-time-string s t)))))) ((string-match ":" s) - (let ((l (nreverse (org-split-string s ":"))) (sum 0.0)) - (while l - (setq sum (+ (string-to-number (pop l)) (/ sum 60)))) - sum)) + (let ((l (nreverse (org-split-string s ":"))) (sum 0.0)) + (while l + (setq sum (+ (string-to-number (pop l)) (/ sum 60)))) + sum)) ((memq fmt '(checkbox checkbox-n-of-m checkbox-percent)) - (if (equal s "[X]") 1. 0.000001)) + (if (equal s "[X]") 1. 0.000001)) + ((memq fmt '(estimate)) (org-string-to-estimate s)) (t (string-to-number s))))) (defun org-columns-uncompile-format (cfmt) @@ -1491,6 +1499,41 @@ (format "%dd %02dh %02dm %02ds" days hours minutes seconds)) "")) +(defun org-estimate-mean-and-var (v) + "Return the mean and variance of an estimate." + (let* ((low (float (car v))) + (high (float (cadr v))) + (mean (/ (+ low high) 2.0)) + (var (/ (+ (expt (- mean low) 2.0) (expt (- high mean) 2.0)) 2.0))) + (list mean var))) + +(defun org-estimate-combine (&rest el) + "Combine a list of estimates, using mean and variance. +The mean and variance of the result will be the sum of the means +and variances (respectively) of the individual estimates." + (let ((mean 0) + (var 0)) + (mapc (lambda (e) + (let ((stats (org-estimate-mean-and-var e))) + (setq mean (+ mean (car stats))) + (setq var (+ var (cadr stats))))) + el) + (let ((stdev (sqrt var))) + (list (- mean stdev) (+ mean stdev))))) + +(defun org-estimate-print (e &optional fmt) + "Prepare a string representation of an estimate. +This formats these numbers as two numbers with a \"-\" between them." + (if (null fmt) (set 'fmt "%.0f")) + (format "%s" (mapconcat (lambda (n) (format fmt n)) e "-"))) + +(defun org-string-to-estimate (s) + "Convert a string to an estimate. +The string should be two numbers joined with a \"-\"." + (if (string-match "\\(.*\\)-\\(.*\\)" s) + (list (string-to-number (match-string 1 s)) + (string-to-number(match-string 2 s))) + (list (string-to-number s) (string-to-number s)))) (provide 'org-colview) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-compat.el --- a/lisp/org/org-compat.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-compat.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -162,6 +162,15 @@ (let ((x (org-get-x-clipboard-compat value))) (if x (org-no-properties x))))) +(defsubst org-decompose-region (beg end) + "Decompose from BEG to END." + (if (featurep 'xemacs) + (let ((modified-p (buffer-modified-p)) + (buffer-read-only nil)) + (remove-text-properties beg end '(composition nil)) + (set-buffer-modified-p modified-p)) + (decompose-region beg end))) + ;; Miscellaneous functions (defun org-add-hook (hook function &optional append local) @@ -197,6 +206,26 @@ (shrink-window-if-larger-than-buffer window))) (or window (selected-window))) +(defun org-number-sequence (from &optional to inc) + "Call `number-sequence or emulate it." + (if (fboundp 'number-sequence) + (number-sequence from to inc) + (if (or (not to) (= from to)) + (list from) + (or inc (setq inc 1)) + (when (zerop inc) (error "The increment can not be zero")) + (let (seq (n 0) (next from)) + (if (> inc 0) + (while (<= next to) + (setq seq (cons next seq) + n (1+ n) + next (+ from (* n inc)))) + (while (>= next to) + (setq seq (cons next seq) + n (1+ n) + next (+ from (* n inc))))) + (nreverse seq))))) + ;; Region compatibility (defvar org-ignore-region nil @@ -353,7 +382,7 @@ (if (fboundp 'looking-at-p) (apply 'looking-at-p args) (save-match-data - (apply 'looking-at-p args)))) + (apply 'looking-at args)))) ; XEmacs does not have `looking-back'. (if (fboundp 'looking-back) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-crypt.el --- a/lisp/org/org-crypt.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-crypt.el Thu Nov 11 22:10:19 2010 -0600 @@ -4,7 +4,7 @@ ;; Emacs Lisp Archive Entry ;; Filename: org-crypt.el -;; Version: 7.01 +;; Version: 7.3 ;; Keywords: org-mode ;; Author: John Wiegley ;; Maintainer: Peter Jones diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-ctags.el --- a/lisp/org/org-ctags.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-ctags.el Thu Nov 11 22:10:19 2010 -0600 @@ -3,10 +3,10 @@ ;; Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. ;; Author: Paul Sexton -;; Version: 7.01 +;; Version: 7.3 ;; Keywords: org, wp -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-datetree.el --- a/lisp/org/org-datetree.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-datetree.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-docbook.el --- a/lisp/org/org-docbook.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-docbook.el Thu Nov 11 22:10:19 2010 -0600 @@ -4,7 +4,7 @@ ;; ;; Emacs Lisp Archive Entry ;; Filename: org-docbook.el -;; Version: 7.01 +;; Version: 7.3 ;; Author: Baoqiu Cui ;; Maintainer: Baoqiu Cui ;; Keywords: org, wp, docbook @@ -552,9 +552,9 @@ (nth 2 (assoc "=" org-export-docbook-emphasis-alist))) table-open type table-buffer table-orig-buffer - ind item-type starter didclose + ind item-type starter rpl path attr caption label desc descp desc1 desc2 link - fnc item-tag initial-number + fnc item-tag item-number footref-seen footnote-list id-file ) @@ -671,7 +671,21 @@ (org-export-docbook-open-para)) (throw 'nextline nil)) - (org-export-docbook-close-lists-maybe line) + ;; List ender: close every open list. + (when (equal "ORG-LIST-END" line) + (while local-list-type + (let ((listtype (car local-list-type))) + (org-export-docbook-close-li listtype) + (insert (cond + ((equal listtype "o") "\n") + ((equal listtype "u") "\n") + ((equal listtype "d") "\n")))) + (pop local-list-type)) + ;; We did close a list, normal text follows: need + (org-export-docbook-open-para) + (setq local-list-indent nil + in-local-list nil) + (throw 'nextline nil)) ;; Protected HTML (when (get-text-property 0 'org-protected line) @@ -963,18 +977,6 @@ txt (match-string 2 line)) (if (string-match quote-re0 txt) (setq txt (replace-match "" t t txt))) - (when in-local-list - ;; Close any local lists before inserting a new header line - (while local-list-type - (let ((listtype (car local-list-type))) - (org-export-docbook-close-li listtype) - (insert (cond - ((equal listtype "o") "\n") - ((equal listtype "u") "\n") - ((equal listtype "d") "\n")))) - (pop local-list-type)) - (setq local-list-indent nil - in-local-list nil)) (org-export-docbook-level-start level txt) ;; QUOTES (when (string-match quote-re line) @@ -1003,7 +1005,9 @@ table-orig-buffer (nreverse table-orig-buffer)) (org-export-docbook-close-para-maybe) (insert (org-export-docbook-finalize-table - (org-format-table-html table-buffer table-orig-buffer))))) + (org-format-table-html table-buffer table-orig-buffer + 'no-css))))) + (t ;; Normal lines (when (string-match @@ -1020,34 +1024,14 @@ (substring (match-string 2 line) 0 -1)) line (substring line (match-beginning 5)) item-tag nil - initial-number nil) - (if (string-match "\\`\\[@start:\\([0-9]+\\)\\][ \t]?" line) - (setq initial-number (match-string 1 line) + item-number nil) + (if (string-match "\\[@\\(?:start:\\)?\\([0-9]+\\)\\][ \t]?" line) + (setq item-number (match-string 1 line) line (replace-match "" t t line))) (if (and starter (string-match "\\(.*?\\) ::[ \t]*" line)) (setq item-type "d" item-tag (match-string 1 line) line (substring line (match-end 0)))) - (when (and (not (equal item-type "d")) - (not (string-match "[^ \t]" line))) - ;; Empty line. Pretend indentation is large. - (setq ind (if org-empty-line-terminates-plain-lists - 0 - (1+ (or (car local-list-indent) 1))))) - (setq didclose nil) - (while (and in-local-list - (or (and (= ind (car local-list-indent)) - (not starter)) - (< ind (car local-list-indent)))) - (setq didclose t) - (let ((listtype (car local-list-type))) - (org-export-docbook-close-li listtype) - (insert (cond - ((equal listtype "o") "\n") - ((equal listtype "u") "\n") - ((equal listtype "d") "\n")))) - (pop local-list-type) (pop local-list-indent) - (setq in-local-list local-list-indent)) (cond ((and starter (or (not in-local-list) @@ -1056,7 +1040,7 @@ (org-export-docbook-close-para-maybe) (insert (cond ((equal item-type "u") "\n\n") - ((equal item-type "o") + ((and (equal item-type "o") item-number) ;; Check for a specific start number. If it ;; is specified, we use the ``override'' ;; attribute of element to pass the @@ -1064,10 +1048,8 @@ ;; ``startingnumber'' attribute of element ;; , but the former works on both ;; DocBook 5.0 and prior versions. - (if initial-number - (format "\n\n" - initial-number) - "\n\n")) + (format "\n\n" item-number)) + ((equal item-type "o") "\n\n") ((equal item-type "d") (format "\n%s\n" item-tag)))) ;; For DocBook, we need to open a para right after tag @@ -1076,11 +1058,27 @@ (push item-type local-list-type) (push ind local-list-indent) (setq in-local-list t)) + ;; Continue current list (starter - ;; Continue current list + ;; terminate any previous sublist but first ensure + ;; list is not ill-formed + (let ((min-ind (apply 'min local-list-indent))) + (when (< ind min-ind) (setq ind min-ind))) + (while (< ind (car local-list-indent)) + (let ((listtype (car local-list-type))) + (org-export-docbook-close-li listtype) + (insert (cond + ((equal listtype "o") "\n") + ((equal listtype "u") "\n") + ((equal listtype "d") "\n")))) + (pop local-list-type) (pop local-list-indent) + (setq in-local-list local-list-indent)) + ;; insert new item (let ((listtype (car local-list-type))) (org-export-docbook-close-li listtype) (insert (cond + ((and (equal listtype "o") item-number) + (format "" item-number)) ((equal listtype "o") "") ((equal listtype "u") "") ((equal listtype "d") (format @@ -1089,9 +1087,6 @@ "???")))))) ;; For DocBook, we need to open a para right after tag ;; . - (org-export-docbook-open-para)) - (didclose - ;; We did close a list, normal text follows: need (org-export-docbook-open-para))) ;; Checkboxes. (if (string-match "^[ \t]*\\(\\[[X -]\\]\\)" line) @@ -1134,18 +1129,7 @@ (when inquote (insert "]]>\n") (org-export-docbook-open-para)) - (when in-local-list - ;; Close any local lists before inserting a new header line - (while local-list-type - (let ((listtype (car local-list-type))) - (org-export-docbook-close-li listtype) - (insert (cond - ((equal listtype "o") "\n") - ((equal listtype "u") "\n") - ((equal listtype "d") "\n")))) - (pop local-list-type)) - (setq local-list-indent nil - in-local-list nil)) + ;; Close all open sections. (org-export-docbook-level-start 1 nil) @@ -1212,24 +1196,6 @@ (defvar in-local-list) (defvar local-list-indent) (defvar local-list-type) -(defun org-export-docbook-close-lists-maybe (line) - (let ((ind (or (get-text-property 0 'original-indentation line))) -; (and (string-match "\\S-" line) -; (org-get-indentation line)))) - didclose) - (when ind - (while (and in-local-list - (<= ind (car local-list-indent))) - (setq didclose t) - (let ((listtype (car local-list-type))) - (org-export-docbook-close-li listtype) - (insert (cond - ((equal listtype "o") "\n") - ((equal listtype "u") "\n") - ((equal listtype "d") "\n")))) - (pop local-list-type) (pop local-list-indent) - (setq in-local-list local-list-indent)) - (and didclose (org-export-docbook-open-para))))) (defun org-export-docbook-level-start (level title) "Insert a new level in DocBook export. @@ -1249,7 +1215,7 @@ ;; all levels, so the rest is done only if title is given. ;; ;; Format tags: put them into a superscript like format. - (when (string-match (org-re "\\(:[[:alnum:]_@:]+:\\)[ \t]*$") title) + (when (string-match (org-re "\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") title) (setq title (replace-match (if org-export-with-tags @@ -1273,7 +1239,7 @@ Applies all active conversions. If there are links in the string, don't modify these." (let* ((re (concat org-bracket-link-regexp "\\|" - (org-re "[ \t]+\\(:[[:alnum:]_@:]+:\\)[ \t]*$"))) + (org-re "[ \t]+\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$"))) m s l res) (while (setq m (string-match re string)) (setq s (substring string 0 m) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-docview.el --- a/lisp/org/org-docview.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-docview.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Jan Böcker ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -45,7 +45,10 @@ (require 'org) -(eval-when-compile (require 'doc-view)) ; doc-view-current-page macro + +(declare-function doc-view-goto-page "ext:doc-view" (page)) +(declare-function image-mode-window-get "ext:image-mode" + (prop &optional winprops)) (autoload 'doc-view-goto-page "doc-view") @@ -66,7 +69,7 @@ (when (eq major-mode 'doc-view-mode) ;; This buffer is in doc-view-mode (let* ((path buffer-file-name) - (page (doc-view-current-page)) + (page (image-mode-window-get 'page)) (link (concat "docview:" path "::" (number-to-string page))) (description "")) (org-store-link-props diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-entities.el --- a/lisp/org/org-entities.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-entities.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Ulf Stegemann ;; Keywords: outlines, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-exp-blocks.el --- a/lisp/org/org-exp-blocks.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-exp-blocks.el Thu Nov 11 22:10:19 2010 -0600 @@ -4,7 +4,7 @@ ;; Free Software Foundation, Inc. ;; Author: Eric Schulte -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. ;; @@ -201,7 +201,8 @@ (interblock start (point-max)) (run-hooks 'org-export-blocks-postblock-hook))))) -(add-hook 'org-export-preprocess-hook 'org-export-blocks-preprocess) +(add-hook 'org-export-preprocess-after-include-files-hook + 'org-export-blocks-preprocess) ;;================================================================================ ;; type specific functions diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-exp.el --- a/lisp/org/org-exp.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-exp.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -181,7 +181,7 @@ ("no" "Forfatter" "Dato" "Innhold" "Fotnoter") ("nb" "Forfatter" "Dato" "Innhold" "Fotnoter") ;; nb = Norsk (bokm.l) ("nn" "Forfattar" "Dato" "Innhald" "Fotnotar") ;; nn = Norsk (nynorsk) - ("pl" "Autor" "Data" "Spis treści" "Przypis") + ("pl" "Autor" "Data" "Spis treści" "Przypis") ("sv" "Författare" "Datum" "Innehåll" "Fotnoter")) "Terms used in export text, translated to different languages. Use the variable `org-export-default-language' to set the language, @@ -417,6 +417,10 @@ This is run after blockquote/quote/verse/center have been marked with cookies.") +(defvar org-export-preprocess-after-radio-targets-hook nil + "Hook for preprocessing an export buffer. +This is run after radio target processing.") + (defvar org-export-preprocess-before-normalizing-links-hook nil "Hook for preprocessing an export buffer. This hook is run before links are normalized.") @@ -467,20 +471,34 @@ :group 'org-export-latex :type 'boolean) -(defcustom org-export-with-LaTeX-fragments nil - "Non-nil means convert LaTeX fragments to images when exporting to HTML. -When set, the exporter will find LaTeX environments if the \\begin line is -the first non-white thing on a line. It will also find the math delimiters -like $a=b$ and \\( a=b \\) for inline math, $$a=b$$ and \\[ a=b \\] for -display math. +(defcustom org-export-with-LaTeX-fragments t + "Non-nil means process LaTeX math fragments for HTML display. +When set, the exporter will find and process LaTeX environments if the +\\begin line is the first non-white thing on a line. It will also find +and process the math delimiters like $a=b$ and \\( a=b \\) for inline math, +$$a=b$$ and \\[ a=b \\] for display math. + +This option can also be set with the +OPTIONS line, e.g. \"LaTeX:mathjax\". -This option can also be set with the +OPTIONS line, e.g. \"LaTeX:t\". +Allowed values are: + +nil Don't do anything. +verbatim Keep eveything in verbatim +dvipng Process the LaTeX fragments to images. + This will also include processing of non-math environments. +t Do MathJax preprocessing if there is at least on math snippet, + and arrange for MathJax.js to be loaded. The default is nil, because this option needs the `dvipng' program which is not available on all systems." :group 'org-export-translation :group 'org-export-latex - :type 'boolean) + :type '(choice + (const :tag "Do not process math in any way" nil) + (const :tag "Obsolete, use dvipng setting" t) + (const :tag "Use dvipng to make images" dvipng) + (const :tag "Use MathJax to display math" mathjax) + (const :tag "Leave math verbatim" verbatim))) (defcustom org-export-with-fixed-width t "Non-nil means lines starting with \":\" will be in fixed width font. @@ -671,12 +689,14 @@ (let ((re (org-make-options-regexp (append '("TITLE" "AUTHOR" "DATE" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE" + "MATHJAX" "LINK_UP" "LINK_HOME" "SETUPFILE" "STYLE" "LATEX_HEADER" "LATEX_CLASS" "EXPORT_SELECT_TAGS" "EXPORT_EXCLUDE_TAGS" "KEYWORDS" "DESCRIPTION" "MACRO" "BIND" "XSLT") (mapcar 'car org-export-inbuffer-options-extra)))) - p key val text options a pr style + (case-fold-search t) + p key val text options mathjax a pr style latex-header latex-class macros letbind ext-setup-or-nil setup-contents (start 0)) (while (or (and ext-setup-or-nil @@ -708,6 +728,8 @@ (setq text (if text (concat text "\n" val) val))) ((string-equal key "OPTIONS") (setq options (concat val " " options))) + ((string-equal key "MATHJAX") + (setq mathjax (concat val " " mathjax))) ((string-equal key "BIND") (push (read (concat "(" val ")")) letbind)) ((string-equal key "XSLT") @@ -744,9 +766,12 @@ (setq p (plist-put p :latex-class latex-class))) (when options (setq p (org-export-add-options-to-plist p options))) + (when mathjax + (setq p (plist-put p :mathjax mathjax))) ;; Add macro definitions (setq p (plist-put p :macro-date "(eval (format-time-string \"$1\"))")) (setq p (plist-put p :macro-time "(eval (format-time-string \"$1\"))")) + (setq p (plist-put p :macro-property "(eval (org-entry-get nil \"$1\" 'selective))")) (setq p (plist-put p :macro-modification-time (and (buffer-file-name) @@ -1052,6 +1077,9 @@ (plist-get parameters :exclude-tags)) (run-hooks 'org-export-preprocess-after-tree-selection-hook) + ;; Mark end of lists + (org-export-mark-list-ending backend) + ;; Handle source code snippets (org-export-replace-src-segments-and-examples backend) @@ -1120,6 +1148,7 @@ ;; Find matches for radio targets and turn them into internal links (org-export-mark-radio-links) + (run-hooks 'org-export-preprocess-after-radio-targets-hook) ;; Find all links that contain a newline and put them into a single line (org-export-concatenate-multiline-links) @@ -1138,7 +1167,8 @@ (when (plist-get parameters :emph-multiline) (org-export-concatenate-multiline-emphasis)) - ;; Remove special table lines + ;; Remove special table lines, and store alignment information + (org-store-forced-table-alignment) (when org-export-table-remove-special-lines (org-export-remove-special-table-lines)) @@ -1185,6 +1215,10 @@ p (or (next-single-property-change p :org-license-to-kill) (point-max)))))) +(defvar org-export-define-heading-targets-headline-hook nil + "Hook that is run when a headline was matched during target search. +This is part of the preprocessing for export.") + (defun org-export-define-heading-targets (target-alist) "Find all headings and define the targets for them. The new targets are added to TARGET-ALIST, which is also returned. @@ -1228,7 +1262,8 @@ (push (cons target target) target-alist) (add-text-properties (point-at-bol) (point-at-eol) - (list 'target target)))))) + (list 'target target)) + (run-hooks 'org-export-define-heading-targets-headline-hook))))) target-alist) (defun org-export-handle-invisible-targets (target-alist) @@ -1289,18 +1324,19 @@ (string-match "^\\." link)) nil) (t - (save-excursion - (setq found (condition-case nil (org-link-search link) - (error nil))) - (when (and found - (or (org-on-heading-p) - (not (eq found 'dedicated)))) - (or (get-text-property (point) 'target) - (get-text-property - (max (point-min) - (1- (or (previous-single-property-change - (point) 'target) 0))) - 'target)))))))) + (let ((org-link-search-inhibit-query t)) + (save-excursion + (setq found (condition-case nil (org-link-search link) + (error nil))) + (when (and found + (or (org-on-heading-p) + (not (eq found 'dedicated)))) + (or (get-text-property (point) 'target) + (get-text-property + (max (point-min) + (1- (or (previous-single-property-change + (point) 'target) 0))) + 'target))))))))) (when target (set-match-data md) (goto-char (match-beginning 1)) @@ -1316,7 +1352,7 @@ (goto-char (point-min)) (let (class) (while (re-search-forward - "^[ \t]*:HTML_CONTAINER_CLASS:[ \t]+\\(\\S-+\\)" nil t) + "^[ \t]*:HTML_CONTAINER_CLASS:[ \t]+\\(.+\\)$" nil t) (setq class (match-string 1)) (save-excursion (org-back-to-heading t) @@ -1446,7 +1482,7 @@ (goto-char (point-min)) (while (re-search-forward re-archive nil t) (if (not (org-on-heading-p t)) - (org-end-of-subtree t) + (goto-char (point-at-eol)) (beginning-of-line 1) (setq a (if export-archived-trees (1+ (point-at-eol)) (point)) @@ -1595,6 +1631,31 @@ (delete-region beg end) (insert (org-add-props content nil 'original-indentation ind)))))) +(defun org-export-mark-list-ending (backend) + "Mark list endings with special cookies. +These special cookies will later be interpreted by the backend. +`org-list-end-re' is replaced by a blank line in the process." + (let ((process-buffer + (lambda (end-list-marker) + (goto-char (point-min)) + (while (org-search-forward-unenclosed org-item-beginning-re nil t) + (goto-char (org-list-bottom-point)) + (when (and (not (eq org-list-ending-method 'indent)) + (looking-at (org-list-end-re))) + (replace-match "\n")) + (insert end-list-marker))))) + ;; We need to divide backends into 3 categories. + (cond + ;; 1. Backends using `org-list-parse-list' do not need markers. + ((memq backend '(latex)) + nil) + ;; 2. Line-processing backends need to be told where lists end. + ((memq backend '(html docbook)) + (funcall process-buffer "ORG-LIST-END\n")) + ;; 3. Others backends do not need to know this: clean list enders. + (t + (funcall process-buffer ""))))) + (defun org-export-attach-captions-and-attributes (backend target-alist) "Move #+CAPTION, #+ATTR_BACKEND, and #+LABEL text into text properties. If the next thing following is a table, add the text properties to the first @@ -1691,7 +1752,7 @@ (while (or (looking-at re) (re-search-forward re nil t)) (setq pos (match-beginning 0)) - (if (get-text-property (point) 'org-protected) + (if (get-text-property (match-beginning 1) 'org-protected) (goto-char (1+ pos)) (goto-char (1+ pos)) (replace-match "") @@ -1712,8 +1773,30 @@ (org-if-unprotected (replace-match "\\1[[\\2]]"))))))) +(defun org-store-forced-table-alignment () + "Find table lines which force alignment, store the results in properties." + (let (line cnt aligns) + (goto-char (point-min)) + (while (re-search-forward "|[ \t]*<[lrc][0-9]*>[ \t]*|" nil t) + ;; OK, this looks like a table line with an alignment cookie + (org-if-unprotected + (setq line (buffer-substring (point-at-bol) (point-at-eol))) + (when (and (org-at-table-p) + (org-table-cookie-line-p line)) + (setq cnt 0 aligns nil) + (mapc + (lambda (x) + (setq cnt (1+ cnt)) + (if (string-match "\\`<\\([lrc]\\)" x) + (push (cons cnt (downcase (match-string 1 x))) aligns))) + (org-split-string line "[ \t]*|[ \t]*")) + (add-text-properties (org-table-begin) (org-table-end) + (list 'org-forced-aligns aligns)))) + (goto-char (point-at-eol))))) + (defun org-export-remove-special-table-lines () - "Remove tables lines that are used for internal purposes." + "Remove tables lines that are used for internal purposes. +Also, store forcedalignment information found in such lines." (goto-char (point-min)) (while (re-search-forward "^[ \t]*|" nil t) (org-if-unprotected-at (1- (point)) @@ -1726,7 +1809,7 @@ (lambda (f) (or (= (length f) 0) (string-match - "\\`<\\([0-9]\\|[rl]\\|[rl][0-9]+\\)>\\'" f))) + "\\`<\\([0-9]\\|[lrc]\\|[lrc][0-9]+\\)>\\'" f))) (org-split-string ;; FIXME, can't we do without splitting??? (buffer-substring (point-at-bol) (point-at-eol)) "[ \t]*|[ \t]*"))))) @@ -1747,16 +1830,19 @@ nodesc) (goto-char (point-min)) (while (re-search-forward re-plain-link nil t) - (goto-char (1- (match-end 0))) - (org-if-unprotected-at (1+ (match-beginning 0)) - (let* ((s (concat (match-string 1) - "[[" (match-string 2) ":" (match-string 3) - "][" (match-string 2) ":" (org-export-protect-sub-super - (match-string 3)) - "]]"))) - ;; added 'org-link face to links - (put-text-property 0 (length s) 'face 'org-link s) - (replace-match s t t)))) + (unless (org-string-match-p + "\\[\\[\\S+:\\S-*?\\<" + (buffer-substring (point-at-bol) (match-beginning 0))) + (goto-char (1- (match-end 0))) + (org-if-unprotected-at (1+ (match-beginning 0)) + (let* ((s (concat (match-string 1) + "[[" (match-string 2) ":" (match-string 3) + "][" (match-string 2) ":" (org-export-protect-sub-super + (match-string 3)) + "]]"))) + ;; added 'org-link face to links + (put-text-property 0 (length s) 'face 'org-link s) + (replace-match s t t))))) (goto-char (point-min)) (while (re-search-forward re-angle-link nil t) (goto-char (1- (match-end 0))) @@ -1807,7 +1893,9 @@ (if (and (not (= (char-after (match-beginning 3)) (char-after (match-beginning 4)))) (save-excursion (goto-char (match-beginning 0)) - (save-match-data (not (org-at-table-p))))) + (save-match-data + (and (not (org-at-table-p)) + (not (org-at-heading-p)))))) (org-if-unprotected (subst-char-in-region (match-beginning 0) (match-end 0) ?\n ?\ t) @@ -1976,16 +2064,15 @@ (intern (concat ":" key))))) (save-match-data (when args - (setq args (org-split-string args ",[ \t\n]*") args2 nil) - (setq args (mapcar 'org-trim args)) + (setq args (org-split-string args ",") args2 nil) (while args (while (string-match "\\\\\\'" (car args)) ;; repair bad splits (setcar (cdr args) (concat (substring (car args) 0 -1) - ";" (nth 1 args))) + "," (nth 1 args))) (pop args)) (push (pop args) args2)) - (setq args (nreverse args2)) + (setq args (mapcar 'org-trim (nreverse args2))) (setq s 0) (while (string-match "\\$\\([0-9]+\\)" val s) (setq s (1+ (match-beginning 0)) @@ -2146,6 +2233,9 @@ (defvar org-export-latex-verbatim-wrap) ;; defined in org-latex.el (defvar org-export-latex-listings) ;; defined in org-latex.el (defvar org-export-latex-listings-langs) ;; defined in org-latex.el +(defvar org-export-latex-listings-w-names) ;; defined in org-latex.el +(defvar org-export-latex-minted-langs) ;; defined in org-latex.el +(defvar org-export-latex-minted-with-line-numbers) ;; defined in org-latex.el (defun org-export-format-source-code-or-example (backend lang code &optional opts indent caption) @@ -2275,32 +2365,56 @@ (setq rtn (org-export-number-lines rtn 'latex 0 0 num cont rpllbl fmt)) (concat "#+BEGIN_LaTeX\n" (org-add-props - (if org-export-latex-listings - (concat - (if lang - (let* - ((lang-sym (intern lang)) - (lstlang - (or (cadr - (assq - lang-sym - org-export-latex-listings-langs)) - lang))) - (format "\\lstset{language=%s}\n" lstlang)) - "\n") - (when caption - (format "\n%s $\\equiv$ \n" caption)) - "\\begin{lstlisting}\n" - rtn "\\end{lstlisting}\n") - (concat (car org-export-latex-verbatim-wrap) - rtn (cdr org-export-latex-verbatim-wrap))) - '(org-protected t org-example t)) - "#+END_LaTeX\n")) - ((eq backend 'ascii) - ;; This is not HTML or LaTeX, so just make it an example. - (setq rtn (org-export-number-lines rtn 'ascii 0 0 num cont rpllbl fmt)) - (concat caption "\n" - "#+BEGIN_ASCII\n" + (cond + ((and org-export-latex-listings + (not (eq org-export-latex-listings 'minted))) + (concat + (if lang + (let* + ((lang-sym (intern lang)) + (lstlang + (or (cadr + (assq + lang-sym + org-export-latex-listings-langs)) + lang))) + (format "\\lstset{language=%s}\n" lstlang)) + "\n") + (when (and caption + org-export-latex-listings-w-names) + (format "\n%s $\\equiv$ \n" + (replace-regexp-in-string + "_" "\\\\_" caption))) + "\\begin{lstlisting}\n" + rtn "\\end{lstlisting}\n")) + ((eq org-export-latex-listings 'minted) + (if lang + (let* + ((lang-sym (intern lang)) + (minted-lang + (or (cadr + (assq + lang-sym + org-export-latex-minted-langs)) + (downcase lang)))) + (concat + (when (and caption + org-export-latex-listings-w-names) + (format "\n%s $\\equiv$ \n" + (replace-regexp-in-string + "_" "\\\\_" caption))) + (format + "\\begin{minted}[mathescape,%s\nnumbersep=5pt,\nframe=lines,\nframesep=2mm]{%s}\n" (if org-export-latex-minted-with-line-numbers "\nlinenos," "") minted-lang) + rtn "\\end{minted}\n")))) + (t (concat (car org-export-latex-verbatim-wrap) + rtn (cdr org-export-latex-verbatim-wrap)))) + '(org-protected t org-example t)) + "#+END_LaTeX\n")) + ((eq backend 'ascii) + ;; This is not HTML or LaTeX, so just make it an example. + (setq rtn (org-export-number-lines rtn 'ascii 0 0 num cont rpllbl fmt)) + (concat caption "\n" + "#+BEGIN_ASCII\n" (org-add-props (concat (mapconcat @@ -2498,6 +2612,28 @@ (defvar org-export-htmlized-org-css-url) ;; defined in org-html.el +(defun org-export-string (string fmt &optional dir) + "Export STRING to FMT using existing export facilities. +During export STRING is saved to a temporary file whose location +could vary. Optional argument DIR can be used to force the +directory in which the temporary file is created during export +which can be useful for resolving relative paths. Dir defaults +to the value of `temporary-file-directory'." + (let ((temporary-file-directory (or dir temporary-file-directory)) + (tmp-file (make-temp-file "org-"))) + (unwind-protect + (with-temp-buffer + (insert string) + (write-file tmp-file) + (org-load-modules-maybe) + (unless org-local-vars + (setq org-local-vars (org-get-local-variables))) + (eval ;; convert to fmt -- mimicing `org-run-like-in-org-mode' + (list 'let org-local-vars + (list (intern (concat "org-export-as-" fmt)) + nil nil nil ''string t)))) + (delete-file tmp-file)))) + ;;;###autoload (defun org-export-as-org (arg &optional hidden ext-plist to-buffer body-only pub-dir) @@ -2760,7 +2896,7 @@ (defun org-export-cleanup-toc-line (s) "Remove tags and timestamps from lines going into the toc." (when (memq org-export-with-tags '(not-in-toc nil)) - (if (string-match (org-re " +:[[:alnum:]_@:]+: *$") s) + (if (string-match (org-re " +:[[:alnum:]_@#%:]+: *$") s) (setq s (replace-match "" t t s)))) (when org-export-remove-timestamps-from-toc (while (string-match org-maybe-keyword-time-regexp s) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-faces.el --- a/lisp/org/org-faces.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-faces.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-feed.el --- a/lisp/org/org-feed.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-feed.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -99,11 +99,11 @@ (declare-function xml-get-children "xml" (node child-name)) (declare-function xml-get-attribute "xml" (node attribute)) (declare-function xml-get-attribute-or-nil "xml" (node attribute)) -(defvar xml-entity-alist) +(declare-function xml-substitute-special "xml" (string)) (defgroup org-feed nil "Options concerning RSS feeds as inputs for Org files." - :tag "Org ID" + :tag "Org Feed" :group 'org) (defcustom org-feed-alist nil @@ -269,17 +269,6 @@ (defvar org-feed-buffer "*Org feed*" "The buffer used to retrieve a feed.") -(defun org-feed-unescape (s) - "Unescape protected entities in S." - (require 'xml) - (let ((re (concat "&\\(" - (mapconcat 'car xml-entity-alist "\\|") - "\\);"))) - (while (string-match re s) - (setq s (replace-match - (cdr (assoc (match-string 1 s) xml-entity-alist)) nil nil s))) - s)) - ;;;###autoload (defun org-feed-update-all () "Get inbox items from all feeds in `org-feed-alist'." @@ -553,7 +542,8 @@ (setq tmp (org-feed-make-indented-block tmp (org-get-indentation)))))) (replace-match tmp t t)))) - (buffer-string))))) + (decode-coding-string + (buffer-string) (detect-coding-region (point-min) (point-max) t)))))) (defun org-feed-make-indented-block (s n) "Add indentation of N spaces to a multiline string S." @@ -613,6 +603,7 @@ (defun org-feed-parse-rss-entry (entry) "Parse the `:item-full-text' field for xml tags and create new properties." + (require 'xml) (with-temp-buffer (insert (plist-get entry :item-full-text)) (goto-char (point-min)) @@ -620,7 +611,7 @@ nil t) (setq entry (plist-put entry (intern (concat ":" (match-string 1))) - (org-feed-unescape (match-string 2))))) + (xml-substitute-special (match-string 2))))) (goto-char (point-min)) (unless (re-search-forward "isPermaLink[ \t]*=[ \t]*\"false\"" nil t) (setq entry (plist-put entry :guid-permalink t)))) @@ -654,7 +645,7 @@ 'href))) ;; Add as :title. (setq entry (plist-put entry :title - (org-feed-unescape + (xml-substitute-special (car (xml-node-children (car (xml-get-children xml 'title))))))) (let* ((content (car (xml-get-children xml 'content))) @@ -664,12 +655,12 @@ ((string= type "text") ;; We like plain text. (setq entry (plist-put entry :description - (org-feed-unescape + (xml-substitute-special (car (xml-node-children content)))))) ((string= type "html") ;; TODO: convert HTML to Org markup. (setq entry (plist-put entry :description - (org-feed-unescape + (xml-substitute-special (car (xml-node-children content)))))) ((string= type "xhtml") ;; TODO: convert XHTML to Org markup. diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-footnote.el --- a/lisp/org/org-footnote.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-footnote.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -49,6 +49,7 @@ (declare-function org-in-verbatim-emphasis "org" ()) (declare-function org-inside-latex-macro-p "org" ()) (defvar org-odd-levels-only) ;; defined in org.el +(defvar message-signature-separator) ;; defined in message.el (defconst org-footnote-re (concat "[^][\n]" ; to make sure it is not at the beginning of a line @@ -188,7 +189,7 @@ (message "Edit definition and go back with `C-c &' or, if unique, with `C-c C-c'.")))) (defun org-footnote-goto-previous-reference (label) - "Find the next previous of the footnote with label LABEL." + "Find the first closest (to point) reference of footnote with label LABEL." (interactive "sLabel: ") (org-mark-ring-push) (setq label (org-footnote-normalize-label label)) @@ -302,15 +303,19 @@ (t (setq re (concat "^" org-footnote-tag-for-non-org-mode-files "[ \t]*$")) (unless (re-search-forward re nil t) - (goto-char (point-max)) - (skip-chars-backward " \t\r\n") - (insert "\n\n") - (delete-region (point) (point-max)) - (insert org-footnote-tag-for-non-org-mode-files "\n")) - (goto-char (point-max)) - (skip-chars-backward " \t\r\n"))) - (insert "\n\n") - (insert "[" label "] ") + (let ((max (if (and (eq major-mode 'message-mode) + (re-search-forward message-signature-separator nil t)) + (progn (beginning-of-line) (point)) + (goto-char (point-max))))) + (skip-chars-backward " \t\r\n") + (delete-region (point) max) + (insert "\n\n") + (insert org-footnote-tag-for-non-org-mode-files "\n"))))) + ;; Skip existing footnotes + (while (re-search-forward "^[[:space:]]*\\[[^]]+\\] " nil t) + (forward-line)) + (insert "[" label "] \n") + (goto-char (1- (point))) (message "Edit definition and go back with `C-c &' or, if unique, with `C-c C-c'."))) ;;;###autoload @@ -506,7 +511,8 @@ (beginning-of-line 0)) (if (looking-at "[ \t]*#\\+TBLFM:") (beginning-of-line 2)) (end-of-line 1) - (skip-chars-backward "\n\r\t ")) + (skip-chars-backward "\n\r\t ") + (forward-line)) (defun org-footnote-delete (&optional label) "Delete the footnote at point. diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-freemind.el --- a/lisp/org/org-freemind.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-freemind.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Lennart Borgman (lennart O borgman A gmail O com) ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 6.35i +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -81,31 +81,35 @@ (require 'xml) (require 'org) -(require 'rx) +;(require 'rx) (require 'org-exp) (eval-when-compile (require 'cl)) +(defgroup org-freemind nil + "Customization group for org-freemind export/import." + :group 'org) + ;; Fix-me: I am not sure these are useful: ;; ;; (defcustom org-freemind-main-fgcolor "black" ;; "Color of main node's text." ;; :type 'color -;; :group 'freemind) +;; :group 'org-freemind) ;; (defcustom org-freemind-main-color "black" ;; "Background color of main node." ;; :type 'color -;; :group 'freemind) +;; :group 'org-freemind) ;; (defcustom org-freemind-child-fgcolor "black" ;; "Color of child nodes' text." ;; :type 'color -;; :group 'freemind) +;; :group 'org-freemind) ;; (defcustom org-freemind-child-color "black" ;; "Background color of child nodes." ;; :type 'color -;; :group 'freemind) +;; :group 'org-freemind) (defvar org-freemind-node-style nil "Internal use.") @@ -152,11 +156,25 @@ (string :tag "Font name" :value "SansSerif")) (list :format "%v" (const :format "" font-size) (integer :tag "Font size" :value 12))))))) - :group 'freemind) + :group 'org-freemind) ;;;###autoload -(defun org-export-as-freemind (arg &optional hidden ext-plist +(defun org-export-as-freemind (&optional hidden ext-plist to-buffer body-only pub-dir) + "Export the current buffer as a Freemind file. +If there is an active region, export only the region. HIDDEN is +obsolete and does nothing. EXT-PLIST is a property list with +external parameters overriding org-mode's default settings, but +still inferior to file-local settings. When TO-BUFFER is +non-nil, create a buffer with that name and export to that +buffer. If TO-BUFFER is the symbol `string', don't leave any +buffer behind but just return the resulting HTML as a string. +When BODY-ONLY is set, don't produce the file header and footer, +simply return the content of the document (all top level +sections). When PUB-DIR is set, use this as the publishing +directory. + +See `org-freemind-from-org-mode' for more information." (interactive "P") (let* ((opt-plist (org-combine-plists (org-default-export-plist) ext-plist @@ -203,7 +221,20 @@ (let ((name (read-file-name "FreeMind file: " nil nil nil (if (buffer-file-name) - (file-name-nondirectory (buffer-file-name)) + (let* ((name-ext (file-name-nondirectory (buffer-file-name))) + (name (file-name-sans-extension name-ext)) + (ext (file-name-extension name-ext))) + (cond + ((string= "mm" ext) + name-ext) + ((string= "org" ext) + (let ((name-mm (concat name ".mm"))) + (if (file-exists-p name-mm) + name-mm + (message "Not exported to Freemind format yet") + ""))) + (t + ""))) "") ;; Fix-me: Is this an Emacs bug? ;; This predicate function is never @@ -227,7 +258,7 @@ (dolist (cc chars) (setq fm-str (concat fm-str - (if (< cc 256) + (if (< cc 160) (cond ((= cc ?\") """) ((= cc ?\&) "&") @@ -265,52 +296,84 @@ ))) org-str)))) -;; (org-freemind-test-escape) -(defun org-freemind-test-escape () - (let* ((str1 "a quote: \", an amp: &, lt: <; over 256: öåäÖÅÄ") - (str2 (org-freemind-escape-str-from-org str1)) - (str3 (org-freemind-unescape-str-to-org str2)) +;; (let* ((str1 "a quote: \", an amp: &, lt: <; over 256: öåäÖÅÄ") +;; (str2 (org-freemind-escape-str-from-org str1)) +;; (str3 (org-freemind-unescape-str-to-org str2))) +;; (unless (string= str1 str3) +;; (error "Error str3=%s" str3))) + +(defun org-freemind-convert-links-helper (matched) + "Helper for `org-freemind-convert-links-from-org'. +MATCHED is the link just matched." + (let* ((link (match-string 1 matched)) + (text (match-string 2 matched)) + (ext (file-name-extension link)) + (col-pos (string-match-p ":" link)) + (is-img (and (image-type-from-file-name link) + (let ((url-type (substring link 0 col-pos))) + (member url-type '("file" "http" "https"))))) ) - (unless (string= str1 str3) - (error "str3=%s" str3)) - )) + (if is-img + ;; Fix-me: I can't find a way to get the border to "shrink + ;; wrap" around the image using <div>. + ;; + ;; (concat "<div style=\"border: solid 1px #ddd; width:auto;\">" + ;; "<img src=\"" link "\" alt=\"" text "\" />" + ;; "<br />" + ;; "<i>" text "</i>" + ;; "</div>") + (concat "<table border=\"0\" style=\"border: solid 1px #ddd;\"><tr><td>" + "<img src=\"" link "\" alt=\"" text "\" />" + "<br />" + "<i>" text "</i>" + "</td></tr></table>") + (concat "<a href=\"" link "\">" text "</a>")))) (defun org-freemind-convert-links-from-org (org-str) "Convert org links in ORG-STR to freemind links and return the result." (let ((fm-str (replace-regexp-in-string - (rx (not (any "[\"")) - (submatch - "http" - (opt ?\s) - "://" - (1+ - (any "-%.?@a-zA-Z0-9()_/:~=&#")))) + ;;(rx (not (any "[\"")) + ;; (submatch + ;; "http" + ;; (opt ?\s) + ;; "://" + ;; (1+ + ;; (any "-%.?@a-zA-Z0-9()_/:~=&#")))) + "[^\"[]\\(http ?://[--:#%&()=?-Z_a-z~]+\\)" "[[\\1][\\1]]" - org-str))) - (replace-regexp-in-string (rx "[[" - (submatch (*? nonl)) - "][" - (submatch (*? nonl)) - "]]") - "<a href=\"\\1\">\\2</a>" - fm-str))) + org-str + nil ;; fixedcase + nil ;; literal + 1 ;; subexp + ))) + (replace-regexp-in-string + ;;(rx "[[" + ;; (submatch (*? nonl)) + ;; "][" + ;; (submatch (*? nonl)) + ;; "]]") + "\\[\\[\\(.*?\\)]\\[\\(.*?\\)]]" + ;;"<a href=\"\\1\">\\2</a>" + 'org-freemind-convert-links-helper + fm-str))) ;;(org-freemind-convert-links-to-org "<a href=\"http://www.somewhere/\">link-text</a>") (defun org-freemind-convert-links-to-org (fm-str) "Convert freemind links in FM-STR to org links and return the result." (let ((org-str (replace-regexp-in-string - (rx "<a" - space - (0+ - (0+ (not (any ">"))) - space) - "href=\"" - (submatch (0+ (not (any "\"")))) - "\"" - (0+ (not (any ">"))) - ">" - (submatch (0+ (not (any "<")))) - "</a>") + ;;(rx "<a" + ;; space + ;; (0+ + ;; (0+ (not (any ">"))) + ;; space) + ;; "href=\"" + ;; (submatch (0+ (not (any "\"")))) + ;; "\"" + ;; (0+ (not (any ">"))) + ;; ">" + ;; (submatch (0+ (not (any "<")))) + ;; "</a>") + "<a[[:space:]]\\(?:[^>]*[[:space:]]\\)*href=\"\\([^\"]*\\)\"[^>]*>\\([^<]*\\)</a>" "[[\\1][\\2]]" fm-str))) org-str)) @@ -319,29 +382,60 @@ ;;(defun org-freemind-convert-drawers-from-org (text) ;; ) -;; (org-freemind-test-links) -;; (defun org-freemind-test-links () ;; (let* ((str1 "[[http://www.somewhere/][link-text]") ;; (str2 (org-freemind-convert-links-from-org str1)) -;; (str3 (org-freemind-convert-links-to-org str2)) -;; ) +;; (str3 (org-freemind-convert-links-to-org str2))) ;; (unless (string= str1 str3) -;; (error "str3=%s" str3)) -;; )) +;; (error "Error str3=%s" str3))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Org => FreeMind +(defvar org-freemind-bol-helper-base-indent nil) + +(defun org-freemind-bol-helper (matched) + "Helper for `org-freemind-convert-text-p'. +MATCHED is the link just matched." + (let ((res "") + (bi org-freemind-bol-helper-base-indent)) + (dolist (cc (append matched nil)) + (if (= 32 cc) + ;;(setq res (concat res " ")) + ;; We need to use the numerical version. Otherwise Freemind + ;; ver 0.9.0 RC9 can not export to html/javascript. + (progn + (if (< 0 bi) + (setq bi (1- bi)) + (setq res (concat res " ")))) + (setq res (concat res (char-to-string cc))))) + res)) +;; (setq x (replace-regexp-in-string "\n +" 'org-freemind-bol-nbsp-helper "\n ")) + (defun org-freemind-convert-text-p (text) "Convert TEXT to html with <p> paragraphs." + ;; (string-match-p "[^ ]" " a") + (setq org-freemind-bol-helper-base-indent (string-match-p "[^ ]" text)) (setq text (org-freemind-escape-str-from-org text)) - (setq text (replace-regexp-in-string (rx "\n" (0+ blank) "\n") "</p><p>\n" text)) - ;;(setq text (replace-regexp-in-string (rx bol (1+ blank) eol) "" text)) - ;;(setq text (replace-regexp-in-string (rx bol (1+ blank)) "<br />" text)) + + (setq text (replace-regexp-in-string "\\([[:space:]]\\)\\(/\\)\\([^/]+\\)\\(/\\)\\([[:space:]]\\)" "\\1<i>\\3</i>\\5" text)) + (setq text (replace-regexp-in-string "\\([[:space:]]\\)\\(\*\\)\\([^*]+\\)\\(\*\\)\\([[:space:]]\\)" "\\1<b>\\3</b>\\5" text)) + + (setq text (concat "<p>" text)) + (setq text (replace-regexp-in-string "\n[[:blank:]]*\n" "</p><p>" text)) + (setq text (replace-regexp-in-string "\\(?:<p>\\|\n\\) +" 'org-freemind-bol-helper text)) (setq text (replace-regexp-in-string "\n" "<br />" text)) - (concat "<p>" - (org-freemind-convert-links-from-org text) - "</p>\n")) + (setq text (concat text "</p>")) + + (org-freemind-convert-links-from-org text)) + +(defcustom org-freemind-node-css-style + "p { margin-top: 3px; margin-bottom: 3px; }" + "CSS style for Freemind nodes." + ;; Fix-me: I do not understand this. It worked to export from Freemind + ;; with this setting now, but not before??? Was this perhaps a java + ;; bug or is it a windows xp bug (some resource gets exhausted if you + ;; use sticky keys which I do). + :group 'org-freemind) (defun org-freemind-org-text-to-freemind-subnode/note (node-name start end drawers-regexp) "Convert text part of org node to freemind subnode or note. @@ -390,11 +484,14 @@ "<node style=\"bubble\" background_color=\"#eeee00\">\n" "<richcontent TYPE=\"NODE\"><html>\n" "<head>\n" + (if (= 0 (length org-freemind-node-css-style)) + "" + (concat "<style type=\"text/css\">\n" "<!--\n" - "p { margin-top: 0 }\n" + org-freemind-node-css-style "-->\n" - "</style>\n" + "</style>\n")) "</head>\n" "<body>\n")) (let ((begin-html-mark (regexp-quote "#+BEGIN_HTML")) @@ -427,21 +524,28 @@ "</html>\n" "</richcontent>\n" ;; Put a note that this is for the parent node - "<richcontent TYPE=\"NOTE\"><html>" - "<head>" - "</head>" - "<body>" - "<p>" - "-- This is more about \"" node-name "\" --" - "</p>" - "</body>" - "</html>" - "</richcontent>\n" + ;; "<richcontent TYPE=\"NOTE\"><html>" + ;; "<head>" + ;; "</head>" + ;; "<body>" + ;; "<p>" + ;; "-- This is more about \"" node-name "\" --" + ;; "</p>" + ;; "</body>" + ;; "</html>" + ;; "</richcontent>\n" + note-res "</node>\n" ;; ok ))) (list node-res note-res)))) -(defun org-freemind-write-node (mm-buffer drawers-regexp num-left-nodes base-level current-level next-level this-m2 this-node-end this-children-visible next-node-start next-has-some-visible-child) +(defun org-freemind-write-node (mm-buffer drawers-regexp + num-left-nodes base-level + current-level next-level this-m2 + this-node-end + this-children-visible + next-node-start + next-has-some-visible-child) (let* (this-icons this-bg-color this-m2-escaped @@ -503,7 +607,7 @@ (insert "<icon builtin=\"" icon "\"/>\n"))) ) (with-current-buffer mm-buffer - (when this-rich-note (insert this-rich-note)) + ;;(when this-rich-note (insert this-rich-note)) (when this-rich-node (insert this-rich-node)))) num-left-nodes) @@ -521,11 +625,13 @@ (error "File %s already exists" file)) t)) -(defvar org-freemind-node-pattern (rx bol - (submatch (1+ "*")) - (1+ space) - (submatch (*? nonl)) - eol)) +(defvar org-freemind-node-pattern + ;;(rx bol + ;; (submatch (1+ "*")) + ;; (1+ space) + ;; (submatch (*? nonl)) + ;; eol) + "^\\(\\*+\\)[[:space:]]+\\(.*?\\)$") (defun org-freemind-look-for-visible-child (node-level) (save-excursion @@ -573,27 +679,31 @@ node-at-line-last) (with-current-buffer mm-buffer (erase-buffer) - (insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n") + (setq buffer-file-coding-system 'utf-8) + ;; Fix-me: Currentl Freemind (ver 0.9.0 RC9) does not support this: + ;;(insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n") (insert "<map version=\"0.9.0\">\n") (insert "<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->\n")) (save-excursion ;; Get special buffer vars: (goto-char (point-min)) - (while (re-search-forward (rx bol "#+DRAWERS:") nil t) + (message "Writing Freemind file...") + (while (re-search-forward "^#\\+DRAWERS:" nil t) (let ((dr-txt (buffer-substring-no-properties (match-end 0) (line-end-position)))) (setq drawers (append drawers (split-string dr-txt) nil)))) (setq drawers-regexp - (concat (rx bol (0+ blank) ":") + (concat "^[[:blank:]]*:" (regexp-opt drawers) - (rx ":" (0+ blank) - "\n" - (*? anything) - "\n" - (0+ blank) - ":END:" - (0+ blank) - eol) - )) + ;;(rx ":" (0+ blank) + ;; "\n" + ;; (*? anything) + ;; "\n" + ;; (0+ blank) + ;; ":END:" + ;; (0+ blank) + ;; eol) + ":[[:blank:]]*\n\\(?:.\\|\n\\)*?\n[[:blank:]]*:END:[[:blank:]]*$" + )) (if node-at-line ;; Get number of top nodes and last line for this node @@ -795,7 +905,8 @@ ;;;###autoload (defun org-freemind-from-org-mode-node (node-line mm-file) - "Convert node at line NODE-LINE to the FreeMind file MM-FILE." + "Convert node at line NODE-LINE to the FreeMind file MM-FILE. +See `org-freemind-from-org-mode' for more information." (interactive (progn (unless (org-back-to-heading nil) @@ -808,20 +919,29 @@ ".mm")) (mm-file (read-file-name "Output FreeMind file: " nil nil nil default-mm-file))) (list line mm-file)))) - (when (org-freemind-check-overwrite mm-file (called-interactively-p 'any)) + (when (org-freemind-check-overwrite mm-file (org-called-interactively-p 'any)) (let ((org-buffer (current-buffer)) (mm-buffer (find-file-noselect mm-file))) (org-freemind-write-mm-buffer org-buffer mm-buffer node-line) (with-current-buffer mm-buffer (basic-save-buffer) - (when (called-interactively-p 'any) + (when (org-called-interactively-p 'any) (switch-to-buffer-other-window mm-buffer) (when (y-or-n-p "Show in FreeMind? ") (org-freemind-show buffer-file-name))))))) ;;;###autoload (defun org-freemind-from-org-mode (org-file mm-file) - "Convert the `org-mode' file ORG-FILE to the FreeMind file MM-FILE." + "Convert the `org-mode' file ORG-FILE to the FreeMind file MM-FILE. +All the nodes will be opened or closed in Freemind just as you +have them in `org-mode'. + +Note that exporting to Freemind also gives you an alternative way +to export from `org-mode' to html. You can create a dynamic html +version of the your org file, by first exporting to Freemind and +then exporting from Freemind to html. The 'As +XHTML (JavaScript)' version in Freemind works very well \(and you +can use a CSS stylesheet to style it)." ;; Fix-me: better doc, include recommendations etc. (interactive (let* ((org-file buffer-file-name) @@ -832,13 +952,13 @@ ".mm")) (mm-file (read-file-name "Output FreeMind file: " nil nil nil default-mm-file))) (list org-file mm-file))) - (when (org-freemind-check-overwrite mm-file (called-interactively-p 'any)) + (when (org-freemind-check-overwrite mm-file (org-called-interactively-p 'any)) (let ((org-buffer (if org-file (find-file-noselect org-file) (current-buffer))) (mm-buffer (find-file-noselect mm-file))) (org-freemind-write-mm-buffer org-buffer mm-buffer nil) (with-current-buffer mm-buffer (basic-save-buffer) - (when (called-interactively-p 'any) + (when (org-called-interactively-p 'any) (switch-to-buffer-other-window mm-buffer) (when (y-or-n-p "Show in FreeMind? ") (org-freemind-show buffer-file-name))))))) @@ -855,7 +975,7 @@ "-sparse.mm")) (mm-file (read-file-name "Output FreeMind file: " nil nil nil default-mm-file))) (list (current-buffer) mm-file))) - (when (org-freemind-check-overwrite mm-file (called-interactively-p 'any)) + (when (org-freemind-check-overwrite mm-file (org-called-interactively-p 'any)) (let (org-buffer (mm-buffer (find-file-noselect mm-file))) (save-window-excursion @@ -864,7 +984,7 @@ (org-freemind-write-mm-buffer org-buffer mm-buffer nil) (with-current-buffer mm-buffer (basic-save-buffer) - (when (called-interactively-p 'any) + (when (org-called-interactively-p 'any) (switch-to-buffer-other-window mm-buffer) (when (y-or-n-p "Show in FreeMind? ") (org-freemind-show buffer-file-name))))))) @@ -1019,7 +1139,7 @@ (save-match-data (let* ((rc (org-freemind-get-richcontent-node node)) (txt (org-freemind-get-tree-text rc))) - ;;(when txt (setq txt (replace-regexp-in-string (rx (1+ whitespace)) " " txt))) + ;;(when txt (setq txt (replace-regexp-in-string "[[:space:]]+" " " txt))) txt ))) @@ -1028,7 +1148,7 @@ (save-match-data (let* ((rc (org-freemind-get-richcontent-note node)) (txt (when rc (org-freemind-get-tree-text rc)))) - ;;(when txt (setq txt (replace-regexp-in-string (rx (1+ whitespace)) " " txt))) + ;;(when txt (setq txt (replace-regexp-in-string "[[:space:]]+" " " txt))) txt ))) @@ -1044,6 +1164,7 @@ (let ((qname (car node)) (attributes (cadr node)) text + ;; Fix-me: note is never inserted (note (org-freemind-get-richcontent-note-text node)) (mark "-- This is more about ") (icons (org-freemind-get-icon-names node)) @@ -1074,6 +1195,8 @@ (case qname ('node (insert (make-string (- level skip-levels) ?*) " " text "\n") + (when note + (insert ":COMMENT:\n" note "\n:END:\n")) )))) (dolist (child children) (unless (or (null child) @@ -1091,7 +1214,7 @@ (default-org-file (concat (file-name-nondirectory mm-file) ".org")) (org-file (read-file-name "Output org-mode file: " nil nil nil default-org-file))) (list mm-file org-file)))) - (when (org-freemind-check-overwrite org-file (called-interactively-p 'any)) + (when (org-freemind-check-overwrite org-file (org-called-interactively-p 'any)) (let ((mm-buffer (find-file-noselect mm-file)) (org-buffer (find-file-noselect org-file))) (with-current-buffer mm-buffer @@ -1100,7 +1223,7 @@ (note (org-freemind-get-richcontent-note-text top-node)) (skip-levels (if (and note - (string-match (rx bol "--org-mode: WHOLE FILE" eol) note)) + (string-match "^--org-mode: WHOLE FILE$" note)) 1 0))) (with-current-buffer org-buffer diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-gnus.el --- a/lisp/org/org-gnus.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-gnus.el Thu Nov 11 22:10:19 2010 -0600 @@ -7,7 +7,7 @@ ;; Tassilo Horn <tassilo at member dot fsf dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -39,9 +39,9 @@ ;; Declare external functions and variables (declare-function message-fetch-field "message" (header &optional not-all)) (declare-function message-narrow-to-head-1 "message" nil) +(declare-function nnimap-group-overview-filename "nnimap" (group server)) ;; The following line suppresses a compiler warning stemming from gnus-sum.el (declare-function gnus-summary-last-subject "gnus-sum" nil) - ;; Customization variables (when (fboundp 'defvaralias) @@ -55,6 +55,17 @@ :group 'org-link-store :type 'boolean) +(defcustom org-gnus-nnimap-query-article-no-from-file nil + "If non-nil, `org-gnus-follow-link' will try to translate +Message-Ids to article numbers by querying the .overview file. +Normally, this translation is done by querying the IMAP server, +which is usually very fast. Unfortunately, some (maybe badly +configured) IMAP servers don't support this operation quickly. +So if following a link to a Gnus article takes ages, try setting +this variable to `t'." + :group 'org-link-store + :type 'boolean) + ;; Install the link type (org-add-link-type "gnus" 'org-gnus-open) @@ -62,6 +73,22 @@ ;; Implementation +(defun org-gnus-nnimap-cached-article-number (group server message-id) + "Return cached article number (uid) of message in GROUP on SERVER. +MESSAGE-ID is the message-id header field that identifies the +message. If the uid is not cached, return nil." + (with-temp-buffer + (let ((nov (nnimap-group-overview-filename group server))) + (when (file-exists-p nov) + (mm-insert-file-contents nov) + (set-buffer-modified-p nil) + (goto-char (point-min)) + (catch 'found + (while (search-forward message-id nil t) + (let ((hdr (split-string (thing-at-point 'line) "\t"))) + (if (string= (nth 4 hdr) message-id) + (throw 'found (nth 0 hdr)))))))))) + (defun org-gnus-group-link (group) "Create a link to the Gnus group GROUP. If GROUP is a newsgroup and `org-gnus-prefer-web-links' is @@ -125,6 +152,11 @@ (from (mail-header-from header)) (message-id (org-remove-angle-brackets (mail-header-id header))) (date (mail-header-date header)) + (date-ts (and date (format-time-string + (org-time-stamp-format t) (date-to-time date)))) + (date-ts-ia (and date (format-time-string + (org-time-stamp-format t t) + (date-to-time date)))) (subject (copy-sequence (mail-header-subject header))) (to (cdr (assq 'To (mail-header-extra header)))) newsgroups x-no-archive desc link) @@ -140,14 +172,27 @@ (setq to (or to (gnus-fetch-original-field "To")) newsgroups (gnus-fetch-original-field "Newsgroups") x-no-archive (gnus-fetch-original-field "x-no-archive"))) - (org-store-link-props :type "gnus" :from from :subject subject + (org-store-link-props :type "gnus" :from from :subject subject :message-id message-id :group group :to to) + (when date + (org-add-link-props :date date :date-timestamp date-ts + :date-timestamp-inactive date-ts-ia)) (setq desc (org-email-link-description) link (org-gnus-article-link group newsgroups message-id x-no-archive)) (org-add-link-props :link link :description desc) link)))) +(defun org-gnus-open-nntp (path) + "Follow the nntp: link specified by PATH." + (let* ((spec (split-string path "/")) + (server (split-string (nth 2 spec) "@")) + (group (nth 3 spec)) + (article (nth 4 spec))) + (org-gnus-follow-link + (format "nntp+%s:%s" (or (cdr server) (car server)) group) + article))) + (defun org-gnus-open (path) "Follow the Gnus message or folder link specified by PATH." (let (group article) @@ -173,7 +218,9 @@ (cond ((and group article) (gnus-activate-group group t) (condition-case nil - (let ((backend (car (gnus-find-method-for-group group)))) + (let* ((method (gnus-find-method-for-group group)) + (backend (car method)) + (server (cadr method))) (cond ((eq backend 'nndoc) (if (gnus-group-read-group t nil group) @@ -183,6 +230,12 @@ (t (let ((articles 1) group-opened) + (when (and (eq backend 'nnimap) + org-gnus-nnimap-query-article-no-from-file) + (setq article + (or (org-gnus-nnimap-cached-article-number + (nth 1 (split-string group ":")) + server (concat "<" article ">")) article))) (while (and (not group-opened) ;; stop on integer overflows (> articles 0)) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-habit.el --- a/lisp/org/org-habit.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-habit.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: John Wiegley <johnw at gnu dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -149,15 +149,17 @@ (assert (org-is-habit-p (point))) (let* ((scheduled (org-get-scheduled-time (point))) (scheduled-repeat (org-get-repeat org-scheduled-string)) - (sr-days (org-habit-duration-to-days scheduled-repeat)) (end (org-entry-end-position)) - (habit-entry (org-no-properties (nth 5 (org-heading-components)))) - closed-dates deadline dr-days) + (habit-entry (org-no-properties (nth 4 (org-heading-components)))) + closed-dates deadline dr-days sr-days) (if scheduled (setq scheduled (time-to-days scheduled)) (error "Habit %s has no scheduled date" habit-entry)) (unless scheduled-repeat - (error "Habit %s has no scheduled repeat period" habit-entry)) + (error + "Habit '%s' has no scheduled repeat period or has an incorrect one" + habit-entry)) + (setq sr-days (org-habit-duration-to-days scheduled-repeat)) (unless (> sr-days 0) (error "Habit %s scheduled repeat period is less than 1d" habit-entry)) (when (string-match "/\\([0-9]+[dwmy]\\)" scheduled-repeat) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-html.el --- a/lisp/org/org-html.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-html.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -126,6 +126,9 @@ .target { } .timestamp { color: #bebebe; } .timestamp-kwd { color: #5f9ea0; } + .right {margin-left:auto; margin-right:0px; text-align:right;} + .left {margin-left:0px; margin-right:auto; text-align:left;} + .center {margin-left:auto; margin-right:auto; text-align:center;} p.verse { margin-left: 3% } pre { border: 1pt solid #AEBDCC; @@ -136,7 +139,13 @@ overflow:auto; } table { border-collapse: collapse; } - td, th { vertical-align: top; } + td, th { vertical-align: top; } + th.right { text-align:center; } + th.left { text-align:center; } + th.center { text-align:center; } + td.right { text-align:right; } + td.left { text-align:left; } + td.center { text-align:center; } dt { font-weight: bold; } div.figure { padding: 0.5em; } div.figure p { text-align: center; } @@ -209,6 +218,112 @@ ;;;###autoload (put 'org-export-html-style-extra 'safe-local-variable 'stringp) +(defcustom org-export-html-mathjax-options + '((path "http://orgmode.org/mathjax/MathJax.js") + (scale "100") + (align "center") + (indent "2em") + (mathml nil)) + "Options for MathJax setup. + +path The path where to find MathJax +scale Scaling for the HTML-CSS backend, usually between 100 and 133 +align How to align display math: left, center, or right +indent If align is not center, how far from the left/right side? +mathml Should a MathML player be used if available? + This is faster and reduces bandwidth use, but currently + sometimes has lower spacing quality. Therefore, the default is + nil. When browsers get better, this switch can be flipped. + +You can also customize this for each buffer, using something like + +#+MATHJAX: scale:\"133\" align:\"right\" mathml:t path:\"/MathJax/\"" + :group 'org-export-html + :type '(list :greedy t + (list :tag "path (the path from where to load MathJax.js)" + (const :format " " path) (string)) + (list :tag "scale (scaling for the displayed math)" + (const :format " " scale) (string)) + (list :tag "align (alignment of displayed equations)" + (const :format " " align) (string)) + (list :tag "indent (indentation with left or right alignment)" + (const :format " " indent) (string)) + (list :tag "mathml (should MathML display be used is possible)" + (const :format " " mathml) (boolean)))) + +(defun org-export-html-mathjax-config (template options in-buffer) + "Insert the user setup into the matchjax template." + (let (name val (yes " ") (no "// ") x) + (mapc + (lambda (e) + (setq name (car e) val (nth 1 e)) + (if (string-match (concat "\\<" (symbol-name name) ":") in-buffer) + (setq val (car (read-from-string + (substring in-buffer (match-end 0)))))) + (if (not (stringp val)) (setq val (format "%s" val))) + (if (string-match (concat "%" (upcase (symbol-name name))) template) + (setq template (replace-match val t t template)))) + options) + (setq val (nth 1 (assq 'mathml options))) + (if (string-match (concat "\\<mathml:") in-buffer) + (setq val (car (read-from-string + (substring in-buffer (match-end 0)))))) + ;; Exchange prefixes depending on mathml setting + (if (not val) (setq x yes yes no no x)) + ;; Replace cookies to turn on or off the config/jax lines + (if (string-match ":MMLYES:" template) + (setq template (replace-match yes t t template))) + (if (string-match ":MMLNO:" template) + (setq template (replace-match no t t template))) + ;; Return the modified template + template)) + +(defcustom org-export-html-mathjax-template + "<script type=\"text/javascript\" src=\"%PATH\"> +<!--/*--><![CDATA[/*><!--*/ + MathJax.Hub.Config({ + // Only one of the two following lines, depending on user settings + // First allows browser-native MathML display, second forces HTML/CSS + :MMLYES: config: [\"MMLorHTML.js\"], jax: [\"input/TeX\"], + :MMLNO: jax: [\"input/TeX\", \"output/HTML-CSS\"], + extensions: [\"tex2jax.js\",\"TeX/AMSmath.js\",\"TeX/AMSsymbols.js\", + \"TeX/noUndefined.js\"], + tex2jax: { + inlineMath: [ [\"\\\\(\",\"\\\\)\"] ], + displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ], + skipTags: [\"script\",\"noscript\",\"style\",\"textarea\",\"pre\",\"code\"], + ignoreClass: \"tex2jax_ignore\", + processEscapes: false, + processEnvironments: true, + preview: \"TeX\" + }, + showProcessingMessages: true, + displayAlign: \"%ALIGN\", + displayIndent: \"%INDENT\", + + \"HTML-CSS\": { + scale: %SCALE, + availableFonts: [\"STIX\",\"TeX\"], + preferredFont: \"TeX\", + webFont: \"TeX\", + imageFont: \"TeX\", + showMathMenu: true, + }, + MMLorHTML: { + prefer: { + MSIE: \"MML\", + Firefox: \"MML\", + Opera: \"HTML\", + other: \"HTML\" + } + } + }); +/*]]>*///--> +</script>" + "The MathJax setup for XHTML files." + :group 'org-export-html + :type 'string) + (defcustom org-export-html-tag-class-prefix "" "Prefix to class names for TODO keywords. Each tag gets a class given by the tag itself, with this prefix. @@ -281,7 +396,7 @@ (const :tag "When there is no description" maybe))) (defcustom org-export-html-inline-image-extensions - '("png" "jpeg" "jpg" "gif") + '("png" "jpeg" "jpg" "gif" "svg") "Extensions of image files that can be inlined into HTML." :group 'org-export-html :type '(repeat (string :tag "Extension"))) @@ -294,17 +409,22 @@ :group 'org-export-html :type 'string) -(defcustom org-export-table-header-tags '("<th scope=\"%s\">" . "</th>") +(defcustom org-export-table-header-tags '("<th scope=\"%s\"%s>" . "</th>") "The opening tag for table header fields. This is customizable so that alignment options can be specified. -%s will be filled with the scope of the field, either row or col. -See also the variable `org-export-html-table-use-header-tags-for-first-column'." +The first %s will be filled with the scope of the field, either row or col. +The second %s will be replaced by a style entry to align the field. +See also the variable `org-export-html-table-use-header-tags-for-first-column'. +See also the variable `org-export-html-table-align-individual-fields'." :group 'org-export-tables :type '(cons (string :tag "Opening tag") (string :tag "Closing tag"))) -(defcustom org-export-table-data-tags '("<td>" . "</td>") +(defcustom org-export-table-data-tags '("<td%s>" . "</td>") "The opening tag for table data fields. -This is customizable so that alignment options can be specified." +This is customizable so that alignment options can be specified. +The first %s will be filled with the scope of the field, either row or col. +The second %s will be replaced by a style entry to align the field. +See also the variable `org-export-html-table-align-individual-fields'." :group 'org-export-tables :type '(cons (string :tag "Opening tag") (string :tag "Closing tag"))) @@ -335,7 +455,13 @@ (string :tag "Specify") (sexp)))) - +(defcustom org-export-html-table-align-individual-fields t + "Non-nil means attach style attributes for alignment to each table field. +When nil, alignment will only be specified in the column tags, but this +is ignored by some browsers (like Firefox, Safari). Opera does it right +though." + :group 'org-export-tables + :type 'boolean) (defcustom org-export-html-table-use-header-tags-for-first-column nil "Non-nil means format column one in tables with header tags. @@ -413,7 +539,7 @@ "Preamble, to be inserted just after <body>. Set by publishing functions. This may also be a function, building and inserting the preamble.") (defvar org-export-html-postamble nil - "Preamble, to be inserted just before </body>. Set by publishing functions. + "Postamble, to be inserted just before </body>. Set by publishing functions. This may also be a function, building and inserting the postamble.") (defvar org-export-html-auto-preamble t "Should default preamble be inserted? Set by publishing functions.") @@ -439,7 +565,13 @@ (file-name-nondirectory org-current-export-file))) org-current-export-dir nil "Creating LaTeX image %s" - nil nil (eq (plist-get parameters :LaTeX-fragments) 'verbatim))) + nil nil + (cond + ((eq (plist-get parameters :LaTeX-fragments) 'verbatim) 'verbatim) + ((eq (plist-get parameters :LaTeX-fragments) 'mathjax ) 'mathjax) + ((eq (plist-get parameters :LaTeX-fragments) t ) 'mathjax) + ((eq (plist-get parameters :LaTeX-fragments) 'dvipng ) 'dvipng) + (t nil)))) (goto-char (point-min)) (let (label l1) (while (re-search-forward "\\\\ref{\\([^{}\n]+\\)}" nil t) @@ -562,7 +694,7 @@ (string-match "\\.org$" path) (progn (list - "http" + "file" (concat (substring path 0 (match-beginning 0)) "." @@ -579,13 +711,10 @@ (declare (special org-export-html-inline-images org-export-html-inline-image-extensions)) - (or - (eq t org-export-html-inline-images) - (and - org-export-html-inline-images - (not descp))) - (org-file-image-p - filename org-export-html-inline-image-extensions)) + (and (or (eq t org-export-html-inline-images) + (and org-export-html-inline-images (not descp))) + (org-file-image-p + filename org-export-html-inline-image-extensions))) ;;; org-html-make-link (defun org-html-make-link (opt-plist type path fragment desc attr @@ -611,7 +740,7 @@ ;;Substitute just if original path was absolute. ;;(Otherwise path must remain relative) (if (file-name-absolute-p path) - (expand-file-name path) + (concat "file://" (expand-file-name path)) path))) ((string= type "") (list nil path)) @@ -637,7 +766,8 @@ ((or (not type) (string= type "http") - (string= type "https")) + (string= type "https") + (string= type "file")) (if fragment (setq thefile (concat thefile "#" fragment)))) @@ -647,8 +777,7 @@ (setq thefile (let ((str (org-export-html-format-href thefile))) - (if (and type (not (string= "file" type)) - (org-string-match-p "^//" str)) + (if (and type (not (string= "file" type))) (concat type ":" str) str))) @@ -781,8 +910,8 @@ (string-match "\\S-" (plist-get opt-plist :link-up)) (plist-get opt-plist :link-up))) (link-home (and (plist-get opt-plist :link-home) - (string-match "\\S-" (plist-get opt-plist :link-home)) - (plist-get opt-plist :link-home))) + (string-match "\\S-" (plist-get opt-plist :link-home)) + (plist-get opt-plist :link-home))) (dummy (setq opt-plist (plist-put opt-plist :title title))) (html-table-tag (plist-get opt-plist :html-table-tag)) (quote-re0 (concat "^[ \t]*" org-quote-string "\\>")) @@ -815,6 +944,7 @@ (buffer-substring (if region-p (region-beginning) (point-min)) (if region-p (region-end) (point-max)))) + (org-export-have-math nil) (lines (org-split-string (org-export-preprocess-string @@ -838,11 +968,21 @@ :LaTeX-fragments (plist-get opt-plist :LaTeX-fragments)) "[\r\n]")) + (mathjax + (if (or (eq (plist-get opt-plist :LaTeX-fragments) 'mathjax) + (and org-export-have-math + (eq (plist-get opt-plist :LaTeX-fragments) t))) + + (org-export-html-mathjax-config + org-export-html-mathjax-template + org-export-html-mathjax-options + (or (plist-get opt-plist :mathjax) "")) + "")) table-open type table-buffer table-orig-buffer - ind item-type starter didclose + ind item-type starter rpl path attr desc descp desc1 desc2 link - snumber fnc item-tag initial-number + snumber fnc item-tag item-number footnotes footref-seen id-file href ) @@ -907,6 +1047,7 @@ <meta name=\"description\" content=\"%s\"/> <meta name=\"keywords\" content=\"%s\"/> %s +%s </head> <body> <div id=\"content\"> @@ -925,6 +1066,7 @@ (or charset "iso-8859-1") date author description keywords style + mathjax (if (or link-up link-home) (concat (format org-export-html-home/up-format @@ -950,73 +1092,73 @@ (push "<ul>\n<li>" thetoc) (setq lines (mapcar '(lambda (line) - (if (and (string-match org-todo-line-regexp line) - (not (get-text-property 0 'org-protected line))) - ;; This is a headline - (progn - (setq have-headings t) - (setq level (- (match-end 1) (match-beginning 1) - level-offset) - level (org-tr-level level) - txt (save-match-data - (org-html-expand - (org-export-cleanup-toc-line - (match-string 3 line)))) - todo - (or (and org-export-mark-todo-in-toc - (match-beginning 2) - (not (member (match-string 2 line) - org-done-keywords))) + (if (and (string-match org-todo-line-regexp line) + (not (get-text-property 0 'org-protected line))) + ;; This is a headline + (progn + (setq have-headings t) + (setq level (- (match-end 1) (match-beginning 1) + level-offset) + level (org-tr-level level) + txt (save-match-data + (org-html-expand + (org-export-cleanup-toc-line + (match-string 3 line)))) + todo + (or (and org-export-mark-todo-in-toc + (match-beginning 2) + (not (member (match-string 2 line) + org-done-keywords))) ; TODO, not DONE - (and org-export-mark-todo-in-toc - (= level umax-toc) - (org-search-todo-below - line lines level)))) - (if (string-match - (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") txt) - (setq txt (replace-match "   <span class=\"tag\"> \\1</span>" t nil txt))) - (if (string-match quote-re0 txt) - (setq txt (replace-match "" t t txt))) - (setq snumber (org-section-number level)) - (if org-export-with-section-numbers - (setq txt (concat snumber " " txt))) - (if (<= level (max umax umax-toc)) - (setq head-count (+ head-count 1))) - (if (<= level umax-toc) - (progn - (if (> level org-last-level) - (progn - (setq cnt (- level org-last-level)) - (while (>= (setq cnt (1- cnt)) 0) - (push "\n<ul>\n<li>" thetoc)) - (push "\n" thetoc))) - (if (< level org-last-level) - (progn - (setq cnt (- org-last-level level)) - (while (>= (setq cnt (1- cnt)) 0) - (push "</li>\n</ul>" thetoc)) - (push "\n" thetoc))) - ;; Check for targets - (while (string-match org-any-target-regexp line) - (setq line (replace-match - (concat "@<span class=\"target\">" (match-string 1 line) "@</span> ") - t t line))) - (while (string-match "<\\(<\\)+\\|>\\(>\\)+" txt) - (setq txt (replace-match "" t t txt))) - (setq href - (replace-regexp-in-string - "\\." "_" (format "sec-%s" snumber))) - (setq href (or (cdr (assoc href org-export-preferred-target-alist)) href)) - (push - (format - (if todo - "</li>\n<li><a href=\"#%s\"><span class=\"todo\">%s</span></a>" - "</li>\n<li><a href=\"#%s\">%s</a>") - href txt) thetoc) + (and org-export-mark-todo-in-toc + (= level umax-toc) + (org-search-todo-below + line lines level)))) + (if (string-match + (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") txt) + (setq txt (replace-match "   <span class=\"tag\"> \\1</span>" t nil txt))) + (if (string-match quote-re0 txt) + (setq txt (replace-match "" t t txt))) + (setq snumber (org-section-number level)) + (if org-export-with-section-numbers + (setq txt (concat snumber " " txt))) + (if (<= level (max umax umax-toc)) + (setq head-count (+ head-count 1))) + (if (<= level umax-toc) + (progn + (if (> level org-last-level) + (progn + (setq cnt (- level org-last-level)) + (while (>= (setq cnt (1- cnt)) 0) + (push "\n<ul>\n<li>" thetoc)) + (push "\n" thetoc))) + (if (< level org-last-level) + (progn + (setq cnt (- org-last-level level)) + (while (>= (setq cnt (1- cnt)) 0) + (push "</li>\n</ul>" thetoc)) + (push "\n" thetoc))) + ;; Check for targets + (while (string-match org-any-target-regexp line) + (setq line (replace-match + (concat "@<span class=\"target\">" (match-string 1 line) "@</span> ") + t t line))) + (while (string-match "<\\(<\\)+\\|>\\(>\\)+" txt) + (setq txt (replace-match "" t t txt))) + (setq href + (replace-regexp-in-string + "\\." "_" (format "sec-%s" snumber))) + (setq href (or (cdr (assoc href org-export-preferred-target-alist)) href)) + (push + (format + (if todo + "</li>\n<li><a href=\"#%s\"><span class=\"todo\">%s</span></a>" + "</li>\n<li><a href=\"#%s\">%s</a>") + href txt) thetoc) - (setq org-last-level level)) - ))) - line) + (setq org-last-level level)) + ))) + line) lines)) (while (> org-last-level (1- org-min-level)) (setq org-last-level (1- org-last-level)) @@ -1059,7 +1201,16 @@ (org-open-par)) (throw 'nextline nil)) - (org-export-html-close-lists-maybe line) + ;; Explicit list closure + (when (equal "ORG-LIST-END" line) + (while local-list-indent + (org-close-li (car local-list-type)) + (insert (format "</%sl>\n" (car local-list-type))) + (pop local-list-type) + (pop local-list-indent)) + (setq in-local-list nil) + (org-open-par) + (throw 'nextline nil)) ;; Protected HTML (when (get-text-property 0 'org-protected line) @@ -1178,79 +1329,79 @@ desc2 (if (match-end 2) (concat type ":" path) path) descp (and desc1 (not (equal desc1 desc2))) desc (or desc1 desc2)) - ;; Make an image out of the description if that is so wanted + ;; Make an image out of the description if that is so wanted (when (and descp (org-file-image-p - desc org-export-html-inline-image-extensions)) - (save-match-data - (if (string-match "^file:" desc) - (setq desc (substring desc (match-end 0))))) - (setq desc (org-add-props + desc org-export-html-inline-image-extensions)) + (save-match-data + (if (string-match "^file:" desc) + (setq desc (substring desc (match-end 0))))) + (setq desc (org-add-props (concat "<img src=\"" desc "\"/>") '(org-protected t)))) (cond ((equal type "internal") - (let - ((frag-0 - (if (= (string-to-char path) ?#) - (substring path 1) - path))) - (setq rpl + (let + ((frag-0 + (if (= (string-to-char path) ?#) + (substring path 1) + path))) + (setq rpl (org-html-make-link - opt-plist - "" - "" - (org-solidify-link-text - (save-match-data (org-link-unescape frag-0)) - nil) - desc attr nil)))) + opt-plist + "" + "" + (org-solidify-link-text + (save-match-data (org-link-unescape frag-0)) + nil) + desc attr nil)))) ((and (equal type "id") (setq id-file (org-id-find-id-file path))) ;; This is an id: link to another file (if it was the same file, ;; it would have become an internal link...) (save-match-data (setq id-file (file-relative-name - id-file - (file-name-directory org-current-export-file))) - (setq rpl - (org-html-make-link opt-plist - "file" id-file - (concat (if (org-uuidgen-p path) "ID-") path) - desc - attr - nil)))) - ((member type '("http" "https")) - ;; standard URL, can inline as image + id-file + (file-name-directory org-current-export-file))) (setq rpl - (org-html-make-link opt-plist - type path nil - desc - attr - (org-html-should-inline-p path descp)))) + (org-html-make-link opt-plist + "file" id-file + (concat (if (org-uuidgen-p path) "ID-") path) + desc + attr + nil)))) + ((member type '("http" "https")) + ;; standard URL, can inline as image + (setq rpl + (org-html-make-link opt-plist + type path nil + desc + attr + (org-html-should-inline-p path descp)))) ((member type '("ftp" "mailto" "news")) - ;; standard URL, can't inline as image - (setq rpl - (org-html-make-link opt-plist - type path nil - desc - attr - nil))) + ;; standard URL, can't inline as image + (setq rpl + (org-html-make-link opt-plist + type path nil + desc + attr + nil))) ((string= type "coderef") - (let* - ((coderef-str (format "coderef-%s" path)) - (attr-1 - (format "class=\"coderef\" onmouseover=\"CodeHighlightOn(this, '%s');\" onmouseout=\"CodeHighlightOff(this, '%s');\"" + (let* + ((coderef-str (format "coderef-%s" path)) + (attr-1 + (format "class=\"coderef\" onmouseover=\"CodeHighlightOn(this, '%s');\" onmouseout=\"CodeHighlightOff(this, '%s');\"" coderef-str coderef-str))) - (setq rpl + (setq rpl (org-html-make-link opt-plist - type "" coderef-str - (format - (org-export-get-coderef-format - path - (and descp desc)) - (cdr (assoc path org-export-code-refs))) - attr-1 - nil)))) + type "" coderef-str + (format + (org-export-get-coderef-format + path + (and descp desc)) + (cdr (assoc path org-export-code-refs))) + attr-1 + nil)))) ((functionp (setq fnc (nth 2 (assoc type org-link-protocols)))) ;; The link protocol has a function for format the link @@ -1259,55 +1410,55 @@ (funcall fnc (org-link-unescape path) desc1 'html)))) ((string= type "file") - ;; FILE link - (save-match-data - (let* - ((components - (if - (string-match "::\\(.*\\)" path) - (list - (replace-match "" t nil path) - (match-string 1 path)) - (list path nil))) + ;; FILE link + (save-match-data + (let* + ((components + (if + (string-match "::\\(.*\\)" path) + (list + (replace-match "" t nil path) + (match-string 1 path)) + (list path nil))) - ;;The proper path, without a fragment - (path-1 - (first components)) + ;;The proper path, without a fragment + (path-1 + (first components)) - ;;The raw fragment - (fragment-0 - (second components)) + ;;The raw fragment + (fragment-0 + (second components)) - ;;Check the fragment. If it can't be used as - ;;target fragment we'll pass nil instead. - (fragment-1 - (if - (and fragment-0 - (not (string-match "^[0-9]*$" fragment-0)) - (not (string-match "^\\*" fragment-0)) - (not (string-match "^/.*/$" fragment-0))) - (org-solidify-link-text - (org-link-unescape fragment-0)) - nil)) - (desc-2 - ;;Description minus "file:" and ".org" - (if (string-match "^file:" desc) - (let - ((desc-1 (replace-match "" t t desc))) - (if (string-match "\\.org$" desc-1) - (replace-match "" t t desc-1) - desc-1)) - desc))) + ;;Check the fragment. If it can't be used as + ;;target fragment we'll pass nil instead. + (fragment-1 + (if + (and fragment-0 + (not (string-match "^[0-9]*$" fragment-0)) + (not (string-match "^\\*" fragment-0)) + (not (string-match "^/.*/$" fragment-0))) + (org-solidify-link-text + (org-link-unescape fragment-0)) + nil)) + (desc-2 + ;;Description minus "file:" and ".org" + (if (string-match "^file:" desc) + (let + ((desc-1 (replace-match "" t t desc))) + (if (string-match "\\.org$" desc-1) + (replace-match "" t t desc-1) + desc-1)) + desc))) - (setq rpl - (if + (setq rpl + (if (and - (functionp link-validate) - (not (funcall link-validate path-1 current-dir))) + (functionp link-validate) + (not (funcall link-validate path-1 current-dir))) desc - (org-html-make-link opt-plist - "file" path-1 fragment-1 desc-2 attr - (org-html-should-inline-p path-1 descp))))))) + (org-html-make-link opt-plist + "file" path-1 fragment-1 desc-2 attr + (org-html-should-inline-p path-1 descp))))))) (t ;; just publish the path, as default @@ -1364,14 +1515,6 @@ (setq txt (replace-match "" t t txt))) (if (<= level (max umax umax-toc)) (setq head-count (+ head-count 1))) - (when in-local-list - ;; Close any local lists before inserting a new header line - (while local-list-type - (org-close-li (car local-list-type)) - (insert (format "</%sl>\n" (car local-list-type))) - (pop local-list-type)) - (setq local-list-indent nil - in-local-list nil)) (setq first-heading-pos (or first-heading-pos (point))) (org-html-level-start level txt umax (and org-export-with-toc (<= level umax)) @@ -1383,19 +1526,6 @@ (insert "<pre>") (setq inquote t))) - ((string-match "^[ \t]*- __+[ \t]*$" line) - ;; Explicit list closure - (when local-list-type - (let ((ind (org-get-indentation line))) - (while (and local-list-indent - (<= ind (car local-list-indent))) - (org-close-li (car local-list-type)) - (insert (format "</%sl>\n" (car local-list-type))) - (pop local-list-type) - (pop local-list-indent)) - (or local-list-indent (setq in-local-list nil)))) - (throw 'nextline nil)) - ((and org-export-with-tables (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" line)) (when (not table-open) @@ -1428,66 +1558,57 @@ starter (if (match-beginning 2) (substring (match-string 2 line) 0 -1)) line (substring line (match-beginning 5)) - initial-number nil + item-number nil item-tag nil) - (if (string-match "\\`\\[@start:\\([0-9]+\\)\\][ \t]?" line) - (setq initial-number (match-string 1 line) + (if (string-match "\\[@\\(?:start:\\)?\\([0-9]+\\)\\][ \t]?" line) + (setq item-number (match-string 1 line) line (replace-match "" t t line))) (if (and starter (string-match "\\(.*?\\) ::[ \t]*" line)) (setq item-type "d" item-tag (match-string 1 line) line (substring line (match-end 0)))) - (when (and (not (equal item-type "d")) - (not (string-match "[^ \t]" line))) - ;; empty line. Pretend indentation is large. - (setq ind (if org-empty-line-terminates-plain-lists - 0 - (1+ (or (car local-list-indent) 1))))) - (setq didclose nil) - (while (and in-local-list - (or (and (= ind (car local-list-indent)) - (not starter)) - (< ind (car local-list-indent)))) - (setq didclose t) - (org-close-li (car local-list-type)) - (insert (format "</%sl>\n" (car local-list-type))) - (pop local-list-type) (pop local-list-indent) - (setq in-local-list local-list-indent)) (cond ((and starter (or (not in-local-list) (> ind (car local-list-indent)))) - ;; check for a specified start number ;; Start new (level of) list (org-close-par-maybe) (insert (cond ((equal item-type "u") "<ul>\n<li>\n") - ((equal item-type "o") - (if initial-number - (format "<ol start=%s>\n<li>\n" initial-number) - "<ol>\n<li>\n")) + ((and (equal item-type "o") item-number) + (format "<ol>\n<li value=\"%s\">\n" item-number)) + ((equal item-type "o") "<ol>\n<li>\n") ((equal item-type "d") (format "<dl>\n<dt>%s</dt><dd>\n" item-tag)))) (push item-type local-list-type) (push ind local-list-indent) (setq in-local-list t)) + ;; Continue list (starter - ;; continue current list + ;; terminate any previous sublist but first ensure + ;; list is not ill-formed. + (let ((min-ind (apply 'min local-list-indent))) + (when (< ind min-ind) (setq ind min-ind))) + (while (< ind (car local-list-indent)) + (org-close-li (car local-list-type)) + (insert (format "</%sl>\n" (car local-list-type))) + (pop local-list-type) (pop local-list-indent) + (setq in-local-list local-list-indent)) + ;; insert new item (org-close-li (car local-list-type)) (insert (cond ((equal (car local-list-type) "d") (format "<dt>%s</dt><dd>\n" (or item-tag "???"))) - (t "<li>\n")))) - (didclose - ;; we did close a list, normal text follows: need <p> - (org-open-par))) + ((and (equal item-type "o") item-number) + (format "<li value=\"%s\">\n" item-number)) + (t "<li>\n"))))) (if (string-match "^[ \t]*\\[\\([X ]\\)\\]" line) (setq line (replace-match (if (equal (match-string 1 line) "X") "<b>[X]</b>" "<b>[<span style=\"visibility:hidden;\">X</span>]</b>") - t t line)))) + t t line)))) ;; Horizontal line (when (string-match "^[ \t]*-\\{5,\\}[ \t]*$" line) @@ -1542,14 +1663,7 @@ (when inquote (insert "</pre>\n") (org-open-par)) - (when in-local-list - ;; Close any local lists before inserting a new header line - (while local-list-type - (org-close-li (car local-list-type)) - (insert (format "</%sl>\n" (car local-list-type))) - (pop local-list-type)) - (setq local-list-indent nil - in-local-list nil)) + (org-html-level-start 1 nil umax (and org-export-with-toc (<= level umax)) head-count) @@ -1630,8 +1744,6 @@ (while (re-search-forward "<li>[ \r\n\t]*</li>\n?" nil t) (replace-match "")) (goto-char (point-min)) - (while (re-search-forward "</ul>\\s-*<ul>\n?" nil t) - (replace-match "")) ;; Convert whitespace place holders (goto-char (point-min)) (let (beg end n) @@ -1726,13 +1838,14 @@ nil)))) (defvar org-table-number-regexp) ; defined in org-table.el -(defun org-format-table-html (lines olines) - "Find out which HTML converter to use and return the HTML code." +(defun org-format-table-html (lines olines &optional no-css) + "Find out which HTML converter to use and return the HTML code. +NO-CSS is passed to the exporter." (if (stringp lines) (setq lines (org-split-string lines "\n"))) (if (string-match "^[ \t]*|" (car lines)) ;; A normal org table - (org-format-org-table-html lines) + (org-format-org-table-html lines nil no-css) ;; Table made by table.el - test for spanning (let* ((hlines (delq nil (mapcar (lambda (x) @@ -1753,8 +1866,12 @@ (org-format-table-table-html-using-table-generate-source olines))))) (defvar org-table-number-fraction) ; defined in org-table.el -(defun org-format-org-table-html (lines &optional splice) - "Format a table into HTML." +(defun org-format-org-table-html (lines &optional splice no-css) + "Format a table into HTML. +LINES is a list of lines. Optional argument SPLICE means, do not +insert header and surrounding <table> tags, just format the lines. +Optional argument NO-CSS means use XHTML attributes instead of CSS +for formatting. This is required for the DocBook exporter." (require 'org-table) ;; Get rid of hlines at beginning and end (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines))) @@ -1768,6 +1885,8 @@ (let* ((caption (org-find-text-property-in-string 'org-caption (car lines))) (label (org-find-text-property-in-string 'org-label (car lines))) + (forced-aligns (org-find-text-property-in-string 'org-forced-aligns + (car lines))) (attributes (org-find-text-property-in-string 'org-attributes (car lines))) (html-table-tag (org-export-splice-attributes @@ -1776,10 +1895,13 @@ (delq nil (mapcar (lambda (x) (string-match "^[ \t]*|-" x)) (cdr lines))))) - - (nline 0) fnum nfields i - tbopen line fields html gr colgropen rowstart rowend) + (nline 0) fnum nfields i (cnt 0) + tbopen line fields html gr colgropen rowstart rowend + ali align aligns n) (setq caption (and caption (org-html-do-expand caption))) + (when (and forced-aligns org-table-clean-did-remove-column) + (setq forced-aligns + (mapcar (lambda (x) (cons (1- (car x)) (cdr x))) forced-aligns))) (if splice (setq head nil)) (unless splice (push (if head "<thead>" "<tbody>") html)) (setq tbopen t) @@ -1803,23 +1925,26 @@ (push (concat rowstart (mapconcat (lambda (x) - (setq i (1+ i)) + (setq i (1+ i) ali (format "@@class%03d@@" i)) (if (and (< i nfields) ; make sure no rogue line causes an error here (string-match org-table-number-regexp x)) (incf (aref fnum i))) (cond (head (concat - (format (car org-export-table-header-tags) "col") + (format (car org-export-table-header-tags) + "col" ali) x (cdr org-export-table-header-tags))) ((and (= i 0) org-export-html-table-use-header-tags-for-first-column) (concat - (format (car org-export-table-header-tags) "row") + (format (car org-export-table-header-tags) + "row" ali) x (cdr org-export-table-header-tags))) (t - (concat (car org-export-table-data-tags) x + (concat (format (car org-export-table-data-tags) ali) + x (cdr org-export-table-data-tags))))) fields "") rowend) @@ -1832,23 +1957,38 @@ (unless (car org-table-colgroup-info) (setq org-table-colgroup-info (cons :start (cdr org-table-colgroup-info)))) + (setq i 0) (push (mapconcat (lambda (x) - (setq gr (pop org-table-colgroup-info)) - (format "%s<col align=\"%s\" />%s" + (setq gr (pop org-table-colgroup-info) + i (1+ i) + align (if (assoc i forced-aligns) + (cdr (assoc (cdr (assoc i forced-aligns)) + '(("l" . "left") ("r" . "right") + ("c" . "center")))) + (if (> (/ (float x) nline) + org-table-number-fraction) + "right" "left"))) + (push align aligns) + (format (if no-css + "%s<col align=\"%s\" />%s" + "%s<col class=\"%s\" />%s") (if (memq gr '(:start :startend)) (prog1 - (if colgropen "</colgroup>\n<colgroup>" "<colgroup>") + (if colgropen + "</colgroup>\n<colgroup>" + "<colgroup>") (setq colgropen t)) "") - (if (> (/ (float x) nline) org-table-number-fraction) - "right" "left") + align (if (memq gr '(:end :startend)) (progn (setq colgropen nil) "</colgroup>") ""))) fnum "") html) - (if colgropen (setq html (cons (car html) (cons "</colgroup>" (cdr html))))) + (setq aligns (nreverse aligns)) + (if colgropen (setq html (cons (car html) + (cons "</colgroup>" (cdr html))))) ;; Since the output of HTML table formatter can also be used in ;; DocBook document, we want to always include the caption to make ;; DocBook XML file valid. @@ -1856,6 +1996,18 @@ (when label (push (format "<a name=\"%s\" id=\"%s\"></a>" label label) html)) (push html-table-tag html)) + (setq html (mapcar + (lambda (x) + (replace-regexp-in-string + "@@class\\([0-9]+\\)@@" + (lambda (txt) + (if (not org-export-html-table-align-individual-fields) + "" + (setq n (string-to-number (match-string 1 txt))) + (format (if no-css " align=\"%s\"" " class=\"%s\"") + (or (nth n aligns) "left")))) + x)) + html)) (concat (mapconcat 'identity html "\n") "\n"))) (defun org-export-splice-attributes (tag attributes) @@ -1900,10 +2052,10 @@ (if (equal x "") (setq x empty)) (if head (concat - (format (car org-export-table-header-tags) "col") + (format (car org-export-table-header-tags) "col" "") x (cdr org-export-table-header-tags)) - (concat (car org-export-table-data-tags) x + (concat (format (car org-export-table-data-tags) "") x (cdr org-export-table-data-tags)))) field-buffer "\n") "</tr>\n")) @@ -2042,7 +2194,7 @@ "Prepare STRING for HTML export. Apply all active conversions. If there are links in the string, don't modify these." (let* ((re (concat org-bracket-link-regexp "\\|" - (org-re "[ \t]+\\(:[[:alnum:]_@:]+:\\)[ \t]*$"))) + (org-re "[ \t]+\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$"))) m s l res) (if (string-match "^[ \t]*\\+-[-+]*\\+[ \t]*$" string) string @@ -2152,28 +2304,6 @@ (defvar in-local-list) (defvar local-list-indent) (defvar local-list-type) -(defun org-export-html-close-lists-maybe (line) - "Close local lists based on the original indentation of the line." - (let* ((rawhtml (and in-local-list - (get-text-property 0 'org-protected line) - (not (get-text-property 0 'org-example line)))) - ;; rawhtml means: This was between #+begin_html..#+end_html - ;; originally, thus it excludes stuff that was a source code example - ;; Actually, this code seems wrong, I don't know why it works, but - ;; it seems to work.... So keep it like this for now. - (ind (if rawhtml - (org-get-indentation line) - (get-text-property 0 'original-indentation line))) - didclose) - (when ind - (while (and in-local-list - (<= ind (car local-list-indent))) - (setq didclose t) - (org-close-li (car local-list-type)) - (insert (format "</%sl>\n" (car local-list-type))) - (pop local-list-type) (pop local-list-indent) - (setq in-local-list local-list-indent)) - (and didclose (org-open-par))))) (defvar body-only) ; dynamically scoped into this. (defun org-html-level-start (level title umax with-toc head-count) @@ -2206,7 +2336,7 @@ (when title ;; If title is nil, this means this function is called to close ;; all levels, so the rest is done only if title is given - (when (string-match (org-re "\\(:[[:alnum:]_@:]+:\\)[ \t]*$") title) + (when (string-match (org-re "\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") title) (setq title (replace-match (if org-export-with-tags (save-match-data diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-icalendar.el --- a/lisp/org/org-icalendar.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-icalendar.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -47,13 +47,24 @@ :group 'org-export-icalendar :type 'file) +(defcustom org-icalendar-alarm-time 0 + "Number of minutes for triggering an alarm for exported timed events. +A zero value (the default) turns off the definition of an alarm trigger +for timed events. If non-zero, alarms are created. + +- a single alarm per entry is defined +- The alarm will go off N minutes before the event +- only a DISPLAY action is defined." + :group 'org-export-icalendar + :type 'integer) + (defcustom org-icalendar-combined-name "OrgMode" "Calendar name for the combined iCalendar representing all agenda files." :group 'org-export-icalendar :type 'string) (defcustom org-icalendar-combined-description nil - "Calendar description for the combined iCalendar representing all agenda files." + "Calendar description for the combined iCalendar (all agenda files)." :group 'org-export-icalendar :type 'string) @@ -183,6 +194,13 @@ (const :tag "Unspecified" nil) (string :tag "Time zone"))) +(defcustom org-icalendar-use-UTC-date-time () + "Non-nil force the use of the universal time for iCalendar DATE-TIME. +The iCalendar DATE-TIME can be expressed with local time or universal Time, +universal time could be more compatible with some external tools." + :group 'org-export-icalendar + :type 'boolean) + ;;; iCalendar export ;;;###autoload @@ -282,7 +300,7 @@ "DTSTART")) hd ts ts2 state status (inc t) pos b sexp rrule scheduledp deadlinep todo prefix due start - tmp pri categories location summary desc uid + tmp pri categories location summary desc uid alarm (sexp-buffer (get-buffer-create "*ical-tmp*"))) (org-refresh-category-properties) (save-excursion @@ -300,7 +318,7 @@ inc t hd (condition-case nil (org-icalendar-cleanup-string - (org-get-heading)) + (org-get-heading t)) (error (throw :skip nil))) summary (org-icalendar-cleanup-string (org-entry-get nil "SUMMARY")) @@ -314,6 +332,7 @@ (org-id-get-create) (or (org-id-get) (org-id-new))) categories (org-export-get-categories) + alarm "" deadlinep nil scheduledp nil) (if (looking-at re2) (progn @@ -362,6 +381,17 @@ ";INTERVAL=" (match-string 1 ts))) (setq rrule "")) (setq summary (or summary hd)) + ;; create an alarm entry if the entry is timed. this is not very general in that: + ;; (a) only one alarm per entry is defined, + ;; (b) only minutes are allowed for the trigger period ahead of the start time, and + ;; (c) only a DISPLAY action is defined. + ;; [ESF] + (let ((t1 (ignore-errors (org-parse-time-string ts 'nodefault)))) + (if (and (> org-icalendar-alarm-time 0) + (car t1) (nth 1 t1) (nth 2 t1)) + (setq alarm (format "\nBEGIN:VALARM\nACTION:DISPLAY\nDESCRIPTION:%s\nTRIGGER:-P0D0H%dM0S\nEND:VALARM" summary org-icalendar-alarm-time)) + (setq alarm "")) + ) (if (string-match org-bracket-link-regexp summary) (setq summary (replace-match (if (match-end 3) @@ -378,7 +408,7 @@ %s %s%s SUMMARY:%s%s%s -CATEGORIES:%s +CATEGORIES:%s%s END:VEVENT\n" (concat prefix uid) (org-ical-ts-to-string ts "DTSTART") @@ -388,7 +418,8 @@ (concat "\nDESCRIPTION: " desc) "") (if (and location (string-match "\\S-" location)) (concat "\nLOCATION: " location) "") - categories))))) + categories + alarm))))) (when (and org-icalendar-include-sexps (condition-case nil (require 'icalendar) (error nil)) (fboundp 'icalendar-export-region)) @@ -415,7 +446,7 @@ (when org-icalendar-include-todo (setq prefix "TODO-") (goto-char (point-min)) - (while (re-search-forward org-todo-line-regexp nil t) + (while (re-search-forward org-complex-heading-regexp nil t) (catch :skip (org-agenda-skip) (when org-icalendar-verify-function @@ -447,7 +478,7 @@ ((eq org-icalendar-include-todo t) ;; include everything that is not done (member state org-not-done-keywords)))) - (setq hd (match-string 3) + (setq hd (match-string 4) summary (org-icalendar-cleanup-string (org-entry-get nil "SUMMARY")) desc (org-icalendar-cleanup-string @@ -610,8 +641,13 @@ (setq h (+ 2 h))) (setq d (1+ d)))) (setq time (encode-time s mi h d m y))) - (setq fmt (if have-time ":%Y%m%dT%H%M%S" ";VALUE=DATE:%Y%m%d")) - (concat keyword (format-time-string fmt time))))) + (setq fmt (if have-time (if org-icalendar-use-UTC-date-time + ":%Y%m%dT%H%M%SZ" + ":%Y%m%dT%H%M%S") + ";VALUE=DATE:%Y%m%d")) + (concat keyword (format-time-string fmt time + (and org-icalendar-use-UTC-date-time + have-time)))))) (provide 'org-icalendar) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-id.el --- a/lisp/org/org-id.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-id.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -596,6 +596,7 @@ ;; Calling the following function is hard-coded into `org-store-link', ;; so we do have to add it to `org-store-link-functions'. +;;;###autoload (defun org-id-store-link () "Store a link to the current entry, using its ID." (interactive) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-indent.el --- a/lisp/org/org-indent.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-indent.el Thu Nov 11 22:10:19 2010 -0600 @@ -4,7 +4,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -135,11 +135,11 @@ ((org-bound-and-true-p org-inhibit-startup) (setq org-indent-mode nil)) ((and org-indent-mode (featurep 'xemacs)) - (message "org-indent-mode does not work in XEmacs - refused to turn it on") + (message "org-indent-mode does not work in XEmacs - refusing to turn it on") (setq org-indent-mode nil)) ((and org-indent-mode (not (org-version-check "23.1.50" "Org Indent mode" :predicate))) - (message "org-indent-mode is can crash Emacs 23.1 - refused to turn it on!") + (message "org-indent-mode can crash Emacs 23.1 - refusing to turn it on!") (ding) (sit-for 1) (setq org-indent-mode nil)) @@ -203,8 +203,9 @@ (defun org-indent-remove-properties (beg end) "Remove indentations between BEG and END." - (org-unmodified - (remove-text-properties beg end '(line-prefix nil wrap-prefix nil)))) + (let ((inhibit-modification-hooks t)) + (with-silent-modifications + (remove-text-properties beg end '(line-prefix nil wrap-prefix nil))))) (defun org-indent-remove-properties-from-string (string) "Remove indentations between BEG and END." @@ -219,8 +220,9 @@ "Add indentation properties between BEG and END. Assumes that BEG is at the beginning of a line." (when (or t org-indent-mode) - (let (ov b e n level exit nstars) - (org-unmodified + (let ((inhibit-modification-hooks t) + ov b e n level exit nstars) + (with-silent-modifications (save-excursion (goto-char beg) (while (not exit) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-info.el --- a/lisp/org/org-info.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-info.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-inlinetask.el --- a/lisp/org/org-inlinetask.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-inlinetask.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -90,7 +90,9 @@ not set, it will be assumed to be one less than the value of smaller than the value of this variable." :group 'org-inlinetask - :type 'boolean) + :type '(choice + (const :tag "Off" nil) + (integer))) (defcustom org-inlinetask-export t "Non-nil means export inline tasks. @@ -104,7 +106,7 @@ (defvar org-complex-heading-regexp) (defvar org-property-end-re) -(defcustom org-inlinetask-defaut-state nil +(defcustom org-inlinetask-default-state nil "Non-nil means make inline tasks have a TODO keyword initially. This should be the state `org-inlinetask-insert-task' should use by default, or nil of no state should be assigned." @@ -115,20 +117,36 @@ (defun org-inlinetask-insert-task (&optional no-state) "Insert an inline task. -If prefix arg NO-STATE is set, ignore `org-inlinetask-defaut-state'." +If prefix arg NO-STATE is set, ignore `org-inlinetask-default-state'." (interactive "P") (or (bolp) (newline)) (let ((indent org-inlinetask-min-level)) (if org-odd-levels-only (setq indent (- (* 2 indent) 1))) (insert (make-string indent ?*) - (if (or no-state (not org-inlinetask-defaut-state)) + (if (or no-state (not org-inlinetask-default-state)) " \n" - (concat " " org-inlinetask-defaut-state " \n")) + (concat " " org-inlinetask-default-state " \n")) (make-string indent ?*) " END\n")) (end-of-line -1)) (define-key org-mode-map "\C-c\C-xt" 'org-inlinetask-insert-task) +(defun org-inlinetask-in-task-p () + "Return true if point is inside an inline task." + (save-excursion + (let* ((nstars (if org-odd-levels-only + (1- (* 2 (or org-inlinetask-min-level 200))) + (or org-inlinetask-min-level 200))) + (stars-re (concat "^\\(?:\\*\\{" + (format "%d" (- nstars 1)) + ",\\}\\)[ \t]+")) + (task-beg-re (concat stars-re "\\(?:.*\\)")) + (task-end-re (concat stars-re "\\(?:END\\|end\\)"))) + (beginning-of-line) + (or (looking-at task-beg-re) + (and (re-search-forward "^\\*+[ \t]+" nil t) + (progn (beginning-of-line) (looking-at task-end-re))))))) + (defvar htmlp) ; dynamically scoped into the next function (defvar latexp) ; dynamically scoped into the next function (defun org-inlinetask-export-handler () diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-irc.el --- a/lisp/org/org-irc.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-irc.el Thu Nov 11 22:10:19 2010 -0600 @@ -4,7 +4,7 @@ ;; ;; Author: Philip Jackson <emacs@shellarchive.co.uk> ;; Keywords: erc, irc, link, org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-jsinfo.el --- a/lisp/org/org-jsinfo.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-jsinfo.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-latex.el --- a/lisp/org/org-latex.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-latex.el Thu Nov 11 22:10:19 2010 -0600 @@ -4,7 +4,7 @@ ;; ;; Emacs Lisp Archive Entry ;; Filename: org-latex.el -;; Version: 7.01 +;; Version: 7.3 ;; Author: Bastien Guerry <bzg AT altern DOT org> ;; Maintainer: Carsten Dominik <carsten.dominik AT gmail DOT com> ;; Keywords: org, wp, tex @@ -280,6 +280,11 @@ (string :tag "Keyword") (string :tag "Markup"))))) +(defcustom org-export-latex-tag-markup "\\textbf{%s}" + "Markup for tags, as a printf format." + :group 'org-export-latex + :type 'string) + (defcustom org-export-latex-timestamp-markup "\\textit{%s}" "A printf format string to be applied to time stamps." :group 'org-export-latex @@ -371,12 +376,30 @@ (require 'org-latex) (add-to-list 'org-export-latex-packages-alist '(\"\" \"listings\")) - (add-to-list 'org-export-latex-packages-alist '(\"\" \"color\"))" + (add-to-list 'org-export-latex-packages-alist '(\"\" \"color\")) + +Alternatively, + + (setq org-export-latex-listings 'minted) + +causes source code to be exported using the minted package as +opposed to listings. If you want to use minted, you need to add +the minted package to `org-export-latex-packages-alist', for +example using customize, or with + + (require 'org-latex) + (add-to-list 'org-export-latex-packages-alist '(\"\" \"minted\")) + +In addition, it is neccessary to install +pygments (http://pygments.org), and to configure +`org-latex-to-pdf-process' so that the -shell-escape option is +passed to pdflatex. +" :group 'org-export-latex :type 'boolean) (defcustom org-export-latex-listings-langs - '((emacs-lisp "Lisp") (lisp "Lisp") + '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp") (c "C") (cc "C++") (fortran "fortran") (perl "Perl") (cperl "Perl") (python "Python") (ruby "Ruby") @@ -398,6 +421,44 @@ (symbol :tag "Major mode ") (string :tag "Listings language")))) +(defcustom org-export-latex-listings-w-names t + "Non-nil means export names of named code blocks. +Code blocks exported with the listings package (controlled by the +`org-export-latex-listings' variable) can be named in the style +of noweb." + :group 'org-export-latex + :type 'boolean) + +(defcustom org-export-latex-minted-langs + '((emacs-lisp "common-lisp") + (cc "c++") + (cperl "perl") + (shell-script "bash") + (caml "ocaml")) + "Alist mapping languages to their minted language counterpart. +The key is a symbol, the major mode symbol without the \"-mode\". +The value is the string that should be inserted as the language parameter +for the minted package. If the mode name and the listings name are +the same, the language does not need an entry in this list - but it does not +hurt if it is present. + +Note that minted uses all lower case for language identifiers, +and that the full list of language identifiers can be obtained +with: +pygmentize -L lexers +" + :group 'org-export-latex + :type '(repeat + (list + (symbol :tag "Major mode ") + (string :tag "Listings language")))) + +(defcustom org-export-latex-minted-with-line-numbers nil + "Should source code line numbers be included when exporting +with the latex minted package?" + :group 'org-export-latex + :type 'boolean) + (defcustom org-export-latex-remove-from-headlines '(:todo nil :priority nil :tags nil) "A plist of keywords to remove from headlines. OBSOLETE. @@ -443,24 +504,53 @@ :group 'org-export) (defcustom org-latex-to-pdf-process - '("pdflatex -interaction nonstopmode %s" - "pdflatex -interaction nonstopmode %s") + '("pdflatex -interaction nonstopmode -output-directory %o %f" + "pdflatex -interaction nonstopmode -output-directory %o %f" + "pdflatex -interaction nonstopmode -output-directory %o %f") "Commands to process a LaTeX file to a PDF file. This is a list of strings, each of them will be given to the shell -as a command. %s in the command will be replaced by the full file name, %b -by the file base name (i.e. without extension). +as a command. %f in the command will be replaced by the full file name, %b +by the file base name (i.e. without extension) and %o by the base directory +of the file. + The reason why this is a list is that it usually takes several runs of -pdflatex, maybe mixed with a call to bibtex. Org does not have a clever +`pdflatex', maybe mixed with a call to `bibtex'. Org does not have a clever mechanism to detect which of these commands have to be run to get to a stable result, and it also does not do any error checking. +By default, Org uses 3 runs of `pdflatex' to do the processing. If you +have texi2dvi on your system and if that does not cause the infamous +egrep/locale bug: + + http://lists.gnu.org/archive/html/bug-texinfo/2010-03/msg00031.html + +then `texi2dvi' is the superior choice. Org does offer it as one +of the customize options. + Alternatively, this may be a Lisp function that does the processing, so you could use this to apply the machinery of AUCTeX or the Emacs LaTeX mode. This function should accept the file name as its single argument." :group 'org-export-pdf - :type '(choice (repeat :tag "Shell command sequence" + :type '(choice + (repeat :tag "Shell command sequence" (string :tag "Shell command")) - (function))) + (const :tag "2 runs of pdflatex" + ("pdflatex -interaction nonstopmode -output-directory %o %f" + "pdflatex -interaction nonstopmode -output-directory %o %f")) + (const :tag "3 runs of pdflatex" + ("pdflatex -interaction nonstopmode -output-directory %o %f" + "pdflatex -interaction nonstopmode -output-directory %o %f" + "pdflatex -interaction nonstopmode -output-directory %o %f")) + (const :tag "pdflatex,bibtex,pdflatex,pdflatex" + ("pdflatex -interaction nonstopmode -output-directory %o %f" + "bibtex %b" + "pdflatex -interaction nonstopmode -output-directory %o %f" + "pdflatex -interaction nonstopmode -output-directory %o %f")) + (const :tag "texi2dvi" + ("texi2dvi -p -b -c -V %f")) + (const :tag "rubber" + ("rubber -d --into %o %f")) + (function))) (defcustom org-export-pdf-logfiles '("aux" "idx" "log" "out" "toc" "nav" "snm" "vrb") @@ -832,9 +922,10 @@ (save-excursion (goto-char (point-min)) (re-search-forward "\\\\bibliography{" nil t)))) - cmd) + cmd output-dir errors) (with-current-buffer outbuf (erase-buffer)) - (message "Processing LaTeX file...") + (message (concat "Processing LaTeX file " file "...")) + (setq output-dir (file-name-directory file)) (if (and cmds (symbolp cmds)) (funcall cmds (shell-quote-argument file)) (while cmds @@ -844,23 +935,52 @@ (save-match-data (shell-quote-argument base)) t t cmd))) - (while (string-match "%s" cmd) + (while (string-match "%f" cmd) (setq cmd (replace-match (save-match-data (shell-quote-argument file)) t t cmd))) - (shell-command cmd outbuf outbuf))) - (message "Processing LaTeX file...done") + (while (string-match "%o" cmd) + (setq cmd (replace-match + (save-match-data + (shell-quote-argument output-dir)) + t t cmd))) + (shell-command cmd outbuf))) + (message (concat "Processing LaTeX file " file "...done")) + (setq errors (org-export-latex-get-error outbuf)) (if (not (file-exists-p pdffile)) - (error "PDF file was not produced") + (error (concat "PDF file " pdffile " was not produced" + (if errors (concat ":" errors "") ""))) (set-window-configuration wconfig) (when org-export-pdf-remove-logfiles (dolist (ext org-export-pdf-logfiles) (setq file (concat base "." ext)) (and (file-exists-p file) (delete-file file)))) - (message "Exporting to PDF...done") + (message (concat + "Exporting to PDF...done" + (if errors + (concat ", with some errors:" errors) + ""))) pdffile))) +(defun org-export-latex-get-error (buf) + "Collect the kinds of errors that remain in pdflatex processing." + (with-current-buffer buf + (save-excursion + (goto-char (point-max)) + (when (re-search-backward "^[ \t]*This is pdf.*?TeX.*?Version" nil t) + ;; OK, we are at the location of the final run + (let ((pos (point)) (errors "") (case-fold-search t)) + (if (re-search-forward "Reference.*?undefined" nil t) + (setq errors (concat errors " [undefined reference]"))) + (goto-char pos) + (if (re-search-forward "Citation.*?undefined" nil t) + (setq errors (concat errors " [undefined citation]"))) + (goto-char pos) + (if (re-search-forward "Undefined control sequence" nil t) + (setq errors (concat errors " [undefined control sequence]"))) + (and (org-string-nw-p errors) errors)))))) + ;;;###autoload (defun org-export-as-pdf-and-open (arg) "Export as LaTeX, then process through to PDF, and open." @@ -1158,7 +1278,7 @@ (plist-get opt-plist :latex-header-extra))) ;; append another special variable (org-export-apply-macros-in-string org-export-latex-append-header) - ;; define align if not yet defined + ;; define alert if not yet defined "\n\\providecommand{\\alert}[1]{\\textbf{#1}}" ;; insert the title (format @@ -1227,9 +1347,13 @@ '(:org-license-to-kill t)) (save-excursion (goto-char pt) - (while (re-search-forward "^[ \t]*#+.*\n?" limit t) - (remove-text-properties (match-beginning 0) (match-end 0) - '(:org-license-to-kill t)))))))))) + (while (re-search-forward "^[ \t]*#\\+.*\n?" limit t) + (let ((case-fold-search t)) + (unless (org-string-match-p + "^[ \t]*#\\+\\(attr_\\|caption\\>\\|label\\>\\)" + (match-string 0)) + (remove-text-properties (match-beginning 0) (match-end 0) + '(:org-license-to-kill t)))))))))))) (defvar org-export-latex-header-defs nil @@ -1310,13 +1434,13 @@ (replace-match "") (replace-match (format "\\textbf{%s}" (match-string 0)) t t))) ;; convert tags - (when (re-search-forward "\\(:[a-zA-Z0-9_@]+\\)+:" nil t) + (when (re-search-forward "\\(:[a-zA-Z0-9_@#%]+\\)+:" nil t) (if (or (not org-export-with-tags) (plist-get remove-list :tags)) (replace-match "") (replace-match (org-export-latex-protect-string - (format "\\textbf{%s}" + (format org-export-latex-tag-markup (save-match-data (replace-regexp-in-string "_" "\\\\_" (match-string 0))))) @@ -1589,7 +1713,7 @@ (org-table-last-column-widths (copy-sequence org-table-last-column-widths)) fnum fields line lines olines gr colgropen line-fmt align - caption shortn label attr floatp longtblp) + caption shortn label attr floatp placement longtblp) (if org-export-latex-tables-verbatim (let* ((tbl (concat "\\begin{verbatim}\n" raw-table "\\end{verbatim}\n"))) @@ -1609,7 +1733,12 @@ align (and attr (stringp attr) (string-match "\\<align=\\([^ \t\n\r]+\\)" attr) (match-string 1 attr)) - floatp (or caption label)) + floatp (or caption label) + placement (if (and attr + (stringp attr) + (string-match "[ \t]*\\<placement=\\(\\S-+\\)" attr)) + (match-string 1 attr) + "[htb]")) (setq caption (and caption (org-export-latex-fontify-headline caption))) (setq lines (org-split-string raw-table "\n")) (apply 'delete-region (list beg end)) @@ -1664,12 +1793,13 @@ (concat (if longtblp (concat "\\begin{longtable}{" align "}\n") - (if floatp "\\begin{table}[htb]\n")) + (if floatp (format "\\begin{table}%s\n" placement))) (if floatp (format - "\\caption%s{%s}" + "\\caption%s{%s} %s" (if shortn (concat "[" shortn "]") "") - (or caption ""))) + (or caption "") + (if label (format "\\label{%s}" label) ""))) (if (and longtblp caption) "\\\\\n" "\n") (if (and org-export-latex-tables-centered (not longtblp)) "\\begin{center}\n") @@ -1741,7 +1871,7 @@ (setq tbl (concat "\\begin{center}\n" tbl "\\end{center}"))) (when floatp (setq tbl (concat "\\begin{table}\n" - (format "\\caption%s{%s%s}\n" + (format "\\caption%s{%s}%s\n" (if shortn (format "[%s]" shortn) "") (if label (format "\\label{%s}" label) "") (or caption "")) @@ -2213,11 +2343,11 @@ "Convert plain text lists in current buffer into LaTeX lists." (let (res) (goto-char (point-min)) - (while (org-re-search-forward-unprotected org-list-beginning-re nil t) + (while (org-search-forward-unenclosed org-item-beginning-re nil t) (beginning-of-line) (setq res (org-list-to-latex (org-list-parse-list t) org-export-latex-list-parameters)) - (while (string-match "^\\(\\\\item[ \t]+\\)\\[@start:\\([0-9]+\\)\\]" + (while (string-match "^\\(\\\\item[ \t]+\\)\\[@\\(?:start:\\)?\\([0-9]+\\)\\]" res) (setq res (replace-match (concat (format "\\setcounter{enumi}{%d}" diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-list.el --- a/lisp/org/org-list.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-list.el Thu Nov 11 22:10:19 2010 -0600 @@ -7,7 +7,7 @@ ;; Bastien Guerry <bzg AT altern DOT org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -40,21 +40,31 @@ (defvar org-M-RET-may-split-line) (defvar org-complex-heading-regexp) (defvar org-odd-levels-only) +(defvar org-outline-regexp) +(defvar org-ts-regexp) +(defvar org-ts-regexp-both) (declare-function org-invisible-p "org" ()) (declare-function org-on-heading-p "org" (&optional invisible-ok)) (declare-function outline-next-heading "outline" ()) (declare-function org-back-to-heading "org" (&optional invisible-ok)) (declare-function org-back-over-empty-lines "org" ()) -(declare-function org-skip-whitespace "org" ()) (declare-function org-trim "org" (s)) (declare-function org-get-indentation "org" (&optional line)) (declare-function org-timer-item "org-timer" (&optional arg)) +(declare-function org-timer-hms-to-secs "org-timer" (hms)) (declare-function org-combine-plists "org" (&rest plists)) (declare-function org-entry-get "org" (pom property &optional inherit literal-nil)) (declare-function org-narrow-to-subtree "org" ()) (declare-function org-show-subtree "org" ()) +(declare-function org-in-regexps-block-p "org" + (start-re end-re &optional bound)) +(declare-function org-level-increment "org" ()) +(declare-function org-at-heading-p "org" (&optional ignored)) +(declare-function outline-previous-heading "outline" ()) +(declare-function org-icompleting-read "org" (&rest args)) +(declare-function org-time-string-to-seconds "org" (s)) (defgroup org-plain-lists nil "Options concerning plain lists in Org-mode." @@ -63,7 +73,6 @@ (defcustom org-cycle-include-plain-lists t "When t, make TAB cycle visibility on plain list items. - Cycling plain lists works only when the cursor is on a plain list item. When the cursor is on an outline heading, plain lists are treated as text. This is the most stable way of handling this, @@ -140,38 +149,88 @@ (defcustom org-list-two-spaces-after-bullet-regexp nil "A regular expression matching bullets that should have 2 spaces after them. When nil, no bullet will have two spaces after them. -When a string, it will be used as a regular expression. When the bullet -type of a list is changed, the new bullet type will be matched against this -regexp. If it matches, there will be two spaces instead of one after -the bullet in each item of he list." +When a string, it will be used as a regular expression. When the +bullet type of a list is changed, the new bullet type will be +matched against this regexp. If it matches, there will be two +spaces instead of one after the bullet in each item of the list." :group 'org-plain-lists :type '(choice (const :tag "never" nil) (regexp))) +(defcustom org-list-ending-method 'both + "Determine where plain lists should end. +Valid values are: `regexp', `indent' or `both'. + +When set to `regexp', Org will look into two variables, +`org-empty-line-terminates-plain-lists' and the more general +`org-list-end-regexp', to determine what will end lists. This is +the fastest method. + +When set to `indent', a list will end whenever a line following +an item, but not starting one, is less or equally indented than +it. + +When set to `both', each of the preceding methods is applied to +determine lists endings. This is the default method." + :group 'org-plain-lists + :type '(choice + (const :tag "With a regexp defining ending" regexp) + (const :tag "With indentation of regular (no bullet) text" indent) + (const :tag "With both methods" both))) + (defcustom org-empty-line-terminates-plain-lists nil "Non-nil means an empty line ends all plain list levels. -This is currently effective only during export. It should also have -an effect for indentation and plain list folding, but it does not. -When nil, empty lines are part of the preceding item." +This variable only makes sense if `org-list-ending-method' is set +to `regexp' or `both'. This is then equivalent to set +`org-list-end-regexp' to \"^[ \\t]*$\"." :group 'org-plain-lists :type 'boolean) -(defcustom org-auto-renumber-ordered-lists t - "Non-nil means automatically renumber ordered plain lists. -Renumbering happens when the sequence have been changed with -\\[org-shiftmetaup] or \\[org-shiftmetadown]. After other editing commands, -use \\[org-ctrl-c-ctrl-c] to trigger renumbering." +(defcustom org-list-end-regexp "^[ \t]*\n[ \t]*\n" + "Regexp matching the end of all plain list levels. +It must start with \"^\" and end with \"\\n\". It defaults to 2 +blank lines. `org-empty-line-terminates-plain-lists' has +precedence over it." :group 'org-plain-lists - :type 'boolean) + :type 'string) + +(defcustom org-list-automatic-rules '((bullet . t) + (checkbox . t) + (indent . t) + (insert . t)) + "Non-nil means apply set of rules when acting on lists. +By default, automatic actions are taken when using + \\[org-meta-return], \\[org-metaright], \\[org-metaleft], + \\[org-shiftmetaright], \\[org-shiftmetaleft], + \\[org-ctrl-c-minus], \\[org-toggle-checkbox] or + \\[org-insert-todo-heading]. You can disable individually these + rules by setting them to nil. Valid rules are: -(defcustom org-provide-checkbox-statistics t - "Non-nil means update checkbox statistics after insert and toggle. -When this is set, checkbox statistics is updated each time you -either insert a new checkbox with \\[org-insert-todo-heading] or -toggle a checkbox with \\[org-ctrl-c-ctrl-c]." - :group 'org-plain-lists - :type 'boolean) +bullet when non-nil, cycling bullet do not allow lists at + column 0 to have * as a bullet and descriptions lists + to be numbered. +checkbox when non-nil, checkbox statistics is updated each time + you either insert a new checkbox or toggle a checkbox. + It also prevents from inserting a checkbox in a + description item. +indent when non-nil, indenting or outdenting list top-item + with its subtree will move the whole list and + outdenting a list whose bullet is * to column 0 will + change that bullet to - +insert when non-nil, trying to insert an item inside a block + will insert it right before the block instead of + throwing an error." + :group 'org-plain-lists + :type '(alist :tag "Sets of rules" + :key-type + (choice + (const :tag "Bullet" bullet) + (const :tag "Checkbox" checkbox) + (const :tag "Indent" indent) + (const :tag "Insert" insert)) + :value-type + (boolean :tag "Activate" :value t))) (defcustom org-hierarchical-checkbox-statistics t "Non-nil means checkbox statistics counts only the state of direct children. @@ -188,9 +247,6 @@ :group 'org-plain-lists :type 'integer) -(defvar org-list-beginning-re - "^\\([ \t]*\\)\\([-+]\\|[0-9]+[.)]\\) +\\(.*\\)$") - (defcustom org-list-radio-list-templates '((latex-mode "% BEGIN RECEIVE ORGLST %n % END RECEIVE ORGLST %n @@ -218,9 +274,14 @@ (list (symbol :tag "Major mode") (string :tag "Format")))) -;;;; Plain list items, including checkboxes +;;; Internal functions -;;; Plain list items +(defun org-list-end-re () + "Return the regex corresponding to the end of a list. +It depends on `org-empty-line-terminates-plain-lists'." + (if org-empty-line-terminates-plain-lists + "^[ \t]*\n" + org-list-end-regexp)) (defun org-item-re (&optional general) "Return the correct regular expression for plain lists. @@ -228,19 +289,526 @@ of `org-plain-list-ordered-item-terminator'." (cond ((or general (eq org-plain-list-ordered-item-terminator t)) - "\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") + "\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)") ((= org-plain-list-ordered-item-terminator ?.) - "\\([ \t]*\\([-+]\\|\\([0-9]+\\.\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") + "\\([ \t]*\\([-+]\\|\\([0-9]+\\.\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)") ((= org-plain-list-ordered-item-terminator ?\)) - "\\([ \t]*\\([-+]\\|\\([0-9]+)\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") + "\\([ \t]*\\([-+]\\|\\([0-9]+)\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)") (t (error "Invalid value of `org-plain-list-ordered-item-terminator'")))) +(defconst org-item-beginning-re (concat "^" (org-item-re)) + "Regexp matching the beginning of a plain list item.") + +(defun org-list-ending-between (min max &optional firstp) + "Find the position of a list ending between MIN and MAX, or nil. +This function looks for `org-list-end-re' outside a block. + +If FIRSTP in non-nil, return the point at the beginning of the +nearest valid terminator from MIN. Otherwise, return the point at +the end of the nearest terminator from MAX." + (save-excursion + (let* ((start (if firstp min max)) + (end (if firstp max min)) + (search-fun (if firstp + #'org-search-forward-unenclosed + #'org-search-backward-unenclosed)) + (list-end-p (progn + (goto-char start) + (funcall search-fun (org-list-end-re) end t)))) + ;; Is there a valid list ending somewhere ? + (and list-end-p + ;; we want to be on the first line of the list ender + (match-beginning 0))))) + +(defun org-list-maybe-skip-block (search limit) + "Return non-nil value if point is in a block, skipping it on the way. +It looks for the boundary of the block in SEARCH direction, +stopping at LIMIT." + (save-match-data + (let ((case-fold-search t) + (boundary (if (eq search 're-search-forward) 3 5))) + (when (save-excursion + (and (funcall search "^[ \t]*#\\+\\(begin\\|end\\)_" limit t) + (= (length (match-string 1)) boundary))) + ;; We're in a block: get out of it + (goto-char (match-beginning 0)))))) + +(defun org-list-search-unenclosed-generic (search re bound noerr) + "Search a string outside blocks and protected places. +Arguments SEARCH, RE, BOUND and NOERR are similar to those in +`search-forward', `search-backward', `re-search-forward' and +`re-search-backward'." + (catch 'exit + (let ((origin (point))) + (while t + ;; 1. No match: return to origin or bound, depending on NOERR. + (unless (funcall search re bound noerr) + (throw 'exit (and (goto-char (if (memq noerr '(t nil)) origin bound)) + nil))) + ;; 2. Match not in block or protected: return point. Else + ;; skip the block and carry on. + (unless (or (get-text-property (match-beginning 0) 'org-protected) + (org-list-maybe-skip-block search bound)) + (throw 'exit (point))))))) + +(defun org-search-backward-unenclosed (regexp &optional bound noerror) + "Like `re-search-backward' but don't stop inside blocks or protected places. +Arguments REGEXP, BOUND and NOERROR are similar to those used in +`re-search-backward'." + (org-list-search-unenclosed-generic + #'re-search-backward regexp (or bound (point-min)) noerror)) + +(defun org-search-forward-unenclosed (regexp &optional bound noerror) + "Like `re-search-forward' but don't stop inside blocks or protected places. +Arguments REGEXP, BOUND and NOERROR are similar to those used in +`re-search-forward'." + (org-list-search-unenclosed-generic + #'re-search-forward regexp (or bound (point-max)) noerror)) + +(defun org-list-in-item-p-with-indent (limit) + "Is the cursor inside a plain list? +Plain lists are considered ending when a non-blank line is less +indented than the previous item within LIMIT." + (save-excursion + (beginning-of-line) + (cond + ;; do not start searching inside a block... + ((org-list-maybe-skip-block #'re-search-backward limit)) + ;; ... or at a blank line + ((looking-at "^[ \t]*$") + (skip-chars-backward " \r\t\n") + (beginning-of-line))) + (beginning-of-line) + (or (org-at-item-p) + (let* ((case-fold-search t) + (ind-ref (org-get-indentation)) + ;; Ensure there is at least an item above + (up-item-p (save-excursion + (org-search-backward-unenclosed + org-item-beginning-re limit t)))) + (and up-item-p + (catch 'exit + (while t + (cond + ((org-at-item-p) + (throw 'exit (< (org-get-indentation) ind-ref))) + ((looking-at "^[ \t]*$") + (skip-chars-backward " \r\t\n") + (beginning-of-line)) + ((looking-at "^[ \t]*#\\+end_") + (re-search-backward "^[ \t]*#\\+begin_")) + (t + (setq ind-ref (min (org-get-indentation) ind-ref)) + (forward-line -1)))))))))) + +(defun org-list-in-item-p-with-regexp (limit) + "Is the cursor inside a plain list? +Plain lists end when `org-list-end-regexp' is matched, or at a +blank line if `org-empty-line-terminates-plain-lists' is true. + +Argument LIMIT specifies the upper-bound of the search." + (save-excursion + (let* ((actual-pos (goto-char (point-at-eol))) + ;; Moved to eol so current line can be matched by + ;; `org-item-re'. + (last-item-start (save-excursion + (org-search-backward-unenclosed + org-item-beginning-re limit t))) + (list-ender (org-list-ending-between + last-item-start actual-pos))) + ;; We are in a list when we are on an item line or when we can + ;; find an item before point and there is no valid list ender + ;; between it and the point. + (and last-item-start (not list-ender))))) + +(defun org-list-top-point-with-regexp (limit) + "Return point at the top level item in a list. +Argument LIMIT specifies the upper-bound of the search. + +List ending is determined by regexp. See +`org-list-ending-method'. for more information." + (save-excursion + (let ((pos (point-at-eol))) + ;; Is there some list above this one ? If so, go to its ending. + ;; Otherwise, go back to the heading above or bob. + (goto-char (or (org-list-ending-between limit pos) limit)) + ;; From there, search down our list. + (org-search-forward-unenclosed org-item-beginning-re pos t) + (point-at-bol)))) + +(defun org-list-bottom-point-with-regexp (limit) + "Return point just before list ending. +Argument LIMIT specifies the lower-bound of the search. + +List ending is determined by regexp. See +`org-list-ending-method'. for more information." + (save-excursion + (let ((pos (org-get-item-beginning))) + ;; The list ending is either first point matching + ;; `org-list-end-re', point at first white-line before next + ;; heading, or eob. + (or (org-list-ending-between (min pos limit) limit t) limit)))) + +(defun org-list-top-point-with-indent (limit) + "Return point at the top level in a list. +Argument LIMIT specifies the upper-bound of the search. + +List ending is determined by indentation of text. See +`org-list-ending-method'. for more information." + (save-excursion + (let ((case-fold-search t)) + (let ((item-ref (goto-char (org-get-item-beginning))) + (ind-ref 10000)) + (forward-line -1) + (catch 'exit + (while t + (let ((ind (org-get-indentation))) + (cond + ((looking-at "^[ \t]*:END:") + (throw 'exit item-ref)) + ((<= (point) limit) + (throw 'exit + (if (and (org-at-item-p) (< ind ind-ref)) + (point-at-bol) + item-ref))) + ((looking-at "^[ \t]*$") + (skip-chars-backward " \r\t\n") + (beginning-of-line)) + ((looking-at "^[ \t]*#\\+end_") + (re-search-backward "^[ \t]*#\\+begin_")) + ((not (org-at-item-p)) + (setq ind-ref (min ind ind-ref)) + (forward-line -1)) + ((>= ind ind-ref) + (throw 'exit item-ref)) + (t + (setq item-ref (point-at-bol) ind-ref 10000) + (forward-line -1)))))))))) + +(defun org-list-bottom-point-with-indent (limit) + "Return point just before list ending or nil if not in a list. +Argument LIMIT specifies the lower-bound of the search. + +List ending is determined by the indentation of text. See +`org-list-ending-method' for more information." + (save-excursion + (let ((ind-ref (progn + (goto-char (org-get-item-beginning)) + (org-get-indentation))) + (case-fold-search t)) + ;; do not start inside a block + (org-list-maybe-skip-block #'re-search-forward limit) + (beginning-of-line) + (catch 'exit + (while t + (skip-chars-forward " \t") + (let ((ind (org-get-indentation))) + (cond + ((or (>= (point) limit) + (looking-at ":END:")) + (throw 'exit (progn + ;; Ensure bottom is just after a + ;; non-blank line. + (skip-chars-backward " \r\t\n") + (min (point-max) (1+ (point-at-eol)))))) + ((= (point) (point-at-eol)) + (skip-chars-forward " \r\t\n") + (beginning-of-line)) + ((org-at-item-p) + (setq ind-ref ind) + (forward-line 1)) + ((<= ind ind-ref) + (throw 'exit (point-at-bol))) + ((looking-at "#\\+begin_") + (re-search-forward "[ \t]*#\\+end_") + (forward-line 1)) + (t (forward-line 1))))))))) + +(defun org-list-at-regexp-after-bullet-p (regexp) + "Is point at a list item with REGEXP after bullet?" + (and (org-at-item-p) + (save-excursion + (goto-char (match-end 0)) + ;; Ignore counter if any + (when (looking-at "\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?") + (goto-char (match-end 0))) + (looking-at regexp)))) + +(defun org-list-get-item-same-level (search-fun pos limit pre-move) + "Return point at the beginning of next item at the same level. +Search items using function SEARCH-FUN, from POS to LIMIT. It +uses PRE-MOVE before search. Return nil if no item was found." + (save-excursion + (goto-char pos) + (let* ((start (org-get-item-beginning)) + (ind (progn (goto-char start) (org-get-indentation)))) + ;; We don't want to match the current line. + (funcall pre-move) + ;; Skip any sublist on the way + (while (and (funcall search-fun org-item-beginning-re limit t) + (> (org-get-indentation) ind))) + (when (and (/= (point-at-bol) start) ; Have we moved ? + (= (org-get-indentation) ind)) + (point-at-bol))))) + +(defun org-list-separating-blank-lines-number (pos top bottom) + "Return number of blank lines that should separate items in list. +POS is the position of point to be considered. + +TOP and BOTTOM are respectively position of list beginning and +list ending. + +Assume point is at item's beginning. If the item is alone, apply +some heuristics to guess the result." + (save-excursion + (let ((insert-blank-p + (cdr (assq 'plain-list-item org-blank-before-new-entry))) + usr-blank) + (cond + ;; Trivial cases where there should be none. + ((or (and (not (eq org-list-ending-method 'indent)) + org-empty-line-terminates-plain-lists) + (not insert-blank-p)) 0) + ;; When `org-blank-before-new-entry' says so, it is 1. + ((eq insert-blank-p t) 1) + ;; plain-list-item is 'auto. Count blank lines separating + ;; neighbours items in list. + (t (let ((next-p (org-get-next-item (point) bottom))) + (cond + ;; Is there a next item? + (next-p (goto-char next-p) + (org-back-over-empty-lines)) + ;; Is there a previous item? + ((org-get-previous-item (point) top) + (org-back-over-empty-lines)) + ;; User inserted blank lines, trust him + ((and (> pos (org-end-of-item-before-blank bottom)) + (> (save-excursion + (goto-char pos) + (skip-chars-backward " \t") + (setq usr-blank (org-back-over-empty-lines))) 0)) + usr-blank) + ;; Are there blank lines inside the item ? + ((save-excursion + (org-search-forward-unenclosed + "^[ \t]*$" (org-end-of-item-before-blank bottom) t)) 1) + ;; No parent: no blank line. + (t 0)))))))) + +(defun org-list-insert-item-generic (pos &optional checkbox after-bullet) + "Insert a new list item at POS. +If POS is before first character after bullet of the item, the +new item will be created before the current one. + +Insert a checkbox if CHECKBOX is non-nil, and string AFTER-BULLET +after the bullet. Cursor will be after this text once the +function ends." + (goto-char pos) + ;; Is point in a special block? + (when (org-in-regexps-block-p + "^[ \t]*#\\+\\(begin\\|BEGIN\\)_\\([a-zA-Z0-9_]+\\)" + '(concat "^[ \t]*#\\+\\(end\\|END\\)_" (match-string 2))) + (if (not (cdr (assq 'insert org-list-automatic-rules))) + ;; Rule in `org-list-automatic-rules' forbids insertion. + (error "Cannot insert item inside a block") + ;; Else, move before it prior to add a new item. + (end-of-line) + (re-search-backward "^[ \t]*#\\+\\(begin\\|BEGIN\\)_" nil t) + (end-of-line 0))) + (let* ((true-pos (point)) + (top (org-list-top-point)) + (bottom (copy-marker (org-list-bottom-point))) + (bullet (and (goto-char (org-get-item-beginning)) + (org-list-bullet-string (org-get-bullet)))) + (ind (org-get-indentation)) + (before-p (progn + ;; Description item: text starts after colons. + (or (org-at-item-description-p) + ;; At a checkbox: text starts after it. + (org-at-item-checkbox-p) + ;; Otherwise, text starts after bullet. + (org-at-item-p)) + (<= true-pos (match-end 0)))) + (blank-lines-nb (org-list-separating-blank-lines-number + true-pos top bottom)) + (insert-fun + (lambda (text) + ;; insert bullet above item in order to avoid bothering + ;; with possible blank lines ending last item. + (goto-char (org-get-item-beginning)) + (indent-to-column ind) + (insert (concat bullet (when checkbox "[ ] ") after-bullet)) + ;; Stay between after-bullet and before text. + (save-excursion + (insert (concat text (make-string (1+ blank-lines-nb) ?\n)))) + (unless before-p + ;; store bottom: exchanging items doesn't change list + ;; bottom point but will modify marker anyway + (setq bottom (marker-position bottom)) + (let ((col (current-column))) + (org-list-exchange-items + (org-get-item-beginning) (org-get-next-item (point) bottom) + bottom) + ;; recompute next-item: last sexp modified list + (goto-char (org-get-next-item (point) bottom)) + (org-move-to-column col))) + ;; checkbox update might modify bottom point, so use a + ;; marker here + (setq bottom (copy-marker bottom)) + (when checkbox (org-update-checkbox-count-maybe)) + (org-list-repair nil top bottom)))) + (goto-char true-pos) + (cond + (before-p (funcall insert-fun nil) t) + ;; Can't split item: insert bullet at the end of item. + ((not (org-get-alist-option org-M-RET-may-split-line 'item)) + (funcall insert-fun nil) t) + ;; else, insert a new bullet along with everything from point + ;; down to last non-blank line of item. + (t + (delete-horizontal-space) + ;; Get pos again in case previous command modified line. + (let* ((pos (point)) + (end-before-blank (org-end-of-item-before-blank bottom)) + (after-text + (when (< pos end-before-blank) + (prog1 + (delete-and-extract-region pos end-before-blank) + ;; delete any blank line at and before point. + (beginning-of-line) + (while (looking-at "^[ \t]*$") + (delete-region (point-at-bol) (1+ (point-at-eol))) + (beginning-of-line 0)))))) + (funcall insert-fun after-text) t))))) + +(defvar org-last-indent-begin-marker (make-marker)) +(defvar org-last-indent-end-marker (make-marker)) + +(defun org-list-indent-item-generic (arg no-subtree top bottom) + "Indent a local list item including its children. +When number ARG is a negative, item will be outdented, otherwise +it will be indented. + +If a region is active, all items inside will be moved. + +If NO-SUBTREE is non-nil, only indent the item itself, not its +children. + +TOP and BOTTOM are respectively position at item beginning and at +item ending. + +Return t if successful." + (let* ((regionp (org-region-active-p)) + (rbeg (and regionp (region-beginning))) + (rend (and regionp (region-end)))) + (cond + ((and regionp + (goto-char rbeg) + (not (org-search-forward-unenclosed org-item-beginning-re rend t))) + (error "No item in region")) + ((not (org-at-item-p)) + (error "Not on an item")) + (t + ;; Are we going to move the whole list? + (let* ((specialp (and (cdr (assq 'indent org-list-automatic-rules)) + (not no-subtree) + (= top (point-at-bol))))) + ;; Determine begin and end points of zone to indent. If moving + ;; more than one item, ensure we keep them on subsequent moves. + (unless (and (memq last-command '(org-shiftmetaright org-shiftmetaleft)) + (memq this-command '(org-shiftmetaright org-shiftmetaleft))) + (if regionp + (progn + (set-marker org-last-indent-begin-marker rbeg) + (set-marker org-last-indent-end-marker rend)) + (set-marker org-last-indent-begin-marker (point-at-bol)) + (set-marker org-last-indent-end-marker + (save-excursion + (cond + (specialp bottom) + (no-subtree (org-end-of-item-or-at-child bottom)) + (t (org-get-end-of-item bottom))))))) + ;; Get everything ready + (let* ((beg (marker-position org-last-indent-begin-marker)) + (end (marker-position org-last-indent-end-marker)) + (struct (org-list-struct + beg end top (if specialp end bottom) (< arg 0))) + (origins (org-list-struct-origins struct)) + (beg-item (assq beg struct))) + (cond + ;; Special case: moving top-item with indent rule + (specialp + (let* ((level-skip (org-level-increment)) + (offset (if (< arg 0) (- level-skip) level-skip)) + (top-ind (nth 1 beg-item))) + (if (< (+ top-ind offset) 0) + (error "Cannot outdent beyond margin") + ;; Change bullet if necessary + (when (and (= (+ top-ind offset) 0) + (string-match "*" (nth 2 beg-item))) + (setcdr beg-item (list (nth 1 beg-item) + (org-list-bullet-string "-")))) + ;; Shift ancestor + (let ((anc (car struct))) + (setcdr anc (list (+ (nth 1 anc) offset) "" nil))) + (org-list-struct-fix-struct struct origins) + (org-list-struct-apply-struct struct end)))) + ;; Forbidden move + ((and (< arg 0) + (or (and no-subtree + (not regionp) + (org-list-struct-get-child beg-item struct)) + (let ((last-item (save-excursion + (goto-char end) + (skip-chars-backward " \r\t\n") + (goto-char (org-get-item-beginning)) + (org-list-struct-assoc-at-point)))) + (org-list-struct-get-child last-item struct)))) + (error "Cannot outdent an item without its children")) + ;; Normal shifting + (t + (let* ((shifted-ori (if (< arg 0) + (org-list-struct-outdent beg end origins) + (org-list-struct-indent beg end origins struct)))) + (org-list-struct-fix-struct struct shifted-ori) + (org-list-struct-apply-struct struct bottom)))))))))) + +;;; Predicates + +(defun org-in-item-p () + "Is the cursor inside a plain list? +This checks `org-list-ending-method'." + (unless (let ((outline-regexp org-outline-regexp)) (org-at-heading-p)) + (let* ((prev-head (save-excursion (outline-previous-heading))) + (bound (if prev-head + (or (save-excursion + (let ((case-fold-search t)) + (re-search-backward "^[ \t]*:END:" prev-head t))) + prev-head) + (point-min)))) + (cond + ((eq org-list-ending-method 'regexp) + (org-list-in-item-p-with-regexp bound)) + ((eq org-list-ending-method 'indent) + (org-list-in-item-p-with-indent bound)) + (t (and (org-list-in-item-p-with-regexp bound) + (org-list-in-item-p-with-indent bound))))))) + +(defun org-list-first-item-p (top) + "Is this item the first item in a plain list? +Assume point is at an item. + +TOP is the position of list's top-item." + (save-excursion + (beginning-of-line) + (let ((ind (org-get-indentation))) + (or (not (org-search-backward-unenclosed org-item-beginning-re top t)) + (< (org-get-indentation) ind))))) + (defun org-at-item-p () "Is point in a line starting a hand-formatted item?" - (save-excursion - (goto-char (point-at-bol)) - (looking-at (org-item-re)))) + (beginning-of-line) (looking-at org-item-beginning-re))) (defun org-at-item-bullet-p () "Is point at the bullet of a plain list item?" @@ -248,170 +816,18 @@ (not (member (char-after) '(?\ ?\t))) (< (point) (match-end 0)))) -(defun org-in-item-p () - "Is the cursor inside a plain list item. -Does not have to be the first line." - (save-excursion - (condition-case nil - (progn - (org-beginning-of-item) - (org-at-item-p) - t) - (error nil)))) +(defun org-at-item-timer-p () + "Is point at a line starting a plain list item with a timer?" + (org-list-at-regexp-after-bullet-p + "\\([0-9]+:[0-9]+:[0-9]+\\)[ \t]+::[ \t]+")) -(defun org-insert-item (&optional checkbox) - "Insert a new item at the current level. -Return t when things worked, nil when we are not in an item." - (when (save-excursion - (condition-case nil - (progn - (org-beginning-of-item) - (org-at-item-p) - (if (org-invisible-p) (error "Invisible item")) - t) - (error nil))) - (let* ((bul (match-string 0)) - (descp (save-excursion (goto-char (match-beginning 0)) - (beginning-of-line 1) - (save-match-data - (and (looking-at "[ \t]*\\(.*?\\) ::") - (match-string 1))))) - (empty-line-p (save-excursion - (goto-char (match-beginning 0)) - (and (not (bobp)) - (or (beginning-of-line 0) t) - (save-match-data - (looking-at "[ \t]*$"))))) - (timerp (and descp - (save-match-data - (string-match "^[-+*][ \t]+[0-9]+:[0-9]+:[0-9]+$" - descp)))) - (eow (save-excursion (beginning-of-line 1) (looking-at "[ \t]*") - (match-end 0))) - (blank-a (if org-empty-line-terminates-plain-lists - nil - (cdr (assq 'plain-list-item org-blank-before-new-entry)))) - (blank (if (eq blank-a 'auto) empty-line-p blank-a)) - pos) - (if descp (setq checkbox nil)) - (if timerp - (progn (org-timer-item) t) - (cond - ((and (org-at-item-p) (<= (point) eow)) - ;; before the bullet - (beginning-of-line 1) - (open-line (if blank 2 1))) - ((<= (point) eow) - (beginning-of-line 1)) - (t - (unless (org-get-alist-option org-M-RET-may-split-line 'item) - (end-of-line 1) - (delete-horizontal-space)) - (newline (if blank 2 1)))) - (insert bul - (if checkbox "[ ]" "") - (if descp (concat (if checkbox " " "") - (read-string "Term: ") " :: ") "")) - (just-one-space) - (setq pos (point)) - (end-of-line 1) - (unless (= (point) pos) (just-one-space) (backward-delete-char 1))) - (org-maybe-renumber-ordered-list) - (and checkbox (org-update-checkbox-count-maybe)) - t))) - -;;; Checkboxes +(defun org-at-item-description-p () + "Is point at a description list item?" + (org-list-at-regexp-after-bullet-p "\\(\\S-.+\\)[ \t]+::[ \t]+")) (defun org-at-item-checkbox-p () "Is point at a line starting a plain-list item with a checklet?" - (and (org-at-item-p) - (save-excursion - (goto-char (match-end 0)) - (skip-chars-forward " \t") - (looking-at "\\[[- X]\\]")))) - -(defun org-toggle-checkbox (&optional toggle-presence) - "Toggle the checkbox in the current line. -With prefix arg TOGGLE-PRESENCE, add or remove checkboxes. -With double prefix, set checkbox to [-]. -When there is an active region, toggle status or presence of the checkbox -in the first line, and make every item in the region have the same -status or presence, respectively. -If the cursor is in a headline, apply this to all checkbox items in the -text below the heading." - (interactive "P") - (catch 'exit - (let (beg end status first-present first-status blocked) - (cond - ((org-region-active-p) - (setq beg (region-beginning) end (region-end))) - ((org-on-heading-p) - (setq beg (point) end (save-excursion (outline-next-heading) (point)))) - ((org-at-item-checkbox-p) - (save-excursion - (if (equal toggle-presence '(4)) - (progn - (replace-match "") - (goto-char (match-beginning 0)) - (just-one-space)) - (when (setq blocked (org-checkbox-blocked-p)) - (error "Checkbox blocked because of unchecked box in line %d" - blocked)) - (replace-match - (cond ((equal toggle-presence '(16)) "[-]") - ((member (match-string 0) '("[ ]" "[-]")) "[X]") - (t "[ ]")) - t t))) - (throw 'exit t)) - ((org-at-item-p) - ;; add a checkbox - (save-excursion - (goto-char (match-end 0)) - (insert "[ ] ")) - (throw 'exit t)) - (t (error "Not at a checkbox or heading, and no active region"))) - (setq end (move-marker (make-marker) end)) - (save-excursion - (goto-char beg) - (setq first-present (org-at-item-checkbox-p) - first-status - (save-excursion - (and (re-search-forward "[ \t]\\(\\[[ X]\\]\\)" end t) - (equal (match-string 1) "[X]")))) - (while (< (point) end) - (if toggle-presence - (cond - ((and first-present (org-at-item-checkbox-p)) - (save-excursion - (replace-match "") - (goto-char (match-beginning 0)) - (just-one-space))) - ((and (not first-present) (not (org-at-item-checkbox-p)) - (org-at-item-p)) - (save-excursion - (goto-char (match-end 0)) - (insert "[ ] ")))) - (when (org-at-item-checkbox-p) - (setq status (equal (match-string 0) "[X]")) - (replace-match - (if first-status "[ ]" "[X]") t t))) - (beginning-of-line 2))))) - (org-update-checkbox-count-maybe)) - -(defun org-reset-checkbox-state-subtree () - "Reset all checkboxes in an entry subtree." - (interactive "*") - (save-restriction - (save-excursion - (org-narrow-to-subtree) - (org-show-subtree) - (goto-char (point-min)) - (let ((end (point-max))) - (while (< (point) end) - (when (org-at-item-checkbox-p) - (replace-match "[ ]" t t)) - (beginning-of-line 2)))) - (org-update-checkbox-count-maybe))) + (org-list-at-regexp-after-bullet-p "\\(\\[[- X]\\]\\)[ \t]+")) (defun org-checkbox-blocked-p () "Is the current checkbox blocked from for being checked now? @@ -424,417 +840,621 @@ (save-match-data (save-excursion (unless (org-at-item-checkbox-p) (throw 'exit nil)) - (when (equal (match-string 0) "[X]") + (when (equal (match-string 1) "[X]") ;; the box is already checked! (throw 'exit nil)) (let ((end (point-at-bol))) (condition-case nil (org-back-to-heading t) (error (throw 'exit nil))) (unless (org-entry-get nil "ORDERED") (throw 'exit nil)) - (if (re-search-forward "^[ \t]*[-+*0-9.)] \\[[- ]\\]" end t) - (org-current-line) - nil)))))) + (when (org-search-forward-unenclosed + "^[ \t]*[-+*0-9.)]+[ \t]+\\(\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[[- ]\\]" end t) + (org-current-line))))))) + +;;; Navigate -(defvar org-checkbox-statistics-hook nil - "Hook that is run whenever Org thinks checkbox statistics should be updated. -This hook runs even if `org-provide-checkbox-statistics' is nil, to it can -be used to implement alternative ways of collecting statistics information.") +;; Every interactive navigation function is derived from a +;; non-interactive one, which doesn't move point, assumes point is +;; already in a list and doesn't compute list boundaries. -(defun org-update-checkbox-count-maybe () - "Update checkbox statistics unless turned off by user." - (when org-provide-checkbox-statistics - (org-update-checkbox-count)) - (run-hooks 'org-checkbox-statistics-hook)) +;; If you plan to use more than one org-list function is some code, +;; you should therefore first check if point is in a list with +;; `org-in-item-p' or `org-at-item-p', then compute list boundaries +;; with `org-list-top-point' and `org-list-bottom-point', and make use +;; of non-interactive forms. -(defun org-update-checkbox-count (&optional all) - "Update the checkbox statistics in the current section. -This will find all statistic cookies like [57%] and [6/12] and update them -with the current numbers. With optional prefix argument ALL, do this for -the whole buffer." - (interactive "P") - (save-excursion - (let* ((buffer-invisibility-spec (org-inhibit-invisibility)) ; Emacs 21 - (beg (condition-case nil - (progn (org-back-to-heading) (point)) - (error (point-min)))) - (end (move-marker (make-marker) - (progn (outline-next-heading) (point)))) - (re "\\(\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)") - (re-box "^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[- X]\\]\\)") - (re-find (concat re "\\|" re-box)) - beg-cookie end-cookie is-percent c-on c-off lim new - eline curr-ind next-ind continue-from startsearch - (recursive - (or (not org-hierarchical-checkbox-statistics) - (string-match "\\<recursive\\>" - (or (ignore-errors - (org-entry-get nil "COOKIE_DATA")) - "")))) - (cstat 0) - ) - (when all - (goto-char (point-min)) - (outline-next-heading) - (setq beg (point) end (point-max))) - (goto-char end) - ;; find each statistics cookie - (while (and (re-search-backward re-find beg t) - (not (save-match-data - (and (org-on-heading-p) - (string-match "\\<todo\\>" - (downcase - (or (org-entry-get - nil "COOKIE_DATA") - ""))))))) - (setq beg-cookie (match-beginning 1) - end-cookie (match-end 1) - cstat (+ cstat (if end-cookie 1 0)) - startsearch (point-at-eol) - continue-from (match-beginning 0) - is-percent (match-beginning 2) - lim (cond - ((org-on-heading-p) (outline-next-heading) (point)) - ((org-at-item-p) (org-end-of-item) (point)) - (t nil)) - c-on 0 - c-off 0) - (when lim - ;; find first checkbox for this cookie and gather - ;; statistics from all that are at this indentation level - (goto-char startsearch) - (if (re-search-forward re-box lim t) - (progn - (org-beginning-of-item) - (setq curr-ind (org-get-indentation)) - (setq next-ind curr-ind) - (while (and (bolp) (org-at-item-p) - (if recursive - (<= curr-ind next-ind) - (= curr-ind next-ind))) - (save-excursion (end-of-line) (setq eline (point))) - (if (re-search-forward re-box eline t) - (if (member (match-string 2) '("[ ]" "[-]")) - (setq c-off (1+ c-off)) - (setq c-on (1+ c-on)))) - (if (not recursive) - (org-end-of-item) - (end-of-line) - (when (re-search-forward org-list-beginning-re lim t) - (beginning-of-line))) - (setq next-ind (org-get-indentation))))) - (goto-char continue-from) - ;; update cookie - (when end-cookie - (setq new (if is-percent - (format "[%d%%]" (/ (* 100 c-on) (max 1 (+ c-on c-off)))) - (format "[%d/%d]" c-on (+ c-on c-off)))) - (goto-char beg-cookie) - (insert new) - (delete-region (point) (+ (point) (- end-cookie beg-cookie)))) - ;; update items checkbox if it has one - (when (org-at-item-p) - (org-beginning-of-item) - (when (and (> (+ c-on c-off) 0) - (re-search-forward re-box (point-at-eol) t)) - (setq beg-cookie (match-beginning 2) - end-cookie (match-end 2)) - (delete-region beg-cookie end-cookie) - (goto-char beg-cookie) - (cond ((= c-off 0) (insert "[X]")) - ((= c-on 0) (insert "[ ]")) - (t (insert "[-]"))) - ))) - (goto-char continue-from)) - (when (interactive-p) - (message "Checkbox statistics updated %s (%d places)" - (if all "in entire file" "in current outline entry") cstat))))) +(defun org-list-top-point () + "Return point at the top level in a list. +Assume point is in a list." + (let* ((prev-head (save-excursion (outline-previous-heading))) + (bound (if prev-head + (or (save-excursion + (let ((case-fold-search t)) + (re-search-backward "^[ \t]*:END:" prev-head t))) + prev-head) + (point-min)))) + (cond + ((eq org-list-ending-method 'regexp) + (org-list-top-point-with-regexp bound)) + ((eq org-list-ending-method 'indent) + (org-list-top-point-with-indent bound)) + (t (let ((top-re (org-list-top-point-with-regexp bound))) + (org-list-top-point-with-indent (or top-re bound))))))) -(defun org-get-checkbox-statistics-face () - "Select the face for checkbox statistics. -The face will be `org-done' when all relevant boxes are checked. Otherwise -it will be `org-todo'." - (if (match-end 1) - (if (equal (match-string 1) "100%") - 'org-checkbox-statistics-done - 'org-checkbox-statistics-todo) - (if (and (> (match-end 2) (match-beginning 2)) - (equal (match-string 2) (match-string 3))) - 'org-checkbox-statistics-done - 'org-checkbox-statistics-todo))) +(defun org-list-bottom-point () + "Return point just before list ending. +Assume point is in a list." + (let* ((next-head (save-excursion + (and (let ((outline-regexp org-outline-regexp)) + ;; Use default regexp because folding + ;; changes OUTLINE-REGEXP. + (outline-next-heading))))) + (limit (or (save-excursion + (and (re-search-forward "^[ \t]*:END:" next-head t) + (point-at-bol))) + next-head + (point-max)))) + (cond + ((eq org-list-ending-method 'regexp) + (org-list-bottom-point-with-regexp limit)) + ((eq org-list-ending-method 'indent) + (org-list-bottom-point-with-indent limit)) + (t (let ((bottom-re (org-list-bottom-point-with-regexp limit))) + (org-list-bottom-point-with-indent (or bottom-re limit))))))) + +(defun org-get-item-beginning () + "Return position of current item beginning." + (save-excursion + ;; possibly match current line + (end-of-line) + (org-search-backward-unenclosed org-item-beginning-re nil t) + (point-at-bol))) (defun org-beginning-of-item () "Go to the beginning of the current hand-formatted item. If the cursor is not in an item, throw an error." (interactive) - (let ((pos (point)) - (limit (save-excursion - (condition-case nil - (progn - (org-back-to-heading) - (beginning-of-line 2) (point)) - (error (point-min))))) - (ind-empty (if org-empty-line-terminates-plain-lists 0 10000)) - ind ind1) - (if (org-at-item-p) - (beginning-of-line 1) - (beginning-of-line 1) - (skip-chars-forward " \t") - (setq ind (current-column)) - (if (catch 'exit - (while t - (beginning-of-line 0) - (if (or (bobp) (< (point) limit)) (throw 'exit nil)) + (if (org-in-item-p) + (goto-char (org-get-item-beginning)) + (error "Not in an item"))) + +(defun org-get-beginning-of-list (top) + "Return position of the first item of the current list or sublist. +TOP is the position at list beginning." + (save-excursion + (let (prev-p) + (while (setq prev-p (org-get-previous-item (point) top)) + (goto-char prev-p)) + (point-at-bol)))) + +(defun org-beginning-of-item-list () + "Go to the beginning item of the current list or sublist. +Return an error if not in a list." + (interactive) + (if (org-in-item-p) + (goto-char (org-get-beginning-of-list (org-list-top-point))) + (error "Not in an item"))) - (if (looking-at "[ \t]*$") - (setq ind1 ind-empty) - (skip-chars-forward " \t") - (setq ind1 (current-column))) - (if (< ind1 ind) - (progn (beginning-of-line 1) (throw 'exit (org-at-item-p)))))) - nil - (goto-char pos) - (error "Not in an item"))))) +(defun org-get-end-of-list (bottom) + "Return position at the end of the current list or sublist. +BOTTOM is the position at list ending." + (save-excursion + (goto-char (org-get-item-beginning)) + (let ((ind (org-get-indentation))) + (while (and (/= (point) bottom) + (>= (org-get-indentation) ind)) + (org-search-forward-unenclosed org-item-beginning-re bottom 'move)) + (if (= (point) bottom) bottom (point-at-bol))))) + +(defun org-end-of-item-list () + "Go to the end of the current list or sublist. +If the cursor in not in an item, throw an error." + (interactive) + (if (org-in-item-p) + (goto-char (org-get-end-of-list (org-list-bottom-point))) + (error "Not in an item"))) + +(defun org-get-end-of-item (bottom) + "Return position at the end of the current item. +BOTTOM is the position at list ending." + (or (org-get-next-item (point) bottom) + (org-get-end-of-list bottom))) (defun org-end-of-item () "Go to the end of the current hand-formatted item. If the cursor is not in an item, throw an error." (interactive) - (let* ((pos (point)) - ind1 - (ind-empty (if org-empty-line-terminates-plain-lists 0 10000)) - (limit (save-excursion (outline-next-heading) (point))) - (ind (save-excursion - (org-beginning-of-item) - (skip-chars-forward " \t") - (current-column))) - (end (catch 'exit - (while t - (beginning-of-line 2) - (if (eobp) (throw 'exit (point))) - (if (>= (point) limit) (throw 'exit (point-at-bol))) - (if (looking-at "[ \t]*$") - (setq ind1 ind-empty) - (skip-chars-forward " \t") - (setq ind1 (current-column))) - (if (<= ind1 ind) - (throw 'exit (point-at-bol))))))) - (if end - (goto-char end) - (goto-char pos) - (error "Not in an item")))) + (if (org-in-item-p) + (goto-char (org-get-end-of-item (org-list-bottom-point))) + (error "Not in an item"))) + +(defun org-end-of-item-or-at-child (bottom) + "Move to the end of the item, stops before the first child if any. +BOTTOM is the position at list ending." + (end-of-line) + (goto-char + (if (org-search-forward-unenclosed org-item-beginning-re bottom t) + (point-at-bol) + (org-get-end-of-item bottom)))) + +(defun org-end-of-item-before-blank (bottom) + "Return point at end of item, before any blank line. +Point returned is at eol. -(defun org-end-of-item-text-before-children () - "Move to the end of the item text, stops before the first child if any. -Assumes that the cursor is in the first line of an item." - (goto-char - (min (save-excursion (org-end-of-item) (point)) - (save-excursion - (goto-char (point-at-eol)) - (if (re-search-forward (concat "^" (org-item-re t)) nil 'move) - (match-beginning 0) - (point-max)))))) +BOTTOM is the position at list ending." + (save-excursion + (goto-char (org-get-end-of-item bottom)) + (skip-chars-backward " \r\t\n") + (point-at-eol))) + +(defun org-get-previous-item (pos limit) + "Return point of the previous item at the same level as POS. +Stop searching at LIMIT. Return nil if no item is found." + (org-list-get-item-same-level + #'org-search-backward-unenclosed pos limit #'beginning-of-line)) + +(defun org-previous-item () + "Move to the beginning of the previous item. +Item is at the same level in the current plain list. Error if not +in a plain list, or if this is the first item in the list." + (interactive) + (if (not (org-in-item-p)) + (error "Not in an item") + (let ((prev-p (org-get-previous-item (point) (org-list-top-point)))) + (if prev-p (goto-char prev-p) (error "On first item"))))) + +(defun org-get-next-item (pos limit) + "Return point of the next item at the same level as POS. +Stop searching at LIMIT. Return nil if no item is found." + (org-list-get-item-same-level + #'org-search-forward-unenclosed pos limit #'end-of-line)) (defun org-next-item () - "Move to the beginning of the next item in the current plain list. -Error if not at a plain list, or if this is the last item in the list." - (interactive) - (let (ind ind1 (pos (point))) - (org-beginning-of-item) - (setq ind (org-get-indentation)) - (org-end-of-item) - (setq ind1 (org-get-indentation)) - (unless (and (org-at-item-p) (= ind ind1)) - (goto-char pos) - (error "On last item")))) - -(defun org-previous-item () - "Move to the beginning of the previous item in the current plain list. -Error if not at a plain list, or if this is the first item in the list." + "Move to the beginning of the next item. +Item is at the same level in the current plain list. Error if not +in a plain list, or if this is the last item in the list." (interactive) - (let (beg ind ind1 (pos (point))) - (org-beginning-of-item) - (setq beg (point)) - (setq ind (org-get-indentation)) - (goto-char beg) - (catch 'exit - (while t - (beginning-of-line 0) - (if (looking-at "[ \t]*$") - nil - (if (<= (setq ind1 (org-get-indentation)) ind) - (throw 'exit t))) - (if (bobp) (throw 'exit t)))) - (condition-case nil - (if (or (not (org-at-item-p)) - (< ind1 (1- ind))) - (error "") - (org-beginning-of-item)) - (error (goto-char pos) - (error "On first item"))))) + (if (not (org-in-item-p)) + (error "Not in an item") + (let ((next-p (org-get-next-item (point) (org-list-bottom-point)))) + (if next-p (goto-char next-p) (error "On last item"))))) + +;;; Manipulate + +(defun org-list-exchange-items (beg-A beg-B bottom) + "Swap item starting at BEG-A with item starting at BEG-B. +Blank lines at the end of items are left in place. Assume BEG-A +is lesser than BEG-B. -(defun org-first-list-item-p () - "Is this heading the first item in a plain list?" - (unless (org-at-item-p) - (error "Not at a plain list item")) +BOTTOM is the position at list ending." (save-excursion - (org-beginning-of-item) - (= (point) (save-excursion (org-beginning-of-item-list))))) + (let* ((end-of-item-no-blank + (lambda (pos) + (goto-char pos) + (goto-char (org-end-of-item-before-blank bottom)))) + (end-A-no-blank (funcall end-of-item-no-blank beg-A)) + (end-B-no-blank (funcall end-of-item-no-blank beg-B)) + (body-A (buffer-substring beg-A end-A-no-blank)) + (body-B (buffer-substring beg-B end-B-no-blank)) + (between-A-no-blank-and-B (buffer-substring end-A-no-blank beg-B))) + (goto-char beg-A) + (delete-region beg-A end-B-no-blank) + (insert (concat body-B between-A-no-blank-and-B body-A))))) (defun org-move-item-down () "Move the plain list item at point down, i.e. swap with following item. Subitems (items with larger indentation) are considered part of the item, so this really moves item trees." (interactive) - (let ((col (current-column)) - (pos (point)) - beg beg0 end end0 ind ind1 txt ne-end ne-beg) - (org-beginning-of-item) - (setq beg0 (point)) - (save-excursion - (setq ne-beg (org-back-over-empty-lines)) - (setq beg (point))) - (goto-char beg0) - (setq ind (org-get-indentation)) - (org-end-of-item) - (setq end0 (point)) - (setq ind1 (org-get-indentation)) - (setq ne-end (org-back-over-empty-lines)) - (setq end (point)) - (goto-char beg0) - (when (and (org-first-list-item-p) (< ne-end ne-beg)) - ;; include less whitespace - (save-excursion - (goto-char beg) - (forward-line (- ne-beg ne-end)) - (setq beg (point)))) - (goto-char end0) - (if (and (org-at-item-p) (= ind ind1)) - (progn - (org-end-of-item) - (org-back-over-empty-lines) - (setq txt (buffer-substring beg end)) - (save-excursion - (delete-region beg end)) - (setq pos (point)) - (insert txt) - (goto-char pos) (org-skip-whitespace) - (org-maybe-renumber-ordered-list) - (move-to-column col)) - (goto-char pos) - (move-to-column col) - (error "Cannot move this item further down")))) + (if (not (org-at-item-p)) + (error "Not at an item") + (let* ((pos (point)) + (col (current-column)) + (bottom (org-list-bottom-point)) + (actual-item (goto-char (org-get-item-beginning))) + (next-item (org-get-next-item (point) bottom))) + (if (not next-item) + (progn + (goto-char pos) + (error "Cannot move this item further down")) + (org-list-exchange-items actual-item next-item bottom) + (org-list-repair nil nil bottom) + (goto-char (org-get-next-item (point) bottom)) + (move-to-column col))))) -(defun org-move-item-up (arg) +(defun org-move-item-up () "Move the plain list item at point up, i.e. swap with previous item. Subitems (items with larger indentation) are considered part of the item, so this really moves item trees." - (interactive "p") - (let ((col (current-column)) (pos (point)) - beg beg0 end ind ind1 txt - ne-beg ne-ins ins-end) - (org-beginning-of-item) - (setq beg0 (point)) - (setq ind (org-get-indentation)) - (save-excursion - (setq ne-beg (org-back-over-empty-lines)) - (setq beg (point))) - (goto-char beg0) - (org-end-of-item) - (org-back-over-empty-lines) - (setq end (point)) - (goto-char beg0) - (catch 'exit - (while t - (beginning-of-line 0) - (if (looking-at "[ \t]*$") - (if org-empty-line-terminates-plain-lists - (progn - (goto-char pos) - (error "Cannot move this item further up")) - nil) - (if (<= (setq ind1 (org-get-indentation)) ind) - (throw 'exit t))))) - (condition-case nil - (org-beginning-of-item) - (error (goto-char beg0) - (move-to-column col) - (error "Cannot move this item further up"))) - (setq ind1 (org-get-indentation)) - (if (and (org-at-item-p) (= ind ind1)) - (progn - (setq ne-ins (org-back-over-empty-lines)) - (setq txt (buffer-substring beg end)) - (save-excursion - (delete-region beg end)) - (setq pos (point)) - (insert txt) - (setq ins-end (point)) - (goto-char pos) (org-skip-whitespace) + (interactive) + (if (not (org-at-item-p)) + (error "Not at an item") + (let* ((pos (point)) + (col (current-column)) + (top (org-list-top-point)) + (bottom (org-list-bottom-point)) + (actual-item (goto-char (org-get-item-beginning))) + (prev-item (org-get-previous-item (point) top))) + (if (not prev-item) + (progn + (goto-char pos) + (error "Cannot move this item further up")) + (org-list-exchange-items prev-item actual-item bottom) + (org-list-repair nil top bottom) + (move-to-column col))))) + +(defun org-insert-item (&optional checkbox) + "Insert a new item at the current level. +If cursor is before first character after bullet of the item, the +new item will be created before the current one. + +If CHECKBOX is non-nil, add a checkbox next to the bullet. + +Return t when things worked, nil when we are not in an item, or +item is invisible." + (unless (or (not (org-in-item-p)) + (save-excursion + (goto-char (org-get-item-beginning)) + (org-invisible-p))) + (if (save-excursion + (goto-char (org-get-item-beginning)) + (org-at-item-timer-p)) + ;; Timer list: delegate to `org-timer-item'. + (progn (org-timer-item) t) + ;; if we're in a description list, ask for the new term. + (let ((desc-text (when (save-excursion + (and (goto-char (org-get-item-beginning)) + (org-at-item-description-p))) + (concat (read-string "Term: ") " :: ")))) + ;; Don't insert a checkbox if checkbox rule is applied and it + ;; is a description item. + (org-list-insert-item-generic + (point) (and checkbox + (or (not desc-text) + (not (cdr (assq 'checkbox org-list-automatic-rules))))) + desc-text))))) + +;;; Structures + +;; The idea behind structures is to avoid moving back and forth in the +;; buffer on costly operations like indenting or fixing bullets. + +;; It achieves this by taking a snapshot of an interesting part of the +;; list, in the shape of an alist, using `org-list-struct'. + +;; It then proceeds to changes directly on the alist, with the help of +;; and `org-list-struct-origins'. When those are done, +;; `org-list-struct-apply-struct' applies the changes to the buffer. + +(defun org-list-struct-assoc-at-point () + "Return the structure association at point. +It is a cons-cell whose key is point and values are indentation, +bullet string and bullet counter, if any." + (save-excursion + (beginning-of-line) + (list (point-at-bol) + (org-get-indentation) + (progn + (looking-at "^[ \t]*\\([-+*0-9.)]+[ \t]+\\)") + (match-string 1)) + (progn + (goto-char (match-end 0)) + (and (looking-at "\\[@\\(?:start:\\)?\\([0-9]+\\)\\]") + (match-string 1)))))) + +(defun org-list-struct (begin end top bottom &optional outdent) + "Return the structure containing the list between BEGIN and END. +A structure is an alist where key is point of item and values +are, in that order, indentation, bullet string and value of +counter, if any. A structure contains every list and sublist that +has items between BEGIN and END along with their common ancestor. +If no such ancestor can be found, the function will add a virtual +ancestor at position 0. + +TOP and BOTTOM are respectively the position of list beginning +and list ending. - (when (and (org-first-list-item-p) (> ne-ins ne-beg)) - ;; Move whitespace back to beginning - (save-excursion - (goto-char ins-end) - (let ((kill-whole-line t)) - (kill-line (- ne-ins ne-beg)) (point))) - (insert (make-string (- ne-ins ne-beg) ?\n))) +If OUTDENT is non-nil, it will also grab all of the parent list +and the grand-parent. Setting OUTDENT to t is mandatory when next +change is an outdent." + (save-excursion + (let* (struct + (extend + (lambda (struct) + (let* ((ind-min (apply 'min (mapcar 'cadr struct))) + (begin (caar struct)) + (end (caar (last struct))) + pre-list post-list) + (goto-char begin) + ;; Find beginning of most outdented list (min list) + (while (and (org-search-backward-unenclosed + org-item-beginning-re top t) + (>= (org-get-indentation) ind-min)) + (setq pre-list (cons (org-list-struct-assoc-at-point) + pre-list))) + ;; Now get the parent. If none, add a virtual ancestor + (if (< (org-get-indentation) ind-min) + (setq pre-list (cons (org-list-struct-assoc-at-point) + pre-list)) + (setq pre-list (cons (list 0 (org-get-indentation) "" nil) + pre-list))) + ;; Find end of min list + (goto-char end) + (end-of-line) + (while (and (org-search-forward-unenclosed + org-item-beginning-re bottom 'move) + (>= (org-get-indentation) ind-min)) + (setq post-list (cons (org-list-struct-assoc-at-point) + post-list))) + ;; Is list is malformed? If some items are less + ;; indented that top-item, add them anyhow. + (when (and (= (caar pre-list) 0) (< (point) bottom)) + (beginning-of-line) + (while (org-search-forward-unenclosed + org-item-beginning-re bottom t) + (setq post-list (cons (org-list-struct-assoc-at-point) + post-list)))) + (append pre-list struct (reverse post-list)))))) + ;; Here we start: first get the core zone... + (goto-char end) + (while (org-search-backward-unenclosed org-item-beginning-re begin t) + (setq struct (cons (org-list-struct-assoc-at-point) struct))) + ;; ... then, extend it to make it a structure... + (let ((extended (funcall extend struct))) + ;; ... twice when OUTDENT is non-nil and struct still can be + ;; extended + (if (and outdent (> (caar extended) 0)) + (funcall extend extended) + extended))))) + +(defun org-list-struct-origins (struct) + "Return an alist where key is item's position and value parent's. +STRUCT is the list's structure looked up." + (let* ((struct-rev (reverse struct)) + (acc (list (cons (nth 1 (car struct)) 0))) + (prev-item (lambda (item) + (car (nth 1 (member (assq item struct) struct-rev))))) + (get-origins + (lambda (item) + (let* ((item-pos (car item)) + (ind (nth 1 item)) + (prev-ind (caar acc))) + (cond + ;; List closing. + ((> prev-ind ind) + (let ((current-origin (or (member (assq ind acc) acc) + ;; needed if top-point is + ;; not the most outdented + (last acc)))) + (setq acc current-origin) + (cons item-pos (cdar acc)))) + ;; New list + ((< prev-ind ind) + (let ((origin (funcall prev-item item-pos))) + (setq acc (cons (cons ind origin) acc)) + (cons item-pos origin))) + ;; Current list going on + (t (cons item-pos (cdar acc)))))))) + (cons '(0 . 0) (mapcar get-origins (cdr struct))))) + +(defun org-list-struct-get-parent (item struct origins) + "Return parent association of ITEM in STRUCT or nil. +ORIGINS is the alist of parents. See `org-list-struct-origins'." + (let* ((parent-pos (cdr (assq (car item) origins)))) + (when (> parent-pos 0) (assq parent-pos struct)))) + +(defun org-list-struct-get-child (item struct) + "Return child association of ITEM in STRUCT or nil." + (let ((ind (nth 1 item)) + (next-item (cadr (member item struct)))) + (when (and next-item (> (nth 1 next-item) ind)) next-item))) + +(defun org-list-struct-fix-bul (struct origins) + "Verify and correct bullets for every association in STRUCT. +ORIGINS is the alist of parents. See `org-list-struct-origins'. - (org-maybe-renumber-ordered-list) - (move-to-column col)) - (goto-char pos) - (move-to-column col) - (error "Cannot move this item further up")))) +This function modifies STRUCT." + (let* (acc + (init-bul (lambda (item) + (let ((counter (nth 3 item)) + (bullet (org-list-bullet-string (nth 2 item)))) + (cond + ((and (string-match "[0-9]+" bullet) counter) + (replace-match counter nil nil bullet)) + ((string-match "[0-9]+" bullet) + (replace-match "1" nil nil bullet)) + (t bullet))))) + (set-bul (lambda (item bullet) + (setcdr item (list (nth 1 item) bullet (nth 3 item))))) + (get-bul (lambda (item bullet) + (let* ((counter (nth 3 item))) + (if (and counter (string-match "[0-9]+" bullet)) + (replace-match counter nil nil bullet) + bullet)))) + (fix-bul + (lambda (item) struct + (let* ((parent (cdr (assq (car item) origins))) + (orig-ref (assq parent acc))) + (if orig-ref + ;; Continuing previous list + (let* ((prev-bul (cdr orig-ref)) + (new-bul (funcall get-bul item prev-bul))) + (setcdr orig-ref (org-list-inc-bullet-maybe new-bul)) + (funcall set-bul item new-bul)) + ;; A new list is starting + (let ((new-bul (funcall init-bul item))) + (funcall set-bul item new-bul) + (setq acc (cons (cons parent + (org-list-inc-bullet-maybe new-bul)) + acc)))))))) + (mapc fix-bul (cdr struct)))) + +(defun org-list-struct-fix-ind (struct origins) + "Verify and correct indentation for every association in STRUCT. +ORIGINS is the alist of parents. See `org-list-struct-origins'. -(defun org-maybe-renumber-ordered-list () - "Renumber the ordered list at point if setup allows it. -This tests the user option `org-auto-renumber-ordered-lists' before -doing the renumbering." - (interactive) - (when (and org-auto-renumber-ordered-lists - (org-at-item-p)) - (if (match-beginning 3) - (org-renumber-ordered-list 1) - (org-fix-bullet-type)))) +This function modifies STRUCT." + (let* ((headless (cdr struct)) + (ancestor (car struct)) + (top-ind (+ (nth 1 ancestor) (length (nth 2 ancestor)))) + (new-ind + (lambda (item) + (let* ((parent (org-list-struct-get-parent item headless origins))) + (if parent + ;; Indent like parent + length of parent's bullet + (setcdr item (cons (+ (length (nth 2 parent)) (nth 1 parent)) + (cddr item))) + ;; If no parent, indent like top-point + (setcdr item (cons top-ind (cddr item)))))))) + (mapc new-ind headless))) + +(defun org-list-struct-fix-struct (struct origins) + "Return STRUCT with correct bullets and indentation. +ORIGINS is the alist of parents. See `org-list-struct-origins'. + +Only elements of STRUCT that have changed are returned." + (let ((old (copy-alist struct))) + (org-list-struct-fix-bul struct origins) + (org-list-struct-fix-ind struct origins) + (delq nil (mapcar (lambda (e) (when (not (equal (pop old) e)) e)) struct)))) -(defun org-maybe-renumber-ordered-list-safe () - (condition-case nil - (save-excursion - (org-maybe-renumber-ordered-list)) - (error nil))) +(defun org-list-struct-outdent (start end origins) + "Outdent items in a structure. +Items are indented when their key is between START, included, and +END, excluded. + +ORIGINS is the alist of parents. See `org-list-struct-origins'. -(defun org-cycle-list-bullet (&optional which) - "Cycle through the different itemize/enumerate bullets. -This cycle the entire list level through the sequence: +STRUCT is the concerned structure." + (let* (acc + (out (lambda (cell) + (let* ((item (car cell)) + (parent (cdr cell))) + (cond + ;; Item not yet in zone: keep association + ((< item start) cell) + ;; Item out of zone: follow associations in acc + ((>= item end) + (let ((convert (assq parent acc))) + (if convert (cons item (cdr convert)) cell))) + ;; Item has no parent: error + ((<= parent 0) + (error "Cannot outdent top-level items")) + ;; Parent is outdented: keep association + ((>= parent start) + (setq acc (cons (cons parent item) acc)) cell) + (t + ;; Parent isn't outdented: reparent to grand-parent + (let ((grand-parent (cdr (assq parent origins)))) + (setq acc (cons (cons parent item) acc)) + (cons item grand-parent)))))))) + (mapcar out origins))) - `-' -> `+' -> `*' -> `1.' -> `1)' +(defun org-list-struct-indent (start end origins struct) + "Indent items in a structure. +Items are indented when their key is between START, included, and +END, excluded. + +ORIGINS is the alist of parents. See `org-list-struct-origins'. -If WHICH is a string, use that as the new bullet. If WHICH is an integer, -0 means `-', 1 means `+' etc." - (interactive "P") - (org-preserve-lc - (org-beginning-of-item-list) - (org-at-item-p) - (beginning-of-line 1) - (let ((current (match-string 0)) - (prevp (eq which 'previous)) - new old) - (setq new (cond - ((and (numberp which) - (nth (1- which) '("-" "+" "*" "1." "1)")))) - ((string-match "-" current) (if prevp "1)" "+")) - ((string-match "\\+" current) - (if prevp "-" (if (looking-at "\\S-") "1." "*"))) - ((string-match "\\*" current) (if prevp "+" "1.")) - ((string-match "\\." current) - (if prevp (if (looking-at "\\S-") "+" "*") "1)")) - ((string-match ")" current) (if prevp "1." "-")) - (t (error "This should not happen")))) - (and (looking-at "\\([ \t]*\\)\\(\\S-+\\)") - (setq old (match-string 2)) - (replace-match (concat "\\1" new))) - (org-shift-item-indentation (- (length new) (length old))) - (org-fix-bullet-type) - (org-maybe-renumber-ordered-list)))) +STRUCT is the concerned structure. It may be modified if +`org-list-demote-modify-bullet' matches bullets between START and +END." + (let* (acc + (orig-rev (reverse origins)) + (get-prev-item + (lambda (cell parent) + (car (rassq parent (cdr (memq cell orig-rev)))))) + (set-assoc + (lambda (cell) + (setq acc (cons cell acc)) cell)) + (change-bullet-maybe + (lambda (item) + (let* ((full-item (assq item struct)) + (item-bul (org-trim (nth 2 full-item))) + (new-bul-p (cdr (assoc item-bul org-list-demote-modify-bullet)))) + (when new-bul-p + ;; new bullet is stored without space to ensure item + ;; will be modified + (setcdr full-item + (list (nth 1 full-item) + new-bul-p + (nth 3 full-item))))))) + (ind + (lambda (cell) + (let* ((item (car cell)) + (parent (cdr cell))) + (cond + ;; Item not yet in zone: keep association + ((< item start) cell) + ((>= item end) + ;; Item out of zone: follow associations in acc + (let ((convert (assq parent acc))) + (if convert (cons item (cdr convert)) cell))) + (t + ;; Item is in zone... + (let ((prev (funcall get-prev-item cell parent))) + ;; Check if bullet needs to be changed + (funcall change-bullet-maybe item) + (cond + ;; First item indented but not parent: error + ((and (or (not prev) (= prev 0)) (< parent start)) + (error "Cannot indent the first item of a list")) + ;; First item and parent indented: keep same parent + ((or (not prev) (= prev 0)) + (funcall set-assoc cell)) + ;; Previous item not indented: reparent to it + ((< prev start) + (funcall set-assoc (cons item prev))) + ;; Previous item indented: reparent like it + (t + (funcall set-assoc (cons item + (cdr (assq prev acc))))))))))))) + (mapcar ind origins))) + +(defun org-list-struct-apply-struct (struct bottom) + "Apply modifications to list so it mirrors STRUCT. +BOTTOM is position at list ending. + +Initial position is restored after the changes." + (let* ((pos (copy-marker (point))) + (ancestor (caar struct)) + (modify + (lambda (item) + (goto-char (car item)) + (let* ((new-ind (nth 1 item)) + (new-bul (org-list-bullet-string (nth 2 item))) + (old-ind (org-get-indentation)) + (old-bul (progn + (looking-at "[ \t]*\\(\\S-+[ \t]*\\)") + (match-string 1))) + (old-body-ind (+ (length old-bul) old-ind)) + (new-body-ind (+ (length new-bul) new-ind))) + ;; 1. Shift item's body + (unless (= old-body-ind new-body-ind) + (org-shift-item-indentation + (- new-body-ind old-body-ind) bottom)) + ;; 2. Replace bullet + (unless (equal new-bul old-bul) + (save-excursion + (looking-at "[ \t]*\\(\\S-+[ \t]*\\)") + (replace-match new-bul nil nil nil 1))) + ;; 3. Indent item to appropriate column + (unless (= new-ind old-ind) + (delete-region (point-at-bol) + (progn + (skip-chars-forward " \t") + (point))) + (indent-to new-ind))))) + ;; Remove ancestor if it is left. + (struct-to-apply (if (or (not ancestor) (= 0 ancestor)) + (cdr struct) + struct))) + ;; Apply changes from bottom to top + (mapc modify (nreverse struct-to-apply)) + (goto-char pos))) + +;;; Indentation (defun org-get-string-indentation (s) "What indentation has S due to SPACE and TAB at the beginning of the string?" @@ -847,299 +1467,555 @@ (t (throw 'exit t))))) i)) -(defun org-renumber-ordered-list (arg) - "Renumber an ordered plain list. -Cursor needs to be in the first line of an item, the line that starts -with something like \"1.\" or \"2)\"." - (interactive "p") - (unless (and (org-at-item-p) - (match-beginning 3)) - (error "This is not an ordered list")) - (let ((line (org-current-line)) - (col (current-column)) - (ind (org-get-string-indentation - (buffer-substring (point-at-bol) (match-beginning 3)))) - ;; (term (substring (match-string 3) -1)) - ind1 (n (1- arg)) - fmt bobp old new delta) - ;; find where this list begins - (org-beginning-of-item-list) - (setq bobp (bobp)) - (looking-at "[ \t]*[0-9]+\\([.)]\\)") - (setq fmt (concat "%d" (or (match-string 1) "."))) - (save-excursion - (goto-char (match-end 0)) - (if (looking-at "[ \t]*\\[@start:\\([0-9]+\\)") - (setq n (1- (string-to-number (match-string 1)))))) - (beginning-of-line 0) - ;; walk forward and replace these numbers - (catch 'exit - (while t - (catch 'next - (if bobp (setq bobp nil) (beginning-of-line 2)) - (if (eobp) (throw 'exit nil)) - (if (looking-at "[ \t]*$") (throw 'next nil)) - (skip-chars-forward " \t") (setq ind1 (current-column)) - (if (> ind1 ind) (throw 'next t)) - (if (< ind1 ind) (throw 'exit t)) - (if (not (org-at-item-p)) (throw 'exit nil)) - (setq old (match-string 2)) - (delete-region (match-beginning 2) (match-end 2)) - (goto-char (match-beginning 2)) - (insert (setq new (format fmt (setq n (1+ n))))) - (setq delta (- (length new) (length old))) - (org-shift-item-indentation delta) - (if (= (org-current-line) line) (setq col (+ col delta)))))) - (org-goto-line line) - (org-move-to-column col))) +(defun org-shift-item-indentation (delta bottom) + "Shift the indentation in current item by DELTA. +Sub-items are not moved. + +BOTTOM is position at list ending." + (save-excursion + (let ((beg (point-at-bol)) + (end (org-end-of-item-or-at-child bottom))) + (beginning-of-line (unless (eolp) 0)) + (while (> (point) beg) + (when (looking-at "[ \t]*\\S-") + ;; this is not an empty line + (let ((i (org-get-indentation))) + (when (and (> i 0) (> (+ i delta) 0)) + (indent-line-to (+ i delta))))) + (beginning-of-line 0))))) + +(defun org-outdent-item () + "Outdent a local list item, but not its children. +If a region is active, all items inside will be moved." + (interactive) + (org-list-indent-item-generic + -1 t (org-list-top-point) (org-list-bottom-point))) + +(defun org-indent-item () + "Indent a local list item, but not its children. +If a region is active, all items inside will be moved." + (interactive) + (org-list-indent-item-generic + 1 t (org-list-top-point) (org-list-bottom-point))) + +(defun org-outdent-item-tree () + "Outdent a local list item including its children. +If a region is active, all items inside will be moved." + (interactive) + (org-list-indent-item-generic + -1 nil (org-list-top-point) (org-list-bottom-point))) + +(defun org-indent-item-tree () + "Indent a local list item including its children. +If a region is active, all items inside will be moved." + (interactive) + (org-list-indent-item-generic + 1 nil (org-list-top-point) (org-list-bottom-point))) + +(defvar org-tab-ind-state) +(defun org-cycle-item-indentation () + "Cycle levels of indentation of an empty item. +The first run indent the item, if applicable. Subsequents runs +outdent it at meaningful levels in the list. When done, item is +put back at its original position with its original bullet. -(defvar org-suppress-item-indentation) ; dynamically scoped parameter -(defun org-fix-bullet-type (&optional force-bullet) - "Make sure all items in this list have the same bullet as the first item. -Also, fix the indentation." +Return t at each successful move." + (let ((org-adapt-indentation nil) + (ind (org-get-indentation)) + (bottom (and (org-at-item-p) (org-list-bottom-point)))) + (when (and (or (org-at-item-description-p) + (org-at-item-checkbox-p) + (org-at-item-p)) + ;; Check that item is really empty + (>= (match-end 0) (save-excursion + (org-end-of-item-or-at-child bottom) + (skip-chars-backward " \r\t\n") + (point)))) + (setq this-command 'org-cycle-item-indentation) + (let ((top (org-list-top-point))) + ;; When in the middle of the cycle, try to outdent first. If it + ;; fails, and point is still at initial position, indent. Else, + ;; go back to original position. + (if (eq last-command 'org-cycle-item-indentation) + (cond + ((ignore-errors (org-list-indent-item-generic -1 t top bottom))) + ((and (= (org-get-indentation) (car org-tab-ind-state)) + (ignore-errors + (org-list-indent-item-generic 1 t top bottom)))) + (t (back-to-indentation) + (indent-to-column (car org-tab-ind-state)) + (end-of-line) + (org-list-repair (cdr org-tab-ind-state)) + ;; Break cycle + (setq this-command 'identity))) + ;; If a cycle is starting, remember indentation and bullet, + ;; then try to indent. If it fails, try to outdent. + (setq org-tab-ind-state (cons ind (org-get-bullet))) + (cond + ((ignore-errors (org-list-indent-item-generic 1 t top bottom))) + ((ignore-errors (org-list-indent-item-generic -1 t top bottom))) + (t (error "Cannot move item"))))) + t))) + +;;; Bullets + +(defun org-get-bullet () + "Return the bullet of the item at point. +Assume cursor is at an item." + (save-excursion + (beginning-of-line) + (and (looking-at "[ \t]*\\(\\S-+\\)") (match-string 1)))) + +(defun org-list-bullet-string (bullet) + "Return BULLET with the correct number of whitespaces. +It determines the number of whitespaces to append by looking at +`org-list-two-spaces-after-bullet-regexp'." + (save-match-data + (string-match "\\S-+\\([ \t]*\\)" bullet) + (replace-match + (save-match-data + (concat + " " + ;; Do we need to concat another white space ? + (when (and org-list-two-spaces-after-bullet-regexp + (string-match org-list-two-spaces-after-bullet-regexp bullet)) + " "))) + nil nil bullet 1))) + +(defun org-list-inc-bullet-maybe (bullet) + "Increment BULLET if applicable." + (if (string-match "[0-9]+" bullet) + (replace-match + (number-to-string (1+ (string-to-number (match-string 0 bullet)))) + nil nil bullet) + bullet)) + +(defun org-list-repair (&optional force-bullet top bottom) + "Make sure all items are correctly indented, with the right bullet. +This function scans the list at point, along with any sublist. + +If FORCE-BULLET is a string, ensure all items in list share this +bullet, or a logical successor in the case of an ordered list. + +When non-nil, TOP and BOTTOM specify respectively position of +list beginning and list ending. + +Item's body is not indented, only shifted with the bullet." (interactive) (unless (org-at-item-p) (error "This is not a list")) - (let ((line (org-current-line)) - (chars-from-eol (- (point-at-eol) (point))) - (ind (current-indentation)) - ind1 bullet oldbullet) - ;; find where this list begins - (org-beginning-of-item-list) - (beginning-of-line 1) - ;; find out what the bullet type is - (looking-at "[ \t]*\\(\\S-+\\)") - (setq bullet (concat (or force-bullet (match-string 1)) " ")) - (if (and org-list-two-spaces-after-bullet-regexp - (string-match org-list-two-spaces-after-bullet-regexp bullet)) - (setq bullet (concat bullet " "))) - ;; walk forward and replace these numbers - (beginning-of-line 0) - (catch 'exit - (while t - (catch 'next - (beginning-of-line 2) - (if (eobp) (throw 'exit nil)) - (if (looking-at "[ \t]*$") (throw 'next nil)) - (skip-chars-forward " \t") (setq ind1 (current-column)) - (if (> ind1 ind) (throw 'next t)) - (if (< ind1 ind) (throw 'exit t)) - (if (not (org-at-item-p)) (throw 'exit nil)) - (skip-chars-forward " \t") - (looking-at "\\S-+ *") - (setq oldbullet (match-string 0)) - (unless (equal bullet oldbullet) (replace-match bullet)) - (org-shift-item-indentation (- (length bullet) - (length oldbullet)))))) - (org-goto-line line) - (goto-char (max (point-at-bol) (- (point-at-eol) chars-from-eol))) - (if (string-match "[0-9]" bullet) - (org-renumber-ordered-list 1)))) + (let* ((bottom (or bottom (org-list-bottom-point))) + (struct (org-list-struct + (point-at-bol) (point-at-eol) + (or top (org-list-top-point)) bottom)) + (origins (org-list-struct-origins struct)) + fixed-struct) + (if (stringp force-bullet) + (let ((begin (nth 1 struct))) + (setcdr begin (list (nth 1 begin) + (org-list-bullet-string force-bullet) + (nth 3 begin))) + (setq fixed-struct + (cons begin (org-list-struct-fix-struct struct origins)))) + (setq fixed-struct (org-list-struct-fix-struct struct origins))) + (org-list-struct-apply-struct fixed-struct bottom))) + +(defun org-cycle-list-bullet (&optional which) + "Cycle through the different itemize/enumerate bullets. +This cycle the entire list level through the sequence: + + `-' -> `+' -> `*' -> `1.' -> `1)' -(defun org-shift-item-indentation (delta) - "Shift the indentation in current item by DELTA." - (unless (org-bound-and-true-p org-suppress-item-indentation) - (save-excursion - (let ((beg (point-at-bol)) - (end (progn (org-end-of-item) (point))) - i) - (goto-char end) - (beginning-of-line 0) - (while (> (point) beg) - (when (looking-at "[ \t]*\\S-") - ;; this is not an empty line - (setq i (org-get-indentation)) - (if (and (> i 0) (> (setq i (+ i delta)) 0)) - (indent-line-to i))) - (beginning-of-line 0)))))) +If WHICH is a valid string, use that as the new bullet. If WHICH +is an integer, 0 means `-', 1 means `+' etc. If WHICH is +'previous, cycle backwards." + (interactive "P") + (let* ((top (org-list-top-point)) + (bullet (save-excursion + (goto-char (org-get-beginning-of-list top)) + (org-get-bullet))) + (current (cond + ((string-match "\\." bullet) "1.") + ((string-match ")" bullet) "1)") + (t bullet))) + (bullet-rule-p (cdr (assq 'bullet org-list-automatic-rules))) + (bullet-list (append '("-" "+" ) + ;; *-bullets are not allowed at column 0 + (unless (and bullet-rule-p + (looking-at "\\S-")) '("*")) + ;; Description items cannot be numbered + (unless (and bullet-rule-p + (or (eq org-plain-list-ordered-item-terminator ?\)) + (org-at-item-description-p))) '("1.")) + (unless (and bullet-rule-p + (or (eq org-plain-list-ordered-item-terminator ?.) + (org-at-item-description-p))) '("1)")))) + (len (length bullet-list)) + (item-index (- len (length (member current bullet-list)))) + (get-value (lambda (index) (nth (mod index len) bullet-list))) + (new (cond + ((member which bullet-list) which) + ((numberp which) (funcall get-value which)) + ((eq 'previous which) (funcall get-value (1- item-index))) + (t (funcall get-value (1+ item-index)))))) + (org-list-repair new top))) + +;;; Checkboxes + +(defun org-toggle-checkbox (&optional toggle-presence) + "Toggle the checkbox in the current line. +With prefix arg TOGGLE-PRESENCE, add or remove checkboxes. With +double prefix, set checkbox to [-]. + +When there is an active region, toggle status or presence of the +first checkbox there, and make every item inside have the +same status or presence, respectively. -(defun org-beginning-of-item-list () - "Go to the beginning of the current item list. -I.e. to the first item in this list." - (interactive) - (org-beginning-of-item) - (let ((pos (point-at-bol)) - (ind (org-get-indentation)) - ind1) - ;; find where this list begins - (catch 'exit - (while t - (catch 'next - (beginning-of-line 0) - (if (looking-at "[ \t]*$") - (throw (if (bobp) 'exit 'next) t)) - (skip-chars-forward " \t") (setq ind1 (current-column)) - (if (or (< ind1 ind) - (and (= ind1 ind) - (not (org-at-item-p))) - (and (= (point-at-bol) (point-min)) - (setq pos (point-min)))) - (throw 'exit t) - (when (org-at-item-p) (setq pos (point-at-bol))))))) - (goto-char pos))) +If the cursor is in a headline, apply this to all checkbox items +in the text below the heading, taking as reference the first item +in subtree, ignoring drawers." + (interactive "P") + ;; Bounds is a list of type (beg end single-p) where single-p is t + ;; when `org-toggle-checkbox' is applied to a single item. Only + ;; toggles on single items will return errors. + (let* ((bounds + (cond + ((org-region-active-p) + (let ((rbeg (region-beginning)) + (rend (region-end))) + (save-excursion + (goto-char rbeg) + (if (org-search-forward-unenclosed org-item-beginning-re rend 'move) + (list (point-at-bol) rend nil) + (error "No item in region"))))) + ((org-on-heading-p) + ;; In this case, reference line is the first item in + ;; subtree outside drawers + (let ((pos (point)) + (limit (save-excursion (outline-next-heading) (point)))) + (save-excursion + (goto-char limit) + (org-search-backward-unenclosed ":END:" pos 'move) + (org-search-forward-unenclosed + org-item-beginning-re limit 'move) + (list (point) limit nil)))) + ((org-at-item-p) + (list (point-at-bol) (1+ (point-at-eol)) t)) + (t (error "Not at an item or heading, and no active region")))) + (beg (car bounds)) + ;; marker is needed because deleting or inserting checkboxes + ;; will change bottom point + (end (copy-marker (nth 1 bounds))) + (single-p (nth 2 bounds)) + (ref-presence (save-excursion + (goto-char beg) + (org-at-item-checkbox-p))) + (ref-status (equal (match-string 1) "[X]")) + (act-on-item + (lambda (ref-pres ref-stat) + (if (equal toggle-presence '(4)) + (cond + ((and ref-pres (org-at-item-checkbox-p)) + (replace-match "")) + ((and (not ref-pres) + (not (org-at-item-checkbox-p)) + (org-at-item-p)) + (goto-char (match-end 0)) + ;; Ignore counter, if any + (when (looking-at "\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?") + (goto-char (match-end 0))) + (let ((desc-p (and (org-at-item-description-p) + (cdr (assq 'checkbox org-list-automatic-rules))))) + (cond + ((and single-p desc-p) + (error "Cannot add a checkbox in a description list")) + ((not desc-p) (insert "[ ] ")))))) + (let ((blocked (org-checkbox-blocked-p))) + (cond + ((and blocked single-p) + (error "Checkbox blocked because of unchecked box in line %d" blocked)) + (blocked nil) + ((org-at-item-checkbox-p) + (replace-match + (cond ((equal toggle-presence '(16)) "[-]") + (ref-stat "[ ]") + (t "[X]")) + t t nil 1)))))))) + (save-excursion + (goto-char beg) + (while (< (point) end) + (funcall act-on-item ref-presence ref-status) + (org-search-forward-unenclosed org-item-beginning-re end 'move))) + (org-update-checkbox-count-maybe))) -(defun org-end-of-item-list () - "Go to the end of the current item list. -I.e. to the text after the last item." - (interactive) - (org-beginning-of-item) - (let ((pos (point-at-bol)) - (ind (org-get-indentation)) - ind1) - ;; find where this list begins - (catch 'exit - (while t - (catch 'next - (beginning-of-line 2) - (if (looking-at "[ \t]*$") - (if (eobp) - (progn (setq pos (point)) (throw 'exit t)) - (throw 'next t))) - (skip-chars-forward " \t") (setq ind1 (current-column)) - (if (or (< ind1 ind) - (and (= ind1 ind) - (not (org-at-item-p))) - (eobp)) - (progn - (setq pos (point-at-bol)) - (throw 'exit t)))))) - (goto-char pos))) +(defun org-reset-checkbox-state-subtree () + "Reset all checkboxes in an entry subtree." + (interactive "*") + (save-restriction + (save-excursion + (org-narrow-to-subtree) + (org-show-subtree) + (goto-char (point-min)) + (let ((end (point-max))) + (while (< (point) end) + (when (org-at-item-checkbox-p) + (replace-match "[ ]" t t nil 1)) + (beginning-of-line 2)))) + (org-update-checkbox-count-maybe))) - -(defvar org-last-indent-begin-marker (make-marker)) -(defvar org-last-indent-end-marker (make-marker)) +(defvar org-checkbox-statistics-hook nil + "Hook that is run whenever Org thinks checkbox statistics should be updated. +This hook runs even if checkbox rule in +`org-list-automatic-rules' does not apply, so it can be used to +implement alternative ways of collecting statistics +information.") -(defun org-outdent-item (arg) - "Outdent a local list item, but not its children." - (interactive "p") - (org-indent-item-tree (- arg) 'no-subtree)) - -(defun org-indent-item (arg) - "Indent a local list item, but not its children." - (interactive "p") - (org-indent-item-tree arg 'no-subtree)) +(defun org-update-checkbox-count-maybe () + "Update checkbox statistics unless turned off by user." + (when (cdr (assq 'checkbox org-list-automatic-rules)) + (org-update-checkbox-count)) + (run-hooks 'org-checkbox-statistics-hook)) -(defun org-outdent-item-tree (arg &optional no-subtree) - "Outdent a local list item including its children. -If NO-SUBTREE is set, only outdent the item itself, not its children." - (interactive "p") - (org-indent-item-tree (- arg) no-subtree)) +(defun org-update-checkbox-count (&optional all) + "Update the checkbox statistics in the current section. +This will find all statistic cookies like [57%] and [6/12] and update them +with the current numbers. With optional prefix argument ALL, do this for +the whole buffer." + (interactive "P") + (save-excursion + (let ((cstat 0)) + (catch 'exit + (while t + (let* ((buffer-invisibility-spec (org-inhibit-invisibility)) ; Emacs 21 + (beg (condition-case nil + (progn (org-back-to-heading) (point)) + (error (point-min)))) + (end (copy-marker (save-excursion + (outline-next-heading) (point)))) + (re-cookie "\\(\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)") + (re-box "^[ \t]*\\([-+*]\\|[0-9]+[.)]\\)[ \t]+\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\(\\[[- X]\\]\\)") + beg-cookie end-cookie is-percent c-on c-off lim new + curr-ind next-ind continue-from startsearch list-beg list-end + (recursive + (or (not org-hierarchical-checkbox-statistics) + (string-match "\\<recursive\\>" + (or (ignore-errors + (org-entry-get nil "COOKIE_DATA")) + ""))))) + (goto-char end) + ;; find each statistics cookie + (while (and (org-search-backward-unenclosed re-cookie beg 'move) + (not (save-match-data + (and (org-on-heading-p) + (string-match "\\<todo\\>" + (downcase + (or (org-entry-get + nil "COOKIE_DATA") + ""))))))) + (setq beg-cookie (match-beginning 1) + end-cookie (match-end 1) + cstat (+ cstat (if end-cookie 1 0)) + startsearch (point-at-eol) + continue-from (match-beginning 0) + is-percent (match-beginning 2) + lim (cond + ((org-on-heading-p) (outline-next-heading) (point)) + ;; Ensure many cookies in the same list won't imply + ;; computing list boundaries as many times. + ((org-at-item-p) + (unless (and list-beg (>= (point) list-beg)) + (setq list-beg (org-list-top-point) + list-end (copy-marker + (org-list-bottom-point)))) + (org-get-end-of-item list-end)) + (t nil)) + c-on 0 + c-off 0) + (when lim + ;; find first checkbox for this cookie and gather + ;; statistics from all that are at this indentation level + (goto-char startsearch) + (if (org-search-forward-unenclosed re-box lim t) + (progn + (beginning-of-line) + (setq curr-ind (org-get-indentation)) + (setq next-ind curr-ind) + (while (and (bolp) (org-at-item-p) + (if recursive + (<= curr-ind next-ind) + (= curr-ind next-ind))) + (when (org-at-item-checkbox-p) + (if (member (match-string 1) '("[ ]" "[-]")) + (setq c-off (1+ c-off)) + (setq c-on (1+ c-on)))) + (if (not recursive) + ;; org-get-next-item goes through list-enders + ;; with proper limit. + (goto-char (or (org-get-next-item (point) lim) lim)) + (end-of-line) + (when (org-search-forward-unenclosed + org-item-beginning-re lim t) + (beginning-of-line))) + (setq next-ind (org-get-indentation))))) + (goto-char continue-from) + ;; update cookie + (when end-cookie + (setq new (if is-percent + (format "[%d%%]" (/ (* 100 c-on) + (max 1 (+ c-on c-off)))) + (format "[%d/%d]" c-on (+ c-on c-off)))) + (goto-char beg-cookie) + (insert new) + (delete-region (point) (+ (point) (- end-cookie beg-cookie)))) + ;; update items checkbox if it has one + (when (and (org-at-item-checkbox-p) + (> (+ c-on c-off) 0)) + (setq beg-cookie (match-beginning 1) + end-cookie (match-end 1)) + (delete-region beg-cookie end-cookie) + (goto-char beg-cookie) + (cond ((= c-off 0) (insert "[X]")) + ((= c-on 0) (insert "[ ]")) + (t (insert "[-]"))))) + (goto-char continue-from))) + (unless (and all (outline-next-heading)) (throw 'exit nil)))) + (when (interactive-p) + (message "Checkbox statistics updated %s (%d places)" + (if all "in entire file" "in current outline entry") cstat))))) -(defun org-indent-item-tree (arg &optional no-subtree) - "Indent a local list item including its children. -If NO-SUBTREE is set, only indent the item itself, not its children." - (interactive "p") - (and (org-region-active-p) (org-cursor-to-region-beginning)) - (unless (org-at-item-p) - (error "Not on an item")) - (let (beg end ind ind1 ind-bul delta ind-down ind-up firstp) - (setq firstp (org-first-list-item-p)) - (save-excursion - (setq end (and (org-region-active-p) (region-end))) - (if (and (memq last-command '(org-shiftmetaright org-shiftmetaleft)) - (memq this-command '(org-shiftmetaright org-shiftmetaleft))) - (setq beg org-last-indent-begin-marker - end org-last-indent-end-marker) - (org-beginning-of-item) - (setq beg (move-marker org-last-indent-begin-marker (point))) - (if no-subtree - (org-end-of-item-text-before-children) - (org-end-of-item)) - (setq end (move-marker org-last-indent-end-marker (or end (point))))) - (goto-char beg) - (setq ind-bul (org-item-indent-positions) - ind (caar ind-bul) - ind-down (car (nth 2 ind-bul)) - ind-up (car (nth 1 ind-bul)) - delta (if (> arg 0) - (if ind-down (- ind-down ind) 2) - (if ind-up (- ind-up ind) -2))) - (if (< (+ delta ind) 0) (error "Cannot outdent beyond margin")) - (while (< (point) end) - (beginning-of-line 1) - (skip-chars-forward " \t") (setq ind1 (current-column)) - (delete-region (point-at-bol) (point)) - (or (eolp) (org-indent-to-column (+ ind1 delta))) - (beginning-of-line 2))) - (org-fix-bullet-type - (and (> arg 0) - (not firstp) - (cdr (assoc (cdr (nth 0 ind-bul)) org-list-demote-modify-bullet)))) - (org-maybe-renumber-ordered-list-safe) - (save-excursion - (beginning-of-line 0) - (condition-case nil (org-beginning-of-item) (error nil)) - (org-maybe-renumber-ordered-list-safe)))) +(defun org-get-checkbox-statistics-face () + "Select the face for checkbox statistics. +The face will be `org-done' when all relevant boxes are checked. +Otherwise it will be `org-todo'." + (if (match-end 1) + (if (equal (match-string 1) "100%") + 'org-checkbox-statistics-done + 'org-checkbox-statistics-todo) + (if (and (> (match-end 2) (match-beginning 2)) + (equal (match-string 2) (match-string 3))) + 'org-checkbox-statistics-done + 'org-checkbox-statistics-todo))) -(defun org-item-indent-positions () - "Return indentation for plain list items. -This returns a list with three values: The current indentation, the -parent indentation and the indentation a child should have. -Assumes cursor in item line." - (let* ((bolpos (point-at-bol)) - (ind (org-get-indentation)) - (bullet (org-get-bullet)) - ind-down ind-up bullet-up bullet-down pos) - (save-excursion - (org-beginning-of-item-list) - (skip-chars-backward "\n\r \t") - (when (org-in-item-p) - (org-beginning-of-item) - (setq ind-up (org-get-indentation)) - (setq bullet-up (org-get-bullet)))) - (setq pos (point)) - (save-excursion - (cond - ((and (condition-case nil (progn (org-previous-item) t) - (error nil)) - (or (forward-char 1) t) - (re-search-forward "^\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)" bolpos t)) - (setq ind-down (org-get-indentation) - bullet-down (org-get-bullet))) - ((and (goto-char pos) - (org-at-item-p)) - (goto-char (match-end 0)) - (skip-chars-forward " \t") - (setq ind-down (current-column) - bullet-down (org-get-bullet))))) - (if (and bullet-down (string-match "\\`[0-9]+\\(\\.\\|)\\)\\'" bullet-down)) - (setq bullet-down (concat "1" (match-string 1 bullet-down)))) - (if (and bullet-up (string-match "\\`[0-9]+\\(\\.\\|)\\)\\'" bullet-up)) - (setq bullet-up (concat "1" (match-string 1 bullet-up)))) - (if (and bullet (string-match "\\`[0-9]+\\(\\.\\|)\\)\\'" bullet)) - (setq bullet (concat "1" (match-string 1 bullet)))) - (list (cons ind bullet) - (cons ind-up bullet-up) - (cons ind-down bullet-down)))) +;;; Misc Tools + +(defun org-apply-on-list (function init-value &rest args) + "Call FUNCTION on each item of the list at point. +FUNCTION must be called with at least one argument: INIT-VALUE, +that will contain the value returned by the function at the +previous item, plus ARGS extra arguments. + +As an example, (org-apply-on-list (lambda (result) (1+ result)) 0) +will return the number of items in the current list. + +Sublists of the list are skipped. Cursor is always at the +beginning of the item." + (let* ((pos (copy-marker (point))) + (end (copy-marker (org-list-bottom-point))) + (next-p (copy-marker (org-get-beginning-of-list (org-list-top-point)))) + (value init-value)) + (while (< next-p end) + (goto-char next-p) + (set-marker next-p (or (org-get-next-item (point) end) end)) + (setq value (apply function value args))) + (goto-char pos) + value)) + +(defun org-sort-list (&optional with-case sorting-type getkey-func compare-func) + "Sort plain list items. +The cursor may be at any item of the list that should be sorted. +Sublists are not sorted. Checkboxes, if any, are ignored. + +Sorting can be alphabetically, numerically, by date/time as given by +a time stamp, by a property or by priority. + +Comparing entries ignores case by default. However, with an +optional argument WITH-CASE, the sorting considers case as well. + +The command prompts for the sorting type unless it has been given +to the function through the SORTING-TYPE argument, which needs to +be a character, \(?n ?N ?a ?A ?t ?T ?f ?F). Here is the precise +meaning of each character: + +n Numerically, by converting the beginning of the item to a number. +a Alphabetically. Only the first line of item is checked. +t By date/time, either the first active time stamp in the entry, if + any, or by the first inactive one. In a timer list, sort the timers. + +Capital letters will reverse the sort order. -(defvar org-tab-ind-state) ; defined in org.el -(defun org-cycle-item-indentation () - (let ((org-suppress-item-indentation t) - (org-adapt-indentation nil)) - (cond - ((and (looking-at "[ \t]*$") - (org-looking-back "^\\([ \t]*\\)\\([-+*]\\|[0-9]+[).]\\)[ \t]+")) - (setq this-command 'org-cycle-item-indentation) - (if (eq last-command 'org-cycle-item-indentation) - (condition-case nil - (progn (org-outdent-item 1) - (if (equal org-tab-ind-state (org-get-indentation)) - (org-outdent-item 1)) - (end-of-line 1)) - (error - (progn - (while (< (org-get-indentation) org-tab-ind-state) - (progn (org-indent-item 1) (end-of-line 1))) - (setq this-command 'org-cycle)))) - (setq org-tab-ind-state (org-get-indentation)) - (org-indent-item 1)) - t)))) - -(defun org-get-bullet () - (save-excursion - (goto-char (point-at-bol)) - (and (looking-at - "^\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\(\\*\\)\\)\\( \\|$\\)") - (or (match-string 2) (match-string 4))))) +If the SORTING-TYPE is ?f or ?F, then GETKEY-FUNC specifies a +function to be called with point at the beginning of the record. +It must return either a string or a number that should serve as +the sorting key for that record. It will then use COMPARE-FUNC to +compare entries." + (interactive "P") + (let* ((case-func (if with-case 'identity 'downcase)) + (top (org-list-top-point)) + (bottom (org-list-bottom-point)) + (start (org-get-beginning-of-list top)) + (end (org-get-end-of-list bottom)) + (sorting-type + (progn + (message + "Sort plain list: [a]lpha [n]umeric [t]ime [f]unc A/N/T/F means reversed:") + (read-char-exclusive))) + (getkey-func (and (= (downcase sorting-type) ?f) + (org-icompleting-read "Sort using function: " + obarray 'fboundp t nil nil) + (intern getkey-func)))) + (message "Sorting items...") + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (let* ((dcst (downcase sorting-type)) + (case-fold-search nil) + (now (current-time)) + (sort-func (cond + ((= dcst ?a) 'string<) + ((= dcst ?f) compare-func) + ((= dcst ?t) '<) + (t nil))) + (begin-record (lambda () + (skip-chars-forward " \r\t\n") + (beginning-of-line))) + (end-record (lambda () + (goto-char (org-end-of-item-before-blank end)))) + (value-to-sort + (lambda () + (when (looking-at "[ \t]*[-+*0-9.)]+\\([ \t]+\\[[- X]\\]\\)?[ \t]+") + (cond + ((= dcst ?n) + (string-to-number (buffer-substring (match-end 0) + (point-at-eol)))) + ((= dcst ?a) + (buffer-substring (match-end 0) (point-at-eol))) + ((= dcst ?t) + (cond + ;; If it is a timer list, convert timer to seconds + ((org-at-item-timer-p) + (org-timer-hms-to-secs (match-string 1))) + ((or (org-search-forward-unenclosed org-ts-regexp + (point-at-eol) t) + (org-search-forward-unenclosed org-ts-regexp-both + (point-at-eol) t)) + (org-time-string-to-seconds (match-string 0))) + (t (org-float-time now)))) + ((= dcst ?f) + (if getkey-func + (let ((value (funcall getkey-func))) + (if (stringp value) + (funcall case-func value) + value)) + (error "Invalid key function `%s'" getkey-func))) + (t (error "Invalid sorting type `%c'" sorting-type))))))) + (sort-subr (/= dcst sorting-type) + begin-record + end-record + value-to-sort + nil + sort-func) + (org-list-repair nil top bottom) + (run-hooks 'org-after-sorting-entries-or-items-hook) + (message "Sorting items...done"))))) ;;; Send and receive lists @@ -1147,85 +2023,55 @@ "Parse the list at point and maybe DELETE it. Return a list containing first level items as strings and sublevels as a list of strings." - (let* ((item-beginning (org-list-item-beginning)) - (start (car item-beginning)) - (end (save-excursion - (goto-char (org-list-end (cdr item-beginning))) - (org-back-over-empty-lines) - (point))) + (let* ((start (goto-char (org-list-top-point))) + (end (org-list-bottom-point)) output itemsep ltype) - (while (re-search-forward org-list-beginning-re end t) - (goto-char (match-beginning 3)) - (save-match-data - (cond ((string-match "[0-9]" (match-string 2)) - (setq itemsep "[0-9]+\\(?:\\.\\|)\\)" - ltype 'ordered)) - ((string-match "^.*::" (match-string 0)) - (setq itemsep "[-+]" ltype 'descriptive)) - (t (setq itemsep "[-+]" ltype 'unordered)))) - (let* ((indent1 (match-string 1)) - (nextitem (save-excursion - (save-match-data - (or (and (re-search-forward - (concat "^" indent1 itemsep " *?") end t) - (match-beginning 0)) end)))) - (item (buffer-substring - (point) - (or (and (org-re-search-forward-unprotected - org-list-beginning-re end t) - (goto-char (match-beginning 0))) - (goto-char end)))) - (nextindent (match-string 1)) - (item (org-trim item)) - (item (if (string-match "^\\[\\([xX ]\\)\\]" item) + (while (org-search-forward-unenclosed org-item-beginning-re end t) + (save-excursion + (beginning-of-line) + (setq ltype (cond ((looking-at-p "^[ \t]*[0-9]") 'ordered) + ((org-at-item-description-p) 'descriptive) + (t 'unordered)))) + (let* ((indent1 (org-get-indentation)) + (nextitem (or (org-get-next-item (point) end) end)) + (item (org-trim (buffer-substring (point) + (org-end-of-item-or-at-child end)))) + (nextindent (if (= (point) end) 0 (org-get-indentation))) + (item (if (string-match + "^\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\([xX ]\\)\\]" + item) (replace-match (if (equal (match-string 1 item) " ") - "[CBOFF]" - "[CBON]") - t nil item) + "CBOFF" + "CBON") + t nil item 1) item))) (push item output) - (when (> (length nextindent) - (length indent1)) - (narrow-to-region (point) nextitem) - (push (org-list-parse-list) output) - (widen)))) - (when delete (delete-region start end)) + (when (> nextindent indent1) + (save-restriction + (narrow-to-region (point) nextitem) + (push (org-list-parse-list) output))))) + (when delete + (delete-region start end) + (save-match-data + (when (and (not (eq org-list-ending-method 'indent)) + (looking-at (org-list-end-re))) + (replace-match "\n")))) (setq output (nreverse output)) (push ltype output))) -(defun org-list-item-beginning () - "Find the beginning of the list item. -Return a cons which car is the beginning position of the item and -cdr is the indentation string." - (save-excursion - (if (not (or (looking-at org-list-beginning-re) - (re-search-backward - org-list-beginning-re nil t))) - (progn (goto-char (point-min)) (point)) - (cons (match-beginning 0) (match-string 1))))) - -(defun org-list-goto-true-beginning () - "Go to the beginning of the list at point." - (beginning-of-line 1) - (while (looking-at org-list-beginning-re) - (beginning-of-line 0)) - (progn - (re-search-forward org-list-beginning-re nil t) - (goto-char (match-beginning 0)))) - (defun org-list-make-subtree () "Convert the plain list at point into a subtree." (interactive) - (org-list-goto-true-beginning) - (let ((list (org-list-parse-list t)) nstars) - (save-excursion - (if (condition-case nil - (org-back-to-heading) - (error nil)) - (progn (re-search-forward org-complex-heading-regexp nil t) - (setq nstars (length (match-string 1)))) - (setq nstars 0))) - (org-list-make-subtrees list (1+ nstars)))) + (if (not (org-in-item-p)) + (error "Not in a list") + (let ((list (org-list-parse-list t)) nstars) + (save-excursion + (if (ignore-errors + (org-back-to-heading)) + (progn (looking-at org-complex-heading-regexp) + (setq nstars (length (match-string 1)))) + (setq nstars 0))) + (org-list-make-subtrees list (1+ nstars))))) (defun org-list-make-subtrees (list level) "Convert LIST into subtrees starting at LEVEL." @@ -1239,20 +2085,6 @@ (org-list-make-subtrees item (1+ level)))) list))) -(defun org-list-end (indent) - "Return the position of the end of the list. -INDENT is the indentation of the list, as a string." - (save-excursion - (catch 'exit - (while (or (looking-at org-list-beginning-re) - (looking-at (concat "^" indent "[ \t]+\\|^$")) - (> (or (get-text-property (point) 'original-indentation) -1) - (length indent))) - (if (eq (point) (point-max)) - (throw 'exit (point-max))) - (forward-line 1))) - (point))) - (defun org-list-insert-radio-list () "Insert a radio list template appropriate for this major mode." (interactive) @@ -1274,20 +2106,29 @@ this list." (interactive) (catch 'exit - (unless (org-at-item-p) (error "Not at a list")) + (unless (org-at-item-p) (error "Not at a list item")) (save-excursion - (org-list-goto-true-beginning) - (beginning-of-line 0) + (re-search-backward "#\\+ORGLST" nil t) (unless (looking-at "[ \t]*#\\+ORGLST[: \t][ \t]*SEND[ \t]+\\([^ \t\r\n]+\\)[ \t]+\\([^ \t\r\n]+\\)\\([ \t]+.*\\)?") (if maybe (throw 'exit nil) (error "Don't know how to transform this list")))) (let* ((name (match-string 1)) (transform (intern (match-string 2))) - (item-beginning (org-list-item-beginning)) - (list (save-excursion (org-list-goto-true-beginning) - (org-list-parse-list))) - txt beg) + (bottom-point + (save-excursion + (re-search-forward + "\\(\\\\end{comment}\\|@end ignore\\|-->\\)" nil t) + (match-beginning 0))) + (top-point + (progn + (re-search-backward "#\\+ORGLST" nil t) + (re-search-forward org-item-beginning-re bottom-point t) + (match-beginning 0))) + (list (save-restriction + (narrow-to-region top-point bottom-point) + (org-list-parse-list))) + beg txt) (unless (fboundp transform) (error "No such transformation function %s" transform)) (let ((txt (funcall transform list))) @@ -1295,22 +2136,22 @@ (save-excursion (goto-char (point-min)) (unless (re-search-forward - (concat "BEGIN RECEIVE ORGLST +" name "\\([ \t]\\|$\\)") nil t) + (concat "BEGIN RECEIVE ORGLST +" + name + "\\([ \t]\\|$\\)") nil t) (error "Don't know where to insert translated list")) (goto-char (match-beginning 0)) (beginning-of-line 2) (setq beg (point)) (unless (re-search-forward (concat "END RECEIVE ORGLST +" name) nil t) (error "Cannot find end of insertion region")) - (beginning-of-line 1) - (delete-region beg (point)) + (delete-region beg (point-at-bol)) (goto-char beg) (insert txt "\n"))) (message "List converted and installed at receiver location")))) (defun org-list-to-generic (list params) "Convert a LIST parsed through `org-list-parse-list' to other formats. - Valid parameters PARAMS are :ustart String to start an unordered list @@ -1339,21 +2180,21 @@ (interactive) (let* ((p params) sublist (splicep (plist-get p :splice)) - (ostart (plist-get p :ostart)) - (oend (plist-get p :oend)) - (ustart (plist-get p :ustart)) - (uend (plist-get p :uend)) - (dstart (plist-get p :dstart)) - (dend (plist-get p :dend)) - (dtstart (plist-get p :dtstart)) - (dtend (plist-get p :dtend)) - (ddstart (plist-get p :ddstart)) - (ddend (plist-get p :ddend)) - (istart (plist-get p :istart)) - (iend (plist-get p :iend)) - (isep (plist-get p :isep)) - (lsep (plist-get p :lsep)) - (cbon (plist-get p :cbon)) + (ostart (plist-get p :ostart)) + (oend (plist-get p :oend)) + (ustart (plist-get p :ustart)) + (uend (plist-get p :uend)) + (dstart (plist-get p :dstart)) + (dend (plist-get p :dend)) + (dtstart (plist-get p :dtstart)) + (dtend (plist-get p :dtend)) + (ddstart (plist-get p :ddstart)) + (ddend (plist-get p :ddend)) + (istart (plist-get p :istart)) + (iend (plist-get p :iend)) + (isep (plist-get p :isep)) + (lsep (plist-get p :lsep)) + (cbon (plist-get p :cbon)) (cboff (plist-get p :cboff))) (let ((wrapper (cond ((eq (car list) 'ordered) @@ -1366,22 +2207,24 @@ (while (setq sublist (pop list)) (cond ((symbolp sublist) nil) ((stringp sublist) - (when (string-match "^\\(.*\\) ::" sublist) + (when (string-match "^\\(.*\\)[ \t]+::" sublist) (setq term (org-trim (format (concat dtstart "%s" dtend) (match-string 1 sublist)))) - (setq sublist (substring sublist (1+ (length term))))) + (setq sublist (concat ddstart + (org-trim (substring sublist + (match-end 0))) + ddend))) (if (string-match "\\[CBON\\]" sublist) (setq sublist (replace-match cbon t t sublist))) (if (string-match "\\[CBOFF\\]" sublist) (setq sublist (replace-match cboff t t sublist))) (if (string-match "\\[-\\]" sublist) (setq sublist (replace-match "$\\boxminus$" t t sublist))) - (setq rtn (concat rtn istart term ddstart - sublist ddend iend isep))) - (t (setq rtn (concat rtn ;; previous list - lsep ;; list separator + (setq rtn (concat rtn istart term sublist iend isep))) + (t (setq rtn (concat rtn ;; previous list + lsep ;; list separator (org-list-to-generic sublist p) - lsep ;; list separator + lsep ;; list separator ))))) (format wrapper rtn)))) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-mac-message.el --- a/lisp/org/org-mac-message.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-mac-message.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: John Wiegley <johnw@gnu.org> ;; Christopher Suckling <suckling at gmail dot com> -;; Version: 7.01 +;; Version: 7.3 ;; Keywords: outlines, hypermedia, calendar, wp ;; This file is part of GNU Emacs. diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-macs.el --- a/lisp/org/org-macs.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-macs.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -38,11 +38,27 @@ (defmacro declare-function (fn file &optional arglist fileonly)))) (declare-function org-add-props "org-compat" (string plist &rest props)) +(declare-function org-string-match-p "org-compat" (&rest args)) + +(defmacro org-called-interactively-p (&optional kind) + `(if (featurep 'xemacs) + (interactive-p) + (if (or (> emacs-major-version 23) + (and (>= emacs-major-version 23) + (>= emacs-minor-version 2))) + (called-interactively-p ,kind) + (interactive-p)))) (defmacro org-bound-and-true-p (var) "Return the value of symbol VAR if it is bound, else nil." `(and (boundp (quote ,var)) ,var)) +(defun org-string-nw-p (s) + "Is S a string with a non-white character?" + (and (stringp s) + (org-string-match-p "\\S-" s) + s)) + (defun org-not-nil (v) "If V not nil, and also not the string \"nil\", then return V. Otherwise return nil." @@ -283,63 +299,6 @@ (match-beginning 0) string))) (replace-match newtext fixedcase literal string)) -(defmacro org-with-limited-levels (&rest body) - "Execute BODY with limited number of outline levels." - `(let* ((outline-regexp (org-get-limited-outline-regexp))) - ,@body)) - -(defvar org-odd-levels-only) ; defined in org.el -(defvar org-inlinetask-min-level) ; defined in org-inlinetask.el -(defun org-get-limited-outline-regexp () - "Return outline-regexp with limited number of levels. -The number of levels is controlled by `org-inlinetask-min-level'" - (if (or (not (org-mode-p)) (not (featurep 'org-inlinetask))) - - outline-regexp - (let* ((limit-level (1- org-inlinetask-min-level)) - (nstars (if org-odd-levels-only (1- (* limit-level 2)) limit-level))) - (format "\\*\\{1,%d\\} " nstars)))) - - -;;; Saving and restoring visibility - -(defun org-outline-overlay-data (&optional use-markers) - "Return a list of the locations of all outline overlays. -The are overlays with the `invisible' property value `outline'. -The return values is a list of cons cells, with start and stop -positions for each overlay. -If USE-MARKERS is set, return the positions as markers." - (let (beg end) - (save-excursion - (save-restriction - (widen) - (delq nil - (mapcar (lambda (o) - (when (eq (overlay-get o 'invisible) 'outline) - (setq beg (overlay-start o) - end (overlay-end o)) - (and beg end (> end beg) - (if use-markers - (cons (move-marker (make-marker) beg) - (move-marker (make-marker) end)) - (cons beg end))))) - (overlays-in (point-min) (point-max)))))))) - -(autoload 'show-all "outline" nil t) - -(defun org-set-outline-overlay-data (data) - "Create visibility overlays for all positions in DATA. -DATA should have been made by `org-outline-overlay-data'." - (let (o) - (save-excursion - (save-restriction - (widen) - (show-all) - (mapc (lambda (c) - (setq o (make-overlay (car c) (cdr c))) - (overlay-put o 'invisible 'outline)) - data))))) - (defmacro org-save-outline-visibility (use-markers &rest body) "Save and restore outline visibility around BODY. If USE-MARKERS is non-nil, use markers for the positions. @@ -359,6 +318,22 @@ (and (markerp (cdr c)) (move-marker (cdr c) nil))) data))))) +(defmacro org-with-limited-levels (&rest body) + "Execute BODY with limited number of outline levels." + `(let* ((outline-regexp (org-get-limited-outline-regexp))) + ,@body)) + +(defvar org-odd-levels-only) ; defined in org.el +(defvar org-inlinetask-min-level) ; defined in org-inlinetask.el +(defun org-get-limited-outline-regexp () + "Return outline-regexp with limited number of levels. +The number of levels is controlled by `org-inlinetask-min-level'" + (if (or (not (org-mode-p)) (not (featurep 'org-inlinetask))) + + outline-regexp + (let* ((limit-level (1- org-inlinetask-min-level)) + (nstars (if org-odd-levels-only (1- (* limit-level 2)) limit-level))) + (format "\\*\\{1,%d\\} " nstars)))) (provide 'org-macs) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-mew.el --- a/lisp/org/org-mew.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-mew.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Tokuya Kameshima <kames at fa2 dot so-net dot ne dot jp> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. @@ -81,7 +81,7 @@ (mew-case-folder (mew-sinfo-get-case) (nth 1 (mew-refile-get msgnum))) (mew-summary-folder-name))) - message-id from to subject desc link) + message-id from to subject desc link date date-ts date-ts-ia) (save-window-excursion (if (fboundp 'mew-summary-set-message-buffer) (mew-summary-set-message-buffer folder-name msgnum) @@ -89,9 +89,19 @@ (setq message-id (mew-header-get-value "Message-Id:")) (setq from (mew-header-get-value "From:")) (setq to (mew-header-get-value "To:")) + (setq date (mew-header-get-value "Date:")) + (setq date-ts (and date (format-time-string + (org-time-stamp-format t) + (date-to-time date)))) + (setq date-ts-ia (and date (format-time-string + (org-time-stamp-format t t) + (date-to-time date)))) (setq subject (mew-header-get-value "Subject:"))) (org-store-link-props :type "mew" :from from :to to :subject subject :message-id message-id) + (when date + (org-add-link-props :date date :date-timestamp date-ts + :date-timestamp-inactive date-ts-ia)) (setq message-id (org-remove-angle-brackets message-id)) (setq desc (org-email-link-description)) (setq link (org-make-link "mew:" folder-name diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-mhe.el --- a/lisp/org/org-mhe.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-mhe.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Thomas Baumann <thomas dot baumann at ch dot tum dot de> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -83,13 +83,22 @@ "Store a link to an MH-E folder or message." (when (or (equal major-mode 'mh-folder-mode) (equal major-mode 'mh-show-mode)) - (let ((from (org-mhe-get-header "From:")) - (to (org-mhe-get-header "To:")) - (message-id (org-mhe-get-header "Message-Id:")) - (subject (org-mhe-get-header "Subject:")) - link desc) + (let* ((from (org-mhe-get-header "From:")) + (to (org-mhe-get-header "To:")) + (message-id (org-mhe-get-header "Message-Id:")) + (subject (org-mhe-get-header "Subject:")) + (date (org-mhe-get-header "Date:")) + (date-ts (and date (format-time-string + (org-time-stamp-format t) (date-to-time date)))) + (date-ts-ia (and date (format-time-string + (org-time-stamp-format t t) + (date-to-time date)))) + link desc) (org-store-link-props :type "mh" :from from :to to :subject subject :message-id message-id) + (when date + (org-add-link-props :date date :date-timestamp date-ts + :date-timestamp-inactive date-ts-ia)) (setq desc (org-email-link-description)) (setq link (org-make-link "mhe:" (org-mhe-get-message-real-folder) "#" (org-remove-angle-brackets message-id))) @@ -181,7 +190,7 @@ (if (equal major-mode 'mh-folder-mode) (mh-show) (mh-show-show)) - header-field))) + (org-trim header-field)))) (defun org-mhe-follow-link (folder article) "Follow an MH-E link to FOLDER and ARTICLE. diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-mks.el --- a/lisp/org/org-mks.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-mks.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-mobile.el --- a/lisp/org/org-mobile.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-mobile.el Thu Nov 11 22:10:19 2010 -0600 @@ -4,7 +4,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -26,10 +26,11 @@ ;;; Commentary: ;; ;; This file contains the code to interact with Richard Moreland's iPhone -;; application MobileOrg. This code is documented in Appendix B of the -;; Org-mode manual. The code is not specific for the iPhone, however. -;; Any external viewer/flagging/editing application that uses the same -;; conventions could be used. +;; application MobileOrg, as well as with the Android version by Matthew Jones. +;; This code is documented in Appendix B of the Org-mode manual. The code is +;; not specific for the iPhone and Android - any external +;; viewer/flagging/editing application that uses the same conventions could +;; be used. (require 'org) (require 'org-agenda) @@ -90,12 +91,29 @@ This is a single password which is used for AES-256 encryption. The same password must also be set in the MobileOrg application. All Org files, including mobileorg.org will be encrypted using this password. + +SECURITY CONSIDERATIONS: + Note that, when Org runs the encryption commands, the password could -be visible on your system with the `ps' command. So this method is only -intended to keep the files secure on the server, not on your own machine." +be visible briefly on your system with the `ps' command. So this method is +only intended to keep the files secure on the server, not on your own machine. + +Also, if you set this variable in an init file (.emacs or .emacs.d/init.el +or custom.el...) and if that file is stored in a way so that other can read +it, this also limits the security of this approach. You can also leave +this variable empty - Org will then ask for the password once per Emacs +session." :group 'org-mobile :type '(string :tag "Password")) +(defvar org-mobile-encryption-password-session nil) + +(defun org-mobile-encryption-password () + (or (org-string-nw-p org-mobile-encryption-password) + (org-string-nw-p org-mobile-encryption-password-session) + (setq org-mobile-encryption-password-session + (read-passwd "Password for MobileOrg: " t)))) + (defcustom org-mobile-inbox-for-pull "~/org/from-mobile.org" "The file where captured notes and flags will be appended to. During the execution of `org-mobile-pull', the file @@ -133,7 +151,7 @@ (string :tag "Selection Keys")))) (defcustom org-mobile-force-id-on-agenda-items t - "Non-nil means make all agenda items carry and ID." + "Non-nil means make all agenda items carry an ID." :group 'org-mobile :type 'boolean) @@ -331,6 +349,7 @@ (defun org-mobile-check-setup () "Check if org-mobile-directory has been set up." + (org-mobile-cleanup-encryption-tempfile) (unless (and org-directory (stringp org-directory) (string-match "\\S-" org-directory) @@ -356,7 +375,7 @@ (string-match "\\S-" org-mobile-checksum-binary)) (error "No executable found to compute checksums")) (when org-mobile-use-encryption - (unless (string-match "\\S-" org-mobile-encryption-password) + (unless (string-match "\\S-" (org-mobile-encryption-password)) (error "To use encryption, you must set `org-mobile-encryption-password'")) (unless (file-writable-p org-mobile-encryption-tempfile) @@ -371,6 +390,8 @@ (lambda (a b) (string< (cdr a) (cdr b))))) (def-todo (default-value 'org-todo-keywords)) (def-tags (default-value 'org-tag-alist)) + (target-file (expand-file-name org-mobile-index-file + org-mobile-directory)) file link-name todo-kwds done-kwds tags drawers entry kwds dwds twds) (org-prepare-agenda-buffers (mapcar 'car files-alist)) @@ -389,7 +410,9 @@ (t nil))) org-tag-alist-for-agenda)))) (with-temp-file - (expand-file-name org-mobile-index-file org-mobile-directory) + (if org-mobile-use-encryption + org-mobile-encryption-tempfile + target-file) (while (setq entry (pop def-todo)) (insert "#+READONLY\n") (setq kwds (mapcar (lambda (x) (if (string-match "(" x) @@ -430,7 +453,11 @@ (insert (format "* [[file:%s][%s]]\n" link-name link-name))) (push (cons org-mobile-index-file (md5 (buffer-string))) - org-mobile-checksum-files)))) + org-mobile-checksum-files)) + (when org-mobile-use-encryption + (org-mobile-encrypt-and-move org-mobile-encryption-tempfile + target-file) + (org-mobile-cleanup-encryption-tempfile)))) (defun org-mobile-copy-agenda-files () "Copy all agenda files to the stage or WebDAV directory." @@ -452,14 +479,20 @@ (when (string-match "[a-fA-F0-9]\\{30,40\\}" check) (push (cons link-name (match-string 0 check)) org-mobile-checksum-files)))) + (setq file (expand-file-name org-mobile-capture-file org-mobile-directory)) (save-excursion (setq buf (find-file file)) - (and (= (point-min) (point-max)) (insert "\n")) - (save-buffer) + (when (and (= (point-min) (point-max))) + (insert "\n") + (save-buffer) + (when org-mobile-use-encryption + (write-file org-mobile-encryption-tempfile) + (org-mobile-encrypt-and-move org-mobile-encryption-tempfile file))) (push (cons org-mobile-capture-file (md5 (buffer-string))) org-mobile-checksum-files)) + (org-mobile-cleanup-encryption-tempfile) (kill-buffer buf))) (defun org-mobile-write-checksums () @@ -606,14 +639,30 @@ (if (org-bound-and-true-p org-mobile-force-id-on-agenda-items) (org-id-get m 'create) - (org-entry-get m "ID"))) + (or (org-entry-get m "ID") + (org-mobile-get-outline-path-link m)))) (insert " :PROPERTIES:\n :ORIGINAL_ID: " id "\n :END:\n"))))) (beginning-of-line 2)) - (push (cons (file-name-nondirectory file) (md5 (buffer-string))) + (push (cons "agendas.org" (md5 (buffer-string))) org-mobile-checksum-files)) (message "Agenda written to Org file %s" file))) +(defun org-mobile-get-outline-path-link (pom) + (org-with-point-at pom + (concat "olp:" + (org-mobile-escape-olp (file-name-nondirectory buffer-file-name)) + "/" + (mapconcat 'org-mobile-escape-olp + (org-get-outline-path) + "/") + "/" + (org-mobile-escape-olp (nth 4 (org-heading-components)))))) + +(defun org-mobile-escape-olp (s) + (let ((table '((?: . "%3a") (?\[ . "%5b") (?\] . "%5d") (?/ . "%2f")))) + (org-link-escape s table))) + ;;;###autoload (defun org-mobile-create-sumo-agenda () "Create a file that contains all custom agenda views." @@ -632,8 +681,9 @@ (when sumo (org-store-agenda-views)) (when org-mobile-use-encryption - (org-mobile-encrypt-file file1 file) - (delete-file file1)))) + (org-mobile-encrypt-and-move file1 file) + (delete-file file1) + (org-mobile-cleanup-encryption-tempfile)))) (defun org-mobile-encrypt-and-move (infile outfile) "Encrypt INFILE locally to INFILE_enc, then move it to OUTFILE. @@ -649,7 +699,8 @@ "Encrypt INFILE to OUTFILE, using `org-mobile-encryption-password'." (shell-command (format "openssl enc -aes-256-cbc -salt -pass %s -in %s -out %s" - (shell-quote-argument (concat "pass:" org-mobile-encryption-password)) + (shell-quote-argument (concat "pass:" + (org-mobile-encryption-password))) (shell-quote-argument (expand-file-name infile)) (shell-quote-argument (expand-file-name outfile))))) @@ -657,10 +708,17 @@ "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" - (shell-quote-argument (concat "pass:" org-mobile-encryption-password)) + (shell-quote-argument (concat "pass:" + (org-mobile-encryption-password))) (shell-quote-argument (expand-file-name infile)) (shell-quote-argument (expand-file-name outfile))))) +(defun org-mobile-cleanup-encryption-tempfile () + "Remove the encryption tempfile if it exists." + (and (stringp org-mobile-encryption-tempfile) + (file-exists-p org-mobile-encryption-tempfile) + (delete-file org-mobile-encryption-tempfile))) + (defun org-mobile-move-capture () "Move the contents of the capture file to the inbox file. Return a marker to the location where the new content has been added. @@ -673,7 +731,7 @@ (capture-buffer (if (not org-mobile-use-encryption) (find-file-noselect capture-file) - (delete-file org-mobile-encryption-tempfile) + (org-mobile-cleanup-encryption-tempfile) (setq encfile (concat org-mobile-encryption-tempfile "_enc")) (copy-file capture-file encfile) (org-mobile-decrypt-file encfile org-mobile-encryption-tempfile) @@ -698,7 +756,8 @@ (kill-buffer capture-buffer) (when org-mobile-use-encryption (org-mobile-encrypt-and-move org-mobile-encryption-tempfile - capture-file)) + capture-file) + (org-mobile-cleanup-encryption-tempfile)) (if not-empty insertion-point))) (defun org-mobile-update-checksum-for-capture-file (buffer-string) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-mouse.el --- a/lisp/org/org-mouse.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-mouse.el Thu Nov 11 22:10:19 2010 -0600 @@ -4,7 +4,7 @@ ;; ;; Author: Piotr Zielinski <piotr dot zielinski at gmail dot com> ;; Maintainer: Carsten Dominik <carsten at orgmode dot org> -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -148,6 +148,7 @@ (declare-function org-agenda-change-all-lines "org-agenda" (newhead hdmarker &optional fixface just-this)) (declare-function org-verify-change-for-undo "org-agenda" (l1 l2)) +(declare-function org-apply-on-list "org-list" (function init-value &rest args)) (defvar org-mouse-plain-list-regexp "\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) " "Regular expression that matches a plain list.") @@ -576,14 +577,11 @@ (goto-char (second contextdata)) (re-search-forward ".*" (third contextdata)))))) -(defun org-mouse-for-each-item (function) - (save-excursion - (ignore-errors - (while t (org-previous-item))) - (ignore-errors - (while t - (funcall function) - (org-next-item))))) +(defun org-mouse-for-each-item (funct) + ;; Functions called by `org-apply-on-list' need an argument + (let ((wrap-fun (lambda (c) (funcall funct)))) + (when (org-in-item-p) + (org-apply-on-list wrap-fun nil)))) (defun org-mouse-bolp () "Return true if there only spaces, tabs, and '*' before point. diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-plot.el --- a/lisp/org/org-plot.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-plot.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Eric Schulte <schulte dot eric at gmail dot com> ;; Keywords: tables, plotting ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-protocol.el --- a/lisp/org/org-protocol.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-protocol.el Thu Nov 11 22:10:19 2010 -0600 @@ -9,7 +9,7 @@ ;; Author: Ross Patterson <me AT rpatterson DOT net> ;; Maintainer: Sebastian Rose <sebastian_rose AT gmx DOT de> ;; Keywords: org, emacsclient, wp -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. ;; @@ -260,7 +260,7 @@ :group 'org-protocol :type '(alist)) -(defcustom org-protocol-default-template-key "w" +(defcustom org-protocol-default-template-key nil "The default org-remember-templates key to use." :group 'org-protocol :type 'string) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-publish.el --- a/lisp/org/org-publish.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-publish.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: David O'Toole <dto@gnu.org> ;; Maintainer: Carsten Dominik <carsten DOT dominik AT gmail DOT com> ;; Keywords: hypermedia, outlines, wp -;; Version: 7.01 +;; Version: 7.3 ;; This file is part of GNU Emacs. ;; @@ -71,11 +71,14 @@ each element is a string, uniquely identifying the project. The CDR of each element is in one of the following forms: - (:property value :property value ... ) +1. A well-formed property list with an even number of elements, alternating + keys and values, specifying parameters for the publishing process. -OR, + (:property value :property value ... ) - (:components (\"project-1\" \"project-2\" ...)) +2. A meta-project definition, specifying of a list of sub-projects: + + (:components (\"project-1\" \"project-2\" ...)) When the CDR of an element of org-publish-project-alist is in this second form, the elements of the list after :components are @@ -92,7 +95,8 @@ :base-directory Directory containing publishing source files :base-extension Extension (without the dot!) of source files. - This can be a regular expression. + This can be a regular expression. If not given, + \"org\" will be used as default extension. :publishing-directory Directory (possibly remote) where output files will be published @@ -188,7 +192,14 @@ The following properties control the creation of a concept index. - :makeindex Create a concept index." + :makeindex Create a concept index. + +Other properties affecting publication. + + :body-only Set this to 't' to publish only the body of the + documents, excluding everything outside and + including the <body> tags in HTML, or + \begin{document}..\end{document} in LaTeX." :group 'org-publish :type 'alist) @@ -464,13 +475,19 @@ (unless (plist-get (cdr prj) :components) ;; [[info:org:Selecting%20files]] shows how this is supposed to work: (let* ((r (plist-get (cdr prj) :recursive)) - (b (expand-file-name (plist-get (cdr prj) :base-directory))) + (b (expand-file-name (file-name-as-directory + (plist-get (cdr prj) :base-directory)))) (x (or (plist-get (cdr prj) :base-extension) "org")) (e (plist-get (cdr prj) :exclude)) (i (plist-get (cdr prj) :include)) (xm (concat "^" b (if r ".+" "[^/]+") "\\.\\(" x "\\)$"))) (when (or - (and i (string-match i filename)) + (and + i + (member filename + (mapcar + (lambda (file) (expand-file-name file b)) + i))) (and (not (and e (string-match e filename))) (string-match xm filename))) @@ -507,7 +524,9 @@ (setq export-buf-or-file (funcall (intern (concat "org-export-as-" format)) (plist-get plist :headline-levels) - nil plist nil nil pub-dir)) + nil plist nil + (plist-get plist :body-only) + pub-dir)) (when (and (bufferp export-buf-or-file) (buffer-live-p export-buf-or-file)) (set-buffer export-buf-or-file) @@ -558,14 +577,32 @@ See `org-publish-org-to' to the list of arguments." (org-publish-org-to "org" plist filename pub-dir)) +(defun org-publish-org-to-ascii (plist filename pub-dir) + "Publish an org file to ASCII. +See `org-publish-org-to' to the list of arguments." + (org-publish-with-aux-preprocess-maybe + (org-publish-org-to "ascii" plist filename pub-dir))) + +(defun org-publish-org-to-latin1 (plist filename pub-dir) + "Publish an org file to Latin-1. +See `org-publish-org-to' to the list of arguments." + (org-publish-with-aux-preprocess-maybe + (org-publish-org-to "latin1" plist filename pub-dir))) + +(defun org-publish-org-to-utf8 (plist filename pub-dir) + "Publish an org file to UTF-8. +See `org-publish-org-to' to the list of arguments." + (org-publish-with-aux-preprocess-maybe + (org-publish-org-to "utf8" plist filename pub-dir))) + (defun org-publish-attachment (plist filename pub-dir) "Publish a file with no transformation of any kind. See `org-publish-org-to' to the list of arguments." ;; make sure eshell/cp code is loaded - (unless (file-directory-p pub-dir) - (make-directory pub-dir t)) - (or (equal (expand-file-name (file-name-directory filename)) - (file-name-as-directory (expand-file-name pub-dir))) + (unless (file-directory-p pub-dir) + (make-directory pub-dir t)) + (or (equal (expand-file-name (file-name-directory filename)) + (file-name-as-directory (expand-file-name pub-dir))) (copy-file filename (expand-file-name (file-name-nondirectory filename) pub-dir) t))) @@ -585,14 +622,22 @@ (error "File %s not part of any known project" (abbreviate-file-name filename))))) (project-plist (cdr project)) - (ftname (file-truename filename)) + (ftname (expand-file-name filename)) (publishing-function (or (plist-get project-plist :publishing-function) 'org-publish-org-to-html)) - (base-dir (file-name-as-directory - (file-truename (plist-get project-plist :base-directory)))) - (pub-dir (file-name-as-directory - (file-truename (plist-get project-plist :publishing-directory)))) + (base-dir + (file-name-as-directory + (expand-file-name + (or (plist-get project-plist :base-directory) + (error "Project %s does not have :base-directory defined" + (car project)))))) + (pub-dir + (file-name-as-directory + (file-truename + (or (plist-get project-plist :publishing-directory) + (error "Project %s does not have :publishing-directory defined" + (car project)))))) tmp-pub-dir) (unless no-cache @@ -770,7 +815,6 @@ (interactive "P") (when force (org-publish-remove-all-timestamps)) - ;; (org-publish-initialize-files-alist force) (save-window-excursion (let ((org-publish-use-timestamps-flag (if force nil org-publish-use-timestamps-flag))) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-remember.el --- a/lisp/org/org-remember.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-remember.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -157,7 +157,7 @@ Apart from these general escapes, you can access information specific to the link type that is created. For example, calling `remember' in emails or gnus will record the author and the subject of the message, which you can access -with %:author and %:subject, respectively. Here is a complete list of what +with %:fromname and %:subject, respectively. Here is a complete list of what is recorded for each link type. Link type | Available information @@ -167,7 +167,8 @@ | %:from %:fromname %:fromaddress | %:to %:toname %:toaddress | %:fromto (either \"to NAME\" or \"from NAME\") -gnus | %:group, for messages also all email fields +gnus | %:group, for messages also all email fields and + | %:org-date (the Date: header in Org format) w3, w3m | %:type %:url info | %:type %:file %:node calendar | %:type %:date" @@ -574,7 +575,7 @@ 'org-tags-completion-function nil nil nil 'org-tags-history))) (setq ins (mapconcat 'identity - (org-split-string ins (org-re "[^[:alnum:]_@]+")) + (org-split-string ins (org-re "[^[:alnum:]_@#%]+")) ":")) (when (string-match "\\S-" ins) (or (equal (char-before) ?:) (insert ":")) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-rmail.el --- a/lisp/org/org-rmail.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-rmail.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -59,10 +59,20 @@ (from (mail-fetch-field "from")) (to (mail-fetch-field "to")) (subject (mail-fetch-field "subject")) + (date (mail-fetch-field "date")) + (date-ts (and date (format-time-string + (org-time-stamp-format t) + (date-to-time date)))) + (date-ts-ia (and date (format-time-string + (org-time-stamp-format t t) + (date-to-time date)))) desc link) (org-store-link-props :type "rmail" :from from :to to :subject subject :message-id message-id) + (when date + (org-add-link-props :date date :date-timestamp date-ts + :date-timestamp-inactive date-ts-ia)) (setq message-id (org-remove-angle-brackets message-id)) (setq desc (org-email-link-description)) (setq link (org-make-link "rmail:" folder "#" message-id)) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-src.el --- a/lisp/org/org-src.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-src.el Thu Nov 11 22:10:19 2010 -0600 @@ -8,7 +8,7 @@ ;; Dan Davison <davison at stats dot ox dot ac dot uk> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -34,6 +34,8 @@ (require 'org-macs) (require 'org-compat) +(require 'ob-keys) +(require 'ob-comint) (eval-when-compile (require 'cl)) @@ -107,6 +109,10 @@ :group 'org-edit-structure :type 'integer) +(defvar org-src-strip-leading-and-trailing-blank-lines nil + "If non-nil, blank lines are removed when exiting the code edit +buffer.") + (defcustom org-edit-src-persistent-message t "Non-nil means show persistent exit help message while editing src examples. The message is shown in the header-line, which will be created in the @@ -147,7 +153,8 @@ (defcustom org-src-lang-modes '(("ocaml" . tuareg) ("elisp" . emacs-lisp) ("ditaa" . artist) - ("asymptote" . asy) ("dot" . fundamental) ("sqlite" . sql)) + ("asymptote" . asy) ("dot" . fundamental) ("sqlite" . sql) + ("calc" . fundamental)) "Alist mapping languages to their major mode. The key is the language name, the value is the string that should be inserted as the name of the major mode. For many languages this is @@ -165,6 +172,7 @@ (defvar org-src-mode-map (make-sparse-keymap)) (define-key org-src-mode-map "\C-c'" 'org-edit-src-exit) + (defvar org-edit-src-force-single-line nil) (defvar org-edit-src-from-org-mode nil) (defvar org-edit-src-allow-write-back-p t) @@ -181,6 +189,8 @@ immediately; otherwise it will ask whether you want to return to the existing edit buffer.") +(defvar org-src-babel-info nil) + (define-minor-mode org-src-mode "Minor mode for language major mode buffers generated by org. This minor mode is turned on in two situations: @@ -189,26 +199,30 @@ There is a mode hook, and keybindings for `org-edit-src-exit' and `org-edit-src-save'") -(defun org-edit-src-code (&optional context code edit-buffer-name) +(defun org-edit-src-code (&optional context code edit-buffer-name quietp) "Edit the source code example at point. -The example is copied to a separate buffer, and that buffer is switched -to the correct language mode. When done, exit with \\[org-edit-src-exit]. -This will remove the original code in the Org buffer, and replace it with -the edited version. Optional argument CONTEXT is used by -\\[org-edit-src-save] when calling this function." +The example is copied to a separate buffer, and that buffer is +switched to the correct language mode. When done, exit with +\\[org-edit-src-exit]. This will remove the original code in the +Org buffer, and replace it with the edited version. Optional +argument CONTEXT is used by \\[org-edit-src-save] when calling +this function. See \\[org-src-window-setup] to configure the +display of windows containing the Org buffer and the code +buffer." (interactive) (unless (eq context 'save) (setq org-edit-src-saved-temp-window-config (current-window-configuration))) - (let ((line (org-current-line)) - (col (current-column)) + (let ((mark (and (org-region-active-p) (mark))) (case-fold-search t) (info (org-edit-src-find-region-and-lang)) + (babel-info (org-babel-get-src-block-info 'light)) (org-mode-p (eq major-mode 'org-mode)) (beg (make-marker)) (end (make-marker)) (preserve-indentation org-src-preserve-indentation) (allow-write-back-p (null code)) - block-nindent total-nindent ovl lang lang-f single lfmt begline buffer msg) + block-nindent total-nindent ovl lang lang-f single lfmt buffer msg + begline markline markcol line col) (if (not info) nil (setq beg (move-marker beg (nth 0 info)) @@ -226,6 +240,10 @@ block-nindent (nth 5 info) lang-f (intern (concat lang "-mode")) begline (save-excursion (goto-char beg) (org-current-line))) + (if (and mark (>= mark beg) (<= mark end)) + (save-excursion (goto-char mark) + (setq markline (org-current-line) + markcol (current-column)))) (if (equal lang-f 'table.el-mode) (setq lang-f (lambda () (text-mode) @@ -235,7 +253,10 @@ (org-set-local 'org-edit-src-content-indentation 0)))) (unless (functionp lang-f) (error "No such language mode: %s" lang-f)) - (org-goto-line line) + (save-excursion + (if (> (point) end) (goto-char end)) + (setq line (org-current-line) + col (current-column))) (if (and (setq buffer (org-edit-src-find-buffer beg end)) (if org-src-ask-before-returning-to-edit-buffer (y-or-n-p "Return to existing edit buffer? [n] will revert changes: ") t)) @@ -267,11 +288,16 @@ (unless preserve-indentation (setq total-nindent (or (org-do-remove-indentation) 0))) (let ((org-inhibit-startup t)) - (funcall lang-f)) + (condition-case e + (funcall lang-f) + (error + (error "Language mode `%s' fails with: %S" lang-f (nth 1 e))))) (set (make-local-variable 'org-edit-src-force-single-line) single) (set (make-local-variable 'org-edit-src-from-org-mode) org-mode-p) (set (make-local-variable 'org-edit-src-allow-write-back-p) allow-write-back-p) (set (make-local-variable 'org-src-preserve-indentation) preserve-indentation) + (when babel-info + (set (make-local-variable 'org-src-babel-info) babel-info)) (when lfmt (set (make-local-variable 'org-coderef-label-format) lfmt)) (when org-mode-p @@ -279,6 +305,12 @@ (while (re-search-forward "^," nil t) (if (eq (org-current-line) line) (setq total-nindent (1+ total-nindent))) (replace-match ""))) + (when markline + (org-goto-line (1+ (- markline begline))) + (org-move-to-column + (if preserve-indentation markcol (max 0 (- markcol total-nindent)))) + (push-mark (point) 'no-message t) + (setq deactivate-mark nil)) (org-goto-line (1+ (- line begline))) (org-move-to-column (if preserve-indentation col (max 0 (- col total-nindent)))) @@ -290,7 +322,7 @@ (set-buffer-modified-p nil) (and org-edit-src-persistent-message (org-set-local 'header-line-format msg))) - (message "%s" msg) + (unless quietp (message "%s" msg)) t))) (defun org-edit-src-continue (e) @@ -321,6 +353,8 @@ (if (eq context 'edit) (delete-other-windows)) (org-switch-to-buffer-other-window buffer) (if (eq context 'exit) (delete-other-windows))) + ('switch-invisibly + (set-buffer buffer)) (t (message "Invalid value %s for org-src-window-setup" (symbol-name org-src-window-setup)) @@ -552,11 +586,12 @@ (delta 0) code line col indent) (when allow-write-back-p (unless preserve-indentation (untabify (point-min) (point-max))) - (save-excursion - (goto-char (point-min)) - (if (looking-at "[ \t\n]*\n") (replace-match "")) - (unless macro - (if (re-search-forward "\n[ \t\n]*\\'" nil t) (replace-match ""))))) + (if org-src-strip-leading-and-trailing-blank-lines + (save-excursion + (goto-char (point-min)) + (if (looking-at "[ \t\n]*\n") (replace-match "")) + (unless macro + (if (re-search-forward "\n[ \t\n]*\\'" nil t) (replace-match "")))))) (setq line (if (org-bound-and-true-p org-edit-src-force-single-line) 1 (org-current-line)) @@ -654,6 +689,122 @@ (org-add-hook 'org-src-mode-hook 'org-src-mode-configure-edit-buffer) + +(defun org-src-associate-babel-session (info) + "Associate edit buffer with comint session." + (interactive) + (let ((session (cdr (assoc :session (nth 2 info))))) + (and session (not (string= session "none")) + (org-babel-comint-buffer-livep session) + ((lambda (f) (and (fboundp f) (funcall f session))) + (intern (format "org-babel-%s-associate-session" (nth 0 info))))))) + +(defun org-src-babel-configure-edit-buffer () + (when org-src-babel-info + (org-src-associate-babel-session org-src-babel-info))) + +(org-add-hook 'org-src-mode-hook 'org-src-babel-configure-edit-buffer) +(defmacro org-src-do-at-code-block (&rest body) + "Execute a command from an edit buffer in the Org-mode buffer." + `(let ((beg-marker org-edit-src-beg-marker)) + (if beg-marker + (with-current-buffer (marker-buffer beg-marker) + (goto-char (marker-position beg-marker)) + ,@body)))) + +(defun org-src-do-key-sequence-at-code-block (&optional key) + "Execute key sequence at code block in the source Org buffer. +The command bound to KEY in the Org-babel key map is executed +remotely with point temporarily at the start of the code block in +the Org buffer. + +This command is not bound to a key by default, to avoid conflicts +with language major mode bindings. To bind it to C-c @ in all +language major modes, you could use + + (add-hook 'org-src-mode-hook + (lambda () (define-key org-src-mode-map \"\\C-c@\" + 'org-src-do-key-sequence-at-code-block))) + +In that case, for example, C-c @ t issued in code edit buffers +would tangle the current Org code block, C-c @ e would execute +the block and C-c @ h would display the other available +Org-babel commands." + (interactive "kOrg-babel key: ") + (if (equal key (kbd "C-g")) (keyboard-quit) + (org-edit-src-save) + (org-src-do-at-code-block + (call-interactively + (lookup-key org-babel-map key))))) + +(defcustom org-src-tab-acts-natively nil + "If non-nil, the effect of TAB in a code block is as if it were +issued in the language major mode buffer." + :type 'boolean + :group 'org-babel) + +(defun org-src-native-tab-command-maybe () + "Perform language-specific TAB action. +Alter code block according to effect of TAB in the language major +mode." + (and org-src-tab-acts-natively + (let ((org-src-strip-leading-and-trailing-blank-lines nil)) + (org-babel-do-key-sequence-in-edit-buffer (kbd "TAB"))))) + +(add-hook 'org-tab-first-hook 'org-src-native-tab-command-maybe) + +(defun org-src-font-lock-fontify-block (lang start end) + "Fontify code block. +This function is called by emacs automatic fontification, as long +as `org-src-fontify-natively' is non-nil. For manual +fontification of code blocks see `org-src-fontify-block' and +`org-src-fontify-buffer'" + (let* ((lang-mode (org-src-get-lang-mode lang)) + (string (buffer-substring-no-properties start end)) + (modified (buffer-modified-p)) + (org-buffer (current-buffer)) pos next) + (remove-text-properties start end '(face nil)) + (with-current-buffer + (get-buffer-create + (concat " org-src-fontification:" (symbol-name lang-mode))) + (delete-region (point-min) (point-max)) + (insert string) + (unless (eq major-mode lang-mode) (funcall lang-mode)) + (font-lock-fontify-buffer) + (setq pos (point-min)) + (while (setq next (next-single-property-change pos 'face)) + (put-text-property + (+ start (1- pos)) (+ start next) 'face + (get-text-property pos 'face) org-buffer) + (setq pos next))) + (add-text-properties + start end + '(font-lock-fontified t fontified t font-lock-multiline t)) + (set-buffer-modified-p modified)) + t) ;; Tell `org-fontify-meta-lines-and-blocks' that we fontified + +(defun org-src-fontify-block () + "Fontify code block at point." + (interactive) + (save-excursion + (let ((org-src-fontify-natively t) + (info (org-edit-src-find-region-and-lang))) + (font-lock-fontify-region (nth 0 info) (nth 1 info))))) + +(defun org-src-fontify-buffer () + "Fontify all code blocks in the current buffer" + (interactive) + (org-babel-map-src-blocks nil + (org-src-fontify-block))) + +(defun org-src-get-lang-mode (lang) + "Return major mode that should be used for LANG. +LANG is a string, and the returned major mode is a symbol." + (intern + (concat + ((lambda (l) (if (symbolp l) (symbol-name l) l)) + (or (cdr (assoc lang org-src-lang-modes)) lang)) "-mode"))) + (provide 'org-src) ;; arch-tag: 6a1fc84f-dec7-47be-a416-64be56bea5d8 diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-table.el --- a/lisp/org/org-table.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-table.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -342,17 +342,21 @@ (defun org-table-cookie-line-p (line) "Is this a table line with only alignment/width cookies?" - (save-match-data (and (string-match "[<>]\\|&[lg]t;" line) - (or (string-match "\\`[ \t]*|[ \t]*/[ \t]*\\(|[ \t<>0-9|lgt&;]+\\)\\'" line) - (string-match "\\(\\`[ \t<>lr0-9|gt&;]+\\'\\)" line)) + (or (string-match + "\\`[ \t]*|[ \t]*/[ \t]*\\(|[ \t<>0-9|lrcgt&;]+\\)\\'" line) + (string-match "\\(\\`[ \t<>lrc0-9|gt&;]+\\'\\)" line)) (not (delq nil (mapcar (lambda (s) (not (or (equal s "") - (string-match "\\`<\\([lr]?[0-9]+\\|[lr]\\)>\\'" s) - (string-match "\\`<\\([lr]?[0-9]+\\|[lr]\\)>\\'" s)))) - (org-split-string (match-string 1 line) "[ \t]*|[ \t]*"))))))) + (string-match + "\\`<\\([lrc]?[0-9]+\\|[lrc]\\)>\\'" s) + (string-match + "\\`<\\([lrc]?[0-9]+\\|[lrc]\\)>\\'" + s)))) + (org-split-string (match-string 1 line) + "[ \t]*|[ \t]*"))))))) (defconst org-table-translate-regexp (concat "\\(" "@[-0-9I$]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\)") @@ -369,8 +373,9 @@ (if (y-or-n-p "Convert table to Org-mode table? ") (org-table-convert))) ((org-at-table-p) - (if (y-or-n-p "Convert table to table.el table? ") - (org-table-convert))) + (when (y-or-n-p "Convert table to table.el table? ") + (org-table-align) + (org-table-convert))) (t (call-interactively 'table-insert)))) (defun org-table-create-or-convert-from-region (arg) @@ -453,7 +458,7 @@ (t 1)))) (goto-char beg) (if (equal separator '(4)) - (while (<= (point) end) + (while (< (point) end) ;; parse the csv stuff (cond ((looking-at "^") (insert "| ")) @@ -656,9 +661,9 @@ (goto-char beg) (setq narrow (and org-table-do-narrow org-format-transports-properties-p - (re-search-forward "<[rl]?[0-9]+>" end t))) + (re-search-forward "<[lrc]?[0-9]+>" end t))) (goto-char beg) - (setq falign (re-search-forward "<[rl][0-9]*>" end t)) + (setq falign (re-search-forward "<[lrc][0-9]*>" end t)) (goto-char beg) ;; Get the rows (setq lines (org-split-string @@ -699,7 +704,7 @@ (setq c column fmax nil falign1 nil) (while c (setq e (pop c)) - (when (and (stringp e) (string-match "^<\\([rl]\\)?\\([0-9]+\\)?>$" e)) + (when (and (stringp e) (string-match "^<\\([lrc]\\)?\\([0-9]+\\)?>$" e)) (if (match-end 1) (setq falign1 (match-string 1 e))) (if (and org-table-do-narrow (match-end 2)) (setq fmax (string-to-number (match-string 2 e)) c nil)))) @@ -1150,11 +1155,14 @@ (defun org-table-current-column () "Find out which column we are in." + (interactive) + (if (interactive-p) (org-table-check-inside-data-field)) (save-excursion (let ((cnt 0) (pos (point))) (beginning-of-line 1) (while (search-forward "|" pos t) (setq cnt (1+ cnt))) + (if (interactive-p) (message "In table column %d" cnt)) cnt))) (defun org-table-current-dline () @@ -4254,7 +4262,7 @@ (lambda (x) (if (eq x 'hline) "|----+----|" - (concat "| " (mapconcat 'identity x " | ") " |"))) + (concat "| " (mapconcat 'org-html-expand x " | ") " |"))) table) splicep)) (if (string-match "\n+\\'" html) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-taskjuggler.el --- a/lisp/org/org-taskjuggler.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-taskjuggler.el Thu Nov 11 22:10:19 2010 -0600 @@ -4,7 +4,7 @@ ;; ;; Emacs Lisp Archive Entry ;; Filename: org-taskjuggler.el -;; Version: 7.01 +;; Version: 7.3 ;; Author: Christian Egli ;; Maintainer: Christian Egli ;; Keywords: org, taskjuggler, project planning @@ -503,7 +503,7 @@ (parts (split-string headline)) (id (org-taskjuggler-clean-id (downcase (pop parts))))) ; try to add more parts of the headline to make it unique - (while (member id unique-ids) + (while (and (member id unique-ids) (car parts)) (setq id (concat id "_" (org-taskjuggler-clean-id (downcase (pop parts)))))) ; if its still not unique add "_" (while (member id unique-ids) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-timer.el --- a/lisp/org/org-timer.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-timer.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -31,7 +31,7 @@ (require 'org) -(declare-function org-show-notification "org-clock" (parameters)) +(declare-function org-notify "org-clock" (notification &optional play-sound)) (declare-function org-agenda-error "org-agenda" ()) (defvar org-timer-start-time nil @@ -145,25 +145,33 @@ (org-timer-set-mode-line 'off)) ;;;###autoload -(defun org-timer (&optional restart) +(defun org-timer (&optional restart no-insert-p) "Insert a H:MM:SS string from the timer into the buffer. The first time this command is used, the timer is started. When used with a \\[universal-argument] prefix, force restarting the timer. -When used with a double prefix argument \ -\\[universal-argument] \\universal-argument], change all the timer string +When used with a double prefix argument \\[universal-argument], change all the timer string in the region by a fixed amount. This can be used to recalibrate a timer -that was not started at the correct moment." +that was not started at the correct moment. + +If NO-INSERT-P is non-nil, return the string instead of inserting +it in the buffer." (interactive "P") - (if (equal restart '(4)) (org-timer-start)) - (or org-timer-start-time (org-timer-start)) - (insert (org-timer-value-string))) + (when (or (equal restart '(4)) (not org-timer-start-time)) + (org-timer-start)) + (if no-insert-p + (org-timer-value-string) + (insert (org-timer-value-string)))) (defun org-timer-value-string () (format org-timer-format (org-timer-secs-to-hms (floor (org-timer-seconds))))) +(defvar org-timer-timer-is-countdown nil) (defun org-timer-seconds () - (- (org-float-time (or org-timer-pause-time (current-time))) - (org-float-time org-timer-start-time))) + (if org-timer-timer-is-countdown + (- (org-float-time org-timer-start-time) + (org-float-time (current-time))) + (- (org-float-time (or org-timer-pause-time (current-time))) + (org-float-time org-timer-start-time)))) ;;;###autoload (defun org-timer-change-times-in-region (beg end delta) @@ -195,19 +203,22 @@ (defun org-timer-item (&optional arg) "Insert a description-type item with the current timer value." (interactive "P") - (let ((ind 0)) - (save-excursion - (skip-chars-backward " \n\t") - (condition-case nil - (progn - (org-beginning-of-item) - (setq ind (org-get-indentation))) - (error nil))) - (or (bolp) (newline)) - (org-indent-line-to ind) - (insert "- ") - (org-timer (if arg '(4))) - (insert ":: "))) + (cond + ;; In a timer list, insert with `org-list-insert-item-generic'. + ((and (org-in-item-p) + (save-excursion (org-beginning-of-item) (org-at-item-timer-p))) + (org-list-insert-item-generic + (point) nil (concat (org-timer (when arg '(4)) t) ":: "))) + ;; In a list of another type, don't break anything: throw an error. + ((org-in-item-p) + (error "This is not a timer list")) + ;; Else, insert the timer correctly indented at bol. + (t + (beginning-of-line) + (org-indent-line-function) + (insert "- ") + (org-timer (when arg '(4))) + (insert ":: ")))) (defun org-timer-fix-incomplete (hms) "If hms is a H:MM:SS string with missing hour or hour and minute, fix it." @@ -292,7 +303,9 @@ (when (eval org-timer-current-timer) (run-hooks 'org-timer-cancel-hook) (cancel-timer org-timer-current-timer) - (setq org-timer-current-timer nil)) + (setq org-timer-current-timer nil) + (setq org-timer-timer-is-countdown nil) + (org-timer-set-mode-line 'off)) (message "Last timer canceled")) (defun org-timer-show-remaining-time () @@ -309,17 +322,13 @@ (message "%d minute(s) %d seconds left before next time out" rmins rsecs)))) -(defun bzg-test (&optional test) - (interactive "P") - test) - ;;;###autoload (defun org-timer-set-timer (&optional opt) "Prompt for a duration and set a timer. If `org-timer-default-timer' is not zero, suggest this value as the default duration for the timer. If a timer is already set, -prompt the use if she wants to replace it. +prompt the user if she wants to replace it. Called with a numeric prefix argument, use this numeric value as the duration of the timer. @@ -353,9 +362,11 @@ (widen) (goto-char pos) (org-show-entry) - (org-get-heading)))) + (or (ignore-errors (org-get-heading)) + (concat "File:" (file-name-nondirectory (buffer-file-name))))))) ((eq major-mode 'org-mode) - (org-get-heading)) + (or (ignore-errors (org-get-heading)) + (concat "File:" (file-name-nondirectory (buffer-file-name))))) (t (error "Not in an Org buffer")))) timer-set) (if (or (and org-timer-current-timer @@ -363,6 +374,7 @@ (y-or-n-p "Replace current timer? "))) (not org-timer-current-timer)) (progn + (require 'org-clock) (when org-timer-current-timer (cancel-timer org-timer-current-timer)) (setq org-timer-current-timer @@ -370,8 +382,14 @@ secs nil `(lambda () (setq org-timer-current-timer nil) (org-notify ,(format "%s: time out" hl) t) + (setq org-timer-timer-is-countdown nil) + (org-timer-set-mode-line 'off) (run-hooks 'org-timer-done-hook)))) - (run-hooks 'org-timer-set-hook)) + (run-hooks 'org-timer-set-hook) + (setq org-timer-timer-is-countdown t + org-timer-start-time + (time-add (current-time) (seconds-to-time (* mins 60)))) + (org-timer-set-mode-line 'on)) (message "No timer set")))))) (provide 'org-timer) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-vm.el --- a/lisp/org/org-vm.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-vm.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -66,9 +66,19 @@ (to (vm-get-header-contents message "To")) (from (vm-get-header-contents message "From")) (message-id (vm-su-message-id message)) + (date (vm-get-header-contents message "Date")) + (date-ts (and date (format-time-string + (org-time-stamp-format t) + (date-to-time date)))) + (date-ts-ia (and date (format-time-string + (org-time-stamp-format t t) + (date-to-time date)))) desc link) (org-store-link-props :type "vm" :from from :to to :subject subject :message-id message-id) + (when date + (org-add-link-props :date date :date-timestamp date-ts + :date-timestamp-inactive date-ts-ia)) (setq message-id (org-remove-angle-brackets message-id)) (setq folder (abbreviate-file-name folder)) (if (and vm-folder-directory diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-w3m.el --- a/lisp/org/org-w3m.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-w3m.el Thu Nov 11 22:10:19 2010 -0600 @@ -5,7 +5,7 @@ ;; Author: Andy Stewart <lazycat dot manatee at gmail dot com> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-wl.el --- a/lisp/org/org-wl.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-wl.el Thu Nov 11 22:10:19 2010 -0600 @@ -7,7 +7,7 @@ ;; David Maus <dmaus at ictsoc dot de> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -84,6 +84,8 @@ (declare-function wl-summary-buffer-msgdb "ext:wl-folder" () t) (declare-function wl-summary-jump-to-msg-by-message-id "ext:wl-summary" (&optional id)) +(declare-function wl-summary-jump-to-msg "ext:wl-summary" + (&optional number beg end)) (declare-function wl-summary-line-from "ext:wl-summary" ()) (declare-function wl-summary-line-subject "ext:wl-summary" ()) (declare-function wl-summary-message-number "ext:wl-summary" ()) @@ -100,6 +102,7 @@ (defvar wl-summary-buffer-folder-name) (defvar wl-folder-group-regexp) (defvar wl-auto-check-folder-name) +(defvar elmo-nntp-default-server) (defconst org-wl-folder-types '(("%" . imap) ("-" . nntp) ("+" . mh) ("=" . spool) @@ -137,18 +140,19 @@ "Return content of FIELD in ENTITY. FIELD is a symbol of a rfc822 message header field. ENTITY is a message entity." - (let ((content (elmo-message-entity-field entity field))) + (let ((content (elmo-message-entity-field entity field 'string))) (if (listp content) (car content) content))) (defun org-wl-store-link () "Store a link to a WL message or folder." - (cond - ((memq major-mode '(wl-summary-mode mime-view-mode)) - (org-wl-store-link-message)) - ((eq major-mode 'wl-folder-mode) - (org-wl-store-link-folder)) - (t - nil))) + (unless (eobp) + (cond + ((memq major-mode '(wl-summary-mode mime-view-mode)) + (org-wl-store-link-message)) + ((eq major-mode 'wl-folder-mode) + (org-wl-store-link-folder)) + (t + nil)))) (defun org-wl-store-link-folder () "Store a link to a WL folder." @@ -189,10 +193,19 @@ msgnum (wl-summary-buffer-msgdb)))) (message-id (org-wl-message-field 'message-id wl-message-entity)) + (message-id-no-brackets + (org-remove-angle-brackets message-id)) (from (org-wl-message-field 'from wl-message-entity)) (to (org-wl-message-field 'to wl-message-entity)) (xref (org-wl-message-field 'xref wl-message-entity)) (subject (org-wl-message-field 'subject wl-message-entity)) + (date (org-wl-message-field 'date wl-message-entity)) + (date-ts (and date (format-time-string + (org-time-stamp-format t) + (date-to-time date)))) + (date-ts-ia (and date (format-time-string + (org-time-stamp-format t t) + (date-to-time date)))) desc link) ;; remove text properties of subject string to avoid possible bug @@ -212,6 +225,7 @@ org-wl-shimbun-prefer-web-links xref) (org-store-link-props :type "http" :link xref :description subject :from from :to to :message-id message-id + :message-id-no-brackets message-id-no-brackets :subject subject)) ((and (eq folder-type 'nntp) org-wl-nntp-prefer-web-links) (setq link @@ -222,16 +236,35 @@ (org-fixup-message-id-for-http message-id))) (org-store-link-props :type "http" :link link :description subject :from from :to to :message-id message-id + :message-id-no-brackets message-id-no-brackets :subject subject)) (t (org-store-link-props :type "wl" :from from :to to - :subject subject :message-id message-id) - (setq message-id (org-remove-angle-brackets message-id)) + :subject subject :message-id message-id + :message-id-no-brackets message-id-no-brackets) (setq desc (org-email-link-description)) - (setq link (org-make-link "wl:" folder-name "#" message-id)) + (setq link (org-make-link "wl:" folder-name "#" message-id-no-brackets)) (org-add-link-props :link link :description desc))) + (when date + (org-add-link-props :date date :date-timestamp date-ts + :date-timestamp-inactive date-ts-ia)) (or link xref))))))) +(defun org-wl-open-nntp (path) + "Follow the nntp: link specified by PATH." + (let* ((spec (split-string path "/")) + (server (split-string (nth 2 spec) "@")) + (group (nth 3 spec)) + (article (nth 4 spec))) + (org-wl-open + (concat "-" group ":" (if (cdr server) + (car (split-string (car server) ":")) + "") + (if (string= elmo-nntp-default-server (nth 2 spec)) + "" + (concat "@" (or (cdr server) (car server)))) + (if article (concat "#" article) ""))))) + (defun org-wl-open (path) "Follow the WL message link specified by PATH. When called with one prefix, open message in namazu search folder @@ -267,8 +300,12 @@ ;; beginning of the current line. So, restore the point ;; in the old buffer. (goto-char old-point)) - (and article (wl-summary-jump-to-msg-by-message-id (org-add-angle-brackets - article)) + (when article + (if (org-string-match-p "@" article) + (wl-summary-jump-to-msg-by-message-id (org-add-angle-brackets + article)) + (or (wl-summary-jump-to-msg (string-to-number article)) + (error "No such message: %s" article))) (wl-summary-redisplay)))))) (provide 'org-wl) diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org-xoxo.el --- a/lisp/org/org-xoxo.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org-xoxo.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; diff -r 62aa3653746a -r 5cb272c831e8 lisp/org/org.el --- a/lisp/org/org.el Thu Nov 11 19:23:58 2010 -0800 +++ b/lisp/org/org.el Thu Nov 11 22:10:19 2010 -0600 @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.01 +;; Version: 7.3 ;; ;; This file is part of GNU Emacs. ;; @@ -86,10 +86,6 @@ (unless (boundp 'diary-fancy-buffer) (defvaralias 'diary-fancy-buffer 'fancy-diary-buffer))) -;; For XEmacs, noutline is not yet provided by outline.el, so arrange for -;; the file noutline.el being loaded. -(if (featurep 'xemacs) (condition-case nil (require 'noutline))) -;; We require noutline, which might be provided in outline.el (require 'outline) (require 'noutline) ;; Other stuff we need. (require 'time-date) @@ -151,6 +147,7 @@ (const :tag "C" C) (const :tag "R" R) (const :tag "Asymptote" asymptote) + (const :tag "Calc" calc) (const :tag "Clojure" clojure) (const :tag "CSS" css) (const :tag "Ditaa" ditaa) @@ -158,15 +155,20 @@ (const :tag "Emacs Lisp" emacs-lisp) (const :tag "Gnuplot" gnuplot) (const :tag "Haskell" haskell) + (const :tag "Javascript" js) (const :tag "Latex" latex) + (const :tag "Ledger" ledger) (const :tag "Matlab" matlab) (const :tag "Mscgen" mscgen) (const :tag "Ocaml" ocaml) (const :tag "Octave" octave) + (const :tag "Org" org) (const :tag "Perl" perl) + (const :tag "PlantUML" plantuml) (const :tag "Python" python) (const :tag "Ruby" ruby) (const :tag "Sass" sass) + (const :tag "Scheme" scheme) (const :tag "Screen" screen) (const :tag "Shell Script" sh) (const :tag "Sql" sql) @@ -184,7 +186,7 @@ ;;; Version -(defconst org-version "7.01" +(defconst org-version "7.3" "The version number of the file org.el.") (defun org-version (&optional here) @@ -295,6 +297,7 @@ (const :tag " wl: Links to Wanderlust folders/messages" org-wl) (const :tag " w3m: Special cut/paste from w3m to Org-mode." org-w3m) (const :tag " mouse: Additional mouse support" org-mouse) + (const :tag " TaskJuggler: Export tasks to a TaskJuggler project" org-taskjuggler) (const :tag "C annotate-file: Annotate a file with org syntax" org-annotate-file) (const :tag "C bookmark: Org-mode links to bookmarks" org-bookmark) @@ -328,7 +331,8 @@ (const :tag "C sqlinsert: Convert Org-mode tables to SQL insertions" orgtbl-sqlinsert) (const :tag "C toc: Table of contents for Org-mode buffer" org-toc) (const :tag "C track: Keep up with Org-mode development" org-track) - (const :tag "C TaskJuggler: Export tasks to a TaskJuggler project" org-taskjuggler) + (const :tag "C velocity Something like Notational Velocity for Org" org-velocity) + (const :tag "C wikinodes: CamelCase wiki-like links" org-wikinodes) (repeat :tag "External packages" :inline t (symbol :tag "Package")))) (defcustom org-support-shift-select nil @@ -468,6 +472,15 @@ :group 'org-startup :type 'boolean) +(defcustom org-startup-with-inline-images nil + "Non-nil means show inline images when loading a new Org file. +This can also be configured on a per-file basis by adding one of +the following lines anywhere in the buffer: + #+STARTUP: inlineimages + #+STARTUP: noinlineimages" + :group 'org-startup + :type 'boolean) + (defcustom org-insert-mode-line-in-empty-file nil "Non-nil means insert the first line setting Org-mode in empty files. When the function `org-mode' is called interactively in an empty file, this @@ -1064,9 +1077,13 @@ (plain-list-item . auto)) "Should `org-insert-heading' leave a blank line before new heading/item? The value is an alist, with `heading' and `plain-list-item' as car, -and a boolean flag as cdr. For plain lists, if the variable -`org-empty-line-terminates-plain-lists' is set, the setting here -is ignored and no empty line is inserted, to keep the list in tact." +and a boolean flag as cdr. The cdr may lso be the symbol `auto', and then +Org will look at the surrounding headings/items and try to make an +intelligent decision wether to insert a blank line or not. + +For plain lists, if the variable `org-empty-line-terminates-plain-lists' is +set, the setting here is ignored and no empty line is inserted, to avoid +breaking the list structure." :group 'org-edit-structure :type '(list (cons (const heading) @@ -1258,7 +1275,7 @@ be a small gain when turning off unused link types. The types are: bracket The recommended [[link][description]] or [[link]] links with hiding. -angular Links in angular brackets that may contain whitespace like +angle Links in angular brackets that may contain whitespace like <bbdb:Carsten Dominik>. plain Plain links in normal text, no whitespace, like http://google.com. radio Text that is matched by a radio target, see manual for details. @@ -1269,8 +1286,8 @@ Changing this variable requires a restart of Emacs to become effective." :group 'org-link :type '(set :greedy t - (const :tag "Double bracket links (new style)" bracket) - (const :tag "Angular bracket links (old style)" angular) + (const :tag "Double bracket links" bracket) + (const :tag "Angular bracket links" angle) (const :tag "Plain text links" plain) (const :tag "Radio target matches" radio) (const :tag "Tags" tag) @@ -1437,6 +1454,17 @@ :group 'org-link-follow :type 'integer) +(defcustom org-link-search-must-match-exact-headline 'query-to-create + "Non-nil means internal links in Org files must exactly match a headline. +When nil, the link search tries to match a phrase will all words +in the search text." + :group 'org-link-follow + :type '(choice + (const :tag "Use fuzy text search" nil) + (const :tag "Match only exact headline" t) + (const :tag "Match extact headline or query to create it" + query-to-create))) + (defcustom org-link-frame-setup '((vm . vm-visit-folder-other-frame) (gnus . org-gnus-no-new-news) @@ -1797,8 +1825,8 @@ - a specification of the files to be considered, either a list of files, or a symbol whose function or variable value will be used to retrieve a file name or a list of file names. If you use `org-agenda-files' for - that, all agenda files will be scanned for targets. The value nil means - consider headings in the current buffer. + that, all agenda files will be scanned for targets. Nil means consider + headings in the current buffer. - A specification of how to find candidate refile targets. This may be any of: - a cons cell (:tag . \"TAG\") to identify refile targets by a tag. @@ -2568,13 +2596,28 @@ Currently none of this works for ISO week specifications. When this option is nil, the current day, month and year will always be -used as defaults." +used as defaults. + +See also `org-agenda-jump-prefer-future'." :group 'org-time :type '(choice (const :tag "Never" nil) (const :tag "Check month and day" t) (const :tag "Check month, day, and time" time))) +(defcustom org-agenda-jump-prefer-future 'org-read-date-prefer-future + "Should the agenda jump command prefer the future for incomplete dates? +The default is to do the same as configured in `org-read-date-prefer-future'. +But you can alse set a deviating value here. +This may t or nil, or the symbol `org-read-date-prefer-future'." + :group 'org-agenda + :group 'org-time + :type '(choice + (const :tag "Use org-aread-date-prefer-future" + org-read-date-prefer-future) + (const :tag "Never" nil) + (const :tag "Always" t))) + (defcustom org-read-date-display-live t "Non-nil means display current interpretation of date prompt live. This display will be in an overlay, in the minibuffer." @@ -3074,15 +3117,15 @@ (defcustom org-format-latex-options '(:foreground default :background default :scale 1.0 - :html-foreground "Black" :html-background "Transparent" :html-scale 1.0 - :matchers ("begin" "$1" "$" "$$" "\\(" "\\[")) + :html-foreground "Black" :html-background "Transparent" + :html-scale 1.0 :matchers ("begin" "$1" "$" "$$" "\\(" "\\[")) "Options for creating images from LaTeX fragments. This is a property list with the following properties: :foreground the foreground color for images embedded in Emacs, e.g. \"Black\". `default' means use the foreground of the default face. :background the background color, or \"Transparent\". `default' means use the background of the default face. -:scale a scaling factor for the size of the images. +:scale a scaling factor for the size of the images, to get more pixels :html-foreground, :html-background, :html-scale the same numbers for HTML export. :matchers a list indicating which matchers should be used to @@ -3162,7 +3205,6 @@ ("" "float" nil) ("" "wrapfig" nil) ("" "soul" t) - ("" "t1enc" t) ("" "textcomp" t) ("" "marvosym" t) ("" "wasysym" t) @@ -3177,7 +3219,7 @@ The packages in this list are needed by one part or another of Org-mode to function properly. -- inputenc, fontenc, t1enc: for basic font and character selection +- inputenc, fontenc: for basic font and character selection - textcomp, marvosymb, wasysym, latexsym, amssym: for various symbols used for interpreting the entities in `org-entities'. You can skip some of these packages if you don't use any of the symbols in it. @@ -3311,6 +3353,8 @@ (defvar org-emph-re nil "Regular expression for matching emphasis. After a match, the match groups contain these elements: +0 The match of the full regular expression, including the characters + before and after the proper match 1 The character before the proper match, or empty at beginning of line 2 The proper match, including the leading and trailing markers 3 The leading marker like * or /, indicating the type of highlighting @@ -3510,6 +3554,7 @@ (declare-function org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item "org-agenda" (&optional end)) (declare-function org-inlinetask-remove-END-maybe "org-inlinetask" ()) +(declare-function org-inlinetask-in-task-p "org-inlinetask" ()) (declare-function org-indent-mode "org-indent" (&optional arg)) (declare-function parse-time-string "parse-time" (string)) (declare-function org-attach-reveal "org-attach" (&optional if-exists)) @@ -3701,7 +3746,6 @@ ;; Autoload org-clock.el - (declare-function org-clock-save-markers-for-cut-and-paste "org-clock" (beg end)) (declare-function org-clock-update-mode-line "org-clock" ()) @@ -3991,7 +4035,7 @@ (org-autoload "org-id" '(org-id-get-create org-id-new org-id-copy org-id-get org-id-get-with-outline-path-completion - org-id-get-with-outline-drilling + org-id-get-with-outline-drilling org-id-store-link org-id-goto org-id-find org-id-store-link)) ;; Autoload Plotting Code @@ -4024,7 +4068,11 @@ group 4: True headline group 5: Tags") (make-variable-buffer-local 'org-complex-heading-regexp) -(defvar org-complex-heading-regexp-format nil) +(defvar org-complex-heading-regexp-format nil + "Printf format to make regexp to match an exact headline. +This regexp will match the headline of any node which hase the exact +headline text that is put into the format, but may have any TODO state, +priority and tags.") (make-variable-buffer-local 'org-complex-heading-regexp-format) (defvar org-todo-line-tags-regexp nil "Matches a headline and puts TODO state into group 2 if present. @@ -4129,6 +4177,8 @@ ("oddeven" org-odd-levels-only nil) ("align" org-startup-align-all-tables t) ("noalign" org-startup-align-all-tables nil) + ("inlineimages" org-startup-with-inline-images t) + ("noinlineimages" org-startup-with-inline-images nil) ("customtime" org-display-custom-times t) ("logdone" org-log-done time) ("lognotedone" org-log-done note) @@ -4357,7 +4407,7 @@ ((equal e "{") (push '(:startgroup) tgs)) ((equal e "}") (push '(:endgroup) tgs)) ((equal e "\\n") (push '(:newline) tgs)) - ((string-match (org-re "^\\([[:alnum:]_@]+\\)(\\(.\\))$") e) + ((string-match (org-re "^\\([[:alnum:]_@#%]+\\)(\\(.\\))$") e) (push (cons (match-string 1 e) (string-to-char (match-string 2 e))) tgs)) @@ -4401,7 +4451,7 @@ (concat "^\\(\\*+\\)[ \t]+\\(?:\\(" (mapconcat 'regexp-quote org-todo-keywords-1 "\\|") "\\)\\>\\)?\\(?:[ \t]*\\(\\[#.\\]\\)\\)?[ \t]*\\(.*?\\)" - "\\(?:[ \t]+\\(:[[:alnum:]_@:]+:\\)\\)?[ \t]*$") + "\\(?:[ \t]+\\(:[[:alnum:]_@#%:]+:\\)\\)?[ \t]*$") org-complex-heading-regexp-format (concat "^\\(\\*+\\)[ \t]+\\(?:\\(" (mapconcat 'regexp-quote org-todo-keywords-1 "\\|") @@ -4410,7 +4460,7 @@ "\\(?:[ \t]*\\(?:\\[[0-9%%/]+\\]\\)\\)?" ;; stats cookie "[ \t]*\\(%s\\)" "\\(?:[ \t]*\\(?:\\[[0-9%%/]+\\]\\)\\)?" ;; stats cookie - "\\(?:[ \t]+\\(:[[:alnum:]_@:]+:\\)\\)?[ \t]*$") + "\\(?:[ \t]+\\(:[[:alnum:]_@#%%:]+:\\)\\)?[ \t]*$") org-nl-done-regexp (concat "\n\\*+[ \t]+" "\\(?:" (mapconcat 'regexp-quote org-done-keywords "\\|") @@ -4419,7 +4469,7 @@ (concat "^\\(\\*+\\)[ \t]+\\(?:\\(" (mapconcat 'regexp-quote org-todo-keywords-1 "\\|") (org-re - "\\)\\>\\)? *\\(.*?\\([ \t]:[[:alnum:]:_@]+:[ \t]*\\)?$\\)")) + "\\)\\>\\)? *\\(.*?\\([ \t]:[[:alnum:]:_@#%]+:[ \t]*\\)?$\\)")) org-looking-at-done-regexp (concat "^" "\\(?:" (mapconcat 'regexp-quote org-done-keywords "\\|") "\\)" @@ -4699,6 +4749,8 @@ (let ((bmp (buffer-modified-p))) (org-table-map-tables 'org-table-align 'quietly) (set-buffer-modified-p bmp))) + (when org-startup-with-inline-images + (org-display-inline-images)) (when org-startup-indented (require 'org-indent) (org-indent-mode 1)) @@ -4736,7 +4788,7 @@ (defconst org-non-link-chars "]\t\n\r<>") (defvar org-link-types '("http" "https" "ftp" "mailto" "file" "news" - "shell" "elisp" "doi")) + "shell" "elisp" "doi" "message")) (defvar org-link-types-re nil "Matches a link that has a url-like prefix like \"http:\"") (defvar org-link-re-with-space nil @@ -4837,7 +4889,7 @@ org-plain-link-re (concat "\\<\\(" (mapconcat 'regexp-quote org-link-types "\\|") "\\):" - (org-re "\\([^ \t\n()<>]+\\(?:([[:word:]0-9]+)\\|\\([^[:punct:] \t\n]\\|/\\)\\)\\)")) + (org-re "\\([^ \t\n()<>]+\\(?:([[:word:]0-9_]+)\\|\\([^[:punct:] \t\n]\\|/\\)\\)\\)")) ;; "\\([^]\t\n\r<>() ]+[^]\t\n\r<>,.;() ]\\)") org-bracket-link-regexp "\\[\\[\\([^][]+\\)\\]\\(\\[\\([^][]+\\)\\]\\)?\\]" @@ -5003,13 +5055,22 @@ '(display t invisible t intangible t)) t))) +(defcustom org-src-fontify-natively nil + "When non-nil, fontify code in code blocks." + :type 'boolean + :group 'org-appearance + :group 'org-babel) + (defun org-fontify-meta-lines-and-blocks (limit) "Fontify #+ lines and blocks, in the correct ways." (let ((case-fold-search t)) (if (re-search-forward - "^\\([ \t]*#\\+\\(\\([a-zA-Z]+:?\\| \\|$\\)\\(_\\([a-zA-Z]+\\)\\)?\\)\\(.*\\)\\)" + "^\\([ \t]*#\\+\\(\\([a-zA-Z]+:?\\| \\|$\\)\\(_\\([a-zA-Z]+\\)\\)?\\)[ \t]*\\(\\([^ \t\n]*\\)[ \t]*\\(.*\\)\\)\\)" limit t) (let ((beg (match-beginning 0)) + (block-start (match-end 0)) + (block-end nil) + (lang (match-string 7)) (beg1 (line-beginning-position 2)) (dc1 (downcase (match-string 2))) (dc3 (downcase (match-string 3))) @@ -5022,8 +5083,9 @@ '(display t invisible t intangible t)) (add-text-properties (match-beginning 1) (match-end 3) '(font-lock-fontified t face org-meta-line)) - (add-text-properties (match-beginning 6) (match-end 6) + (add-text-properties (match-beginning 6) (+ (match-end 6) 1) '(font-lock-fontified t face org-block)) + ; for backend-specific code t) ((and (match-end 4) (equal dc3 "begin")) ;; Truly a block @@ -5033,6 +5095,7 @@ (concat "^[ \t]*#\\+end" (match-string 4) "\\>.*") nil t) ;; on purpose, we look further than LIMIT (setq end (match-end 0) end1 (1- (match-beginning 0))) + (setq block-end (match-beginning 0)) (when quoting (remove-text-properties beg end '(display t invisible t intangible t))) @@ -5040,10 +5103,15 @@ beg end '(font-lock-fontified t font-lock-multiline t)) (add-text-properties beg beg1 '(face org-meta-line)) - (add-text-properties end1 end '(face org-meta-line)) + (add-text-properties end1 (+ end 1) '(face org-meta-line)) + ; for end_src (cond + ((and lang org-src-fontify-natively) + (org-src-font-lock-fontify-block lang block-start block-end)) (quoting - (add-text-properties beg1 end1 '(face org-block))) + (add-text-properties beg1 (+ end1 1) '(face + org-block))) + ; end of source block ((not org-fontify-quote-and-verse-blocks)) ((string= block-type "quote") (add-text-properties beg1 end1 '(face org-quote))) @@ -5329,7 +5397,7 @@ "\\)\\>"))) (defun org-activate-tags (limit) - (if (re-search-forward (org-re "^\\*+.*[ \t]\\(:[[:alnum:]_@:]+:\\)[ \r\n]") limit t) + (if (re-search-forward (org-re "^\\*+.*[ \t]\\(:[[:alnum:]_@#%:]+:\\)[ \r\n]") limit t) (progn (org-remove-flyspell-overlays-in (match-beginning 1) (match-end 1)) (add-text-properties (match-beginning 1) (match-end 1) @@ -5360,6 +5428,12 @@ (defvar org-font-lock-hook nil "Functions to be called for special font lock stuff.") +(defvar org-font-lock-set-keywords-hook nil + "Functions that can manipulate `org-font-lock-extra-keywords'. +This is calles after `org-font-lock-extra-keywords' is defined, but before +it is installed to be used by font lock. This can be useful if something +needs to be inserted at a specific position in the font-lock sequence.") + (defun org-font-lock-hook (limit) (run-hook-with-args 'org-font-lock-hook limit)) @@ -5384,7 +5458,7 @@ '("^[ \t]*|\\(?:.*?|\\)? *\\(:?=[^|\n]*\\)" (1 'org-formula t)) '("^[ \t]*| *\\([#*]\\) *|" (1 'org-formula t)) '("^[ \t]*|\\( *\\([$!_^/]\\) *|.*\\)|" (1 'org-formula t)) - '("| *\\(<[lr]?[0-9]*>\\)" (1 'org-formula t)) + '("| *\\(<[lrc]?[0-9]*>\\)" (1 'org-formula t)) ;; Drawers (list org-drawer-regexp '(0 'org-special-keyword t)) (list "^[ \t]*:END:" '(0 'org-special-keyword t)) @@ -5428,13 +5502,13 @@ '(org-do-emphasis-faces (0 nil append)) '(org-do-emphasis-faces))) ;; Checkboxes - '("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[- X]\\]\\)" - 2 'org-checkbox prepend) - (if org-provide-checkbox-statistics + '("^[ \t]*\\(?:[-+*]\\|[0-9]+[.)]\\)[ \t]+\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\(\\[[- X]\\]\\)" + 1 'org-checkbox prepend) + (if (cdr (assq 'checkbox org-list-automatic-rules)) '("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]" (0 (org-get-checkbox-statistics-face) t))) ;; Description list items - '("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(.*? ::\\)" + '("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\)[ \t]+\\(.*? ::\\)" 2 'bold prepend) ;; ARCHIVEd headings (list (concat "^\\*+ \\(.*:" org-archive-tag ":.*\\)") @@ -5454,6 +5528,7 @@ '(org-fontify-meta-lines-and-blocks) ))) (setq org-font-lock-extra-keywords (delq nil org-font-lock-extra-keywords)) + (run-hooks 'org-font-lock-set-keywords-hook) ;; Now set the full font-lock-keywords (org-set-local 'org-font-lock-keywords org-font-lock-extra-keywords) (org-set-local 'font-lock-defaults @@ -5469,7 +5544,7 @@ (message "Entities are displayed as UTF8 characers") (save-restriction (widen) - (decompose-region (point-min) (point-max)) + (org-decompose-region (point-min) (point-max)) (message "Entities are displayed plain")))) (defun org-fontify-entities (limit) @@ -5569,7 +5644,7 @@ (inhibit-read-only t) (inhibit-point-motion-hooks t) (inhibit-modification-hooks t) deactivate-mark buffer-file-name buffer-file-truename) - (decompose-region beg end) + (org-decompose-region beg end) (remove-text-properties beg end (if org-indent-mode @@ -5698,7 +5773,8 @@ `org-cycle-emulate-tab' for details. - Special case: if point is at the beginning of the buffer and there is - no headline in line 1, this function will act as if called with prefix arg. + no headline in line 1, this function will act as if called with prefix arg + (C-u TAB, same as S-TAB) also when called without prefix arg. But only if also the variable `org-cycle-global-at-bob' is t." (interactive "P") (org-load-modules-maybe) @@ -5724,7 +5800,7 @@ (if nstars (format "\\{1,%d\\}" nstars) "+") " \\|\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) \\)")) (t (concat "\\*" (if nstars (format "\\{1,%d\\} " nstars) "+ "))))) - (bob-special (and org-cycle-global-at-bob (bobp) + (bob-special (and org-cycle-global-at-bob (not arg) (bobp) (not (looking-at outline-regexp)))) (org-cycle-hook (if bob-special @@ -5740,6 +5816,7 @@ (cond ((equal arg '(16)) + (setq last-command 'dummy) (org-set-startup-visibility) (message "Startup visibility, plus VISIBILITY properties")) @@ -5847,7 +5924,6 @@ (defun org-cycle-internal-local () "Do the local cycling action." - (org-back-to-heading) (let ((goal-column 0) eoh eol eos level has-children children-skipped) ;; First, some boundaries (save-excursion @@ -5871,12 +5947,15 @@ (outline-next-heading) (setq has-children (and (org-at-heading-p t) (> (funcall outline-level) level)))) - (org-end-of-subtree t) - (unless (eobp) - (skip-chars-forward " \t\n") - (beginning-of-line 1) ; in case this is an item - ) - (setq eos (if (eobp) (point) (1- (point))))) + ;; if we're in a list, org-end-of-subtree is in fact org-end-of-item. + (if (org-at-item-p) + (setq eos (if (and (org-end-of-item) (bolp)) + (1- (point)) + (point))) + (org-end-of-subtree t) + (unless (eobp) + (skip-chars-forward " \t\n")) + (setq eos (if (eobp) (point) (1- (point)))))) ;; Find out what to do next and set `this-command' (cond ((= eos eoh) @@ -5910,14 +5989,14 @@ ;; We just showed the children, or no children are there, ;; now show everything. (run-hook-with-args 'org-pre-cycle-hook 'subtree) - (org-show-subtree) + (outline-flag-region eoh eos nil) (message (if children-skipped "SUBTREE (NO CHILDREN)" "SUBTREE")) (setq org-cycle-subtree-status 'subtree) (run-hook-with-args 'org-cycle-hook 'subtree)) (t ;; Default action: hide the subtree. (run-hook-with-args 'org-pre-cycle-hook 'folded) - (hide-subtree) + (outline-flag-region eoh eos t) (message "FOLDED") (setq org-cycle-subtree-status 'folded) (run-hook-with-args 'org-cycle-hook 'folded))))) @@ -5961,8 +6040,8 @@ (interactive) (let (org-show-entry-below state) (save-excursion - (goto-char (point-min)) - (while (re-search-forward + (goto-char (point-max)) + (while (re-search-backward "^[ \t]*:VISIBILITY:[ \t]+\\([a-z]+\\)" nil t) (setq state (match-string 1)) @@ -6190,6 +6269,42 @@ (beginning-of-line) (recenter (prefix-numeric-value N)))) +;;; Saving and restoring visibility + +(defun org-outline-overlay-data (&optional use-markers) + "Return a list of the locations of all outline overlays. +These are overlays with the `invisible' property value `outline'. +The return value is a list of cons cells, with start and stop +positions for each overlay. +If USE-MARKERS is set, return the positions as markers." + (let (beg end) + (save-excursion + (save-restriction + (widen) + (delq nil + (mapcar (lambda (o) + (when (eq (overlay-get o 'invisible) 'outline) + (setq beg (overlay-start o) + end (overlay-end o)) + (and beg end (> end beg) + (if use-markers + (cons (move-marker (make-marker) beg) + (move-marker (make-marker) end)) + (cons beg end))))) + (overlays-in (point-min) (point-max)))))))) + +(defun org-set-outline-overlay-data (data) + "Create visibility overlays for all positions in DATA. +DATA should have been made by `org-outline-overlay-data'." + (let (o) + (save-excursion + (save-restriction + (widen) + (show-all) + (mapc (lambda (c) + (setq o (make-overlay (car c) (cdr c))) + (overlay-put o 'invisible 'outline)) + data))))) ;;; Folding of blocks @@ -6360,7 +6475,9 @@ (selected-point (if (eq interface 'outline) (car (org-get-location (current-buffer) org-goto-help)) - (nth 3 (org-refile-get-location "Goto: "))))) + (let ((pa (org-refile-get-location "Goto: "))) + (org-refile-check-position pa) + (nth 3 pa))))) (if selected-point (progn (org-mark-ring-push org-goto-start-pos) @@ -6582,22 +6699,40 @@ "Insert a new heading or item with same depth at point. If point is in a plain list and FORCE-HEADING is nil, create a new list item. If point is at the beginning of a headline, insert a sibling before the -current headline. If point is not at the beginning, do not split the line, -but create the new headline after the current line. +current headline. If point is not at the beginning, split the line, +create the new headline with the text in the current line after point +\(but see also the variable `org-M-RET-may-split-line'). + When INVISIBLE-OK is set, stop at invisible headlines when going back. This is important for non-interactive uses of the command." (interactive "P") (if (or (= (buffer-size) 0) - (and (not (save-excursion (and (ignore-errors (org-back-to-heading invisible-ok)) - (org-on-heading-p)))) + (and (not (save-excursion + (and (ignore-errors (org-back-to-heading invisible-ok)) + (org-on-heading-p)))) (not (org-in-item-p)))) - (insert "\n* ") + (progn + (insert "\n* ") + (run-hooks 'org-insert-heading-hook)) (when (or force-heading (not (org-insert-item))) (let* ((empty-line-p nil) + (level nil) + (on-heading (org-on-heading-p)) (head (save-excursion (condition-case nil (progn (org-back-to-heading invisible-ok) + (when (and (not on-heading) + (featurep 'org-inlinetask) + (integerp org-inlinetask-min-level) + (>= (length (match-string 0)) + org-inlinetask-min-level)) + ;; Find a heading level before the inline task + (while (and (setq level (org-up-heading-safe)) + (>= level org-inlinetask-min-level))) + (if (org-on-heading-p) + (org-back-to-heading invisible-ok) + (error "This should not happen"))) (setq empty-line-p (org-previous-line-empty-p)) (match-string 0)) (error "*")))) @@ -6635,6 +6770,12 @@ (cond (org-insert-heading-respect-content (org-end-of-subtree nil t) + (when (featurep 'org-inlinetask) + (while (and (not (eobp)) + (looking-at "\\(\\*+\\)[ \t]+") + (>= (length (match-string 1)) + org-inlinetask-min-level)) + (org-end-of-subtree nil t))) (or (bolp) (newline)) (or (org-previous-line-empty-p) (and blank (newline))) @@ -6643,7 +6784,7 @@ (when hide-previous (show-children) (org-show-entry)) - (looking-at ".*?\\([ \t]+\\(:[[:alnum:]_@:]+:\\)\\)?[ \t]*$") + (looking-at ".*?\\([ \t]+\\(:[[:alnum:]_@#%:]+:\\)\\)?[ \t]*$") (setq tags (and (match-end 2) (match-string 2))) (and (match-end 1) (delete-region (match-beginning 1) (match-end 1))) @@ -6679,7 +6820,7 @@ (org-back-to-heading t) (if (looking-at (if no-tags - (org-re "\\*+[ \t]+\\([^\n\r]*?\\)\\([ \t]+:[[:alnum:]:_@]+:[ \t]*\\)?$") + (org-re "\\*+[ \t]+\\([^\n\r]*?\\)\\([ \t]+:[[:alnum:]:_@#%]+:[ \t]*\\)?$") "\\*+[ \t]+\\([^\r\n]*\\)")) (match-string 1) ""))) @@ -6764,7 +6905,7 @@ (org-insert-heading arg) (cond ((org-on-heading-p) (org-do-demote)) - ((org-at-item-p) (org-indent-item 1)))) + ((org-at-item-p) (org-indent-item)))) (defun org-insert-todo-subheading (arg) "Insert a new subheading with TODO keyword or checkbox and demote it. @@ -6773,7 +6914,7 @@ (org-insert-todo-heading arg) (cond ((org-on-heading-p) (org-do-demote)) - ((org-at-item-p) (org-indent-item 1)))) + ((org-at-item-p) (org-indent-item)))) ;;; Promotion and Demotion @@ -7449,13 +7590,15 @@ ;;; Outline Sorting (defun org-sort (with-case) - "Call `org-sort-entries-or-items' or `org-table-sort-lines'. + "Call `org-sort-entries', `org-table-sort-lines' or `org-sort-list'. Optional argument WITH-CASE means sort case-sensitively. With a double prefix argument, also remove duplicate entries." (interactive "P") - (if (org-at-table-p) - (org-call-with-arg 'org-table-sort-lines with-case) - (org-call-with-arg 'org-sort-entries-or-items with-case))) + (cond + ((org-at-table-p) (org-call-with-arg 'org-table-sort-lines with-case)) + ((org-at-item-p) (org-call-with-arg 'org-sort-list with-case)) + (t + (org-call-with-arg 'org-sort-entries with-case)))) (defun org-sort-remove-invisible (s) (remove-text-properties 0 (length s) org-rm-props s) @@ -7473,14 +7616,12 @@ hook gets called. When a region or a plain list is sorted, the cursor will be in the first entry of the sorted region/list.") -(defun org-sort-entries-or-items +(defun org-sort-entries (&optional with-case sorting-type getkey-func compare-func property) - "Sort entries on a certain level of an outline tree, or plain list items. + "Sort entries on a certain level of an outline tree. If there is an active region, the entries in the region are sorted. Else, if the cursor is before the first entry, sort the top-level items. Else, the children of the entry at point are sorted. -If the cursor is at the first item in a plain list, the list items will be -sorted. Sorting can be alphabetically, numerically, by date/time as given by a time stamp, by a property or by priority. @@ -7494,7 +7635,6 @@ a Alphabetically, ignoring the TODO keyword and the priority, if any. t By date/time, either the first active time stamp in the entry, or, if none exist, by the first inactive one. - In items, only the first line will be checked. s By the scheduled date/time. d By deadline date/time. c By creation time, which is assumed to be the first inactive time stamp @@ -7513,7 +7653,7 @@ (interactive "P") (let ((case-func (if with-case 'identity 'downcase)) start beg end stars re re2 - txt what tmp plain-list-p) + txt what tmp) ;; Find beginning and end of region to sort (cond ((org-region-active-p) @@ -7523,15 +7663,6 @@ (goto-char (region-beginning)) (if (not (org-on-heading-p)) (outline-next-heading)) (setq start (point))) - ((org-at-item-p) - ;; we will sort this plain list - (org-beginning-of-item-list) (setq start (point)) - (org-end-of-item-list) - (or (bolp) (insert "\n")) - (setq end (point)) - (goto-char start) - (setq plain-list-p t - what "plain list")) ((or (org-on-heading-p) (condition-case nil (progn (org-back-to-heading) t) (error nil))) ;; we will sort the children of the current headline @@ -7564,43 +7695,39 @@ (setq beg (point)) (if (>= beg end) (error "Nothing to sort")) - (unless plain-list-p - (looking-at "\\(\\*+\\)") - (setq stars (match-string 1) - re (concat "^" (regexp-quote stars) " +") - re2 (concat "^" (regexp-quote (substring stars 0 -1)) "[^*]") - txt (buffer-substring beg end)) - (if (not (equal (substring txt -1) "\n")) (setq txt (concat txt "\n"))) - (if (and (not (equal stars "*")) (string-match re2 txt)) - (error "Region to sort contains a level above the first entry"))) + (looking-at "\\(\\*+\\)") + (setq stars (match-string 1) + re (concat "^" (regexp-quote stars) " +") + re2 (concat "^" (regexp-quote (substring stars 0 -1)) "[^*]") + txt (buffer-substring beg end)) + (if (not (equal (substring txt -1) "\n")) (setq txt (concat txt "\n"))) + (if (and (not (equal stars "*")) (string-match re2 txt)) + (error "Region to sort contains a level above the first entry")) (unless sorting-type (message - (if plain-list-p - "Sort %s: [a]lpha [n]umeric [t]ime [f]unc A/N/T/F means reversed:" - "Sort %s: [a]lpha [n]umeric [p]riority p[r]operty todo[o]rder [f]unc + "Sort %s: [a]lpha [n]umeric [p]riority p[r]operty todo[o]rder [f]unc [t]ime [s]cheduled [d]eadline [c]reated - A/N/T/S/D/C/P/O/F means reversed:") + A/N/T/S/D/C/P/O/F means reversed:" what) (setq sorting-type (read-char-exclusive)) (and (= (downcase sorting-type) ?f) (setq getkey-func (org-icompleting-read "Sort using function: " - obarray 'fboundp t nil nil)) + obarray 'fboundp t nil nil)) (setq getkey-func (intern getkey-func))) (and (= (downcase sorting-type) ?r) (setq property (org-icompleting-read "Property: " - (mapcar 'list (org-buffer-property-keys t)) - nil t)))) + (mapcar 'list (org-buffer-property-keys t)) + nil t)))) (message "Sorting entries...") (save-restriction (narrow-to-region start end) - (let ((dcst (downcase sorting-type)) (case-fold-search nil) (now (current-time))) @@ -7608,99 +7735,70 @@ (/= dcst sorting-type) ;; This function moves to the beginning character of the "record" to ;; be sorted. - (if plain-list-p - (lambda nil - (if (org-at-item-p) t (goto-char (point-max)))) - (lambda nil - (if (re-search-forward re nil t) - (goto-char (match-beginning 0)) - (goto-char (point-max))))) + (lambda nil + (if (re-search-forward re nil t) + (goto-char (match-beginning 0)) + (goto-char (point-max)))) ;; This function moves to the last character of the "record" being ;; sorted. - (if plain-list-p - 'org-end-of-item - (lambda nil - (save-match-data - (condition-case nil - (outline-forward-same-level 1) - (error - (goto-char (point-max))))))) - + (lambda nil + (save-match-data + (condition-case nil + (outline-forward-same-level 1) + (error + (goto-char (point-max)))))) ;; This function returns the value that gets sorted against. - (if plain-list-p - (lambda nil - (when (looking-at "[ \t]*[-+*0-9.)]+[ \t]+") - (cond - ((= dcst ?n) - (string-to-number (buffer-substring (match-end 0) - (point-at-eol)))) - ((= dcst ?a) - (buffer-substring (match-end 0) (point-at-eol))) - ((= dcst ?t) - (if (or (re-search-forward org-ts-regexp (point-at-eol) t) - (re-search-forward org-ts-regexp-both - (point-at-eol) t)) - (org-time-string-to-seconds (match-string 0)) - (org-float-time now))) - ((= dcst ?f) - (if getkey-func - (progn - (setq tmp (funcall getkey-func)) - (if (stringp tmp) (setq tmp (funcall case-func tmp))) - tmp) - (error "Invalid key function `%s'" getkey-func))) - (t (error "Invalid sorting type `%c'" sorting-type))))) - (lambda nil - (cond - ((= dcst ?n) - (if (looking-at org-complex-heading-regexp) - (string-to-number (match-string 4)) - nil)) - ((= dcst ?a) - (if (looking-at org-complex-heading-regexp) - (funcall case-func (match-string 4)) - nil)) - ((= dcst ?t) - (let ((end (save-excursion (outline-next-heading) (point)))) - (if (or (re-search-forward org-ts-regexp end t) - (re-search-forward org-ts-regexp-both end t)) - (org-time-string-to-seconds (match-string 0)) - (org-float-time now)))) - ((= dcst ?c) - (let ((end (save-excursion (outline-next-heading) (point)))) - (if (re-search-forward - (concat "^[ \t]*\\[" org-ts-regexp1 "\\]") - end t) - (org-time-string-to-seconds (match-string 0)) - (org-float-time now)))) - ((= dcst ?s) - (let ((end (save-excursion (outline-next-heading) (point)))) - (if (re-search-forward org-scheduled-time-regexp end t) - (org-time-string-to-seconds (match-string 1)) - (org-float-time now)))) - ((= dcst ?d) - (let ((end (save-excursion (outline-next-heading) (point)))) - (if (re-search-forward org-deadline-time-regexp end t) - (org-time-string-to-seconds (match-string 1)) - (org-float-time now)))) - ((= dcst ?p) - (if (re-search-forward org-priority-regexp (point-at-eol) t) - (string-to-char (match-string 2)) - org-default-priority)) - ((= dcst ?r) - (or (org-entry-get nil property) "")) - ((= dcst ?o) - (if (looking-at org-complex-heading-regexp) - (- 9999 (length (member (match-string 2) - org-todo-keywords-1))))) - ((= dcst ?f) - (if getkey-func - (progn - (setq tmp (funcall getkey-func)) - (if (stringp tmp) (setq tmp (funcall case-func tmp))) - tmp) - (error "Invalid key function `%s'" getkey-func))) - (t (error "Invalid sorting type `%c'" sorting-type))))) + (lambda nil + (cond + ((= dcst ?n) + (if (looking-at org-complex-heading-regexp) + (string-to-number (match-string 4)) + nil)) + ((= dcst ?a) + (if (looking-at org-complex-heading-regexp) + (funcall case-func (match-string 4)) + nil)) + ((= dcst ?t) + (let ((end (save-excursion (outline-next-heading) (point)))) + (if (or (re-search-forward org-ts-regexp end t) + (re-search-forward org-ts-regexp-both end t)) + (org-time-string-to-seconds (match-string 0)) + (org-float-time now)))) + ((= dcst ?c) + (let ((end (save-excursion (outline-next-heading) (point)))) + (if (re-search-forward + (concat "^[ \t]*\\[" org-ts-regexp1 "\\]") + end t) + (org-time-string-to-seconds (match-string 0)) + (org-float-time now)))) + ((= dcst ?s) + (let ((end (save-excursion (outline-next-heading) (point)))) + (if (re-search-forward org-scheduled-time-regexp end t) + (org-time-string-to-seconds (match-string 1)) + (org-float-time now)))) + ((= dcst ?d) + (let ((end (save-excursion (outline-next-heading) (point)))) + (if (re-search-forward org-deadline-time-regexp end t) + (org-time-string-to-seconds (match-string 1)) + (org-float-time now)))) + ((= dcst ?p) + (if (re-search-forward org-priority-regexp (point-at-eol) t) + (string-to-char (match-string 2)) + org-default-priority)) + ((= dcst ?r) + (or (org-entry-get nil property) "")) + ((= dcst ?o) + (if (looking-at org-complex-heading-regexp) + (- 9999 (length (member (match-string 2) + org-todo-keywords-1))))) + ((= dcst ?f) + (if getkey-func + (progn + (setq tmp (funcall getkey-func)) + (if (stringp tmp) (setq tmp (funcall case-func tmp))) + tmp) + (error "Invalid key function `%s'" getkey-func))) + (t (error "Invalid sorting type `%c'" sorting-type)))) nil (cond ((= dcst ?a) 'string<) @@ -8105,11 +8203,13 @@ path the path of the link, the text after the prefix (like \"http:\") desc the description of the link, if any, nil if there was no description - format the export format, a symbol like `html' or `latex'. + format the export format, a symbol like `html' or `latex' or `ascii'.. The function may use the FORMAT information to return different values depending on the format. The return value will be put literally into -the exported file. +the exported file. If the return value is nil, this means Org should +do what it normally does with links which do not have EXPORT defined. + Org-mode has a built-in default for exporting links. If you are happy with this default, there is no need to define an export function for the link type. For a simple example of an export function, see `org-bbdb.el'." @@ -8134,7 +8234,7 @@ (org-load-modules-maybe) (setq org-store-link-plist nil) ; reset (let ((outline-regexp (org-get-limited-outline-regexp)) - link cpltxt desc description search txt custom-id) + link cpltxt desc description search txt custom-id agenda-link) (cond ((run-hook-with-args-until-success 'org-store-link-functions) @@ -8166,9 +8266,10 @@ (get-text-property (point) 'org-marker)))) (when m (org-with-point-at m - (if (interactive-p) - (call-interactively 'org-store-link) - (org-store-link nil)))))) + (setq agenda-link + (if (interactive-p) + (call-interactively 'org-store-link) + (org-store-link nil))))))) ((eq major-mode 'calendar-mode) (let ((cd (calendar-cursor-to-date))) @@ -8216,13 +8317,14 @@ (setq cpltxt (concat "file:" file) link (org-make-link cpltxt)))) - ((and buffer-file-name (org-mode-p)) + ((and (buffer-file-name (buffer-base-buffer)) (org-mode-p)) (setq custom-id (ignore-errors (org-entry-get nil "CUSTOM_ID"))) (cond ((org-in-regexp "<<\\(.*?\\)>>") (setq cpltxt (concat "file:" - (abbreviate-file-name buffer-file-name) + (abbreviate-file-name + (buffer-file-name (buffer-base-buffer))) "::" (match-string 1)) link (org-make-link cpltxt))) ((and (featurep 'org-id) @@ -8244,11 +8346,13 @@ (error ;; probably before first headline, link to file only (concat "file:" - (abbreviate-file-name buffer-file-name)))))) + (abbreviate-file-name + (buffer-file-name (buffer-base-buffer)))))))) (t ;; Just link to current headline (setq cpltxt (concat "file:" - (abbreviate-file-name buffer-file-name))) + (abbreviate-file-name + (buffer-file-name (buffer-base-buffer))))) ;; Add a context search string (when (org-xor org-context-in-file-links arg) (setq txt (cond @@ -8305,7 +8409,7 @@ "::#" custom-id)) (setq org-stored-links (cons (list link desc) org-stored-links)))) - (and link (org-make-link-string link desc))))) + (or agenda-link (and link (org-make-link-string link desc)))))) (defun org-store-link-props (&rest plist) "Store link properties, extract names and addresses." @@ -8369,7 +8473,7 @@ ;; We are using a headline, clean up garbage in there. (if (string-match org-todo-regexp s) (setq s (replace-match "" t t s))) - (if (string-match (org-re ":[[:alnum:]_@:]+:[ \t]*$") s) + (if (string-match (org-re ":[[:alnum:]_@#%:]+:[ \t]*$") s) (setq s (replace-match "" t t s))) (setq s (org-trim s)) (if (string-match (concat "^\\(" org-quote-string "\\|" @@ -8377,8 +8481,6 @@ (setq s (replace-match "" t t s))) (while (string-match org-ts-regexp s) (setq s (replace-match "" t t s)))) - (while (string-match "[^a-zA-Z_0-9 \t]+" s) - (setq s (replace-match " " t t s))) (or string (setq s (concat "*" s))) ; Add * for headlines (mapconcat 'identity (org-split-string s "[ \t]+") " "))) @@ -8406,7 +8508,11 @@ (when (and (not description) (not (equal link (org-link-escape link)))) (setq description (org-extract-attributes link))) - (concat "[[" (org-link-escape link) "]" + (setq link (if (string-match org-link-types-re link) + (concat (match-string 1 link) + (org-link-escape (substring link (match-end 1)))) + (org-link-escape link))) + (concat "[[" link "]" (if description (concat "[" description "]") "") "]")) @@ -8914,6 +9020,13 @@ org-link-abbrev-alist-local))) (org-open-at-point arg reference-buffer))))) +(defvar org-open-at-point-functions nil + "Hook that is run when following a link at point. + +Functions in this hook must return t if they identify and follow +a link at point. If they don't find anything interesting at point, +they must return nil.") + (defun org-open-at-point (&optional in-emacs reference-buffer) "Open link at or after point. If there is no link at point, this function will search forward up to @@ -8939,6 +9052,7 @@ (not (get-text-property (point) 'org-linked-text))) (or (org-offer-links-in-entry in-emacs) (progn (require 'org-attach) (org-attach-reveal 'if-exists)))) + ((run-hook-with-args-until-success 'org-open-at-point-functions)) ((org-at-timestamp-p t) (org-follow-timestamp-link)) ((or (org-footnote-at-reference-p) (org-footnote-at-definition-p)) (org-footnote-action)) @@ -8977,7 +9091,7 @@ (setq type (match-string 1) path (match-string 2)) (throw 'match t))) (save-excursion - (when (org-in-regexp (org-re "\\(:[[:alnum:]_@:]+\\):[ \t]*$")) + (when (org-in-regexp (org-re "\\(:[[:alnum:]_@#%:]+\\):[ \t]*$")) (setq type "tags" path (match-string 1)) (while (string-match ":" path) @@ -9243,6 +9357,7 @@ (set-window-configuration org-window-config-before-follow-link)") +(defvar org-link-search-inhibit-query nil) ;; dynamically scoped (defun org-link-search (s &optional type avoid-pos) "Search for a link search option. If S is surrounded by forward slashes, it is interpreted as a @@ -9260,7 +9375,7 @@ (pre nil) (post nil) words re0 re1 re2 re3 re4_ re4 re5 re2a re2a_ reall) (cond - ;; First check if there are any special + ;; First check if there are any special search functions ((run-hook-with-args-until-success 'org-execute-file-search-functions s)) ;; Now try the builtin stuff ((and (equal (string-to-char s0) ?#) @@ -9305,12 +9420,33 @@ ;;((eq major-mode 'dired-mode) ;; (grep (concat "grep -n -e '" (match-string 1 s) "' *"))) (t (org-do-occur (match-string 1 s))))) + ((and (org-mode-p) org-link-search-must-match-exact-headline) + (and (equal (string-to-char s) ?*) (setq s (substring s 1))) + (goto-char (point-min)) + (cond + ((let (case-fold-search) + (re-search-forward (format org-complex-heading-regexp-format + (regexp-quote s)) + nil t)) + ;; OK, found a match + (setq type 'dedicated) + (goto-char (match-beginning 0))) + ((and (not org-link-search-inhibit-query) + (eq org-link-search-must-match-exact-headline 'query-to-create) + (y-or-n-p "No match - create this as a new heading? ")) + (goto-char (point-max)) + (or (bolp) (newline)) + (insert "* " s "\n") + (beginning-of-line 0)) + (t + (goto-char pos) + (error "No match")))) (t - ;; A normal search strings + ;; A normal search string (when (equal (string-to-char s) ?*) ;; Anchor on headlines, post may include tags. (setq pre "^\\*+[ \t]+\\(?:\\sw+\\)?[ \t]*" - post (org-re "[ \t]*\\(?:[ \t]+:[[:alnum:]_@:+]:[ \t]*\\)?$") + post (org-re "[ \t]*\\(?:[ \t]+:[[:alnum:]_@#%:+]:[ \t]*\\)?$") s (substring s 1))) (remove-text-properties 0 (length s) @@ -9351,13 +9487,7 @@ ) (goto-char (match-beginning 1)) (goto-char pos) - (error "No match"))))) - (t - ;; Normal string-search - (goto-char (point-min)) - (if (search-forward s nil t) - (goto-char (match-beginning 0)) - (error "No match")))) + (error "No match")))))) (and (org-mode-p) (org-show-context 'link-search)) type)) @@ -9836,15 +9966,9 @@ (setq level (org-reduced-level (- (match-end 1) (match-beginning 1))) txt (org-link-display-format (match-string 4)) - re (concat "^" (regexp-quote - (buffer-substring - (match-beginning 1) - (match-end 4))))) - (if (match-end 5) (setq re (concat - re "[ \t]+" - (regexp-quote - (match-string 5))))) - (setq re (concat re "[ \t]*$")) + txt (replace-regexp-in-string "\\( *\[[0-9]+/?[0-9]*%?\]\\)+$" "" txt) + re (format org-complex-heading-regexp-format + (regexp-quote (match-string 4)))) (when org-refile-use-outline-path (setq txt (mapconcat 'org-protect-slash @@ -10143,6 +10267,7 @@ (setq answ (funcall cfunc prompt tbl nil (not new-nodes) nil 'org-refile-history)) (setq pa (or (assoc answ tbl) (assoc (concat answ "/") tbl))) + (org-refile-check-position pa) (if pa (progn (when (or (not org-refile-history) @@ -10169,6 +10294,26 @@ (org-refile-new-child parent-target child))) (error "Invalid target location"))))) +(defun org-refile-check-position (refile-pointer) + "Check if the refile pointer matches the readline to which it points." + (let* ((file (nth 1 refile-pointer)) + (re (nth 2 refile-pointer)) + (pos (nth 3 refile-pointer)) + buffer) + (when (org-string-nw-p re) + (setq buffer (if (markerp pos) + (marker-buffer pos) + (or (find-buffer-visiting file) + (find-file-noselect file)))) + (with-current-buffer buffer + (save-excursion + (save-restriction + (widen) + (goto-char pos) + (beginning-of-line 1) + (unless (org-looking-at-p re) + (error "Invalid refile position, please rebuild the cache")))))))) + (defun org-refile-new-child (parent-target child) "Use refile target PARENT-TARGET to add new CHILD below it." (unless parent-target @@ -10378,7 +10523,7 @@ "BEGIN_VERSE" "END_VERSE" "BEGIN_CENTER" "END_CENTER" "BEGIN_SRC" "END_SRC" - "CATEGORY" "COLUMNS" + "CATEGORY" "COLUMNS" "PROPERTY" "CAPTION" "LABEL" "SETUPFILE" "BIND" @@ -10482,7 +10627,7 @@ (let* ((a nil) (end (point)) (beg1 (save-excursion - (skip-chars-backward (org-re "[:alnum:]_@")) + (skip-chars-backward (org-re "[:alnum:]_@#%")) (point))) (beg (save-excursion (skip-chars-backward "a-zA-Z0-9_:$") @@ -10497,8 +10642,10 @@ (throw 'exit t))) (tag (and (equal (char-before beg1) ?:) (equal (char-after (point-at-bol)) ?*))) - (prop (and (equal (char-before beg1) ?:) - (not (equal (char-after (point-at-bol)) ?*)))) + (prop (or (and (equal (char-before beg1) ?:) + (not (equal (char-after (point-at-bol)) ?*))) + (string-match "^#\\+PROPERTY:.*" + (buffer-substring (point-at-bol) (point))))) (texp (equal (char-before beg) ?\\)) (link (equal (char-before beg) ?\[)) (opt (equal (buffer-substring (max (point-at-bol) (- beg 2)) @@ -10575,7 +10722,10 @@ (delete-window (get-buffer-window "*Completions*"))) (if (assoc completion table) (if (eq type :todo) (insert " ") - (if (memq type '(:tag :prop)) (insert ":")))) + (if (and (memq type '(:tag :prop)) + (not (string-match "^#[ \t]*\\+property:" + (org-current-line-string t)))) + (insert ":")))) (if (and (equal type :opt) (assoc completion table)) (message "%s" (substitute-command-keys "Press \\[org-complete] again to insert example settings")))) @@ -10613,27 +10763,6 @@ (defvar org-setting-tags nil) ; dynamically skipped -(defun org-parse-local-options (string var) - "Parse STRING for startup setting relevant for variable VAR." - (let ((rtn (symbol-value var)) - e opts) - (save-match-data - (if (or (not string) (not (string-match "\\S-" string))) - rtn - (setq opts (delq nil (mapcar (lambda (x) - (setq e (assoc x org-startup-options)) - (if (eq (nth 1 e) var) e nil)) - (org-split-string string "[ \t]+")))) - (if (not opts) - rtn - (setq rtn nil) - (while (setq e (pop opts)) - (if (not (nth 3 e)) - (setq rtn (nth 2 e)) - (if (not (listp rtn)) (setq rtn nil)) - (push (nth 2 e) rtn))) - rtn))))) - (defvar org-todo-setup-filter-hook nil "Hook for functions that pre-filter todo specs. Each function takes a todo spec and returns either nil or the spec @@ -11313,7 +11442,6 @@ (msg "Entry repeats: ") (org-log-done nil) (org-todo-log-states nil) - (nshiftmax 10) (nshift 0) re type n what ts time to-state) (when repeat (if (eq org-log-repeat t) (setq org-log-repeat 'state)) @@ -11360,15 +11488,17 @@ (- (time-to-days (current-time)) (time-to-days time)) 'day)) ((equal (match-string 1 ts) "+") - (while (or (= nshift 0) - (<= (time-to-days time) (time-to-days (current-time)))) - (when (= (incf nshift) nshiftmax) - (or (y-or-n-p (message "%d repeater intervals were not enough to shift date past today. Continue? " nshift)) - (error "Abort"))) - (org-timestamp-change n (cdr (assoc what whata))) - (org-at-timestamp-p t) - (setq ts (match-string 1)) - (setq time (save-match-data (org-time-string-to-time ts)))) + (let ((nshiftmax 10) (nshift 0)) + (while (or (= nshift 0) + (<= (time-to-days time) + (time-to-days (current-time)))) + (when (= (incf nshift) nshiftmax) + (or (y-or-n-p (message "%d repeater intervals were not enough to shift date past today. Continue? " nshift)) + (error "Abort"))) + (org-timestamp-change n (cdr (assoc what whata))) + (org-at-timestamp-p t) + (setq ts (match-string 1)) + (setq time (save-match-data (org-time-string-to-time ts))))) (org-timestamp-change (- n) (cdr (assoc what whata))) ;; rematch, so that we have everything in place for the real shift (org-at-timestamp-p t) @@ -11631,7 +11761,7 @@ (defvar org-property-end-re) (defun org-add-log-setup (&optional purpose state prev-state - findpos how &optional extra) + findpos how extra) "Set up the post command hook to take a note. If this is about to TODO state change, the new state is expected in STATE. When FINDPOS is non-nil, find the correct position for the note in @@ -11692,10 +11822,11 @@ (defun org-skip-over-state-notes () "Skip past the list of State notes in an entry." (if (looking-at "\n[ \t]*- State") (forward-char 1)) - (while (looking-at "[ \t]*- State") - (condition-case nil - (org-next-item) - (error (org-end-of-item))))) + (when (org-in-item-p) + (let ((limit (org-list-bottom-point))) + (while (looking-at "[ \t]*- State") + (goto-char (or (org-get-next-item (point) limit) + (org-get-end-of-item limit))))))) (defun org-add-log-note (&optional purpose) "Pop up a window for taking a note, and add this note later at point." @@ -11740,7 +11871,7 @@ "Finish taking a log note, and insert it to where it belongs." (let ((txt (buffer-string)) (note (cdr (assq org-log-note-purpose org-log-note-headings))) - lines ind) + lines ind bul) (kill-buffer (current-buffer)) (while (string-match "\\`#.*\n[ \t\n]*" txt) (setq txt (replace-match "" t t txt))) @@ -11780,13 +11911,26 @@ (move-marker org-log-note-marker nil) (end-of-line 1) (if (not (bolp)) (let ((inhibit-read-only t)) (insert "\n"))) - (insert "- " (pop lines)) - (org-indent-line-function) - (beginning-of-line 1) - (looking-at "[ \t]*") - (setq ind (concat (match-string 0) " ")) - (end-of-line 1) - (while lines (insert "\n" ind (pop lines))) + (setq ind (save-excursion + (if (org-in-item-p) + (progn + (goto-char (org-list-top-point)) + (org-get-indentation)) + (skip-chars-backward " \r\t\n") + (cond + ((and (org-at-heading-p) + org-adapt-indentation) + (1+ (org-current-level))) + ((org-at-heading-p) 0) + (t (org-get-indentation)))))) + (setq bul (org-list-bullet-string "-")) + (org-indent-line-to ind) + (insert bul (pop lines)) + (let ((ind-body (+ (length bul) ind))) + (while lines + (insert "\n") + (org-indent-line-to ind-body) + (insert (pop lines)))) (message "Note stored") (org-back-to-heading t) (org-cycle-hide-drawers 'children))))) @@ -12024,7 +12168,8 @@ (setq new action) (message "Priority %c-%c, SPC to remove: " org-highest-priority org-lowest-priority) - (setq new (read-char-exclusive))) + (save-match-data + (setq new (read-char-exclusive)))) (if (and (= (upcase org-highest-priority) org-highest-priority) (= (upcase org-lowest-priority) org-lowest-priority)) (setq new (upcase new))) @@ -12109,7 +12254,7 @@ (let* ((re (concat "^" outline-regexp " *\\(\\<\\(" (mapconcat 'regexp-quote org-todo-keywords-1 "\\|") (org-re - "\\>\\)\\)? *\\(.*?\\)\\(:[[:alnum:]_@:]+:\\)?[ \t]*$"))) + "\\>\\)\\)? *\\(.*?\\)\\(:[[:alnum:]_@#%:]+:\\)?[ \t]*$"))) (props (list 'face 'default 'done-face 'org-agenda-done 'undone-face 'default @@ -12309,7 +12454,7 @@ ;; Parse the string and create a lisp form (let ((match0 match) - (re (org-re "^&?\\([-+:]\\)?\\({[^}]+}\\|LEVEL\\([<=>]\\{1,2\\}\\)\\([0-9]+\\)\\|\\([[:alnum:]_]+\\)\\([<>=]\\{1,2\\}\\)\\({[^}]+}\\|\"[^\"]*\"\\|-?[.0-9]+\\(?:[eE][-+]?[0-9]+\\)?\\)\\|[[:alnum:]_@]+\\)")) + (re (org-re "^&?\\([-+:]\\)?\\({[^}]+}\\|LEVEL\\([<=>]\\{1,2\\}\\)\\([0-9]+\\)\\|\\(\\(?:[[:alnum:]_]+\\(?:\\\\-\\)*\\)+\\)\\([<>=]\\{1,2\\}\\)\\({[^}]+}\\|\"[^\"]*\"\\|-?[.0-9]+\\(?:[eE][-+]?[0-9]+\\)?\\)\\|[[:alnum:]_@#%]+\\)")) minus tag mm tagsmatch todomatch tagsmatcher todomatcher kwd matcher orterms term orlist re-p str-p level-p level-op time-p @@ -12337,7 +12482,9 @@ (setq rest (substring term (match-end 0)) minus (and (match-end 1) (equal (match-string 1 term) "-")) - tag (match-string 2 term) + tag (save-match-data (replace-regexp-in-string + "\\\\-" "-" + (match-string 2 term))) re-p (equal (string-to-char tag) ?{) level-p (match-end 4) prop-p (match-end 5) @@ -12516,7 +12663,7 @@ (while (not (equal lastpos (point))) (setq lastpos (point)) (when (looking-at - (org-re "[^\r\n]+?:\\([[:alnum:]_@:]+\\):[ \t]*$")) + (org-re "[^\r\n]+?:\\([[:alnum:]_@#%:]+\\):[ \t]*$")) (setq ltags (org-split-string (org-match-string-no-properties 1) ":")) (when parent @@ -12543,7 +12690,7 @@ (let (res current) (save-excursion (org-back-to-heading t) - (if (re-search-forward (org-re "[ \t]:\\([[:alnum:]_@:]+\\):[ \t]*$") + (if (re-search-forward (org-re "[ \t]:\\([[:alnum:]_@#%:]+\\):[ \t]*$") (point-at-eol) t) (progn (setq current (match-string 1)) @@ -12573,7 +12720,7 @@ ;; Assumes that this is a headline (let ((pos (point)) (col (current-column)) ncol tags-l p) (beginning-of-line 1) - (if (and (looking-at (org-re ".*?\\([ \t]+\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$")) + (if (and (looking-at (org-re ".*?\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")) (< pos (match-beginning 2))) (progn (setq tags-l (- (match-end 2) (match-beginning 2))) @@ -12643,6 +12790,7 @@ (org-set-tags t) (message "No headings")))) +(defvar org-indent-indentation-per-level) (defun org-set-tags (&optional arg just-align) "Set the tags for the current headline. With prefix ARG, realign all tags in headings in the current buffer." @@ -12652,7 +12800,7 @@ (col (current-column)) (org-setting-tags t) table current-tags inherited-tags ; computed below when needed - tags p0 c0 c1 rpl) + tags p0 c0 c1 rpl di tc level) (if arg (save-excursion (goto-char (point-min)) @@ -12667,8 +12815,10 @@ (save-excursion (setq table (append org-tag-persistent-alist (or org-tag-alist (org-get-buffer-tags)) - (and org-complete-tags-always-offer-all-agenda-tags - (org-global-tags-completion-table (org-agenda-files)))) + (and + org-complete-tags-always-offer-all-agenda-tags + (org-global-tags-completion-table + (org-agenda-files)))) org-last-tags-completion-table table current-tags (org-split-string current ":") inherited-tags (nreverse @@ -12680,19 +12830,24 @@ (delq nil (mapcar 'cdr table)))) (org-fast-tag-selection current-tags inherited-tags table - (if org-fast-tag-selection-include-todo org-todo-key-alist)) + (if org-fast-tag-selection-include-todo + org-todo-key-alist)) (let ((org-add-colon-after-tag-completion t)) (org-trim (org-without-partial-completion - (org-icompleting-read "Tags: " 'org-tags-completion-function + (org-icompleting-read "Tags: " + 'org-tags-completion-function nil nil current 'org-tags-history))))))) (while (string-match "[-+&]+" tags) ;; No boolean logic, just a list (setq tags (replace-match ":" t t tags)))) + (setq tags (replace-regexp-in-string "[ ,]" ":" tags)) + (if org-tags-sort-function (setq tags (mapconcat 'identity - (sort (org-split-string tags (org-re "[^[:alnum:]_@]+")) + (sort (org-split-string + tags (org-re "[^[:alnum:]_@#%]+")) org-tags-sort-function) ":"))) (if (string-match "\\`[\t ]*\\'" tags) @@ -12702,6 +12857,9 @@ ;; Insert new tags at the correct column (beginning-of-line 1) + (setq level (or (and (looking-at org-outline-regexp) + (- (match-end 0) (point) 1)) + 1)) (cond ((and (equal current "") (equal tags ""))) ((re-search-forward @@ -12710,11 +12868,14 @@ (if (equal tags "") (setq rpl "") (goto-char (match-beginning 0)) - (setq c0 (current-column) p0 (if (equal (char-before) ?*) - (1+ (point)) (point)) - c1 (max (1+ c0) (if (> org-tags-column 0) - org-tags-column - (- (- org-tags-column) (length tags)))) + (setq c0 (current-column) + ;; compute offset for the case of org-indent-mode active + di (if org-indent-mode + (* (1- org-indent-indentation-per-level) (1- level)) + 0) + p0 (if (equal (char-before) ?*) (1+ (point)) (point)) + tc (+ org-tags-column (if (> org-tags-column 0) (- di) di)) + c1 (max (1+ c0) (if (> tc 0) tc (- (- tc) (length tags)))) rpl (concat (make-string (max 0 (- c1 c0)) ?\ ) tags))) (replace-match rpl t t) (and (not (featurep 'xemacs)) c0 indent-tabs-mode (tabify p0 (point))) @@ -12766,7 +12927,7 @@ (defun org-tags-completion-function (string predicate &optional flag) (let (s1 s2 rtn (ctable org-last-tags-completion-table) (confirm (lambda (x) (stringp (car x))))) - (if (string-match "^\\(.*[-+:&|]\\)\\([^-+:&|]*\\)$" string) + (if (string-match "^\\(.*[-+:&,|]\\)\\([^-+:&,|]*\\)$" string) (setq s1 (match-string 1 string) s2 (match-string 2 string)) (setq s1 "" s2 string)) @@ -12843,7 +13004,7 @@ (save-excursion (beginning-of-line 1) (if (looking-at - (org-re ".*[ \t]\\(:[[:alnum:]_@:]+:\\)[ \t]*$")) + (org-re ".*[ \t]\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")) (setq ov-start (match-beginning 1) ov-end (match-end 1) ov-prefix "") @@ -12993,7 +13154,7 @@ (org-fast-tag-insert "Current" current c-face) (org-set-current-tags-overlay current ov-prefix) (while (re-search-forward - (org-re "\\[.\\] \\([[:alnum:]_@]+\\)") nil t) + (org-re "\\[.\\] \\([[:alnum:]_@#%]+\\)") nil t) (setq tg (match-string 1)) (add-text-properties (match-beginning 1) (match-end 1) @@ -13014,7 +13175,7 @@ (error "Not on a heading")) (save-excursion (beginning-of-line 1) - (if (looking-at (org-re ".*[ \t]\\(:[[:alnum:]_@:]+:\\)[ \t]*$")) + (if (looking-at (org-re ".*[ \t]\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")) (org-match-string-no-properties 1) ""))) @@ -13028,7 +13189,7 @@ (save-excursion (goto-char (point-min)) (while (re-search-forward - (org-re "[ \t]:\\([[:alnum:]_@:]+\\):[ \t\r\n]") nil t) + (org-re "[ \t]:\\([[:alnum:]_@#%:]+\\):[ \t\r\n]") nil t) (when (equal (char-after (point-at-bol 0)) ?*) (mapc (lambda (x) (add-to-list 'tags x)) (org-split-string (org-match-string-no-properties 1) ":"))))) @@ -13899,6 +14060,42 @@ (when (org-on-heading-p) (move-marker (make-marker) (point)))))))) +(defun org-find-exact-headline-in-buffer (heading &optional buffer pos-only) + "Find node HEADING in BUFFER. +Return a marker to the heading if it was found, or nil if not. +If POS-ONLY is set, return just the position instead of a marker. + +The heading text must match exact, but it may have a TODO keyword, +a priority cookie and tags in the standard locations." + (with-current-buffer (or buffer (current-buffer)) + (save-excursion + (save-restriction + (widen) + (goto-char (point-min)) + (let (case-fold-search) + (if (re-search-forward + (format org-complex-heading-regexp-format + (regexp-quote heading)) nil t) + (if pos-only + (match-beginning 0) + (move-marker (make-marker) (match-beginning 0))))))))) + +(defun org-find-exact-heading-in-directory (heading &optional dir) + "Find Org node headline HEADING in all .org files in directory DIR. +When the target headline is found, return a marker to this location." + (let ((files (directory-files (or dir default-directory) + nil "\\`[^.#].*\\.org\\'")) + file visiting m buffer) + (catch 'found + (while (setq file (pop files)) + (message "trying %s" file) + (setq visiting (org-find-base-buffer-visiting file)) + (setq buffer (or visiting (find-file-noselect file))) + (setq m (org-find-exact-headline-in-buffer + heading buffer)) + (when (and (not m) (not visiting)) (kill-buffer buffer)) + (and m (throw 'found m)))))) + (defun org-find-entry-with-id (ident) "Locate the entry that contains the ID property with exact value IDENT. IDENT can be a string, a symbol or a number, this function will search for @@ -14190,6 +14387,10 @@ (setq org-read-date-overlay nil))))) (setq final (org-read-date-analyze ans def defdecode)) + + ;; One round trip to get rid of 34th of August and stuff like that.... + (setq final (decode-time (apply 'encode-time final))) + (setq org-read-date-final-answer ans) (if to-time @@ -14457,9 +14658,10 @@ (list arg2 arg1 arg3)) ((eq calendar-date-style 'iso) (list arg2 arg3 arg1))) - (if (org-bound-and-true-p european-calendar-style) - (list arg2 arg1 arg3) - (list arg1 arg2 arg3)))) + (with-no-warnings ;; european-calendar-style is obsolete as of version 23.1 + (if (org-bound-and-true-p european-calendar-style) + (list arg2 arg1 arg3) + (list arg1 arg2 arg3))))) (defun org-eval-in-calendar (form &optional keepdate) "Eval FORM in the calendar window and return to current window. @@ -14498,7 +14700,6 @@ stamp) (if inactive (setq fmt (concat "[" (substring fmt 1 -1) "]"))) (insert-before-markers (or pre "")) - (insert-before-markers (setq stamp (format-time-string fmt time))) (when (listp extra) (setq extra (car extra)) (if (and (stringp extra) @@ -14508,9 +14709,8 @@ (string-to-number (match-string 2 extra)))) (setq extra nil))) (when extra - (backward-char 1) - (insert-before-markers extra) - (forward-char 1)) + (setq fmt (concat (substring fmt 0 -1) extra (substring fmt -1)))) + (insert-before-markers (setq stamp (format-time-string fmt time))) (insert-before-markers (or post "")) (setq org-last-inserted-timestamp stamp))) @@ -14827,7 +15027,10 @@ (sleep-for 2)))))) (cond ((stringp result) result) ((and (consp result) + (not (consp (cdr result))) (stringp (cdr result))) (cdr result)) + ((and (consp result) + (stringp (car result))) result) (result entry) (t nil)))) @@ -15747,7 +15950,7 @@ (concat "ltxpng/" (file-name-sans-extension (file-name-nondirectory buffer-file-name))) - default-directory 'overlays msg at 'forbuffer) + default-directory 'overlays msg at 'forbuffer 'dvipng) (message msg "done. Use `C-c C-c' to remove images."))))) (defvar org-latex-regexps @@ -15761,8 +15964,9 @@ ("$$" "\\$\\$[^\000]*?\\$\\$" 0 nil)) "Regular expressions for matching embedded LaTeX.") +(defvar org-export-have-math nil) ;; dynamic scoping (defun org-format-latex (prefix &optional dir overlays msg at - forbuffer protect-only) + forbuffer processing-type) "Replace LaTeX fragments with links to an image, and produce images. Some of the options can be changed using the variable `org-format-latex-options'." @@ -15776,7 +15980,7 @@ (org-format-latex-header-extra (plist-get (org-infile-export-plist) :latex-header-extra)) (cnt 0) txt hash link beg end re e checkdir - executables-checked + executables-checked string m n block linkfile movefile ov) ;; Check the different regular expressions (while (setq e (pop re-list)) @@ -15792,9 +15996,26 @@ (not (eq (get-char-property (match-beginning n) 'org-overlay-type) 'org-latex-overlay)))) - (if protect-only + (setq org-export-have-math t) + (cond + ((eq processing-type 'verbatim) + ;; Leave the text verbatim, just protect it + (add-text-properties (match-beginning n) (match-end n) + '(org-protected t))) + ((eq processing-type 'mathjax) + ;; Prepare for MathJax processing + (setq string (match-string n)) + (if (member m '("$" "$1")) + (save-excursion + (delete-region (match-beginning n) (match-end n)) + (goto-char (match-beginning n)) + (insert (org-add-props (concat "\\(" (substring string 1 -1) + "\\)") + '(org-protected t)))) (add-text-properties (match-beginning n) (match-end n) - '(org-protected t)) + '(org-protected t)))) + ((or (eq processing-type 'dvipng) t) + ;; Process to an image (setq txt (match-string n) beg (match-beginning n) end (match-end n) cnt (1+ cnt)) @@ -15813,15 +16034,15 @@ (goto-char beg) (unless checkdir ; make sure the directory exists (setq checkdir t) - (or (file-directory-p todir) (make-directory todir))) - + (or (file-directory-p todir) (make-directory todir t))) + (unless executables-checked (org-check-external-command "latex" "needed to convert LaTeX fragments to images") (org-check-external-command "dvipng" "needed to convert LaTeX fragments to images") (setq executables-checked t)) - + (unless (file-exists-p movefile) (org-create-formula-image txt movefile opt forbuffer)) @@ -15848,7 +16069,8 @@ (delete-region beg end) (insert (org-add-props link (list 'org-latex-src - (replace-regexp-in-string "\"" "" txt)))))))))))) + (replace-regexp-in-string + "\"" "" txt))))))))))))) ;; This function borrows from Ganesh Swami's latex2png.el (defun org-create-formula-image (string tofile options buffer) @@ -16019,7 +16241,7 @@ (widen) (setq beg (or beg (point-min)) end (or end (point-max))) (goto-char (point-min)) - (let ((re (concat "\\[\\[\\(\\(file:\\)\\|\\([./~]\\)\\)\\([-+~.:/\\_0-9a-zA-Z ]+" + (let ((re (concat "\\[\\[\\(\\(file:\\)\\|\\([./~]\\)\\)\\([^]\n]+?" (substring (org-image-file-name-regexp) 0 -2) "\\)\\]" (if include-linked "" "\\]"))) old file ov img) @@ -16031,7 +16253,7 @@ (when (file-exists-p file) (if (and (car-safe old) refresh) (image-refresh (overlay-get (cdr old) 'display)) - (setq img (create-image file)) + (setq img (save-match-data (create-image file))) (when img (setq ov (make-overlay (match-beginning 0) (match-end 0))) (overlay-put ov 'display img) @@ -16236,10 +16458,12 @@ (org-defkey org-mode-map "\C-c\C-xo" 'org-toggle-ordered-property) (org-defkey org-mode-map "\C-c\C-xi" 'org-insert-columns-dblock) (org-defkey org-mode-map [(control ?c) (control ?x) ?\;] 'org-timer-set-timer) +(org-defkey org-mode-map [(control ?c) (control ?x) ?\:] 'org-timer-cancel-timer) (org-defkey org-mode-map "\C-c\C-x." 'org-timer) (org-defkey org-mode-map "\C-c\C-x-" 'org-timer-item) (org-defkey org-mode-map "\C-c\C-x0" 'org-timer-start) +(org-defkey org-mode-map "\C-c\C-x_" 'org-timer-stop) (org-defkey org-mode-map "\C-c\C-x," 'org-timer-pause-or-continue) (define-key org-mode-map "\C-c\C-x\C-c" 'org-columns) @@ -16300,6 +16524,8 @@ ("Misc") ("o" . org-open-at-point) ("?" . org-speed-command-help) + ("<" . (org-agenda-set-restriction-lock 'subtree)) + (">" . (org-agenda-remove-restriction-lock)) ) "The default speed commands.") @@ -16346,6 +16572,40 @@ (defvar org-table-auto-blank-field) ; defined in org-table.el (defvar org-speed-command nil) + +(defun org-speed-command-default-hook (keys) + "Hook for activating single-letter speed commands. +`org-speed-commands-default' specifies a minimal command set. Use +`org-speed-commands-user' for further customization." + (when (or (and (bolp) (looking-at outline-regexp)) + (and (functionp org-use-speed-commands) + (funcall org-use-speed-commands))) + (cdr (assoc keys (append org-speed-commands-user + org-speed-commands-default))))) + +(defun org-babel-speed-command-hook (keys) + "Hook for activating single-letter code block commands." + (when (and (bolp) (looking-at org-babel-src-block-regexp)) + (cdr (assoc keys org-babel-key-bindings)))) + +(defcustom org-speed-command-hook + '(org-speed-command-default-hook org-babel-speed-command-hook) + "Hook for activating speed commands at strategic locations. +Hook functions are called in sequence until a valid handler is +found. + +Each hook takes a single argument, a user-pressed command key +which is also a `self-insert-command' from the global map. + +Within the hook, examine the cursor position and the command key +and return nil or a valid handler as appropriate. Handler could +be one of an interactive command, a function, or a form. + +Set `org-use-speed-commands' to non-nil value to enable this +hook. The default setting is `org-speed-command-default-hook'." + :group 'org-structure + :type 'hook) + (defun org-self-insert-command (N) "Like `self-insert-command', use overwrite-mode for whitespace in tables. If the cursor is in a table looking at whitespace, the whitespace is @@ -16353,13 +16613,9 @@ (interactive "p") (cond ((and org-use-speed-commands - (or (and (bolp) (looking-at outline-regexp)) - (and (functionp org-use-speed-commands) - (funcall org-use-speed-commands))) - (setq - org-speed-command - (or (cdr (assoc (this-command-keys) org-speed-commands-user)) - (cdr (assoc (this-command-keys) org-speed-commands-default))))) + (setq org-speed-command + (run-hook-with-args-until-success + 'org-speed-command-hook (this-command-keys)))) (cond ((commandp org-speed-command) (setq this-command org-speed-command) @@ -16426,9 +16682,11 @@ (noalign (looking-at "[^|\n\r]* |")) (c org-table-may-need-update)) (backward-delete-char N) - (skip-chars-forward "^|") - (insert " ") - (goto-char (1- pos)) + (if (not overwrite-mode) + (progn + (skip-chars-forward "^|") + (insert " ") + (goto-char (1- pos)))) ;; noalign: if there were two spaces at the end, this field ;; does not determine the width of the column. (if noalign (setq org-table-may-need-update c))) @@ -17022,13 +17280,10 @@ - If the cursor is a the beginning of a dynamic block, update it. -- If the current buffer is a remember buffer, close note and file - it. A prefix argument of 1 files to the default location - without further interaction. A prefix argument of 2 files to - the currently clocking task. - -- If the cursor is on a <<<target>>>, update radio targets and corresponding - links in this buffer. +- If the current buffer is a capture buffer, close note and file it. + +- If the cursor is on a <<<target>>>, update radio targets and + corresponding links in this buffer. - If the cursor is on a numbered item in a plain list, renumber the ordered list. @@ -17074,12 +17329,12 @@ (org-footnote-at-definition-p)) (call-interactively 'org-footnote-action)) ((org-at-item-checkbox-p) + (call-interactively 'org-list-repair) (call-interactively 'org-toggle-checkbox) (org-list-send-list 'maybe)) ((org-at-item-p) - (if arg - (call-interactively 'org-toggle-checkbox) - (call-interactively 'org-maybe-renumber-ordered-list)) + (call-interactively 'org-list-repair) + (when arg (call-interactively 'org-toggle-checkbox)) (org-list-send-list 'maybe)) ((save-excursion (beginning-of-line 1) (looking-at org-dblock-start-re)) ;; Dynamic block @@ -17136,7 +17391,7 @@ (call-interactively 'org-open-at-point)) ((and (org-at-heading-p) (looking-at - (org-re "\\([ \t]+\\(:[[:alnum:]_@:]+:\\)\\)[ \t]*$"))) + (org-re "\\([ \t]+\\(:[[:alnum:]_@#%:]+:\\)\\)[ \t]*$"))) (org-show-entry) (end-of-line 1) (newline)) @@ -17202,21 +17457,21 @@ ;; We already have items, de-itemize (while (< (setq l (1+ l)) l2) (when (org-at-item-p) - (goto-char (match-beginning 2)) - (delete-region (match-beginning 2) (match-end 2)) - (and (looking-at "[ \t]+") (replace-match ""))) + (skip-chars-forward " \t") + (delete-region (point) (match-end 0))) (beginning-of-line 2)) (if (org-on-heading-p) ;; Headings, convert to items (while (< (setq l (1+ l)) l2) (if (looking-at org-outline-regexp) - (replace-match "- " t t)) + (replace-match (org-list-bullet-string "-") t t)) (beginning-of-line 2)) ;; normal lines, turn them into items (while (< (setq l (1+ l)) l2) (unless (org-at-item-p) (if (looking-at "\\([ \t]*\\)\\(\\S-\\)") - (replace-match "\\1- \\2"))) + (replace-match + (concat "\\1" (org-list-bullet-string "-") "\\2")))) (beginning-of-line 2))))))) (defun org-toggle-heading (&optional nstars) @@ -17518,14 +17773,6 @@ (org-inside-LaTeX-fragment-p)] ["Insert citation" org-reftex-citation t] "--" - ["Export LaTeX fragments as images" - (if (featurep 'org-exp) - (setq org-export-with-LaTeX-fragments - (not org-export-with-LaTeX-fragments)) - (require 'org-exp)) - :style toggle :selected (and (boundp 'org-export-with-LaTeX-fragments) - org-export-with-LaTeX-fragments)] - "--" ["Template for BEAMER" org-insert-beamer-options-template t]) "--" ("MobileOrg" @@ -18107,16 +18354,23 @@ (throw 'exit t))) nil)))) -(defun org-in-regexps-block-p (start-re end-re) +(defun org-in-regexps-block-p (start-re end-re &optional bound) "Return t if the current point is between matches of START-RE and END-RE. -This will also return to if point is on one of the two matches." - (interactive) - (let ((p (point))) - (save-excursion - (and (or (org-at-regexp-p start-re) - (re-search-backward start-re nil t)) - (re-search-forward end-re nil t) - (>= (point) p))))) +This will also return t if point is on one of the two matches or +in an unfinished block. END-RE can be a string or a form +returning a string. + +An optional third argument bounds the search for START-RE. It +defaults to previous heading or `point-min'." + (let ((pos (point)) + (limit (or bound (save-excursion (outline-previous-heading))))) + (save-excursion + ;; we're on a block when point is on start-re... + (or (org-at-regexp-p start-re) + ;; ... or start-re can be found above... + (and (re-search-backward start-re limit t) + ;; ... but no end-re between start-re and point. + (not (re-search-forward (eval end-re) pos t))))))) (defun org-occur-in-agenda-files (regexp &optional nlines) "Call `multi-occur' with buffers for all agenda files." @@ -18392,61 +18646,90 @@ (itemp (org-at-item-p)) (case-fold-search t) (org-drawer-regexp (or org-drawer-regexp "\000")) + (inline-task-p (and (featurep 'org-inlinetask) + (org-inlinetask-in-task-p))) column bpos bcol tpos tcol bullet btype bullet-type) ;; Find the previous relevant line (beginning-of-line 1) (cond + ;; Comments ((looking-at "#") (setq column 0)) + ;; Headings ((looking-at "\\*+ ") (setq column 0)) + ;; Drawers ((and (looking-at "[ \t]*:END:") (save-excursion (re-search-backward org-drawer-regexp nil t))) (save-excursion (goto-char (1- (match-beginning 1))) (setq column (current-column)))) - ((and (looking-at "[ \t]+#\\+end_\\([a-z]+\\)") + ;; Special blocks + ((and (looking-at "[ \t]*#\\+end_\\([a-z]+\\)") (save-excursion (re-search-backward (concat "^[ \t]*#\\+begin_" (downcase (match-string 1))) nil t))) (setq column (org-get-indentation (match-string 0)))) + ((and (not (looking-at "[ \t]*#\\+begin_")) + (org-in-regexps-block-p "^[ \t]*#\\+begin_" "[ \t]*#\\+end_")) + (save-excursion + (re-search-backward "^[ \t]*#\\+begin_\\([a-z]+\\)" nil t)) + (setq column + (if (equal (downcase (match-string 1)) "src") + ;; src blocks: let `org-edit-src-exit' handle them + (org-get-indentation) + (org-get-indentation (match-string 0))))) + ;; Lists + ((org-in-item-p) + (org-beginning-of-item) + (looking-at "[ \t]*\\(\\S-+\\)[ \t]*\\(\\(:?\\[@\\(:?start:\\)?[0-9]+\\][ \t]*\\)?\\[[- X]\\][ \t]*\\|.*? :: \\)?") + (setq bpos (match-beginning 1) tpos (match-end 0) + bcol (progn (goto-char bpos) (current-column)) + tcol (progn (goto-char tpos) (current-column)) + bullet (match-string 1) + bullet-type (if (string-match "[0-9]" bullet) "n" bullet)) + (if (> tcol (+ bcol org-description-max-indent)) + (setq tcol (+ bcol 5))) + (if (not itemp) + (setq column tcol) + (beginning-of-line 1) + (goto-char pos) + (if (looking-at "\\S-") + (progn + (looking-at "[ \t]*\\(\\S-+\\)[ \t]*") + (setq bullet (match-string 1) + btype (if (string-match "[0-9]" bullet) "n" bullet)) + (setq column (if (equal btype bullet-type) bcol tcol))) + (setq column (org-get-indentation))))) + ;; This line has nothing special, look upside to get a clue about + ;; what to do. (t (beginning-of-line 0) - (while (and (not (bobp)) (looking-at "[ \t]*[\n:#|]") - (not (looking-at "[ \t]*:END:")) - (not (looking-at org-drawer-regexp))) - (beginning-of-line 0)) + (while (and (not (bobp)) + ;; skip comments, verbatim, empty lines, tables, + ;; inline tasks + (or (looking-at "[ \t]*[\n:#|]") + (and (org-in-item-p) (goto-char (org-list-top-point))) + (and (not inline-task-p) + (featurep 'org-inlinetask) + (org-inlinetask-in-task-p))) + (not (looking-at "[ \t]*:END:")) + (not (looking-at org-drawer-regexp))) + (beginning-of-line 0)) (cond + ;; There was an heading above. ((looking-at "\\*+[ \t]+") (if (not org-adapt-indentation) (setq column 0) (goto-char (match-end 0)) (setq column (current-column)))) + ;; A drawer had started and is unfinished: indent consequently. ((looking-at org-drawer-regexp) - (goto-char (1- (match-beginning 1))) - (setq column (current-column))) + (goto-char (1- (match-beginning 1))) + (setq column (current-column))) + ;; The drawer had ended: indent like its :END: line. ((looking-at "\\([ \t]*\\):END:") - (goto-char (match-end 1)) - (setq column (current-column))) - ((org-in-item-p) - (org-beginning-of-item) - (looking-at "[ \t]*\\(\\S-+\\)[ \t]*\\(\\[[- X]\\][ \t]*\\|.*? :: \\)?") - (setq bpos (match-beginning 1) tpos (match-end 0) - bcol (progn (goto-char bpos) (current-column)) - tcol (progn (goto-char tpos) (current-column)) - bullet (match-string 1) - bullet-type (if (string-match "[0-9]" bullet) "n" bullet)) - (if (> tcol (+ bcol org-description-max-indent)) - (setq tcol (+ bcol 5))) - (if (not itemp) - (setq column tcol) - (goto-char pos) - (beginning-of-line 1) - (if (looking-at "\\S-") - (progn - (looking-at "[ \t]*\\(\\S-+\\)[ \t]*") - (setq bullet (match-string 1) - btype (if (string-match "[0-9]" bullet) "n" bullet)) - (setq column (if (equal btype bullet-type) bcol tcol))) - (setq column (org-get-indentation))))) + (goto-char (match-end 1)) + (setq column (current-column))) + ;; Else, nothing noticeable found: get indentation and go on. (t (setq column (org-get-indentation)))))) (goto-char pos) (if (<= (current-column) (current-indentation)) @@ -18705,7 +18988,7 @@ (t 'end-of-line))) (let ((pos (point))) (beginning-of-line 1) - (if (looking-at (org-re ".*?\\(?:\\([ \t]*\\)\\(:[[:alnum:]_@:]+:\\)?[ \t]*\\)?$")) + (if (looking-at (org-re ".*?\\(?:\\([ \t]*\\)\\(:[[:alnum:]_@#%:]+:\\)?[ \t]*\\)?$")) (if (eq special t) (if (or (< pos (match-beginning 1)) (= pos (match-end 0))) @@ -18759,7 +19042,7 @@ (not (y-or-n-p "Kill hidden subtree along with headline? "))) (error "C-k aborted - would kill hidden subtree"))) (call-interactively 'kill-line)) - ((looking-at (org-re ".*?\\S-\\([ \t]+\\(:[[:alnum:]_@:]+:\\)\\)[ \t]*$")) + ((looking-at (org-re ".*?\\S-\\([ \t]+\\(:[[:alnum:]_@#%:]+:\\)\\)[ \t]*$")) (kill-region (point) (match-beginning 1)) (org-set-tags nil t)) (t (kill-region (point) (point-at-eol))))) @@ -19003,6 +19286,18 @@ (while (org-goto-sibling 'previous) (org-flag-heading nil)))) +(defun org-goto-first-child () + "Goto the first child, even if it is invisible. +Return t when a child was found. Otherwise don't move point and +return nil." + (let (level (pos (point)) (re (concat "^" outline-regexp))) + (when (condition-case nil (org-back-to-heading t) (error nil)) + (setq level (outline-level)) + (forward-char 1) + (if (and (re-search-forward re nil t) (> (outline-level) level)) + (progn (goto-char (match-beginning 0)) t) + (goto-char pos) nil)))) + (defun org-show-hidden-entry () "Show an entry where even the heading is hidden." (save-excursion @@ -19094,7 +19389,9 @@ (defun org-forward-same-level (arg &optional invisible-ok) "Move forward to the arg'th subheading at same level as this one. -Stop at the first and last subheadings of a superior heading." +Stop at the first and last subheadings of a superior heading. +Normally this only looks at visible headings, but when INVISIBLE-OK is non-nil +it wil also look at invisible ones." (interactive "p") (org-back-to-heading invisible-ok) (org-on-heading-p) @@ -19311,8 +19608,8 @@ ;; Make flyspell not check words in links, to not mess up our keymap (defun org-mode-flyspell-verify () "Don't let flyspell put overlays at active buttons." - (and (not (get-text-property (point) 'keymap)) - (not (get-text-property (point) 'org-no-flyspell)))) + (and (not (get-text-property (max (1- (point)) (point-min)) 'keymap)) + (not (get-text-property (max (1- (point)) (point-min)) 'org-no-flyspell)))) (defun org-remove-flyspell-overlays-in (beg end) "Remove flyspell overlays in region."