From 4be4c56239c224094e717dcd57068f58f99c2dfc Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Thu, 31 Jan 2008 10:30:03 +0100 Subject: [PATCH] version 4.12a --- README | 18 + org | 3730 +++++++++++++++ org.el | 13032 ++++++++++++++++++++++++++++++++++++++++++++++++++ org.pdf | Bin 0 -> 442839 bytes org.texi | 3542 ++++++++++++++ orgcard.pdf | Bin 0 -> 58215 bytes orgcard.tex | 747 +++ 7 files changed, 21069 insertions(+) create mode 100644 README create mode 100644 org create mode 100644 org.el create mode 100644 org.pdf create mode 100644 org.texi create mode 100644 orgcard.pdf create mode 100644 orgcard.tex diff --git a/README b/README new file mode 100644 index 000000000..39ffe5c9f --- /dev/null +++ b/README @@ -0,0 +1,18 @@ +The is the distribution of org-mode, version 3.14 + +The homepage of org-mode is at http://www.astro.uva.nl/~domnik/Tools/org/ + +INSTALLATION +------------ + +The installation instructions are in the documentation, org.pdf + +FILES IN THE DISTRIBUTION +------------------------- + +org.el The Emacs lisp code +org.texi Documentation source file +org.pdf Documentation in PDF format +org Documentation in Info format +orgcard.pdf Refcard, PDF format +orgcard.tex TeX source for refcard.pdf diff --git a/org b/org new file mode 100644 index 000000000..d88a8e50d --- /dev/null +++ b/org @@ -0,0 +1,3730 @@ +This is org, produced by makeinfo version 4.8 from org.texi. + +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* Org Mode: (org). outline-based notes management and organizer +END-INFO-DIR-ENTRY + + This manual is for Org-mode (version 4.12). + + Copyright (C) 2004, 2005, 2006 Free Software Foundation + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.1 or any later version published by the Free Software + Foundation; with no Invariant Sections, with the Front-Cover texts + being "A GNU Manual," and with the Back-Cover Texts as in (a) + below. A copy of the license is included in the section entitled + "GNU Free Documentation License." + + (a) The FSF's Back-Cover Text is: "You have freedom to copy and + modify this GNU Manual, like GNU software. Copies published by + the Free Software Foundation raise funds for GNU development." + + +File: org, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) + +Org Mode Manual +*************** + +This manual is for Org-mode (version 4.12). + + Copyright (C) 2004, 2005, 2006 Free Software Foundation + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.1 or any later version published by the Free Software + Foundation; with no Invariant Sections, with the Front-Cover texts + being "A GNU Manual," and with the Back-Cover Texts as in (a) + below. A copy of the license is included in the section entitled + "GNU Free Documentation License." + + (a) The FSF's Back-Cover Text is: "You have freedom to copy and + modify this GNU Manual, like GNU software. Copies published by + the Free Software Foundation raise funds for GNU development." + +* Menu: + +* Introduction:: Getting started +* Document Structure:: A tree works like your brain +* Tables:: Pure magic for quick formatting +* Hyperlinks:: Notes in context +* TODO items:: Every tree branch can be a TODO item +* Timestamps:: Assign date and time to items +* Agenda Views:: Collecting information into views +* Exporting:: Sharing and publishing of notes +* Miscellaneous:: All the rest which did not fit elsewhere +* Index:: The fast road to specific information +* Key Index:: Key bindings and where they are described + + --- The Detailed Node Listing --- + +Introduction + +* Summary:: Brief summary of what Org-mode does +* Installation and Activation:: How to install Org-mode +* Feedback:: Bug reports, ideas, patches etc. + +Document Structure + +* Outlines:: Org-mode is based on outline-mode +* Headlines:: How to typeset org-tree headlines +* Visibility cycling:: Show and hide, much simplified +* Motion:: Jumping to other headlines +* Structure editing:: Changing sequence and level of headlines +* Archiving:: Move done task trees to a different place +* Sparse trees:: Matches embedded in context +* Tags:: Tagging headlines and matching sets of tags +* Plain Lists:: Editing hand-formatted lists + +Tables + +* Built-in table editor:: Simple tables +* Table calculations:: Compute a field from other fields +* orgtbl-mode:: The table editor as minor mode +* table.el:: Complex tables + +Calculations in tables + +* Formula syntax:: How to write a formula +* Column formulas:: Formulas valid for all fields in a column +* Advanced features:: Field names, parameters and automatic recalc +* Named-field formulas:: Formulas valid in single fields +* Editing/debugging formulas:: Changing a stored formula +* Appetizer:: Taste the power of calc + +Hyperlinks + +* Internal Links:: Links to other places in the current file +* External Links:: URL-like links to the world +* Managing links:: Creating, inserting and following +* Search Options:: Linking to a specific location +* Remember:: Org-trees store quick notes + +Internal Links + +* Radio targets:: Make targets trigger links in plain text. +* CamelCase links:: Activating CamelCase words as links + +TODO items + +* TODO basics:: Marking and displaying TODO entries +* Progress Logging:: Document your productivity +* TODO extensions:: Workflow and assignments +* Priorities:: Some things are more important than others + +Extended use of TODO keywords + +* Workflow states:: From TODO to DONE in steps +* TODO types:: I do this, Fred the rest +* Per file keywords:: Different files, different requirements + +Timestamps + +* Time stamps:: Assigning a time to a tree entry +* Creating timestamps:: Commands which insert timestamps + +Agenda Views + +* Agenda files:: Files being searched for agenda information +* Agenda dispatcher:: Keyboard access to agenda views +* Weekly/Daily Agenda:: The calendar page with current tasks +* Global TODO list:: All unfinished action items +* Matching headline tags:: Structured information with fine-tuned search +* Timeline:: Time-sorted view for single file +* Agenda commands:: Remote editing of org trees + +The weekly/daily agenda + +* Categories:: Not all tasks are equal +* Time-of-day specifications:: How the agenda knows the time +* Calendar/Diary integration:: Integrating Anniversaries and more +* Sorting of agenda items:: The order of things + +Exporting + +* ASCII export:: Export as a structured ASCII file +* HTML export:: Export as an HTML file +* iCalendar export:: Create calendar entries. + +HTML export + +* HTML formatting:: Interpretation of the buffer content +* Export options:: How to influence exports +* Comment lines:: Lines which will not be exported + +Miscellaneous + +* Completion:: M-TAB knows what you need +* Customization:: Adapting Org-mode to your taste +* Clean view:: Getting rid of leading stars in the outline +* TTY keys:: Using Org-mode on a tty +* FAQ:: Frequently asked questions +* Interaction:: Other Emacs packages +* Bugs:: Things which do not work perfectly +* Acknowledgments:: These people provided feedback and more + + +File: org, Node: Introduction, Next: Document Structure, Prev: Top, Up: Top + +1 Introduction +************** + +* Menu: + +* Summary:: Brief summary of what Org-mode does +* Installation and Activation:: How to install Org-mode +* Feedback:: Bug reports, ideas, patches etc. + + +File: org, Node: Summary, Next: Installation and Activation, Prev: Introduction, Up: Introduction + +1.1 Summary +=========== + +Org-mode is a mode for keeping notes, maintaining ToDo lists, and doing +project planning with a fast and effective plain-text system. + + Org-mode develops organizational tasks around NOTES files that +contain information about projects as plain text. Org-mode is +implemented on top of outline-mode, which makes it possible to keep the +content of large files well structured. Visibility cycling and +structure editing help to work with the tree. Tables are easily +created with a built-in table editor. Org-mode supports ToDo items, +deadlines, time stamps, and scheduling. It dynamically compiles +entries into an agenda that utilizes and smoothly integrates much of +the Emacs calendar and diary. Plain text URL-like links connect to +websites, emails, Usenet messages, BBDB entries, and any files related +to the projects. For printing and sharing of notes, an Org-mode file +can be exported as a structured ASCII file, as HTML, or (todo and +agenda items only) as an iCalendar file. + + Org-mode keeps simple things simple. When first fired up, it should +feel like a simple but easy to use outliner. Complexity is not +imposed, but a large amount of functionality is available when you need +it. Org-mode can be used on different levels and in different ways, +for example + + * as an outline extension with visibility cycling and structure editing + * as an ASCII system and table editor for taking structured notes + * as an ASCII table editor with spreadsheet-like capabilities + * as a simple hypertext system, with HTML export + * as a TODO list editor + * as a full agenda and planner with deadlines and work scheduling + + The Org-mode table editor can be integrated into any major mode by +activating the minor Orgtbl-mode. + + There is a website for Org-mode which provides links to the newest +version of Org-mode, as well as additional information, screen shots +and example files. This page is located at +`http://www.astro.uva.nl/~dominik/Tools/org/'. + + +File: org, Node: Installation and Activation, Next: Feedback, Prev: Summary, Up: Introduction + +1.2 Installation and Activation +=============================== + +If Org-mode is part of the Emacs distribution or an XEmacs package, you +only need to copy the following lines to your `.emacs' file. The last +two lines define _global_ keys for the commands `org-store-link' and +`org-agenda' - please choose suitable keys yourself. + + ;; The following lines are always needed. Choose your own keys. + (add-to-list 'auto-mode-alist '("\\.org$" . org-mode)) + (define-key global-map "\C-cl" 'org-store-link) + (define-key global-map "\C-ca" 'org-agenda) + + If you have downloaded Org-mode from the Web, you must byte-compile +`org.el' and put it on your load path. In addition to the Emacs Lisp +lines above, you also need to add the following lines to `.emacs': + + ;; These lines only if org-mode is not part of the X/Emacs distribution. + (autoload 'org-mode "org" "Org mode" t) + (autoload 'org-diary "org" "Diary entries from Org mode") + (autoload 'org-agenda "org" "Multi-file agenda from Org mode" t) + (autoload 'org-store-link "org" "Store a link to the current location" t) + (autoload 'orgtbl-mode "org" "Org tables as a minor mode" t) + (autoload 'turn-on-orgtbl "org" "Org tables as a minor mode") + + With this setup, all files with extension `.org' will be put into +Org-mode. As an alternative, make the first line of a file look like +this: + + MY PROJECTS -*- mode: org; -*- + +which will select Org-mode for this buffer no matter what the file's +name is. See also the variable `org-insert-mode-line-in-empty-file''. + + +File: org, Node: Feedback, Prev: Installation and Activation, Up: Introduction + +1.3 Feedback +============ + +If you find problems with Org-mode, or if you have questions, remarks, +or ideas about it, please contact the maintainer Carsten Dominik at +. + + For bug reports, please provide as much information as possible, +including the version information of Emacs (`C-h v emacs-version +') and Org-mode (`M-x org-version'), as well as the Org-mode +related setup in `.emacs'. If an error occurs, a traceback can be very +useful. Often a small example file helps, along with clear information +about: + 1. What exactly did you do? + + 2. What did you expect to happen? + + 3. What happened instead? + Thanks for helping to improve this mode. + + +File: org, Node: Document Structure, Next: Tables, Prev: Introduction, Up: Top + +2 Document Structure +******************** + +Org-mode is based on outline mode and provides flexible commands to +edit the structure of the document. + +* Menu: + +* Outlines:: Org-mode is based on outline-mode +* Headlines:: How to typeset org-tree headlines +* Visibility cycling:: Show and hide, much simplified +* Motion:: Jumping to other headlines +* Structure editing:: Changing sequence and level of headlines +* Archiving:: Move done task trees to a different place +* Sparse trees:: Matches embedded in context +* Tags:: Tagging headlines and matching sets of tags +* Plain Lists:: Editing hand-formatted lists + + +File: org, Node: Outlines, Next: Headlines, Prev: Document Structure, Up: Document Structure + +2.1 Outlines +============ + +Org-mode is implemented on top of outline-mode. Outlines allow to +organize a document in a hierarchical structure, which (at least for +me) is the best representation of notes and thoughts. Overview over +this structure is achieved by folding (hiding) large parts of the +document to show only the general document structure and the parts +currently being worked on. Org-mode greatly simplifies the use of +outlines by compressing the entire show/hide functionality into a +single command `org-cycle', which is bound to the key. + + +File: org, Node: Headlines, Next: Visibility cycling, Prev: Outlines, Up: Document Structure + +2.2 Headlines +============= + +Headlines define the structure of an outline tree. The Headlines in +Org-mode start with one or more stars, on the left margin. For example + + * Top level headline + ** Second level + *** 3rd level + some text + *** 3rd level + more text + * Another top level headline + Some people find the many stars too noisy and would prefer an +outline that has whitespace followed by a single star as headline +starters. *Note Clean view:: describes a setup to realize this. + + +File: org, Node: Visibility cycling, Next: Motion, Prev: Headlines, Up: Document Structure + +2.3 Visibility cycling +====================== + +Outlines make it possible to hide parts of the text in the buffer. +Org-mode uses a single command bound to the key to change the +visibility in the buffer. + +`' + Rotate current subtree between the states + ,-> FOLDED -> CHILDREN -> SUBTREE --. + '-----------------------------------' + At the beginning of the buffer (or when called with `C-u'), this + does the same as the command `S-' below. + +`S-' + Rotate the entire buffer between the states + ,-> OVERVIEW -> CONTENTS -> SHOW ALL --. + '--------------------------------------' + Note that inside tables, `S-' jumps to the previous field. + +`C-c C-a' + Show all. + + When Emacs first visits an Org-mode file, the global state is set to +OVERVIEW, i.e. only the top level headlines are visible. This can be +configured through the variable `org-startup-folded', or on a per-file +basis by adding one of the following lines anywhere in the buffer: + + #+STARTUP: fold + #+STARTUP: nofold + #+STARTUP: content + + +File: org, Node: Motion, Next: Structure editing, Prev: Visibility cycling, Up: Document Structure + +2.4 Motion +========== + +The following commands jump to other headlines in the buffer. + +`C-c C-n' + Next heading. + +`C-c C-p' + Previous heading. + +`C-c C-f' + Next heading same level. + +`C-c C-b' + Previous heading same level. + +`C-c C-u' + Backward to higher level heading. + +`C-c C-j' + Jump to a different place without changing the current outline + visibility. Shows the document structure in a temporary buffer, + where you can use visibility cycling () to find your + destination. After pressing , the cursor moves to the + selected location in the original buffer, and the headings + hierarchy above it is made visible. + + +File: org, Node: Structure editing, Next: Archiving, Prev: Motion, Up: Document Structure + +2.5 Structure editing +===================== + +`M-' + Insert new heading with same level as current. If the cursor is + in a plain list item, a new item is created. To force creation of + a new headline, use a prefix arg, or first press to get to + the beginning of the next line. + +`M-S-' + Insert new TODO entry with same level as current heading. + +`M-' + Promote current heading by one level + +`M-' + Demote current heading by one level + +`M-S-' + Promote the current subtree by one level + +`M-S-' + Demote the current subtree by one level + +`M-S-' + Move subtree up (swap with previous subtree of same level) + +`M-S-' + Move subtree down (swap with next subtree of same level) + +`C-c C-x C-w' +`C-c C-x C-k' + Kill subtree, i.e. remove it from buffer but save in kill ring. + +`C-c C-x M-w' + Copy subtree to kill ring. + +`C-c C-x C-y' + 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 prefix arg, or by + yanking after a headline marker like `****'. + + When there is an active region (transient-mark-mode), promotion and +demotion work on all headlines in the region. To select a region of +headlines, it is best to place both point and mark at the beginning of a +line, mark at the beginning of the first headline, and point at the line +just after the last headline to change. Note that when the cursor is +inside a table (*note Tables::), the Meta-Cursor keys have different +functionality. + + +File: org, Node: Archiving, Next: Sparse trees, Prev: Structure editing, Up: Document Structure + +2.6 Archiving +============= + +When a project represented by a (sub)tree is finished, you may want to +move the tree to an archive place, either in the same file under a +special top-level heading, or even to a different file. +`C-c $' + Archive the subtree starting at the cursor position to the location + given by `org-archive-location'. + + The default archive is a file in the same directory as the current +file, with the name derived by appending `_archive' to the current file +name. For information and examples on how to change this, see the +documentation string of the variable `org-archive-location'. If you +are also using the Org-mode agenda, archiving to a different file is a +good way to keep archived trees from contributing agenda items. + + +File: org, Node: Sparse trees, Next: Tags, Prev: Archiving, Up: Document Structure + +2.7 Sparse trees +================ + +An important feature of Org-mode is the ability to construct _sparse +trees_ for selected information in an outline tree. A sparse tree +means that the entire document is folded as much as possible, but the +selected information is made visible along with the headline structure +above it(1). Just try it out and you will see immediately how it works. + + Org-mode contains several commands creating such trees. The most +basic one is `org-occur': + +`C-c /' + Occur. Prompts for a regexp and shows a sparse tree with all + matches. If the match is in a headline, the headline is made + visible. If the match is in the body of an entry, headline and + body are made visible. In order to provide minimal context, also + the full hierarchy of headlines above the match is shown, as well + as the headline following the match. Each match is also + highlighted, the highlights disappear when the buffer is changed + with an editing command. + For frequently used sparse trees of specific search strings, you can +use the variable `org-agenda-custom-commands' to define fast keyboard +access to specific sparse trees. These commands will then be +accessible through the agenda dispatcher (*note Agenda dispatcher::). +For example + (setq org-agenda-custom-commands + '(("f" occur-tree "FIXME"))) + will define the key `C-c a f' as a shortcut for creating a sparse +tree matching the string `FIXME'. + + Other commands are using sparse trees as well. For example `C-c +C-v' creates a sparse TODO tree (*note TODO basics::). + + To print a sparse tree, you can use the Emacs command +`ps-print-buffer-with-faces' which does not print invisible parts of +the document (2). Or you can use the command `C-c C-x v' to copy the +visible part of the document to another file (extension `.txt') which +then can be printed in any desired way. + + ---------- Footnotes ---------- + + (1) See also the variables `org-show-hierarchy-above' and +`org-show-following-heading'. + + (2) This does not work under XEmacs, because XEmacs uses selective +display for outlining, not text properties + + +File: org, Node: Tags, Next: Plain Lists, Prev: Sparse trees, Up: Document Structure + +2.8 Tags +======== + +If you wish to implement a tag system to cross-correlate information, +this can be done as well in Org-mode. Every headline can contain a +list of tags, at the end of the headline. Tags are normal words +containing letters, numbers, `_', and `@'. Tags must be preceded and +followed by a single colon; like `:WORK:'. Several tags can be +specified like `:WORK:URGENT:'. + + Tags make use of the hierarchical structure of outline trees. If a +heading has a certain tag, all subheadings will inherit the tag as +well. For example, in the list + + * Meeting with the French group :WORK: + ** Summary by Frank :BOSS:NOTES: + *** TODO Prepare slides for him :ACTION: + the final heading will have the tags `:WORK:', `:BOSS:', `:NOTES:', +and `:ACTION:'. When executing tag searches and Org-mode finds that a +certain headline matches the search criterion, it will not check any +sublevel headline, assuming that these likely also match, and that the +list of matches can become very long. You can influence inheritance +and searching using the variables `org-use-tag-inheritance' and +`org-tags-match-list-sublevels'. + + Tags can simply be typed into the buffer. After a colon, `M-' +offers completion on all tags being used in the current buffer. There +are also special commands for inserting tags, and for executing +searches based on tags. + +`C-c C-c' + Enter new tags for the current headline. The minibuffer will + prompt for a list of tags and offer completion with respect to all + other tags used in the current buffer. Several tags, separated by + colons, may be specified at the prompt. After pressing , the + tags will be inserted and aligned to `org-tags-column'. When + called with a `C-u' prefix, align all tags in the current buffer + to that column, just to make things look nice. TAGS are + automatically realigned after promotion, demotion, and TODO state + changes (*note TODO basics::). + +`C-c \' + Create a sparse tree with all headlines matching a tags search. + +`C-c a m' + Create a global list of tag matches from all agenda files. *Note + Matching headline tags::. + +`C-c a M' + Create a global list of tag matches from all agenda files, but + check only TODO items and force checking subitems (see variable + `org-tags-match-list-sublevels'). + + A tags search string can use Boolean operators `&' for AND and `|' +for OR. `&' binds more strongly than `|'. Parenthesis are currently no +implemented. A tag may also be preceded by `-', to select against it, +and `+' is syntactic sugar for positive selection. The AND operator +`&' is optional when `+' or `-' is present. For example, `+WORK-BOSS' +would select all headlines that are tagged `:WORK:', but discard those +also tagged `:BOSS:'. The search string `WORK|LAPTOP' selects all +lines tagged `:WORK:' or `:LAPTOP:'. The string `WORK|LAPTOP&NIGHT' +requires that the `:LAPTOP:' lines are also tagged `NIGHT'. + + +File: org, Node: Plain Lists, Prev: Tags, Up: Document Structure + +2.9 Plain Lists +=============== + +Headlines define the structure of the Org-mode file, and also lists +(for example TODO items (*note TODO items::) should be created using +headline levels. However, when taking notes, the plain text is +sometimes easier to read with hand-formatted lists. Org-mode supports +editing such lists, and the HTML exporter (*note Exporting::) does +parse and format them. + + Org-mode knows ordered and unordered lists. Unordered list items +start with `-', `+', or `*'(1) as bullets. Ordered list items start +with `1.' or `1)'. Items belonging to the same list must have the same +indentation on the first line. In particular, if an ordered list +reaches number `10.', also 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. For example: + + ** Lord of the Rings + My favorite scenes are (in this order) + 1. Eowyns fight with the witch king + + this was already my favorite scene in the book + + I really like Miranda Otto. + 2. The attack of the Rohirrim + 3. Peter Jackson being shot by Legolas + - on DVD only + He makes a really funny face when it happens. + + Org-mode supports these lists by tuning filling and wrapping commands +to correctly deal with them. Furthermore, the following commands act +on items when the cursor is in the first line of an item (the line with +the bullet or number). + +`' + Items can be folded just like headline levels if you set the + variable `org-cycle-include-plain-lists'. The level of an item is + then given by the indentation of the bullet/number. However, + items are always subordinate to real headlines, the hierarchies + remain completely separated. + +`M-' + Insert new item at current level. With prefix arg, for a new + heading. + +`M-S-' +`M-S-' + Move the item including subitems up/down (swap with previous/next + item of same indentation). If the list is ordered, renumbering is + automatic. + +`M-S-' +`M-S-' + 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. + +`C-c C-c' + Renumber the ordered list at the cursor. + + ---------- Footnotes ---------- + + (1) When using `*' as a bullet, lines must be indented or they will +be seen as top-level headlines. Also, when you are hiding leading +stars to get a clean outline view, plain list items starting with a +star are visually indistinguishable from true headlines. In short: +Even though `*' is supported, it may be better to not use it for plain +list items + + +File: org, Node: Tables, Next: Hyperlinks, Prev: Document Structure, Up: Top + +3 Tables +******** + +Org-mode has a very fast and intuitive table editor built-in. +Spreadsheet-like calculations are supported in connection with the +Emacs `calc' package. + +* Menu: + +* Built-in table editor:: Simple tables +* Table calculations:: Compute a field from other fields +* orgtbl-mode:: The table editor as minor mode +* table.el:: Complex tables + + +File: org, Node: Built-in table editor, Next: Table calculations, Prev: Tables, Up: Tables + +3.1 The built-in table editor +============================= + +Org-mode makes it easy to format tables in plain ASCII. Any line with +`|' as the first non-white character is considered part of a table. +`|' is also the column separator. A table might look like this: + + | Name | Phone | Age | + |-------+-------+-----| + | Peter | 1234 | 17 | + | Anna | 4321 | 25 | + + A table is re-aligned automatically each time you press or + or `C-c C-c' inside the table. also moves to the next +field ( to the next row) and creates new table rows at the end of +the table or before horizontal lines. The indentation of the table is +set by the first line. Any line starting with `|-' is considered as a +horizontal separator line and will be expanded on the next re-align to +span the whole table width. So, to create the above table, you would +only type + + |Name|Phone|Age + |- + and then press to align the table and start filling in fields. + + When typing text into a field, Org-mode treats , , +and all character keys in a special way, so that inserting and deleting +avoids shifting other fields. Also, when typing _immediately after the +cursor was moved into a new field with `', `S-' or `'_, +the field is automatically made blank. If this behavior is too +unpredictable for you, configure the variables +`org-enable-table-editor' and `org-table-auto-blank-field'. + +Creation and conversion +....................... + +`M-x org-table-create' + Creates an empty Org-mode table. However, it is much easier to + just start typing, like `|Name|Phone|Age |- ' + +`C-c C-c' + Convert region to table. Works when the cursor is not in an + existing table, and when there is a region defined. If every line + contains at least one TAB character, the function assumes that the + material is tab separated. If not, lines are split at whitespace + into fields. You can use a prefix argument to indicate how many + consecutive spaces are at least required to indicate a field + separator (default: just one). + +Re-aligning and field motion +............................ + +`C-c C-c' + Re-align the table without moving the cursor. + +`' + Re-align the table, move to the next field. Creates a new row if + necessary. + +`S-' + Re-align, move to previous field. + +`' + Re-align the table and move down to next row. Creates a new row if + necessary. At the beginning or end of a line, still does + NEWLINE, so it can be used to split a table. + +Column and row editing +...................... + +`M-' +`M-' + Move the current column left/right + +`M-S-' + Kill the current column. + +`M-S-' + Insert a new column to the left of the cursor position. + +`M-' +`M-' + Move the current row up/down + +`M-S-' + Kill the current row or horizontal line. + +`M-S-' + Insert a new row above (with arg: below) the current row. + +`C-c -' + Insert a horizontal line below current row. With prefix arg, the + line is created above the current line. + +`C-c ^' + Sort the table lines in the region. Point and mark must be in the + first and last line to be included, and must be in the column that + should be used for sorting. The command prompts for numerical + versus alphanumerical sorting. + +Regions +....... + +`C-c C-x M-w' + Copy a rectangular region from a table to a special clipboard. + Point and mark determine edge fields of the rectangle. The + process ignores horizontal separator lines. + +`C-c C-x C-w' + Copy a rectangular region from a table to a special clipboard, and + blank all fields in the rectangle. So this is the "cut" operation. + +`C-c C-x C-y' + Paste a rectangular region into a table. The upper right corner + ends up in the current field. All involved fields will be + overwritten. If the rectangle does not fit into the present table, + the table is enlarged as needed. The process ignores horizontal + separator lines. + +`C-c C-q' + Wrap several fields in a column like a paragraph. If there is an + active region, and both point and mark are in the same column, the + text in the column is wrapped to minimum width for the given + number of lines. A prefix ARG may be used to change the number of + desired lines. If there is no region, the current field is split + at the cursor position and the text fragment to the right of the + cursor is prepended to the field one line down. If there is no + region, but you specify a prefix ARG, the current field gets + blank, and the content is appended to the field above. + +Calculations +............ + +`C-c =' + Install a new formula for the current column and replace current + field with the result of the formula. + +`C-u C-c =' + Install a new formula for the current field, which must be a named + field. Evaluate the formula and replace the field content with the + result. + +`C-c '' + Edit all formulas associated with the current table in a separate + buffer. + +`C-c *' + Recalculate the current row by applying the stored formulas from + left to right. When called with a `C-u' prefix, recalculate the + entire table, starting with the first non-header line (i.e. below + the first horizontal separator line). For details, see *Note + Table calculations::. + +`C-#' + Rotate the calculation mark in first column through the states `', + `#', `*', `!', `$'. For the meaning of these marks see *Note + Advanced features::. When there is an active region, change all + marks in the region. + +`C-c ?' + Which table column is the cursor in? Displays number >0 in echo + area. + +`C-c +' + Sum the numbers in the current column, or in the rectangle defined + by the active region. The result is shown in the echo area and can + be inserted with `C-y'. + +`S-' + When current field is empty, copy from first non-empty field above. + When not empty, copy current field down to next row and move cursor + along with it. Depending on the variable + `org-table-copy-increment', integer field values will be + incremented during copy. This key is also used by CUA-mode (*note + Interaction::). + +Miscellaneous +............. + +`C-c |' + Toggle the visibility of vertical lines in tables. The lines are + still there, only made invisible with a text property. Any `|' + added by hand will become invisible on the next align. + +`M-x org-table-import' + Import a file as a table. The table should be TAB- or whitespace + separated. Useful for example to import an Excel table or data + from a database, because these programs generally can write + TAB-separated text files. This command works by inserting the + file into the buffer and then converting the region to a table. + Any prefix argument is passed on to the converter, which uses it + to determine the separator. + +`M-x org-table-export' + Export the table as a TAB-separated file. Useful for data + exchange with for example Excel or database programs. + + + If you don't like the automatic table editor because it gets into +your way in lines which you would like to start with `|', you can turn +it off with + (setq org-enable-table-editor nil) + The only table command which then still works is `C-c C-c' to do a +manual re-align. + + +File: org, Node: Table calculations, Next: orgtbl-mode, Prev: Built-in table editor, Up: Tables + +3.2 Calculations in tables +========================== + +The table editor makes use of the Emacs `calc' package to implement +spreadsheet-like capabilities. Org-mode has two levels of complexity +for table calculations. On the basic level, tables do only horizontal +computations, so a field can be computed from other fields _in the same +row_, and Org-mode assumes that there is only one formula for each +column. This is very efficient to work with and enough for many tasks. +On the complex level, columns and individual fields can be named for +easier referencing in formulas, individual named fields can have their +own formula associated with them, and recalculation can be automated. + +* Menu: + +* Formula syntax:: How to write a formula +* Column formulas:: Formulas valid for all fields in a column +* Advanced features:: Field names, parameters and automatic recalc +* Named-field formulas:: Formulas valid in single fields +* Editing/debugging formulas:: Changing a stored formula +* Appetizer:: Taste the power of calc + + +File: org, Node: Formula syntax, Next: Column formulas, Prev: Table calculations, Up: Table calculations + +3.2.1 Formula syntax +-------------------- + +A formula can be any algebraic expression understood by the Emacs +`calc' package. Note that `calc' has the slightly non-standard +conversion that `/' has lower precedence than `*', so that `a/b*c' is +interpreted as `a/(b*c)'. Before evaluation by `calc-eval' (*note +calc-eval: (calc)Calling Calc from Your Lisp Programs.), variable +substitution takes place: + + $ refers to the current field + $3 refers to the field in column 3 of the current row + $3..$7 a vector of the fields in columns 3-7 of current row + $P1..$P3 vector of column range, using column names + &2 second data field above the current, in same column + &5-2 vector from fifth to second field above current + &III-II vector of fields between 2nd and 3rd hline above + &III vector of fields between third hline above and current field + $name a named field, parameter or constant + + The range vectors can be directly fed into the calc vector functions +like `vmean' and `vsum'. + + `$name' is interpreted as the name of a column, parameter or +constant. Constants are defined globally through the variable +`org-table-formula-constants'. If you have the `constants.el' package, +it will also be used to resolve constants, including natural constants +like `$h' for Planck's constant, units like `$km' for kilometers. +Column names and parameters can be specified in special table lines. +These are described below, see *Note Advanced features::. + + A formula can contain an optional mode string after a semicolon. +This string consists of flags to influence calc's modes(1) during +execution, e.g. `p20' to switch the internal precision to 20 digits, +`n3', `s3', `e2' or `f4' to switch to normal, scientific, engineering, +or fix display format, respectively, and `D', `R', `F', and `S' to turn +on degrees, radians, fraction and symbolic modes, respectively. In +addition, you may provide a `printf' format specifier to reformat the +final result. A few examples: + $1+$2 Sum of first and second field + $1+$2;%.2f Same, format result to two decimals + exp($2)+exp($1) Math functions can be used + $;%.1f Reformat current cell to 1 decimal + ($3-32)*5/9 Degrees F -> C conversion + $c/$1/$cm Hz -> cm conversion, using `constants.el' + tan($1);Dp3s1 Compute in degrees, precision 3, display SCI 1 + sin($1);Dp3%.1e Same, but use printf specifier for display + vmean($2..$7) Compute column range mean, using vector function + vsum(&III) Sum numbers from 3rd hline above to here + taylor($3,x=7,2) taylor series of $3, at x=7, second degree + + ---------- Footnotes ---------- + + (1) By default, Org-mode uses the standard calc modes (precision 12, +angular units degrees, fraction and symbolic modes off). However, the +display format has been changed to `(float 5)' to keep tables compact. +The default settings can be configured using the variable +`org-calc-default-modes'. + + +File: org, Node: Column formulas, Next: Advanced features, Prev: Formula syntax, Up: Table calculations + +3.2.2 Column formulas +--------------------- + +To apply a formula to a field, type it directly into the field, +preceded by an equal sign, like `=$1+$2'. When you press or + or `C-c C-c' with the cursor still in the field, the formula will +be stored as the formula for the current column, evaluated and the +current field replaced with the result. If the field contains only +`=', the previously stored formula for this column is used. + + For each column, Org-mode will remember the most recently used +formula. The information is stored in a special line starting with +`#+TBLFM' directly below the table. When adding/deleting/moving +columns with the appropriate commands, the stored equations will be +modified accordingly. When a column used in a calculation is removed, +references to this column become invalid and will cause an error upon +applying the equation. + + Instead of typing an equation into the field, you may also use the +command `C-c ='. It prompts for a formula (with default taken from the +`#+TBLFM:' line) and applies it to the current field. A numerical +prefix (e.g. `C-5 C-c =') will apply it to that many subsequent fields +in the current column. + + To recompute all the fields in a line, use the command `C-c *'. It +re-applies all stored equations to the current row, from left to right. +With a `C-u' prefix, this will be done to every line in the table, so +use this command it you want to make sure the entire table is +up-to-date. `C-u C-c C-c' is another way to update the entire table. +Global updating does not touch the line(s) above the first horizontal +separator line, assuming that this is the table header. + + +File: org, Node: Advanced features, Next: Named-field formulas, Prev: Column formulas, Up: Table calculations + +3.2.3 Advanced features +----------------------- + +If you want want the recalculation of fields to happen automatically, +or if you want to be able to assign a formula to an individual field +(instead of an entire column) you need to reserve the first column of +the table for special marking characters. Here is an example of a +table that collects exam results of students and makes use of these +features: + |---+---------+--------+--------+--------+-------+------| + | | Student | Prob 1 | Prob 2 | Prob 3 | Total | Note | + |---+---------+--------+--------+--------+-------+------| + | ! | | P1 | P2 | P3 | Tot | | + | # | Maximum | 10 | 15 | 25 | 50 | 10.0 | + | ^ | | m1 | m2 | m3 | mt | | + |---+---------+--------+--------+--------+-------+------| + | # | Peter | 10 | 8 | 23 | 41 | 8.2 | + | # | Sara | 6 | 14 | 19 | 39 | 7.8 | + | # | Sam | 2 | 4 | 3 | 9 | 1.8 | + |---+---------+--------+--------+--------+-------+------| + | | Average | | | | 29.7 | | + | ^ | | | | | at | | + | $ | max=50 | | | | | | + |---+---------+--------+--------+--------+-------+------| + #+TBLFM: $6=vsum($P1..$P3)::$7=10*$Tot/$max;%.1f::$at=vmean(&II);%.1f + +Important: Please note that for these special tables, recalculating the +table with `C-u C-c *' does only affect rows which are marked `#' or +`*', and named fields. The column formulas are not applied in rows +with empty first field. + + The marking characters have the following meaning: +`!' + The fields in this line define names for the columns, so that you + may refer to a column as `$Tot' instead of `$6'. + +`^' + This row defines names for the fields _above_ the row. With such + a definition, any formula in the table may use `$m1' to refer to + the value `10'. Also, named fields can have their own formula + associated with them. + +`_' + Similar to `^', but defines names for the fields in the row + _below_. + +`$' + Fields in this row can define _parameters_ for formulas. For + example, if a field in a `$' row contains `max=50', then formulas + in this table can refer to the value 50 using `$max'. Parameters + work exactly like constants, only that they can be defined on a + per-table basis. Changing a parameter and then recalculating the + table can be useful. + +`#' + Fields in this row are automatically recalculated when pressing + or or `S-' in this row. Also, this row is + selected for a global recalculation with `C-u C-c *'. Unmarked + lines will be left alone by this command. + +`*' + Selects this line for global recalculation with `C-u C-c *', but + not for automatic recalculation. Use this when automatic + recalculation slows down editing too much. + +`' + Unmarked lines are exempted from recalculation with `C-u C-c *'. + All lines that should be recalculated should be marked with `#' or + `*'. + + +File: org, Node: Named-field formulas, Next: Editing/debugging formulas, Prev: Advanced features, Up: Table calculations + +3.2.4 Named-field formulas +-------------------------- + +A named field can have its own formula associated with it. In the +example above, this is used for the `at' field that contains the +average result of the students. To enter a formula for a named field, +just type it onto the buffer, preceded by `:='. Or use `C-u C-c ='. +This equation will be stored below the table like `$name=...'. Any +recalculation in the table (even if only requested for the current +line) will also update all named field formulas. + + +File: org, Node: Editing/debugging formulas, Next: Appetizer, Prev: Named-field formulas, Up: Table calculations + +3.2.5 Editing and debugging formulas +------------------------------------ + +To edit a column or field formula, you can use the commands `C-c =' and +`C-u C-c =', respectively. The currently active expression is then +presented as default in the minibuffer, were it may be edited. + + Note that making a table field blank does not remove the formula +associated with the field - during the next recalculation the field +will be filled again. To remove a formula from a field, you have to +give an empty reply when prompted for the formula, or to edit the +`#+TBLFM' line. + + You may edit the `#+TBLFM' directly and re-apply the changed +equations with `C-c C-c' in that line, or with the normal recalculation +commands in the table. + + In particular for large tables with many formulas, it is convenient +to use the command `C-c '' to edit the formulas of the current table in +a separate buffer. That buffer will show the formulas one per line, +and you are free to edit, add and remove formulas. Press `C-c ?' on a +`$...' expression to get information about its interpretation. +Exiting the buffer with `C-c C-c' only stores the modified formulas +below the table. Exiting with `C-u C-c C-c' also applies them to the +entire table. `C-c C-q' exits without installing the changes. + + When the evaluation of a formula leads to an error, the field content +becomes the string `#ERROR'. If you would like see what is going on +during variable substitution and calculation in order to find a bug, +turn on formula debugging in the menu and repeat the calculation by +pressing, for example by pressing `C-c = ' in a field. Detailed +information will be displayed. + + +File: org, Node: Appetizer, Prev: Editing/debugging formulas, Up: Table calculations + +3.2.6 Appetizer +--------------- + +Finally, just to wet your appetite on what can be done with the +fantastic `calc' package, here is a table that computes the Taylor +series for a couple of functions (homework: try that with Excel :-) + + |---+-------------+---+-----+--------------------------------------| + | | Func | n | x | Result | + |---+-------------+---+-----+--------------------------------------| + | # | exp(x) | 1 | x | 1 + x | + | # | exp(x) | 2 | x | 1 + x + x^2 / 2 | + | # | exp(x) | 3 | x | 1 + x + x^2 / 2 + x^3 / 6 | + | # | x^2+sqrt(x) | 2 | x=0 | x*(0.5 / 0) + x^2 (2 - 0.25 / 0) / 2 | + | # | x^2+sqrt(x) | 2 | x=1 | 2 + 2.5 x - 2.5 + 0.875 (x - 1)^2 | + | * | tan(x) | 3 | x | 0.0175 x + 1.77e-6 x^3 | + |---+-------------+---+-----+--------------------------------------| + #+TBLFM: $5=taylor($2,$4,$3);n3 + + +File: org, Node: orgtbl-mode, Next: table.el, Prev: Table calculations, Up: Tables + +3.3 The Orgtbl minor mode +========================= + +If you like the intuitive way the Org-mode table editor works, you +might want to use it also in other modes like text-mode or mail-mode. +The minor mode Orgtbl-mode makes this possible. You can always toggle +the mode with `M-x orgtbl-mode'. To turn it on by default, for example +in mail mode, use + (add-hook 'mail-mode-hook 'turn-on-orgtbl) + + +File: org, Node: table.el, Prev: orgtbl-mode, Up: Tables + +3.4 The `table.el' package +========================== + +Complex ASCII tables with automatic line wrapping, column- and +row-spanning, and alignment can be created using the Emacs table +package by Takaaki Ota (`http://sourceforge.net/projects/table', and +also part of Emacs 22). When or `C-c C-c' is pressed in such a +table, Org-mode will call `table-recognize-table' and move the cursor +into the table. Inside a table, the keymap of Org-mode is inactive. +In order to execute Org-mode-related commands, leave the table. + +`C-c C-c' + Recognize `table.el' table. Works when the cursor is in a + table.el table. + +`C-c ~' + Insert a table.el table. If there is already a table at point, + this command converts it between the table.el format and the + Org-mode format. See the documentation string of the command + `org-convert-table' for the restrictions under which this is + possible. + + +File: org, Node: Hyperlinks, Next: TODO items, Prev: Tables, Up: Top + +4 Hyperlinks +************ + +Just like HMTL, Org-mode provides links inside a file, and external +links to other files, Usenet articles, emails and much more. + +* Menu: + +* Internal Links:: Links to other places in the current file +* External Links:: URL-like links to the world +* Managing links:: Creating, inserting and following +* Search Options:: Linking to a specific location +* Remember:: Org-trees store quick notes + + +File: org, Node: Internal Links, Next: External Links, Prev: Hyperlinks, Up: Hyperlinks + +4.1 Internal Links +================== + +Strings inside double brackets like `[[My Target]]' are links that lead +to a text search in the current file. The link can be followed with +`C-c C-o' or with a mouse click (*note Managing links::). The +preferred match for such a link is a dedicated target: The same string +in double angular brackets. Targets may be located anywhere, often it +is convenient to put them into a comment line, for example + # <> + + If no dedicated target exists, Org-mode will search for the words in +the link, in the above example for `my target'. Links starting with a +star like `*My Target' restrict the search to headlines. When +searching, Org-mode will first try an exact match, but then move on to +more and more lenient searches. For example, the link `[[*My +Targets]]' will find any of the following + ** My targets + ** TODO my targets are bright + ** my 20 targets are + It is therefore often not necessary to set a dedicated target. 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 `M-'. All headlines in the current buffer will be offered +as completions. *Note Managing links::, for more commands creating +links. + + Following a link pushes a mark onto Org-mode's own mark ring. You +can return to the previous position with `C-c &'. Using this command +several times in direct succession goes back to positions recorded +earlier. + +* Menu: + +* Radio targets:: Make targets trigger links in plain text. +* CamelCase links:: Activating CamelCase words as links + + +File: org, Node: Radio targets, Next: CamelCase links, Prev: Internal Links, Up: Internal Links + +4.1.1 Radio targets +------------------- + +You can configure Org-mode to link any occurrences of certain target +names in normal text. So without explicitly creating a link, the text +connects to the target radioing its position. Radio targets are +enclosed by triple angular brackets. For example, a target `<<>>' causes each occurrence of `my target' in normal text to +become activated as a link. The Org-mode file is scanned automatically +for radio targets only when the file is first loaded into Emacs. To +update the target list during editing, press `C-c C-c' with the cursor +on or at a target. + + +File: org, Node: CamelCase links, Prev: Radio targets, Up: Internal Links + +4.1.2 CamelCase words as links +------------------------------ + +As an alternative to `[[...]]' links, Org-mode also supports CamelCase +words as links. This feature is not turned on by default because of +the occasional inconsistencies this system suffers from. To activate +CamelCase words as links, and to make headline completion offer +CamelCase version of headlines, the following customization is needed: + (setq org-activate-camels t + org-file-link-context-use-camel-case t) + + +File: org, Node: External Links, Next: Managing links, Prev: Internal Links, Up: Hyperlinks + +4.2 External Links +================== + +Org-mode supports links to files, websites, Usenet and email messages; +and BBDB database entries. Links are just plain-text URL-like +locators, optionally enclosed by angular brackets. The following list +shows examples for each link type. + + on the web + file, absolute path + file, relative path + Usenet link + Mail link + VM folder link + VM message link + VM on remote machine + WANDERLUST folder link + WANDERLUST message link + MH-E folder link + MH-E message link + RMAIL folder link + RMAIL message link + GNUS group link + GNUS article link + BBDB link + (1) A shell command + + A link may contain space characters and is terminated by `>' or by +the end of a line. In tables, the end of a table field also terminates +a link. Angle brackets around a link are not required, but are +recommended to avoid problems with punctuation and other text following +the link. See also the variable `org-allow-space-in-links'. + + ---------- Footnotes ---------- + + (1) Note that `<' and `>' cannot be part of a link, and therefore of +a shell command. If you need redirection, use @{ and @} instead. + + +File: org, Node: Managing links, Next: Search Options, Prev: External Links, Up: Hyperlinks + +4.3 Managing links +================== + +Org-mode provides methods to create a link in the correct syntax, to +insert it into an org-mode file, and to follow the link. + +`C-c l' + Store a link to the current location. This is a _global_ command + which can be used in any buffer to create a link. The link will be + stored for later insertion into an Org-mode buffer (see below). + For VM, RMAIL, WANDERLUST, GNUS and BBDB buffers, the link will + point to the current article/entry. For W3 and W3M buffer, the + link goes to the current URL. For Org-mode files, the current + headline is targeted. For any other files, the link will point to + the file, with a search string (*note Search Options::) pointing + to the contents of the current line. If there is an active + region, the selected words will form the basis of the search + string. The key binding `C-c l' is only a suggestion - see *Note + Installation and Activation::. + +`C-c C-l' + Insert a link. This prompts for a link to be inserted into the + buffer. You can just type a link, using one of the link type + prefixes mentioned in the examples above. Through completion, all + links stored during the current session can be accessed. When + called with prefix arg, you can use file name completion to enter + a file link. The link will be formatted as given in the variable + `org-link-format' and inserted into the buffer. Note that you + don't have to use this command to insert a link. Links in + Org-mode are plain text, and you can type or paste them straight + into the buffer. + +`C-c C-o' + Open link at point. This will launch a web browser for URLs (using + `browse-url-at-point'), run vm/gnus/bbdb for the corresponding + links, and execute the command in a shell link. When the cursor + is on a CamelCase link, this commands runs the corresponding + search. When the cursor is on a TAGS list in a headline, it + creates the corresponding TAGS view. Furthermore, it will visit + text files in `file:' links with Emacs and select a suitable + application for non-text files. Classification of files is based + on file extension only. See option `org-file-apps'. If there is + no link at point, the current subtree will be searched for one. + If you want to override the default application and visit the file + with Emacs, use a `C-u' prefix. If the cursor is on a time stamp, + compiles the agenda for that date. + + *IMPORTANT*: Be careful not to use any dangerous commands in a + shell link. + +`mouse-2' +`mouse-1' + On links, `mouse-2' will open the link just like `C-c C-o' would. + Under Emacs 22, also `mouse-1' will follow a link. + +`mouse-3' + Like `mouse-2', but force file links to be opened with Emacs. + +`C-c %' + Push the current position onto the mark ring, to be able to return + easily. Commands following an internal link do this automatically. + +`C-c &' + Jump back to a recorded position. A position is recorded by the + commands following internal links, and by `C-c %'. Using this + command several times in direct succession moves through a ring of + previously recorded positions. + + +File: org, Node: Search Options, Next: Remember, Prev: Managing links, Up: Hyperlinks + +4.4 Search options in file links +================================ + +File links can contain additional information to make Emacs jump to a +particular location in the file when following a link. This can be a +line number or a search option after a double(1) colon. For example: + + + + + Here is what these options do. + +`255' + Jump to line 255. + +`My Target' + Search for a link target `<>', or do a text search for + `my target', similar to the search in internal links, see *Note + Internal Links::. + +`*My Target' + In an Org-mode file, restrict search to headlines. + +`/regexp/' + Do a regular expression search for `regexp'. This uses the Emacs + command `occur' to list all matches in a separate window. If the + target file is in Org-mode, `org-occur' is used to create a sparse + tree with the matches. + + As a degenerate case, a file link with an empty file name can be used +to search the current file. For example, `' does a +search for `find me' in the current file, just like `[[find me]]' would. + + ---------- Footnotes ---------- + + (1) For backward compatibility, line numbers can also follow a +single colon. + + +File: org, Node: Remember, Prev: Search Options, Up: Hyperlinks + +4.5 Remember +============ + +Another way to create org entries with links to other files is through +the _Remember_ package by John Wiegley. _Remember_ lets you store +quick notes with little interruption of your work flow. See +`http://www.emacswiki.org/cgi-bin/wiki/RememberMode' for more +information. The notes produced by _Remember_ can be stored in +different ways, and Org-mode files are a good target. Org-mode allows +to file away notes either to a default file, or directly to the correct +location in your Org-mode outline tree. The following customization(1) +will tell _Remember_ to use org files as target, and to create +annotations compatible with Org-mode links. + + (autoload 'org-remember-annotation "org") + (autoload 'org-remember-apply-template "org") + (autoload 'org-remember-handler "org") + (setq org-directory "~/path/to/my/orgfiles/") + (setq org-default-notes-file "~/.notes") + (setq remember-annotation-functions '(org-remember-annotation)) + (setq remember-handler-functions '(org-remember-handler)) + (add-hook 'remember-mode-hook 'org-remember-apply-template) + + In combination with Org-mode, you can use templates to generate +different types of remember notes. For example, if you would like to +use one template to create general TODO entries, and another one for +journal entries, you could use: + + (setq org-remember-templates + '((?t "* TODO %?\n %i\n %a" "~/org/TODO.org") + (?j "* %U %?\n\n %i\n %a" "~/org/JOURNAL.org"))) + In these entries, the character specifies how to select the +template, the first string specifies the template, and the second string +specifies a default file (overruling `org-default-notes-file') as a +target for this note. + + When you call `M-x remember' to remember something, org will prompt +for a key to select the template and then prepare the buffer like + * TODO + + or + * [2006-03-21 Tue 15:37] + + + +See the variable `org-remember-templates' for more details. + + When you are finished composing a note with remember, you have to +press `C-c C-c' to exit remember-mode and to file the note away. The +handler first prompts for a target file - if you press , the value +of `org-default-notes-file' is used. Then the command offers the +headings tree of the selected file. You can either immediately press + to get the note appended to the file. Or you can use vertical +cursor motion ( and ) and visibility cycling () to find +a better place. Pressing or or leads to the +following result. + +Cursor Key Note gets inserted +position +buffer-start as level 2 heading at end of file +on headline as sublevel of the heading at cursor + as same level, before current heading + as same level, after current heading +not on at cursor position, level taken from context. +headline Or use prefix arg to specify level + manually. + + So a fast way to store the note is to press `C-c C-c ' to +append it to the default file. Even shorter would be `C-u C-c C-c', +which does the same without even showing the tree. But with little +extra effort, you can push it directly to the correct location. + + Before inserting the text into a tree, the function ensures that the +text has a headline, i.e. a first line that starts with a `*'. If not, +a headline is constructed from the current date and some additional +data. If the variable `org-adapt-indentation' is non-nil, the entire +text is also indented so that it starts in the same column as the +headline (after the asterisks). + + ---------- Footnotes ---------- + + (1) The three autoload forms are only necessary if `org.el' is not +part of the Emacs distribution or an XEmacs package. + + +File: org, Node: TODO items, Next: Timestamps, Prev: Hyperlinks, Up: Top + +5 TODO items +************ + +Org-mode does not maintain TODO lists as a separate document. TODO +items are an integral part of the notes file, because TODO items +usually come up while taking notes! With Org-mode, you simply mark any +entry in a tree as being a TODO item. In this way, the information is +not duplicated, and the entire context from which the item emerged is +always present when you check. + + Of course, this technique causes TODO items to be scattered +throughout your file. Org-mode provides methods to give you an +overview over all things you have to do. + +* Menu: + +* TODO basics:: Marking and displaying TODO entries +* Progress Logging:: Document your productivity +* TODO extensions:: Workflow and assignments +* Priorities:: Some things are more important than others + + +File: org, Node: TODO basics, Next: Progress Logging, Prev: TODO items, Up: TODO items + +5.1 Basic TODO functionality +============================ + +Any headline can become a TODO item by starting it with the word TODO, +for example + + *** TODO Write letter to Sam Fortune + +The most important commands to work with TODO entries are: + +`C-c C-t' + Rotate the TODO state of the current item between + ,-> (unmarked) -> TODO -> DONE --. + '--------------------------------' + The same rotation can also be done "remotely" from the timeline and + agenda buffers with the `t' command key (*note Agenda commands::). + +`C-c C-v' + View TODO items in a _sparse tree_ (*note Sparse trees::). Folds + the entire buffer, but shows all TODO items and the headings + hierarchy above them. With prefix arg, show also the DONE + entries. With numerical prefix N, show the tree for the Nth + keyword in the variable `org-todo-keywords'. + +`C-c a t' + Show the global TODO list. This collects the TODO items from all + agenda files (*note Agenda Views::) into a single buffer. The + buffer is in `agenda-mode', so there are commands to examine and + manipulate the TODO entries directly from that buffer (*note + Agenda commands::). *Note Global TODO list::, for more + information. + +``org-agenda-include-all-todo'' + If you would like to have all your TODO items listed as part of + your agenda, customize the variable `org-agenda-include-all-todo'. + + +File: org, Node: Progress Logging, Next: TODO extensions, Prev: TODO basics, Up: TODO items + +5.2 Progress Logging +==================== + +If you want to keep track of _when_ a certain TODO item was finished, +turn on logging with + (setq org-log-done t) + Then each time you turn a TODO entry into DONE using either `C-c +C-t' in the Org-mode buffer or `t' in the agenda buffer, a line +`CLOSED: [timestamp]' will be inserted just after the headline. If you +turn the entry back into a TODO item again through further state +cycling, that line will be removed again. In the timeline (*note +Timeline::) and in the agenda (*note Weekly/Daily Agenda::), you can +then use the `L' key to display the TODO items closed on each day, +giving you an overview of what has been done on a day. + + +File: org, Node: TODO extensions, Next: Priorities, Prev: Progress Logging, Up: TODO items + +5.3 Extended use of TODO keywords +================================= + +The default implementation of TODO entries is just two states: TODO +and DONE. You can, however, use the TODO feature for more complicated +things by configuring the variables `org-todo-keywords' and +`org-todo-interpretation'. Using special setup, you can even use TODO +keywords in different ways in different org files. + +* Menu: + +* Workflow states:: From TODO to DONE in steps +* TODO types:: I do this, Fred the rest +* Per file keywords:: Different files, different requirements + + +File: org, Node: Workflow states, Next: TODO types, Prev: TODO extensions, Up: TODO extensions + +5.3.1 TODO keywords as workflow states +-------------------------------------- + +You can use TODO keywords to indicate different states in the process +of working on an item, for example + + (setq org-todo-keywords '("TODO" "FEEDBACK" "VERIFY" "DONE") + org-todo-interpretation 'sequence) + + Changing these variables becomes only effective in a new Emacs +session. With this setup, the command `C-c C-t' will cycle an entry +from TODO to FEEDBACK, then to VERIFY, and finally to DONE. You may +also use a prefix argument to quickly select a specific state. For +example `C-3 C-c C-t' will change the state immediately to VERIFY. If +you define many keywords, you can use in-buffer completion (see *Note +Completion::) to insert these words into the buffer. + + +File: org, Node: TODO types, Next: Per file keywords, Prev: Workflow states, Up: TODO extensions + +5.3.2 TODO keywords as types +---------------------------- + +The second possibility is to use TODO keywords to indicate different +types of action items. For example, you might want to indicate that +items are for "work" or "home". If you are into David Allen's _Getting +Things DONE_, you might want to use todo types `NEXTACTION', `WAITING', +`MAYBE'. Or, when you work with several people on a single project, +you might want to assign action items directly to persons, by using +their names as TODO keywords. This would be set up like this: + + (setq org-todo-keywords '("Fred" "Sara" "Lucy" "Mike" "DONE") + org-todo-interpretation 'type) + + In this case, different keywords do not indicate a sequence, but +rather different types. So it is normally not useful to change from +one type to another. Therefore, in this case the behavior of the +command `C-c C-t' is changed slightly(1). When used several times in +succession, it will still cycle through all names. But when you return +to the item after some time and execute `C-c C-t' again, it will switch +from each name directly to DONE. Use prefix arguments or completion to +quickly select a specific name. You can also review the items of a +specific TODO type in a sparse tree by using a numeric prefix to `C-c +C-v'. For example, to see all things Lucy has to do, you would use +`C-3 C-c C-v'. To collect collect Lucy's items from all agenda files +into a single buffer, you would use the prefix arg as well when +creating the global todo list: `C-3 C-c t'. + + ---------- Footnotes ---------- + + (1) This is also true for the `t' command in the timeline and agenda +buffers. + + +File: org, Node: Per file keywords, Prev: TODO types, Up: TODO extensions + +5.3.3 Setting up TODO keywords for individual files +--------------------------------------------------- + +It can be very useful to use different aspects of the TODO mechanism in +different files, which is not possible with the global settings +described above. For file-local settings, you need to add special +lines to the file which set the keywords and interpretation for that +file only. For example, to set one of the two examples discussed +above, you need one of the following lines, starting in column zero +anywhere in the file: + + #+SEQ_TODO: TODO FEEDBACK VERIFY DONE + #+TYP_TODO: Fred Sara Lucy Mike DONE + +To make sure you are using the correct keyword, type `#+' into the +buffer and then use `M-' completion. + + Remember that the last keyword must always mean that the item is DONE +(you may use a different word, though). Also note that in each file, +only one of the two aspects of TODO keywords can be used. After +changing one of these lines, use `C-c C-c' with the cursor still in the +line to make the changes known to Org-mode(1). + + If you want to use very many keywords, for example when working with +a large group of people, you may split the names over several lines: + + #+TYP_TODO: Fred Sara Lucy Mike + #+TYP_TODO: Luis George Jules Jessica + #+TYP_TODO: Kim Arnold Peter + #+TYP_TODO: DONE + + ---------- Footnotes ---------- + + (1) Org-mode parses these lines only when Org-mode is activated +after visiting a file. `C-c C-c' with the cursor in a line starting +with `#+' is simply restarting Org-mode, making sure that these changes +will be respected. + + +File: org, Node: Priorities, Prev: TODO extensions, Up: TODO items + +5.4 Priorities +============== + +If you use Org-mode extensively to organize your work, you may end up +with a number of TODO entries so large that you'd like to prioritize +them. This can be done by placing a _priority cookie_ into the +headline, like this + + *** TODO [#A] Write letter to Sam Fortune + +With its standard setup, Org-mode supports priorities `A', `B', and +`C'. `A' is the highest priority. An entry without a cookie is +treated as priority `B'. Priorities make a difference only in the +agenda (*note Weekly/Daily Agenda::). + +`C-c ,' + Set the priority of the current item. The command prompts for a + priority character `A', `B' or `C'. When you press instead, + the priority cookie is removed from the headline. The priorities + can also be changed "remotely" from the timeline and agenda buffer + with the `,' command (*note Agenda commands::). + +`S-' +`S-' + Increase/decrease priority of current item. Note that these keys + are also used to modify time stamps (*note Creating timestamps::). + Furthermore, these keys are also used by CUA-mode (*note + Interaction::). + + +File: org, Node: Timestamps, Next: Agenda Views, Prev: TODO items, Up: Top + +6 Timestamps +************ + +Items can be labeled with timestamps to make them useful for project +planning. + +* Menu: + +* Time stamps:: Assigning a time to a tree entry +* Creating timestamps:: Commands which insert timestamps + + +File: org, Node: Time stamps, Next: Creating timestamps, Prev: Timestamps, Up: Timestamps + +6.1 Time stamps, deadlines and scheduling +========================================= + +A time stamp is a specification of a date (possibly with time) in a +special format, either `<2003-09-16 Tue>' or `<2003-09-16 Tue 09:39>'. +A time stamp can appear anywhere in the headline or body of an org-tree +entry. Its presence allows to show entries on specific dates in the +agenda (*note Weekly/Daily Agenda::). We distinguish: + +TIMESTAMP + A simple time stamp just assigns a date/time to an item. In the + timeline and agenda displays, the headline of the entry will be + shown exactly on that date. + +TIMERANGE + Two time stamps connected by `--' denote a time range. The + headline will be shown on the first and last day of the range, and + on any dates that are displayed and fall in the range. Here is an + example: + + ** Meeting in Amsterdam + <2004-08-23 Mon>--<2004-08-26 Thu> + +DEADLINE + If a time stamp is preceded by the word `DEADLINE:', the task + (most likely a TODO item) is supposed to be finished on that date, + and it will be listed then. In addition, the compilation for + _today_ will carry a warning about the approaching or missed + deadline, starting `org-deadline-warning-days' before the due + date, and continuing until the entry is marked DONE. An example: + + *** TODO write article about the Earth for the Guide + The editor in charge is + DEADLINE: <2004-02-29 Sun> + +SCHEDULED + If a time stamp is preceded by the word `SCHEDULED:', it means you + are planning to start working on that task on the given date. The + headline will be listed under the given date. In addition, a + reminder that the scheduled date has passed will be present in the + compilation for _today_, until the entry is marked DONE. I.e., the + task will automatically be forwarded. + + +File: org, Node: Creating timestamps, Prev: Time stamps, Up: Timestamps + +6.2 Creating timestamps +======================= + +For Org-mode to recognize time stamps, they need to be in the specific +format. All commands listed below produce time stamps in the correct +format. + +`C-c .' + Prompt for a date and insert a corresponding time stamp. When the + cursor is at a previously used time stamp, it is updated to NOW. + When this command is used twice in succession, a time range is + inserted. + +`C-u C-c .' + Like `C-c .', but use the alternative format which contains date + and time. The default time can be rounded to to multiples of 5 + minutes, see the option `org-time-stamp-rounding-minutes'. + +`C-c !' + Like `C-c .', but insert an inactive time stamp not triggering the + agenda. + +`C-c <' + Insert a time stamp corresponding to the cursor date in the + Calendar. + +`C-c >' + Access the Emacs calendar for the current date. If there is a + timestamp in the current line, goto the corresponding date instead. + +`C-c C-o' + Access the agenda for the date given by the time stamp at point + (*note Weekly/Daily Agenda::). + +`C-c C-d' + Insert `DEADLINE' keyword along with a stamp. + +`C-c C-w' + Create a sparse tree with all deadlines that are either past-due, + or which will become due within `org-deadline-warning-days'. With + `C-u' prefix, show all deadlines in the file. With a numeric + prefix, check that many days. For example, `C-1 C-c C-w' shows + all deadlines due tomorrow. + +`C-c C-s' + Insert `SCHEDULED' keyword along with a stamp. + +`S-' +`S-' + Change date at cursor by one day. These key bindings conflict with + CUA-mode (*note Interaction::). + +`S-' +`S-' + Change the item under the cursor in a timestamp. The cursor can + be on a year, month, day, hour or minute. Note that if the cursor + is not at a time stamp, these same keys modify the priority of an + item. (*note Priorities::). The key bindings also conflict with + CUA-mode (*note Interaction::). + +`C-c C-y' + Evaluate a time range by computing the difference between start and + end. With prefix arg, insert result after the time range (in a + table: into the following column). + + When Org-mode prompts for a date/time, the function reading your +input will replace anything you choose not to specify with the current +date and time. For details, see the documentation string of +`org-read-date'. Also, a calender will pop up to allow selecting a +date. The calendar can be fully controlled from the minibuffer, and a +date can be selected with the following commands: + +`<' + Scroll calendar backwards by one month. + +`>' + Scroll calendar forwards by one month. + +`mouse-1' + Select date by clicking on it. + +`S-' + One day forward. + +`S-' + One day back. + +`S-' + One week forward. + +`S-' + One week back. + +`M-S-' + One month forward. + +`M-S-' + One month back. + +`' + Choose date in calendar (only if nothing typed into minibuffer). + + +File: org, Node: Agenda Views, Next: Exporting, Prev: Timestamps, Up: Top + +7 Agenda Views +************** + +Due to the way Org-mode works, TODO items and time-stamped items can be +scattered throughout a file or even a number of files. To get an +overview over open action items, or over events that are important for +a particular date, this information must be collected, sorted and +displayed in an organized way. + + Org-mode can select items based on various criteria, and display them +in a separate buffer. Three different views are provided: + * an _agenda_ that is like a calendar and shows information for + specific dates + + * a _TODO list_ that covers all unfinished action items, and + + * a _tags view_ that shows information based on the tags associated + with headlines in the outline tree. + The extracted information is displayed in a special _agenda buffer_. +This buffer is read-only, but provides commands to visit the +corresponding locations in the original Org-mode files, and even to +edit these files remotely. + +* Menu: + +* Agenda files:: Files being searched for agenda information +* Agenda dispatcher:: Keyboard access to agenda views +* Weekly/Daily Agenda:: The calendar page with current tasks +* Global TODO list:: All unfinished action items +* Matching headline tags:: Structured information with fine-tuned search +* Timeline:: Time-sorted view for single file +* Agenda commands:: Remote editing of org trees + + +File: org, Node: Agenda files, Next: Agenda dispatcher, Prev: Agenda Views, Up: Agenda Views + +7.1 Agenda files +================ + +The information to be shown is collected from all _agenda files_, the +files listed in the variable `org-agenda-files'. Thus even if you only +work with a single Org-mode file, this file should be put into that +list(1). You can customize `org-agenda-files', but the easiest way to +maintain it is through the following commands + +`C-c [' + Add current file to the list of agenda files. The file is added to + the front of the list. If it was already in the list, it is moved + to the front. With prefix arg, file is added/moved to the end. + +`C-c ]' + Remove current file from the list of agenda files. + +`C-,' + Cycle through agenda file list. + The Org menu contains the current list of files and can be used to +visit any of them. + + ---------- Footnotes ---------- + + (1) When using the dispatcher pressing `1' before selecting a +command will actually limit the command to the current file, and ignore +`org-agenda-files' until the next dispatcher command. + + +File: org, Node: Agenda dispatcher, Next: Weekly/Daily Agenda, Prev: Agenda files, Up: Agenda Views + +7.2 The agenda dispatcher +========================= + +The views are created through a dispatcher that should be bound to a +global key, for example `C-c a' (*note Installation and Activation::). +In the following we will assume that `C-c a' is indeed how the +dispatcher is accessed and list keyboard access to commands +accordingly. After pressing `C-c a', an additional letter is required +to execute a command. The dispatcher offers the following default +commands: +`a' + Create the calendar-like agenda (*note Weekly/Daily Agenda::). + +`t / T' + Create a list of all TODO items (*note Global TODO list::). + +`m / M' + Create a list of headline matching a TAGS expression (*note + Matching headline tags::). + + You can also define custom commands that will be accessible through +the dispatcher, just like the default commands. Custom commands are +global searches for tags and specific TODO keywords, or a variety of +sparse tree creating commands (*note Sparse trees::). As sparse trees +are only defined for a single org-mode file, these latter commands act +on the current buffer instead of the list of agenda files. + + Custom commands are configured in the variable +`org-agenda-custom-commands'. You can customize this variable, for +example by pressing `C-c a C'. You can also directly set it with Emacs +Lisp in `.emacs'. For example: + (setq org-agenda-custom-commands + '(("w" todo "WAITING") + ("u" tags "+BOSS-URGENT") + ("U" tags-tree "+BOSS-URGENT") + ("f" occur-tree "\\"))) + will define `C-c a w' as a global search for TODO entries with +`WAITING' as todo keyword, `C-c a u' as a global tags search for +headlines marked `:BOSS:' but not `:URGENT:', `C-c a U' to do the same +search but only in the current buffer and display the result as a +sparse tree, and `C-c a f' to create a sparse tree with all entries +containing the word `FIXME'. For more information, look at the +documentation string of the variable `org-agenda-custom-commands'. + + +File: org, Node: Weekly/Daily Agenda, Next: Global TODO list, Prev: Agenda dispatcher, Up: Agenda Views + +7.3 The weekly/daily agenda +=========================== + +The purpose of the weekly/daily _agenda_ is to act like a page of a +paper agenda, showing all the tasks for the current week or day. + +`C-c a a' + Compile an agenda for the current week from a list of org files. + The agenda shows the entries for each day. With a `C-u' prefix (or + when the variable `org-agenda-include-all-todo' is `t'), all + unfinished TODO items (also those without a date) are also listed + at the beginning of the buffer, before the first date. + + Remote editing from the agenda buffer means for example that you can +change the dates of deadlines and appointments from the agenda buffer. +The commands available in the Agenda buffer are listed in *Note Agenda +commands::. + +* Menu: + +* Categories:: Not all tasks are equal +* Time-of-day specifications:: How the agenda knows the time +* Calendar/Diary integration:: Integrating Anniversaries and more +* Sorting of agenda items:: The order of things + + +File: org, Node: Categories, Next: Time-of-day specifications, Prev: Weekly/Daily Agenda, Up: Weekly/Daily Agenda + +7.3.1 Categories +---------------- + +In the agenda buffer, each entry is preceded by a _category_, which is +derived from the file name. The category can also be set with a +special line anywhere in the buffer, looking like this: + #+CATEGORY: Thesis + If there are several such lines in a file, each specifies the +category for the text below it. The display in the agenda buffer looks +best if the category is not longer than 10 characters. + + +File: org, Node: Time-of-day specifications, Next: Calendar/Diary integration, Prev: Categories, Up: Weekly/Daily Agenda + +7.3.2 Time-of-Day Specifications +-------------------------------- + +Org-mode checks each agenda item for a time-of-day specification. The +time can be part of the time stamp that triggered inclusion into the +agenda, for example as in `<2005-05-10 Tue 19:00>'. Time ranges can be +specified with two time stamps, like +`<2005-05-10 Tue 20:30>--<2005-05-10 Tue 22:15>'. + + In the headline of the entry itself, a time(range) may also appear as +plain text (like `12:45' or a `8:30-1pm'. If the agenda integrates the +Emacs diary (*note Calendar/Diary integration::), time specifications +in diary entries are recognized as well. + + For agenda display, Org-mode extracts the time and displays it in a +standard 24 hour format as part of the prefix. The example times in +the previous paragraphs would end up in the agenda like this: + + 8:30-13:00 Arthur Dent lies in front of the bulldozer + 12:45...... Ford Prefect arrives and takes Arthur to the pub + 19:00...... The Vogon reads his poem + 20:30-22:15 Marwin escorts the Hitchhikers to the bridge + + If the agenda is in single-day mode, or for the display of today, the +timed entries are embedded in a time grid, like + + 8:00...... ------------------ + 8:30-13:00 Arthur Dent lies in front of the bulldozer + 10:00...... ------------------ + 12:00...... ------------------ + 12:45...... Ford Prefect arrives and takes Arthur to the pub + 14:00...... ------------------ + 16:00...... ------------------ + 18:00...... ------------------ + 19:00...... The Vogon reads his poem + 20:00...... ------------------ + 20:30-22:15 Marwin escorts the Hitchhikers to the bridge + + The time grid can be turned on and off with the variable +`org-agenda-use-time-grid', and can be configured with +`org-agenda-time-grid'. + + +File: org, Node: Calendar/Diary integration, Next: Sorting of agenda items, Prev: Time-of-day specifications, Up: Weekly/Daily Agenda + +7.3.3 Calendar/Diary integration +-------------------------------- + +Emacs contains the calendar and diary by Edward M. Reingold. The +calendar displays a three-month calendar with holidays from different +countries and cultures. The diary allows to keep track of +anniversaries, lunar phases, sunrise/set, recurrent appointments +(weekly, monthly) and more. In this way, it is quite complementary to +Org-mode. It can be very useful to combine output from Org-mode with +the diary. + + In order to include entries from the Emacs diary into Org-mode's +agenda, you only need to customize the variable + + (setq org-agenda-include-diary t) + After that, everything will happen automatically. All diary entries +including holidays, anniversaries etc will be included in the agenda +buffer created by Org-mode. , , and can be used from +the agenda buffer to jump to the diary file, in order to edit existing +diary entries. The `i' command to insert new entries for the current +date works in the agenda buffer, as well as the commands `S', `M', and +`C' to display Sunrise/Sunset times, show lunar phases and to convert +to other calendars, respectively. `c' can be used to switch back and +forth between calendar and agenda. + + +File: org, Node: Sorting of agenda items, Prev: Calendar/Diary integration, Up: Weekly/Daily Agenda + +7.3.4 Sorting of agenda items +----------------------------- + +The entries for each day are sorted. The default order is to first +collect all items containing an explicit time-of-day specification. +These entries will be shown at the beginning of the list, as a +_schedule_ for the day. After that, items remain grouped in +categories, in the sequence given by `org-agenda-files'. Within each +category, items are sorted by priority (*note Priorities::). + + The priority is a numerical quantity composed of the base priority +(2000 for priority `A', 1000 for `B', and 0 for `C'), plus additional +increments for overdue scheduled or deadline items. + + Sorting can be customized using the variable +`org-agenda-sorting-strategy'. + + +File: org, Node: Global TODO list, Next: Matching headline tags, Prev: Weekly/Daily Agenda, Up: Agenda Views + +7.4 The global TODO list +======================== + +The global TODO list contains all unfinished TODO items, formatted and +collected into a single place. + +`C-c a t' + Show the global TODO list. This collects the TODO items from all + agenda files (*note Agenda Views::) into a single buffer. The + buffer is in `agenda-mode', so there are commands to examine and + manipulate the TODO entries directly from that buffer (*note + Agenda commands::). *Note Global TODO list::, for more + information. + +`C-c a T' + Like the above, but allow to select a specific TODO keyword. You + can also do this by specifying a prefix argument to `C-c a t'. + With a `C-u' prefix you are prompted for a keyword. With a numeric + prefix, the Nth keyword in `org-todo-keywords' is selected. The + `r' key in the agenda buffer regenerates it, and you can give a + prefix argument to this command to change the selected TODO + keyword, for example `3 r'. If you often need a search for a + specific keyword, define a custom command for it (*note Agenda + dispatcher::). + + Remote editing of TODO items means that you can change the state of a +TODO entry with a single key press. The commands available in the TODO +list are described in *Note Agenda commands::. + + +File: org, Node: Matching headline tags, Next: Timeline, Prev: Global TODO list, Up: Agenda Views + +7.5 Matching headline tags +========================== + +If headlines in the agenda files are marked with _tags_ (*note Tags::), +you can select headlines based on the tags that apply to them and +collect them into an agenda buffer. + +`C-c a m' + Produce a list of all headlines that match a given set of tags. + The command prompts for a selection criterion, which is a boolean + logic expression with tags, like `+WORK+URGENT-WITHBOSS' or + `WORK|HOME' (*note Tags::). If you often need a specific search, + define a custom command for it (*note Agenda dispatcher::). + +`C-c a M' + Like `C-c a m', but only select headlines that are also TODO items + and force checking subitems (see variable + `org-tags-match-list-sublevels'. + + The commands available in the tags list are described in *Note +Agenda commands::. + + +File: org, Node: Timeline, Next: Agenda commands, Prev: Matching headline tags, Up: Agenda Views + +7.6 Timeline for a single file +============================== + +The timeline is not really an agenda view, because it only summarizes +items from a single Org-mode file. But it also uses the agenda buffer +and provides similar commands, so we discuss it here. The timeline +shows all time-stamped items in a single Org-mode file (or the selected +part of it), in _time-sorted view_. The main purpose of this command +is to give an overview over events in a project. + +`C-c C-r' + Show a time-sorted view of the org file, with all time-stamped + items. When called with a `C-u' prefix, all unfinished TODO + entries (scheduled or not) are also listed under the current date. + The commands available in the timeline buffer are listed in *Note +Agenda commands::. + + +File: org, Node: Agenda commands, Prev: Timeline, Up: Agenda Views + +7.7 Commands in the agenda buffer +================================= + +Entries in the agenda buffer are linked back to the org file or diary +file where they originate. You are not allowed to edit the agenda +buffer itself, but commands are provided to show and jump to the +original entry location, and to edit the org-files "remotely" from the +agenda buffer. In this way, all information is stored only once, and +you don't risk that your agenda and note files diverge. + + Some commands can be executed with mouse clicks on agenda lines. For +the other commands, the cursor needs to be in the desired line. + +Motion +...... + +`n' + Next line (same as ). + +`p' + Previous line (same as ). + +View/GoTo org file +.................. + +`mouse-3' +`' + Display the original location of the item in another window. + +`L' + Display original location and recenter that window. + +`mouse-2' +`mouse-1' +`' + Go to the original location of the item in another window. Under + Emacs 22, also `mouse-1' will works for this. + +`' + Go to the original location of the item and delete other windows. + +`f' + Toggle Follow mode. In Follow mode, as you move the cursor through + the agenda buffer, the other window always shows the corresponding + location in the org file. + +`l' + Toggle Logbook mode. In Logbook mode, entries that where marked + DONE while logging was on (variable `org-log-done') are shown in + the agenda. + +Change display +.............. + +`o' + Delete other windows. + +`w' + Switch to weekly view (7 days displayed together) + +`d' + Switch to daily view (just one day displayed) + +`D' + Toggle the inclusion of diary entries. See *Note Calendar/Diary + integration::. + +`g' + Toggle the time grid on and off. See also the variables + `org-agenda-use-time-grid' and `org-agenda-time-grid'. + +`r' + Recreate the agenda buffer, for example to reflect the changes + after modification of the time stamps of items with S- and + S-. When the buffer is the global todo list, a prefix + argument is interpreted to create a selective list for a specific + TODO keyword. + +`' + Display the following `org-agenda-ndays' days. For example, if + the display covers a week, switch to the following week. With + prefix arg, go forward that many times `org-agenda-ndays' days. + +`' + Display the previous dates. + +`.' + Goto today. + +Remote editing +.............. + +`0-9' + Digit argument. + +`t' + Change the TODO state of the item, both in the agenda and in the + original org file. + +`T' + Show all tags assiciated with the current item. Because of + inheritance, this may be more than the tags listed in the line + itself. + +`:' + Set tags for the current headline. + +`,' + Set the priority for the current item. Org-mode prompts for the + priority character. If you reply with , the priority cookie + is removed from the entry. + +`p' + Display weighted priority of current item. + +`+' +`S-' + Increase the priority of the current item. The priority is + changed in the original buffer, but the agenda is not resorted. + Use the `r' key for this. + +`-' +`S-' + Decrease the priority of the current item. + +`S-' + Change the time stamp associated with the current line by one day + into the future. With prefix argument, change it by that many + days. For example, `3 6 5 S-' will change it by a year. + The stamp is changed in the original org file, but the change is + not directly reflected in the agenda buffer. Use the `r' key to + update the buffer. + +`S-' + Change the time stamp associated with the current line by one day + into the past. + +`>' + Change the time stamp associated with the current line to today. + The key `>' has been chosen, because it is the same as `S-.' on my + keyboard. + +`i' + Insert a new entry into the diary. Prompts for the type of entry + (day, weekly, monthly, yearly, anniversary, cyclic) and creates a + new entry in the diary, just like `i d' etc. would do in the + calendar. The date is taken from the cursor position. + +Calendar commands +................. + +`c' + Open the Emacs calendar and move to the date at the agenda cursor. + +`c' + When in the calendar, compute and show the Org-mode agenda for the + date at the cursor. + +`M' + Show the phases of the moon for three month around current date. + +`S' + Show sunrise and sunset times. The geographical location must be + set with calendar variables, see documentation of the Emacs + calendar. + +`C' + Convert the date at cursor into many other cultural and historic + calendars. + +`H' + Show holidays for three month around the cursor date. + +`C-c C-x C-c' + Export a single iCalendar file containing entries from all agenda + files. + +Quit and Exit +............. + +`q' + Quit Agenda, remove the agenda buffer. + +`x' + Exit agenda, remove the agenda buffer and all buffers loaded by + Emacs for the compilation of the agenda. Buffers created by the + user to visit org files will not be removed. + + + +File: org, Node: Exporting, Next: Miscellaneous, Prev: Agenda Views, Up: Top + +8 Exporting +*********** + +For printing and sharing of notes, Org-mode documents can be exported +as ASCII or HTML files. To incorporate entries with associated times +like deadlines or appointments into a desktop calendar program like +iCal, Org-mode can also produce extracts in the iCalendar format. + +* Menu: + +* ASCII export:: Export as a structured ASCII file +* HTML export:: Export as an HTML file +* iCalendar export:: Create calendar entries. + + +File: org, Node: ASCII export, Next: HTML export, Prev: Exporting, Up: Exporting + +8.1 ASCII export +================ + +`C-c C-x a' + Export as ASCII file. If there is an active region, only the + region will be exported. For an org file `myfile.org', the ASCII + file will be `myfile.txt'. The file will be overwritten without + warning. + + In the exported version, the first 3 outline levels will become +headlines, defining a general document structure. Additional levels +will be exported as itemize lists. If you want that transition to occur +at a different level, specify it with a prefix argument. For example, + C-1 C-c C-x a org-export-as-ascii + creates only top level headlines and does the rest as items. Lines +starting with `#' and subtrees starting with the word `COMMENT' will +not be exported. + + +File: org, Node: HTML export, Next: iCalendar export, Prev: ASCII export, Up: Exporting + +8.2 HTML export +=============== + +Org-mode contains an HTML exporter with extensive HTML formatting, in +ways similar to John Grubers _markdown_ language, but with additional +support for tables. + +`C-c C-x h' + Export as HTML file `myfile.html'. + +`C-c C-x b' + Export as HTML file and open it with a browser. + +`C-c C-x t' + Insert template with export options, see below. + +`C-c :' + Toggle fixed-width for entry (QUOTE) or region, see below. + + In the exported version, the first 3 outline levels will become +headlines, defining a general document structure. Additional levels +will be exported as itemize lists. If you want that transition to occur +at a different level, specify it with a prefix argument. For example, + C-2 C-c C-x b + creates two levels of headings and does the rest as items. + +* Menu: + +* HTML formatting:: Interpretation of the buffer content +* Export options:: How to influence exports +* Comment lines:: Lines which will not be exported + + +File: org, Node: HTML formatting, Next: Export options, Prev: HTML export, Up: HTML export + +8.2.1 HTML formatting +--------------------- + +Not all text is transferred literally to the exported HTML file. The +exporter implements the following interpretation: + + * Hand-formatted lists with `-', `*' or `+' as bullet, or with `1.' + or `2)' as enumerator will be recognized and transformed into HTML + lists. See *Note Plain Lists::. + + * You can make words *bold*, /italic/, and _underlined_ + + * Simple TeX-like math constructs are interpreted: + + - `10^22' and `J_n' are super- and subscripts. You can quote + `^' and `_' with a backslash: `\_' and `\^' + + - `\alpha' indicates a Greek letter, `\to' an arrow. You can + use completion for these macros, just type `\' and maybe a few + letters, and press `M-' to see possible completions. + + * Tables are transformed into HTML tables. Data fields before the + first horizontal separator line will be formatted as table header + fields. + + * If a headline starts with the word `QUOTE', the text below the + headline will be typeset as fixed-width, to allow quoting of + computer codes etc. Lines starting with `:' are also typeset in + fixed-width font. + + * If you want to include HTML tags which should be interpreted as + such, mark them with a `@' like in `@bold text@'. Plain + `<' and `>' are always transformed to `<' and `>' in HTML + export. + + If these conversions conflict with your habits of typing ASCII text, +they can all be turned off with corresponding variables. + + +File: org, Node: Export options, Next: Comment lines, Prev: HTML formatting, Up: HTML export + +8.2.2 Export options +-------------------- + +The exporter recognizes special lines in the buffer which provide +additional information. These lines may be put anywhere in the file. +The whole set of lines can be inserted into the buffer with `C-c C-x +t'. For individual lines, a good way to make sure the keyword is +correct is to type `#+' and then use `M-' completion (*note +Completion::). + + #+TITLE: the title to be shown (default is the buffer name) + #+AUTHOR: the author (default taken from `user-full-name') + #+EMAIL: his/her email address (default from `user-mail-address') + #+LANGUAGE: language for HTML, e.g. `en' (`org-export-default-language') + #+TEXT: Some descriptive text to be inserted at the beginning. + #+TEXT: Several lines may be given. + #+OPTIONS: H:2 num:t toc:t \n:nil t ::t |:t ^:t *:nil TeX:t + The OPTIONS line is a compact form to specify export settings. Here +you can + H: set the number of headline levels for export + num: turn on/off section-numbers + toc: turn on/off table of contents + \n: turn on/off linebreak-preservation + @: turn on/off quoted html tags + :: turn on/off fixed-width sections + |: turn on/off tables + ^: turn on/off TeX-like syntax for sub- and superscripts. + *: turn on/off emphasized text (bold, italic, underlined) + TeX: turn on/off TeX macros + + You can also give style information for the exported file. The +default specification can be configured through the option +`org-export-html-style'. If you want to use a file-local style, you +may use file variables, best wrapped into a COMMENT section at the end +of the outline tree. For example: + + * COMMENT HTML style specifications + + # Local Variables: + # org-export-html-style: " " + # End: *** + + Remember to execute `M-x normal-mode' after changing this to make +the new style visible to Emacs. + + +File: org, Node: Comment lines, Prev: Export options, Up: HTML export + +8.2.3 Comment lines +------------------- + +Lines starting with `#' in column zero are treated as comments and will +never be exported. Also entire subtrees starting with the word +`COMMENT' will never be exported. Finally, any text before the first +headline will not be exported either. This applies also for ASCII +export. + +`C-c ;' + Toggle the COMMENT keyword at the beginning of an entry. + + +File: org, Node: iCalendar export, Prev: HTML export, Up: Exporting + +8.3 iCalendar export +==================== + +Some people like to 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 have deadlines and +other time-stamped items in Org-mode files show up in the calendar +application. Org-mode can export calendar information in the standard +iCalendar format. + +`C-c C-x i' + Create iCalendar entries for the current file and store them in + the same directory, using a file extension `.ics'. + +`C-c C-x C-i' + Like `C-c C-x i', but do this for all files in `org-agenda-files'. + For each of these files, a separate iCalendar file will be + written. + +`C-c C-x c' + Create a single large iCalendar file from all files in + `org-agenda-files' and write it to the file given by + `org-combined-agenda-icalendar-file'. + + How this calendar is best read and updated, depends on the +application you are using. For example, when using iCal under Apple +MacOS X, you could create a new calendar `OrgMode' (the default name +for the calendar created by `C-c C-x c', see the variables +`org-icalendar-combined-name' and +`org-combined-agenda-icalendar-file'). Then set Org-mode to overwrite +the corresponding file `~/Library/Calendars/OrgMode.ics'. You may even +use AppleScript to make iCal re-read the calendar files each time a new +version of `OrgMode.ics' is produced. Here is the setup needed for +this: + + (setq org-combined-agenda-icalendar-file + "~/Library/Calendars/OrgMode.ics") + (add-hook 'org-after-save-iCalendar-file-hook + (lambda () + (shell-command + "osascript -e 'tell application \"iCal\" to reload calendars'"))) + + +File: org, Node: Miscellaneous, Next: Index, Prev: Exporting, Up: Top + +9 Miscellaneous +*************** + +* Menu: + +* Completion:: M-TAB knows what you need +* Customization:: Adapting Org-mode to your taste +* Clean view:: Getting rid of leading stars in the outline +* TTY keys:: Using Org-mode on a tty +* FAQ:: Frequently asked questions +* Interaction:: Other Emacs packages +* Bugs:: Things which do not work perfectly +* Acknowledgments:: These people provided feedback and more + + +File: org, Node: Completion, Next: Customization, Prev: Miscellaneous, Up: Miscellaneous + +9.1 Completion +============== + +Org-mode supports in-buffer completion. This type of completion does +not make use of the minibuffer. You simply type a few letters into the +buffer and use the key to complete text right there. + +`M-' + Complete word at point + * At the beginning of a headline, complete TODO keywords. + + * After `\', complete TeX symbols supported by the exporter. + + * After `*', complete CamelCase versions of all headlines in the + buffer. + + * After `:', complete tags used elsewhere in the buffer. + + * After `#+', complete the special keywords like `TYP_TODO' or + `OPTIONS' which set file-specific options for Org-mode. When + the option keyword is already complete, pressing `M-' + again will insert example settings for this keyword. + + * Elsewhere, complete dictionary words using ispell. + + +File: org, Node: Customization, Next: Clean view, Prev: Completion, Up: Miscellaneous + +9.2 Customization +================= + +There are more than 100 variables that can be used to customize +Org-mode. For the sake of compactness of the manual, we are not +describing the variables here. A structured overview of customization +variables is available with `M-x org-customize'. Or select `Browse Org +Group' from the `Org->Customization' menu. + + +File: org, Node: Clean view, Next: TTY keys, Prev: Customization, Up: Miscellaneous + +9.3 A cleaner outline view +========================== + +Some people find it noisy and distracting that the Org-mode headlines +are starting with a potentially large number of stars. For example in +the example tree from *Note Headlines::: + + * Top level headline + ** Second level + *** 3rd level + some text + *** 3rd level + more text + * Another top level headline + +Unfortunately this is deeply ingrained into the code of Org-mode and +cannot be easily changed. You can, however, modify the display in such +a way that all leading stars become invisible and the outline more easy +to read. To do this, customize the variable `org-hide-leading-stars' +like this: + + (setq org-hide-leading-stars t) + +or change this on a per-file basis with one of the lines (anywhere in +the buffer) + + #+STARTUP: showstars + #+STARTUP: hidestars + Press `C-c C-c' with the cursor in a `STARTUP' line to activate the +modifications. + + With stars hidden, the tree becomes: + + * Top level headline + * Second level + * 3rd level + some text + * 3rd level + more text + * Another top level headline + +Note that the leading stars are not truly replaced by whitespace, they +are only fontified with the face `org-hide' that uses the background +color as font color. If are are not using either white or black +background, you may have to customize this face to get the wanted +effect. Another possibility is to set this font such that the extra +stars are almost invisible, for example using the color `grey90' on a +white background. + + Things become cleaner still if you skip all the even levels and use +only odd levels 1, 3, 5..., effectively adding two stars to go from one +outline level to the next: + + * Top level headline + * Second level + * 3rd level + some text + * 3rd level + more text + * Another top level headline + +In order to make the structure editing and export commands handle this +convention correctly, use + + (setq org-odd-levels-only t) + +or set this on a per-file basis with one of the following lines (don't +forget to press `C-c C-c' with the cursor in the startup line to +activate changes immediately). + + #+STARTUP: odd + #+STARTUP: oddeven + + You can convert an Org-mode file from single-star-per-level to +double-star-per-level convention with `M-x org-convert-to-odd-levels +RET' in that file. There is no command for the back conversion because +such a command might merge levels and in this way destroy the structure +of the tree. + + +File: org, Node: TTY keys, Next: FAQ, Prev: Clean view, Up: Miscellaneous + +9.4 Using org-mode on a tty +=========================== + +Org-mode uses a number of keys that are not accessible on a tty. This +applies to most special keys like cursor keys, and , when +these are combined with modifier keys like and/or . +Org-mode uses these bindings because it needs to provide keys for a +large number of commands, and because these keys appeared particularly +easy to remember. In order to still be able to access the core +functionality of Org-mode on a tty, alternative bindings are provided. +Here is a complete list of these bindings, which are obviously more +cumbersome to use. Note that sometimes a work-around can be better. +For example changing a time stamp is really only fun with `S-' +keys. On a tty you would rather use `C-c .' to re-insert the +timestamp. + +Default Alternative 1 Alternative 2 +`S-' `C-u ' +`M-' `C-c C-x l' ` ' +`M-S-'`C-c C-x L' +`M-' `C-c C-x r' ` + ' +`M-S-'`C-c C-x R' +`M-' `C-c C-x u' ` ' +`M-S-' `C-c C-x U' +`M-' `C-c C-x d' ` ' +`M-S-'`C-c C-x D' +`S-' `C-c C-x c' +`M-' `C-c C-x m' ` ' +`M-S-' `C-c C-x M' +`S-' `C-c C-x + ' +`S-' `C-c C-x + ' +`S-' `C-c C-x + ' +`S-' `C-c C-x + ' + + +File: org, Node: FAQ, Next: Interaction, Prev: TTY keys, Up: Miscellaneous + +9.5 Frequently asked questions +============================== + + 1. Org-mode seems to be a useful default mode for the various + `README' files I have scattered through my directories. How do I + turn it on for all `README' files? + (add-to-list 'auto-mode-alist '("README$" . org-mode)) + + 2. All these stars are driving me mad, I just find the Emacs outlines + unreadable. Can't you just put white space and a single star as a + starter for headlines? + See *Note Clean view::. + + 3. I would like to have two windows on the same Org-mode file, but + with different outline visibility. Is that possible? + In GNU Emacs, you may use _indirect buffers_ which do exactly + this. See the documentation on the command + `make-indirect-buffer'. In XEmacs, this is currently not possible + because of the different outline implementation. + + 4. Is there an easy way to insert links to web locations? + Sure, just type or paste them into the buffer. A plain-text + URL-like string is directly interpreted as a link. + + 5. When I export my TODO list, every TODO item becomes a separate + section. How do I enforce these items to be exported as an + itemized list? + If you plan to use ASCII or HTML export, make sure things you want + to be exported as item lists are level 4 at least, even if that + does mean there is a level jump. For example + + * Todays top priorities + **** TODO write a letter to xyz + **** TODO Finish the paper + **** Pick up kids at the school + + Alternatively, if you need a specific value for the heading/item + transition in a particular file, use the `+OPTIONS' line to + configure the `H' switch. + + +OPTIONS: H:2; ... + + 6. I would like to export only a subtree of my file to HTML. How? + If you want to export a subtree, mark the subtree as region and + then export. Marking can be done with `C-c @ C-x C-x', for + example. + + 7. Org-mode takes over the S-cursor keys. I also want to use + CUA-mode, is there a way to fix this conflict? + Yes, see *Note Interaction:: + + 8. Is there an easy way to insert an empty table template with a + default number of rows and columns? + To insert an empty table template, just type `|-' and use . + The default size can be changed with the variable + `org-table-default-size'. However, just starting to type the + first line is usually much easier. + + 9. One of my table columns has started to fill up with `#ERROR'. + What is going on? + Org-mode tried to compute the column from other fields using a + formula stored in the `#+TBLFMT:' line just below the table, and + the evaluation of the formula fails. Fix the fields used in the + formula, or fix the formula, or remove it! + + 10. When I am in the last column of a table and just above a + horizontal line in the table, pressing TAB creates a new table line + before the horizontal line. How can I quickly move to the line + below the horizontal line instead? + Press (to get on the separator line) and then . Or + configure the variable `org-table-tab-jumps-over-hlines'. + + 11. How can I change the indentation of an entire table without fixing + every line by hand? + The indentation of a table is set by the first line. So just fix + the indentation of the first line and realign with . + + 12. Is it possible to include entries from org-mode files into my + emacs diary? + Since the org-mode agenda is much more powerful and can contain the + diary (*note Calendar/Diary integration::), you should think twice + before deciding to do this. Inegrating org-mode information into + the diary is, however, possible. The following steps are + necessary: Autoload the function `org-diary' as shown above under + *Note Installation and Activation::. You also need to use _fancy + diary display_ by setting in `.emacs': + + (add-hook 'diary-display-hook 'fancy-diary-display) + + Then include the following line into your `~/diary' file, in order + to get the entries from all files listed in the variable + `org-agenda-files': + + &%%(org-diary) + You may also select specific files with + + &%%(org-diary) ~/path/to/some/org-file.org + &%%(org-diary) ~/path/to/another/org-file.org + + If you now launch the calendar and press `d' to display a diary, + the headlines of entries containing a timestamp, date range, + schedule, or deadline referring to the selected date will be + listed. Just like in Org-mode's agenda view, the diary for + _today_ contains additional entries for overdue deadlines and + scheduled items. See also the documentation of the `org-diary' + function. + + + +File: org, Node: Interaction, Next: Bugs, Prev: FAQ, Up: Miscellaneous + +9.6 Interaction with other packages +=================================== + +Org-mode can cooperate with the following packages: + +`org-mouse.el' by Piotr Zielinski + This package implements extended mouse functionality for Org-mode. + It allows to cycle visibility and to edit the document structure + with the mouse. It also provides a context-sensitive menu that + changes depending on the context of a mouse-click. Use a search + engine to find this package on the web. + +`table.el' by Takaaki Ota + Org mode cooperates with table.el, see *Note table.el::. + `table.el' is part of Emacs 22. + +`calc.el' by Dave Gillespie + Org-mode uses the calc package for implementing spreadsheet + functionality in its tables (*note Table calculations::). + Org-modes checks for the availability of calc by looking for the + function `calc-eval' which should be autoloaded in your setup if + calc has been installed properly. As of Emacs 22, calc is part of + the Emacs distribution. Another possibility for interaction + between the two packages is using calc for embedded calculations. + *Note Embedded Mode: (calc)Embedded Mode. + +`constants.el' by Carsten Dominik + In a table formula (*note Table calculations::), it is possible to + use names for natural constants or units. Instead of defining you + own constants in the variable `org-table-formula-constants', + install the `constants' package which defines a large number of + constants and units, and lets you use unit prefixes like `M' for + `Mega' etc. You will need version 2.0 of this package, available + at `http://www.astro.uva.nl/~dominik/Tools'. Org-mode checks for + the function `constants-get', which has to be autoloaded in your + setup. See the installation instructions in the file + `constants.el'. + +`CUA.el' by Kim. F. Storm + Keybindings in Org-mode conflict with the `S-' keys used + by CUA-mode (as well as pc-select-mode and s-region-mode) to + select and extend the region. If you want to use one of these + packages along with Org-mode, configure the variable + `org-CUA-compatible'. When set, Org-mode will move the following + keybindings in org-mode files, and in the agenda buffer (but not + during date selection). + S-UP -> M-p S-DOWN -> M-n + S-LEFT -> M-- S-RIGHT -> M-+ + S-RET -> C-S-RET + Yes, these are unfortunately more difficult to remember. If you + want to have other replacement keys, look at the variable + `org-disputed-keys'. + +`remember.el' by John Wiegley + Org mode cooperates with remember, see *Note Remember::. + `Remember.el' is not part of Emacs, find it on the web. + +`planner.el' by John Wiegley + Planner is another tool to plan work and keep track of tasks. + Planner uses a multi-file approach with project pages and day + pages. Is based on Emacs-Wiki. If Planner is your primary tool, + it can be useful to display the agenda entries resulting from org + files in day-pages of the planner. This can be done through the + diary of the calendar: Integrate org files into the diary as + described above, and then turn on the diary support of planner. + Planner is not part of Emacs, find it on the web. + + +File: org, Node: Bugs, Next: Acknowledgments, Prev: Interaction, Up: Miscellaneous + +9.7 Bugs +======== + +Here is a list of things which should work differently, but which I +have found too hard to fix. + + * Text in an entry protected with the `QUOTE' keyword should not + autowrap. + + * When the application called by `C-c C-o' to open a file link fails + (for example because the application does not exits or refuses to + open the file), it does so silently. No error message is + displayed. + + * Plain list items should be able to hold a TODO item. + Unfortunately this has so many technical problems that I will only + consider this change for the next major release (5.0). + + * The remote-editing commands in the agenda buffer cannot be undone + with `undo' called from within the agenda buffer. But you can go + to the corresponding buffer (using or and execute + `undo' there. + + * Recalculating a table line applies the formulas from left to right. + If a formula uses _calculated_ fields further down the row, + multiple recalculation may be needed to get all fields consistent. + + * Under XEmacs, if Org-mode entries are included into the diary, it + is not possible to jump back from the diary to the org file. + Apparently, the text properties are lost when the + fancy-diary-display is used. However, from Org-mode's timeline + and agenda buffers (created with `C-c C-r' and `C-c a'), things do + work correctly. + + * You can only make a single word boldface or italic. To emphasize + several words in a row, each must have the emphasize markers, like + in `*three* *bold* *words*'. + + * The exporters work well, but could be made more efficient. + + +File: org, Node: Acknowledgments, Prev: Bugs, Up: Miscellaneous + +9.8 Acknowledgments +=================== + +Org-mode was written by Carsten Dominik, who still maintains it at the +Org-mode homepage `http://www.astro.uva.nl/~dominik/Tools/org/'. The +following people (in alphabetic order) have helped the development +along with ideas, suggestions and patches. Many thanks to all of you, +Org-mode would not be what it is without your input. + + * Thomas Baumann contributed the code for links to the MH-E email + system. + + * Alex Bochannek provided a patch for rounding time stamps. + + * Charles Cave's suggestion sparked the implementation of templates + for Remember. + + * Pavel Chalmoviansky influenced the agenda treatment of items with + specified time. + + * Sacha Chua suggested to copy linking code from Planner (we did take + some). + + * Christian Egli converted the documentation into TeXInfo format, + patched CSS formatting into the HTML exporter, and inspired the + agenda. + + * Kai Grossjohann pointed out key-binding conflicts caused by + Org-mode. + + * Stefan Monnier provided a patch to keep the Emacs-Lisp compiler + happy. + + * Tim O'Callaghan suggested in-file links, search options for + general file links, and TAGS. + + * Oliver Oppitz suggested multi-state TODO items. + + * Pete Phillips helped the development of the TAGS feature. + + * Matthias Rempe (Oelde) provided ideas, Windows support, and quality + control. + + * Kevin Rogers contributed code to access VM files on remote hosts. + + * Philip Rooke created the Org-mode reference card and provided lots + of feedback. + + * Christian Schlauer proposed angular brackets around links, among + other things. + + * Linking to VM/BBDB/GNUS was inspired by Tom Shannon's + `organizer-mode.el'. + + * Ju"rgen Vollmer contributed code generating the table of contents + in HTML output. + + * Chris Wallace provided a patch implementing the `QUOTE' keyword. + + * David Wainberg suggested archiving, and improvements to the linking + system. + + * Scheduling TODO items was inspired by John Wiegley's `planner.el'. + + * Carsten Wimmer suggested some changes and helped fix a bug in + linking to GNUS. + + * Roland Winkler requested additional keybindings to make Org-mode + work on a tty. + + * Piotr Zielinski wrote `org-mouse.el' and showed how to follow links + with mouse-1. + + +File: org, Node: Index, Next: Key Index, Prev: Miscellaneous, Up: Top + +10 Index +******** + +[index] +* Menu: + +* acknowledgments: Acknowledgments. (line 6) +* active region <1>: HTML export. (line 10) +* active region <2>: ASCII export. (line 6) +* active region <3>: Built-in table editor. + (line 166) +* active region: Structure editing. (line 46) +* agenda: Weekly/Daily Agenda. (line 6) +* agenda commands, custom: Agenda dispatcher. (line 6) +* agenda dispatcher: Agenda dispatcher. (line 6) +* agenda files, removing buffers: Agenda commands. (line 186) +* agenda views: Agenda Views. (line 6) +* agenda, for single file: Timeline. (line 6) +* applescript, for calendar update: iCalendar export. (line 38) +* archive locations: Archiving. (line 13) +* archiving: Archiving. (line 6) +* ASCII export: ASCII export. (line 6) +* author: Feedback. (line 6) +* autoload: Installation and Activation. + (line 6) +* BBDB links: External Links. (line 6) +* bold text: HTML formatting. (line 13) +* bug reports: Feedback. (line 6) +* bugs: Bugs. (line 6) +* calc package: Table calculations. (line 6) +* calc.el: Interaction. (line 17) +* calculations, in tables <1>: Table calculations. (line 6) +* calculations, in tables: Built-in table editor. + (line 136) +* calendar integration: Calendar/Diary integration. + (line 6) +* calendar, for selecting date: Creating timestamps. (line 68) +* CamelCase link completion: Completion. (line 6) +* CamelCase links: Internal Links. (line 6) +* CamelCase links, completion of: CamelCase links. (line 6) +* category: Categories. (line 6) +* children, subtree visibility state: Visibility cycling. (line 10) +* clean outline view: Clean view. (line 6) +* column formula: Column formulas. (line 6) +* commands, in agenda buffer: Agenda commands. (line 6) +* comment lines: Comment lines. (line 6) +* completion, of CamelCase links <1>: Completion. (line 6) +* completion, of CamelCase links: CamelCase links. (line 6) +* completion, of dictionary words: Completion. (line 6) +* completion, of file names: Managing links. (line 23) +* completion, of links: Managing links. (line 23) +* completion, of option keywords <1>: Completion. (line 6) +* completion, of option keywords: Export options. (line 6) +* Completion, of option keywords: Per file keywords. (line 17) +* completion, of tags <1>: Completion. (line 6) +* completion, of tags: Tags. (line 34) +* completion, of TeX symbols <1>: Completion. (line 6) +* completion, of TeX symbols: HTML formatting. (line 17) +* completion, of TODO keywords <1>: Completion. (line 6) +* completion, of TODO keywords: Workflow states. (line 12) +* constants, in calculations: Formula syntax. (line 26) +* constants.el: Interaction. (line 27) +* contents, global visibility state: Visibility cycling. (line 17) +* copying, of subtrees: Structure editing. (line 6) +* creating timestamps: Creating timestamps. (line 6) +* CUA.el: Interaction. (line 39) +* custom agenda commands: Agenda dispatcher. (line 6) +* customization: Customization. (line 6) +* cutting, of subtrees: Structure editing. (line 6) +* cycling, of TODO states: TODO basics. (line 13) +* cycling, visibility: Visibility cycling. (line 6) +* date stamps: Time stamps. (line 6) +* date, reading in minibuffer: Creating timestamps. (line 68) +* DEADLINE keyword: Time stamps. (line 27) +* deadlines: Time stamps. (line 6) +* demotion, of subtrees: Structure editing. (line 6) +* diary entries, creating from agenda: Agenda commands. (line 145) +* diary integration: Calendar/Diary integration. + (line 6) +* dictionary word completion: Completion. (line 6) +* dispatching agenda commands: Agenda dispatcher. (line 6) +* document structure: Document Structure. (line 6) +* DONE, final TODO keyword: Per file keywords. (line 20) +* editing tables: Tables. (line 6) +* editing, of table formulas: Editing/debugging formulas. + (line 6) +* emphasized text: Export options. (line 21) +* evaluate time range: Creating timestamps. (line 63) +* exporting: Exporting. (line 6) +* exporting a subtree: FAQ. (line 46) +* exporting, not: Comment lines. (line 6) +* extended TODO keywords: TODO extensions. (line 6) +* external links: External Links. (line 6) +* FAQ: FAQ. (line 6) +* feedback: Feedback. (line 6) +* file links: External Links. (line 6) +* file links, searching: Search Options. (line 6) +* file name completion: Managing links. (line 23) +* files, adding to agenda list: Agenda files. (line 12) +* filing subtrees: Archiving. (line 6) +* fixed width: HTML formatting. (line 28) +* fixed-width sections: Export options. (line 21) +* folded, subtree visibility state: Visibility cycling. (line 10) +* folding, sparse trees: Sparse trees. (line 6) +* following links: Managing links. (line 35) +* format specifier: Formula syntax. (line 34) +* formula editing: Editing/debugging formulas. + (line 6) +* formula syntax: Formula syntax. (line 6) +* formula, for named table field: Named-field formulas. + (line 6) +* formula, for table column: Column formulas. (line 6) +* formula, in tables: Built-in table editor. + (line 136) +* global keybindings: Installation and Activation. + (line 6) +* global TODO list: Global TODO list. (line 6) +* global visibility states: Visibility cycling. (line 17) +* GNUS links: External Links. (line 6) +* hand-formatted lists: HTML formatting. (line 9) +* headline levels: Export options. (line 21) +* headline levels, for exporting <1>: HTML export. (line 22) +* headline levels, for exporting: ASCII export. (line 12) +* headline navigation: Motion. (line 6) +* headline tagging: Tags. (line 6) +* headline, promotion and demotion: Structure editing. (line 6) +* headlines: Headlines. (line 6) +* hide text: Visibility cycling. (line 6) +* hiding leading stars: Clean view. (line 6) +* HTML export: HTML export. (line 6) +* HTML tags: HTML formatting. (line 33) +* hyperlinks: Hyperlinks. (line 6) +* iCalendar export: iCalendar export. (line 6) +* indentation, of tables: FAQ. (line 77) +* indirect buffers: FAQ. (line 18) +* inheritance, of tags: Tags. (line 13) +* inserting links: Managing links. (line 23) +* installation: Installation and Activation. + (line 6) +* internal links: Internal Links. (line 6) +* introduction: Introduction. (line 6) +* italic text: HTML formatting. (line 13) +* jumping, to headlines: Motion. (line 6) +* keybindings, global: Installation and Activation. + (line 6) +* keyword options: Per file keywords. (line 6) +* linebreak preservation: Export options. (line 21) +* link completion: Managing links. (line 23) +* links, external: External Links. (line 6) +* links, internal: Internal Links. (line 6) +* links, returning to: Managing links. (line 65) +* lists, hand-formatted: HTML formatting. (line 9) +* lists, ordered: Plain Lists. (line 6) +* lists, plain: Plain Lists. (line 6) +* logging, of progress: Progress Logging. (line 6) +* maintainer: Feedback. (line 6) +* make-indirect-buffer: FAQ. (line 18) +* mark ring: Managing links. (line 61) +* marking characters, tables: Advanced features. (line 34) +* matching, of tags: Matching headline tags. + (line 6) +* matching, tags: Tags. (line 6) +* MH-E links: External Links. (line 6) +* minor mode for tables: orgtbl-mode. (line 6) +* mode, for calc: Formula syntax. (line 34) +* motion, between headlines: Motion. (line 6) +* name, of column or field: Formula syntax. (line 26) +* named field formula: Named-field formulas. + (line 6) +* names as TODO keywords: TODO types. (line 6) +* occur, command: Sparse trees. (line 6) +* option keyword completion: Completion. (line 6) +* options, for customization: Customization. (line 6) +* options, for export: Export options. (line 6) +* ordered lists: Plain Lists. (line 6) +* org-agenda, command: Weekly/Daily Agenda. (line 9) +* org-mode, turning on: Installation and Activation. + (line 28) +* org-mouse.el: Interaction. (line 8) +* orgtbl-mode: orgtbl-mode. (line 6) +* outline tree: Headlines. (line 6) +* outline-mode: Outlines. (line 6) +* outlines: Outlines. (line 6) +* overview, global visibility state: Visibility cycling. (line 17) +* packages, interaction with other: Interaction. (line 6) +* pasting, of subtrees: Structure editing. (line 6) +* per file keywords: Per file keywords. (line 6) +* plain lists: Plain Lists. (line 6) +* planner.el: Interaction. (line 58) +* printing sparse trees: Sparse trees. (line 37) +* priorities: Priorities. (line 6) +* priorities, of agenda items: Sorting of agenda items. + (line 6) +* progress logging: Progress Logging. (line 6) +* promotion, of subtrees: Structure editing. (line 6) +* quoted html tags: Export options. (line 21) +* ranges, time: Time stamps. (line 6) +* recomputing table fields: Column formulas. (line 27) +* region, active <1>: HTML export. (line 10) +* region, active <2>: ASCII export. (line 6) +* region, active <3>: Built-in table editor. + (line 166) +* region, active: Structure editing. (line 46) +* remember.el <1>: Interaction. (line 39) +* remember.el: Remember. (line 6) +* RMAIL links: External Links. (line 6) +* SCHEDULED keyword: Time stamps. (line 39) +* scheduling: Time stamps. (line 6) +* search option in file links: Search Options. (line 6) +* section-numbers: Export options. (line 21) +* SHELL links: External Links. (line 6) +* show all, command: Visibility cycling. (line 23) +* show all, global visibility state: Visibility cycling. (line 17) +* show hidden text: Visibility cycling. (line 6) +* single file summary: Timeline. (line 6) +* sorting, of agenda items: Sorting of agenda items. + (line 6) +* sparse tree, for deadlines: Creating timestamps. (line 38) +* sparse tree, for TODO: TODO basics. (line 18) +* sparse tree, tag based: Tags. (line 6) +* sparse trees: Sparse trees. (line 6) +* spreadsheet capabilities: Table calculations. (line 6) +* storing links: Managing links. (line 9) +* structure editing: Structure editing. (line 6) +* structure of document: Document Structure. (line 6) +* subtree visibility states: Visibility cycling. (line 10) +* subtree, cut and paste: Structure editing. (line 6) +* subtree, subtree visibility state: Visibility cycling. (line 10) +* subtrees, cut and paste: Structure editing. (line 6) +* summary: Summary. (line 6) +* syntax, of formulas: Formula syntax. (line 6) +* table editor, builtin: Built-in table editor. + (line 6) +* table editor, table.el: table.el. (line 6) +* table of contents: Export options. (line 21) +* table, empty template: FAQ. (line 56) +* table.el <1>: Interaction. (line 13) +* table.el: table.el. (line 6) +* tables <1>: Export options. (line 21) +* tables: Tables. (line 6) +* tables, export to HTML: HTML formatting. (line 24) +* tag completion: Completion. (line 6) +* tags: Tags. (line 6) +* tags view: Matching headline tags. + (line 6) +* templates, for remember: Remember. (line 26) +* TeX interpretation: HTML formatting. (line 15) +* TeX macros: Export options. (line 21) +* TeX symbol completion: Completion. (line 6) +* TeX-like syntax for sub- and superscripts: Export options. (line 21) +* thanks: Acknowledgments. (line 6) +* time stamps: Time stamps. (line 6) +* time, reading in minibuffer: Creating timestamps. (line 68) +* time-sorted view: Timeline. (line 6) +* timeline, single file: Timeline. (line 6) +* timerange: Time stamps. (line 18) +* timestamp: Time stamps. (line 12) +* timestamps, creating: Creating timestamps. (line 6) +* TODO items: TODO items. (line 6) +* TODO keywords completion: Completion. (line 6) +* TODO list, global: Global TODO list. (line 6) +* TODO types: TODO types. (line 6) +* TODO workflow: Workflow states. (line 6) +* transient-mark-mode <1>: HTML export. (line 10) +* transient-mark-mode <2>: ASCII export. (line 6) +* transient-mark-mode <3>: Built-in table editor. + (line 166) +* transient-mark-mode: Structure editing. (line 46) +* trees, sparse: Sparse trees. (line 6) +* trees, visibility: Visibility cycling. (line 6) +* tty keybindings: TTY keys. (line 6) +* types as TODO keywords: TODO types. (line 6) +* underlined text: HTML formatting. (line 13) +* URL links: External Links. (line 6) +* URL, paste into buffer: FAQ. (line 24) +* USENET links: External Links. (line 6) +* variables, for customization: Customization. (line 6) +* vectors, in table calculations: Formula syntax. (line 23) +* visibility cycling: Visibility cycling. (line 6) +* visible text, printing: Sparse trees. (line 37) +* VM links: External Links. (line 6) +* WANDERLUST links: External Links. (line 6) +* workflow states as TODO keywords: Workflow states. (line 6) + + +File: org, Node: Key Index, Prev: Index, Up: Top + +11 Key Index +************ + +[index] +* Menu: + +* +: Agenda commands. (line 118) +* ,: Agenda commands. (line 110) +* -: Agenda commands. (line 124) +* .: Agenda commands. (line 89) +* :: Agenda commands. (line 107) +* <: Creating timestamps. (line 75) +* : Agenda commands. (line 86) +* <1>: Agenda commands. (line 41) +* <2>: Creating timestamps. (line 100) +* : Built-in table editor. + (line 65) +* : Agenda commands. (line 81) +* : Agenda commands. (line 28) +* <1>: Agenda commands. (line 35) +* <2>: Built-in table editor. + (line 58) +* <3>: Plain Lists. (line 37) +* : Visibility cycling. (line 10) +* > <1>: Agenda commands. (line 140) +* >: Creating timestamps. (line 76) +* C: Agenda commands. (line 169) +* c: Agenda commands. (line 154) +* C-#: Built-in table editor. + (line 156) +* C-,: Agenda files. (line 18) +* C-c !: Creating timestamps. (line 21) +* C-c $: Archiving. (line 9) +* C-c %: Managing links. (line 61) +* C-c &: Managing links. (line 65) +* C-c ' <1>: Editing/debugging formulas. + (line 20) +* C-c ': Built-in table editor. + (line 145) +* C-c *: Built-in table editor. + (line 149) +* C-c +: Built-in table editor. + (line 166) +* C-c ,: Priorities. (line 18) +* C-c -: Built-in table editor. + (line 93) +* C-c .: Creating timestamps. (line 10) +* C-c /: Sparse trees. (line 15) +* C-c :: HTML export. (line 17) +* C-c ;: Comment lines. (line 12) +* C-c <: Creating timestamps. (line 25) +* C-c =: Built-in table editor. + (line 136) +* C-c >: Creating timestamps. (line 29) +* C-c ? <1>: Editing/debugging formulas. + (line 20) +* C-c ?: Built-in table editor. + (line 162) +* C-c [: Agenda files. (line 12) +* C-c \: Tags. (line 42) +* C-c ]: Agenda files. (line 15) +* C-c ^: Built-in table editor. + (line 97) +* C-c a a: Weekly/Daily Agenda. (line 9) +* C-c a C: Agenda dispatcher. (line 30) +* C-c a M: Matching headline tags. + (line 15) +* C-c a m: Matching headline tags. + (line 10) +* C-c a M: Tags. (line 49) +* C-c a m: Tags. (line 45) +* C-c a T: Global TODO list. (line 15) +* C-c a t <1>: Global TODO list. (line 9) +* C-c a t: TODO basics. (line 25) +* C-c C-a: Visibility cycling. (line 23) +* C-c C-b: Motion. (line 15) +* C-c C-c <1>: table.el. (line 6) +* C-c C-c <2>: Editing/debugging formulas. + (line 16) +* C-c C-c <3>: Built-in table editor. + (line 43) +* C-c C-c <4>: Plain Lists. (line 61) +* C-c C-c: Tags. (line 33) +* C-c C-d: Creating timestamps. (line 37) +* C-c C-f: Motion. (line 12) +* C-c C-j: Motion. (line 21) +* C-c C-l: Managing links. (line 23) +* C-c C-n: Motion. (line 8) +* C-c C-o <1>: Creating timestamps. (line 33) +* C-c C-o: Managing links. (line 35) +* C-c C-p: Motion. (line 9) +* C-c C-q <1>: Editing/debugging formulas. + (line 20) +* C-c C-q: Built-in table editor. + (line 120) +* C-c C-r: Timeline. (line 13) +* C-c C-s: Creating timestamps. (line 47) +* C-c C-t: TODO basics. (line 13) +* C-c C-u: Motion. (line 18) +* C-c C-v: TODO basics. (line 18) +* C-c C-w: Creating timestamps. (line 38) +* C-c C-x a: ASCII export. (line 6) +* C-c C-x b: HTML export. (line 11) +* C-c C-x c: iCalendar export. (line 20) +* C-c C-x C-c: Agenda commands. (line 176) +* C-c C-x C-i: iCalendar export. (line 15) +* C-c C-x C-k: Structure editing. (line 31) +* C-c C-x C-w <1>: Built-in table editor. + (line 109) +* C-c C-x C-w: Structure editing. (line 31) +* C-c C-x C-y <1>: Built-in table editor. + (line 113) +* C-c C-x C-y: Structure editing. (line 38) +* C-c C-x h: HTML export. (line 10) +* C-c C-x i: iCalendar export. (line 13) +* C-c C-x M-w <1>: Built-in table editor. + (line 106) +* C-c C-x M-w: Structure editing. (line 35) +* C-c C-x t: HTML export. (line 14) +* C-c C-x v: Sparse trees. (line 37) +* C-c C-y: Creating timestamps. (line 63) +* C-c l: Managing links. (line 9) +* C-c |: Built-in table editor. + (line 182) +* C-c ~: table.el. (line 18) +* C-u C-c .: Creating timestamps. (line 16) +* C-u C-c =: Built-in table editor. + (line 140) +* D: Agenda commands. (line 66) +* d: Agenda commands. (line 63) +* f: Agenda commands. (line 44) +* g: Agenda commands. (line 70) +* H: Agenda commands. (line 173) +* i: Agenda commands. (line 145) +* l: Agenda commands. (line 49) +* L: Agenda commands. (line 32) +* M: Agenda commands. (line 161) +* M-: Built-in table editor. + (line 83) +* M- <1>: Built-in table editor. + (line 73) +* M-: Structure editing. (line 13) +* M- <1>: Plain Lists. (line 42) +* M-: Structure editing. (line 6) +* M- <1>: Built-in table editor. + (line 73) +* M-: Structure editing. (line 16) +* M- <1>: Completion. (line 10) +* M- <2>: Per file keywords. (line 17) +* M-: Tags. (line 28) +* M-: Built-in table editor. + (line 83) +* M-S- <1>: Built-in table editor. + (line 90) +* M-S- <2>: Plain Lists. (line 46) +* M-S-: Structure editing. (line 28) +* M-S- <1>: Creating timestamps. (line 97) +* M-S- <2>: Built-in table editor. + (line 77) +* M-S- <3>: Plain Lists. (line 52) +* M-S-: Structure editing. (line 19) +* M-S-: Structure editing. (line 10) +* M-S- <1>: Creating timestamps. (line 94) +* M-S- <2>: Built-in table editor. + (line 80) +* M-S- <3>: Plain Lists. (line 52) +* M-S-: Structure editing. (line 22) +* M-S- <1>: Built-in table editor. + (line 87) +* M-S- <2>: Plain Lists. (line 46) +* M-S-: Structure editing. (line 25) +* mouse-1 <1>: Agenda commands. (line 35) +* mouse-1 <2>: Creating timestamps. (line 79) +* mouse-1: Managing links. (line 53) +* mouse-2 <1>: Agenda commands. (line 35) +* mouse-2: Managing links. (line 53) +* mouse-3 <1>: Agenda commands. (line 28) +* mouse-3: Managing links. (line 58) +* n: Agenda commands. (line 19) +* o: Agenda commands. (line 57) +* P: Agenda commands. (line 115) +* p: Agenda commands. (line 20) +* q: Agenda commands. (line 183) +* r <1>: Agenda commands. (line 74) +* r: Global TODO list. (line 21) +* S: Agenda commands. (line 164) +* S- <1>: Agenda commands. (line 124) +* S- <2>: Creating timestamps. (line 55) +* S-: Priorities. (line 25) +* S- <1>: Agenda commands. (line 136) +* S-: Creating timestamps. (line 50) +* S-: Built-in table editor. + (line 171) +* S- <1>: Agenda commands. (line 128) +* S-: Creating timestamps. (line 50) +* S- <1>: Built-in table editor. + (line 62) +* S-: Visibility cycling. (line 17) +* S- <1>: Agenda commands. (line 118) +* S- <2>: Creating timestamps. (line 55) +* S-: Priorities. (line 25) +* T: Agenda commands. (line 102) +* t: Agenda commands. (line 98) +* w: Agenda commands. (line 60) +* x: Agenda commands. (line 186) + + + +Tag Table: +Node: Top959 +Node: Introduction6836 +Node: Summary7150 +Node: Installation and Activation9261 +Node: Feedback10931 +Node: Document Structure11705 +Node: Outlines12547 +Node: Headlines13207 +Node: Visibility cycling13832 +Node: Motion15019 +Node: Structure editing15803 +Node: Archiving17534 +Node: Sparse trees18394 +Ref: Sparse trees-Footnote-120416 +Ref: Sparse trees-Footnote-220508 +Node: Tags20622 +Node: Plain Lists23713 +Ref: Plain Lists-Footnote-126454 +Node: Tables26811 +Node: Built-in table editor27298 +Node: Table calculations34833 +Node: Formula syntax36016 +Ref: Formula syntax-Footnote-138940 +Node: Column formulas39239 +Node: Advanced features41001 +Node: Named-field formulas44262 +Node: Editing/debugging formulas44902 +Node: Appetizer46679 +Node: orgtbl-mode47781 +Node: table.el48271 +Node: Hyperlinks49248 +Node: Internal Links49814 +Node: Radio targets51563 +Node: CamelCase links52278 +Node: External Links52851 +Ref: External Links-Footnote-154777 +Node: Managing links54916 +Node: Search Options58247 +Ref: Search Options-Footnote-159560 +Node: Remember59641 +Ref: Remember-Footnote-163525 +Node: TODO items63649 +Node: TODO basics64572 +Node: Progress Logging66084 +Node: TODO extensions66871 +Node: Workflow states67559 +Node: TODO types68426 +Ref: TODO types-Footnote-170092 +Node: Per file keywords70174 +Ref: Per file keywords-Footnote-171627 +Node: Priorities71855 +Node: Timestamps73064 +Node: Time stamps73393 +Node: Creating timestamps75404 +Node: Agenda Views78536 +Node: Agenda files80063 +Ref: Agenda files-Footnote-180987 +Node: Agenda dispatcher81179 +Node: Weekly/Daily Agenda83305 +Node: Categories84432 +Node: Time-of-day specifications84997 +Node: Calendar/Diary integration86973 +Node: Sorting of agenda items88349 +Node: Global TODO list89181 +Node: Matching headline tags90593 +Node: Timeline91536 +Node: Agenda commands92409 +Node: Exporting97650 +Node: ASCII export98222 +Node: HTML export99057 +Node: HTML formatting100173 +Node: Export options101805 +Node: Comment lines103997 +Node: iCalendar export104467 +Node: Miscellaneous106262 +Node: Completion106887 +Node: Customization107881 +Node: Clean view108327 +Node: TTY keys110974 +Node: FAQ112573 +Node: Interaction117456 +Node: Bugs120856 +Node: Acknowledgments122598 +Node: Index125018 +Node: Key Index145222 + +End Tag Table diff --git a/org.el b/org.el new file mode 100644 index 000000000..3aba8c55f --- /dev/null +++ b/org.el @@ -0,0 +1,13032 @@ +;;; org.el --- Outline-based notes management and organize +;; Carstens outline-mode for keeping track of everything. +;; Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. +;; +;; Author: Carsten Dominik +;; Keywords: outlines, hypermedia, calendar, wp +;; Homepage: http://www.astro.uva.nl/~dominik/Tools/org/ +;; Version: 4.12 +;; +;; 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 2, 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; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Org-mode is a mode for keeping notes, maintaining ToDo lists, and doing +;; project planning with a fast and effective plain-text system. +;; +;; Org-mode develops organizational tasks around a NOTES file that contains +;; information about projects as plain text. Org-mode is implemented on top +;; of outline-mode - ideal to keep the content of large files well structured. +;; It supports ToDo items, deadlines and time stamps, which can be extracted +;; to create a daily/weekly agenda that also integrates the diary of the Emacs +;; calendar. Tables are easily created with a built-in table editor. Plain +;; text URL-like links connect to websites, emails (VM, RMAIL, WANDERLUST), +;; Usenet messages (Gnus), BBDB entries, and any files related to the +;; projects. For printing and sharing of notes, an Org-mode file (or a part +;; of it) can be exported as a structured ASCII file, or as HTML. +;; +;; Installation +;; ------------ +;; If Org-mode is part of the Emacs distribution or an XEmacs package, you +;; only need to copy the following lines to your .emacs file. The last two +;; lines define *global* keys for the commands `org-store-link' and +;; `org-agenda' - please choose suitable keys yourself. +;; +;; (add-to-list 'auto-mode-alist '("\\.org$" . org-mode)) +;; (define-key global-map "\C-cl" 'org-store-link) +;; (define-key global-map "\C-ca" 'org-agenda) +;; +;; If you have downloaded Org-mode from the Web, you must byte-compile +;; org.el and put it on your load path. In addition to the Emacs Lisp +;; lines above, you also need to add the following lines to .emacs: +;; +;; (autoload 'org-mode "org" "Org mode" t) +;; (autoload 'org-diary "org" "Diary entries from Org mode") +;; (autoload 'org-agenda "org" "Multi-file agenda from Org mode" t) +;; (autoload 'org-store-link "org" "Store a link to the current location" t) +;; (autoload 'orgtbl-mode "org" "Org tables as a minor mode" t) +;; (autoload 'turn-on-orgtbl "org" "Org tables as a minor mode") +;; +;; This setup will put all files with extension ".org" into Org-mode. As +;; an alternative, make the first line of a file look like this: +;; +;; MY PROJECTS -*- mode: org; -*- +;; +;; which will select Org-mode for this buffer no matter what the file's +;; name is. +;; +;; Documentation +;; ------------- +;; The documentation of Org-mode can be found in the TeXInfo file. The +;; distribution also contains a PDF version of it. At the homepage of +;; Org-mode, you can read the same text online as HTML. There is also an +;; excellent reference card made by Philip Rooke. This card can be found +;; in the etc/ directory of Emacs 22. +;; +;; Changes since version 4.00: +;; --------------------------- +;; Version 4.12 +;; - Templates for remember buffer. Note that the remember setup changes. +;; To set up templates, see `org-remember-templates'. +;; - The time in new time stamps can be rounded, see new option +;; `org-time-stamp-rounding-minutes'. +;; - Bug fixes (there are *always* more bugs). +;; +;; Version 4.10 +;; - Bug fixes. +;; +;; Version 4.09 +;; - Bug fixes. +;; - Small improvements to font-lock support. +;; - MHE support finalized. +;; +;; Version 4.08 +;; - Bug fixes. +;; - Improved MHE support +;; +;; Version 4.07 +;; - Bug fixes. +;; - Leading stars in headlines can be hidden, so make the outline look +;; cleaner. +;; - Mouse-1 can be used to follow links. +;; +;; Version 4.06 +;; - HTML exporter treats targeted internal links. +;; - Bug fixes. +;; +;; Version 4.05 +;; - Changes to internal link system (thanks to David Wainberg for ideas). +;; - in-file links: [[Search String]] instead of +;; - automatic links to "radio targets". +;; - CamelCase not longer active by default, configure org-activate-camels +;; if you want to turn it back on. +;; - After following a link, `C-c &' jumps back to it. +;; - MH-E link support (thanks to Thomas Baumann). +;; - Special table lines are no longer exported. +;; - Bug fixes and minor improvements. +;; +;; Version 4.04 +;; - Cleanup tags display in agenda. +;; - Bug fixes. +;; +;; Version 4.03 +;; - Table alignment fixed for use with wide characters. +;; - `C-c -' leaves cursor in current table line. +;; - The current TAG can be incorporated into the agenda prefix. +;; See option `org-agenda-prefix-format' for details. +;; +;; Version 4.02 +;; - Minor bug fixes and improvements around tag searches. +;; - XEmacs compatibility fixes. +;; +;; Version 4.01 +;; - Tags can also be set remotely from agenda buffer. +;; - Boolean logic for tag searches. +;; - Additional agenda commands can be configured through the variable +;; `org-agenda-custom-commands'. +;; - Minor bug fixes. +;; +;;; Code: + +(eval-when-compile (require 'cl) (require 'calendar)) +(require 'outline) +(require 'time-date) +(require 'easymenu) + +(defvar calc-embedded-close-formula) ; defined by the calc package +(defvar calc-embedded-open-formula) ; defined by the calc package +(defvar font-lock-unfontify-region-function) ; defined by font-lock.el + +;;; Customization variables + +(defvar org-version "4.12" + "The version number of the file org.el.") +(defun org-version () + (interactive) + (message "Org-mode version %s" org-version)) + +;; The following two constants are for compatibility with different Emacs +;; versions (Emacs versus XEmacs) and with different versions of outline.el. +;; The compatibility code in org.el is based on these two constants. +(defconst org-xemacs-p (featurep 'xemacs) + "Are we running XEmacs?") +(defconst org-noutline-p (featurep 'noutline) + "Are we using the new outline mode?") + +(defgroup org nil + "Outline-based notes management and organizer." + :tag "Org" + :group 'outlines + :group 'hypermedia + :group 'calendar) + +(defgroup org-startup nil + "Options concerning startup of Org-mode." + :tag "Org Startup" + :group 'org) + +(defcustom org-CUA-compatible nil + "Non-nil means use alternative key bindings for S-. +Org-mode used S- for changing timestamps and priorities. +S- is also used for example by `CUA-mode' to select text. +If you want to use Org-mode together with `CUA-mode', Org-mode needs to use +alternative bindings. Setting this variable to t will replace the following +keys both in Org-mode and in the Org-agenda buffer. + +S-RET -> C-S-RET +S-up -> M-p +S-down -> M-n +S-left -> M-- +S-right -> M-+ + +If you do not like the alternative keys, take a look at the variable +`org-disputed-keys'. + +This option is only relevant at load-time of Org-mode. Changing it requires +a restart of Emacs to become effective." + :group 'org-startup + :type 'boolean) + +(defvar org-disputed-keys + '((S-up [(shift up)] [(meta ?p)]) + (S-down [(shift down)] [(meta ?n)]) + (S-left [(shift left)] [(meta ?-)]) + (S-right [(shift right)] [(meta ?+)]) + (S-return [(shift return)] [(control shift return)])) + "Keys for which Org-mode and other modes compete. +This is an alist, cars are symbols for lookup, 1st element is the default key, +second element will be used when `org-CUA-compatible' is t.") + +(defun org-key (key) + "Select a key according to `org-CUA-compatible'." + (nth (if org-CUA-compatible 2 1) + (or (assq key org-disputed-keys) + (error "Invalid Key %s in `org-key'" key)))) + +(defcustom org-startup-folded t + "Non-nil means, entering Org-mode will switch to OVERVIEW. +This can also be configured on a per-file basis by adding one of +the following lines anywhere in the buffer: + + #+STARTUP: fold + #+STARTUP: nofold + #+STARTUP: content" + :group 'org-startup + :type '(choice + (const :tag "nofold: show all" nil) + (const :tag "fold: overview" t) + (const :tag "content: all headlines" content))) + +(defcustom org-startup-truncated t + "Non-nil means, entering Org-mode will set `truncate-lines'. +This is useful since some lines containing links can be very long and +uninteresting. Also tables look terrible when wrapped." + :group 'org-startup + :type 'boolean) + +(defcustom org-startup-with-deadline-check nil + "Non-nil means, entering Org-mode will run the deadline check. +This means, if you start editing an org file, you will get an +immediate reminder of any due deadlines. +This can also be configured on a per-file basis by adding one of +the following lines anywhere in the buffer: + + #+STARTUP: dlcheck + #+STARTUP: nodlcheck" + :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 +normally means that the file name does not automatically trigger Org-mode. +To ensure that the file will always be in Org-mode in the future, a +line enforcing Org-mode will be inserted into the buffer, if this option +has been set." + :group 'org-startup + :type 'boolean) + +(defgroup org-keywords nil + "Options concerning TODO items in Org-mode." + :tag "Org Keywords" + :group 'org) + +(defcustom org-todo-keywords '("TODO" "DONE") + "List of TODO entry keywords. +\\By default, this is '(\"TODO\" \"DONE\"). The last entry in the list is +considered to mean that the entry is \"done\". All the other mean that +action is required, and will make the entry show up in todo lists, diaries +etc. +The command \\[org-todo] cycles an entry through these states, and an +additional state where no keyword is present. For details about this +cycling, see also the variable `org-todo-interpretation' +Changes become only effective after restarting Emacs." + :group 'org-keywords + :type '(repeat (string :tag "Keyword"))) + +(defcustom org-todo-interpretation 'sequence + "Controls how TODO keywords are interpreted. +\\Possible values are `sequence' and `type'. +This variable is only relevant if `org-todo-keywords' contains more than two +states. There are two ways how these keywords can be used: + +- As a sequence in the process of working on a TODO item, for example + (setq org-todo-keywords '(\"TODO\" \"STARTED\" \"VERIFY\" \"DONE\") + org-todo-interpretation 'sequence) + +- As different types of TODO items, for example + (setq org-todo-keywords '(\"URGENT\" \"RELAXED\" \"REMIND\" \"FOR_TOM\" \"DONE\") + org-todo-interpretation 'type) + +When the states are interpreted as a sequence, \\[org-todo] always cycles +to the next state, in order to walk through all different states. So with +\\[org-todo], you turn an empty entry into the state TODO. When you started +working on the item, you use \\[org-todo] again to switch it to \"STARTED\", +later to VERIFY and finally to DONE. + +When the states are interpreted as types, \\[org-todo] still cycles through +when it is called several times in direct succession, in order to initially +select the type. However, if not called immediately after a previous +\\[org-todo], it switches from each type directly to DONE. So with the +above example, you could use `\\[org-todo] \\[org-todo]' to label an entry +RELAXED. If you later return to this entry and press \\[org-todo] again, +RELAXED will not be changed REMIND, but directly to DONE. + +You can create a large number of types. To initially select a +type, it is then best to use \\[universal-argument] \\[org-todo] in order to specify the +type with completion. Of course, you can also type the keyword +directly into the buffer. M-TAB completes TODO keywords at the +beginning of a headline." + :group 'org-keywords + :type '(choice (const sequence) + (const type))) + +(defcustom org-default-priority ?B + "The default priority of TODO items. +This is the priority an item get if no explicit priority is given." + :group 'org-keywords + :type 'character) + +(defcustom org-lowest-priority ?C + "The lowest priority of TODO items. A character like ?A, ?B etc." + :group 'org-keywords + :type 'character) + +(defcustom org-deadline-string "DEADLINE:" + "String to mark deadline entries. +A deadline is this string, followed by a time stamp. Should be a word, +terminated by a colon. You can insert a schedule keyword and +a timestamp with \\[org-deadline]. +Changes become only effective after restarting Emacs." + :group 'org-keywords + :type 'string) + +(defcustom org-scheduled-string "SCHEDULED:" + "String to mark scheduled TODO entries. +A schedule is this string, followed by a time stamp. Should be a word, +terminated by a colon. You can insert a schedule keyword and +a timestamp with \\[org-schedule]. +Changes become only effective after restarting Emacs." + :group 'org-keywords + :type 'string) + +(defcustom org-closed-string "CLOSED:" + "String used as the prefix for timestamps logging closing a TODO entry." + :group 'org-keywords + :type 'string) + +(defcustom org-comment-string "COMMENT" + "Entries starting with this keyword will never be exported. +An entry can be toggled between COMMENT and normal with +\\[org-toggle-comment]. +Changes become only effective after restarting Emacs." + :group 'org-keywords + :type 'string) + +(defcustom org-quote-string "QUOTE" + "Entries starting with this keyword will be exported in fixed-width font. +Quoting applies only to the text in the entry following the headline, and does +not extend beyond the next headline, even if that is lower level. +An entry can be toggled between QUOTE and normal with +\\[org-toggle-fixed-width-section]." + :group 'org-keywords + :type 'string) + +(defcustom org-after-todo-state-change-hook nil + "Hook which is run after the state of a TODO item was changed. +The new state (a string with a TODO keyword, or nil) is available in the +Lisp variable `state'." + :group 'org-keywords + :type 'hook) + +;; Variables for pre-computed regular expressions, all buffer local +(defvar org-todo-kwd-priority-p nil + "Do TODO items have priorities?") +(make-variable-buffer-local 'org-todo-kwd-priority-p) +(defvar org-todo-kwd-max-priority nil + "Maximum priority of TODO items.") +(make-variable-buffer-local 'org-todo-kwd-max-priority) +(defvar org-ds-keyword-length 12 + "Maximum length of the Deadline and SCHEDULED keywords.") +(make-variable-buffer-local 'org-ds-keyword-length) +(defvar org-done-string nil + "The last string in `org-todo-keywords', indicating an item is DONE.") +(make-variable-buffer-local 'org-done-string) +(defvar org-todo-regexp nil + "Matches any of the TODO state keywords.") +(make-variable-buffer-local 'org-todo-regexp) +(defvar org-not-done-regexp nil + "Matches any of the TODO state keywords except the last one.") +(make-variable-buffer-local 'org-not-done-regexp) +(defvar org-todo-line-regexp nil + "Matches a headline and puts TODO state into group 2 if present.") +(make-variable-buffer-local 'org-todo-line-regexp) +(defvar org-nl-done-regexp nil + "Matches newline followed by a headline with the DONE keyword.") +(make-variable-buffer-local 'org-nl-done-regexp) +(defvar org-looking-at-done-regexp nil + "Matches the DONE keyword a point.") +(make-variable-buffer-local 'org-looking-at-done-regexp) +(defvar org-deadline-regexp nil + "Matches the DEADLINE keyword.") +(make-variable-buffer-local 'org-deadline-regexp) +(defvar org-deadline-time-regexp nil + "Matches the DEADLINE keyword together with a time stamp.") +(make-variable-buffer-local 'org-deadline-time-regexp) +(defvar org-deadline-line-regexp nil + "Matches the DEADLINE keyword and the rest of the line.") +(make-variable-buffer-local 'org-deadline-line-regexp) +(defvar org-scheduled-regexp nil + "Matches the SCHEDULED keyword.") +(make-variable-buffer-local 'org-scheduled-regexp) +(defvar org-scheduled-time-regexp nil + "Matches the SCHEDULED keyword together with a time stamp.") +(make-variable-buffer-local 'org-scheduled-time-regexp) + +(defvar org-category nil + "Variable used by org files to set a category for agenda display. +Such files should use a file variable to set it, for example + + -*- mode: org; org-category: \"ELisp\" + +or contain a special line + +#+CATEGORY: ELisp + +If the file does not specify a category, then file's base name +is used instead.") +(make-variable-buffer-local 'org-category) + +(defgroup org-time nil + "Options concerning time stamps and deadlines in Org-mode." + :tag "Org Time" + :group 'org) + +(defconst org-time-stamp-formats '("<%Y-%m-%d %a>" . "<%Y-%m-%d %a %H:%M>") + "Formats for `format-time-string' which are used for time stamps. +It is not recommended to change this constant.") + +(defcustom org-time-stamp-rounding-minutes 0 + "Number of minutes to round time stamps to upon insertion. +When zero, insert the time unmodified. Useful rounding numbers +should be factors of 60, so for example 5, 10, 15. +When this is not zero, you can still force an exact time-stamp by using +a double prefix argument to a time-stamp command like `C-c .' or `C-c !'." + :group 'org-time + :type 'integer) + +(defcustom org-deadline-warning-days 30 + "No. of days before expiration during which a deadline becomes active. +This variable governs the display in the org file." + :group 'org-time + :type 'number) + +(defcustom org-popup-calendar-for-date-prompt t + "Non-nil means, pop up a calendar when prompting for a date. +In the calendar, the date can be selected with mouse-1. However, the +minibuffer will also be active, and you can simply enter the date as well. +When nil, only the minibuffer will be available." + :group 'org-time + :type 'boolean) + +(defcustom org-calendar-follow-timestamp-change t + "Non-nil means, make the calendar window follow timestamp changes. +When a timestamp is modified and the calendar window is visible, it will be +moved to the new date." + :group 'org-time + :type 'boolean) + +(defcustom org-log-done nil + "When set, insert a (non-active) time stamp when TODO entry is marked DONE. +When the state of an entry is changed from nothing to TODO, remove a previous +closing date." + :group 'org-time + :type 'boolean) + +(defgroup org-agenda nil + "Options concerning agenda display Org-mode." + :tag "Org Agenda" + :group 'org) + +(defcustom org-agenda-files nil + "A list of org files for agenda/diary display. +Entries are added to this list with \\[org-agenda-file-to-front] and removed with +\\[org-remove-file]. You can also use customize to edit the list." + :group 'org-agenda + :type '(repeat file)) + +(defcustom org-agenda-custom-commands '(("w" todo "WAITING")) + "Custom commands for the agenda. +These commands will be offered on the splash screen displayed by the +agenda dispatcher \\[org-agenda]. Each entry is a list of 3 items: + +key The key (a single char as a string) to be associated with the command. +type The command type, any of the following symbols: + todo Entries with a specific TODO keyword, in all agenda files. + tags Tags match in all agenda files. + todo-tree Sparse tree of specific TODO keyword in *current* file. + tags-tree Sparse tree with all tags matches in *current* file. + occur-tree Occur sparse tree for current file. +match What to search for: + - a single keyword for TODO keyword searches + - a tags match expression for tags searches + - a regular expression for occur searches" + :group 'org-agenda + :type '(repeat + (list (string :tag "Key") + (choice :tag "Type" + (const :tag "Tags search in all agenda files" tags) + (const :tag "TODO keyword search in all agenda files" todo) + (const :tag "Tags sparse tree in current buffer" tags-tree) + (const :tag "TODO keyword tree in current buffer" todo-tree) + (const :tag "Occur tree in current buffer" occur-tree)) + (string :tag "Match")))) + +(defcustom org-select-timeline-window t + "Non-nil means, after creating a timeline, move cursor into Timeline window. +When nil, cursor will remain in the current window." + :group 'org-agenda + :type 'boolean) + +(defcustom org-select-agenda-window t + "Non-nil means, after creating an agenda, move cursor into Agenda window. +When nil, cursor will remain in the current window." + :group 'org-agenda + :type 'boolean) + +(defcustom org-fit-agenda-window t + "Non-nil means, change window size of agenda to fit content." + :group 'org-agenda + :type 'boolean) + +(defcustom org-agenda-show-all-dates t + "Non-nil means, `org-agenda' shows every day in the selected range. +When nil, only the days which actually have entries are shown." + :group 'org-agenda + :type 'boolean) + +;; FIXME: First day of month works only for current month because it would +;; require a variable ndays treatment. +(defcustom org-agenda-start-on-weekday 1 + "Non-nil means, start the overview always on the specified weekday. +0 Denotes Sunday, 1 denotes Monday etc. +When nil, always start on the current day." + :group 'org-agenda + :type '(choice (const :tag "Today" nil) + (const :tag "First day of month" t) + (number :tag "Weekday No."))) + +(defcustom org-agenda-ndays 7 + "Number of days to include in overview display." + :group 'org-agenda + :type 'number) + +(defcustom org-agenda-include-all-todo t + "Non-nil means, the agenda will always contain all TODO entries. +When nil, date-less entries will only be shown if `org-agenda' is called +with a prefix argument. +When non-nil, the TODO entries will be listed at the top of the agenda, before +the entries for specific days." + :group 'org-agenda + :type 'boolean) + +(defcustom org-agenda-include-diary nil + "If non-nil, include in the agenda entries from the Emacs Calendar's diary." + :group 'org-agenda + :type 'boolean) + +(defcustom org-calendar-to-agenda-key [?c] + "The key to be installed in `calendar-mode-map' for switching to the agenda. +The command `org-calendar-goto-agenda' will be bound to this key. The +default is the character `c' because then `c' can be used to switch back and +forth between agenda and calendar." + :group 'org-agenda + :type 'sexp) + +(defcustom org-agenda-sorting-strategy '(time-up category-keep priority-down) + "Sorting structure for the agenda items of a single day. +This is a list of symbols which will be used in sequence to determine +if an entry should be listed before another entry. The following +symbols are recognized: + +time-up Put entries with time-of-day indications first, early first +time-down Put entries with time-of-day indications first, late first +category-keep Keep the default order of categories, corresponding to the + sequence in `org-agenda-files'. +category-up Sort alphabetically by category, A-Z. +category-down Sort alphabetically by category, Z-A. +priority-up Sort numerically by priority, high priority last. +priority-down Sort numerically by priority, high priority first. + +The different possibilities will be tried in sequence, and testing stops +if one comparison returns a \"not-equal\". For example, the default + '(time-up category-keep priority-down) +means: Pull out all entries having a specified time of day and sort them, +in order to make a time schedule for the current day the first thing in the +agenda listing for the day. Of the entries without a time indication, keep +the grouped in categories, don't sort the categories, but keep them in +the sequence given in `org-agenda-files'. Within each category sort by +priority. + +Leaving out `category-keep' would mean that items will be sorted across +categories by priority." + :group 'org-agenda + :type '(repeat + (choice + (const time-up) + (const time-down) + (const category-keep) + (const category-up) + (const category-down) + (const priority-up) + (const priority-down)))) + +(defcustom org-agenda-prefix-format " %-12:c%?-12t% s" + "Format specification for the prefix of items in the agenda buffer. +This format works similar to a printf format, with the following meaning: + + %c the category of the item, \"Diary\" for entries from the diary, or + as given by the CATEGORY keyword or derived from the file name. + %T the first tag of the item. + %t the time-of-day specification if one applies to the entry, in the + format HH:MM + %s Scheduling/Deadline information, a short string + +All specifiers work basically like the standard `%s' of printf, but may +contain two additional characters: A question mark just after the `%' and +a whitespace/punctuation character just before the final letter. + +If the first character after `%' is a question mark, the entire field +will only be included if the corresponding value applies to the +current entry. This is useful for fields which should have fixed +width when present, but zero width when absent. For example, +\"%?-12t\" will result in a 12 character time field if a time of the +day is specified, but will completely disappear in entries which do +not contain a time. + +If there is punctuation or whitespace character just before the final +format letter, this character will be appended to the field value if +the value is not empty. For example, the format \"%-12:c\" leads to +\"Diary: \" if the category is \"Diary\". If the category were be +empty, no additional colon would be interted. + +The default value of this option is \" %-12:c%?-12t% s\", meaning: +- Indent the line with two space characters +- Give the category in a 12 chars wide field, padded with whitespace on + the right (because of `-'). Append a colon if there is a category + (because of `:'). +- If there is a time-of-day, put it into a 12 chars wide field. If no + time, don't put in an empty field, just skip it (because of '?'). +- Finally, put the scheduling information and append a whitespace. + +As another example, if you don't want the time-of-day of entries in +the prefix, you could use: + + (setq org-agenda-prefix-format \" %-11:c% s\") + +See also the variables `org-agenda-remove-times-when-in-prefix' and +`org-agenda-remove-tags-when-in-prefix'." + :type 'string + :group 'org-agenda) + +(defcustom org-timeline-prefix-format " % s" + "Like `org-agenda-prefix-format', but for the timeline of a single file." + :type 'string + :group 'org-agenda) + +(defvar org-prefix-format-compiled nil + "The compiled version of the most recently used prefix format. +Depending on which command was used last, this may be the compiled version +of `org-agenda-prefix-format' or `org-timeline-prefix-format'.") + +(defcustom org-agenda-use-time-grid t + "Non-nil means, show a time grid in the agenda schedule. +A time grid is a set of lines for specific times (like every two hours between +8:00 and 20:00). The items scheduled for a day at specific times are +sorted in between these lines. +For details about when the grid will be shown, and what it will look like, see +the variable `org-agenda-time-grid'." + :group 'org-agenda + :type 'boolean) + +(defcustom org-agenda-time-grid + '((daily today require-timed) + "----------------" + (800 1000 1200 1400 1600 1800 2000)) + + "The settings for time grid for agenda display. +This is a list of three items. The first item is again a list. It contains +symbols specifying conditions when the grid should be displayed: + + daily if the agenda shows a single day + weekly if the agenda shows an entire week + today show grid on current date, independent of daily/weekly display + require-timed show grid only if at least on item has a time specification + +The second item is a string which will be places behing the grid time. + +The third item is a list of integers, indicating the times that should have +a grid line." + :group 'org-agenda + :type + '(list + (set :greedy t :tag "Grid Display Options" + (const :tag "Show grid in single day agenda display" daily) + (const :tag "Show grid in weekly agenda display" weekly) + (const :tag "Always show grid for today" today) + (const :tag "Show grid only if any timed entries are present" + require-timed) + (const :tag "Skip grid times already present in an entry" + remove-match)) + (string :tag "Grid String") + (repeat :tag "Grid Times" (integer :tag "Time")))) + +(defcustom org-agenda-remove-times-when-in-prefix t + "Non-nil means, remove duplicate time specifications in agenda items. +When the format `org-agenda-prefix-format' contains a `%t' specifier, a +time-of-day specification in a headline or diary entry is extracted and +placed into the prefix. If this option is non-nil, the original specification +\(a timestamp or -range, or just a plain time(range) specification like +11:30-4pm) will be removed for agenda display. This makes the agenda less +cluttered. +The option can be t or nil. It may also be the symbol `beg', indicating +that the time should only be removed what it is located at the beginning of +the headline/diary entry." + :group 'org-agenda + :type '(choice + (const :tag "Always" t) + (const :tag "Never" nil) + (const :tag "When at beginning of entry" beg))) + +(defcustom org-sort-agenda-notime-is-late t + "Non-nil means, items without time are considered late. +This is only relevant for sorting. When t, items which have no explicit +time like 15:30 will be considered as 24:01, i.e. later than any items which +do have a time. When nil, the default time is before 0:00. You can use this +option to decide if the schedule for today should come before or after timeless +agenda entries." + :group 'org-agenda + :type 'boolean) + +(defcustom org-agenda-remove-tags-when-in-prefix nil + "Non-nil means, the tags from copy of headline in agenda. +When this is the symbol `prefix', only remove tags when +`org-agenda-prefix-format' contains a `%T' specifier." + :group 'org-agenda + :type '(choice + (const :tag "Always" t) + (const :tag "Never" nil) + (const :tag "When prefix format contains %T" prefix))) + +(defgroup org-structure nil + "Options concerning structure editing in Org-mode." + :tag "Org Structure" + :group 'org) + +(defcustom org-cycle-include-plain-lists nil + "Non-nil means, include plain lists into visibility cycling. +This means that during cycling, plain list items will *temporarily* be +interpreted as outline headlines with a level given by 1000+i where i is the +indentation of the bullet. In all other operations, plain list items are +not seen as headlines. For example, you cannot assign a TODO keyword to +such an item." + :group 'org-structure + :type 'boolean) + +(defcustom org-cycle-emulate-tab t + "Where should `org-cycle' emulate TAB. +nil Never +white Only in completely white lines +t Everywhere except in headlines" + :group 'org-structure + :type '(choice (const :tag "Never" nil) + (const :tag "Only in completely white lines" white) + (const :tag "Everywhere except in headlines" t) + )) + +(defcustom org-cycle-hook '(org-optimize-window-after-visibility-change) + "Hook that is run after `org-cycle' has changed the buffer visibility. +The function(s) in this hook must accept a single argument which indicates +the new state that was set by the most recent `org-cycle' command. The +argument is a symbol. After a global state change, it can have the values +`overview', `content', or `all'. After a local state change, it can have +the values `folded', `children', or `subtree'." + :group 'org-structure + :type 'hook) + +(defcustom org-highlight-sparse-tree-matches t + "Non-nil means, highlight all matches that define a sparse tree. +The highlights will automatically disappear the next time the buffer is +changed by an edit command." + :group 'org-structure + :type 'boolean) + +(defcustom org-show-hierarchy-above t + "Non-nil means, show full hierarchy when showing a spot in the tree. +Turning this off makes sparse trees more compact, but also less clear." + :group 'org-structure + :type 'boolean) + +(defcustom org-show-following-heading t + "Non-nil means, show heading following match in `org-occur'. +When doing an `org-occur' it is useful to show the headline which +follows the match, even if they do not match the regexp. This makes it +easier to edit directly inside the sparse tree. However, if you use +`org-occur' mainly as an overview, the following headlines are +unnecessary clutter." + :group 'org-structure + :type 'boolean) + +(defcustom org-occur-hook '(org-first-headline-recenter) + "Hook that is run after `org-occur' has constructed a sparse tree. +This can be used to recenter the window to show as much of the structure +as possible." + :group 'org-structure + :type 'hook) + +(defcustom org-odd-levels-only nil + "Non-nil means, skip even levels and only use odd levels for the outline. +This has the effect that two stars are being added/taken away in +promotion/demotion commands. It also influences how levels are +handled by the exporters. +Changing it requires restart of `font-lock-mode' to become effective +for fontification also in regions already fontified." + :group 'org-structure + :group 'org-font-lock + :type 'boolean) + +(defcustom org-adapt-indentation t + "Non-nil means, adapt indentation when promoting and demoting. +When this is set and the *entire* text in an entry is indented, the +indentation is increased by one space in a demotion command, and +decreased by one in a promotion command. If any line in the entry +body starts at column 0, indentation is not changed at all." + :group 'org-structure + :type 'boolean) + +(defcustom org-plain-list-ordered-item-terminator t + "The character that makes a line with leading number an ordered list item. +Valid values are ?. and ?\). To get both terminators, use t. While +?. may look nicer, it creates the danger that a line with leading +number may be incorrectly interpreted as an item. ?\) therefore is +the safe choice." + :group 'org-structure + :type '(choice (const :tag "dot like in \"2.\"" ?.) + (const :tag "paren like in \"2)\"" ?\)) + (const :tab "both" t))) + +(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." + :group 'org-structure + :type 'boolean) + +(defcustom org-enable-fixed-width-editor t + "Non-nil means, lines starting with \":\" are treated as fixed-width. +This currently only means, they are never auto-wrapped. +When nil, such lines will be treated like ordinary lines. +See also the QUOTE keyword." + :group 'org-structure + :type 'boolean) + +(defcustom org-archive-location "%s_archive::" + "The location where subtrees should be archived. +This string consists of two parts, separated by a double-colon. + +The first part is a file name - when omitted, archiving happens in the same +file. %s will be replaced by the current file name (without directory part). +Archiving to a different file is useful to keep archived entries from +contributing to the Org-mode Agenda. + +The part after the double colon is a headline. The archived entries will be +filed under that headline. When omitted, the subtrees are simply filed away +at the end of the file, as top-level entries. + +Here are a few examples: +\"%s_archive::\" + If the current file is Projects.org, archive in file + Projects.org_archive, as top-level trees. This is the default. + +\"::* Archived Tasks\" + Archive in the current file, under the top-level headline + \"* Archived Tasks\". + +\"~/org/archive.org::\" + Archive in file ~/org/archive.org (absolute path), as top-level trees. + +\"basement::** Finished Tasks\" + Archive in file ./basement (relative path), as level 3 trees + below the level 2 heading \"** Finished Tasks\". + +You may set this option on a per-file basis by adding to the buffer a +line like + +#+ARCHIVE: basement::** Finished Tasks" + :group 'org-structure + :type 'string) + +(defcustom org-archive-mark-done t + "Non-nil means, mark archived entries as DONE." + :group 'org-structure + :type 'boolean) + +(defcustom org-archive-stamp-time t + "Non-nil means, add a time stamp to archived entries. +The time stamp will be added directly after the TODO state keyword in the +first line, so it is probably best to use this in combinations with +`org-archive-mark-done'." + :group 'org-structure + :type 'boolean) + +(defgroup org-tags nil + "Options concerning startup of Org-mode." + :tag "Org Tags" + :group 'org) + +(defcustom org-tags-column 48 + "The column to which tags should be indented in a headline. +If this number is positive, it specifies the column. If it is negative, +it means that the tags should be flushright to that column. For example, +-79 works well for a normal 80 character screen." + :group 'org-tags + :type 'integer) + +(defcustom org-auto-align-tags t + "Non-nil means, realign tags after pro/demotion of TODO state change. +These operations change the length of a headline and therefore shift +the tags around. With this options turned on, after each such operation +the tags are again aligned to `org-tags-column'." + :group 'org-tags + :type 'boolean) + +(defcustom org-use-tag-inheritance t + "Non-nil means, tags in levels apply also for sublevels. +When nil, only the tags directly given in a specific line apply there. +If you turn off this option, you very likely want to turn on the +companion option `org-tags-match-list-sublevels'." + :group 'org-tags + :type 'boolean) + +(defcustom org-tags-match-list-sublevels nil + "Non-nil means list also sublevels of headlines matching tag search. +Because of tag inheritance (see variable `org-use-tag-inheritance'), +the sublevels of a headline matching a tag search often also match +the same search. Listing all of them can create very long lists. +Setting this variable to nil causes subtrees to be skipped. +This option is off by default, because inheritance in on. If you turn +inheritance off, you very likely want to turn this option on. + +As a special case, if the tag search is restricted to TODO items, the +value of this variable is ignored and sublevels are always checked, to +make sure all corresponding TODO items find their way into the list." + :group 'org-tags + :type 'boolean) + +(defvar org-tags-history nil + "History of minibuffer reads for tags.") +(defvar org-last-tags-completion-table nil + "The last used completion table for tags.") + +(defgroup org-link nil + "Options concerning links in Org-mode." + :tag "Org Link" + :group 'org) + +(defcustom org-tab-follows-link nil + "Non-nil means, on links TAB will follow the link. +Needs to be set before org.el is loaded." + :group 'org-link + :type 'boolean) + +(defcustom org-return-follows-link nil + "Non-nil means, on links RET will follow the link. +Needs to be set before org.el is loaded." + :group 'org-link + :type 'boolean) + +(defcustom org-mark-ring-length 4 + "Number of different positions to be recorded in the ring +Changing this requires a restart of Emacs to work correctly." + :group 'org-link + :type 'interger) + +(defcustom org-link-format "<%s>" + "Default format for linkes in the buffer. +This is a format string for printf, %s will be replaced by the link text. +If you want to make sure that your link is always properly terminated, +include angle brackets into this format, like \"<%s>\". Some people also +recommend an additional URL: prefix, so the format would be \"\"." + :group 'org-link + :type '(choice + (const :tag "\"%s\" (e.g. http://www.there.com)" "%s") + (const :tag "\"<%s>\" (e.g. )" "<%s>") + (const :tag "\"\" (e.g. )" "") + (string :tag "Other" :value "<%s>"))) + +(defcustom org-allow-space-in-links t + "Non-nil means, file names in links may contain space characters. +When nil, it becomes possible to put several links into a line. +Note that in tables, a link never extends accross fields, so in a table +it is always possible to put several links into a line. +Changing this variable requires a restart of Emacs of become effective." + :group 'org-link + :type 'boolean) + +(defcustom org-radio-targets t + "Non-nil means activate text matching a link target. +Radio targets are strings in triple angular brackets, like <<>>. +When this option is set, any occurrence of \"my target\" in normal text +becomes a link." + :group 'org-link + :type 'boolean) + +(defcustom org-activate-camels nil + "Non-nil means, treat words in CamelCase as in-file links. +Changing this requires restart of Emacs to become effective." + :group 'org-link + :type 'boolean) + +(defcustom org-context-in-file-links t + "Non-nil means, file links from `org-store-link' contain context. +A search string will be added to the file name with :: as separator and +used to find the context when the link is activated by the command +`org-open-at-point'. +Using a prefix arg to the command \\[org-store-link] (`org-store-link') +negates this setting for the duration of the command." + :group 'org-link + :type 'boolean) + +(defcustom org-file-link-context-use-camel-case nil + "Non-nil means, use CamelCase to store a search context in a file link. +When nil, the search string simply consists of the words of the string." + :group 'org-link + :type 'boolean) + +(defcustom org-keep-stored-link-after-insertion nil + "Non-nil means, keep link in list for entire session. + +The command `org-store-link' adds a link pointing to the current +location to an internal list. These links accumulate during a session. +The command `org-insert-link' can be used to insert links into any +Org-mode file (offering completion for all stored links). When this +option is nil, every link which has been inserted once using \\[org-insert-link] +will be removed from the list, to make completing the unused links +more efficient." + :group 'org-link + :type 'boolean) + +(defcustom org-link-frame-setup + '((vm . vm-visit-folder-other-frame) + (gnus . gnus-other-frame) + (file . find-file-other-window)) + "Setup the frame configuration for following links. +When following a link with Emacs, it may often be useful to display +this link in another window or frame. This variable can be used to +set this up for the different types of links. +For VM, use any of + `vm-visit-folder' + `vm-visit-folder-other-frame' +For Gnus, use any of + `gnus' + `gnus-other-frame' +For FILE, use any of + `find-file' + `find-file-other-window' + `find-file-other-frame' +For the calendar, use the variable `calendar-setup'. +For BBDB, it is currently only possible to display the matches in +another window." + :group 'org-link + :type '(list + (cons (const vm) + (choice + (const vm-visit-folder) + (const vm-visit-folder-other-window) + (const vm-visit-folder-other-frame))) + (cons (const gnus) + (choice + (const gnus) + (const gnus-other-frame))) + (cons (const file) + (choice + (const find-file) + (const find-file-other-window) + (const find-file-other-frame))))) + +(defcustom org-usenet-links-prefer-google nil + "Non-nil means, `org-store-link' will create web links to Google groups. +When nil, Gnus will be used for such links. +Using a prefix arg to the command \\[org-store-link] (`org-store-link') +negates this setting for the duration of the command." + :group 'org-link + :type 'boolean) + +(defcustom org-open-non-existing-files nil + "Non-nil means, `org-open-file' will open non-existing file. +When nil, an error will be generated." + :group 'org-link + :type 'boolean) + +(defcustom org-confirm-shell-links t + "Non-nil means, ask for confirmation before executing shell links. +The default is true, to keep new users from shooting into their own foot." + :group 'org-link + :type 'boolean) + +(defconst org-file-apps-defaults-gnu + '((t . mailcap)) + "Default file applications on a UNIX or GNU/Linux system. +See `org-file-apps'.") + +(defconst org-file-apps-defaults-macosx + '((t . "open %s") + ("ps" . "gv %s") + ("ps.gz" . "gv %s") + ("eps" . "gv %s") + ("eps.gz" . "gv %s") + ("dvi" . "xdvi %s") + ("fig" . "xfig %s")) + "Default file applications on a MacOS X system. +The system \"open\" is known as a default, but we use X11 applications +for some files for which the OS does not have a good default. +See `org-file-apps'.") + +(defconst org-file-apps-defaults-windowsnt + '((t . (w32-shell-execute "open" file))) + "Default file applications on a Windows NT system. +The system \"open\" is used for most files. +See `org-file-apps'.") + +(defcustom org-file-apps + '( + ("txt" . emacs) + ("tex" . emacs) + ("ltx" . emacs) + ("org" . emacs) + ("el" . emacs) + ) + "External applications for opening `file:path' items in a document. +Org-mode uses system defaults for different file types, but +you can use this variable to set the application for a given file +extension. The entries in this list are cons cells with a file extension +and the corresponding command. Possible values for the command are: + `emacs' The file will be visited by the current Emacs process. + `default' Use the default application for this file type. + string A command to be executed by a shell; %s will be replaced + by the path to the file. + sexp A Lisp form which will be evaluated. The file path will + be available in the Lisp variable `file'. +For more examples, see the system specific constants +`org-file-apps-defaults-macosx' +`org-file-apps-defaults-windowsnt' +`org-file-apps-defaults-gnu'." + :group 'org-link + :type '(repeat + (cons (choice :value "" + (string :tag "Extension") + (const :tag "Default for unrecognized files" t) + (const :tag "Links to a directory" directory)) + (choice :value "" + (const :tag "Visit with Emacs" emacs) + (const :tag "Use system default" default) + (string :tag "Command") + (sexp :tag "Lisp form"))))) + +(defcustom org-mhe-search-all-folders nil + "Non-nil means, that the search for the mh-message will be extended to +all folders if the message cannot be found in the folder given in the link. +Searching all folders is very effective with one of the search engines +supported by MH-E, but will be slow with pick." + :group 'org-link + :type 'boolean) + +(defgroup org-remember nil + "Options concerning interaction with remember.el." + :tag "Org Remember" + :group 'org) + +(defcustom org-directory "~/org" + "Directory with org files. +This directory will be used as default to prompt for org files. +Used by the hooks for remember.el." + :group 'org-remember + :type 'directory) + +(defcustom org-default-notes-file "~/.notes" + "Default target for storing notes. +Used by the hooks for remember.el. This can be a string, or nil to mean +the value of `remember-data-file'." + :group 'org-remember + :type '(choice + (const :tag "Default from remember-data-file" nil) + file)) + +(defcustom org-remember-templates nil + "Templates for the creation of remember buffers. +When nil, just let remember make the buffer. +When not nil, this is a list of 3-element lists. In each entry, the first +element is a character, a unique key to select this template. +The second element is the template. The third element is optional and can +specify a destination file for remember items created with this template. +The default file is given by `org-default-notes-file'. + +The template specifies the structure of the remember buffer. It should have +a first line starting with a star, to act as the org-mode headline. +Furthermore, the following %-escapes will be replaced with content: + %t time stamp, date only + %T time stamp with date and time + %u inactive time stamp, date only + %U inactive time stamp with date and time + %n user name + %a annotation, normally the link created with org-store-link + %i initial content, the region when remember is called with C-u. + If %i is indented, the entire inserted text will be indented as well. + %? This will be removed, and the cursor placed at this position." + :group 'org-remember + :type '(repeat :tag "enabled" + (list :value (?a "\n" nil) + (character :tag "Selection Key") + (string :tag "Template") + (file :tag "Destination file (optional)")))) + +(defcustom org-reverse-note-order nil + "Non-nil means, store new notes at the beginning of a file or entry. +When nil, new notes will be filed to the end of a file or entry." + :group 'org-remember + :type '(choice + (const :tag "Reverse always" t) + (const :tag "Reverse never" nil) + (repeat :tag "By file name regexp" + (cons regexp boolean)))) + +(defgroup org-table nil + "Options concerning tables in Org-mode." + :tag "Org Table" + :group 'org) + +(defcustom org-enable-table-editor 'optimized + "Non-nil means, lines starting with \"|\" are handled by the table editor. +When nil, such lines will be treated like ordinary lines. + +When equal to the symbol `optimized', the table editor will be optimized to +do the following: +- Use automatic overwrite mode in front of whitespace in table fields. + This make the structure of the table stay in tact as long as the edited + field does not exceed the column width. +- Minimize the number of realigns. Normally, the table is aligned each time + TAB or RET are pressed to move to another field. With optimization this + happens only if changes to a field might have changed the column width. +Optimization requires replacing the functions `self-insert-command', +`delete-char', and `backward-delete-char' in Org-mode buffers, with a +slight (in fact: unnoticeable) speed impact for normal typing. Org-mode is +very good at guessing when a re-align will be necessary, but you can always +force one with \\[org-ctrl-c-ctrl-c]. + +If you would like to use the optimized version in Org-mode, but the +un-optimized version in OrgTbl-mode, see the variable `orgtbl-optimized'. + +This variable can be used to turn on and off the table editor during a session, +but in order to toggle optimization, a restart is required. + +See also the variable `org-table-auto-blank-field'." + :group 'org-table + :type '(choice + (const :tag "off" nil) + (const :tag "on" t) + (const :tag "on, optimized" optimized))) + +;; FIXME: We could have a third option which makes it jump only over the first +;; hline in a table. +(defcustom org-table-tab-jumps-over-hlines t + "Non-nil means, tab in the last column of a table with jump over a hline. +If a horizontal separator line is following the current line, +`org-table-next-field' can either create a new row before that line, or jump +over the line. When this option is nil, a new line will be created before +this line." + :group 'org-table + :type 'boolean) + +(defcustom org-table-auto-blank-field t + "Non-nil means, automatically blank table field when starting to type into it. +This only happens when typing immediately after a field motion +command (TAB, S-TAB or RET). +Only relevant when `org-enable-table-editor' is equal to `optimized'." + :group 'org-table + :type 'boolean) + +(defcustom org-table-default-size "5x2" + "The default size for newly created tables, Columns x Rows." + :group 'org-table + :type 'string) + +(defcustom org-table-automatic-realign t + "Non-nil means, automatically re-align table when pressing TAB or RETURN. +When nil, aligning is only done with \\[org-table-align], or after column +removal/insertion." + :group 'org-table + :type 'boolean) + +(defcustom org-table-spaces-around-separators '(1 . 1) + "The number of spaces to be placed before and after separators." + :group 'org-table + :type '(cons (number :tag "Before \"|\"") (number :tag " After \"|\""))) + +(defcustom org-table-spaces-around-invisible-separators '(1 . 2) + "The number of spaces to be placed before and after separators. +This option applies when the column separators have been made invisible." + :group 'org-table + :type '(cons (number :tag "Before \"|\"") (number :tag " After \"|\""))) + +(defcustom org-table-number-regexp "^[<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%]*$" + "Regular expression for recognizing numbers in table columns. +If a table column contains mostly numbers, it will be aligned to the +right. If not, it will be aligned to the left. + +The default value of this option is a regular expression which allows +anything which looks remotely like a number as used in scientific +context. For example, all of the following will be considered a +number: + 12 12.2 2.4e-08 2x10^12 4.034+-0.02 2.7(10) >3.5 + +Other options offered by the customize interface are more restrictive." + :group 'org-table + :type '(choice + (const :tag "Positive Integers" + "^[0-9]+$") + (const :tag "Integers" + "^[-+]?[0-9]+$") + (const :tag "Floating Point Numbers" + "^[-+]?\\([0-9]*\\.[0-9]+\\|[0-9]+\\.[0-9]*\\)$") + (const :tag "Floating Point Number or Integer" + "^[-+]?\\([0-9]*\\.[0-9]+\\|[0-9]+\\.?[0-9]*\\)$") + (const :tag "Exponential, Floating point, Integer" + "^[-+]?[0-9.]+\\([eEdD][-+0-9]+\\)?$") + (const :tag "Very General Number-Like" + "^[<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%]*$") + (string :tag "Regexp:"))) + +(defcustom org-table-number-fraction 0.5 + "Fraction of numbers in a column required to make the column align right. +In a column all non-white fields are considered. If at least this +fraction of fields is matched by `org-table-number-fraction', +alignment to the right border applies." + :group 'org-table + :type 'number) + +(defcustom org-export-highlight-first-table-line t + "Non-nil means, highlight the first table line. +In HTML export, this means use instead of . +In tables created with table.el, this applies to the first table line. +In Org-mode tables, all lines before the first horizontal separator +line will be formatted with tags." + :group 'org-table + :type 'boolean) + +(defcustom org-table-tab-recognizes-table.el t + "Non-nil means, TAB will automatically notice a table.el table. +When it sees such a table, it moves point into it and - if necessary - +calls `table-recognize-table'." + :group 'org-table + :type 'boolean) + +(defgroup org-table-calculation nil + "Options concerning tables in Org-mode." + :tag "Org Table Calculation" + :group 'org) + +(defcustom org-table-copy-increment t + "Non-nil means, increment when copying current field with \\[org-table-copy-down]." + :group 'org-table-calculation + :type 'boolean) + +(defcustom org-calc-default-modes + '(calc-internal-prec 12 + calc-float-format (float 5) + calc-angle-mode deg + calc-prefer-frac nil + calc-symbolic-mode nil + calc-date-format (YYYY "-" MM "-" DD " " Www (" " HH ":" mm)) + calc-display-working-message t + ) + "List with Calc mode settings for use in calc-eval for table formulas. +The list must contain alternating symbols (Calc modes variables and values). +Don't remove any of the default settings, just change the values. Org-mode +relies on the variables to be present in the list." + :group 'org-table-calculation + :type 'plist) + +(defcustom org-table-formula-evaluate-inline t + "Non-nil means, TAB and RET evaluate a formula in current table field. +If the current field starts with an equal sign, it is assumed to be a formula +which should be evaluated as described in the manual and in the documentation +string of the command `org-table-eval-formula'. This feature requires the +Emacs calc package. +When this variable is nil, formula calculation is only available through +the command \\[org-table-eval-formula]." + :group 'org-table-calculation + :type 'boolean) + + +(defcustom org-table-formula-use-constants t + "Non-nil means, interpret constants in formulas in tables. +A constant looks like `$c' or `$Grav' and will be replaced before evaluation +by the value given in `org-table-formula-constants', or by a value obtained +from the `constants.el' package." + :group 'org-table-calculation + :type 'boolean) + +(defcustom org-table-formula-constants nil + "Alist with constant names and values, for use in table formulas. +The car of each element is a name of a constant, without the `$' before it. +The cdr is the value as a string. For example, if you'd like to use the +speed of light in a formula, you would configure + + (setq org-table-formula-constants '((\"c\" . \"299792458.\"))) + +and then use it in an equation like `$1*$c'." + :group 'org-table-calculation + :type '(repeat + (cons (string :tag "name") + (string :tag "value")))) + +(defcustom org-table-formula-numbers-only nil + "Non-nil means, calculate only with numbers in table formulas. +Then all input fields will be converted to a number, and the result +must also be a number. When nil, calc's full potential is available +in table calculations, including symbolics etc." + :group 'org-table-calculation + :type 'boolean) + +(defcustom org-table-allow-automatic-line-recalculation t + "Non-nil means, lines marked with |#| or |*| will be recomputed automatically. +Automatically means, when TAB or RET or C-c C-c are pressed in the line." + :group 'org-table-calculation + :type 'boolean) + +(defgroup org-export nil + "Options for exporting org-listings." + :tag "Org Export" + :group 'org) + +(defcustom org-export-language-setup + '(("en" "Author" "Date" "Table of Contents") + ("da" "Ophavsmand" "Dato" "Indhold") + ("de" "Autor" "Datum" "Inhaltsverzeichnis") + ("es" "Autor" "Fecha" "\xccndice") + ("fr" "Auteur" "Date" "Table des Mati\xe8res") + ("it" "Autore" "Data" "Indice") + ("nl" "Auteur" "Datum" "Inhoudsopgave") + ("nn" "Forfattar" "Dato" "Innhold") ;; nn = Norsk (nynorsk) + ("sv" "F\xf6rfattarens" "Datum" "Inneh\xe5ll")) + "Terms used in export text, translated to different languages. +Use the variable `org-export-default-language' to set the language, +or use the +OPTION lines for a per-file setting." + :group 'org-export + :type '(repeat + (list + (string :tag "HTML language tag") + (string :tag "Author") + (string :tag "Date") + (string :tag "Table of Contents")))) + +(defcustom org-export-default-language "en" + "The default language of HTML export, as a string. +This should have an association in `org-export-language-setup'." + :group 'org-export + :type 'string) + +(defcustom org-export-html-style +"" + "The default style specification for exported HTML files. +Since there are different ways of setting style information, this variable +needs to contain the full HTML structure to provide a style, including the +surrounding HTML tags. The style specifications should include definitions +for new classes todo, done, title, and deadline. For example, legal values +would be: + + + +or, if you want to keep the style in a file, + + + +As the value of this option simply gets inserted into the HTML header, +you can \"misuse\" it to add arbitrary text to the header." + :group 'org-export + :type 'string) + +(defcustom org-export-headline-levels 3 + "The last level which is still exported as a headline. +Inferior levels will produce itemize lists when exported. +Note that a numeric prefix argument to an exporter function overrides +this setting. + +This option can also be set with the +OPTIONS line, e.g. \"H:2\"." + :group 'org-export + :type 'number) + +(defcustom org-export-with-section-numbers t + "Non-nil means, add section numbers to headlines when exporting. + +This option can also be set with the +OPTIONS line, e.g. \"num:t\"." + :group 'org-export + :type 'boolean) + +(defcustom org-export-with-toc t + "Non-nil means, create a table of contents in exported files. +The TOC contains headlines with levels up to`org-export-headline-levels'. + +Headlines which contain any TODO items will be marked with \"(*)\" in +ASCII export, and with red color in HTML output. + +In HTML output, the TOC will be clickable. + +This option can also be set with the +OPTIONS line, e.g. \"toc:nil\"." + :group 'org-export + :type 'boolean) + +(defcustom org-export-plain-list-max-depth 20 + "Maximum depth of hand-formatted lists in HTML export. + +Org-mode parses hand-formatted enumeration and bullet lists and +transforms them to HTML open export. Different indentation of the +bullet or number indicates different list nesting levels. To avoid +confusion, only a single level is allowed by default. When this is +larger than 1, deeper indentation leads to deeper list nesting. For +example, the default value of 3 allows the following list to be +formatted correctly in HTML: + + * Fruit + - Apple + - Banana + 1. from Africa + 2. from South America + - Pineapple + * Bread + * Dairy products" + :group 'org-export + :type 'integer) + +(defcustom org-export-preserve-breaks nil + "Non-nil means, preserve all line breaks when exporting. +Normally, in HTML output paragraphs will be reformatted. In ASCII +export, line breaks will always be preserved, regardless of this variable. + +This option can also be set with the +OPTIONS line, e.g. \"\\n:t\"." + :group 'org-export + :type 'boolean) + +(defcustom org-export-html-inline-images t + "Non-nil means, inline images into exported HTML pages. +The link will still be to the original location of the image file. +So if you are moving the page, lets say to your public HTML site, +you will have to move the image and maybe change the link." + :group 'org-export + :type 'boolean) + +(defcustom org-export-html-expand t + "Non-nil means, for HTML export, treat @<...> as HTML tag. +When nil, these tags will be exported as plain text and therefore +not be interpreted by a browser. + +This option can also be set with the +OPTIONS line, e.g. \"@:nil\"." + :group 'org-export + :type 'boolean) + +(defcustom org-export-with-fixed-width t + "Non-nil means, lines starting with \":\" will be in fixed width font. +This can be used to have pre-formatted text, fragments of code etc. For +example: + : ;; Some Lisp examples + : (while (defc cnt) + : (ding)) +will be looking just like this in also HTML. In ASCII export, this option +has no effect. + +This option can also be set with the +OPTIONS line, e.g. \"::nil\"." + :group 'org-export + :type 'boolean) + +(defcustom org-export-with-tables t + "If non-nil, lines starting with \"|\" define a table. +For example: + + | Name | Address | Birthday | + |-------------+----------+-----------| + | Arthur Dent | England | 29.2.2100 | + +In ASCII export, this option has no effect. + +This option can also be set with the +OPTIONS line, e.g. \"|:nil\"." + :group 'org-export + :type 'boolean) + +(defcustom org-export-table-remove-special-lines t + "Remove special lines and marking characters in calculating tables. +This removes the special marking character column from tables that are set +up for spreadsheet calculations. It also removes the entire lines +marked with `!', `_', or `^'. The lines with `$' are kept, because +the values of constants may be useful to have." + :group 'org-export + :type 'boolean) + +(defcustom org-export-prefer-native-exporter-for-tables nil + "Non-nil means, always export tables created with table.el natively. +Natively means, use the HTML code generator in table.el. +When nil, Org-mode's own HTML generator is used when possible (i.e. if +the table does not use row- or column-spanning). This has the +advantage, that the automatic HTML conversions for math symbols and +sub/superscripts can be applied. Org-mode's HTML generator is also +much faster." + :group 'org-export + :type 'boolean) + +(defcustom org-export-html-table-tag + "" + "The HTML tag used to start a table. +This must be a
tag, but you may change the options like +borders and spacing." + :group 'org-export + :type 'string) + +(defcustom org-export-with-emphasize t + "Non-nil means, interpret *word*, /word/, and _word_ as emphasized text. +If the export target supports emphasizing text, the word will be +typeset in bold, italic, or underlined, respectively. Works only for +single words, but you can say: I *really* *mean* *this*. +In ASCII export, this option has no effect. + +This option can also be set with the +OPTIONS line, e.g. \"*:nil\"." + :group 'org-export + :type 'boolean) + +(defcustom org-match-sexp-depth 3 + "Number of stacked braces for sub/superscript matching. +This has to be set before loading org.el to be effective." + :group 'org-export + :type 'integer) + +;; FIXME: Should () parens be removed as well in sub/superscripts? +(defcustom org-export-with-sub-superscripts t + "Non-nil means, interpret \"_\" and \"^\" for export. +When this option is turned on, you can use TeX-like syntax for sub- and +superscripts. Several characters after \"_\" or \"^\" will be +considered as a single item - so grouping with {} is normally not +needed. For example, the following things will be parsed as single +sub- or superscripts. + + 10^24 or 10^tau several digits will be considered 1 item. + 10^-12 or 10^-tau a leading sign with digits or a word + x^2-y^3 will be read as x^2 - y^3, because items are + terminated by almost any nonword/nondigit char. + x_{i^2} or x^(2-i) braces or parenthesis do grouping. + +Still, ambiguity is possible - so when in doubt use {} to enclose the +sub/superscript. +In ASCII export, this option has no effect. + +This option can also be set with the +OPTIONS line, e.g. \"^:nil\"." + :group 'org-export + :type 'boolean) + +(defcustom org-export-with-TeX-macros t + "Non-nil means, interpret simple TeX-like macros when exporting. +For example, HTML export converts \\alpha to α and \\AA to Å. +No only real TeX macros will work here, but the standard HTML entities +for math can be used as macro names as well. For a list of supported +names in HTML export, see the constant `org-html-entities'. +In ASCII export, this option has no effect. + +This option can also be set with the +OPTIONS line, e.g. \"TeX:nil\"." + :group 'org-export + :type 'boolean) + +(defcustom org-export-html-with-timestamp nil + "If non-nil, write `org-export-html-html-helper-timestamp' +into the exported HTML text. Otherwise, the buffer will just be saved +to a file." + :group 'org-export + :type 'boolean) + +(defcustom org-export-html-html-helper-timestamp + "


\n" + "The HTML tag used as timestamp delimiter for HTML-helper-mode." + :group 'org-export + :type 'string) + +(defcustom org-export-ascii-show-new-buffer t + "Non-nil means, popup buffer containing the exported ASCII text. +Otherwise the buffer will just be saved to a file and stay hidden." + :group 'org-export + :type 'boolean) + +(defcustom org-export-html-show-new-buffer nil + "Non-nil means, popup buffer containing the exported html text. +Otherwise, the buffer will just be saved to a file and stay hidden." + :group 'org-export + :type 'boolean) + +(defcustom org-combined-agenda-icalendar-file "~/org.ics" + "The file name for the iCalendar file covering all agenda files. +This file is created with the command \\[org-export-icalendar-all-agenda-files]." + :group 'org-export + :type 'file) + +(defcustom org-icalendar-include-todo nil + "Non-nil means, export to iCalendar files should also cover TODO items." + :group 'org-export + :type 'boolean) + +(defcustom org-icalendar-combined-name "OrgMode" + "Calendar name for the combined iCalendar representing all agenda files." + :group 'org-export + :type 'string) + +(defgroup org-font-lock nil + "Faces and settings for highlighting in Org-mode." + :tag "Org Font Lock" + :group 'org) + +(defcustom org-level-color-stars-only nil + "Non-nil means fontify only the stars in each headline. +When nil, the entire headline is fontified. +Changing it requires restart of `font-lock-mode' to become effective +also in regions already fontified." + :group 'org-font-lock + :type 'boolean) + +(defcustom org-hide-leading-stars nil + "Non-nil means, hide the first N-1 stars in a headline. +This works by using the face `org-hide' for these stars. This +face is white for a light background, and black for a dark +background. You may have to customize the face `org-hide' to +make this work. +Changing it requires restart of `font-lock-mode' to become effective +also in regions already fontified." + :group 'org-font-lock + :type 'boolean) + +(defcustom org-fontify-done-headline nil + "Non-nil means, change the face of a headline if it is marked DONE. +Normally, only the TODO/DONE keyword indicates the state of a headline. +When this is non-nil, the headline after the keyword is set to the +`org-headline-done' as an additional indication." + :group 'org-font-lock + :type 'boolean) + +(defcustom org-fontify-emphasized-text t + "Non-nil means fontify *bold*, /italic/ and _underlined_ text. +Changing this variable requires a restart of Emacs to take effect." + :group 'org-font-lock + :type 'boolean) + +(defface org-hide + '( + (((type tty) (class color)) (:foreground "white")) + (((class color) (background light)) (:foreground "white")) + (((class color) (background dark)) (:foreground "black")) +; (((class color) (backgro6und light)) (:foreground "grey90")) +; (((class color) (background dark)) (:foreground "grey10")) + (t (:inverse-video nil))) + "Face used for level 1 headlines." + :group 'org-font-lock) + +(defface org-level-1 ;; font-lock-function-name-face + '((((type tty) (class color)) (:foreground "blue" :weight bold)) + (((class color) (background light)) (:foreground "Blue")) + (((class color) (background dark)) (:foreground "LightSkyBlue")) + (t (:inverse-video t :bold t))) + "Face used for level 1 headlines." + :group 'org-font-lock) + +(defface org-level-2 ;; font-lock-variable-name-face + '((((type tty) (class color)) (:foreground "yellow" :weight light)) + (((class color) (background light)) (:foreground "DarkGoldenrod")) + (((class color) (background dark)) (:foreground "LightGoldenrod")) + (t (:bold t :italic t))) + "Face used for level 2 headlines." + :group 'org-font-lock) + +(defface org-level-3 ;; font-lock-keyword-face + '((((type tty) (class color)) (:foreground "cyan" :weight bold)) + (((class color) (background light)) (:foreground "Purple")) + (((class color) (background dark)) (:foreground "Cyan")) + (t (:bold t))) + "Face used for level 3 headlines." + :group 'org-font-lock) + +(defface org-level-4 ;; font-lock-comment-face + '((((type tty pc) (class color) (background light)) (:foreground "red")) + (((type tty pc) (class color) (background dark)) (:foreground "red1")) + (((class color) (background light)) (:foreground "Firebrick")) + (((class color) (background dark)) (:foreground "chocolate1")) + (t (:bold t :italic t))) + "Face used for level 4 headlines." + :group 'org-font-lock) + +(defface org-level-5 ;; font-lock-type-face + '((((type tty) (class color)) (:foreground "green")) + (((class color) (background light)) (:foreground "ForestGreen")) + (((class color) (background dark)) (:foreground "PaleGreen")) + (t (:bold t :underline t))) + "Face used for level 5 headlines." + :group 'org-font-lock) + +(defface org-level-6 ;; font-lock-constant-face + '((((type tty) (class color)) (:foreground "magenta")) + (((class color) (background light)) (:foreground "CadetBlue")) + (((class color) (background dark)) (:foreground "Aquamarine")) + (t (:bold t :underline t))) + "Face used for level 6 headlines." + :group 'org-font-lock) + +(defface org-level-7 ;; font-lock-builtin-face + '((((type tty) (class color)) (:foreground "blue" :weight light)) + (((class color) (background light)) (:foreground "Orchid")) + (((class color) (background dark)) (:foreground "LightSteelBlue")) + (t (:bold t))) + "Face used for level 7 headlines." + :group 'org-font-lock) + +(defface org-level-8 ;; font-lock-string-face + '((((type tty) (class color)) (:foreground "green")) + (((class color) (background light)) (:foreground "RosyBrown")) + (((class color) (background dark)) (:foreground "LightSalmon")) + (t (:italic t))) + "Face used for level 8 headlines." + :group 'org-font-lock) + +(defface org-special-keyword ;; font-lock-string-face + '((((type tty) (class color)) (:foreground "green")) + (((class color) (background light)) (:foreground "RosyBrown")) + (((class color) (background dark)) (:foreground "LightSalmon")) + (t (:italic t))) + "Face used for special keywords." + :group 'org-font-lock) + +(defface org-warning ;; font-lock-warning-face + '((((type tty) (class color)) (:foreground "red")) + (((class color) (background light)) (:foreground "Red" :bold t)) + (((class color) (background dark)) (:foreground "Red1" :bold t)) +; (((class color) (background dark)) (:foreground "Pink" :bold t)) + (t (:inverse-video t :bold t))) + "Face for deadlines and TODO keywords." + :group 'org-font-lock) + +(defface org-headline-done ;; font-lock-string-face + '((((type tty) (class color)) (:foreground "green")) + (((class color) (background light)) (:foreground "RosyBrown")) + (((class color) (background dark)) (:foreground "LightSalmon")) + (t (:italic t))) + "Face used to indicate that a headline is DONE. See also the variable +`org-fontify-done-headline'." + :group 'org-font-lock) + +;; Inheritance does not yet work for xemacs. So we just copy... + +(defface org-deadline-announce + '((((type tty) (class color)) (:foreground "blue" :weight bold)) + (((class color) (background light)) (:foreground "Blue")) + (((class color) (background dark)) (:foreground "LightSkyBlue")) + (t (:inverse-video t :bold t))) + "Face for upcoming deadlines." + :group 'org-font-lock) + +(defface org-scheduled-today + '((((type tty) (class color)) (:foreground "green")) + (((class color) (background light)) (:foreground "DarkGreen")) + (((class color) (background dark)) (:foreground "PaleGreen")) + (t (:bold t :underline t))) + "Face for items scheduled for a certain day." + :group 'org-font-lock) + +(defface org-scheduled-previously + '((((type tty pc) (class color) (background light)) (:foreground "red")) + (((type tty pc) (class color) (background dark)) (:foreground "red1")) + (((class color) (background light)) (:foreground "Firebrick")) + (((class color) (background dark)) (:foreground "chocolate1")) + (t (:bold t :italic t))) + "Face for items scheduled previously, and not yet done." + :group 'org-font-lock) + +(defface org-formula + '((((type tty pc) (class color) (background light)) (:foreground "red")) + (((type tty pc) (class color) (background dark)) (:foreground "red1")) + (((class color) (background light)) (:foreground "Firebrick")) + (((class color) (background dark)) (:foreground "chocolate1")) + (t (:bold t :italic t))) + "Face for formulas." + :group 'org-font-lock) + +(defface org-link + '((((type tty) (class color)) (:foreground "cyan" :weight bold)) + (((class color) (background light)) (:foreground "Purple")) + (((class color) (background dark)) (:foreground "Cyan")) + (t (:bold t))) + "Face for links." + :group 'org-font-lock) + +(defface org-tag + '((((type tty) (class color)) (:foreground "cyan" :weight bold)) + (((class color) (background light)) (:foreground "Purple" :weight bold)) + (((class color) (background dark)) (:foreground "Cyan" :weight bold)) + (t (:bold t))) + "Face for tags." + :group 'org-font-lock) + +(defface org-done ;; font-lock-type-face + '((((type tty) (class color)) (:foreground "green")) + (((class color) (background light)) (:foreground "ForestGreen" :bold t)) + (((class color) (background dark)) (:foreground "PaleGreen" :bold t)) + (t (:bold t :underline t))) + "Face used for DONE." + :group 'org-font-lock) + +(defface org-table ;; font-lock-function-name-face + '((((type tty) (class color)) (:foreground "blue" :weight bold)) + (((class color) (background light)) (:foreground "Blue")) + (((class color) (background dark)) (:foreground "LightSkyBlue")) + (t (:inverse-video t :bold t))) + "Face used for tables." + :group 'org-font-lock) + +(defface org-time-grid ;; font-lock-variable-name-face + '((((type tty) (class color)) (:foreground "yellow" :weight light)) + (((class color) (background light)) (:foreground "DarkGoldenrod")) + (((class color) (background dark)) (:foreground "LightGoldenrod")) + (t (:bold t :italic t))) + "Face used for time grids." + :group 'org-font-lock) + +(defvar org-level-faces + '(org-level-1 org-level-2 org-level-3 org-level-4 + org-level-5 org-level-6 org-level-7 org-level-8 + )) +(defvar org-n-levels (length org-level-faces)) + +(defun org-set-regexps-and-options () + "Precompute regular expressions for current buffer." + (when (eq major-mode 'org-mode) + (let ((re (org-make-options-regexp + '("CATEGORY" "SEQ_TODO" "PRI_TODO" "TYP_TODO" + "STARTUP" "ARCHIVE"))) + (splitre "[ \t]+") + kwds int key value cat arch) + (save-excursion + (save-restriction + (widen) + (goto-char (point-min)) + (while (re-search-forward re nil t) + (setq key (match-string 1) value (match-string 2)) + (cond + ((equal key "CATEGORY") + (if (string-match "[ \t]+$" value) + (setq value (replace-match "" t t value))) + (setq cat (intern value))) + ((equal key "SEQ_TODO") + (setq int 'sequence + kwds (append kwds (org-split-string value splitre)))) + ((equal key "PRI_TODO") + (setq int 'priority + kwds (append kwds (org-split-string value splitre)))) + ((equal key "TYP_TODO") + (setq int 'type + kwds (append kwds (org-split-string value splitre)))) + ((equal key "STARTUP") + (let ((opts (org-split-string value splitre)) + (set '(("fold" org-startup-folded t) + ("nofold" org-startup-folded nil) + ("content" org-startup-folded content) + ("hidestars" org-hide-leading-stars t) + ("showstars" org-hide-leading-stars nil) + ("odd" org-odd-levels-only t) + ("oddeven" org-odd-levels-only nil) + ("dlcheck" org-startup-with-deadline-check t) + ("nodlcheck" org-startup-with-deadline-check nil))) + l var val) + (while (setq l (assoc (pop opts) set)) + (setq var (nth 1 l) val (nth 2 l)) + (set (make-local-variable var) val)))) + ((equal key "ARCHIVE") + (string-match " *$" value) + (setq arch (replace-match "" t t value)) + (remove-text-properties 0 (length arch) + '(face t fontified t) arch))) + ))) + (and cat (set (make-local-variable 'org-category) cat)) + (and kwds (set (make-local-variable 'org-todo-keywords) kwds)) + (and arch (set (make-local-variable 'org-archive-location) arch)) + (and int (set (make-local-variable 'org-todo-interpretation) int))) + ;; Compute the regular expressions and other local variables + (setq org-todo-kwd-priority-p (equal org-todo-interpretation 'priority) + org-todo-kwd-max-priority (1- (length org-todo-keywords)) + org-ds-keyword-length (+ 2 (max (length org-deadline-string) + (length org-scheduled-string))) + org-done-string + (nth (1- (length org-todo-keywords)) org-todo-keywords) + org-todo-regexp + (concat "\\<\\(" (mapconcat 'regexp-quote org-todo-keywords + "\\|") "\\)\\>") + org-not-done-regexp + (concat "\\<\\(" + (mapconcat 'regexp-quote + (nreverse (cdr (reverse org-todo-keywords))) + "\\|") + "\\)\\>") + org-todo-line-regexp + (concat "^\\(\\*+\\)[ \t]*\\(" + (mapconcat 'regexp-quote org-todo-keywords "\\|") + "\\)? *\\(.*\\)") + org-nl-done-regexp + (concat "[\r\n]\\*+[ \t]+" org-done-string "\\>") + org-looking-at-done-regexp (concat "^" org-done-string "\\>") + org-deadline-regexp (concat "\\<" org-deadline-string) + org-deadline-time-regexp + (concat "\\<" org-deadline-string " *<\\([^>]+\\)>") + org-deadline-line-regexp + (concat "\\<\\(" org-deadline-string "\\).*") + org-scheduled-regexp + (concat "\\<" org-scheduled-string) + org-scheduled-time-regexp + (concat "\\<" org-scheduled-string " *<\\([^>]+\\)>")) + (org-set-font-lock-defaults))) + +;; Tell the compiler about dynamically scoped variables, +;; and variables from other packages +(defvar zmacs-regions) ; XEmacs regions +(defvar original-date) ; dynamically scoped in calendar +(defvar org-old-auto-fill-inhibit-regexp) ; local variable used by `orgtbl-mode' +(defvar orgtbl-mode-menu) ; defined when orgtbl mode get initialized +(defvar org-html-entities) ; defined later in this file +(defvar org-goto-start-pos) ; dynamically scoped parameter +(defvar org-time-was-given) ; dynamically scoped parameter +(defvar org-ts-what) ; dynamically scoped parameter +(defvar mark-active) ; Emacs only, not available in XEmacs. +(defvar timecnt) ; dynamically scoped parameter +(defvar levels-open) ; dynamically scoped parameter +(defvar title) ; dynamically scoped parameter +(defvar author) ; dynamically scoped parameter +(defvar email) ; dynamically scoped parameter +(defvar text) ; dynamically scoped parameter +(defvar entry) ; dynamically scoped parameter +(defvar date) ; dynamically scoped parameter +(defvar language) ; dynamically scoped parameter +(defvar options) ; dynamically scoped parameter +(defvar ans1) ; dynamically scoped parameter +(defvar ans2) ; dynamically scoped parameter +(defvar starting-day) ; local variable +(defvar include-all-loc) ; local variable +(defvar vm-message-pointer) ; from vm +(defvar vm-folder-directory) ; from vm +(defvar wl-summary-buffer-elmo-folder) ; from wanderlust +(defvar wl-summary-buffer-folder-name) ; from wanderlust +(defvar gnus-group-name) ; from gnus +(defvar gnus-article-current) ; from gnus +(defvar w3m-current-url) ; from w3m +(defvar mh-progs) ; from MH-E +(defvar mh-current-folder) ; from MH-E +(defvar mh-show-folder-buffer) ; from MH-E +(defvar mh-index-folder) ; from MH-E +(defvar mh-searcher) ; from MH-E +(defvar org-selected-point) ; dynamically scoped parameter +(defvar calendar-mode-map) ; from calendar.el +(defvar last-arg) ; local variable +(defvar remember-save-after-remembering) ; from remember.el +(defvar remember-data-file) ; from remember.el +(defvar annotation) ; from remember.el, dynamically scoped in `remember-mode' +(defvar initial) ; from remember.el, dynamically scoped in `remember-mode' + +;;; Define the mode + +(defvar org-mode-map (copy-keymap outline-mode-map) + "Keymap for Org-mode.") + +(defvar org-struct-menu) ; defined later in this file +(defvar org-org-menu) ; defined later in this file +(defvar org-tbl-menu) ; defined later in this file + +;; We use a before-change function to check if a table might need +;; an update. +(defvar org-table-may-need-update t + "Indicates that a table might need an update. +This variable is set by `org-before-change-function'. +`org-table-align' sets it back to nil.") +(defvar org-mode-hook nil) +(defvar org-inhibit-startup nil) ; Dynamically-scoped param. +(defvar org-agenda-keep-modes nil) ; Dynamically-scoped param. + + +;;;###autoload +(define-derived-mode org-mode outline-mode "Org" + "Outline-based notes management and organizer, alias +\"Carsten's outline-mode for keeping track of everything.\" + +Org-mode develops organizational tasks around a NOTES file which +contains information about projects as plain text. Org-mode is +implemented on top of outline-mode, which is ideal to keep the content +of large files well structured. It supports ToDo items, deadlines and +time stamps, which magically appear in the diary listing of the Emacs +calendar. Tables are easily created with a built-in table editor. +Plain text URL-like links connect to websites, emails (VM), Usenet +messages (Gnus), BBDB entries, and any files related to the project. +For printing and sharing of notes, an Org-mode file (or a part of it) +can be exported as a structured ASCII or HTML file. + +The following commands are available: + +\\{org-mode-map}" + (easy-menu-add org-org-menu) + (easy-menu-add org-tbl-menu) + (org-install-agenda-files-menu) + (setq outline-regexp "\\*+") +; (setq outline-regexp "\\(?:\\*+\\|[ \t]*\\(?:[-+*]\\|[0-9]+[.)]\\) \\)") + (setq outline-level 'org-outline-level) + (if org-startup-truncated (setq truncate-lines t)) + (org-set-regexps-and-options) + (set (make-local-variable 'font-lock-unfontify-region-function) + 'org-unfontify-region) + ;; Activate before-change-function + (set (make-local-variable 'org-table-may-need-update) t) + (org-add-hook 'before-change-functions 'org-before-change-function nil + 'local) + ;; Paragraphs and auto-filling + (org-set-autofill-regexps) + (org-update-radio-target-regexp) + ;; Settings for Calc embedded mode + (set (make-local-variable 'calc-embedded-open-formula) "|\\|\n") + (set (make-local-variable 'calc-embedded-close-formula) "|\\|\n") + (if (and org-insert-mode-line-in-empty-file + (interactive-p) + (= (point-min) (point-max))) + (insert " -*- mode: org -*-\n\n")) + + ;; Get rid of Outline menus, they are not needed + ;; Need to do this here because define-derived-mode sets up + ;; the keymap so late. + (if org-xemacs-p + (progn + (delete-menu-item '("Headings")) + (delete-menu-item '("Show")) + (delete-menu-item '("Hide")) + (set-menubar-dirty-flag)) + (define-key org-mode-map [menu-bar headings] 'undefined) + (define-key org-mode-map [menu-bar hide] 'undefined) + (define-key org-mode-map [menu-bar show] 'undefined)) + + (unless org-inhibit-startup + (if org-startup-with-deadline-check + (call-interactively 'org-check-deadlines) + (cond + ((eq org-startup-folded t) + (org-cycle '(4))) + ((eq org-startup-folded 'content) + (let ((this-command 'org-cycle) (last-command 'org-cycle)) + (org-cycle '(4)) (org-cycle '(4)))))))) + +(defsubst org-current-line (&optional pos) + (+ (if (bolp) 1 0) (count-lines (point-min) (or pos (point))))) + +(defun org-current-time () + "Current time, possibly rounded to `org-time-stamp-rounding-minutes'." + (if (> org-time-stamp-rounding-minutes 0) + (let ((r org-time-stamp-rounding-minutes) + (time (decode-time))) + (apply 'encode-time + (append (list 0 (* r (floor (+ .5 (/ (float (nth 1 time)) r))))) + (nthcdr 2 time)))) + (current-time))) + +;; FIXME: Do we need to copy? +(defun org-string-props (string &rest properties) + "Add PROPERTIES to string." + (add-text-properties 0 (length string) properties string) + string) + +;;; Font-Lock stuff + +(defvar org-mouse-map (make-sparse-keymap)) +(define-key org-mouse-map + (if org-xemacs-p [button2] [mouse-2]) 'org-open-at-mouse) +(define-key org-mouse-map + (if org-xemacs-p [button3] [mouse-3]) 'org-find-file-at-mouse) +(define-key org-mouse-map [follow-link] 'mouse-face) +(when org-tab-follows-link + (define-key org-mouse-map [(tab)] 'org-open-at-point) + (define-key org-mouse-map "\C-i" 'org-open-at-point)) +(when org-return-follows-link + (define-key org-mouse-map [(return)] 'org-open-at-point) + (define-key org-mouse-map "\C-m" 'org-open-at-point)) + +(require 'font-lock) + +(defconst org-non-link-chars "\t\n\r|<>\000") +(defconst org-link-regexp + (if org-allow-space-in-links + (concat + "\\(https?\\|ftp\\|mailto\\|file\\|news\\|bbdb\\|vm\\|wl\\|mhe\\|rmail\\|gnus\\|shell\\):\\([^" org-non-link-chars "]+[^ " org-non-link-chars "]\\)") + (concat + "\\(https?\\|ftp\\|mailto\\|file\\|news\\|bbdb\\|vm\\|wl\\|mhe\\|rmail\\|gnus\\|shell\\):\\([^ " org-non-link-chars "]+\\)") + ) + "Regular expression for matching links.") +(defconst org-link-maybe-angles-regexp + (concat "?") + "Matches a link and optionally surrounding angle brackets.") +(defconst org-protected-link-regexp + (concat "\000" org-link-regexp "\000") + "Matches a link and optionally surrounding angle brackets.") + +(defconst org-bracket-link-regexp + "\\[\\[\\([^]]+\\)\\]\\(\\[\\([^]]+\\)\\]\\)?\\]" + "Matches a link in double brackets.") + +(defconst org-ts-lengths + (cons (length (format-time-string (car org-time-stamp-formats))) + (length (format-time-string (cdr org-time-stamp-formats)))) + "This holds the lengths of the two different time formats.") +(defconst org-ts-regexp "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}[^\r\n>]*?\\)>" + "Regular expression for fast time stamp matching.") +(defconst org-ts-regexp-both "[[<]\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}[^\r\n>]*?\\)[]>]" + "Regular expression for fast time stamp matching.") +(defconst org-ts-regexp1 "\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\)\\([^0-9>\r\n]*\\)\\(\\([0-9]\\{2\\}\\):\\([0-9]\\{2\\}\\)\\)?\\)" + "Regular expression matching time strings for analysis.") +(defconst org-ts-regexp2 (concat "<" org-ts-regexp1 ">") + "Regular expression matching time stamps, with groups.") +(defconst org-tr-regexp (concat org-ts-regexp "--?-?" org-ts-regexp) + "Regular expression matching a time stamp range.") +(defconst org-tsr-regexp (concat org-ts-regexp "\\(--?-?" + org-ts-regexp "\\)?") + "Regular expression matching a time stamp or time stamp range.") + +(defun org-activate-links (limit) + "Run through the buffer and add overlays to links." + (if (re-search-forward org-link-regexp limit t) + (progn + (add-text-properties (match-beginning 0) (match-end 0) + (list 'mouse-face 'highlight + 'keymap org-mouse-map)) + t))) + +(defun org-activate-links2 (limit) + "Run through the buffer and add overlays to links." + (if (re-search-forward org-bracket-link-regexp limit t) + (progn + (add-text-properties (match-beginning 0) (match-end 0) + (list 'mouse-face 'highlight + 'keymap org-mouse-map)) + t))) + +(defun org-activate-dates (limit) + "Run through the buffer and add overlays to dates." + (if (re-search-forward org-tsr-regexp limit t) + (progn + (add-text-properties (match-beginning 0) (match-end 0) + (list 'mouse-face 'highlight + 'keymap org-mouse-map)) + t))) + +(defvar org-target-link-regexp nil + "Regular expression matching radio targets in plain text.") +(defvar org-target-regexp "<<\\([^<>\n\r]+\\)>>" + "Regular expression matching a link target.") +(defvar org-radio-target-regexp "<<<\\([^<>\n\r]+\\)>>>" + "Regular expression matching a link target.") + +(defun org-activate-target-links (limit) + "Run through the buffer and add overlays to target matches." + (when (and org-radio-targets org-target-link-regexp) + (let ((case-fold-search t)) + (if (re-search-forward org-target-link-regexp limit t) + (progn + (add-text-properties (match-beginning 0) (match-end 0) + (list 'mouse-face 'highlight + 'keymap org-mouse-map + 'org-linked-text t)) + t))))) + +(defun org-update-radio-target-regexp () + "Find all radio targets in this file and update the regular expression." + (interactive) + (when org-radio-targets + (setq org-target-link-regexp + (org-make-target-link-regexp (org-all-targets 'radio))) + (font-lock-mode -1) + (font-lock-mode 1))) + +(defun org-all-targets (&optional radio) + "Return a list of all targets in this file. +With optional argument RADIO, only find radio targets." + (let ((re (if radio org-radio-target-regexp org-target-regexp)) + rtn) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward re nil t) + (add-to-list 'rtn (downcase + (if (fboundp 'match-string-no-properties) + (match-string-no-properties 1) + (match-string 1))))) + rtn))) + +(defun org-make-target-link-regexp (targets) + "Make regular expression matching all strings in TARGETS. +The regular expression finds the targets also if there is a line break +between words." + (and targets + (concat + "\\<\\(" + (mapconcat + (lambda (x) + (while (string-match " +" x) + (setq x (replace-match "\\s-+" t t x))) + x) + targets + "\\|") + "\\)\\>"))) + +(defvar org-camel-regexp "\\*?\\<[A-Z]+[a-z]+[A-Z][a-zA-Z]*\\>" + "Matches CamelCase words, possibly with a star before it.") + +(defun org-activate-camels (limit) + "Run through the buffer and add overlays to dates." + (if org-activate-camels + (if (re-search-forward org-camel-regexp limit t) + (progn + (add-text-properties (match-beginning 0) (match-end 0) + (list 'mouse-face 'highlight + 'keymap org-mouse-map)) + t)))) + +(defun org-activate-tags (limit) + (if (re-search-forward "[ \t]\\(:[A-Za-z_@0-9:]+:\\)[ \r\n]" limit t) + (progn + (add-text-properties (match-beginning 1) (match-end 1) + (list 'mouse-face 'highlight + 'keymap org-mouse-map)) + t))) + +(defun org-font-lock-level () + (save-excursion + (org-back-to-heading t) + (- (match-end 0) (match-beginning 0)))) + +(defun org-outline-level () + (save-excursion + (looking-at outline-regexp) + (if (match-beginning 1) + (+ (org-get-string-indentation (match-string 1)) 1000) + (- (match-end 0) (match-beginning 0))))) + +(defvar org-font-lock-keywords nil) + +(defun org-set-font-lock-defaults () + (let* ((em org-fontify-emphasized-text) + (org-font-lock-extra-keywords + (list + '("^\\(\\**\\)\\(\\*\\)\\(.*\\)" (1 (org-get-level-face 1)) + (2 (org-get-level-face 2)) (3 (org-get-level-face 3))) + '(org-activate-links (0 'org-link t)) + '(org-activate-links2 (0 'org-link t)) + '(org-activate-target-links (0 'org-link t)) + '(org-activate-dates (0 'org-link t)) + '(org-activate-camels (0 'org-link t)) + '(org-activate-tags (1 'org-tag t)) + (list (concat "^\\*+[ \t]*" org-not-done-regexp) + '(1 'org-warning t)) + (list (concat "\\[#[A-Z]\\]") '(0 'org-special-keyword t)) + (list (concat "\\<" org-deadline-string) '(0 'org-special-keyword t)) + (list (concat "\\<" org-scheduled-string) '(0 'org-special-keyword t)) + (list (concat "\\<" org-closed-string) '(0 'org-special-keyword t)) + (if em '("\\(\\W\\|^\\)\\(\\*\\w+\\*\\)\\(\\W\\|$\\)" 2 'bold)) + (if em '("\\(\\W\\|^\\)\\(/\\w+/\\)\\(\\W\\|$\\)" 2 'italic)) + (if em '("\\(\\W\\|^\\)\\(_\\w+_\\)\\(\\W\\|$\\)" 2 'underline)) + (list (concat "^\\*+[ \t]*\\<\\(" org-comment-string + "\\|" org-quote-string "\\)\\>") + '(1 'org-special-keyword t)) + '("^#.*" (0 'font-lock-comment-face t)) + (if org-fontify-done-headline + (list (concat "^[*]+ +\\<\\(" org-done-string "\\)\\(.*\\)\\>") + '(1 'org-done t) '(2 'org-headline-done t)) + (list (concat "^[*]+ +\\<\\(" org-done-string "\\)\\>") + '(1 'org-done t))) + '("^[ \t]*\\(\\(|\\|\\+-[-+]\\).*\\S-\\)" + (1 'org-table t)) + '("^[ \t]*\\(:.*\\)" (1 'org-table t)) + '("| *\\(:?=[^|\n]*\\)" (1 'org-formula t)) + '("^[ \t]*| *\\([#!$*_^]\\) *|" (1 'org-formula t)) + ))) + (setq org-font-lock-extra-keywords (delq nil org-font-lock-extra-keywords)) + ;; Now set the full font-lock-keywords + (set (make-local-variable 'org-font-lock-keywords) + org-font-lock-extra-keywords) + (set (make-local-variable 'font-lock-defaults) + '(org-font-lock-keywords t nil nil backward-paragraph)) + (kill-local-variable 'font-lock-keywords) nil)) + +(defvar org-m nil) +(defvar org-l nil) +(defvar org-f nil) +(defun org-get-level-face (n) + "Get the right face for match N in font-lock matching of healdines." + (setq org-l (- (match-end 2) (match-beginning 1))) + (if org-odd-levels-only (setq org-l (1+ (/ org-l 2)))) + (setq org-f (nth (1- (% org-l org-n-levels)) org-level-faces)) + (cond + ((eq n 1) (if org-hide-leading-stars 'org-hide org-f)) + ((eq n 2) org-f) + (t (if org-level-color-stars-only nil org-f)))) + +(defun org-unfontify-region (beg end &optional maybe_loudly) + "Remove fontification and activation overlays from links." + (font-lock-default-unfontify-region beg end) + (let* ((buffer-undo-list t) + (inhibit-read-only t) (inhibit-point-motion-hooks t) + (inhibit-modification-hooks t) + deactivate-mark buffer-file-name buffer-file-truename) + (remove-text-properties beg end + '(mouse-face nil keymap nil org-linked-text nil)))) + +;;; Visibility cycling + +(defvar org-cycle-global-status nil) +(defvar org-cycle-subtree-status nil) +(defun org-cycle (&optional arg) + "Visibility cycling for Org-mode. + +- When this function is called with a prefix argument, rotate the entire + buffer through 3 states (global cycling) + 1. OVERVIEW: Show only top-level headlines. + 2. CONTENTS: Show all headlines of all levels, but no body text. + 3. SHOW ALL: Show everything. + +- When point is at the beginning of a headline, rotate the subtree started + by this line through 3 different states (local cycling) + 1. FOLDED: Only the main headline is shown. + 2. CHILDREN: The main headline and the direct children are shown. + From this state, you can move to one of the children + and zoom in further. + 3. SUBTREE: Show the entire subtree, including body text. + +- When there is a numeric prefix, go up to a heading with level ARG, do + a `show-subtree' and return to the previous cursor position. If ARG + is negative, go up that many levels. + +- When point is not at the beginning of a headline, execute + `indent-relative', like TAB normally does. See the option + `org-cycle-emulate-tab' for details. + +- Special case: if point is the the beginning of the buffer and there is + no headline in line 1, this function will act as if called with prefix arg." + (interactive "P") + + (if (or (and (bobp) (not (looking-at outline-regexp))) + (equal arg '(4))) + ;; special case: use global cycling + (setq arg t)) + + (let ((outline-regexp + (if org-cycle-include-plain-lists + "\\*+\\|\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) " + outline-regexp))) + + (cond + + ((org-at-table-p 'any) + ;; Enter the table or move to the next field in the table + (or (org-table-recognize-table.el) + (progn + (org-table-justify-field-maybe) + (org-table-next-field)))) + + ((eq arg t) ;; Global cycling + + (cond + ((and (eq last-command this-command) + (eq org-cycle-global-status 'overview)) + ;; We just created the overview - now do table of contents + ;; This can be slow in very large buffers, so indicate action + (message "CONTENTS...") + (save-excursion + ;; Visit all headings and show their offspring + (goto-char (point-max)) + (catch 'exit + (while (and (progn (condition-case nil + (outline-previous-visible-heading 1) + (error (goto-char (point-min)))) + t) + (looking-at outline-regexp)) + (show-branches) + (if (bobp) (throw 'exit nil)))) + (message "CONTENTS...done")) + (setq org-cycle-global-status 'contents) + (run-hook-with-args 'org-cycle-hook 'contents)) + + ((and (eq last-command this-command) + (eq org-cycle-global-status 'contents)) + ;; We just showed the table of contents - now show everything + (show-all) + (message "SHOW ALL") + (setq org-cycle-global-status 'all) + (run-hook-with-args 'org-cycle-hook 'all)) + + (t + ;; Default action: go to overview + (hide-sublevels 1) + (message "OVERVIEW") + (setq org-cycle-global-status 'overview) + (run-hook-with-args 'org-cycle-hook 'overview)))) + + ((integerp arg) + ;; Show-subtree, ARG levels up from here. + (save-excursion + (org-back-to-heading) + (outline-up-heading (if (< arg 0) (- arg) + (- (funcall outline-level) arg))) + (org-show-subtree))) + + ((save-excursion (beginning-of-line 1) (looking-at outline-regexp)) + ;; At a heading: rotate between three different views + (org-back-to-heading) + (let ((goal-column 0) eoh eol eos) + ;; First, some boundaries + (save-excursion + (org-back-to-heading) + (save-excursion + (beginning-of-line 2) + (while (and (not (eobp)) ;; this is like `next-line' + (get-char-property (1- (point)) 'invisible)) + (beginning-of-line 2)) (setq eol (point))) + (outline-end-of-heading) (setq eoh (point)) + (org-end-of-subtree t) (setq eos (point)) + (outline-next-heading)) + ;; Find out what to do next and set `this-command' + (cond + ((= eos eoh) + ;; Nothing is hidden behind this heading + (message "EMPTY ENTRY") + (setq org-cycle-subtree-status nil)) + ((>= eol eos) + ;; Entire subtree is hidden in one line: open it + (org-show-entry) + (show-children) + (message "CHILDREN") + (setq org-cycle-subtree-status 'children) + (run-hook-with-args 'org-cycle-hook 'children)) + ((and (eq last-command this-command) + (eq org-cycle-subtree-status 'children)) + ;; We just showed the children, now show everything. + (org-show-subtree) + (message "SUBTREE") + (setq org-cycle-subtree-status 'subtree) + (run-hook-with-args 'org-cycle-hook 'subtree)) + (t + ;; Default action: hide the subtree. + (hide-subtree) + (message "FOLDED") + (setq org-cycle-subtree-status 'folded) + (run-hook-with-args 'org-cycle-hook 'folded))))) + + ;; TAB emulation + (buffer-read-only (org-back-to-heading)) + ((if (and (eq org-cycle-emulate-tab 'white) + (save-excursion (beginning-of-line 1) (looking-at "[ \t]+$"))) + t + (eq org-cycle-emulate-tab t)) + (if (and (looking-at "[ \n\r\t]") + (string-match "^[ \t]*$" (buffer-substring + (point-at-bol) (point)))) + (progn + (beginning-of-line 1) + (and (looking-at "[ \t]+") (replace-match "")))) + (indent-relative)) + + (t (save-excursion + (org-back-to-heading) + (org-cycle)))))) + +(defun org-optimize-window-after-visibility-change (state) + "Adjust the window after a change in outline visibility. +This function is the default value of the hook `org-cycle-hook'." + (cond + ((eq state 'overview) (org-first-headline-recenter 1)) + ((eq state 'content) nil) + ((eq state 'all) nil) + ((eq state 'folded) nil) + ((eq state 'children) (or (org-subtree-end-visible-p) (recenter 1))) + ((eq state 'subtree) (or (org-subtree-end-visible-p) (recenter 1))))) + +(defun org-subtree-end-visible-p () + "Is the end of the current subtree visible?" + (pos-visible-in-window-p + (save-excursion (org-end-of-subtree t) (point)))) + +(defun org-first-headline-recenter (&optional N) + "Move cursor to the first headline and recenter the headline. +Optional argument N means, put the headline into the Nth line of the window." + (goto-char (point-min)) + (when (re-search-forward (concat "^" outline-regexp) nil t) + (beginning-of-line) + (recenter (prefix-numeric-value N)))) + +(defvar org-goto-window-configuration nil) +(defvar org-goto-marker nil) +(defvar org-goto-map (make-sparse-keymap)) +(let ((cmds '(isearch-forward isearch-backward)) cmd) + (while (setq cmd (pop cmds)) + (substitute-key-definition cmd cmd org-goto-map global-map))) +(define-key org-goto-map "\C-m" 'org-goto-ret) +(define-key org-goto-map [(left)] 'org-goto-left) +(define-key org-goto-map [(right)] 'org-goto-right) +(define-key org-goto-map [(?q)] 'org-goto-quit) +(define-key org-goto-map [(control ?g)] 'org-goto-quit) +(define-key org-goto-map "\C-i" 'org-cycle) +(define-key org-goto-map [(tab)] 'org-cycle) +(define-key org-goto-map [(down)] 'outline-next-visible-heading) +(define-key org-goto-map [(up)] 'outline-previous-visible-heading) +(define-key org-goto-map "n" 'outline-next-visible-heading) +(define-key org-goto-map "p" 'outline-previous-visible-heading) +(define-key org-goto-map "f" 'outline-forward-same-level) +(define-key org-goto-map "b" 'outline-backward-same-level) +(define-key org-goto-map "u" 'outline-up-heading) +(define-key org-goto-map "\C-c\C-n" 'outline-next-visible-heading) +(define-key org-goto-map "\C-c\C-p" 'outline-previous-visible-heading) +(define-key org-goto-map "\C-c\C-f" 'outline-forward-same-level) +(define-key org-goto-map "\C-c\C-b" 'outline-backward-same-level) +(define-key org-goto-map "\C-c\C-u" 'outline-up-heading) +(let ((l '(1 2 3 4 5 6 7 8 9 0))) + (while l (define-key org-goto-map (int-to-string (pop l)) 'digit-argument))) + +(defconst org-goto-help +"Select a location to jump to, press RET +\[Up]/[Down]=next/prev headline TAB=cycle visibility RET=select [Q]uit") + +(defun org-goto () + "Go to a different location of the document, keeping current visibility. + +When you want to go to a different location in a document, the fastest way +is often to fold the entire buffer and then dive into the tree. This +method has the disadvantage, that the previous location will be folded, +which may not be what you want. + +This command works around this by showing a copy of the current buffer in +overview mode. You can dive into the tree in that copy, to find the +location you want to reach. When pressing RET, the command returns to the +original buffer in which the visibility is still unchanged. It then jumps +to the new location, making it and the headline hierarchy above it visible." + (interactive) + (let* ((org-goto-start-pos (point)) + (selected-point + (org-get-location (current-buffer) org-goto-help))) + (if selected-point + (progn + (org-mark-ring-push org-goto-start-pos) + (goto-char selected-point) + (if (or (org-invisible-p) (org-invisible-p2)) + (org-show-hierarchy-above))) + (error "Quit")))) + +(defun org-get-location (buf help) + "Let the user select a location in the Org-mode buffer BUF. +This function uses a recursive edit. It returns the selected position +or nil." + (let (org-selected-point) + (save-excursion + (save-window-excursion + (delete-other-windows) + (switch-to-buffer (get-buffer-create "*org-goto*")) + (with-output-to-temp-buffer "*Help*" + (princ help)) + (shrink-window-if-larger-than-buffer (get-buffer-window "*Help*")) + (setq buffer-read-only nil) + (erase-buffer) + (insert-buffer-substring buf) + (let ((org-startup-truncated t) + (org-startup-folded t) + (org-startup-with-deadline-check nil)) + (org-mode)) + (setq buffer-read-only t) + (if (boundp 'org-goto-start-pos) + (goto-char org-goto-start-pos) + (goto-char (point-min))) + (org-beginning-of-line) + (message "Select location and press RET") + ;; now we make sure that during selection, ony very few keys work + ;; and that it is impossible to switch to another window. + (let ((gm (current-global-map)) + (overriding-local-map org-goto-map)) + (unwind-protect + (progn + (use-global-map org-goto-map) + (recursive-edit)) + (use-global-map gm))))) + (kill-buffer "*org-goto*") + org-selected-point)) + +;; FIXME: It may not be a good idea to temper with the prefix argument... +(defun org-goto-ret (&optional arg) + "Finish `org-goto' by going to the new location." + (interactive "P") + (setq org-selected-point (point) + current-prefix-arg arg) + (throw 'exit nil)) + +(defun org-goto-left () + "Finish `org-goto' by going to the new location." + (interactive) + (if (org-on-heading-p) + (progn + (beginning-of-line 1) + (setq org-selected-point (point) + current-prefix-arg (- (match-end 0) (match-beginning 0))) + (throw 'exit nil)) + (error "Not on a heading"))) + +(defun org-goto-right () + "Finish `org-goto' by going to the new location." + (interactive) + (if (org-on-heading-p) + (progn + (outline-end-of-subtree) + (or (eobp) (forward-char 1)) + (setq org-selected-point (point) + current-prefix-arg (- (match-end 0) (match-beginning 0))) + (throw 'exit nil)) + (error "Not on a heading"))) + +(defun org-goto-quit () + "Finish `org-goto' without cursor motion." + (interactive) + (setq org-selected-point nil) + (throw 'exit nil)) + +;;; Promotion, Demotion, Inserting new headlines + +(defvar org-ignore-region nil + "To temporarily disable the active region.") + +(defun org-insert-heading (&optional force-heading) + "Insert a new heading or item with same depth at point." + (interactive "P") + (when (or force-heading (not (org-insert-item))) + (let* ((head (save-excursion + (condition-case nil + (org-back-to-heading) + (error (outline-next-heading))) + (prog1 (match-string 0) + (funcall outline-level))))) + (unless (bolp) (newline)) + (insert head) + (unless (eolp) + (save-excursion (newline-and-indent))) + (unless (equal (char-before) ?\ ) + (insert " ")) + (run-hooks 'org-insert-heading-hook)))) + +(defun org-insert-item () + "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) + t) + (error nil))) + (unless (bolp) (newline)) + (insert (match-string 0)) + (org-maybe-renumber-ordered-list) + t)) + +(defun org-insert-todo-heading (arg) + "Insert a new heading with the same level and TODO state as current heading. +If the heading has no TODO state, or if the state is DONE, use the first +state (TODO by default). Also with prefix arg, force first state." + (interactive "P") + (org-insert-heading) + (save-excursion + (org-back-to-heading) + (outline-previous-heading) + (looking-at org-todo-line-regexp)) + (if (or arg + (not (match-beginning 2)) + (equal (match-string 2) org-done-string)) + (insert (car org-todo-keywords) " ") + (insert (match-string 2) " "))) + +(defun org-promote-subtree () + "Promote the entire subtree. +See also `org-promote'." + (interactive) + (save-excursion + (org-map-tree 'org-promote))) + +(defun org-demote-subtree () + "Demote the entire subtree. See `org-demote'. +See also `org-promote'." + (interactive) + (save-excursion + (org-map-tree 'org-demote))) + +(defun org-do-promote () + "Promote the current heading higher up the tree. +If the region is active in `transient-mark-mode', promote all headings +in the region." + (interactive) + (save-excursion + (if (org-region-active-p) + (org-map-region 'org-promote (region-beginning) (region-end)) + (org-promote))) + (org-fix-position-after-promote)) + +(defun org-do-demote () + "Demote the current heading lower down the tree. +If the region is active in `transient-mark-mode', demote all headings +in the region." + (interactive) + (save-excursion + (if (org-region-active-p) + (org-map-region 'org-demote (region-beginning) (region-end)) + (org-demote))) + (org-fix-position-after-promote)) + +(defun org-fix-position-after-promote () + "Make sure that after pro/demotion cursor position is right." + (and (equal (char-after) ?\ ) + (equal (char-before) ?*) + (forward-char 1))) + +(defun org-get-legal-level (level change) + "Rectify a level change under the influence of `org-odd-levels-only' +LEVEL is a current level, CHANGE is by how much the level should be +modified. Even if CHANGE is nil, LEVEL may be returned modified because +even level numbers will become the next higher odd number." + (if org-odd-levels-only + (cond ((not change) (1+ (* 2 (/ level 2)))) + ((> change 0) (1+ (* 2 (/ (+ level (* 2 change)) 2)))) + ((< change 0) (max 1 (1+ (* 2 (/ (+ level (* 2 change)) 2)))))) + (max 1 (+ level change)))) + +(defun org-promote () + "Promote the current heading higher up the tree. +If the region is active in `transient-mark-mode', promote all headings +in the region." + (org-back-to-heading t) + (let* ((level (save-match-data (funcall outline-level))) + (up-head (make-string (org-get-legal-level level -1) ?*)) + (diff (abs (- level (length up-head))))) + (if (= level 1) (error "Cannot promote to level 0. UNDO to recover")) + (replace-match up-head nil t) + ;; Fixup tag positioning + (and org-auto-align-tags (org-set-tags nil t)) + (if org-adapt-indentation + (org-fixup-indentation (if (> diff 1) "^ " "^ ") "" + (if (> diff 1) "^ ? ?\\S-" "^ ?\\S-"))))) + +(defun org-demote () + "Demote the current heading lower down the tree. +If the region is active in `transient-mark-mode', demote all headings +in the region." + (org-back-to-heading t) + (let* ((level (save-match-data (funcall outline-level))) + (down-head (make-string (org-get-legal-level level 1) ?*)) + (diff (abs (- level (length down-head))))) + (replace-match down-head nil t) + ;; Fixup tag positioning + (and org-auto-align-tags (org-set-tags nil t)) + (if org-adapt-indentation + (org-fixup-indentation "^ " (if (> diff 1) " " " ") "^\\S-")))) + +(defun org-map-tree (fun) + "Call FUN for every heading underneath the current one." + (org-back-to-heading) + (let ((level (funcall outline-level))) + (save-excursion + (funcall fun) + (while (and (progn + (outline-next-heading) + (> (funcall outline-level) level)) + (not (eobp))) + (funcall fun))))) + +(defun org-map-region (fun beg end) + "Call FUN for every heading between BEG and END." + (let ((org-ignore-region t)) + (save-excursion + (setq end (copy-marker end)) + (goto-char beg) + (if (and (re-search-forward (concat "^" outline-regexp) nil t) + (< (point) end)) + (funcall fun)) + (while (and (progn + (outline-next-heading) + (< (point) end)) + (not (eobp))) + (funcall fun))))) + +(defun org-fixup-indentation (from to prohibit) + "Change the indentation in the current entry by re-replacing FROM with TO. +However, if the regexp PROHIBIT matches at all, don't do anything. +This is being used to change indentation along with the length of the +heading marker. But if there are any lines which are not indented, nothing +is changed at all." + (save-excursion + (let ((end (save-excursion (outline-next-heading) + (point-marker)))) + (unless (save-excursion (re-search-forward prohibit end t)) + (while (re-search-forward from end t) + (replace-match to) + (beginning-of-line 2))) + (move-marker end nil)))) + +;;; Vertical tree motion, cutting and pasting of subtrees + +(defun org-move-subtree-up (&optional arg) + "Move the current subtree up past ARG headlines of the same level." + (interactive "p") + (org-move-subtree-down (- (prefix-numeric-value arg)))) + +(defun org-move-subtree-down (&optional arg) + "Move the current subtree down past ARG headlines of the same level." + (interactive "p") + (setq arg (prefix-numeric-value arg)) + (let ((movfunc (if (> arg 0) 'outline-get-next-sibling + 'outline-get-last-sibling)) + (ins-point (make-marker)) + (cnt (abs arg)) + beg end txt folded) + ;; Select the tree + (org-back-to-heading) + (setq beg (point)) + (save-match-data + (save-excursion (outline-end-of-heading) + (setq folded (org-invisible-p))) + (outline-end-of-subtree)) + (outline-next-heading) + (setq end (point)) + ;; Find insertion point, with error handling + (goto-char beg) + (while (> cnt 0) + (or (and (funcall movfunc) (looking-at outline-regexp)) + (progn (goto-char beg) + (error "Cannot move past superior level or buffer limit"))) + (setq cnt (1- cnt))) + (if (> arg 0) + ;; Moving forward - still need to move over subtree + (progn (outline-end-of-subtree) + (outline-next-heading) + (if (not (or (looking-at (concat "^" outline-regexp)) + (bolp))) + (newline)))) + (move-marker ins-point (point)) + (setq txt (buffer-substring beg end)) + (delete-region beg end) + (insert txt) + (goto-char ins-point) + (if folded (hide-subtree)) + (move-marker ins-point nil))) + +(defvar org-subtree-clip "" + "Clipboard for cut and paste of subtrees. +This is actually only a copy of the kill, because we use the normal kill +ring. We need it to check if the kill was created by `org-copy-subtree'.") + +(defvar org-subtree-clip-folded nil + "Was the last copied subtree folded? +This is used to fold the tree back after pasting.") + +(defun org-cut-subtree () + "Cut the current subtree into the clipboard. +This is a short-hand for marking the subtree and then cutting it." + (interactive) + (org-copy-subtree 'cut)) + +(defun org-copy-subtree (&optional cut) + "Cut the current subtree into the clipboard. +This is a short-hand for marking the subtree and then copying it. +If CUT is non nil, actually cut the subtree." + (interactive) + (let (beg end folded) + (org-back-to-heading) + (setq beg (point)) + (save-match-data + (save-excursion (outline-end-of-heading) + (setq folded (org-invisible-p))) + (outline-end-of-subtree)) + (if (equal (char-after) ?\n) (forward-char 1)) + (setq end (point)) + (goto-char beg) + (when (> end beg) + (setq org-subtree-clip-folded folded) + (if cut (kill-region beg end) (copy-region-as-kill beg end)) + (setq org-subtree-clip (current-kill 0)) + (message "%s: Subtree with %d characters" + (if cut "Cut" "Copied") + (length org-subtree-clip))))) + +(defun org-paste-subtree (&optional level tree) + "Paste the clipboard as a subtree, with modification of headline level. +The entire subtree is promoted or demoted in order to match a new headline +level. By default, the new level is derived from the visible headings +before and after the insertion point, and taken to be the inferior headline +level of the two. So if the previous visible heading is level 3 and the +next is level 4 (or vice versa), level 4 will be used for insertion. +This makes sure that the subtree remains an independent subtree and does +not swallow low level entries. + +You can also force a different level, either by using a numeric prefix +argument, or by inserting the heading marker by hand. For example, if the +cursor is after \"*****\", then the tree will be shifted to level 5. + +If you want to insert the tree as is, just use \\[yank]. + +If optional TREE is given, use this text instead of the kill ring." + (interactive "P") + (unless (org-kill-is-subtree-p tree) + (error + (substitute-command-keys + "The kill is not a (set of) tree(s) - please use \\[yank] to yank anyway"))) + (let* ((txt (or tree (current-kill 0))) + (^re (concat "^\\(" outline-regexp "\\)")) + (re (concat "\\(" outline-regexp "\\)")) + (^re_ (concat "\\(" outline-regexp "\\)[ \t]*")) + + (old-level (if (string-match ^re txt) + (- (match-end 0) (match-beginning 0)) + -1)) + (force-level (cond (level (prefix-numeric-value level)) + ((string-match + ^re_ (buffer-substring (point-at-bol) (point))) + (- (match-end 0) (match-beginning 0))) + (t nil))) + (previous-level (save-excursion + (condition-case nil + (progn + (outline-previous-visible-heading 1) + (if (looking-at re) + (- (match-end 0) (match-beginning 0)) + 1)) + (error 1)))) + (next-level (save-excursion + (condition-case nil + (progn + (outline-next-visible-heading 1) + (if (looking-at re) + (- (match-end 0) (match-beginning 0)) + 1)) + (error 1)))) + (new-level (or force-level (max previous-level next-level))) + (shift (if (or (= old-level -1) + (= new-level -1) + (= old-level new-level)) + 0 + (- new-level old-level))) + (shift1 shift) + (delta (if (> shift 0) -1 1)) + (func (if (> shift 0) 'org-demote 'org-promote)) + (org-odd-levels-only nil) + beg end) + ;; Remove the forces level indicator + (if force-level + (delete-region (point-at-bol) (point))) + ;; Make sure we start at the beginning of an empty line + (if (not (bolp)) (insert "\n")) + (if (not (looking-at "[ \t]*$")) + (progn (insert "\n") (backward-char 1))) + ;; Paste + (setq beg (point)) + (insert txt) + (setq end (point)) + (goto-char beg) + ;; Shift if necessary + (if (= shift 0) + (message "Pasted at level %d, without shift" new-level) + (save-restriction + (narrow-to-region beg end) + (while (not (= shift 0)) + (org-map-region func (point-min) (point-max)) + (setq shift (+ delta shift))) + (goto-char (point-min)) + (message "Pasted at level %d, with shift by %d levels" + new-level shift1))) + (if (and (eq org-subtree-clip (current-kill 0)) + org-subtree-clip-folded) + ;; The tree was folded before it was killed/copied + (hide-subtree)))) + +(defun org-kill-is-subtree-p (&optional txt) + "Check if the current kill is an outline subtree, or a set of trees. +Returns nil if kill does not start with a headline, or if the first +headline level is not the largest headline level in the tree. +So this will actually accept several entries of equal levels as well, +which is OK for `org-paste-subtree'. +If optional TXT is given, check this string instead of the current kill." + (let* ((kill (or txt (current-kill 0) "")) + (start-level (and (string-match (concat "\\`" outline-regexp) kill) + (- (match-end 0) (match-beginning 0)))) + (re (concat "^" outline-regexp)) + (start 1)) + (if (not start-level) + nil ;; does not even start with a heading + (catch 'exit + (while (setq start (string-match re kill (1+ start))) + (if (< (- (match-end 0) (match-beginning 0)) start-level) + (throw 'exit nil))) + t)))) + +;;; Plain list items + +(defun org-at-item-p () + "Is point in a line starting a hand-formatted item?" + (let ((llt org-plain-list-ordered-item-terminator)) + (save-excursion + (goto-char (point-at-bol)) + (looking-at + (cond + ((eq llt t) "\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") + ((= llt ?.) "\\([ \t]*\\([-+]\\|\\([0-9]+\\.\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") + ((= llt ?\)) "\\([ \t]*\\([-+]\\|\\([0-9]+)\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") + (t (error "Invalid value of `org-plain-list-ordered-item-terminator'"))))))) + +(defun org-get-indentation () + "Get the indentation of the current line, interpreting tabs." + (save-excursion + (beginning-of-line 1) + (skip-chars-forward " \t") + (current-column))) + +(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." + (let ((pos (point)) + (limit (save-excursion (org-back-to-heading) + (beginning-of-line 2) (point))) + 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 (< (point) limit) (throw 'exit nil)) + (unless (looking-at " \t]*$") + (skip-chars-forward " \t") + (setq ind1 (current-column)) + (if (< ind1 ind) + (throw 'exit (org-at-item-p)))))) + nil + (goto-char pos) + (error "Not in an item"))))) + +(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." + (let ((pos (point)) + (limit (save-excursion (outline-next-heading) (point))) + (ind (save-excursion + (org-beginning-of-item) + (skip-chars-forward " \t") + (current-column))) + ind1) + (if (catch 'exit + (while t + (beginning-of-line 2) + (if (>= (point) limit) (throw 'exit t)) + (unless (looking-at "[ \t]*$") + (skip-chars-forward " \t") + (setq ind1 (current-column)) + (if (<= ind1 ind) (throw 'exit t))))) + (beginning-of-line 1) + (goto-char pos) + (error "Not in an item")))) + +(defun org-move-item-down (arg) + "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 "p") + (let (beg end ind ind1 (pos (point)) txt) + (org-beginning-of-item) + (setq beg (point)) + (setq ind (org-get-indentation)) + (org-end-of-item) + (setq end (point)) + (setq ind1 (org-get-indentation)) + (if (and (org-at-item-p) (= ind ind1)) + (progn + (org-end-of-item) + (setq txt (buffer-substring beg end)) + (save-excursion + (delete-region beg end)) + (setq pos (point)) + (insert txt) + (goto-char pos) + (org-maybe-renumber-ordered-list)) + (goto-char pos) + (error "Cannot move this item further down")))) + +(defun org-move-item-up (arg) + "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 (beg end ind ind1 (pos (point)) txt) + (org-beginning-of-item) + (setq beg (point)) + (setq ind (org-get-indentation)) + (org-end-of-item) + (setq end (point)) + (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))))) + (condition-case nil + (org-beginning-of-item) + (error (goto-char beg) + (error "Cannot move this item further up"))) + (setq ind1 (org-get-indentation)) + (if (and (org-at-item-p) (= ind ind1)) + (progn + (setq txt (buffer-substring beg end)) + (save-excursion + (delete-region beg end)) + (setq pos (point)) + (insert txt) + (goto-char pos) + (org-maybe-renumber-ordered-list)) + (goto-char pos) + (error "Cannot move this item further up")))) + +(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." + (and org-auto-renumber-ordered-lists + (org-at-item-p) + (match-beginning 3) + (org-renumber-ordered-list 1))) + +(defun org-get-string-indentation (s) + "What indentation has S due to SPACE and TAB at the beginning of the string?" + (let ((n -1) (i 0) (w tab-width) c) + (catch 'exit + (while (< (setq n (1+ n)) (length s)) + (setq c (aref s n)) + (cond ((= c ?\ ) (setq i (1+ i))) + ((= c ?\t) (setq i (* (/ (+ w i) w) w))) + (t (throw 'exit t))))) + i)) + +(defun org-renumber-ordered-list (arg) + "Renumber an ordered plain list. +Cursor next 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))) + ;; find where this list begins + (catch 'exit + (while t + (catch 'next + (beginning-of-line 0) + (if (looking-at "[ \t]*$") (throw 'next t)) + (skip-chars-forward " \t") (setq ind1 (current-column)) + (if (or (< ind1 ind) + (and (= ind1 ind) + (not (org-at-item-p)))) + (throw 'exit t))))) + ;; Walk forward and replace these numbers + (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)) + (if (not (match-beginning 3)) + (error "unordered bullet in ordered list. Press \\[undo] to recover")) + (delete-region (match-beginning 3) (1- (match-end 3))) + (goto-char (match-beginning 3)) + (insert (format "%d" (setq n (1+ n))))))) + (goto-line line) + (move-to-column col))) + +(defvar org-last-indent-begin-marker (make-marker)) +(defvar org-last-indent-end-marker (make-marker)) + +(defun org-outdent-item (arg) + "Outdent a local list item." + (interactive "p") + (org-indent-item (- arg))) + +(defun org-indent-item (arg) + "Indent a local list item." + (interactive "p") + (unless (org-at-item-p) + (error "Not on an item")) + (let (beg end ind ind1) + (if (memq last-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))) + (org-end-of-item) + (setq end (move-marker org-last-indent-end-marker (point)))) + (goto-char beg) + (skip-chars-forward " \t") (setq ind (current-column)) + (if (< (+ arg 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)) + (indent-to-column (+ ind1 arg)) + (beginning-of-line 2)) + (goto-char beg))) + +;;; Archiving + +(defun org-archive-subtree () + "Move the current subtree to the archive. +The archive can be a certain top-level heading in the current file, or in +a different file. The tree will be moved to that location, the subtree +heading be marked DONE, and the current time will be added." + (interactive) + ;; Save all relevant TODO keyword-relatex variables + (let ((tr-org-todo-line-regexp org-todo-line-regexp) ; keep despite compiler + (tr-org-todo-keywords org-todo-keywords) + (tr-org-todo-interpretation org-todo-interpretation) + (tr-org-done-string org-done-string) + (tr-org-todo-regexp org-todo-regexp) + (tr-org-todo-line-regexp org-todo-line-regexp) + (this-buffer (current-buffer)) + file heading buffer level newfile-p) + (if (string-match "\\(.*\\)::\\(.*\\)" org-archive-location) + (progn + (setq file (format (match-string 1 org-archive-location) + (file-name-nondirectory buffer-file-name)) + heading (match-string 2 org-archive-location))) + (error "Invalid `org-archive-location'")) + (if (> (length file) 0) + (setq newfile-p (not (file-exists-p file)) + buffer (find-file-noselect file)) + (setq buffer (current-buffer))) + (unless buffer + (error "Cannot access file \"%s\"" file)) + (if (and (> (length heading) 0) + (string-match "^\\*+" heading)) + (setq level (match-end 0)) + (setq heading nil level 0)) + (save-excursion + ;; We first only copy, in case something goes wrong + ;; we need to protect this-command, to avoid kill-region sets it, + ;; which would lead to duplication of subtrees + (let (this-command) (org-copy-subtree)) + (set-buffer buffer) + ;; Enforce org-mode for the archive buffer + (if (not (eq major-mode 'org-mode)) + ;; Force the mode for future visits. + (let ((org-insert-mode-line-in-empty-file t)) + (call-interactively 'org-mode))) + (when newfile-p + (goto-char (point-max)) + (insert (format "\nArchived entries from file %s\n\n" + (buffer-file-name this-buffer)))) + ;; Force the TODO keywords of the original buffer + (let ((org-todo-line-regexp tr-org-todo-line-regexp) + (org-todo-keywords tr-org-todo-keywords) + (org-todo-interpretation tr-org-todo-interpretation) + (org-done-string tr-org-done-string) + (org-todo-regexp tr-org-todo-regexp) + (org-todo-line-regexp tr-org-todo-line-regexp)) + (goto-char (point-min)) + (if heading + (progn + (if (re-search-forward + (concat "\\(^\\|\r\\)" + (regexp-quote heading) "[ \t]*\\($\\|\r\\)") + nil t) + (goto-char (match-end 0)) + ;; Heading not found, just insert it at the end + (goto-char (point-max)) + (or (bolp) (insert "\n")) + (insert "\n" heading "\n") + (end-of-line 0)) + ;; Make the heading visible, and the following as well + (let ((org-show-following-heading t)) (org-show-hierarchy-above)) + (if (re-search-forward + (concat "^" (regexp-quote (make-string level ?*)) "[ \t]") + nil t) + (progn (goto-char (match-beginning 0)) (insert "\n") + (beginning-of-line 0)) + (goto-char (point-max)) (insert "\n"))) + (goto-char (point-max)) (insert "\n")) + ;; Paste + (org-paste-subtree (1+ level)) + ;; Mark the entry as done, i.e. set to last work in org-todo-keywords + (if org-archive-mark-done + (org-todo (length org-todo-keywords))) + ;; Move cursor to right after the TODO keyword + (when org-archive-stamp-time + (beginning-of-line 1) + (looking-at org-todo-line-regexp) + (goto-char (or (match-end 2) (match-beginning 3))) + (insert "(" (format-time-string (cdr org-time-stamp-formats) + (org-current-time)) + ")")) + ;; Save the buffer, if it is not the same buffer. + (if (not (eq this-buffer buffer)) (save-buffer)))) + ;; Here we are back in the original buffer. Everything seems to have + ;; worked. So now cut the tree and finish up. + (let (this-command) (org-cut-subtree)) + (if (looking-at "[ \t]*$") (kill-line)) + (message "Subtree archived %s" + (if (eq this-buffer buffer) + (concat "under heading: " heading) + (concat "in file: " (abbreviate-file-name file)))))) + +;;; Completion + +(defun org-complete (&optional arg) + "Perform completion on word at point. +At the beginning of a headline, this completes TODO keywords as given in +`org-todo-keywords'. +If the current word is preceded by a backslash, completes the TeX symbols +that are supported for HTML support. +If the current word is preceded by \"#+\", completes special words for +setting file options. +At all other locations, this simply calls `ispell-complete-word'." + (interactive "P") + (catch 'exit + (let* ((end (point)) + (beg1 (save-excursion + (if (equal (char-before (point)) ?\ ) (backward-char 1)) + (skip-chars-backward "a-zA-Z_@0-9") + (point))) + (beg (save-excursion + (if (equal (char-before (point)) ?\ ) (backward-char 1)) + (skip-chars-backward "a-zA-Z0-9_:$") + (point))) + (camel (equal (char-before beg) ?*)) + (tag (equal (char-before beg1) ?:)) + (texp (equal (char-before beg) ?\\)) + (opt (equal (buffer-substring (max (point-at-bol) (- beg 2)) + beg) + "#+")) + (completion-ignore-case opt) + (type nil) + (tbl nil) + (table (cond + (opt + (setq type :opt) + (mapcar (lambda (x) + (string-match "^#\\+\\(\\([A-Z_]+:?\\).*\\)" x) + (cons (match-string 2 x) (match-string 1 x))) + (org-split-string (org-get-current-options) "\n"))) + (texp + (setq type :tex) + org-html-entities) + ((string-match "\\`\\*+[ \t]*\\'" + (buffer-substring (point-at-bol) beg)) + (setq type :todo) + (mapcar 'list org-todo-keywords)) + (camel + (setq type :camel) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward org-todo-line-regexp nil t) + (push (list + (if org-file-link-context-use-camel-case + (org-make-org-heading-camel (match-string 3) t) + (org-make-org-heading-search-string + (match-string 3) t))) + tbl))) + tbl) + (tag (setq type :tag beg beg1) + (org-get-buffer-tags)) + (t (progn (ispell-complete-word arg) (throw 'exit nil))))) + (pattern (buffer-substring-no-properties beg end)) + (completion (try-completion pattern table))) + (cond ((eq completion t) + (if (equal type :opt) + (insert (substring (cdr (assoc (upcase pattern) table)) + (length pattern))))) + ((null completion) + (message "Can't find completion for \"%s\"" pattern) + (ding)) + ((not (string= pattern completion)) + (delete-region beg end) + (if (string-match " +$" completion) + (setq completion (replace-match "" t t completion))) + (insert completion) + (if (get-buffer-window "*Completions*") + (delete-window (get-buffer-window "*Completions*"))) + (if (assoc completion table) + (if (eq type :todo) (insert " ") + (if (eq type :tag) (insert ":")))) + (if (and (equal type :opt) (assoc completion table)) + (message "%s" (substitute-command-keys + "Press \\[org-complete] again to insert example settings")))) + (t + (message "Making completion list...") + (let ((list (sort (all-completions pattern table) 'string<))) + (with-output-to-temp-buffer "*Completions*" + (condition-case nil + ;; Protection needed for XEmacs and emacs 21 + (display-completion-list list pattern) + (error (display-completion-list list))))) + (message "Making completion list...%s" "done")))))) + +;;; Comments, TODO and DEADLINE + +(defun org-toggle-comment () + "Change the COMMENT state of an entry." + (interactive) + (save-excursion + (org-back-to-heading) + (if (looking-at (concat outline-regexp + "\\( +\\<" org-comment-string "\\>\\)")) + (replace-match "" t t nil 1) + (if (looking-at outline-regexp) + (progn + (goto-char (match-end 0)) + (insert " " org-comment-string)))))) + +(defvar org-last-todo-state-is-todo nil + "This is non-nil when the last TODO state change led to a TODO state. +If the last change removed the TODO tag or switched to DONE, then +this is nil.") + +(defun org-todo (&optional arg) + "Change the TODO state of an item. +The state of an item is given by a keyword at the start of the heading, +like + *** TODO Write paper + *** DONE Call mom + +The different keywords are specified in the variable `org-todo-keywords'. +By default the available states are \"TODO\" and \"DONE\". +So for this example: when the item starts with TODO, it is changed to DONE. +When it starts with DONE, the DONE is removed. And when neither TODO nor +DONE are present, add TODO at the beginning of the heading. + +With prefix arg, use completion to determine the new state. With numeric +prefix arg, switch to that state." + (interactive "P") + (save-excursion + (org-back-to-heading) + (if (looking-at outline-regexp) (goto-char (match-end 0))) + (or (looking-at (concat " +" org-todo-regexp " *")) + (looking-at " *")) + (let* ((this (match-string 1)) + (completion-ignore-case t) + (member (member this org-todo-keywords)) + (tail (cdr member)) + (state (cond + ((equal arg '(4)) + ;; Read a state with completion + (completing-read "State: " (mapcar (lambda(x) (list x)) + org-todo-keywords) + nil t)) + ((eq arg 'right) + (if this + (if tail (car tail) nil) + (car org-todo-keywords))) + ((eq arg 'left) + (if (equal member org-todo-keywords) + nil + (if this + (nth (- (length org-todo-keywords) (length tail) 2) + org-todo-keywords) + org-done-string))) + (arg + ;; user requests a specific state + (nth (1- (prefix-numeric-value arg)) + org-todo-keywords)) + ((null member) (car org-todo-keywords)) + ((null tail) nil) ;; -> first entry + ((eq org-todo-interpretation 'sequence) + (car tail)) + ((memq org-todo-interpretation '(type priority)) + (if (eq this-command last-command) + (car tail) + (if (> (length tail) 0) org-done-string nil))) + (t nil))) + (next (if state (concat " " state " ") " "))) + (replace-match next t t) + (setq org-last-todo-state-is-todo + (not (equal state org-done-string))) + (when org-log-done + (if (equal state org-done-string) + (org-log-done) + (if (not this) + (org-log-done t)))) + ;; Fixup tag positioning + (and org-auto-align-tags (org-set-tags nil t)) + (run-hooks 'org-after-todo-state-change-hook))) + ;; Fixup cursor location if close to the keyword + (if (and (outline-on-heading-p) + (not (bolp)) + (save-excursion (beginning-of-line 1) + (looking-at org-todo-line-regexp)) + (< (point) (+ 2 (or (match-end 2) (match-end 1))))) + (progn + (goto-char (or (match-end 2) (match-end 1))) + (just-one-space)))) + +(defun org-log-done (&optional undone) + "Add a time stamp logging that a TODO entry has been closed. +When UNDONE is non-nil, remove such a time stamp again." + (interactive) + (let (beg end col) + (save-excursion + (org-back-to-heading t) + (setq beg (point)) + (looking-at (concat outline-regexp " *")) + (goto-char (match-end 0)) + (setq col (current-column)) + (outline-next-heading) + (setq end (point)) + (goto-char beg) + (when (re-search-forward (concat + "[\r\n]\\([ \t]*" + (regexp-quote org-closed-string) + " *\\[.*?\\][^\n\r]*[\n\r]?\\)") end t) + (delete-region (match-beginning 1) (match-end 1))) + (unless undone + (org-back-to-heading t) + (skip-chars-forward "^\n\r") + (goto-char (min (1+ (point)) (point-max))) + (when (not (member (char-before) '(?\r ?\n))) + (insert "\n")) + (indent-to col) + (insert org-closed-string " " + (format-time-string + (concat "[" (substring (cdr org-time-stamp-formats) 1 -1) "]") + (org-current-time)) + "\n"))))) + +(defun org-show-todo-tree (arg) + "Make a compact tree which shows all headlines marked with TODO. +The tree will show the lines where the regexp matches, and all higher +headlines above the match. +With \\[universal-argument] prefix, also show the DONE entries. +With a numeric prefix N, construct a sparse tree for the Nth element +of `org-todo-keywords'." + (interactive "P") + (let ((case-fold-search nil) + (kwd-re + (cond ((null arg) org-not-done-regexp) + ((equal arg '(4)) org-todo-regexp) + ((<= (prefix-numeric-value arg) (length org-todo-keywords)) + (regexp-quote (nth (1- (prefix-numeric-value arg)) + org-todo-keywords))) + (t (error "Invalid prefix argument: %s" arg))))) + (message "%d TODO entries found" + (org-occur (concat "^" outline-regexp " +" kwd-re ))))) + +(defun org-deadline () + "Insert the DEADLINE: string to make a deadline. +A timestamp is also inserted - use \\[org-timestamp-up] and \\[org-timestamp-down] +to modify it to the correct date." + (interactive) + (insert + org-deadline-string " " + (format-time-string (car org-time-stamp-formats) + (org-read-date nil 'to-time))) + (message "%s" (substitute-command-keys + "Use \\[org-timestamp-up-day] and \\[org-timestamp-down-day] to change the date."))) + +(defun org-schedule () + "Insert the SCHEDULED: string to schedule a TODO item. +A timestamp is also inserted - use \\[org-timestamp-up] and \\[org-timestamp-down] +to modify it to the correct date." + (interactive) + (insert + org-scheduled-string " " + (format-time-string (car org-time-stamp-formats) + (org-read-date nil 'to-time))) + (message "%s" (substitute-command-keys + "Use \\[org-timestamp-up-day] and \\[org-timestamp-down-day] to change the date."))) + + +(defun org-occur (regexp &optional callback) + "Make a compact tree which shows all matches of REGEXP. +The tree will show the lines where the regexp matches, and all higher +headlines above the match. It will also show the heading after the match, +to make sure editing the matching entry is easy. +If CALLBACK is non-nil, it is a function which is called to confirm +that the match should indeed be shown." + (interactive "sRegexp: ") + (org-remove-occur-highlights nil nil t) + (setq regexp (org-check-occur-regexp regexp)) + (let ((cnt 0)) + (save-excursion + (goto-char (point-min)) + (hide-sublevels 1) + (while (re-search-forward regexp nil t) + (when (or (not callback) + (save-match-data (funcall callback))) + (setq cnt (1+ cnt)) + (org-highlight-new-match (match-beginning 0) (match-end 0)) + (org-show-hierarchy-above)))) + (org-add-hook 'before-change-functions 'org-remove-occur-highlights + nil 'local) + (run-hooks 'org-occur-hook) + (if (interactive-p) + (message "%d match(es) for regexp %s" cnt regexp)) + cnt)) + +(defun org-show-hierarchy-above () + "Make sure point and the headings hierarchy above is visible." + (catch 'exit + (if (org-on-heading-p t) + (org-flag-heading nil) ; only show the heading + (and (or (org-invisible-p) (org-invisible-p2)) + (org-show-hidden-entry))) ; show entire entry + (save-excursion + (and org-show-following-heading + (outline-next-heading) + (org-flag-heading nil))) ; show the next heading + (when org-show-hierarchy-above + (save-excursion ; show all higher headings + (while (and (condition-case nil + (progn (org-up-heading-all 1) t) + (error nil)) + (not (bobp))) + (org-flag-heading nil)))))) + +;; Overlay compatibility functions +(defun org-make-overlay (beg end &optional buffer) + (if org-xemacs-p (make-extent beg end buffer) (make-overlay beg end buffer))) +(defun org-delete-overlay (ovl) + (if org-xemacs-p (delete-extent ovl) (delete-overlay ovl))) +(defun org-detatch-overlay (ovl) + (if org-xemacs-p (detach-extent ovl) (delete-overlay ovl))) +(defun org-move-overlay (ovl beg end &optional buffer) + (if org-xemacs-p + (set-extent-endpoints ovl beg end buffer) + (move-overlay ovl beg end buffer))) +(defun org-overlay-put (ovl prop value) + (if org-xemacs-p + (set-extent-property ovl prop value) + (overlay-put ovl prop value))) + +(defvar org-occur-highlights nil) +(defun org-highlight-new-match (beg end) + "Highlight from BEG to END and mark the highlight is an occur headline." + (let ((ov (org-make-overlay beg end))) + (org-overlay-put ov 'face 'secondary-selection) + (push ov org-occur-highlights))) + +(defun org-remove-occur-highlights (&optional beg end noremove) + "Remove the occur highlights from the buffer. +BEG and END are ignored. If NOREMOVE is nil, remove this function +from the `before-change-functions' in the current buffer." + (interactive) + (mapc 'org-delete-overlay org-occur-highlights) + (setq org-occur-highlights nil) + (unless noremove + (remove-hook 'before-change-functions + 'org-remove-occur-highlights 'local))) + +;;; Priorities + +(defvar org-priority-regexp ".*?\\(\\[#\\([A-Z]\\)\\] ?\\)" + "Regular expression matching the priority indicator.") + +(defvar org-remove-priority-next-time nil) + +(defun org-priority-up () + "Increase the priority of the current item." + (interactive) + (org-priority 'up)) + +(defun org-priority-down () + "Decrease the priority of the current item." + (interactive) + (org-priority 'down)) + +(defun org-priority (&optional action) + "Change the priority of an item by ARG. +ACTION can be set, up, or down." + (interactive) + (setq action (or action 'set)) + (let (current new news have remove) + (save-excursion + (org-back-to-heading) + (if (looking-at org-priority-regexp) + (setq current (string-to-char (match-string 2)) + have t) + (setq current org-default-priority)) + (cond + ((eq action 'set) + (message "Priority A-%c, SPC to remove: " org-lowest-priority) + (setq new (read-char-exclusive)) + (cond ((equal new ?\ ) (setq remove t)) + ((or (< (upcase new) ?A) (> (upcase new) org-lowest-priority)) + (error "Priority must be between `%c' and `%c'" + ?A org-lowest-priority)))) + ((eq action 'up) + (setq new (1- current))) + ((eq action 'down) + (setq new (1+ current))) + (t (error "Invalid action"))) + (setq new (min (max ?A (upcase new)) org-lowest-priority)) + (setq news (format "%c" new)) + (if have + (if remove + (replace-match "" t t nil 1) + (replace-match news t t nil 2)) + (if remove + (error "No priority cookie found in line") + (looking-at org-todo-line-regexp) + (if (match-end 2) + (progn + (goto-char (match-end 2)) + (insert " [#" news "]")) + (goto-char (match-beginning 3)) + (insert "[#" news "] "))))) + (if remove + (message "Priority removed") + (message "Priority of current item set to %s" news)))) + + +(defun org-get-priority (s) + "Find priority cookie and return priority." + (save-match-data + (if (not (string-match org-priority-regexp s)) + (* 1000 (- org-lowest-priority org-default-priority)) + (* 1000 (- org-lowest-priority + (string-to-char (match-string 2 s))))))) + +;;; Timestamps + +(defvar org-last-changed-timestamp nil) + +(defun org-time-stamp (arg) + "Prompt for a date/time and insert a time stamp. +If the user specifies a time like HH:MM, or if this command is called +with a prefix argument, the time stamp will contain date and time. +Otherwise, only the date will be included. All parts of a date not +specified by the user will be filled in from the current date/time. +So if you press just return without typing anything, the time stamp +will represent the current date/time. If there is already a timestamp +at the cursor, it will be modified." + (interactive "P") + (let ((fmt (if arg (cdr org-time-stamp-formats) + (car org-time-stamp-formats))) + (org-time-was-given nil) + time) + (cond + ((and (org-at-timestamp-p) + (eq last-command 'org-time-stamp) + (eq this-command 'org-time-stamp)) + (insert "--") + (setq time (let ((this-command this-command)) + (org-read-date arg 'totime))) + (if org-time-was-given (setq fmt (cdr org-time-stamp-formats))) + (insert (format-time-string fmt time))) + ((org-at-timestamp-p) + (setq time (let ((this-command this-command)) + (org-read-date arg 'totime))) + (and (org-at-timestamp-p) (replace-match + (setq org-last-changed-timestamp + (format-time-string fmt time)) + t t)) + (message "Timestamp updated")) + (t + (setq time (let ((this-command this-command)) + (org-read-date arg 'totime))) + (if org-time-was-given (setq fmt (cdr org-time-stamp-formats))) + (insert (format-time-string fmt time)))))) + +(defun org-time-stamp-inactive (&optional arg) + "Insert an inactive time stamp. +An inactive time stamp is enclosed in square brackets instead of angle +brackets. It is inactive in the sense that it does not trigger agenda entries, +does not link to the calendar and cannot be changed with the S-cursor keys. +So these are more for recording a certain time/date." + ;; FIXME: Would it be better not to ask for a date/time here? + (interactive "P") + (let ((fmt (if arg (cdr org-time-stamp-formats) + (car org-time-stamp-formats))) + (org-time-was-given nil) + time) + (setq time (org-read-date arg 'totime)) + (if org-time-was-given (setq fmt (cdr org-time-stamp-formats))) + (setq fmt (concat "[" (substring fmt 1 -1) "]")) + (insert (format-time-string fmt time)))) + +(defvar org-date-ovl (org-make-overlay 1 1)) +(org-overlay-put org-date-ovl 'face 'org-warning) +(org-detatch-overlay org-date-ovl) + +;;; FIXME: Make the function take "Fri" as "next friday" +;;; because these are mostly being used to record the current time. +(defun org-read-date (&optional with-time to-time) + "Read a date and make things smooth for the user. +The prompt will suggest to enter an ISO date, but you can also enter anything +which will at least partially be understood by `parse-time-string'. +Unrecognized parts of the date will default to the current day, month, year, +hour and minute. For example, + 3-2-5 --> 2003-02-05 + feb 15 --> currentyear-02-15 + sep 12 9 --> 2009-09-12 + 12:45 --> today 12:45 + 22 sept 0:34 --> currentyear-09-22 0:34 + 12 --> currentyear-currentmonth-12 + etc. +The function understands only English month and weekday abbreviations, +but this can be configured with the variables `parse-time-months' and +`parse-time-weekdays'. + +While prompting, a calendar is popped up - you can also select the +date with the mouse (button 1). The calendar shows a period of three +months. To scroll it to other months, use the keys `>' and `<'. +If you don't like the calendar, turn it off with + \(setq org-popup-calendar-for-date-prompt nil) + +With optional argument TO-TIME, the date will immediately be converted +to an internal time. +With an optional argument WITH-TIME, the prompt will suggest to also +insert a time. Note that when WITH-TIME is not set, you can still +enter a time, and this function will inform the calling routine about +this change. The calling routine may then choose to change the format +used to insert the time stamp into the buffer to include the time." + (require 'parse-time) + (let* ((org-time-stamp-rounding-minutes + (if (equal with-time '(16)) 0 org-time-stamp-rounding-minutes)) + (ct (org-current-time)) + (default-time + ;; Default time is either today, or, when entering a range, + ;; the range start. + (if (save-excursion + (re-search-backward + (concat org-ts-regexp "--\\=") + (- (point) 20) t)) + (apply + 'encode-time + (mapcar (lambda(x) (or x 0)) ;; FIXME: Problem with timezone? + (parse-time-string (match-string 1)))) + ct)) + (calendar-move-hook nil) + (view-diary-entries-initially nil) + (timestr (format-time-string + (if with-time "%Y-%m-%d %H:%M" "%Y-%m-%d") default-time)) + (prompt (format "YYYY-MM-DD [%s]: " timestr)) + ans ans1 ans2 + second minute hour day month year tl) + + (if org-popup-calendar-for-date-prompt + ;; Also show a calendar for date selection + ;; Copied (with modifications) from planner.el by John Wiegley + (save-excursion + (save-window-excursion + (calendar) + (calendar-forward-day (- (time-to-days default-time) + (calendar-absolute-from-gregorian + (calendar-current-date)))) + (org-eval-in-calendar nil) + (let* ((old-map (current-local-map)) + (map (copy-keymap calendar-mode-map)) + (minibuffer-local-map (copy-keymap minibuffer-local-map))) + (define-key map (kbd "RET") 'org-calendar-select) + (define-key map (if org-xemacs-p [button1] [mouse-1]) + 'org-calendar-select-mouse) + (define-key map (if org-xemacs-p [button2] [mouse-2]) + 'org-calendar-select-mouse) + (define-key minibuffer-local-map [(meta shift left)] + (lambda () (interactive) + (org-eval-in-calendar '(calendar-backward-month 1)))) + (define-key minibuffer-local-map [(meta shift right)] + (lambda () (interactive) + (org-eval-in-calendar '(calendar-forward-month 1)))) + (define-key minibuffer-local-map [(shift up)] + (lambda () (interactive) + (org-eval-in-calendar '(calendar-backward-week 1)))) + (define-key minibuffer-local-map [(shift down)] + (lambda () (interactive) + (org-eval-in-calendar '(calendar-forward-week 1)))) + (define-key minibuffer-local-map [(shift left)] + (lambda () (interactive) + (org-eval-in-calendar '(calendar-backward-day 1)))) + (define-key minibuffer-local-map [(shift right)] + (lambda () (interactive) + (org-eval-in-calendar '(calendar-forward-day 1)))) + (define-key minibuffer-local-map ">" + (lambda () (interactive) + (org-eval-in-calendar '(scroll-calendar-left 1)))) + (define-key minibuffer-local-map "<" + (lambda () (interactive) + (org-eval-in-calendar '(scroll-calendar-right 1)))) + (unwind-protect + (progn + (use-local-map map) + (setq ans (read-string prompt "" nil nil)) + (if (not (string-match "\\S-" ans)) (setq ans nil)) + (setq ans (or ans1 ans ans2))) + (use-local-map old-map))))) + ;; Naked prompt only + (setq ans (read-string prompt "" nil timestr))) + (org-detatch-overlay org-date-ovl) + + (if (string-match + "^ *\\(\\([0-9]+\\)-\\)?\\([0-1]?[0-9]\\)-\\([0-3]?[0-9]\\)\\([^-0-9]\\|$\\)" ans) + (progn + (setq year (if (match-end 2) + (string-to-number (match-string 2 ans)) + (string-to-number (format-time-string "%Y"))) + month (string-to-number (match-string 3 ans)) + day (string-to-number (match-string 4 ans))) + (if (< year 100) (setq year (+ 2000 year))) + (setq ans (replace-match (format "%04d-%02d-%02d\\5" year month day) + t nil ans)))) + (setq tl (parse-time-string ans) + year (or (nth 5 tl) (string-to-number (format-time-string "%Y" ct))) + month (or (nth 4 tl) (string-to-number (format-time-string "%m" ct))) + day (or (nth 3 tl) (string-to-number (format-time-string "%d" ct))) + hour (or (nth 2 tl) (string-to-number (format-time-string "%H" ct))) + minute (or (nth 1 tl) (string-to-number (format-time-string "%M" ct))) + second (or (nth 0 tl) 0)) + (if (and (boundp 'org-time-was-given) + (nth 2 tl)) + (setq org-time-was-given t)) + (if (< year 100) (setq year (+ 2000 year))) + (if to-time + (encode-time second minute hour day month year) + (if (or (nth 1 tl) (nth 2 tl)) + (format "%04d-%02d-%02d %02d:%02d" year month day hour minute) + (format "%04d-%02d-%02d" year month day))))) + +(defun org-eval-in-calendar (form) + "Eval FORM in the calendar window and return to current window. +Also, store the cursor date in variable ans2." + (let ((sw (selected-window))) + (select-window (get-buffer-window "*Calendar*")) + (eval form) + (when (calendar-cursor-to-date) + (let* ((date (calendar-cursor-to-date)) + (time (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))) + (setq ans2 (format-time-string "%Y-%m-%d" time)))) + (org-move-overlay org-date-ovl (1- (point)) (1+ (point)) (current-buffer)) + (select-window sw))) + +(defun org-calendar-select () + "Return to `org-read-date' with the date currently selected. +This is used by `org-read-date' in a temporary keymap for the calendar buffer." + (interactive) + (when (calendar-cursor-to-date) + (let* ((date (calendar-cursor-to-date)) + (time (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))) + (setq ans1 (format-time-string "%Y-%m-%d" time))) + (if (active-minibuffer-window) (exit-minibuffer)))) + +(defun org-calendar-select-mouse (ev) + "Return to `org-read-date' with the date currently selected. +This is used by `org-read-date' in a temporary keymap for the calendar buffer." + (interactive "e") + (mouse-set-point ev) + (when (calendar-cursor-to-date) + (let* ((date (calendar-cursor-to-date)) + (time (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))) + (setq ans1 (format-time-string "%Y-%m-%d" time))) + (if (active-minibuffer-window) (exit-minibuffer)))) + +(defun org-check-deadlines (ndays) + "Check if there are any deadlines due or past due. +A deadline is considered due if it happens within `org-deadline-warning-days' +days from today's date. If the deadline appears in an entry marked DONE, +it is not shown. The prefix arg NDAYS can be used to test that many +days. If the prefix is a raw \\[universal-argument] prefix, all deadlines are shown." + (interactive "P") + (let* ((org-warn-days + (cond + ((equal ndays '(4)) 100000) + (ndays (prefix-numeric-value ndays)) + (t org-deadline-warning-days))) + (case-fold-search nil) + (regexp (concat "\\<" org-deadline-string " *<\\([^>]+\\)>")) + (callback + (lambda () + (and (let ((d1 (time-to-days (current-time))) + (d2 (time-to-days + (org-time-string-to-time (match-string 1))))) + (< (- d2 d1) org-warn-days)) + (not (org-entry-is-done-p)))))) + (message "%d deadlines past-due or due within %d days" + (org-occur regexp callback) + org-warn-days))) + +(defun org-evaluate-time-range (&optional to-buffer) + "Evaluate a time range by computing the difference between start and end. +Normally the result is just printed in the echo area, but with prefix arg +TO-BUFFER, the result is inserted just after the date stamp into the buffer. +If the time range is actually in a table, the result is inserted into the +next column. +For time difference computation, a year is assumed to be exactly 365 +days in order to avoid rounding problems." + (interactive "P") + (save-excursion + (unless (org-at-date-range-p) + (goto-char (point-at-bol)) + (re-search-forward org-tr-regexp (point-at-eol) t)) + (if (not (org-at-date-range-p)) + (error "Not at a time-stamp range, and none found in current line"))) + (let* ((ts1 (match-string 1)) + (ts2 (match-string 2)) + (havetime (or (> (length ts1) 15) (> (length ts2) 15))) + (match-end (match-end 0)) + (time1 (org-time-string-to-time ts1)) + (time2 (org-time-string-to-time ts2)) + (t1 (time-to-seconds time1)) + (t2 (time-to-seconds time2)) + (diff (abs (- t2 t1))) + (negative (< (- t2 t1) 0)) + ;; (ys (floor (* 365 24 60 60))) + (ds (* 24 60 60)) + (hs (* 60 60)) + (fy "%dy %dd %02d:%02d") + (fy1 "%dy %dd") + (fd "%dd %02d:%02d") + (fd1 "%dd") + (fh "%02d:%02d") + y d h m align) + ;; FIXME: Should I re-introduce years, make year refer to same date? + ;; This would be the only useful way to have years, actually. + (if havetime + (setq ; y (floor (/ diff ys)) diff (mod diff ys) + y 0 + d (floor (/ diff ds)) diff (mod diff ds) + h (floor (/ diff hs)) diff (mod diff hs) + m (floor (/ diff 60))) + (setq ; y (floor (/ diff ys)) diff (mod diff ys) + y 0 + d (floor (+ (/ diff ds) 0.5)) + h 0 m 0)) + (if (not to-buffer) + (message (org-make-tdiff-string y d h m)) + (when (org-at-table-p) + (goto-char match-end) + (setq align t) + (and (looking-at " *|") (goto-char (match-end 0)))) + (if (looking-at + "\\( *-? *[0-9]+y\\)?\\( *[0-9]+d\\)? *[0-9][0-9]:[0-9][0-9]") + (replace-match "")) + (if negative (insert " -")) + (if (> y 0) (insert " " (format (if havetime fy fy1) y d h m)) + (if (> d 0) (insert " " (format (if havetime fd fd1) d h m)) + (insert " " (format fh h m)))) + (if align (org-table-align)) + (message "Time difference inserted")))) + +(defun org-make-tdiff-string (y d h m) + (let ((fmt "") + (l nil)) + (if (> y 0) (setq fmt (concat fmt "%d year" (if (> y 1) "s" "") " ") + l (push y l))) + (if (> d 0) (setq fmt (concat fmt "%d day" (if (> d 1) "s" "") " ") + l (push d l))) + (if (> h 0) (setq fmt (concat fmt "%d hour" (if (> h 1) "s" "") " ") + l (push h l))) + (if (> m 0) (setq fmt (concat fmt "%d minute" (if (> m 1) "s" "") " ") + l (push m l))) + (apply 'format fmt (nreverse l)))) + +(defun org-time-string-to-time (s) + (apply 'encode-time (org-parse-time-string s))) + +(defun org-parse-time-string (s &optional nodefault) + "Parse the standard Org-mode time string. +This should be a lot faster than the normal `parse-time-string'. +If time is not given, defaults to 0:00. However, with optional NODEFAULT, +hour and minute fields will be nil if not given." + (if (string-match org-ts-regexp1 s) + (list 0 + (if (or (match-beginning 8) (not nodefault)) + (string-to-number (or (match-string 8 s) "0"))) + (if (or (match-beginning 7) (not nodefault)) + (string-to-number (or (match-string 7 s) "0"))) + (string-to-number (match-string 4 s)) + (string-to-number (match-string 3 s)) + (string-to-number (match-string 2 s)) + nil nil nil) + (make-list 9 0))) + +(defun org-timestamp-up (&optional arg) + "Increase the date item at the cursor by one. +If the cursor is on the year, change the year. If it is on the month or +the day, change that. +With prefix ARG, change by that many units." + (interactive "p") + (org-timestamp-change (prefix-numeric-value arg))) + +(defun org-timestamp-down (&optional arg) + "Decrease the date item at the cursor by one. +If the cursor is on the year, change the year. If it is on the month or +the day, change that. +With prefix ARG, change by that many units." + (interactive "p") + (org-timestamp-change (- (prefix-numeric-value arg)))) + +(defun org-timestamp-up-day (&optional arg) + "Increase the date in the time stamp by one day. +With prefix ARG, change that many days." + (interactive "p") + (if (and (not (org-at-timestamp-p)) + (org-on-heading-p)) + (org-todo 'up) + (org-timestamp-change (prefix-numeric-value arg) 'day))) + +(defun org-timestamp-down-day (&optional arg) + "Decrease the date in the time stamp by one day. +With prefix ARG, change that many days." + (interactive "p") + (if (and (not (org-at-timestamp-p)) + (org-on-heading-p)) + (org-todo 'down) + (org-timestamp-change (- (prefix-numeric-value arg)) 'day))) + +(defsubst org-pos-in-match-range (pos n) + (and (match-beginning n) + (<= (match-beginning n) pos) + (>= (match-end n) pos))) + +(defun org-at-timestamp-p () + "Determine if the cursor is in or at a timestamp." + (interactive) + (let* ((tsr org-ts-regexp2) + (pos (point)) + (ans (or (looking-at tsr) + (save-excursion + (skip-chars-backward "^<\n\r\t") + (if (> (point) 1) (backward-char 1)) + (and (looking-at tsr) + (> (- (match-end 0) pos) -1)))))) + (and (boundp 'org-ts-what) + (setq org-ts-what + (cond + ((org-pos-in-match-range pos 2) 'year) + ((org-pos-in-match-range pos 3) 'month) + ((org-pos-in-match-range pos 7) 'hour) + ((org-pos-in-match-range pos 8) 'minute) + ((or (org-pos-in-match-range pos 4) + (org-pos-in-match-range pos 5)) 'day) + (t 'day)))) + ans)) + +(defun org-timestamp-change (n &optional what) + "Change the date in the time stamp at point. +The date will be changed by N times WHAT. WHAT can be `day', `month', +`year', `minute', `second'. If WHAT is not given, the cursor position +in the timestamp determines what will be changed." + (let ((fmt (car org-time-stamp-formats)) + org-ts-what + (pos (point)) + ts time time0) + (if (not (org-at-timestamp-p)) + (error "Not at a timestamp")) + (setq org-ts-what (or what org-ts-what)) + (setq fmt (if (<= (abs (- (cdr org-ts-lengths) + (- (match-end 0) (match-beginning 0)))) + 1) + (cdr org-time-stamp-formats) + (car org-time-stamp-formats))) + (setq ts (match-string 0)) + (replace-match "") + (setq time0 (org-parse-time-string ts)) + (setq time + (apply 'encode-time + (append + (list (or (car time0) 0)) + (list (+ (if (eq org-ts-what 'minute) n 0) (nth 1 time0))) + (list (+ (if (eq org-ts-what 'hour) n 0) (nth 2 time0))) + (list (+ (if (eq org-ts-what 'day) n 0) (nth 3 time0))) + (list (+ (if (eq org-ts-what 'month) n 0) (nth 4 time0))) + (list (+ (if (eq org-ts-what 'year) n 0) (nth 5 time0))) + (nthcdr 6 time0)))) + (if (eq what 'calendar) + (let ((cal-date + (save-excursion + (save-match-data + (set-buffer "*Calendar*") + (calendar-cursor-to-date))))) + (setcar (nthcdr 4 time0) (nth 0 cal-date)) ; month + (setcar (nthcdr 3 time0) (nth 1 cal-date)) ; day + (setcar (nthcdr 5 time0) (nth 2 cal-date)) ; year + (setcar time0 (or (car time0) 0)) + (setcar (nthcdr 1 time0) (or (nth 1 time0) 0)) + (setcar (nthcdr 2 time0) (or (nth 1 time0) 0)) + (setq time (apply 'encode-time time0)))) + (insert (setq org-last-changed-timestamp (format-time-string fmt time))) + (goto-char pos) + ;; Try to recenter the calendar window, if any + (if (and org-calendar-follow-timestamp-change + (get-buffer-window "*Calendar*" t) + (memq org-ts-what '(day month year))) + (org-recenter-calendar (time-to-days time))))) + +(defun org-recenter-calendar (date) + "If the calendar is visible, recenter it to DATE." + (let* ((win (selected-window)) + (cwin (get-buffer-window "*Calendar*" t)) + (calendar-move-hook nil)) + (when cwin + (select-window cwin) + (calendar-goto-date (if (listp date) date + (calendar-gregorian-from-absolute date))) + (select-window win)))) + +(defun org-goto-calendar (&optional arg) + "Go to the Emacs calendar at the current date. +If there is a time stamp in the current line, go to that date. +A prefix ARG can be used to force the current date." + (interactive "P") + (let ((tsr org-ts-regexp) diff + (calendar-move-hook nil) + (view-diary-entries-initially nil)) + (if (or (org-at-timestamp-p) + (save-excursion + (beginning-of-line 1) + (looking-at (concat ".*" tsr)))) + (let ((d1 (time-to-days (current-time))) + (d2 (time-to-days + (org-time-string-to-time (match-string 1))))) + (setq diff (- d2 d1)))) + (calendar) + (calendar-goto-today) + (if (and diff (not arg)) (calendar-forward-day diff)))) + +(defun org-date-from-calendar () + "Insert time stamp corresponding to cursor date in *Calendar* buffer. +If there is already a time stamp at the cursor position, update it." + (interactive) + (org-timestamp-change 0 'calendar)) + +;;; Agenda, and Diary Integration + +;;; Define the mode + +(defvar org-agenda-mode-map (make-sparse-keymap) + "Keymap for `org-agenda-mode'.") + +(defvar org-agenda-menu) ; defined later in this file. +(defvar org-agenda-follow-mode nil) +(defvar org-agenda-show-log nil) +(defvar org-agenda-buffer-name "*Org Agenda*") +(defvar org-agenda-redo-command nil) +(defvar org-agenda-mode-hook nil) +(defvar org-agenda-type nil) +(defvar org-agenda-force-single-file nil) + +;;;###autoload +(defun org-agenda-mode () + "Mode for time-sorted view on action items in Org-mode files. + +The following commands are available: + +\\{org-agenda-mode-map}" + (interactive) + (kill-all-local-variables) + (setq major-mode 'org-agenda-mode) + (setq mode-name "Org-Agenda") + (use-local-map org-agenda-mode-map) + (easy-menu-add org-agenda-menu) + (if org-startup-truncated (setq truncate-lines t)) + (org-add-hook 'post-command-hook 'org-agenda-post-command-hook nil 'local) + (org-add-hook 'pre-command-hook 'org-unhighlight nil 'local) + (unless org-agenda-keep-modes + (setq org-agenda-follow-mode nil + org-agenda-show-log nil)) + (easy-menu-change + '("Agenda") "Agenda Files" + (append + (list + (vector + (if (get 'org-agenda-files 'org-restrict) + "Restricted to single file" + "Edit File List") + '(customize-variable 'org-agenda-files) + (not (get 'org-agenda-files 'org-restrict))) + "--") + (mapcar 'org-file-menu-entry (org-agenda-files)))) + (org-agenda-set-mode-name) + (apply + (if (fboundp 'run-mode-hooks) 'run-mode-hooks 'run-hooks) + (list 'org-agenda-mode-hook))) + +(define-key org-agenda-mode-map "\C-i" 'org-agenda-goto) +(define-key org-agenda-mode-map [(tab)] 'org-agenda-goto) +(define-key org-agenda-mode-map "\C-m" 'org-agenda-switch-to) +(define-key org-agenda-mode-map " " 'org-agenda-show) +(define-key org-agenda-mode-map "\C-c\C-t" 'org-agenda-todo) +(define-key org-agenda-mode-map "o" 'delete-other-windows) +(define-key org-agenda-mode-map "L" 'org-agenda-recenter) +(define-key org-agenda-mode-map "t" 'org-agenda-todo) +(define-key org-agenda-mode-map ":" 'org-agenda-set-tags) +(define-key org-agenda-mode-map "." 'org-agenda-goto-today) +(define-key org-agenda-mode-map "d" 'org-agenda-day-view) +(define-key org-agenda-mode-map "w" 'org-agenda-week-view) +(define-key org-agenda-mode-map (org-key 'S-right) 'org-agenda-date-later) +(define-key org-agenda-mode-map (org-key 'S-left) 'org-agenda-date-earlier) +(define-key org-agenda-mode-map [?\C-c ?\C-x (right)] 'org-agenda-date-later) +(define-key org-agenda-mode-map [?\C-c ?\C-x (left)] 'org-agenda-date-earlier) + +(define-key org-agenda-mode-map ">" 'org-agenda-date-prompt) +(let ((l '(1 2 3 4 5 6 7 8 9 0))) + (while l (define-key org-agenda-mode-map + (int-to-string (pop l)) 'digit-argument))) + +(define-key org-agenda-mode-map "f" 'org-agenda-follow-mode) +(define-key org-agenda-mode-map "l" 'org-agenda-log-mode) +(define-key org-agenda-mode-map "D" 'org-agenda-toggle-diary) +(define-key org-agenda-mode-map "g" 'org-agenda-toggle-time-grid) +(define-key org-agenda-mode-map "r" 'org-agenda-redo) +(define-key org-agenda-mode-map "q" 'org-agenda-quit) +(define-key org-agenda-mode-map "x" 'org-agenda-exit) +(define-key org-agenda-mode-map "P" 'org-agenda-show-priority) +(define-key org-agenda-mode-map "T" 'org-agenda-show-tags) +(define-key org-agenda-mode-map "n" 'next-line) +(define-key org-agenda-mode-map "p" 'previous-line) +(define-key org-agenda-mode-map "\C-n" 'org-agenda-next-date-line) +(define-key org-agenda-mode-map "\C-p" 'org-agenda-previous-date-line) +(define-key org-agenda-mode-map "," 'org-agenda-priority) +(define-key org-agenda-mode-map "\C-c," 'org-agenda-priority) +(define-key org-agenda-mode-map "i" 'org-agenda-diary-entry) +(define-key org-agenda-mode-map "c" 'org-agenda-goto-calendar) +(eval-after-load "calendar" + '(define-key calendar-mode-map org-calendar-to-agenda-key + 'org-calendar-goto-agenda)) +(define-key org-agenda-mode-map "C" 'org-agenda-convert-date) +(define-key org-agenda-mode-map "m" 'org-agenda-phases-of-moon) +(define-key org-agenda-mode-map "M" 'org-agenda-phases-of-moon) +(define-key org-agenda-mode-map "s" 'org-agenda-sunrise-sunset) +(define-key org-agenda-mode-map "S" 'org-agenda-sunrise-sunset) +(define-key org-agenda-mode-map "h" 'org-agenda-holidays) +(define-key org-agenda-mode-map "H" 'org-agenda-holidays) +(define-key org-agenda-mode-map "+" 'org-agenda-priority-up) +(define-key org-agenda-mode-map "-" 'org-agenda-priority-down) +(define-key org-agenda-mode-map (org-key 'S-up) 'org-agenda-priority-up) +(define-key org-agenda-mode-map (org-key 'S-down) 'org-agenda-priority-down) +(define-key org-agenda-mode-map [?\C-c ?\C-x (up)] 'org-agenda-priority-up) +(define-key org-agenda-mode-map [?\C-c ?\C-x (down)] 'org-agenda-priority-down) +(define-key org-agenda-mode-map [(right)] 'org-agenda-later) +(define-key org-agenda-mode-map [(left)] 'org-agenda-earlier) +(define-key org-agenda-mode-map "\C-c\C-x\C-c" 'org-export-icalendar-combine-agenda-files) +(defvar org-agenda-keymap (copy-keymap org-agenda-mode-map) + "Local keymap for agenda entries from Org-mode.") + +(define-key org-agenda-keymap + (if org-xemacs-p [(button2)] [(mouse-2)]) 'org-agenda-goto-mouse) +(define-key org-agenda-keymap + (if org-xemacs-p [(button3)] [(mouse-3)]) 'org-agenda-show-mouse) +(define-key org-agenda-keymap [follow-link] 'mouse-face) +(easy-menu-define org-agenda-menu org-agenda-mode-map "Agenda menu" + '("Agenda" + ("Agenda Files") + "--" + ["Show" org-agenda-show t] + ["Go To (other window)" org-agenda-goto t] + ["Go To (one window)" org-agenda-switch-to t] + ["Follow Mode" org-agenda-follow-mode + :style toggle :selected org-agenda-follow-mode :active t] + "--" + ["Cycle TODO" org-agenda-todo t] + ("Tags" + ["Show all Tags" org-agenda-show-tags t] + ["Set Tags" org-agenda-set-tags t]) + ("Reschedule" + ["Reschedule +1 day" org-agenda-date-later (org-agenda-check-type nil 'agenda 'timeline)] + ["Reschedule -1 day" org-agenda-date-earlier (org-agenda-check-type nil 'agenda 'timeline)] + "--" + ["Reschedule to ..." org-agenda-date-prompt (org-agenda-check-type nil 'agenda 'timeline)]) + ("Priority" + ["Set Priority" org-agenda-priority t] + ["Increase Priority" org-agenda-priority-up t] + ["Decrease Priority" org-agenda-priority-down t] + ["Show Priority" org-agenda-show-priority t]) + "--" + ;; ["New agenda command" org-agenda t] + ["Rebuild buffer" org-agenda-redo t] + "--" + ["Goto Today" org-agenda-goto-today (org-agenda-check-type nil 'agenda 'timeline)] + ["Next Dates" org-agenda-later (org-agenda-check-type nil 'agenda)] + ["Previous Dates" org-agenda-earlier (org-agenda-check-type nil 'agenda)] + "--" + ["Day View" org-agenda-day-view :active (org-agenda-check-type nil 'agenda) + :style radio :selected (equal org-agenda-ndays 1)] + ["Week View" org-agenda-week-view :active (org-agenda-check-type nil 'agenda) + :style radio :selected (equal org-agenda-ndays 7)] + "--" + ["Show Logbook entries" org-agenda-log-mode + :style toggle :selected org-agenda-show-log :active (org-agenda-check-type nil 'agenda 'timeline)] + ["Include Diary" org-agenda-toggle-diary + :style toggle :selected org-agenda-include-diary :active (org-agenda-check-type nil 'agenda)] + ["Use Time Grid" org-agenda-toggle-time-grid + :style toggle :selected org-agenda-use-time-grid :active (org-agenda-check-type nil 'agenda)] + "--" + ["New Diary Entry" org-agenda-diary-entry (org-agenda-check-type nil 'agenda 'timeline)] + ("Calendar Commands" + ["Goto Calendar" org-agenda-goto-calendar (org-agenda-check-type nil 'agenda 'timeline)] + ["Phases of the Moon" org-agenda-phases-of-moon (org-agenda-check-type nil 'agenda 'timeline)] + ["Sunrise/Sunset" org-agenda-sunrise-sunset (org-agenda-check-type nil 'agenda 'timeline)] + ["Holidays" org-agenda-holidays (org-agenda-check-type nil 'agenda 'timeline)] + ["Convert" org-agenda-convert-date (org-agenda-check-type nil 'agenda 'timeline)]) + ["Create iCalendar file" org-export-icalendar-combine-agenda-files t] + "--" + ["Quit" org-agenda-quit t] + ["Exit and Release Buffers" org-agenda-exit t] + )) + +;;;###autoload +(defun org-agenda (arg) + "Dispatch agenda commands to collect entries to the agenda buffer. +Prompts for a character to select a command. Any prefix arg will be passed +on to the selected command. The default selections are: + +a Call `org-agenda' to display the agenda for the current day or week. +t Call `org-todo-list' to display the global todo list. +T Call `org-todo-list' to display the global todo list, select only + entries with a specific TODO keyword (the user gets a prompt). +m Call `org-tags-view' to display headlines with tags matching + a condition (the user is prompted for the condition). +M Like `m', but select only TODO entries, no ordinary headlines. + +More commands can be added by configuring the variable +`org-agenda-custom-commands'. In particular, specific tags and TODO keyword +searches can be pre-defined in this way. + +If the current buffer is in Org-mode and visiting a file, you can also +first press `1' to indicate that the agenda should be temporarily (until the +next use of \\[org-agenda]) restricted to the current file." + (interactive "P") + (catch 'exit + (let ((restrict-ok (and buffer-file-name (eq major-mode 'org-mode))) + (custom org-agenda-custom-commands) + c entry key type string) + (put 'org-agenda-files 'org-restrict nil) + (save-window-excursion + (delete-other-windows) + (switch-to-buffer-other-window " *Agenda Commands*") + (erase-buffer) + (insert + "Press key for an agenda command: +-------------------------------- +a Agenda for current week or day +t List of all TODO entries T Entries with special TODO kwd +m Match a TAGS query M Like m, but only TODO entries +C Configure your own agenda commands") + (while (setq entry (pop custom)) + (setq key (car entry) type (nth 1 entry) string (nth 2 entry)) + (insert (format "\n%-4s%-14s: %s" + key + (cond + ((eq type 'tags) "Tags query") + ((eq type 'todo) "TODO keyword") + ((eq type 'tags-tree) "Tags tree") + ((eq type 'todo-tree) "TODO kwd tree") + ((eq type 'occur-tree) "Occur tree") + (t "???")) + (org-string-props string 'face 'org-link)))) + (goto-char (point-min)) + (if (fboundp 'fit-window-to-buffer) (fit-window-to-buffer)) + (message "Press key for agenda command%s" + (if restrict-ok ", or [1] to restrict to current file" "")) + (setq c (read-char-exclusive)) + (message "") + (when (equal c ?1) + (if restrict-ok + (put 'org-agenda-files 'org-restrict (list buffer-file-name)) + (error "Cannot restrict agenda to current buffer")) + (message "Press key for agenda command%s" + (if restrict-ok " (restricted to current file)" "")) + (setq c (read-char-exclusive)) + (message ""))) + (require 'calendar) ; FIXME: can we avoid this for some commands? + ;; For example the todo list should not need it (but does...) + (cond + ((equal c ?C) (customize-variable 'org-agenda-custom-commands)) + ((equal c ?a) (call-interactively 'org-agenda-list)) + ((equal c ?t) (call-interactively 'org-todo-list)) + ((equal c ?T) + (setq current-prefix-arg (or arg '(4))) + (call-interactively 'org-todo-list)) + ((equal c ?m) (call-interactively 'org-tags-view)) + ((equal c ?M) + (setq current-prefix-arg (or arg '(4))) + (call-interactively 'org-tags-view)) + ((setq entry (assoc (char-to-string c) org-agenda-custom-commands)) + (setq type (nth 1 entry) string (nth 2 entry)) + (cond + ((eq type 'tags) + (org-tags-view current-prefix-arg string)) + ((eq type 'todo) + (org-todo-list string)) + ((eq type 'tags-tree) + (org-check-for-org-mode) + (org-tags-sparse-tree current-prefix-arg string)) + ((eq type 'todo-tree) + (org-check-for-org-mode) + (org-occur (concat "^" outline-regexp "[ \t]*" + (regexp-quote string) "\\>"))) + ((eq type 'occur-tree) + (org-check-for-org-mode) + (org-occur string)) + (t (error "Invalid custom agenda command type %s" type)))) + (t (error "Invalid key")))))) + +(defun org-check-for-org-mode () + "Make sure current buffer is in org-mode. Error if not." + (or (eq major-mode 'org-mode) + (error "Cannot execute org-mode agenda command on buffer in %s." + major-mode))) + +(defun org-fit-agenda-window () + "Fit the window to the buffer size." + (and org-fit-agenda-window + (fboundp 'fit-window-to-buffer) + (fit-window-to-buffer nil (/ (* (frame-height) 3) 4) + (/ (frame-height) 2)))) + +(defun org-agenda-files () + "Get the list of agenda files." + (or (get 'org-agenda-files 'org-restrict) + org-agenda-files)) + +(defvar org-agenda-markers nil + "List of all currently active markers created by `org-agenda'.") +(defvar org-agenda-last-marker-time (time-to-seconds (current-time)) + "Creation time of the last agenda marker.") + +(defun org-agenda-new-marker (&optional pos) + "Return a new agenda marker. +Org-mode keeps a list of these markers and resets them when they are +no longer in use." + (let ((m (copy-marker (or pos (point))))) + (setq org-agenda-last-marker-time (time-to-seconds (current-time))) + (push m org-agenda-markers) + m)) + +(defun org-agenda-maybe-reset-markers (&optional force) + "Reset markers created by `org-agenda'. But only if they are old enough." + (if (or force + (> (- (time-to-seconds (current-time)) + org-agenda-last-marker-time) + 5)) + (while org-agenda-markers + (move-marker (pop org-agenda-markers) nil)))) + +(defvar org-agenda-new-buffers nil + "Buffers created to visit agenda files.") + +(defun org-get-agenda-file-buffer (file) + "Get a buffer visiting FILE. If the buffer needs to be created, add +it to the list of buffers which might be released later." + (let ((buf (find-buffer-visiting file))) + (if buf + buf ; just return it + ;; Make a new buffer and remember it + (setq buf (find-file-noselect file)) + (if buf (push buf org-agenda-new-buffers)) + buf))) + +(defun org-release-buffers (blist) + "Release all buffers in list, asking the user for confirmation when needed. +When a buffer is unmodified, it is just killed. When modified, it is saved +\(if the user agrees) and then killed." + (let (buf file) + (while (setq buf (pop blist)) + (setq file (buffer-file-name buf)) + (when (and (buffer-modified-p buf) + file + (y-or-n-p (format "Save file %s? " file))) + (with-current-buffer buf (save-buffer))) + (kill-buffer buf)))) + +(defvar org-respect-restriction nil) ; Dynamically-scoped param. + +(defun org-timeline (&optional include-all keep-modes) + "Show a time-sorted view of the entries in the current org file. +Only entries with a time stamp of today or later will be listed. With +\\[universal-argument] prefix, all unfinished TODO items will also be shown, +under the current date. +If the buffer contains an active region, only check the region for +dates." + (interactive "P") + (require 'calendar) + (org-agenda-maybe-reset-markers 'force) + (org-compile-prefix-format org-timeline-prefix-format) + (let* ((dopast t) + (dotodo include-all) + (doclosed org-agenda-show-log) + (org-agenda-keep-modes keep-modes) + (entry buffer-file-name) + (org-agenda-files (list buffer-file-name)) + (date (calendar-current-date)) + (win (selected-window)) + (pos1 (point)) + (beg (if (org-region-active-p) (region-beginning) (point-min))) + (end (if (org-region-active-p) (region-end) (point-max))) + (day-numbers (org-get-all-dates beg end 'no-ranges + t doclosed)) ; always include today + (today (time-to-days (current-time))) + (org-respect-restriction t) + (past t) + args + s e rtn d) + (setq org-agenda-redo-command + (list 'progn + (list 'switch-to-buffer-other-window (current-buffer)) + (list 'org-timeline (list 'quote include-all) t))) + (if (not dopast) + ;; Remove past dates from the list of dates. + (setq day-numbers (delq nil (mapcar (lambda(x) + (if (>= x today) x nil)) + day-numbers)))) + (switch-to-buffer-other-window + (get-buffer-create org-agenda-buffer-name)) + (setq buffer-read-only nil) + (erase-buffer) + (org-agenda-mode) (setq buffer-read-only nil) + (set (make-local-variable 'org-agenda-type) 'timeline) + (if doclosed (push :closed args)) + (push :timestamp args) + (if dotodo (push :todo args)) + (while (setq d (pop day-numbers)) + (if (and (>= d today) + dopast + past) + (progn + (setq past nil) + (insert (make-string 79 ?-) "\n"))) + (setq date (calendar-gregorian-from-absolute d)) + (setq s (point)) + (setq rtn (apply 'org-agenda-get-day-entries + entry date args)) + (if (or rtn (equal d today)) + (progn + (insert (calendar-day-name date) " " + (number-to-string (extract-calendar-day date)) " " + (calendar-month-name (extract-calendar-month date)) " " + (number-to-string (extract-calendar-year date)) "\n") + (put-text-property s (1- (point)) 'face + 'org-link) + (if (equal d today) + (put-text-property s (1- (point)) 'org-today t)) + (insert (org-finalize-agenda-entries rtn) "\n") + (put-text-property s (1- (point)) 'day d)))) + (goto-char (point-min)) + (setq buffer-read-only t) + (goto-char (or (text-property-any (point-min) (point-max) 'org-today t) + (point-min))) + (when (not org-select-timeline-window) + (select-window win) + (goto-char pos1)))) + +;;;###autoload +(defun org-agenda-list (&optional include-all start-day ndays keep-modes) + "Produce a weekly view from all files in variable `org-agenda-files'. +The view will be for the current week, but from the overview buffer you +will be able to go to other weeks. +With one \\[universal-argument] prefix argument INCLUDE-ALL, all unfinished TODO items will +also be shown, under the current date. +With two \\[universal-argument] prefix argument INCLUDE-ALL, all TODO entries marked DONE +on the days are also shown. See the variable `org-log-done' for how +to turn on logging. +START-DAY defaults to TODAY, or to the most recent match for the weekday +given in `org-agenda-start-on-weekday'. +NDAYS defaults to `org-agenda-ndays'." + (interactive "P") + (org-agenda-maybe-reset-markers 'force) + (org-compile-prefix-format org-agenda-prefix-format) + (require 'calendar) + (let* ((org-agenda-start-on-weekday + (if (or (equal ndays 1) + (and (null ndays) (equal 1 org-agenda-ndays))) + nil org-agenda-start-on-weekday)) + (org-agenda-keep-modes keep-modes) + (files (copy-sequence (org-agenda-files))) + (win (selected-window)) + (today (time-to-days (current-time))) + (sd (or start-day today)) + (start (if (or (null org-agenda-start-on-weekday) + (< org-agenda-ndays 7)) + sd + (let* ((nt (calendar-day-of-week + (calendar-gregorian-from-absolute sd))) + (n1 org-agenda-start-on-weekday) + (d (- nt n1))) + (- sd (+ (if (< d 0) 7 0) d))))) + (day-numbers (list start)) + (inhibit-redisplay t) + s e rtn rtnall file date d start-pos end-pos todayp nd) + (setq org-agenda-redo-command + (list 'org-agenda-list (list 'quote include-all) start-day ndays t)) + ;; Make the list of days + (setq ndays (or ndays org-agenda-ndays) + nd ndays) + (while (> ndays 1) + (push (1+ (car day-numbers)) day-numbers) + (setq ndays (1- ndays))) + (setq day-numbers (nreverse day-numbers)) + (if (not (equal (current-buffer) (get-buffer org-agenda-buffer-name))) + (progn + (delete-other-windows) + (switch-to-buffer-other-window + (get-buffer-create org-agenda-buffer-name)))) + (setq buffer-read-only nil) + (erase-buffer) + (org-agenda-mode) (setq buffer-read-only nil) + (set (make-local-variable 'org-agenda-type) 'agenda) + (set (make-local-variable 'starting-day) (car day-numbers)) + (set (make-local-variable 'include-all-loc) include-all) + (when (and (or include-all org-agenda-include-all-todo) + (member today day-numbers)) + (setq files (org-agenda-files) + rtnall nil) + (while (setq file (pop files)) + (catch 'nextfile + (org-check-agenda-file file) + (setq date (calendar-gregorian-from-absolute today) + rtn (org-agenda-get-day-entries + file date :todo)) + (setq rtnall (append rtnall rtn)))) + (when rtnall + (insert "ALL CURRENTLY OPEN TODO ITEMS:\n") + (add-text-properties (point-min) (1- (point)) + (list 'face 'org-link)) + (insert (org-finalize-agenda-entries rtnall) "\n"))) + (while (setq d (pop day-numbers)) + (setq date (calendar-gregorian-from-absolute d) + s (point)) + (if (or (setq todayp (= d today)) + (and (not start-pos) (= d sd))) + (setq start-pos (point)) + (if (and start-pos (not end-pos)) + (setq end-pos (point)))) + (setq files (org-agenda-files) + rtnall nil) + (while (setq file (pop files)) + (catch 'nextfile + (org-check-agenda-file file) + (if org-agenda-show-log + (setq rtn (org-agenda-get-day-entries + file date + :deadline :scheduled :timestamp :closed)) + (setq rtn (org-agenda-get-day-entries + file date + :deadline :scheduled :timestamp))) + (setq rtnall (append rtnall rtn)))) + (if org-agenda-include-diary + (progn + (require 'diary-lib) + (setq rtn (org-get-entries-from-diary date)) + (setq rtnall (append rtnall rtn)))) + (if (or rtnall org-agenda-show-all-dates) + (progn + (insert (format "%-9s %2d %s %4d\n" + (calendar-day-name date) + (extract-calendar-day date) + (calendar-month-name (extract-calendar-month date)) + (extract-calendar-year date))) + (put-text-property s (1- (point)) 'face + 'org-link) + (if rtnall (insert + (org-finalize-agenda-entries + (org-agenda-add-time-grid-maybe + rtnall nd todayp)) + "\n")) + (put-text-property s (1- (point)) 'day d)))) + (goto-char (point-min)) + (setq buffer-read-only t) + (org-fit-agenda-window) + (unless (and (pos-visible-in-window-p (point-min)) + (pos-visible-in-window-p (point-max))) + (goto-char (1- (point-max))) + (recenter -1) + (if (not (pos-visible-in-window-p (or start-pos 1))) + (progn + (goto-char (or start-pos 1)) + (recenter 1)))) + (goto-char (or start-pos 1)) + (if (not org-select-agenda-window) (select-window win)) + (message ""))) + +(defvar org-select-this-todo-keyword nil) + +;;;###autoload +(defun org-todo-list (arg &optional keep-modes) + "Show all TODO entries from all agenda file in a single list. +The prefix arg can be used to select a specific TODO keyword and limit +the list to these. When using \\[universal-argument], you will be prompted +for a keyword. A numeric prefix directly selects the Nth keyword in +`org-todo-keywords'." + (interactive "P") + (org-agenda-maybe-reset-markers 'force) + (org-compile-prefix-format org-agenda-prefix-format) + (let* ((org-agenda-keep-modes keep-modes) + (today (time-to-days (current-time))) + (date (calendar-gregorian-from-absolute today)) + (win (selected-window)) + (kwds org-todo-keywords) + (completion-ignore-case t) + (org-select-this-todo-keyword + (if (stringp arg) arg + (and arg (integerp arg) (nth (1- arg) org-todo-keywords)))) + rtn rtnall files file pos) + (when (equal arg '(4)) + (setq org-select-this-todo-keyword + (completing-read "Keyword: " (mapcar 'list org-todo-keywords) + nil t))) + (and (equal 0 arg) (setq org-select-this-todo-keyword nil)) + (if (not (equal (current-buffer) (get-buffer org-agenda-buffer-name))) + (progn + (delete-other-windows) + (switch-to-buffer-other-window + (get-buffer-create org-agenda-buffer-name)))) + (setq buffer-read-only nil) + (erase-buffer) + (org-agenda-mode) (setq buffer-read-only nil) + (set (make-local-variable 'org-agenda-type) 'todo) + (set (make-local-variable 'last-arg) arg) + (set (make-local-variable 'org-todo-keywords) kwds) + (set (make-local-variable 'org-agenda-redo-command) + '(org-todo-list (or current-prefix-arg last-arg) t)) + (setq files (org-agenda-files) + rtnall nil) + (while (setq file (pop files)) + (catch 'nextfile + (org-check-agenda-file file) + (setq rtn (org-agenda-get-day-entries file date :todo)) + (setq rtnall (append rtnall rtn)))) + (insert "Global list of TODO items of type: ") + (add-text-properties (point-min) (1- (point)) + (list 'face 'org-link)) + (setq pos (point)) + (insert (or org-select-this-todo-keyword "ALL") "\n") + (add-text-properties pos (1- (point)) (list 'face 'org-warning)) + (setq pos (point)) + (insert + "Available with `N r': (0)ALL " + (let ((n 0)) + (mapconcat (lambda (x) + (format "(%d)%s" (setq n (1+ n)) x)) + org-todo-keywords " ")) + "\n") + (add-text-properties pos (1- (point)) (list 'face 'org-link)) + (when rtnall + (insert (org-finalize-agenda-entries rtnall) "\n")) + (goto-char (point-min)) + (setq buffer-read-only t) + (org-fit-agenda-window) + (if (not org-select-agenda-window) (select-window win)))) + +(defun org-check-agenda-file (file) + "Make sure FILE exists. If not, ask user what to do." + ;; FIXME: this does not correctly change the menus + ;; Could probably be fixed by explicitly going to the buffer where + ;; the call originated. + (when (not (file-exists-p file)) + (message "non-existent file %s. [R]emove from agenda-files or [A]bort?" + file) + (let ((r (downcase (read-char-exclusive)))) + (cond + ((equal r ?r) + (org-remove-file file) + (throw 'nextfile t)) + (t (error "Abort")))))) + +(defun org-agenda-check-type (error &rest types) + "Check if agenda buffer is of allowed type. +If ERROR is non-nil, throw an error, otherwise just return nil." + (if (memq org-agenda-type types) + t + (if error + (error "Now allowed in %s-type agenda buffers" org-agenda-type) + nil))) + +(defun org-agenda-quit () + "Exit agenda by removing the window or the buffer." + (interactive) + (let ((buf (current-buffer))) + (if (not (one-window-p)) (delete-window)) + (kill-buffer buf) + (org-agenda-maybe-reset-markers 'force))) + +(defun org-agenda-exit () + "Exit agenda by removing the window or the buffer. +Also kill all Org-mode buffers which have been loaded by `org-agenda'. +Org-mode buffers visited directly by the user will not be touched." + (interactive) + (org-release-buffers org-agenda-new-buffers) + (setq org-agenda-new-buffers nil) + (org-agenda-quit)) + +(defun org-agenda-redo () + "Rebuild Agenda. +When this is the global TODO list, a prefix argument will be interpreted." + (interactive) + (message "Rebuilding agenda buffer...") + (eval org-agenda-redo-command) + (message "Rebuilding agenda buffer...done")) + +(defun org-agenda-goto-today () + "Go to today." + (interactive) + (org-agenda-check-type t 'timeline 'agenda) + (if (boundp 'starting-day) + (let ((cmd (car org-agenda-redo-command)) + (iall (nth 1 org-agenda-redo-command)) + (nday (nth 3 org-agenda-redo-command)) + (keep (nth 4 org-agenda-redo-command))) + (eval (list cmd iall nil nday keep))) + (goto-char (or (text-property-any (point-min) (point-max) 'org-today t) + (point-min))))) + +(defun org-agenda-later (arg) + "Go forward in time by `org-agenda-ndays' days. +With prefix ARG, go forward that many times `org-agenda-ndays'." + (interactive "p") + (org-agenda-check-type t 'agenda) + (org-agenda-list (if (boundp 'include-all-loc) include-all-loc nil) + (+ starting-day (* arg org-agenda-ndays)) nil t)) + +(defun org-agenda-earlier (arg) + "Go back in time by `org-agenda-ndays' days. +With prefix ARG, go back that many times `org-agenda-ndays'." + (interactive "p") + (org-agenda-check-type t 'agenda) + (org-agenda-list (if (boundp 'include-all-loc) include-all-loc nil) + (- starting-day (* arg org-agenda-ndays)) nil t)) + +(defun org-agenda-week-view () + "Switch to weekly view for agenda." + (interactive) + (org-agenda-check-type t 'agenda) + (setq org-agenda-ndays 7) + (org-agenda-list include-all-loc + (or (get-text-property (point) 'day) + starting-day) + nil t) + (org-agenda-set-mode-name) + (message "Switched to week view")) + +(defun org-agenda-day-view () + "Switch to daily view for agenda." + (interactive) + (org-agenda-check-type t 'agenda) + (setq org-agenda-ndays 1) + (org-agenda-list include-all-loc + (or (get-text-property (point) 'day) + starting-day) + nil t) + (org-agenda-set-mode-name) + (message "Switched to day view")) + +(defun org-agenda-next-date-line (&optional arg) + "Jump to the next line indicating a date in agenda buffer." + (interactive "p") + (org-agenda-check-type t 'agenda 'timeline) + (beginning-of-line 1) + (if (looking-at "^\\S-") (forward-char 1)) + (if (not (re-search-forward "^\\S-" nil t arg)) + (progn + (backward-char 1) + (error "No next date after this line in this buffer"))) + (goto-char (match-beginning 0))) + +(defun org-agenda-previous-date-line (&optional arg) + "Jump to the previous line indicating a date in agenda buffer." + (interactive "p") + (org-agenda-check-type t 'agenda 'timeline) + (beginning-of-line 1) + (if (not (re-search-backward "^\\S-" nil t arg)) + (error "No previous date before this line in this buffer"))) + +;; Initialize the highlight +(defvar org-hl (org-make-overlay 1 1)) +(org-overlay-put org-hl 'face 'highlight) + +(defun org-highlight (begin end &optional buffer) + "Highlight a region with overlay." + (funcall (if org-xemacs-p 'set-extent-endpoints 'move-overlay) + org-hl begin end (or buffer (current-buffer)))) + +(defun org-unhighlight () + "Detach overlay INDEX." + (funcall (if org-xemacs-p 'detach-extent 'delete-overlay) org-hl)) + + +(defun org-agenda-follow-mode () + "Toggle follow mode in an agenda buffer." + (interactive) + (setq org-agenda-follow-mode (not org-agenda-follow-mode)) + (org-agenda-set-mode-name) + (message "Follow mode is %s" + (if org-agenda-follow-mode "on" "off"))) + +(defun org-agenda-log-mode () + "Toggle log mode in an agenda buffer." + (interactive) + (org-agenda-check-type t 'agenda 'timeline) + (setq org-agenda-show-log (not org-agenda-show-log)) + (org-agenda-set-mode-name) + (org-agenda-redo) + (message "Log mode is %s" + (if org-agenda-show-log "on" "off"))) + +(defun org-agenda-toggle-diary () + "Toggle diary inclusion in an agenda buffer." + (interactive) + (org-agenda-check-type t 'agenda) + (setq org-agenda-include-diary (not org-agenda-include-diary)) + (org-agenda-redo) + (org-agenda-set-mode-name) + (message "Diary inclusion turned %s" + (if org-agenda-include-diary "on" "off"))) + +(defun org-agenda-toggle-time-grid () + "Toggle time grid in an agenda buffer." + (interactive) + (org-agenda-check-type t 'agenda) + (setq org-agenda-use-time-grid (not org-agenda-use-time-grid)) + (org-agenda-redo) + (org-agenda-set-mode-name) + (message "Time-grid turned %s" + (if org-agenda-use-time-grid "on" "off"))) + +(defun org-agenda-set-mode-name () + "Set the mode name to indicate all the small mode settings." + (setq mode-name + (concat "Org-Agenda" + (if (equal org-agenda-ndays 1) " Day" "") + (if (equal org-agenda-ndays 7) " Week" "") + (if org-agenda-follow-mode " Follow" "") + (if org-agenda-include-diary " Diary" "") + (if org-agenda-use-time-grid " Grid" "") + (if org-agenda-show-log " Log" ""))) + (force-mode-line-update)) + +(defun org-agenda-post-command-hook () + (and (eolp) (not (bolp)) (backward-char 1)) + (if (and org-agenda-follow-mode + (get-text-property (point) 'org-marker)) + (org-agenda-show))) + +(defvar org-disable-agenda-to-diary nil) ;Dynamically-scoped param. + +(defun org-get-entries-from-diary (date) + "Get the (Emacs Calendar) diary entries for DATE." + (let* ((fancy-diary-buffer "*temporary-fancy-diary-buffer*") + (diary-display-hook '(fancy-diary-display)) + (list-diary-entries-hook + (cons 'org-diary-default-entry list-diary-entries-hook)) + (diary-file-name-prefix-function nil) ; turn this feature off + (diary-modify-entry-list-string-function 'org-modify-diary-entry-string) + entries + (org-disable-agenda-to-diary t)) + (save-excursion + (save-window-excursion + (list-diary-entries date 1))) + (if (not (get-buffer fancy-diary-buffer)) + (setq entries nil) + (with-current-buffer fancy-diary-buffer + (setq buffer-read-only nil) + (if (= (point-max) 1) + ;; No entries + (setq entries nil) + ;; Omit the date and other unnecessary stuff + (org-agenda-cleanup-fancy-diary) + ;; Add prefix to each line and extend the text properties + (if (= (point-max) 1) + (setq entries nil) + (setq entries (buffer-substring (point-min) (- (point-max) 1))))) + (set-buffer-modified-p nil) + (kill-buffer fancy-diary-buffer))) + (when entries + (setq entries (org-split-string entries "\n")) + (setq entries + (mapcar + (lambda (x) + (setq x (org-format-agenda-item "" x "Diary" nil 'time)) + ;; Extend the text properties to the beginning of the line + (add-text-properties + 0 (length x) + (text-properties-at (1- (length x)) x) + x) + x) + entries))))) + +(defun org-agenda-cleanup-fancy-diary () + "Remove unwanted stuff in buffer created by `fancy-diary-display'. +This gets rid of the date, the underline under the date, and +the dummy entry installed by `org-mode' to ensure non-empty diary for each +date. It also removes lines that contain only whitespace." + (goto-char (point-min)) + (if (looking-at ".*?:[ \t]*") + (progn + (replace-match "") + (re-search-forward "\n=+$" nil t) + (replace-match "") + (while (re-search-backward "^ +\n?" nil t) (replace-match ""))) + (re-search-forward "\n=+$" nil t) + (delete-region (point-min) (min (point-max) (1+ (match-end 0))))) + (goto-char (point-min)) + (while (re-search-forward "^ +\n" nil t) + (replace-match "")) + (goto-char (point-min)) + (if (re-search-forward "^Org-mode dummy\n?" nil t) + (replace-match ""))) + +;; Make sure entries from the diary have the right text properties. +(eval-after-load "diary-lib" + '(if (boundp 'diary-modify-entry-list-string-function) + ;; We can rely on the hook, nothing to do + nil + ;; Hook not avaiable, must use advice to make this work + (defadvice add-to-diary-list (before org-mark-diary-entry activate) + "Make the position visible." + (if (and org-disable-agenda-to-diary ;; called from org-agenda + (stringp string) + buffer-file-name) + (setq string (org-modify-diary-entry-string string)))))) + +(defun org-modify-diary-entry-string (string) + "Add text properties to string, allowing org-mode to act on it." + (add-text-properties + 0 (length string) + (list 'mouse-face 'highlight + 'keymap org-agenda-keymap + 'help-echo + (format + "mouse-2 or RET jump to diary file %s" + (abbreviate-file-name buffer-file-name)) + 'org-agenda-diary-link t + 'org-marker (org-agenda-new-marker (point-at-bol))) + string) + string) + +(defun org-diary-default-entry () + "Add a dummy entry to the diary. +Needed to avoid empty dates which mess up holiday display." + ;; Catch the error if dealing with the new add-to-diary-alist + (when org-disable-agenda-to-diary + (condition-case nil + (add-to-diary-list original-date "Org-mode dummy" "") + (error + (add-to-diary-list original-date "Org-mode dummy" "" nil))))) + +(defun org-cycle-agenda-files () + "Cycle through the files in `org-agenda-files'. +If the current buffer visits an agenda file, find the next one in the list. +If the current buffer does not, find the first agenda file." + (interactive) + (let ((files (append org-agenda-files (list (car org-agenda-files)))) + (tcf (if buffer-file-name (file-truename buffer-file-name))) + file) + (unless files (error "No agenda files")) + (catch 'exit + (while (setq file (pop files)) + (if (equal (file-truename file) tcf) + (when (car files) + (find-file (car files)) + (throw 'exit t)))) + (find-file (car org-agenda-files))))) + +(defun org-agenda-file-to-end () + "Move/add the current file to the end of the agenda file list. +If the file is not present in the list, it is appended to the list. If it is +present, it is moved there." + (interactive) + (org-agenda-file-to-front 'to-end)) + +(defun org-agenda-file-to-front (&optional to-end) + "Move/add the current file to the top of the agenda file list. +If the file is not present in the list, it is added to the front. If it is +present, it is moved there. With optional argument TO-END, add/move to the +end of the list." + (interactive "P") + (let ((file-alist (mapcar (lambda (x) + (cons (file-truename x) x)) + org-agenda-files)) + (ctf (file-truename buffer-file-name)) + x had) + (setq x (assoc ctf file-alist) had x) + + (if (not x) (setq x (cons ctf (abbreviate-file-name buffer-file-name)))) + (if to-end + (setq file-alist (append (delq x file-alist) (list x))) + (setq file-alist (cons x (delq x file-alist)))) + (setq org-agenda-files (mapcar 'cdr file-alist)) + (let ((org-mode-hook nil) (default-major-mode 'fundamental-mode)) + (customize-save-variable 'org-agenda-files org-agenda-files)) + (org-install-agenda-files-menu) + (message "File %s to %s of agenda file list" + (if had "moved" "added") (if to-end "end" "front")))) + +(defun org-remove-file (&optional file) + "Remove current file from the list of files in variable `org-agenda-files'. +These are the files which are being checked for agenda entries. +Optional argument FILE means, use this file instead of the current." + (interactive) + (let* ((file (or file buffer-file-name)) + (true-file (file-truename file)) + (afile (abbreviate-file-name file)) + (files (delq nil (mapcar + (lambda (x) + (if (equal true-file + (file-truename x)) + nil x)) + org-agenda-files)))) + (if (not (= (length files) (length org-agenda-files))) + (progn + (setq org-agenda-files files) + (customize-save-variable 'org-agenda-files org-agenda-files) + (org-install-agenda-files-menu) + (message "Removed file: %s" afile)) + (message "File was not in list: %s" afile)))) + +(defun org-file-menu-entry (file) + (vector file (list 'find-file file) t)) +;; FIXME: Maybe we removed a buffer visited through the menu from +;; org-agenda-new-buffers, so that the buffer will not be removed +;; when exiting the agenda???? + +(defun org-get-all-dates (beg end &optional no-ranges force-today inactive) + "Return a list of all relevant day numbers from BEG to END buffer positions. +If NO-RANGES is non-nil, include only the start and end dates of a range, +not every single day in the range. If FORCE-TODAY is non-nil, make +sure that TODAY is included in the list. If INACTIVE is non-nil, also +inactive time stamps (those in square brackets) are included." + (let ((re (if inactive org-ts-regexp-both org-ts-regexp)) + dates date day day1 day2 ts1 ts2) + (if force-today + (setq dates (list (time-to-days (current-time))))) + (save-excursion + (goto-char beg) + (while (re-search-forward re end t) + (setq day (time-to-days (org-time-string-to-time + (substring (match-string 1) 0 10)))) + (or (memq day dates) (push day dates))) + (unless no-ranges + (goto-char beg) + (while (re-search-forward org-tr-regexp end t) + (setq ts1 (substring (match-string 1) 0 10) + ts2 (substring (match-string 2) 0 10) + day1 (time-to-days (org-time-string-to-time ts1)) + day2 (time-to-days (org-time-string-to-time ts2))) + (while (< (setq day1 (1+ day1)) day2) + (or (memq day1 dates) (push day1 dates))))) + (sort dates '<)))) + +;;;###autoload +(defun org-diary (&rest args) + "Return diary information from org-files. +This function can be used in a \"sexp\" diary entry in the Emacs calendar. +It accesses org files and extracts information from those files to be +listed in the diary. The function accepts arguments specifying what +items should be listed. The following arguments are allowed: + + :timestamp List the headlines of items containing a date stamp or + date range matching the selected date. Deadlines will + also be listed, on the expiration day. + + :deadline List any deadlines past due, or due within + `org-deadline-warning-days'. The listing occurs only + in the diary for *today*, not at any other date. If + an entry is marked DONE, it is no longer listed. + + :scheduled List all items which are scheduled for the given date. + The diary for *today* also contains items which were + scheduled earlier and are not yet marked DONE. + + :todo List all TODO items from the org-file. This may be a + long list - so this is not turned on by default. + Like deadlines, these entries only show up in the + diary for *today*, not at any other date. + +The call in the diary file should look like this: + + &%%(org-diary) ~/path/to/some/orgfile.org + +Use a separate line for each org file to check. Or, if you omit the file name, +all files listed in `org-agenda-files' will be checked automatically: + + &%%(org-diary) + +If you don't give any arguments (as in the example above), the default +arguments (:deadline :scheduled :timestamp) are used. So the example above may +also be written as + + &%%(org-diary :deadline :timestamp :scheduled) + +The function expects the lisp variables `entry' and `date' to be provided +by the caller, because this is how the calendar works. Don't use this +function from a program - use `org-agenda-get-day-entries' instead." + (org-agenda-maybe-reset-markers) + (org-compile-prefix-format org-agenda-prefix-format) + (setq args (or args '(:deadline :scheduled :timestamp))) + (let* ((files (if (and entry (stringp entry) (string-match "\\S-" entry)) + (list entry) + org-agenda-files)) + file rtn results) + ;; If this is called during org-agenda, don't return any entries to + ;; the calendar. Org Agenda will list these entries itself. + (if org-disable-agenda-to-diary (setq files nil)) + (while (setq file (pop files)) + (setq rtn (apply 'org-agenda-get-day-entries file date args)) + (setq results (append results rtn))) + (if results + (concat (org-finalize-agenda-entries results) "\n")))) +(defvar org-category-table nil) +(defun org-get-category-table () + "Get the table of categories and positions in current buffer." + (let (tbl) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "\\(^\\|\r\\)#\\+CATEGORY:[ \t]*\\(.*\\)" nil t) + (push (cons (point) (org-trim (match-string 2))) tbl))) + tbl)) +(defun org-get-category (&optional pos) + "Get the category applying to position POS." + (if (not org-category-table) + (cond + ((null org-category) + (setq org-category + (if buffer-file-name + (file-name-sans-extension + (file-name-nondirectory buffer-file-name)) + "???"))) + ((symbolp org-category) (symbol-name org-category)) + (t org-category)) + (let ((tbl org-category-table) + (pos (or pos (point)))) + (while (and tbl (> (caar tbl) pos)) + (pop tbl)) + (or (cdar tbl) (cdr (nth (1- (length org-category-table)) + org-category-table)))))) + +(defun org-agenda-get-day-entries (file date &rest args) + "Does the work for `org-diary' and `org-agenda'. +FILE is the path to a file to be checked for entries. DATE is date like +the one returned by `calendar-current-date'. ARGS are symbols indicating +which kind of entries should be extracted. For details about these, see +the documentation of `org-diary'." + (setq args (or args '(:deadline :scheduled :timestamp))) + (let* ((org-startup-with-deadline-check nil) + (org-startup-folded nil) + (buffer (if (file-exists-p file) + (org-get-agenda-file-buffer file) + (error "No such file %s" file))) + arg results rtn) + (if (not buffer) + ;; If file does not exist, make sure an error message ends up in diary + (list (format "ORG-AGENDA-ERROR: No such org-file %s" file)) + (with-current-buffer buffer + (unless (eq major-mode 'org-mode) + (error "Agenda file %s is not in `org-mode'" file)) + (setq org-category-table (org-get-category-table)) + (let ((case-fold-search nil)) + (save-excursion + (save-restriction + (if org-respect-restriction + (if (org-region-active-p) + ;; Respect a region to restrict search + (narrow-to-region (region-beginning) (region-end))) + ;; If we work for the calendar or many files, + ;; get rid of any restriction + (widen)) + ;; The way we repeatedly append to `results' makes it O(n^2) :-( + (while (setq arg (pop args)) + (cond + ((and (eq arg :todo) + (equal date (calendar-current-date))) + (setq rtn (org-agenda-get-todos)) + (setq results (append results rtn))) + ((eq arg :timestamp) + (setq rtn (org-agenda-get-blocks)) + (setq results (append results rtn)) + (setq rtn (org-agenda-get-timestamps)) + (setq results (append results rtn))) + ((eq arg :scheduled) + (setq rtn (org-agenda-get-scheduled)) + (setq results (append results rtn))) + ((eq arg :closed) + (setq rtn (org-agenda-get-closed)) + (setq results (append results rtn))) + ((and (eq arg :deadline) + (equal date (calendar-current-date))) + (setq rtn (org-agenda-get-deadlines)) + (setq results (append results rtn)))))))) + results)))) + +(defun org-entry-is-done-p () + "Is the current entry marked DONE?" + (save-excursion + (and (re-search-backward "[\r\n]\\*" nil t) + (looking-at org-nl-done-regexp)))) + +(defun org-at-date-range-p () + "Is the cursor inside a date range?" + (interactive) + (save-excursion + (catch 'exit + (let ((pos (point))) + (skip-chars-backward "^<\r\n") + (skip-chars-backward "<") + (and (looking-at org-tr-regexp) + (>= (match-end 0) pos) + (throw 'exit t)) + (skip-chars-backward "^<\r\n") + (skip-chars-backward "<") + (and (looking-at org-tr-regexp) + (>= (match-end 0) pos) + (throw 'exit t))) + nil))) + +(defun org-agenda-get-todos () + "Return the TODO information for agenda display." + (let* ((props (list 'face nil + 'done-face 'org-done + 'mouse-face 'highlight + 'keymap org-agenda-keymap + 'help-echo + (format "mouse-2 or RET jump to org file %s" + (abbreviate-file-name buffer-file-name)))) + (regexp (concat "[\n\r]\\*+ *\\(" + (if org-select-this-todo-keyword + (concat "\\<\\(" org-select-this-todo-keyword + "\\)\\>") + org-not-done-regexp) + "[^\n\r]*\\)")) + marker priority category tags + ee txt) + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (goto-char (match-beginning 1)) + (setq marker (org-agenda-new-marker (1+ (match-beginning 0))) + category (org-get-category) + tags (org-get-tags-at (point)) + txt (org-format-agenda-item "" (match-string 1) category tags) + priority + (+ (org-get-priority txt) + (if org-todo-kwd-priority-p + (- org-todo-kwd-max-priority -2 + (length + (member (match-string 2) org-todo-keywords))) + 1))) + (add-text-properties + 0 (length txt) (append (list 'org-marker marker 'org-hd-marker marker + 'priority priority 'category category) + props) + txt) + (push txt ee) + (goto-char (match-end 1))) + (nreverse ee))) + +(defconst org-agenda-no-heading-message + "No heading for this item in buffer or region.") + +(defun org-agenda-get-timestamps () + "Return the date stamp information for agenda display." + (let* ((props (list 'face nil + 'mouse-face 'highlight + 'keymap org-agenda-keymap + 'help-echo + (format "mouse-2 or RET jump to org file %s" + (abbreviate-file-name buffer-file-name)))) + (regexp (regexp-quote + (substring + (format-time-string + (car org-time-stamp-formats) + (apply 'encode-time ; DATE bound by calendar + (list 0 0 0 (nth 1 date) (car date) (nth 2 date)))) + 0 11))) + marker hdmarker deadlinep scheduledp donep tmp priority category + ee txt timestr tags) + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (if (not (save-match-data (org-at-date-range-p))) + (progn + (setq marker (org-agenda-new-marker (match-beginning 0)) + category (org-get-category (match-beginning 0)) + tmp (buffer-substring (max (point-min) + (- (match-beginning 0) + org-ds-keyword-length)) + (match-beginning 0)) + timestr (buffer-substring (match-beginning 0) (point-at-eol)) + deadlinep (string-match org-deadline-regexp tmp) + scheduledp (string-match org-scheduled-regexp tmp) + donep (org-entry-is-done-p)) + (if (string-match ">" timestr) + ;; substring should only run to end of time stamp + (setq timestr (substring timestr 0 (match-end 0)))) + (save-excursion + (if (re-search-backward "\\(^\\|\r\\)\\*+" nil t) + (progn + (goto-char (match-end 1)) + (setq hdmarker (org-agenda-new-marker) + tags (org-get-tags-at)) + (looking-at "\\*+[ \t]*\\([^\r\n]+\\)") + (setq txt (org-format-agenda-item + (format "%s%s" + (if deadlinep "Deadline: " "") + (if scheduledp "Scheduled: " "")) + (match-string 1) category tags timestr))) + (setq txt org-agenda-no-heading-message)) + (setq priority (org-get-priority txt)) + (add-text-properties + 0 (length txt) (append (list 'org-marker marker + 'org-hd-marker hdmarker) props) + txt) + (if deadlinep + (add-text-properties + 0 (length txt) + (list 'face + (if donep 'org-done 'org-warning) + 'undone-face 'org-warning + 'done-face 'org-done + 'category category + 'priority (+ 100 priority)) + txt) + (if scheduledp + (add-text-properties + 0 (length txt) + (list 'face 'org-scheduled-today + 'undone-face 'org-scheduled-today + 'done-face 'org-done + 'category category + priority (+ 99 priority)) + txt) + (add-text-properties + 0 (length txt) + (list 'priority priority 'category category) txt))) + (push txt ee)) + (outline-next-heading)))) + (nreverse ee))) + +(defun org-agenda-get-closed () + "Return the logged TODO entries for agenda display." + (let* ((props (list 'mouse-face 'highlight + 'keymap org-agenda-keymap + 'help-echo + (format "mouse-2 or RET jump to org file %s" + (abbreviate-file-name buffer-file-name)))) + (regexp (concat + "\\<" org-closed-string " *\\[" + (regexp-quote + (substring + (format-time-string + (car org-time-stamp-formats) + (apply 'encode-time ; DATE bound by calendar + (list 0 0 0 (nth 1 date) (car date) (nth 2 date)))) + 1 11)))) + marker hdmarker priority category tags + ee txt timestr) + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (if (not (save-match-data (org-at-date-range-p))) + (progn + (setq marker (org-agenda-new-marker (match-beginning 0)) + category (org-get-category (match-beginning 0)) + timestr (buffer-substring (match-beginning 0) (point-at-eol)) + ;; donep (org-entry-is-done-p) + ) + (if (string-match "\\]" timestr) + ;; substring should only run to end of time stamp + (setq timestr (substring timestr 0 (match-end 0)))) + (save-excursion + (if (re-search-backward "\\(^\\|\r\\)\\*+" nil t) + (progn + (goto-char (match-end 1)) + (setq hdmarker (org-agenda-new-marker) + tags (org-get-tags-at)) + (looking-at "\\*+[ \t]*\\([^\r\n]+\\)") + (setq txt (org-format-agenda-item + "Closed: " + (match-string 1) category tags timestr))) + (setq txt org-agenda-no-heading-message)) + (setq priority 100000) + (add-text-properties + 0 (length txt) (append (list 'org-marker marker + 'org-hd-marker hdmarker + 'face 'org-done + 'priority priority + 'category category + 'undone-face 'org-warning + 'done-face 'org-done) props) + txt) + (push txt ee)) + (outline-next-heading)))) + (nreverse ee))) + +(defun org-agenda-get-deadlines () + "Return the deadline information for agenda display." + (let* ((wdays org-deadline-warning-days) + (props (list 'mouse-face 'highlight + 'keymap org-agenda-keymap + 'help-echo + (format "mouse-2 or RET jump to org file %s" + (abbreviate-file-name buffer-file-name)))) + (regexp org-deadline-time-regexp) + (todayp (equal date (calendar-current-date))) ; DATE bound by calendar + (d1 (calendar-absolute-from-gregorian date)) ; DATE bound by calendar + d2 diff pos pos1 category tags + ee txt head) + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (setq pos (1- (match-beginning 1)) + d2 (time-to-days + (org-time-string-to-time (match-string 1))) + diff (- d2 d1)) + ;; When to show a deadline in the calendar: + ;; If the expiration is within wdays warning time. + ;; Past-due deadlines are only shown on the current date + (if (and (< diff wdays) todayp (not (= diff 0))) + (save-excursion + (setq category (org-get-category)) + (if (re-search-backward "\\(^\\|\r\\)\\*+[ \t]*" nil t) + (progn + (goto-char (match-end 0)) + (setq pos1 (match-end 1)) + (setq tags (org-get-tags-at pos1)) + (setq head (buffer-substring-no-properties + (point) + (progn (skip-chars-forward "^\r\n") + (point)))) + (if (string-match org-looking-at-done-regexp head) + (setq txt nil) + (setq txt (org-format-agenda-item + (format "In %3d d.: " diff) head category tags)))) + (setq txt org-agenda-no-heading-message)) + (when txt + (add-text-properties + 0 (length txt) + (append + (list 'org-marker (org-agenda-new-marker pos) + 'org-hd-marker (org-agenda-new-marker pos1) + 'priority (+ (- 10 diff) (org-get-priority txt)) + 'category category + 'face (cond ((<= diff 0) 'org-warning) + ((<= diff 5) 'org-scheduled-previously) + (t nil)) + 'undone-face (cond + ((<= diff 0) 'org-warning) + ((<= diff 5) 'org-scheduled-previously) + (t nil)) + 'done-face 'org-done) + props) + txt) + (push txt ee))))) + ee)) + +(defun org-agenda-get-scheduled () + "Return the scheduled information for agenda display." + (let* ((props (list 'face 'org-scheduled-previously + 'undone-face 'org-scheduled-previously + 'done-face 'org-done + 'mouse-face 'highlight + 'keymap org-agenda-keymap + 'help-echo + (format "mouse-2 or RET jump to org file %s" + (abbreviate-file-name buffer-file-name)))) + (regexp org-scheduled-time-regexp) + (todayp (equal date (calendar-current-date))) ; DATE bound by calendar + (d1 (calendar-absolute-from-gregorian date)) ; DATE bound by calendar + d2 diff pos pos1 category tags + ee txt head) + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (setq pos (1- (match-beginning 1)) + d2 (time-to-days + (org-time-string-to-time (match-string 1))) + diff (- d2 d1)) + ;; When to show a scheduled item in the calendar: + ;; If it is on or past the date. + (if (and (< diff 0) todayp) + (save-excursion + (setq category (org-get-category)) + (if (re-search-backward "\\(^\\|\r\\)\\*+[ \t]*" nil t) + (progn + (goto-char (match-end 0)) + (setq pos1 (match-end 1)) + (setq tags (org-get-tags-at)) + (setq head (buffer-substring-no-properties + (point) + (progn (skip-chars-forward "^\r\n") (point)))) + (if (string-match org-looking-at-done-regexp head) + (setq txt nil) + (setq txt (org-format-agenda-item + (format "Sched.%2dx: " (- 1 diff)) head + category tags)))) + (setq txt org-agenda-no-heading-message)) + (when txt + (add-text-properties + 0 (length txt) + (append (list 'org-marker (org-agenda-new-marker pos) + 'org-hd-marker (org-agenda-new-marker pos1) + 'priority (+ (- 5 diff) (org-get-priority txt)) + 'category category) + props) txt) + (push txt ee))))) + ee)) + +(defun org-agenda-get-blocks () + "Return the date-range information for agenda display." + (let* ((props (list 'face nil + 'mouse-face 'highlight + 'keymap org-agenda-keymap + 'help-echo + (format "mouse-2 or RET jump to org file %s" + (abbreviate-file-name buffer-file-name)))) + (regexp org-tr-regexp) + (d0 (calendar-absolute-from-gregorian date)) + marker hdmarker ee txt d1 d2 s1 s2 timestr category tags) + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (setq timestr (match-string 0) + s1 (match-string 1) + s2 (match-string 2) + d1 (time-to-days (org-time-string-to-time s1)) + d2 (time-to-days (org-time-string-to-time s2))) + (if (and (> (- d0 d1) -1) (> (- d2 d0) -1)) + ;; Only allow days between the limits, because the normal + ;; date stamps will catch the limits. + (save-excursion + (setq marker (org-agenda-new-marker (point))) + (setq category (org-get-category)) + (if (re-search-backward "\\(^\\|\r\\)\\*+" nil t) + (progn + (setq hdmarker (org-agenda-new-marker (match-end 1))) + (goto-char (match-end 1)) + (setq tags (org-get-tags-at)) + (looking-at "\\*+[ \t]*\\([^\r\n]+\\)") + (setq txt (org-format-agenda-item + (format (if (= d1 d2) "" "(%d/%d): ") + (1+ (- d0 d1)) (1+ (- d2 d1))) + (match-string 1) category tags + (if (= d0 d1) timestr)))) + (setq txt org-agenda-no-heading-message)) + (add-text-properties + 0 (length txt) (append (list 'org-marker marker + 'org-hd-marker hdmarker + 'priority (org-get-priority txt) + 'category category) + props) + txt) + (push txt ee))) + (outline-next-heading)) + ;; Sort the entries by expiration date. + (nreverse ee))) + +(defconst org-plain-time-of-day-regexp + (concat + "\\(\\<[012]?[0-9]" + "\\(\\(:\\([0-5][0-9]\\([AaPp][Mm]\\)?\\)\\)\\|\\([AaPp][Mm]\\)\\)\\>\\)" + "\\(--?" + "\\(\\<[012]?[0-9]" + "\\(\\(:\\([0-5][0-9]\\([AaPp][Mm]\\)?\\)\\)\\|\\([AaPp][Mm]\\)\\)\\>\\)" + "\\)?") + "Regular expression to match a plain time or time range. +Examples: 11:45 or 8am-13:15 or 2:45-2:45pm. After a match, the following +groups carry important information: +0 the full match +1 the first time, range or not +8 the second time, if it is a range.") + +(defconst org-stamp-time-of-day-regexp + (concat + "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} +[a-zA-Z]+ +\\)" + "\\([012][0-9]:[0-5][0-9]\\)>" + "\\(--?" + "<\\1\\([012][0-9]:[0-5][0-9]\\)>\\)?") + "Regular expression to match a timestamp time or time range. +After a match, the following groups carry important information: +0 the full match +1 date plus weekday, for backreferencing to make sure both times on same day +2 the first time, range or not +4 the second time, if it is a range.") + +(defvar org-prefix-has-time nil + "A flag, set by `org-compile-prefix-format'. +The flag is set if the currently compiled format contains a `%t'.") +(defvar org-prefix-has-tag nil + "A flag, set by `org-compile-prefix-format'. +The flag is set if the currently compiled format contains a `%T'.") + +(defun org-format-agenda-item (extra txt &optional category tags dotime noprefix) + "Format TXT to be inserted into the agenda buffer. +In particular, it adds the prefix and corresponding text properties. EXTRA +must be a string and replaces the `%s' specifier in the prefix format. +CATEGORY (string, symbol or nil) may be used to overrule the default +category taken from local variable or file name. It will replace the `%c' +specifier in the format. DOTIME, when non-nil, indicates that a +time-of-day should be extracted from TXT for sorting of this entry, and for +the `%t' specifier in the format. When DOTIME is a string, this string is +searched for a time before TXT is. NOPREFIX is a flag and indicates that +only the correctly processes TXT should be returned - this is used by +`org-agenda-change-all-lines'. TAG can be the tag of the headline." + (save-match-data + ;; Diary entries sometimes have extra whitespace at the beginning + (if (string-match "^ +" txt) (setq txt (replace-match "" nil nil txt))) + (let* ((category (or category + org-category + (if buffer-file-name + (file-name-sans-extension + (file-name-nondirectory buffer-file-name)) + ""))) + (tag (or (nth (1- (or (length tags) 0)) tags) "")) + time ;; needed for the eval of the prefix format + (ts (if dotime (concat (if (stringp dotime) dotime "") txt))) + (time-of-day (and dotime (org-get-time-of-day ts))) + stamp plain s0 s1 s2 rtn) + (when (and dotime time-of-day org-prefix-has-time) + ;; Extract starting and ending time and move them to prefix + (when (or (setq stamp (string-match org-stamp-time-of-day-regexp ts)) + (setq plain (string-match org-plain-time-of-day-regexp ts))) + (setq s0 (match-string 0 ts) + s1 (match-string (if plain 1 2) ts) + s2 (match-string (if plain 8 4) ts)) + + ;; If the times are in TXT (not in DOTIMES), and the prefix will list + ;; them, we might want to remove them there to avoid duplication. + ;; The user can turn this off with a variable. + (if (and org-agenda-remove-times-when-in-prefix (or stamp plain) + (string-match (concat (regexp-quote s0) " *") txt) + (if (eq org-agenda-remove-times-when-in-prefix 'beg) + (= (match-beginning 0) 0) + t)) + (setq txt (replace-match "" nil nil txt)))) + ;; Normalize the time(s) to 24 hour + (if s1 (setq s1 (org-get-time-of-day s1 'string))) + (if s2 (setq s2 (org-get-time-of-day s2 'string)))) + + (when (and (or (eq org-agenda-remove-tags-when-in-prefix t) + (and org-agenda-remove-tags-when-in-prefix + org-prefix-has-tag)) + (string-match ":[a-zA-Z_@0-9:]+:[ \t]*$" txt)) + (setq txt (replace-match "" t t txt))) + + ;; Create the final string + (if noprefix + (setq rtn txt) + ;; Prepare the variables needed in the eval of the compiled format + (setq time (cond (s2 (concat s1 "-" s2)) + (s1 (concat s1 "......")) + (t "")) + extra (or extra "") + category (if (symbolp category) (symbol-name category) category)) + ;; Evaluate the compiled format + (setq rtn (concat (eval org-prefix-format-compiled) txt))) + + ;; And finally add the text properties + (add-text-properties + 0 (length rtn) (list 'category (downcase category) + 'tags tags + 'prefix-length (- (length rtn) (length txt)) + 'time-of-day time-of-day + 'dotime dotime) + rtn) + rtn))) + +(defun org-agenda-add-time-grid-maybe (list ndays todayp) + (catch 'exit + (cond ((not org-agenda-use-time-grid) (throw 'exit list)) + ((and todayp (member 'today (car org-agenda-time-grid)))) + ((and (= ndays 1) (member 'daily (car org-agenda-time-grid)))) + ((member 'weekly (car org-agenda-time-grid))) + (t (throw 'exit list))) + (let* ((have (delq nil (mapcar + (lambda (x) (get-text-property 1 'time-of-day x)) + list))) + (string (nth 1 org-agenda-time-grid)) + (gridtimes (nth 2 org-agenda-time-grid)) + (req (car org-agenda-time-grid)) + (remove (member 'remove-match req)) + new time) + (if (and (member 'require-timed req) (not have)) + ;; don't show empty grid + (throw 'exit list)) + (while (setq time (pop gridtimes)) + (unless (and remove (member time have)) + (setq time (int-to-string time)) + (push (org-format-agenda-item + nil string "" nil ;; FIXME: put a category for the grid? + (concat (substring time 0 -2) ":" (substring time -2))) + new) + (put-text-property + 1 (length (car new)) 'face 'org-time-grid (car new)))) + (if (member 'time-up org-agenda-sorting-strategy) + (append new list) + (append list new))))) + +(defun org-compile-prefix-format (format) + "Compile the prefix format into a Lisp form that can be evaluated. +The resulting form is returned and stored in the variable +`org-prefix-format-compiled'." + (setq org-prefix-has-time nil org-prefix-has-tag nil) + (let ((start 0) varform vars var (s format)e c f opt) + (while (string-match "%\\(\\?\\)?\\([-+]?[0-9.]*\\)\\([ .;,:!?=|/<>]?\\)\\([cts]\\)" + s start) + (setq var (cdr (assoc (match-string 4 s) + '(("c" . category) ("t" . time) ("s" . extra) + ("T" . tag)))) + c (or (match-string 3 s) "") + opt (match-beginning 1) + start (1+ (match-beginning 0))) + (if (equal var 'time) (setq org-prefix-has-time t)) + (if (equal var 'tag) (setq org-prefix-has-tag t)) + (setq f (concat "%" (match-string 2 s) "s")) + (if opt + (setq varform + `(if (equal "" ,var) + "" + (format ,f (if (equal "" ,var) "" (concat ,var ,c))))) + (setq varform `(format ,f (if (equal ,var "") "" (concat ,var ,c))))) + (setq s (replace-match "%s" t nil s)) + (push varform vars)) + (setq vars (nreverse vars)) + (setq org-prefix-format-compiled `(format ,s ,@vars)))) + +(defun org-get-time-of-day (s &optional string) + "Check string S for a time of day. +If found, return it as a military time number between 0 and 2400. +If not found, return nil. +The optional STRING argument forces conversion into a 5 character wide string +HH:MM." + (save-match-data + (when + (or + (string-match + "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)\\([AaPp][Mm]\\)?\\> *" s) + (string-match + "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\([AaPp][Mm]\\)\\> *" s)) + (let* ((t0 (+ (* 100 + (+ (string-to-number (match-string 1 s)) + (if (and (match-beginning 4) + (equal (downcase (match-string 4 s)) "pm")) + 12 0))) + (if (match-beginning 3) + (string-to-number (match-string 3 s)) + 0))) + (t1 (concat " " + (if (< t0 100) "0" "") (if (< t0 10) "0" "") + (int-to-string t0)))) + (if string (concat (substring t1 -4 -2) ":" (substring t1 -2)) t0))))) + +(defun org-finalize-agenda-entries (list) + "Sort and concatenate the agenda items." + (mapconcat 'identity (sort list 'org-entries-lessp) "\n")) + +(defsubst org-cmp-priority (a b) + "Compare the priorities of string A and B." + (let ((pa (or (get-text-property 1 'priority a) 0)) + (pb (or (get-text-property 1 'priority b) 0))) + (cond ((> pa pb) +1) + ((< pa pb) -1) + (t nil)))) + +(defsubst org-cmp-category (a b) + "Compare the string values of categories of strings A and B." + (let ((ca (or (get-text-property 1 'category a) "")) + (cb (or (get-text-property 1 'category b) ""))) + (cond ((string-lessp ca cb) -1) + ((string-lessp cb ca) +1) + (t nil)))) + +(defsubst org-cmp-time (a b) + "Compare the time-of-day values of strings A and B." + (let* ((def (if org-sort-agenda-notime-is-late 2401 -1)) + (ta (or (get-text-property 1 'time-of-day a) def)) + (tb (or (get-text-property 1 'time-of-day b) def))) + (cond ((< ta tb) -1) + ((< tb ta) +1) + (t nil)))) + +(defun org-entries-lessp (a b) + "Predicate for sorting agenda entries." + ;; The following variables will be used when the form is evaluated. + (let* ((time-up (org-cmp-time a b)) + (time-down (if time-up (- time-up) nil)) + (priority-up (org-cmp-priority a b)) + (priority-down (if priority-up (- priority-up) nil)) + (category-up (org-cmp-category a b)) + (category-down (if category-up (- category-up) nil)) + (category-keep (if category-up +1 nil))) ; FIXME +1 or -1? + (cdr (assoc + (eval (cons 'or org-agenda-sorting-strategy)) + '((-1 . t) (1 . nil) (nil . nil)))))) + +(defun org-agenda-show-priority () + "Show the priority of the current item. +This priority is composed of the main priority given with the [#A] cookies, +and by additional input from the age of a schedules or deadline entry." + (interactive) + (let* ((pri (get-text-property (point-at-bol) 'priority))) + (message "Priority is %d" (if pri pri -1000)))) + +(defun org-agenda-show-tags () + "Show the tags applicable to the current item." + (interactive) + (let* ((tags (get-text-property (point-at-bol) 'tags))) + (if tags + (message "Tags are :%s:" (mapconcat 'identity tags ":")) + (message "No tags associated with this line")))) + +(defun org-agenda-goto (&optional highlight) + "Go to the Org-mode file which contains the item at point." + (interactive) + (let* ((marker (or (get-text-property (point) 'org-marker) + (org-agenda-error))) + (buffer (marker-buffer marker)) + (pos (marker-position marker))) + (switch-to-buffer-other-window buffer) + (widen) + (goto-char pos) + (when (eq major-mode 'org-mode) + (org-show-hidden-entry) + (save-excursion + (and (outline-next-heading) + (org-flag-heading nil)))) ; show the next heading + (and highlight (org-highlight (point-at-bol) (point-at-eol))))) + +(defun org-agenda-switch-to () + "Go to the Org-mode file which contains the item at point." + (interactive) + (let* ((marker (or (get-text-property (point) 'org-marker) + (org-agenda-error))) + (buffer (marker-buffer marker)) + (pos (marker-position marker))) + (switch-to-buffer buffer) + (delete-other-windows) + (widen) + (goto-char pos) + (when (eq major-mode 'org-mode) + (org-show-hidden-entry) + (save-excursion + (and (outline-next-heading) + (org-flag-heading nil)))))) ; show the next heading + +(defun org-agenda-goto-mouse (ev) + "Go to the Org-mode file which contains the item at the mouse click." + (interactive "e") + (mouse-set-point ev) + (org-agenda-goto)) + +(defun org-agenda-show () + "Display the Org-mode file which contains the item at point." + (interactive) + (let ((win (selected-window))) + (org-agenda-goto t) + (select-window win))) + +(defun org-agenda-recenter (arg) + "Display the Org-mode file which contains the item at point and recenter." + (interactive "P") + (let ((win (selected-window))) + (org-agenda-goto t) + (recenter arg) + (select-window win))) + +(defun org-agenda-show-mouse (ev) + "Display the Org-mode file which contains the item at the mouse click." + (interactive "e") + (mouse-set-point ev) + (org-agenda-show)) + +(defun org-agenda-check-no-diary () + "Check if the entry is a diary link and abort if yes." + (if (get-text-property (point) 'org-agenda-diary-link) + (org-agenda-error))) + +(defun org-agenda-error () + (error "Command not allowed in this line")) + +(defvar org-last-heading-marker (make-marker) + "Marker pointing to the headline that last changed its TODO state +by a remote command from the agenda.") + +(defun org-agenda-todo (&optional arg) + "Cycle TODO state of line at point, also in Org-mode file. +This changes the line at point, all other lines in the agenda referring to +the same tree node, and the headline of the tree node in the Org-mode file." + (interactive "P") + (org-agenda-check-no-diary) + (let* ((col (current-column)) + (marker (or (get-text-property (point) 'org-marker) + (org-agenda-error))) + (buffer (marker-buffer marker)) + (pos (marker-position marker)) + (hdmarker (get-text-property (point) 'org-hd-marker)) + (buffer-read-only nil) + newhead) + (with-current-buffer buffer + (widen) + (goto-char pos) + (org-show-hidden-entry) + (save-excursion + (and (outline-next-heading) + (org-flag-heading nil))) ; show the next heading + (org-todo arg) + (forward-char 1) + (setq newhead (org-get-heading)) + (save-excursion + (org-back-to-heading) + (move-marker org-last-heading-marker (point)))) + (beginning-of-line 1) + (save-excursion + (org-agenda-change-all-lines newhead hdmarker 'fixface)) + (move-to-column col))) + +(defun org-agenda-change-all-lines (newhead hdmarker &optional fixface) + "Change all lines in the agenda buffer which match HDMARKER. +The new content of the line will be NEWHEAD (as modified by +`org-format-agenda-item'). HDMARKER is checked with +`equal' against all `org-hd-marker' text properties in the file. +If FIXFACE is non-nil, the face of each item is modified acording to +the new TODO state." + (let* (props m pl undone-face done-face finish new dotime cat tags) +; (setq newhead (org-format-agenda-item "x" newhead "x" nil 'noprefix)) + (save-excursion + (goto-char (point-max)) + (beginning-of-line 1) + (while (not finish) + (setq finish (bobp)) + (when (and (setq m (get-text-property (point) 'org-hd-marker)) + (equal m hdmarker)) + (setq props (text-properties-at (point)) + dotime (get-text-property (point) 'dotime) + cat (get-text-property (point) 'category) + tags (get-text-property (point) 'tags) + new (org-format-agenda-item "x" newhead cat tags dotime 'noprefix) + pl (get-text-property (point) 'prefix-length) + undone-face (get-text-property (point) 'undone-face) + done-face (get-text-property (point) 'done-face)) + (move-to-column pl) + (if (looking-at ".*") + (progn + (replace-match new t t) + (beginning-of-line 1) + (add-text-properties (point-at-bol) (point-at-eol) props) + (if fixface + (add-text-properties + (point-at-bol) (point-at-eol) + (list 'face + (if org-last-todo-state-is-todo + undone-face done-face)))) + (beginning-of-line 1)) + (error "Line update did not work"))) + (beginning-of-line 0))))) + +(defun org-agenda-priority-up () + "Increase the priority of line at point, also in Org-mode file." + (interactive) + (org-agenda-priority 'up)) + +(defun org-agenda-priority-down () + "Decrease the priority of line at point, also in Org-mode file." + (interactive) + (org-agenda-priority 'down)) + +(defun org-agenda-priority (&optional force-direction) + "Set the priority of line at point, also in Org-mode file. +This changes the line at point, all other lines in the agenda referring to +the same tree node, and the headline of the tree node in the Org-mode file." + (interactive) + (org-agenda-check-no-diary) + (let* ((marker (or (get-text-property (point) 'org-marker) + (org-agenda-error))) + (buffer (marker-buffer marker)) + (pos (marker-position marker)) + (hdmarker (get-text-property (point) 'org-hd-marker)) + (buffer-read-only nil) + newhead) + (with-current-buffer buffer + (widen) + (goto-char pos) + (org-show-hidden-entry) + (save-excursion + (and (outline-next-heading) + (org-flag-heading nil))) ; show the next heading + (funcall 'org-priority force-direction) + (end-of-line 1) + (setq newhead (org-get-heading))) + (org-agenda-change-all-lines newhead hdmarker) + (beginning-of-line 1))) + +(defun org-get-tags-at (&optional pos) + "Get a list of all headline targs applicable at POS. +POS defaults to point. If tags are inherited, the list contains +the targets in the same sequence as the headlines appear, i.e. +the tags of the current headline come last." + (interactive) + (let (tags) + (save-excursion + (goto-char (or pos (point))) + (save-match-data + (org-back-to-heading t) + (condition-case nil + (while t + (if (looking-at "[^\r\n]+?:\\([a-zA-Z_@0-9:]+\\):[ \t]*\\([\n\r]\\|\\'\\)") + (setq tags (append (org-split-string (match-string 1) ":") tags))) + (or org-use-tag-inheritance (error "")) + (org-up-heading-all 1)) + (error nil)))) + (message "%s" tags) + tags)) + +(defun org-agenda-set-tags () + "Set tags for the current headline." + (interactive) + (org-agenda-check-no-diary) + (org-agenda-show) ;;; FIXME This is a stupid hack and should not be needed + (let* ((hdmarker (or (get-text-property (point) 'org-hd-marker) + (org-agenda-error))) + (buffer (marker-buffer hdmarker)) + (pos (marker-position hdmarker)) + (buffer-read-only nil) + newhead) + (with-current-buffer buffer + (widen) + (goto-char pos) + (org-show-hidden-entry) + (save-excursion + (and (outline-next-heading) + (org-flag-heading nil))) ; show the next heading + (call-interactively 'org-set-tags) + (end-of-line 1) + (setq newhead (org-get-heading))) + (org-agenda-change-all-lines newhead hdmarker) + (beginning-of-line 1))) + +(defun org-agenda-date-later (arg &optional what) + "Change the date of this item to one day later." + (interactive "p") + (org-agenda-check-type t 'agenda 'timeline) + (org-agenda-check-no-diary) + (let* ((marker (or (get-text-property (point) 'org-marker) + (org-agenda-error))) + (buffer (marker-buffer marker)) + (pos (marker-position marker))) + (with-current-buffer buffer + (widen) + (goto-char pos) + (if (not (org-at-timestamp-p)) + (error "Cannot find time stamp")) + (org-timestamp-change arg (or what 'day)) + (message "Time stamp changed to %s" org-last-changed-timestamp)))) + +(defun org-agenda-date-earlier (arg &optional what) + "Change the date of this item to one day earlier." + (interactive "p") + (org-agenda-date-later (- arg) what)) + +(defun org-agenda-date-prompt (arg) + "Change the date of this item. Date is prompted for, with default today. +The prefix ARG is passed to the `org-time-stamp' command and can therefore +be used to request time specification in the time stamp." + (interactive "P") + (org-agenda-check-type t 'agenda 'timeline) + (org-agenda-check-no-diary) + (let* ((marker (or (get-text-property (point) 'org-marker) + (org-agenda-error))) + (buffer (marker-buffer marker)) + (pos (marker-position marker))) + (with-current-buffer buffer + (widen) + (goto-char pos) + (if (not (org-at-timestamp-p)) + (error "Cannot find time stamp")) + (org-time-stamp arg) + (message "Time stamp changed to %s" org-last-changed-timestamp)))) + +(defun org-get-heading () + "Return the heading of the current entry, without the stars." + (save-excursion + (and (memq (char-before) '(?\n ?\r)) (skip-chars-forward "^\n\r")) +;;FIXME???????? (and (bolp) (end-of-line 1)) + (if (and (re-search-backward "[\r\n]\\*" nil t) + (looking-at "[\r\n]\\*+[ \t]+\\([^\r\n]*\\)")) + (match-string 1) + ""))) + +(defun org-agenda-diary-entry () + "Make a diary entry, like the `i' command from the calendar. +All the standard commands work: block, weekly etc." + (interactive) + (org-agenda-check-type t 'agenda 'timeline) + (require 'diary-lib) + (let* ((char (progn + (message "Diary entry: [d]ay [w]eekly [m]onthly [y]early [a]nniversary [b]lock [c]yclic") + (read-char-exclusive))) + (cmd (cdr (assoc char + '((?d . insert-diary-entry) + (?w . insert-weekly-diary-entry) + (?m . insert-monthly-diary-entry) + (?y . insert-yearly-diary-entry) + (?a . insert-anniversary-diary-entry) + (?b . insert-block-diary-entry) + (?c . insert-cyclic-diary-entry))))) + (oldf (symbol-function 'calendar-cursor-to-date)) + (point (point)) + (mark (or (mark t) (point)))) + (unless cmd + (error "No command associated with <%c>" char)) + (unless (and (get-text-property point 'day) + (or (not (equal ?b char)) + (get-text-property mark 'day))) + (error "Don't know which date to use for diary entry")) + ;; We implement this by hacking the `calendar-cursor-to-date' function + ;; and the `calendar-mark-ring' variable. Saves a lot of code. + (let ((calendar-mark-ring + (list (calendar-gregorian-from-absolute + (or (get-text-property mark 'day) + (get-text-property point 'day)))))) + (unwind-protect + (progn + (fset 'calendar-cursor-to-date + (lambda (&optional error) + (calendar-gregorian-from-absolute + (get-text-property point 'day)))) + (call-interactively cmd)) + (fset 'calendar-cursor-to-date oldf))))) + + +(defun org-agenda-execute-calendar-command (cmd) + "Execute a calendar command from the agenda, with the date associated to +the cursor position." + (org-agenda-check-type t 'agenda 'timeline) + (require 'diary-lib) + (unless (get-text-property (point) 'day) + (error "Don't know which date to use for calendar command")) + (let* ((oldf (symbol-function 'calendar-cursor-to-date)) + (point (point)) + (date (calendar-gregorian-from-absolute + (get-text-property point 'day))) + (displayed-day (extract-calendar-day date)) + (displayed-month (extract-calendar-month date)) + (displayed-year (extract-calendar-year date))) + (unwind-protect + (progn + (fset 'calendar-cursor-to-date + (lambda (&optional error) + (calendar-gregorian-from-absolute + (get-text-property point 'day)))) + (call-interactively cmd)) + (fset 'calendar-cursor-to-date oldf)))) + +(defun org-agenda-phases-of-moon () + "Display the phases of the moon for the 3 months around the cursor date." + (interactive) + (org-agenda-execute-calendar-command 'calendar-phases-of-moon)) + +(defun org-agenda-holidays () + "Display the holidays for the 3 months around the cursor date." + (interactive) + (org-agenda-execute-calendar-command 'list-calendar-holidays)) + +(defun org-agenda-sunrise-sunset (arg) + "Display sunrise and sunset for the cursor date. +Latitude and longitude can be specified with the variables +`calendar-latitude' and `calendar-longitude'. When called with prefix +argument, latitude and longitude will be prompted for." + (interactive "P") + (let ((calendar-longitude (if arg nil calendar-longitude)) + (calendar-latitude (if arg nil calendar-latitude)) + (calendar-location-name + (if arg "the given coordinates" calendar-location-name))) + (org-agenda-execute-calendar-command 'calendar-sunrise-sunset))) + +(defun org-agenda-goto-calendar () + "Open the Emacs calendar with the date at the cursor." + (interactive) + (org-agenda-check-type t 'agenda 'timeline) + (let* ((day (or (get-text-property (point) 'day) + (error "Don't know which date to open in calendar"))) + (date (calendar-gregorian-from-absolute day)) + (calendar-move-hook nil) + (view-diary-entries-initially nil)) + (calendar) + (calendar-goto-date date))) + +(defun org-calendar-goto-agenda () + "Compute the Org-mode agenda for the calendar date displayed at the cursor. +This is a command that has to be installed in `calendar-mode-map'." + (interactive) + (org-agenda-list nil (calendar-absolute-from-gregorian + (calendar-cursor-to-date)) + nil t)) + +(defun org-agenda-convert-date () + (interactive) + (org-agenda-check-type t 'agenda 'timeline) + (let ((day (get-text-property (point) 'day)) + date s) + (unless day + (error "Don't know which date to convert")) + (setq date (calendar-gregorian-from-absolute day)) + (setq s (concat + "Gregorian: " (calendar-date-string date) "\n" + "ISO: " (calendar-iso-date-string date) "\n" + "Day of Yr: " (calendar-day-of-year-string date) "\n" + "Julian: " (calendar-julian-date-string date) "\n" + "Astron. JD: " (calendar-astro-date-string date) + " (Julian date number at noon UTC)\n" + "Hebrew: " (calendar-hebrew-date-string date) " (until sunset)\n" + "Islamic: " (calendar-islamic-date-string date) " (until sunset)\n" + "French: " (calendar-french-date-string date) "\n" + "Mayan: " (calendar-mayan-date-string date) "\n" + "Coptic: " (calendar-coptic-date-string date) "\n" + "Ethiopic: " (calendar-ethiopic-date-string date) "\n" + "Persian: " (calendar-persian-date-string date) "\n" + "Chinese: " (calendar-chinese-date-string date) "\n")) + (with-output-to-temp-buffer "*Dates*" + (princ s)) + (if (fboundp 'fit-window-to-buffer) + (fit-window-to-buffer (get-buffer-window "*Dates*"))))) + +;;; Tags + +(defun org-scan-tags (action matcher &optional todo-only) + "Scan headline tags with inheritance and produce output ACTION. +ACTION can be `sparse-tree' or `agenda'. MATCHER is a Lisp form to be +evaluated, testing if a given set of tags qualifies a headline for +inclusion. When TODO-ONLY is non-nil, only lines with a TODO keyword +are included in the output." + (let* ((re (concat "[\n\r]" outline-regexp " *\\(\\<\\(" + (mapconcat 'regexp-quote + (nreverse (cdr (reverse org-todo-keywords))) + "\\|") + "\\>\\)\\)? *\\(.*?\\)\\(:[A-Za-z_@0-9:]+:\\)?[ \t]*[\n\r]")) + (props (list 'face nil + 'done-face 'org-done + 'undone-face nil + 'mouse-face 'highlight + 'keymap org-agenda-keymap + 'help-echo + (format "mouse-2 or RET jump to org file %s" + (abbreviate-file-name buffer-file-name)))) + lspos + tags tags-list tags-alist (llast 0) rtn level category i txt + todo marker) + + (save-excursion + (goto-char (point-min)) + (when (eq action 'sparse-tree) (hide-sublevels 1)) + (while (re-search-forward re nil t) + (setq todo (if (match-end 1) (match-string 2)) + tags (if (match-end 4) (match-string 4))) + (goto-char (setq lspos (1+ (match-beginning 0)))) + (setq level (funcall outline-level) + category (org-get-category)) + (setq i llast llast level) + ;; remove tag lists from same and sublevels + (while (>= i level) + (when (setq entry (assoc i tags-alist)) + (setq tags-alist (delete entry tags-alist))) + (setq i (1- i))) + ;; add the nex tags + (when tags + (setq tags (mapcar 'downcase (org-split-string tags ":")) + tags-alist + (cons (cons level tags) tags-alist))) + ;; compile tags for current headline + (setq tags-list + (if org-use-tag-inheritance + (apply 'append (mapcar 'cdr tags-alist)) + tags)) + (when (and (or (not todo-only) todo) + (eval matcher)) + ;; list this headline + (if (eq action 'sparse-tree) + (progn + (org-show-hierarchy-above)) + (setq txt (org-format-agenda-item + "" + (concat + (if org-tags-match-list-sublevels + (make-string (1- level) ?.) "") + (org-get-heading)) + category tags-list)) + (goto-char lspos) + (setq marker (org-agenda-new-marker)) + (add-text-properties + 0 (length txt) + (append (list 'org-marker marker 'org-hd-marker marker + 'category category) + props) + txt) + (push txt rtn)) + ;; if we are to skip sublevels, jump to end of subtree + (point) + (or org-tags-match-list-sublevels (org-end-of-subtree))))) + (nreverse rtn))) + +(defun org-tags-sparse-tree (&optional arg match) + "Create a sparse tree according to tags search string MATCH. +MATCH can contain positive and negative selection of tags, like +\"+WORK+URGENT-WITHBOSS\"." + (interactive "P") + (let ((org-show-following-heading nil) + (org-show-hierarchy-above nil)) + (org-scan-tags 'sparse-tree (cdr (org-make-tags-matcher match))))) + +(defun org-make-tags-matcher (match) + "Create the TAGS matcher form for the tags-selecting string MATCH." + (unless match + ;; Get a new match request, with completion + (setq org-last-tags-completion-table + (or (org-get-buffer-tags) + org-last-tags-completion-table)) + (setq match (completing-read + "Tags: " 'org-tags-completion-function nil nil nil + 'org-tags-history))) + ;; parse the string and create a lisp form + (let ((match0 match) minus tag mm matcher orterms term orlist) + (setq orterms (org-split-string match "|")) + (while (setq term (pop orterms)) + (while (string-match "^&?\\([-+:]\\)?\\([A-Za-z_@0-9]+\\)" term) + (setq minus (and (match-end 1) + (equal (match-string 1 term) "-")) + tag (match-string 2 term) + term (substring term (match-end 0)) + mm (list 'member (downcase tag) 'tags-list) + mm (if minus (list 'not mm) mm)) + (push mm matcher)) + (push (if (> (length matcher) 1) (cons 'and matcher) (car matcher)) + orlist) + (setq matcher nil)) + (setq matcher (if (> (length orlist) 1) (cons 'or orlist) (car orlist))) + ;; Return the string and lisp forms of the matcher + (cons match0 matcher))) + +;;;###autoload +(defun org-tags-view (&optional todo-only match keep-modes) + "Show all headlines for all `org-agenda-files' matching a TAGS criterion. +The prefix arg TODO-ONLY limits the search to TODO entries." + (interactive "P") + (org-agenda-maybe-reset-markers 'force) + (org-compile-prefix-format org-agenda-prefix-format) + (let* ((org-agenda-keep-modes keep-modes) + (org-tags-match-list-sublevels + (if todo-only t org-tags-match-list-sublevels)) + (win (selected-window)) + (completion-ignore-case t) + rtn rtnall files file pos matcher + buffer) + (setq matcher (org-make-tags-matcher match) + match (car matcher) matcher (cdr matcher)) + (if (not (equal (current-buffer) (get-buffer org-agenda-buffer-name))) + (progn + (delete-other-windows) + (switch-to-buffer-other-window + (get-buffer-create org-agenda-buffer-name)))) + (setq buffer-read-only nil) + (erase-buffer) + (org-agenda-mode) (setq buffer-read-only nil) + (set (make-local-variable 'org-agenda-type) 'tags) + (set (make-local-variable 'org-agenda-redo-command) + (list 'org-tags-view (list 'quote todo-only) + (list 'if 'current-prefix-arg nil match) t)) + (setq files (org-agenda-files) + rtnall nil) + (while (setq file (pop files)) + (catch 'nextfile + (org-check-agenda-file file) + (setq buffer (if (file-exists-p file) + (org-get-agenda-file-buffer file) + (error "No such file %s" file))) + (if (not buffer) + ;; If file does not exist, merror message to agenda + (setq rtn (list + (format "ORG-AGENDA-ERROR: No such org-file %s" file)) + rtnall (append rtnall rtn)) + (with-current-buffer buffer + (unless (eq major-mode 'org-mode) + (error "Agenda file %s is not in `org-mode'" file)) + (save-excursion + (save-restriction + (if org-respect-restriction + (if (org-region-active-p) + ;; Respect a region to restrict search + (narrow-to-region (region-beginning) (region-end))) + ;; If we work for the calendar or many files, + ;; get rid of any restriction + (widen)) + (setq rtn (org-scan-tags 'agenda matcher todo-only)) + (setq rtnall (append rtnall rtn)))))))) + (insert "Headlines with TAGS match: ") + (add-text-properties (point-min) (1- (point)) + (list 'face 'org-link)) + (setq pos (point)) + (insert match "\n") + (add-text-properties pos (1- (point)) (list 'face 'org-warning)) + (setq pos (point)) + (insert "Press `C-u r' to search again with new search string\n") + (add-text-properties pos (1- (point)) (list 'face 'org-link)) + (when rtnall + (insert (mapconcat 'identity rtnall "\n"))) + (goto-char (point-min)) + (setq buffer-read-only t) + (org-fit-agenda-window) + (if (not org-select-agenda-window) (select-window win)))) + +(defvar org-add-colon-after-tag-completion nil) ;; dynamically skoped param +(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." + (interactive) + (let* (;(inherit (org-get-inherited-tags)) + (re (concat "^" outline-regexp)) + (col (current-column)) + (current (org-get-tags)) + tags hd empty invis) + (if arg + (save-excursion + (goto-char (point-min)) + (while (re-search-forward re nil t) + (org-set-tags nil t)) + (message "All tags realigned to column %d" org-tags-column)) + (if just-align + (setq tags current) + (setq org-last-tags-completion-table + (or (org-get-buffer-tags) + org-last-tags-completion-table)) + (setq tags + (let ((org-add-colon-after-tag-completion t)) + (completing-read "Tags: " 'org-tags-completion-function + nil nil current 'org-tags-history))) + (while (string-match "[-+&]+" tags) + (setq tags (replace-match ":" t t tags)))) + ;; FIXME: still optimize this by not checking when JUST-ALIGN? + (unless (setq empty (string-match "\\`[\t ]*\\'" tags)) + (unless (string-match ":$" tags) (setq tags (concat tags ":"))) + (unless (string-match "^:" tags) (setq tags (concat ":" tags)))) + (if (equal current "") + (progn + (end-of-line 1) + (or empty (insert-before-markers " "))) + (beginning-of-line 1) + (setq invis (org-invisible-p)) + (looking-at (concat "\\(.*\\)\\(" (regexp-quote current) "\\)[ \t]*")) + (setq hd (match-string 1)) + (delete-region (match-beginning 0) (match-end 0)) + (insert-before-markers (org-trim hd) (if empty "" " "))) + ;; FIXME: What happens when adding a new tag??? Seems OK!!! + (unless (equal tags "") + (move-to-column (max (current-column) + (if (> org-tags-column 0) + org-tags-column + (- (- org-tags-column) (length tags)))) + t) + (insert-before-markers tags) + (if (and (not invis) (org-invisible-p)) + (outline-flag-region (point-at-bol) (point) nil))) + (move-to-column col)))) + +(defun org-tags-completion-function (string predicate &optional flag) + (let (s1 s2 rtn (ctable org-last-tags-completion-table)) + (if (string-match "^\\(.*[-+:&|]\\)\\([^-+:&|]*\\)$" string) + (setq s1 (match-string 1 string) + s2 (match-string 2 string)) + (setq s1 "" s2 string)) + (cond + ((eq flag nil) + ;; try completion + (setq rtn (try-completion s2 ctable)) + (if (stringp rtn) + (concat s1 s2 (substring rtn (length s2)) + (if (and org-add-colon-after-tag-completion + (assoc rtn ctable)) + ":" ""))) + ) + ((eq flag t) + ;; all-completions + (all-completions s2 ctable) + ) + ((eq flag 'lambda) + ;; exact match? + (assoc s2 ctable))) + )) + +(defun org-get-tags () + "Get the TAGS string in the current headline." + (unless (org-on-heading-p) + (error "Not on a heading")) + (save-excursion + (beginning-of-line 1) + (if (looking-at ".*[ \t]\\(:[A-Za-z_@0-9:]+:\\)[ \t]*\\(\r\\|$\\)") + (match-string 1) + ""))) + +(defun org-get-buffer-tags () + "Get a table of all tags used in the buffer, for completion." + (let (tags) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "[ \t]:\\([A-Za-z_@0-9:]+\\):[ \t\r\n]" nil t) + (mapc (lambda (x) (add-to-list 'tags x)) + (org-split-string (match-string 1) ":")))) + (mapcar 'list tags))) + +;;; Link Stuff + +(defun org-find-file-at-mouse (ev) + "Open file link or URL at mouse." + (interactive "e") + (mouse-set-point ev) + (org-open-at-point 'in-emacs)) + +(defun org-open-at-mouse (ev) + "Open file link or URL at mouse." + (interactive "e") + (mouse-set-point ev) + (org-open-at-point)) + +(defun org-open-at-point (&optional in-emacs) + "Open link at or after point. +If there is no link at point, this function will search forward up to +the end of the current subtree. +Normally, files will be opened by an appropriate application. If the +optional argument IN-EMACS is non-nil, Emacs will visit the file." + (interactive "P") + (org-remove-occur-highlights nil nil t) + (if (org-at-timestamp-p) + (org-agenda-list nil (time-to-days (org-time-string-to-time + (substring (match-string 1) 0 10))) + 1) + (let (type path link line search (pos (point))) + (catch 'match + (save-excursion + (skip-chars-forward "^]\n\r") + (when (and (re-search-backward "\\[\\[" nil t) + (looking-at org-bracket-link-regexp) + (<= (match-beginning 0) pos) + (>= (match-end 0) pos)) + (setq link (match-string 1)) + (while (string-match " *\n *" link) + (setq link (replace-match " " t t link))) + (if (string-match org-link-regexp link) + (setq type (match-string 1 link) + path (match-string 2 link)) + (setq type "thisfile" + path link)) + (throw 'match t))) + + (when (get-text-property (point) 'org-linked-text) + (setq type "thisfile" + pos (if (get-text-property (1+ (point)) 'org-linked-text) + (1+ (point)) (point)) + path (buffer-substring + (previous-single-property-change pos 'org-linked-text) + (next-single-property-change pos 'org-linked-text))) + (throw 'match t)) + + (save-excursion + (skip-chars-backward + (concat (if org-allow-space-in-links "^" "^ ") + org-non-link-chars)) + (when (or (looking-at org-link-regexp) + (and (re-search-forward org-link-regexp (point-at-eol) t) + (<= (match-beginning 0) pos) + (>= (match-end 0) pos))) + (setq type (match-string 1) + path (match-string 2)) + (throw 'match t))) + (save-excursion + (skip-chars-backward "^ \t\n\r") + (when (looking-at "\\(:[A-Za-z_@0-9:]+\\):[ \t\r\n]") + (setq type "tags" + path (match-string 1)) + (while (string-match ":" path) + (setq path (replace-match "+" t t path))) + (throw 'match t))) + (save-excursion + (skip-chars-backward "a-zA-Z_") + (when (and org-activate-camels + (looking-at org-camel-regexp)) + (setq type "camel" path (match-string 0)) + (if (equal (char-before) ?*) + (setq path (concat "*" path)))) + (throw 'match t)) + (save-excursion + (when (re-search-forward + org-link-regexp + (save-excursion + (condition-case nil + (progn (outline-end-of-subtree) (max pos (point))) + (error (end-of-line 1) (point)))) + t) + (setq type (match-string 1) + path (match-string 2))))) + (unless path + (error "No link found")) + ;; Remove any trailing spaces in path + (if (string-match " +\\'" path) + (setq path (replace-match "" t t path))) + + (cond + + ((member type '("http" "https" "ftp" "mailto" "news")) + (browse-url (concat type ":" path))) + + ((string= type "tags") + (org-tags-view in-emacs path)) + ((or (string= type "camel") + (string= type "thisfile")) + (org-mark-ring-push) + (org-link-search + path + (cond ((equal in-emacs '(4)) 'occur) + ((equal in-emacs '(16)) 'org-occur) + (t nil)))) + + ((string= type "file") + (if (string-match "::?\\([0-9]+\\)\\'" path) ;; second : optional + (setq line (string-to-number (match-string 1 path)) + path (substring path 0 (match-beginning 0))) + (if (string-match "::\\(.+\\)\\'" path) + (setq search (match-string 1 path) + path (substring path 0 (match-beginning 0))))) + (org-open-file path in-emacs line search)) + + ((string= type "news") + (org-follow-gnus-link path)) + + ((string= type "bbdb") + (org-follow-bbdb-link path)) + + ((string= type "gnus") + (let (group article) + (if (not (string-match "\\`\\([^#]+\\)\\(#\\(.*\\)\\)?" path)) + (error "Error in Gnus link")) + (setq group (match-string 1 path) + article (match-string 3 path)) + (org-follow-gnus-link group article))) + + ((string= type "vm") + (let (folder article) + (if (not (string-match "\\`\\([^#]+\\)\\(#\\(.*\\)\\)?" path)) + (error "Error in VM link")) + (setq folder (match-string 1 path) + article (match-string 3 path)) + ;; in-emacs is the prefix arg, will be interpreted as read-only + (org-follow-vm-link folder article in-emacs))) + + ((string= type "wl") + (let (folder article) + (if (not (string-match "\\`\\([^#]+\\)\\(#\\(.*\\)\\)?" path)) + (error "Error in Wanderlust link")) + (setq folder (match-string 1 path) + article (match-string 3 path)) + (org-follow-wl-link folder article))) + + ((string= type "mhe") + (let (folder article) + (if (not (string-match "\\`\\([^#]+\\)\\(#\\(.*\\)\\)?" path)) + (error "Error in MHE link")) + (setq folder (match-string 1 path) + article (match-string 3 path)) + (org-follow-mhe-link folder article))) + + ((string= type "rmail") + (let (folder article) + (if (not (string-match "\\`\\([^#]+\\)\\(#\\(.*\\)\\)?" path)) + (error "Error in RMAIL link")) + (setq folder (match-string 1 path) + article (match-string 3 path)) + (org-follow-rmail-link folder article))) + + ((string= type "shell") + (let ((cmd path)) + (while (string-match "@{" cmd) + (setq cmd (replace-match "<" t t cmd))) + (while (string-match "@}" cmd) + (setq cmd (replace-match ">" t t cmd))) + (if (or (not org-confirm-shell-links) + (yes-or-no-p (format "Execute \"%s\" in the shell? " cmd))) + (shell-command cmd) + (error "Abort")))) + + (t + (browse-url-at-point)))))) + +(defun org-link-search (s &optional type) + "Search for a link search option. +When S is a CamelCaseWord, search for a target, or for a sentence containing +the words. If S is surrounded by forward slashes, it is interpreted as a +regular expression. In org-mode files, this will create an `org-occur' +sparse tree. In ordinary files, `occur' will be used to list matches. +If the current buffer is in `dired-mode', grep will be used to search +in all files." + (let ((case-fold-search t) + (s0 (mapconcat 'identity (org-split-string s "[ \t\r\n]+") " ")) + (pos (point)) + (pre "") (post "") + words re0 re1 re2 re3 re4 re5 re2a reall camel) + (cond ((save-excursion + (goto-char (point-min)) + (and + (re-search-forward + (concat "<<" (regexp-quote s0) ">>") nil t) + (setq pos (match-beginning 0)))) + ;; There is an exact target for this + (goto-char pos)) + ((string-match "^/\\(.*\\)/$" s) + ;; A regular expression + (cond + ((eq major-mode 'org-mode) + (org-occur (match-string 1 s))) + ;;((eq major-mode 'dired-mode) + ;; (grep (concat "grep -n -e '" (match-string 1 s) "' *"))) + (t (org-do-occur (match-string 1 s))))) + ((or (setq camel (string-match (concat "^" org-camel-regexp "$") s)) + t) + ;; A camel or a normal search string + (when (equal (string-to-char s) ?*) + ;; Anchor on headlines, post may include tags. + (setq pre "^\\*+[ \t]*\\(\\sw+\\)?[ \t]*" + post "[ \t]*\\([ \t]+:[a-zA-Z_@0-9:+]:[ \t]*\\)?$" + s (substring s 1))) + (remove-text-properties + 0 (length s) + '(face nil mouse-face nil keymap nil fontified nil) s) + ;; Make a series of regular expressions to find a match + (setq words + (if camel + (org-camel-to-words s) + (org-split-string s "[ \n\r\t]+")) + re0 (concat "<<" (regexp-quote s0) ">>") + re2 (concat "\\<" (mapconcat 'downcase words "[ \t]+") "\\>") + re2a (concat "\\<" (mapconcat 'downcase words "[ \t\r\n]+") "\\>") + re4 (concat "\\<" (mapconcat 'downcase words "[^a-zA-Z_\r\n]+") "\\>") + re1 (concat pre re2 post) + re3 (concat pre re4 post) + re5 (concat pre ".*" re4) + re2 (concat pre re2) + re2a (concat pre re2a) + re4 (concat pre re4) + reall (concat "\\(" re0 "\\)\\|\\(" re1 "\\)\\|\\(" re2 + "\\)\\|\\(" re3 "\\)\\|\\(" re4 "\\)\\|\\(" + re5 "\\)" + )) + (cond + ((eq type 'org-occur) (org-occur reall)) + ((eq type 'occur) (org-do-occur (downcase reall) 'cleanup)) + (t (goto-char (point-min)) + (if (or (org-search-not-link re0 nil t) + (org-search-not-link re1 nil t) + (org-search-not-link re2 nil t) + (org-search-not-link re2a nil t) ;; FIXME: Right place??? + (org-search-not-link re3 nil t) + (org-search-not-link re4 nil t) + (org-search-not-link re5 nil t) + ) + (goto-char (match-beginning 0)) + (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")))) + (and (eq major-mode 'org-mode) (org-show-hierarchy-above)))) + +(defun org-search-not-link (&rest args) + "Execute `re-search-forward', but only accept matches that are not a link." + (catch 'exit + (let ((pos (point)) p1) + (while (apply 're-search-forward args) + (setq p1 (point)) + (if (not (save-match-data + (and (re-search-backward "\\[\\[" nil t) + (looking-at org-bracket-link-regexp) + (<= (match-beginning 0) p1) + (>= (match-end 0) p1)))) + (progn (goto-char (match-end 0)) + (throw 'exit (point))) + (goto-char (match-end 0))))))) + +(defun org-do-occur (regexp &optional cleanup) + "Call the Emacs command `occur'. +If CLEANUP is non-nil, remove the printout of the regular expression +in the *Occur* buffer. This is useful if the regex is long and not useful +to read." + (occur regexp) + (when cleanup + (let ((cwin (selected-window)) win beg end) + (when (setq win (get-buffer-window "*Occur*")) + (select-window win)) + (goto-char (point-min)) + (when (re-search-forward "match[a-z]+" nil t) + (setq beg (match-end 0)) + (if (re-search-forward "^[ \t]*[0-9]+" nil t) + (setq end (1- (match-beginning 0))))) + (and beg end (let ((buffer-read-only)) (delete-region beg end))) + (goto-char (point-min)) + (select-window cwin)))) + +(defvar org-mark-ring nil + "Mark ring for positions before jumps in Org-mode.") +(defvar org-mark-ring-last-goto nil + "Last position in the mark ring used to go back.") +;; Fill and close the ring +(setq org-mark-ring nil org-mark-ring-last-goto nil) ;; in case file is reloaded +(loop for i from 1 to org-mark-ring-length do + (push (make-marker) org-mark-ring)) +(setcdr (nthcdr (1- org-mark-ring-length) org-mark-ring) + org-mark-ring) + +(defun org-mark-ring-push (&optional pos buffer) + "Put the current position or POS into the mark ring and rotate it." + (interactive) + (setq pos (or pos (point))) + (setq org-mark-ring (nthcdr (1- org-mark-ring-length) org-mark-ring)) + (move-marker (car org-mark-ring) + (or pos (point)) + (or buffer (current-buffer))) + (message + (substitute-command-keys + "Position saved to mark ring, go back with \\[org-mark-ring-goto]."))) + +(defun org-mark-ring-goto (&optional n) + "Jump to the previous position in the mark ring. +With prefix arg N, jump back that many stored positions. When +called several times in succession, walk through the entire ring. +Org-mode commands jumping to a different position in the current file, +or to another Org-mode file, automatically push the old position +onto the ring." + (interactive "p") + (let (p m) + (if (eq last-command this-command) + (setq p (nthcdr n (or org-mark-ring-last-goto org-mark-ring))) + (setq p org-mark-ring)) + (setq org-mark-ring-last-goto p) + (setq m (car p)) + (switch-to-buffer (marker-buffer m)) + (goto-char m) + (if (or (org-invisible-p) (org-invisible-p2)) (org-show-hierarchy-above)))) + +(defun org-camel-to-words (s) + "Split \"CamelCaseWords\" to (\"Camel\" \"Case\" \"Words\")." + (let ((case-fold-search nil) + words) + (while (string-match "[a-z][A-Z]" s) + (push (substring s 0 (1+ (match-beginning 0))) words) + (setq s (substring s (1+ (match-beginning 0))))) + (nreverse (cons s words)))) + +(defun org-remove-angle-brackets (s) + (if (equal (substring s 0 1) "<") (setq s (substring s 1))) + (if (equal (substring s -1) ">") (setq s (substring s 0 -1))) + s) +(defun org-add-angle-brackets (s) + (if (equal (substring s 0 1) "<") nil (setq s (concat "<" s))) + (if (equal (substring s -1) ">") nil (setq s (concat s ">"))) + s) + +(defun org-follow-bbdb-link (name) + "Follow a BBDB link to NAME." + (require 'bbdb) + (let ((inhibit-redisplay t) + (bbdb-electric-p nil)) + (catch 'exit + ;; Exact match on name + (bbdb-name (concat "\\`" name "\\'") nil) + (if (< 0 (buffer-size (get-buffer "*BBDB*"))) (throw 'exit nil)) + ;; Exact match on name + (bbdb-company (concat "\\`" name "\\'") nil) + (if (< 0 (buffer-size (get-buffer "*BBDB*"))) (throw 'exit nil)) + ;; Partial match on name + (bbdb-name name nil) + (if (< 0 (buffer-size (get-buffer "*BBDB*"))) (throw 'exit nil)) + ;; Partial match on company + (bbdb-company name nil) + (if (< 0 (buffer-size (get-buffer "*BBDB*"))) (throw 'exit nil)) + ;; General match including network address and notes + (bbdb name nil) + (when (= 0 (buffer-size (get-buffer "*BBDB*"))) + (delete-window (get-buffer-window "*BBDB*")) + (error "No matching BBDB record"))))) + +(defun org-follow-gnus-link (&optional group article) + "Follow a Gnus link to GROUP and ARTICLE." + (require 'gnus) + (funcall (cdr (assq 'gnus org-link-frame-setup))) + (if group (gnus-fetch-group group)) + (if article + (or (gnus-summary-goto-article article nil 'force) + (if (fboundp 'gnus-summary-insert-cached-articles) + (progn + (gnus-summary-insert-cached-articles) + (gnus-summary-goto-article article nil 'force)) + (message "Message could not be found."))))) + +(defun org-follow-vm-link (&optional folder article readonly) + "Follow a VM link to FOLDER and ARTICLE." + (require 'vm) + (setq article (org-add-angle-brackets article)) + (if (string-match "^//\\([a-zA-Z]+@\\)?\\([^:]+\\):\\(.*\\)" folder) + ;; ange-ftp or efs or tramp access + (let ((user (or (match-string 1 folder) (user-login-name))) + (host (match-string 2 folder)) + (file (match-string 3 folder))) + (cond + ((featurep 'tramp) + ;; use tramp to access the file + (if org-xemacs-p + (setq folder (format "[%s@%s]%s" user host file)) + (setq folder (format "/%s@%s:%s" user host file)))) + (t + ;; use ange-ftp or efs + (require (if org-xemacs-p 'efs 'ange-ftp)) + (setq folder (format "/%s@%s:%s" user host file)))))) + (when folder + (funcall (cdr (assq 'vm org-link-frame-setup)) folder readonly) + (sit-for 0.1) + (when article + (vm-select-folder-buffer) + (widen) + (let ((case-fold-search t)) + (goto-char (point-min)) + (if (not (re-search-forward + (concat "^" "message-id: *" (regexp-quote article)))) + (error "Could not find the specified message in this folder")) + (vm-isearch-update) + (vm-isearch-narrow) + (vm-beginning-of-message) + (vm-summarize))))) + +(defun org-follow-wl-link (folder article) + "Follow a Wanderlust link to FOLDER and ARTICLE." + (setq article (org-add-angle-brackets article)) + (wl-summary-goto-folder-subr folder 'no-sync t nil t) + (if article (wl-summary-jump-to-msg-by-message-id article ">")) + (wl-summary-redisplay)) + +(defun org-follow-rmail-link (folder article) + "Follow an RMAIL link to FOLDER and ARTICLE." + (setq article (org-add-angle-brackets article)) + (let (message-number) + (save-excursion + (save-window-excursion + (rmail (if (string= folder "RMAIL") rmail-file-name folder)) + (setq message-number + (save-restriction + (widen) + (goto-char (point-max)) + (if (re-search-backward + (concat "^Message-ID:\\s-+" (regexp-quote + (or article ""))) + nil t) + (rmail-what-message)))))) + (if message-number + (progn + (rmail (if (string= folder "RMAIL") rmail-file-name folder)) + (rmail-show-message message-number) + message-number) + (error "Message not found")))) + +;; mh-e integration based on planner-mode +(defun org-mhe-get-message-real-folder () + "Return the name of the current message real folder, so if you use +sequences, it will now work." + (save-excursion + (let* ((folder + (if (equal major-mode 'mh-folder-mode) + mh-current-folder + ;; Refer to the show buffer + mh-show-folder-buffer)) + (end-index + (if (boundp 'mh-index-folder) + (min (length mh-index-folder) (length folder)))) + ) + ;; a simple test on mh-index-data does not work, because + ;; mh-index-data is always nil in a show buffer. + (if (and (boundp 'mh-index-folder) + (string= mh-index-folder (substring folder 0 end-index))) + (if (equal major-mode 'mh-show-mode) + (save-window-excursion + (when (buffer-live-p (get-buffer folder)) + (progn + (pop-to-buffer folder) + (org-mhe-get-message-folder-from-index) + ) + )) + (org-mhe-get-message-folder-from-index) + ) + folder + ) + ))) + +(defun org-mhe-get-message-folder-from-index () + "Returns the name of the message folder in a index folder buffer." + (save-excursion + (mh-index-previous-folder) + (re-search-forward "^\\(+.*\\)$" nil t) + (message (match-string 1)))) + +(defun org-mhe-get-message-folder () + "Return the name of the current message folder. Be careful if you +use sequences." + (save-excursion + (if (equal major-mode 'mh-folder-mode) + mh-current-folder + ;; Refer to the show buffer + mh-show-folder-buffer))) + +(defun org-mhe-get-message-num () + "Return the number of the current message. Be careful if you +use sequences." + (save-excursion + (if (equal major-mode 'mh-folder-mode) + (mh-get-msg-num nil) + ;; Refer to the show buffer + (mh-show-buffer-message-number)))) + +(defun org-mhe-get-header (header) + "Return a header of the message in folder mode. This will create a +show buffer for the corresponding message. If you have a more clever +idea..." + (let* ((folder (org-mhe-get-message-folder)) + (num (org-mhe-get-message-num)) + (buffer (get-buffer-create (concat "show-" folder))) + (header-field)) + (with-current-buffer buffer + (mh-display-msg num folder) + (if (equal major-mode 'mh-folder-mode) + (mh-header-display) + (mh-show-header-display)) + (set-buffer buffer) + (setq header-field (mh-get-header-field header)) + (if (equal major-mode 'mh-folder-mode) + (mh-show) + (mh-show-show)) + header-field))) + +(defun org-follow-mhe-link (folder article) + "Follow an MHE link to FOLDER and ARTICLE. +If ARTICLE is nil FOLDER is shown. If the configuration variable +`org-mhe-search-all-folders' is t and `mh-searcher' is pick, +ARTICLE is searched in all folders. Indexed searches (swish++, +namazu, and others supported by MH-E) will always search in all +folders." + (require 'mh-e) + (require 'mh-search) + (require 'mh-utils) + (mh-find-path) + (if (not article) + (mh-visit-folder (mh-normalize-folder-name folder)) + (setq article (org-add-angle-brackets article)) + (mh-search-choose) + (if (equal mh-searcher 'pick) + (progn + (mh-search folder (list "--message-id" article)) + (when (and org-mhe-search-all-folders + (not (org-mhe-get-message-real-folder))) + (kill-this-buffer) + (mh-search "+" (list "--message-id" article)))) + (mh-search "+" article)) + (if (org-mhe-get-message-real-folder) + (mh-show-msg 1) + (kill-this-buffer) + (error "Message not found")))) + +(defun org-open-file (path &optional in-emacs line search) + "Open the file at PATH. +First, this expands any special file name abbreviations. Then the +configuration variable `org-file-apps' is checked if it contains an +entry for this file type, and if yes, the corresponding command is launched. +If no application is found, Emacs simply visits the file. +With optional argument IN-EMACS, Emacs will visit the file. +Optional LINE specifies a line to go to, optional SEARCH a string to +search for. If LINE or SEARCH is given, the file will always be +opened in Emacs. +If the file does not exist, an error is thrown." + (setq in-emacs (or in-emacs line search)) + (let* ((file (if (equal path "") + buffer-file-name + (convert-standard-filename (org-expand-file-name path)))) + (dirp (file-directory-p file)) + (dfile (downcase file)) + (old-buffer (current-buffer)) + (old-pos (point)) + (old-mode major-mode) + ext cmd apps) + (if (and (not (file-exists-p file)) + (not org-open-non-existing-files)) + (error "No such file: %s" file)) + (if (string-match "^.*\\.\\([a-zA-Z0-9]+\\.gz\\)$" dfile) + (setq ext (match-string 1 dfile)) + (if (string-match "^.*\\.\\([a-zA-Z0-9]+\\)$" dfile) + (setq ext (match-string 1 dfile)))) + (setq apps (append org-file-apps (org-default-apps))) + (if in-emacs + (setq cmd 'emacs) + (setq cmd (or (and dirp (cdr (assoc 'directory apps))) + (cdr (assoc ext apps)) + (cdr (assoc t apps))))) + (when (eq cmd 'mailcap) + (require 'mailcap) + (mailcap-parse-mailcaps) + (let* ((mime-type (mailcap-extension-to-mime (or ext ""))) + (command (mailcap-mime-info mime-type))) + (if (stringp command) + (setq cmd command) + (setq cmd 'emacs)))) + (cond + ((and (stringp cmd) (not (string-match "^\\s-*$" cmd))) + (setq cmd (format cmd (concat "\"" file "\""))) + (save-window-excursion + (shell-command (concat cmd " &")))) + ((or (stringp cmd) + (eq cmd 'emacs)) + (unless (equal (file-truename file) (file-truename (or buffer-file-name ""))) + (funcall (cdr (assq 'file org-link-frame-setup)) file)) + (if line (goto-line line) + (if search (org-link-search search)))) + ((consp cmd) + (eval cmd)) + (t (funcall (cdr (assq 'file org-link-frame-setup)) file))) + (and (eq major-mode 'org-mode) (eq old-mode 'org-mode) + (or (not (equal old-buffer (current-buffer))) + (not (equal old-pos (point)))) + (org-mark-ring-push old-pos old-buffer)))) + +(defun org-default-apps () + "Return the default applications for this operating system." + (cond + ((eq system-type 'darwin) + org-file-apps-defaults-macosx) + ((eq system-type 'windows-nt) + org-file-apps-defaults-windowsnt) + (t org-file-apps-defaults-gnu))) + +(defun org-expand-file-name (path) + "Replace special path abbreviations and expand the file name." + (expand-file-name path)) + + +(defvar org-insert-link-history nil + "Minibuffer history for links inserted with `org-insert-link'.") + +(defvar org-stored-links nil + "Contains the links stored with `org-store-link'.") + +;;;###autoload +(defun org-store-link (arg) + "\\Store an org-link to the current location. +This link can later be inserted into an org-buffer with +\\[org-insert-link]. +For some link types, a prefix arg is interpreted: +For links to usenet articles, arg negates `org-usenet-links-prefer-google'. +For file links, arg negates `org-context-in-file-links'." + (interactive "P") + (let (link cpltxt txt (pos (point))) + (cond + + ((eq major-mode 'bbdb-mode) + (setq cpltxt (concat + "bbdb:" + (or (bbdb-record-name (bbdb-current-record)) + (bbdb-record-company (bbdb-current-record)))) + link (org-make-link cpltxt))) + + ((eq major-mode 'calendar-mode) + (let ((cd (calendar-cursor-to-date))) + (setq link + (format-time-string + (car org-time-stamp-formats) + (apply 'encode-time + (list 0 0 0 (nth 1 cd) (nth 0 cd) (nth 2 cd) + nil nil nil)))))) + + ((or (eq major-mode 'vm-summary-mode) + (eq major-mode 'vm-presentation-mode)) + (and (eq major-mode 'vm-presentation-mode) (vm-summarize)) + (vm-follow-summary-cursor) + (save-excursion + (vm-select-folder-buffer) + (let* ((message (car vm-message-pointer)) + (folder buffer-file-name) + (subject (vm-su-subject message)) + (author (vm-su-full-name message)) + (message-id (vm-su-message-id message))) + (setq message-id (org-remove-angle-brackets message-id)) + (setq folder (abbreviate-file-name folder)) + (if (string-match (concat "^" (regexp-quote vm-folder-directory)) + folder) + (setq folder (replace-match "" t t folder))) + (setq cpltxt (concat author " on: " subject)) + (setq link (concat cpltxt "\n " + (org-make-link + "vm:" folder "#" message-id)))))) + + ((eq major-mode 'wl-summary-mode) + (let* ((msgnum (wl-summary-message-number)) + (message-id (elmo-message-field wl-summary-buffer-elmo-folder + msgnum 'message-id)) + (wl-message-entity (elmo-msgdb-overview-get-entity + msgnum (wl-summary-buffer-msgdb))) + (author (wl-summary-line-from)) ; FIXME: how to get author name? + (subject "???")) ; FIXME: How to get subject of email? + (setq message-id (org-remove-angle-brackets message-id)) + (setq cpltxt (concat author " on: " subject)) + (setq link (concat cpltxt "\n " + (org-make-link + "wl:" wl-summary-buffer-folder-name + "#" message-id))))) + + ((or (equal major-mode 'mh-folder-mode) + (equal major-mode 'mh-show-mode)) + (let ((from-header (org-mhe-get-header "From:")) + (to-header (org-mhe-get-header "To:")) + (subject (org-mhe-get-header "Subject:"))) + (setq cpltxt (concat from-header " on: " subject)) + (setq link (concat cpltxt "\n " + (org-make-link + "mhe:" (org-mhe-get-message-real-folder) "#" + (org-remove-angle-brackets + (org-mhe-get-header "Message-Id:"))))))) + + ((eq major-mode 'rmail-mode) + (save-excursion + (save-restriction + (rmail-narrow-to-non-pruned-header) + (let ((folder buffer-file-name) + (message-id (mail-fetch-field "message-id")) + (author (mail-fetch-field "from")) + (subject (mail-fetch-field "subject"))) + (setq message-id (org-remove-angle-brackets message-id)) + (setq cpltxt (concat author " on: " subject)) + (setq link (concat cpltxt "\n " + (org-make-link + "rmail:" folder "#" message-id))))))) + + ((eq major-mode 'gnus-group-mode) + (let ((group (cond ((fboundp 'gnus-group-group-name) ; depending on Gnus + (gnus-group-group-name)) ; version + ((fboundp 'gnus-group-name) + (gnus-group-name)) + (t "???")))) + (setq cpltxt (concat + (if (org-xor arg org-usenet-links-prefer-google) + "http://groups.google.com/groups?group=" + "gnus:") + group) + link (org-make-link cpltxt)))) + + ((memq major-mode '(gnus-summary-mode gnus-article-mode)) + (and (eq major-mode 'gnus-article-mode) (gnus-article-show-summary)) + (gnus-summary-beginning-of-article) + (let* ((group (car gnus-article-current)) + (article (cdr gnus-article-current)) + (header (gnus-summary-article-header article)) + (author (mail-header-from header)) + (message-id (mail-header-id header)) + (date (mail-header-date header)) + (subject (gnus-summary-subject-string))) + (setq cpltxt (concat author " on: " subject)) + (if (org-xor arg org-usenet-links-prefer-google) + (setq link + (concat + cpltxt "\n " + (format "http://groups.google.com/groups?as_umsgid=%s" + (org-fixup-message-id-for-http message-id)))) + (setq link (concat cpltxt "\n" + (org-make-link + "gnus:" group + "#" (number-to-string article))))))) + + ((eq major-mode 'w3-mode) + (setq cpltxt (url-view-url t) + link (org-make-link cpltxt))) + ((eq major-mode 'w3m-mode) + (setq cpltxt w3m-current-url + link (org-make-link cpltxt))) + + ((eq major-mode 'org-mode) + ;; Just link to current headline + (setq cpltxt (concat "file:" + (abbreviate-file-name buffer-file-name))) + ;; Add a context search string + (when (org-xor org-context-in-file-links arg) + ;; Check if we are on a target + (if (save-excursion + (skip-chars-forward "^>\n\r") + (and (re-search-backward "<<" nil t) + (looking-at "<<\\(.*?\\)>>") + (<= (match-beginning 0) pos) + (>= (match-end 0) pos))) + (setq cpltxt (concat cpltxt "::" (match-string 1))) + (setq txt (cond + ((org-on-heading-p) nil) + ((org-region-active-p) + (buffer-substring (region-beginning) (region-end))) + (t (buffer-substring (point-at-bol) (point-at-eol))))) + (setq cpltxt + (concat cpltxt "::" + (if org-file-link-context-use-camel-case + (org-make-org-heading-camel txt) + (org-make-org-heading-search-string txt)))))) + (if (string-match "::\\'" cpltxt) + (setq cpltxt (substring cpltxt 0 -2))) + (setq link (org-make-link cpltxt))) + + (buffer-file-name + ;; Just link to this file here. + (setq cpltxt (concat "file:" + (abbreviate-file-name buffer-file-name))) + ;; Add a context string + (when (org-xor org-context-in-file-links arg) + (setq txt (if (org-region-active-p) + (buffer-substring (region-beginning) (region-end)) + (buffer-substring (point-at-bol) (point-at-eol)))) + (setq cpltxt + (concat cpltxt "::" + (if org-file-link-context-use-camel-case + (org-make-org-heading-camel txt) + (org-make-org-heading-search-string txt))))) + (setq link (org-make-link cpltxt))) + + ((interactive-p) + (error "Cannot link to a buffer which is not visiting a file")) + + (t (setq link nil))) + + (if (consp link) (setq cpltxt (car link) link (cdr link))) + + (if (and (interactive-p) link) + (progn + (setq org-stored-links + (cons (cons (or cpltxt link) link) org-stored-links)) + (message "Stored: %s" (or cpltxt link))) + link))) + +(defun org-make-org-heading-search-string (&optional string heading) + "Make search string for STRING or current headline." + (interactive) + (let ((s (or string (org-get-heading)))) + (unless (and string (not heading)) + ;; 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 ":[a-zA-Z_@0-9:]+:[ \t]*$" s) + (setq s (replace-match "" t t s))) + (setq s (org-trim s)) + (if (string-match (concat "^\\(" org-quote-string "\\|" + org-comment-string "\\)") s) + (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]+") " "))) + +(defun org-make-org-heading-camel (&optional string heading) + "Make a CamelCase string for STRING or the current headline." + (interactive) + (let ((s (or string (org-get-heading)))) + (unless (and string (not heading)) + ;; 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 ":[a-zA-Z_@0-9:]+:[ \t]*$" s) + (setq s (replace-match "" t t s))) + (setq s (org-trim s)) + (if (string-match (concat "^\\(" org-quote-string "\\|" + org-comment-string "\\)") s) + (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_ \t]+" s) + (setq s (replace-match " " t t s))) + (or string (setq s (concat "*" s))) ; Add * for headlines + (mapconcat 'capitalize (org-split-string s "[ \t]+") ""))) + +(defun org-make-link (&rest strings) + "Concatenate STRINGS, format resulting string with `org-link-format'." + (format org-link-format (apply 'concat strings))) + +(defun org-make-link2 (link &optional description) + "Make a link with brackets." + (concat "[[" link "]" + (if description (concat "[" description "]") "") + "]")) + +(defun org-xor (a b) + "Exclusive or." + (if a (not b) b)) + +(defun org-get-header (header) + "Find a header field in the current buffer." + (save-excursion + (goto-char (point-min)) + (let ((case-fold-search t) s) + (cond + ((eq header 'from) + (if (re-search-forward "^From:\\s-+\\(.*\\)" nil t) + (setq s (match-string 1))) + (while (string-match "\"" s) + (setq s (replace-match "" t t s))) + (if (string-match "[<(].*" s) + (setq s (replace-match "" t t s)))) + ((eq header 'message-id) + (if (re-search-forward "^message-id:\\s-+\\(.*\\)" nil t) + (setq s (match-string 1)))) + ((eq header 'subject) + (if (re-search-forward "^subject:\\s-+\\(.*\\)" nil t) + (setq s (match-string 1))))) + (if (string-match "\\`[ \t\]+" s) (setq s (replace-match "" t t s))) + (if (string-match "[ \t\]+\\'" s) (setq s (replace-match "" t t s))) + s))) + + +(defun org-fixup-message-id-for-http (s) + "Replace special characters in a message id, so it can be used in an http query." + (while (string-match "<" s) + (setq s (replace-match "%3C" t t s))) + (while (string-match ">" s) + (setq s (replace-match "%3E" t t s))) + (while (string-match "@" s) + (setq s (replace-match "%40" t t s))) + s) + +(defun org-insert-link (&optional complete-file) + "Insert a link. At the prompt, enter the link. + +Completion can be used to select a link previously stored with +`org-store-link'. When the empty string is entered (i.e. if you just +press RET at the prompt), the link defaults to the most recently +stored link. As SPC triggers completion in the minibuffer, you need to +use M-SPC or C-q SPC to force the insertion of a space character. + +With a \\[universal-argument] prefix, prompts for a file to link to. The file name can be +selected using completion. The path to the file will be relative to +the current directory if the file is in the current directory or a +subdirectory. Otherwise, the link will be the absolute path as +completed in the minibuffer (i.e. normally ~/path/to/file). + +With two \\[universal-argument] prefixes, enforce an absolute path even if the file +is in the current directory or below." + (interactive "P") + (let ((link (if complete-file + (read-file-name "File: ") + (completing-read + "Link: " org-stored-links nil nil nil + org-insert-link-history + (or (car (car org-stored-links)))))) + linktxt matched) + (if (or (not link) (equal link "")) + (error "No links available")) + (if complete-file + (let ((pwd (file-name-as-directory (expand-file-name ".")))) + (cond + ((equal complete-file '(16)) + (insert + (org-make-link + "file:" (abbreviate-file-name (expand-file-name link))))) + ((string-match (concat "^" (regexp-quote pwd) "\\(.+\\)") + (expand-file-name link)) + (insert + (org-make-link + "file:" (match-string 1 (expand-file-name link))))) + (t (insert (org-make-link "file:" link))))) + (setq linktxt (cdr (assoc link org-stored-links))) + (if (not org-keep-stored-link-after-insertion) + (setq org-stored-links (delq (assoc link org-stored-links) + org-stored-links))) + (if (not linktxt) (setq link (org-make-link link))) + (setq link (or linktxt link)) + (when (string-match "<\\]+\\)>" link) + (let* ((path (match-string 1 link)) + (case-fold-search nil) + (search (match-string 2 link))) + (when (save-match-data + (equal (file-truename buffer-file-name) + (file-truename path))) + ;; We are linking to this same file + (if (and org-file-link-context-use-camel-case + (save-match-data + (string-match (concat "^" org-camel-regexp "$") search))) + (setq link (replace-match search t t link) + matched t) + (setq link (replace-match (concat "[[" search "]]") + t t link) + matched t))))) + (let ((lines (org-split-string link "\n"))) + (insert (car lines)) + (setq matched (or matched (string-match org-link-regexp (car lines)))) + (setq lines (cdr lines)) + (while lines + (insert "\n") + (if (save-excursion + (beginning-of-line 0) + (looking-at "[ \t]+\\S-")) + (indent-relative)) + (setq matched (or matched + (string-match org-link-regexp (car lines)))) + (insert (car lines)) + (setq lines (cdr lines)))) + (unless matched + (error "Add link type: http(s),ftp,mailto,file,news,bbdb,vm,wl,rmail,gnus, or shell"))))) + +;;; Hooks for remember.el +;;;###autoload +(defun org-remember-annotation () + "Return a link to the current location as an annotation for remember.el. +If you are using Org-mode files as target for data storage with +remember.el, then the annotations should include a link compatible with the +conventions in Org-mode. This function returns such a link." + (org-store-link nil)) + +(defconst org-remember-help +"Select a destination location for the note. +UP/DOWN=headline TAB=cycle visibility [Q]uit RET//=Store +RET at beg-of-buf -> Append to file as level 2 headline +RET on headline -> Store as sublevel entry to current headline +/ -> before/after current headline, same headings level") + +;;;###autoload +(defun org-remember-apply-template () + "Initialize *remember* buffer with template, invode `org-mode'. +This function should be placed into `remember-mode-hook' and in fact requires +to be run from that hook to fucntion properly." + (when org-remember-templates + (let* ((entry (if (= (length org-remember-templates) 1) + (cdar org-remember-templates) + (message "Select template: %s" + (mapconcat + (lambda (x) (char-to-string (car x))) + org-remember-templates " ")) + (cdr (assoc (read-char-exclusive) org-remember-templates)))) + (tpl (if (consp (cdr entry)) (cadr entry) (cdr entry))) + (file (if (consp (cdr entry)) (nth 2 entry))) + (v-t (format-time-string (car org-time-stamp-formats) (org-current-time))) + (v-T (format-time-string (cdr org-time-stamp-formats) (org-current-time))) + (v-u (concat "[" (substring v-t 1 -1) "]")) + (v-U (concat "[" (substring v-T 1 -1) "]")) + (v-a annotation) ; defined in `remember-mode' + (v-i initial) ; defined in `remember-mode' + (v-n user-full-name) + ) + (unless tpl (setq tpl "") (message "No template") (ding)) + (insert tpl) (goto-char (point-min)) + (while (re-search-forward "%\\([tTuTai]\\)" nil t) + (when (and initial (equal (match-string 0) "%i")) + (save-match-data + (let* ((lead (buffer-substring + (point-at-bol) (match-beginning 0)))) + (setq v-i (mapconcat 'identity + (org-split-string initial "\n") + (concat "\n" lead)))))) + (replace-match + (or (eval (intern (concat "v-" (match-string 1)))) "") + t t)) + (let ((org-startup-folded nil) + (org-startup-with-deadline-check nil)) + (org-mode)) +; (use-local-map org-mode-map) +; (org-set-font-lock-defaults) + (if (and file (string-match "\\S-" file) (not (file-directory-p file))) + (set (make-local-variable 'org-default-notes-file) file)) + (goto-char (point-min)) + (if (re-search-forward "%\\?" nil t) (replace-match ""))))) + +;;;###autoload +(defun org-remember-handler () + "Store stuff from remember.el into an org file. +First prompts for an org file. If the user just presses return, the value +of `org-default-notes-file' is used. +Then the command offers the headings tree of the selected file in order to +file the text at a specific location. +You can either immediately press RET to get the note appended to the +file, or you can use vertical cursor motion and visibility cycling (TAB) to +find a better place. Then press RET or or in insert the note. + +Key Cursor position Note gets inserted +----------------------------------------------------------------------------- +RET buffer-start as level 2 heading at end of file +RET on headline as sublevel of the heading at cursor +RET no heading at cursor position, level taken from context. + Or use prefix arg to specify level manually. + on headline as same level, before current heading + on headline as same level, after current heading + +So the fastest way to store the note is to press RET RET to append it to +the default file. This way your current train of thought is not +interrupted, in accordance with the principles of remember.el. But with +little extra effort, you can push it directly to the correct location. + +Before being stored away, the function ensures that the text has a +headline, i.e. a first line that starts with a \"*\". If not, a headline +is constructed from the current date and some additional data. + +If the variable `org-adapt-indentation' is non-nil, the entire text is +also indented so that it starts in the same column as the headline +\(i.e. after the stars). + +See also the variable `org-reverse-note-order'." + (catch 'quit + (let* ((txt (buffer-substring (point-min) (point-max))) + (fastp current-prefix-arg) + (file (if fastp org-default-notes-file (org-get-org-file))) + (visiting (find-buffer-visiting file)) + (org-startup-with-deadline-check nil) + (org-startup-folded nil) + spos level indent reversed) + ;; Modify text so that it becomes a nice subtree which can be inserted + ;; into an org tree. + (let* ((lines (split-string txt "\n")) + first) + ;; remove empty lines at the beginning + (while (and lines (string-match "^[ \t]*\n" (car lines))) + (setq lines (cdr lines))) + (setq first (car lines) lines (cdr lines)) + (if (string-match "^\\*+" first) + ;; Is already a headline + (setq indent nil) + ;; We need to add a headline: Use time and first buffer line + (setq lines (cons first lines) + first (concat "* " (current-time-string) + " (" (remember-buffer-desc) ")") + indent " ")) + (if (and org-adapt-indentation indent) + (setq lines (mapcar (lambda (x) (concat indent x)) lines))) + (setq txt (concat first "\n" + (mapconcat 'identity lines "\n")))) + ;; Find the file + (if (not visiting) + (find-file-noselect file)) + (with-current-buffer (get-file-buffer file) + (setq reversed (org-notes-order-reversed-p)) + (save-excursion + (save-restriction + (widen) + ;; Ask the User for a location + (setq spos (if fastp 1 (org-get-location + (current-buffer) + org-remember-help))) + (if (not spos) (throw 'quit nil)) ; return nil to show we did + ; not handle this note + (goto-char spos) + (cond ((bobp) + ;; Put it at the start or end, as level 2 + (save-restriction + (widen) + (goto-char (if reversed (point-min) (point-max))) + (if (not (bolp)) (newline)) + (org-paste-subtree 2 txt))) + ((and (org-on-heading-p nil) (not current-prefix-arg)) + ;; Put it below this entry, at the beg/end of the subtree + (org-back-to-heading) + (setq level (funcall outline-level)) + (if reversed + (outline-end-of-heading) + (outline-end-of-subtree)) + (if (not (bolp)) (newline)) + (beginning-of-line 1) + (org-paste-subtree (1+ level) txt)) + (t + ;; Put it right there, with automatic level determined by + ;; org-paste-subtree or from prefix arg + (org-paste-subtree current-prefix-arg txt))) + (when remember-save-after-remembering + (save-buffer) + (if (not visiting) (kill-buffer (current-buffer))))))))) + t) ;; return t to indicate that we took care of this note. + +(defun org-get-org-file () + "Read a filename, with default directory `org-directory'." + (let ((default (or org-default-notes-file remember-data-file))) + (read-file-name (format "File name [%s]: " default) + (file-name-as-directory org-directory) + default))) + +(defun org-notes-order-reversed-p () + "Check if the current file should receive notes in reversed order." + (cond + ((not org-reverse-note-order) nil) + ((eq t org-reverse-note-order) t) + ((not (listp org-reverse-note-order)) nil) + (t (catch 'exit + (let ((all org-reverse-note-order) + entry) + (while (setq entry (pop all)) + (if (string-match (car entry) buffer-file-name) + (throw 'exit (cdr entry)))) + nil))))) + +;;; Tables + +;; Watch out: Here we are talking about two different kind of tables. +;; Most of the code is for the tables created with the Org-mode table editor. +;; Sometimes, we talk about tables created and edited with the table.el +;; Emacs package. We call the former org-type tables, and the latter +;; table.el-type tables. + + +(defun org-before-change-function (beg end) + "Every change indicates that a table might need an update." + (setq org-table-may-need-update t)) + +(defconst org-table-line-regexp "^[ \t]*|" + "Detects an org-type table line.") +(defconst org-table-dataline-regexp "^[ \t]*|[^-]" + "Detects an org-type table line.") +(defconst org-table-auto-recalculate-regexp "^[ \t]*| *# *\\(|\\|$\\)" + "Detects a table line marked for automatic recalculation.") +(defconst org-table-recalculate-regexp "^[ \t]*| *[#*] *\\(|\\|$\\)" + "Detects a table line marked for automatic recalculation.") +(defconst org-table-calculate-mark-regexp "^[ \t]*| *[!$^_#*] *\\(|\\|$\\)" + "Detects a table line marked for automatic recalculation.") +(defconst org-table-hline-regexp "^[ \t]*|-" + "Detects an org-type table hline.") +(defconst org-table1-hline-regexp "^[ \t]*\\+-[-+]" + "Detects a table-type table hline.") +(defconst org-table-any-line-regexp "^[ \t]*\\(|\\|\\+-[-+]\\)" + "Detects an org-type or table-type table.") +(defconst org-table-border-regexp "^[ \t]*[^| \t]" + "Searching from within a table (any type) this finds the first line +outside the table.") +(defconst org-table-any-border-regexp "^[ \t]*[^|+ \t]" + "Searching from within a table (any type) this finds the first line +outside the table.") + +(defun org-table-create-with-table.el () + "Use the table.el package to insert a new table. +If there is already a table at point, convert between Org-mode tables +and table.el tables." + (interactive) + (require 'table) + (cond + ((org-at-table.el-p) + (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))) + (t (call-interactively 'table-insert)))) + +(defun org-table-create (&optional size) + "Query for a size and insert a table skeleton. +SIZE is a string Columns x Rows like for example \"3x2\"." + (interactive "P") + (unless size + (setq size (read-string + (concat "Table size Columns x Rows [e.g. " + org-table-default-size "]: ") + "" nil org-table-default-size))) + + (let* ((pos (point)) + (indent (make-string (current-column) ?\ )) + (split (org-split-string size " *x *")) + (rows (string-to-number (nth 1 split))) + (columns (string-to-number (car split))) + (line (concat (apply 'concat indent "|" (make-list columns " |")) + "\n"))) + (if (string-match "^[ \t]*$" (buffer-substring-no-properties + (point-at-bol) (point))) + (beginning-of-line 1) + (newline)) + ;; (mapcar (lambda (x) (insert line)) (make-list rows t)) + (dotimes (i rows) (insert line)) + (goto-char pos) + (if (> rows 1) + ;; Insert a hline after the first row. + (progn + (end-of-line 1) + (insert "\n|-") + (goto-char pos))) + (org-table-align))) + +(defun org-table-convert-region (beg0 end0 nspace) + "Convert region to a table. +The region goes from BEG0 to END0, but these borders will be moved +slightly, to make sure a beginning of line in the first line is included. +When NSPACE is non-nil, it indicates the minimum number of spaces that +separate columns (default: just one space)." + (let* ((beg (min beg0 end0)) + (end (max beg0 end0)) + (tabsep t) + re) + (goto-char beg) + (beginning-of-line 1) + (setq beg (move-marker (make-marker) (point))) + (goto-char end) + (if (bolp) (backward-char 1) (end-of-line 1)) + (setq end (move-marker (make-marker) (point))) + ;; Lets see if this is tab-separated material. If every nonempty line + ;; contains a tab, we will assume that it is tab-separated material + (if nspace + (setq tabsep nil) + (goto-char beg) + (and (re-search-forward "^[^\n\t]+$" end t) (setq tabsep nil))) + (if nspace (setq tabsep nil)) + (if tabsep + (setq re "^\\|\t") + (setq re (format "^ *\\| *\t *\\| \\{%d,\\}" + (max 1 (prefix-numeric-value nspace))))) + (goto-char beg) + (while (re-search-forward re end t) + (replace-match "|" t t)) + (goto-char beg) + (insert " ") + (org-table-align))) + +(defun org-table-import (file arg) + "Import FILE as a table. +The file is assumed to be tab-separated. Such files can be produced by most +spreadsheet and database applications. If no tabs (at least one per line) +are found, lines will be split on whitespace into fields." + (interactive "f\nP") + (or (bolp) (newline)) + (let ((beg (point)) + (pm (point-max))) + (insert-file-contents file) + (org-table-convert-region beg (+ (point) (- (point-max) pm)) arg))) + +(defun org-table-export () + "Export table as a tab-separated file. +Such a file can be imported into a spreadsheet program like Excel." + (interactive) + (let* ((beg (org-table-begin)) + (end (org-table-end)) + (table (buffer-substring beg end)) + (file (read-file-name "Export table to: ")) + buf) + (unless (or (not (file-exists-p file)) + (y-or-n-p (format "Overwrite file %s? " file))) + (error "Abort")) + (with-current-buffer (find-file-noselect file) + (setq buf (current-buffer)) + (erase-buffer) + (fundamental-mode) + (insert table) + (goto-char (point-min)) + (while (re-search-forward "^[ \t]*|[ \t]*" nil t) + (replace-match "" t t) + (end-of-line 1)) + (goto-char (point-min)) + (while (re-search-forward "[ \t]*|[ \t]*$" nil t) + (replace-match "" t t) + (goto-char (min (1+ (point)) (point-max)))) + (goto-char (point-min)) + (while (re-search-forward "^-[-+]*$" nil t) + (replace-match "") + (if (looking-at "\n") + (delete-char 1))) + (goto-char (point-min)) + (while (re-search-forward "[ \t]*|[ \t]*" nil t) + (replace-match "\t" t t)) + (save-buffer)) + (kill-buffer buf))) + +(defvar org-table-aligned-begin-marker (make-marker) + "Marker at the beginning of the table last aligned. +Used to check if cursor still is in that table, to minimize realignment.") +(defvar org-table-aligned-end-marker (make-marker) + "Marker at the end of the table last aligned. +Used to check if cursor still is in that table, to minimize realignment.") +(defvar org-table-last-alignment nil + "List of flags for flushright alignment, from the last re-alignment. +This is being used to correctly align a single field after TAB or RET.") +(defvar org-table-last-column-widths nil + "List of max width of fields in each column. +This is being used to correctly align a single field after TAB or RET.") + +(defvar org-last-recalc-line nil) + +(defun org-table-align () + "Align the table at point by aligning all vertical bars." + (interactive) + ;; (message "align") (sit-for 2) + (let* ( + ;; Limits of table + (beg (org-table-begin)) + (end (org-table-end)) + ;; Current cursor position + (linepos (+ (if (bolp) 1 0) (count-lines (point-min) (point)))) + (colpos (org-table-current-column)) + (winstart (window-start)) + text lines (new "") lengths l typenums ty fields maxfields i + column + (indent "") cnt frac + rfmt hfmt + (spaces (if (org-in-invisibility-spec-p '(org-table)) + org-table-spaces-around-invisible-separators + org-table-spaces-around-separators)) + (sp1 (car spaces)) + (sp2 (cdr spaces)) + (rfmt1 (concat + (make-string sp2 ?\ ) "%%%s%ds" (make-string sp1 ?\ ) "|")) + (hfmt1 (concat + (make-string sp2 ?-) "%s" (make-string sp1 ?-) "+")) + emptystrings) + (untabify beg end) + ;; (message "Aligning table...") + ;; Get the rows + (setq lines (org-split-string + (buffer-substring-no-properties beg end) "\n")) + ;; Store the indentation of the first line + (if (string-match "^ *" (car lines)) + (setq indent (make-string (- (match-end 0) (match-beginning 0)) ?\ ))) + ;; Mark the hlines + (setq lines (mapcar (lambda (l) + (if (string-match "^ *|-" l) + nil + (if (string-match "[ \t]+$" l) + (substring l 0 (match-beginning 0)) + l))) + lines)) + ;; Get the data fields + (setq fields (mapcar + (lambda (l) + (org-split-string l " *| *")) + (delq nil (copy-sequence lines)))) + ;; How many fields in the longest line? + (condition-case nil + (setq maxfields (apply 'max (mapcar 'length fields))) + (error + (kill-region beg end) + (org-table-create org-table-default-size) + (error "Empty table - created default table"))) + ;; A list of empty string to fill any short rows on output + (setq emptystrings (make-list maxfields "")) + ;; Get the maximum length of a field and the most common datatype + ;; for each column + (setq i -1) + (while (< (setq i (1+ i)) maxfields) ;; Loop over all columns + (setq column (mapcar (lambda (x) (or (nth i x) "")) fields)) + ;; maximum length + (push (apply 'max 1 (mapcar 'string-width column)) lengths) + ;; compute the fraction stepwise, ignoring empty fields + (setq cnt 0 frac 0.0) + (mapcar + (lambda (x) + (if (equal x "") + nil + (setq frac ( / (+ (* frac cnt) + (if (string-match org-table-number-regexp x) 1 0)) + (setq cnt (1+ cnt)))))) + column) + (push (>= frac org-table-number-fraction) typenums)) + (setq lengths (nreverse lengths) + typenums (nreverse typenums)) + (setq org-table-last-alignment typenums + org-table-last-column-widths lengths) + ;; Compute the formats needed for output of the table + (setq rfmt (concat indent "|") hfmt (concat indent "|")) + (while (setq l (pop lengths)) + (setq ty (if (pop typenums) "" "-")) ; number types flushright + (setq rfmt (concat rfmt (format rfmt1 ty l)) + hfmt (concat hfmt (format hfmt1 (make-string l ?-))))) + (setq rfmt (concat rfmt "\n") + hfmt (concat (substring hfmt 0 -1) "|\n")) + ;; Produce the new table + ;;(while lines + ;; (setq l (pop lines)) + ;; (if l + ;; (setq new (concat new (apply 'format rfmt + ;; (append (pop fields) emptystrings)))) + ;; (setq new (concat new hfmt)))) + (setq new (mapconcat + (lambda (l) + (if l (apply 'format rfmt + (append (pop fields) emptystrings)) + hfmt)) + lines "")) + ;; Replace the old one + (delete-region beg end) + (move-marker end nil) + (move-marker org-table-aligned-begin-marker (point)) + (insert new) + (move-marker org-table-aligned-end-marker (point)) + ;; Try to move to the old location (approximately) + (goto-line linepos) + (set-window-start (selected-window) winstart 'noforce) + (org-table-goto-column colpos) + (setq org-table-may-need-update nil) + (if (org-in-invisibility-spec-p '(org-table)) + (org-table-add-invisible-to-vertical-lines)) + )) + +(defun org-table-begin (&optional table-type) + "Find the beginning of the table and return its position. +With argument TABLE-TYPE, go to the beginning of a table.el-type table." + (save-excursion + (if (not (re-search-backward + (if table-type org-table-any-border-regexp + org-table-border-regexp) + nil t)) + (error "Can't find beginning of table") + (goto-char (match-beginning 0)) + (beginning-of-line 2) + (point)))) + +(defun org-table-end (&optional table-type) + "Find the end of the table and return its position. +With argument TABLE-TYPE, go to the end of a table.el-type table." + (save-excursion + (if (not (re-search-forward + (if table-type org-table-any-border-regexp + org-table-border-regexp) + nil t)) + (goto-char (point-max)) + (goto-char (match-beginning 0))) + (point-marker))) + +(defun org-table-justify-field-maybe (&optional new) + "Justify the current field, text to left, number to right. +Optional argument NEW may specify text to replace the current field content." + (cond + ((and (not new) org-table-may-need-update)) ; Realignment will happen anyway + ((org-at-table-hline-p) + ;; FIXME: I used to enforce realign here, but I think this is not needed. + ;; (setq org-table-may-need-update t) + ) + ((and (not new) + (or (not (equal (marker-buffer org-table-aligned-begin-marker) + (current-buffer))) + (< (point) org-table-aligned-begin-marker) + (>= (point) org-table-aligned-end-marker))) + ;; This is not the same table, force a full re-align + (setq org-table-may-need-update t)) + (t ;; realign the current field, based on previous full realign + (let* ((pos (point)) s + (col (org-table-current-column)) + (num (nth (1- col) org-table-last-alignment)) + l f n o e) + (when (> col 0) + (skip-chars-backward "^|\n") + (if (looking-at " *\\([^|\n]*?\\) *\\(|\\|$\\)") + (progn + (setq s (match-string 1) + o (match-string 0) + l (max 1 (- (match-end 0) (match-beginning 0) 3)) + e (not (= (match-beginning 2) (match-end 2)))) + (setq f (format (if num " %%%ds %s" " %%-%ds %s") + l (if e "|" (setq org-table-may-need-update t) "")) + n (format f s t t)) + (if new + (if (<= (length new) l) + (setq n (format f new t t)) ;; FIXME: why t t????? + (setq n (concat new "|") org-table-may-need-update t))) + (or (equal n o) + (let (org-table-may-need-update) + (replace-match n)))) + (setq org-table-may-need-update t)) + (goto-char pos)))))) + +(defun org-table-next-field () + "Go to the next field in the current table, creating new lines as needed. +Before doing so, re-align the table if necessary." + (interactive) + (org-table-maybe-eval-formula) + (org-table-maybe-recalculate-line) + (if (and org-table-automatic-realign + org-table-may-need-update) + (org-table-align)) + (let ((end (org-table-end))) + (if (org-at-table-hline-p) + (end-of-line 1)) + (condition-case nil + (progn + (re-search-forward "|" end) + (if (looking-at "[ \t]*$") + (re-search-forward "|" end)) + (if (and (looking-at "-") + org-table-tab-jumps-over-hlines + (re-search-forward "^[ \t]*|\\([^-]\\)" end t)) + (goto-char (match-beginning 1))) + (if (looking-at "-") + (progn + (beginning-of-line 0) + (org-table-insert-row 'below)) + (if (looking-at " ") (forward-char 1)))) + (error + (org-table-insert-row 'below))))) + +(defun org-table-previous-field () + "Go to the previous field in the table. +Before doing so, re-align the table if necessary." + (interactive) + (org-table-justify-field-maybe) + (org-table-maybe-recalculate-line) + (if (and org-table-automatic-realign + org-table-may-need-update) + (org-table-align)) + (if (org-at-table-hline-p) + (end-of-line 1)) + (re-search-backward "|" (org-table-begin)) + (re-search-backward "|" (org-table-begin)) + (while (looking-at "|\\(-\\|[ \t]*$\\)") + (re-search-backward "|" (org-table-begin))) + (if (looking-at "| ?") + (goto-char (match-end 0)))) + +(defun org-table-next-row () + "Go to the next row (same column) in the current table. +Before doing so, re-align the table if necessary." + (interactive) + (org-table-maybe-eval-formula) + (org-table-maybe-recalculate-line) + (if (or (looking-at "[ \t]*$") + (save-excursion (skip-chars-backward " \t") (bolp))) + (newline) + (if (and org-table-automatic-realign + org-table-may-need-update) + (org-table-align)) + (let ((col (org-table-current-column))) + (beginning-of-line 2) + (if (or (not (org-at-table-p)) + (org-at-table-hline-p)) + (progn + (beginning-of-line 0) + (org-table-insert-row 'below))) + (org-table-goto-column col) + (skip-chars-backward "^|\n\r") + (if (looking-at " ") (forward-char 1))))) + +(defun org-table-copy-down (n) + "Copy a field down in the current column. +If the field at the cursor is empty, copy into it the content of the nearest +non-empty field above. With argument N, use the Nth non-empty field. +If the current field is not empty, it is copied down to the next row, and +the cursor is moved with it. Therefore, repeating this command causes the +column to be filled row-by-row. +If the variable `org-table-copy-increment' is non-nil and the field is an +integer, it will be incremented while copying." + (interactive "p") + (let* ((colpos (org-table-current-column)) + (field (org-table-get-field)) + (non-empty (string-match "[^ \t]" field)) + (beg (org-table-begin)) + txt) + (org-table-check-inside-data-field) + (if non-empty + (progn + (setq txt (org-trim field)) + (org-table-next-row) + (org-table-blank-field)) + (save-excursion + (setq txt + (catch 'exit + (while (progn (beginning-of-line 1) + (re-search-backward org-table-dataline-regexp + beg t)) + (org-table-goto-column colpos t) + (if (and (looking-at + "|[ \t]*\\([^| \t][^|]*?\\)[ \t]*|") + (= (setq n (1- n)) 0)) + (throw 'exit (match-string 1)))))))) + (if txt + (progn + (if (and org-table-copy-increment + (string-match "^[0-9]+$" txt)) + (setq txt (format "%d" (+ (string-to-number txt) 1)))) + (insert txt) + (org-table-maybe-recalculate-line) + (org-table-align)) + (error "No non-empty field found")))) + +(defun org-table-check-inside-data-field () + "Is point inside a table data field? +I.e. not on a hline or before the first or after the last column? +This actually throws an error, so it aborts the current command." + (if (or (not (org-at-table-p)) + (= (org-table-current-column) 0) + (org-at-table-hline-p) + (looking-at "[ \t]*$")) + (error "Not in table data field"))) + +(defvar org-table-clip nil + "Clipboard for table regions.") + +(defun org-table-blank-field () + "Blank the current table field or active region." + (interactive) + (org-table-check-inside-data-field) + (if (and (interactive-p) (org-region-active-p)) + (let (org-table-clip) + (org-table-cut-region (region-beginning) (region-end))) + (skip-chars-backward "^|") + (backward-char 1) + (if (looking-at "|[^|\n]+") + (let* ((pos (match-beginning 0)) + (match (match-string 0)) + (len (string-width match))) + (replace-match (concat "|" (make-string (1- len) ?\ ))) + (goto-char (+ 2 pos)) + (substring match 1))))) + +(defun org-table-get-field (&optional n replace) + "Return the value of the field in column N of current row. +N defaults to current field. +If REPLACE is a string, replace field with this value. The return value +is always the old value." + (and n (org-table-goto-column n)) + (skip-chars-backward "^|\n") + (backward-char 1) + (if (looking-at "|[^|\r\n]*") + (let* ((pos (match-beginning 0)) + (val (buffer-substring (1+ pos) (match-end 0)))) + (if replace + (replace-match (concat "|" replace))) + (goto-char (min (point-at-eol) (+ 2 pos))) + val) + (forward-char 1) "")) + +(defun org-table-current-column () + "Find out which column we are in. +When called interactively, column is also displayed in echo area." + (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 "This is table column %d" cnt)) + cnt))) + +(defun org-table-goto-column (n &optional on-delim force) + "Move the cursor to the Nth column in the current table line. +With optional argument ON-DELIM, stop with point before the left delimiter +of the field. +If there are less than N fields, just go to after the last delimiter. +However, when FORCE is non-nil, create new columns if necessary." + (interactive "p") + (let ((pos (point-at-eol))) + (beginning-of-line 1) + (when (> n 0) + (while (and (> (setq n (1- n)) -1) + (or (search-forward "|" pos t) + (and force + (progn (end-of-line 1) + (skip-chars-backward "^|") + (insert " | ")))))) +; (backward-char 2) t))))) + (when (and force (not (looking-at ".*|"))) + (save-excursion (end-of-line 1) (insert " | "))) + (if on-delim + (backward-char 1) + (if (looking-at " ") (forward-char 1)))))) + +(defun org-at-table-p (&optional table-type) + "Return t if the cursor is inside an org-type table. +If TABLE-TYPE is non-nil, also check for table.el-type tables." + (if org-enable-table-editor + (save-excursion + (beginning-of-line 1) + (looking-at (if table-type org-table-any-line-regexp + org-table-line-regexp))) + nil)) + +(defun org-at-table.el-p () + "Return t if and only if we are at a table.el table." + (and (org-at-table-p 'any) + (save-excursion + (goto-char (org-table-begin 'any)) + (looking-at org-table1-hline-regexp)))) + +(defun org-table-recognize-table.el () + "If there is a table.el table nearby, recognize it and move into it." + (if org-table-tab-recognizes-table.el + (if (org-at-table.el-p) + (progn + (beginning-of-line 1) + (if (looking-at org-table-dataline-regexp) + nil + (if (looking-at org-table1-hline-regexp) + (progn + (beginning-of-line 2) + (if (looking-at org-table-any-border-regexp) + (beginning-of-line -1))))) + (if (re-search-forward "|" (org-table-end t) t) + (progn + (require 'table) + (if (table--at-cell-p (point)) + t + (message "recognizing table.el table...") + (table-recognize-table) + (message "recognizing table.el table...done"))) + (error "This should not happen...")) + t) + nil) + nil)) + +(defun org-at-table-hline-p () + "Return t if the cursor is inside a hline in a table." + (if org-enable-table-editor + (save-excursion + (beginning-of-line 1) + (looking-at org-table-hline-regexp)) + nil)) + +(defun org-table-insert-column () + "Insert a new column into the table." + (interactive) + (if (not (org-at-table-p)) + (error "Not at a table")) + (org-table-find-dataline) + (let* ((col (max 1 (org-table-current-column))) + (beg (org-table-begin)) + (end (org-table-end)) + ;; Current cursor position + (linepos (+ (if (bolp) 1 0) (count-lines (point-min) (point)))) + (colpos col)) + (goto-char beg) + (while (< (point) end) + (if (org-at-table-hline-p) + nil + (org-table-goto-column col t) + (insert "| ")) + (beginning-of-line 2)) + (move-marker end nil) + (goto-line linepos) + (org-table-goto-column colpos) + (org-table-align) + (org-table-modify-formulas 'insert col))) + +(defun org-table-find-dataline () + "Find a dataline in the current table, which is needed for column commands." + (if (and (org-at-table-p) + (not (org-at-table-hline-p))) + t + (let ((col (current-column)) + (end (org-table-end))) + (move-to-column col) + (while (and (< (point) end) + (or (not (= (current-column) col)) + (org-at-table-hline-p))) + (beginning-of-line 2) + (move-to-column col)) + (if (and (org-at-table-p) + (not (org-at-table-hline-p))) + t + (error + "Please position cursor in a data line for column operations"))))) + +(defun org-table-delete-column () + "Delete a column into the table." + (interactive) + (if (not (org-at-table-p)) + (error "Not at a table")) + (org-table-find-dataline) + (org-table-check-inside-data-field) + (let* ((col (org-table-current-column)) + (beg (org-table-begin)) + (end (org-table-end)) + ;; Current cursor position + (linepos (+ (if (bolp) 1 0) (count-lines (point-min) (point)))) + (colpos col)) + (goto-char beg) + (while (< (point) end) + (if (org-at-table-hline-p) + nil + (org-table-goto-column col t) + (and (looking-at "|[^|\n]+|") + (replace-match "|"))) + (beginning-of-line 2)) + (move-marker end nil) + (goto-line linepos) + (org-table-goto-column colpos) + (org-table-align) + (org-table-modify-formulas 'remove col))) + +(defun org-table-move-column-right () + "Move column to the right." + (interactive) + (org-table-move-column nil)) +(defun org-table-move-column-left () + "Move column to the left." + (interactive) + (org-table-move-column 'left)) + +(defun org-table-move-column (&optional left) + "Move the current column to the right. With arg LEFT, move to the left." + (interactive "P") + (if (not (org-at-table-p)) + (error "Not at a table")) + (org-table-find-dataline) + (org-table-check-inside-data-field) + (let* ((col (org-table-current-column)) + (col1 (if left (1- col) col)) + (beg (org-table-begin)) + (end (org-table-end)) + ;; Current cursor position + (linepos (+ (if (bolp) 1 0) (count-lines (point-min) (point)))) + (colpos (if left (1- col) (1+ col)))) + (if (and left (= col 1)) + (error "Cannot move column further left")) + (if (and (not left) (looking-at "[^|\n]*|[^|\n]*$")) + (error "Cannot move column further right")) + (goto-char beg) + (while (< (point) end) + (if (org-at-table-hline-p) + nil + (org-table-goto-column col1 t) + (and (looking-at "|\\([^|\n]+\\)|\\([^|\n]+\\)|") + (replace-match "|\\2|\\1|"))) + (beginning-of-line 2)) + (move-marker end nil) + (goto-line linepos) + (org-table-goto-column colpos) + (org-table-align) + (org-table-modify-formulas 'swap col (if left (1- col) (1+ col))))) + +(defun org-table-move-row-down () + "Move table row down." + (interactive) + (org-table-move-row nil)) +(defun org-table-move-row-up () + "Move table row up." + (interactive) + (org-table-move-row 'up)) + +(defun org-table-move-row (&optional up) + "Move the current table line down. With arg UP, move it up." + (interactive "P") + (let ((col (current-column)) + (pos (point)) + (tonew (if up 0 2)) + txt) + (beginning-of-line tonew) + (if (not (org-at-table-p)) + (progn + (goto-char pos) + (error "Cannot move row further"))) + (goto-char pos) + (beginning-of-line 1) + (setq pos (point)) + (setq txt (buffer-substring (point) (1+ (point-at-eol)))) + (delete-region (point) (1+ (point-at-eol))) + (beginning-of-line tonew) + (insert txt) + (beginning-of-line 0) + (move-to-column col))) + +(defun org-table-insert-row (&optional arg) + "Insert a new row above the current line into the table. +With prefix ARG, insert below the current line." + (interactive "P") + (if (not (org-at-table-p)) + (error "Not at a table")) + (let* ((line + (org-expand-wide-chars + (buffer-substring-no-properties (point-at-bol) (point-at-eol)))) + new) + (if (string-match "^[ \t]*|-" line) + (setq new (mapcar (lambda (x) (if (member x '(?| ?+)) ?| ?\ )) line)) + (setq new (mapcar (lambda (x) (if (equal x ?|) ?| ?\ )) line))) + ;; Fix the first field if necessary + (setq new (concat new)) + (if (string-match "^[ \t]*| *[#$] *|" line) + (setq new (replace-match (match-string 0 line) t t new))) + (beginning-of-line (if arg 2 1)) + (let (org-table-may-need-update) + (insert-before-markers new) + (insert-before-markers "\n")) + (beginning-of-line 0) + (re-search-forward "| ?" (point-at-eol) t) + (and org-table-may-need-update (org-table-align)))) + +(defun org-table-insert-hline (&optional arg) + "Insert a horizontal-line below the current line into the table. +With prefix ARG, insert above the current line." + (interactive "P") + (if (not (org-at-table-p)) + (error "Not at a table")) + (let ((line + (org-expand-wide-chars + (buffer-substring-no-properties (point-at-bol) (point-at-eol)))) + (col (current-column)) + start) + (if (string-match "^[ \t]*|-" line) + (setq line + (mapcar (lambda (x) (if (member x '(?| ?+)) + (prog1 (if start ?+ ?|) (setq start t)) + (if start ?- ?\ ))) + line)) + (setq line + (mapcar (lambda (x) (if (equal x ?|) + (prog1 (if start ?+ ?|) (setq start t)) + (if start ?- ?\ ))) + line))) + (beginning-of-line (if arg 1 2)) + (apply 'insert line) + (if (equal (char-before (point)) ?+) + (progn (backward-delete-char 1) (insert "|"))) + (insert "\n") + (beginning-of-line (if arg 1 -1)) + (move-to-column col))) + +(defun org-expand-wide-chars (s) + "Expand wide characters to spaces." + (let (w a) + (mapconcat + (lambda (x) + (if (> (setq w (string-width (setq a (char-to-string x)))) 1) + (make-string w ?\ ) + a)) + s ""))) + +(defun org-table-kill-row () + "Delete the current row or horizontal line from the table." + (interactive) + (if (not (org-at-table-p)) + (error "Not at a table")) + (let ((col (current-column))) + (kill-region (point-at-bol) (min (1+ (point-at-eol)) (point-max))) + (if (not (org-at-table-p)) (beginning-of-line 0)) + (move-to-column col))) + +(defun org-table-sort-lines (beg end numericp) + "Sort table lines in region. +Point and mark define the first and last line to include. Both point and +mark should be in the column that is used for sorting. For example, to +sort according to column 3, put the mark in the first line to sort, in +table column 3. Put point into the last line to be included in the sorting, +also in table column 3. The command will prompt for the sorting method +\(n for numerical, a for alphanumeric)." + (interactive "r\nsSorting method: [n]=numeric [a]=alpha: ") + (setq numericp (string-match "[nN]" numericp)) + (org-table-align) ;; Just to be safe + (let* (bcol ecol cmp column lns) + (goto-char beg) + (org-table-check-inside-data-field) + (setq column (org-table-current-column) + beg (move-marker (make-marker) (point-at-bol))) + (goto-char end) + (org-table-check-inside-data-field) + (setq end (move-marker (make-marker) (1+ (point-at-eol)))) + (untabify beg end) + (goto-char beg) + (org-table-goto-column column) + (skip-chars-backward "^|") + (setq bcol (current-column)) + (org-table-goto-column (1+ column)) + (skip-chars-backward "^|") + (setq ecol (1- (current-column))) + (setq cmp (if numericp + (lambda (a b) (< (car a) (car b))) + (lambda (a b) (string< (car a) (car b))))) + (setq lns (mapcar (lambda(x) (cons (org-trim (substring x bcol ecol)) x)) + (split-string (buffer-substring beg end) "\n"))) + (if numericp + (setq lns (mapcar (lambda(x) + (cons (string-to-number (car x)) (cdr x))) + lns))) + (delete-region beg end) + (move-marker beg nil) + (move-marker end nil) + (insert (mapconcat 'cdr (setq lns (sort lns cmp)) "\n") "\n") + (message "%d lines sorted %s based on column %d" + (length lns) + (if numericp "numerically" "alphabetically") column))) + +(defun org-table-cut-region (beg end) + "Copy region in table to the clipboard and blank all relevant fields." + (interactive "r") + (org-table-copy-region beg end 'cut)) + +(defun org-table-copy-region (beg end &optional cut) + "Copy rectangular region in table to clipboard. +A special clipboard is used which can only be accessed +with `org-table-paste-rectangle'." + (interactive "rP") + (let* (l01 c01 l02 c02 l1 c1 l2 c2 ic1 ic2 + region cols + (rpl (if cut " " nil))) + (goto-char beg) + (org-table-check-inside-data-field) + (setq l01 (count-lines (point-min) (point)) + c01 (org-table-current-column)) + (goto-char end) + (org-table-check-inside-data-field) + (setq l02 (count-lines (point-min) (point)) + c02 (org-table-current-column)) + (setq l1 (min l01 l02) l2 (max l01 l02) + c1 (min c01 c02) c2 (max c01 c02)) + (catch 'exit + (while t + (catch 'nextline + (if (> l1 l2) (throw 'exit t)) + (goto-line l1) + (if (org-at-table-hline-p) (throw 'nextline (setq l1 (1+ l1)))) + (setq cols nil ic1 c1 ic2 c2) + (while (< ic1 (1+ ic2)) + (push (org-table-get-field ic1 rpl) cols) + (setq ic1 (1+ ic1))) + (push (nreverse cols) region) + (setq l1 (1+ l1))))) + (setq org-table-clip (nreverse region)) + (if cut (org-table-align)) + org-table-clip)) + +(defun org-table-paste-rectangle () + "Paste a rectangular region into a table. +The upper right corner ends up in the current field. All involved fields +will be overwritten. If the rectangle does not fit into the present table, +the table is enlarged as needed. The process ignores horizontal separator +lines." + (interactive) + (unless (and org-table-clip (listp org-table-clip)) + (error "First cut/copy a region to paste!")) + (org-table-check-inside-data-field) + (let* ((clip org-table-clip) + (line (count-lines (point-min) (point))) + (col (org-table-current-column)) + (org-enable-table-editor t) + (org-table-automatic-realign nil) + c cols field) + (while (setq cols (pop clip)) + (while (org-at-table-hline-p) (beginning-of-line 2)) + (if (not (org-at-table-p)) + (progn (end-of-line 0) (org-table-next-field))) + (setq c col) + (while (setq field (pop cols)) + (org-table-goto-column c nil 'force) + (org-table-get-field nil field) + (setq c (1+ c))) + (beginning-of-line 2)) + (goto-line line) + (org-table-goto-column col) + (org-table-align))) + +(defun org-table-convert () + "Convert from `org-mode' table to table.el and back. +Obviously, this only works within limits. When an Org-mode table is +converted to table.el, all horizontal separator lines get lost, because +table.el uses these as cell boundaries and has no notion of horizontal lines. +A table.el table can be converted to an Org-mode table only if it does not +do row or column spanning. Multiline cells will become multiple cells. +Beware, Org-mode does not test if the table can be successfully converted - it +blindly applies a recipe that works for simple tables." + (interactive) + (require 'table) + (if (org-at-table.el-p) + ;; convert to Org-mode table + (let ((beg (move-marker (make-marker) (org-table-begin t))) + (end (move-marker (make-marker) (org-table-end t)))) + (table-unrecognize-region beg end) + (goto-char beg) + (while (re-search-forward "^\\([ \t]*\\)\\+-.*\n" end t) + (replace-match "")) + (goto-char beg)) + (if (org-at-table-p) + ;; convert to table.el table + (let ((beg (move-marker (make-marker) (org-table-begin))) + (end (move-marker (make-marker) (org-table-end)))) + ;; first, get rid of all horizontal lines + (goto-char beg) + (while (re-search-forward "^\\([ \t]*\\)|-.*\n" end t) + (replace-match "")) + ;; insert a hline before first + (goto-char beg) + (org-table-insert-hline 'above) + (beginning-of-line -1) + ;; insert a hline after each line + (while (progn (beginning-of-line 3) (< (point) end)) + (org-table-insert-hline)) + (goto-char beg) + (setq end (move-marker end (org-table-end))) + ;; replace "+" at beginning and ending of hlines + (while (re-search-forward "^\\([ \t]*\\)|-" end t) + (replace-match "\\1+-")) + (goto-char beg) + (while (re-search-forward "-|[ \t]*$" end t) + (replace-match "-+")) + (goto-char beg))))) + +(defun org-table-wrap-region (arg) + "Wrap several fields in a column like a paragraph. +This is useful if you'd like to spread the contents of a field over several +lines, in order to keep the table compact. + +If there is an active region, and both point and mark are in the same column, +the text in the column is wrapped to minimum width for the given number of +lines. Generally, this makes the table more compact. A prefix ARG may be +used to change the number of desired lines. For example, `C-2 \\[org-table-wrap]' +formats the selected text to two lines. If the region was longer than two +lines, the remaining lines remain empty. A negative prefix argument reduces +the current number of lines by that amount. The wrapped text is pasted back +into the table. If you formatted it to more lines than it was before, fields +further down in the table get overwritten - so you might need to make space in +the table first. + +If there is no region, the current field is split at the cursor position and +the text fragment to the right of the cursor is prepended to the field one +line down. + +If there is no region, but you specify a prefix ARG, the current field gets +blank, and the content is appended to the field above." + (interactive "P") + (org-table-check-inside-data-field) + (if (org-region-active-p) + ;; There is a region: fill as a paragraph + (let ((beg (region-beginning)) + nlines) + (org-table-cut-region (region-beginning) (region-end)) + (if (> (length (car org-table-clip)) 1) + (error "Region must be limited to single column")) + (setq nlines (if arg + (if (< arg 1) + (+ (length org-table-clip) arg) + arg) + (length org-table-clip))) + (setq org-table-clip + (mapcar 'list (org-wrap (mapconcat 'car org-table-clip " ") + nil nlines))) + (goto-char beg) + (org-table-paste-rectangle)) + ;; No region, split the current field at point + (if arg + ;; combine with field above + (let ((s (org-table-blank-field)) + (col (org-table-current-column))) + (beginning-of-line 0) + (while (org-at-table-hline-p) (beginning-of-line 0)) + (org-table-goto-column col) + (skip-chars-forward "^|") + (skip-chars-backward " ") + (insert " " (org-trim s)) + (org-table-align)) + ;; split field + (when (looking-at "\\([^|]+\\)+|") + (let ((s (match-string 1))) + (replace-match " |") + (goto-char (match-beginning 0)) + (org-table-next-row) + (insert (org-trim s) " ") + (org-table-align)))))) + +(defun org-trim (s) + "Remove whitespace at beginning and end of string." + (if (string-match "^[ \t]+" s) (setq s (replace-match "" t t s))) + (if (string-match "[ \t]+$" s) (setq s (replace-match "" t t s))) + s) + +(defun org-wrap (string &optional width lines) + "Wrap string to either a number of lines, or a width in characters. +If WIDTH is non-nil, the string is wrapped to that width, however many lines +that costs. If there is a word longer than WIDTH, the text is actually +wrapped to the length of that word. +IF WIDTH is nil and LINES is non-nil, the string is forced into at most that +many lines, whatever width that takes. +The return value is a list of lines, without newlines at the end." + (let* ((words (org-split-string string "[ \t\n]+")) + (maxword (apply 'max (mapcar 'string-width words))) + w ll) + (cond (width + (org-do-wrap words (max maxword width))) + (lines + (setq w maxword) + (setq ll (org-do-wrap words maxword)) + (if (<= (length ll) lines) + ll + (setq ll words) + (while (> (length ll) lines) + (setq w (1+ w)) + (setq ll (org-do-wrap words w))) + ll)) + (t (error "Cannot wrap this"))))) + + +(defun org-do-wrap (words width) + "Create lines of maximum width WIDTH (in characters) from word list WORDS." + (let (lines line) + (while words + (setq line (pop words)) + (while (and words (< (+ (length line) (length (car words))) width)) + (setq line (concat line " " (pop words)))) + (setq lines (push line lines))) + (nreverse lines))) + +;; FIXME: I think I can make this more efficient +(defun org-split-string (string &optional separators) + "Splits STRING into substrings at SEPARATORS. +No empty strings are returned if there are matches at the beginning +and end of string." + (let ((rexp (or separators "[ \f\t\n\r\v]+")) + (start 0) + notfirst + (list nil)) + (while (and (string-match rexp string + (if (and notfirst + (= start (match-beginning 0)) + (< start (length string))) + (1+ start) start)) + (< (match-beginning 0) (length string))) + (setq notfirst t) + (or (eq (match-beginning 0) 0) + (and (eq (match-beginning 0) (match-end 0)) + (eq (match-beginning 0) start)) + (setq list + (cons (substring string start (match-beginning 0)) + list))) + (setq start (match-end 0))) + (or (eq start (length string)) + (setq list + (cons (substring string start) + list))) + (nreverse list))) + +(defun org-table-add-invisible-to-vertical-lines () + "Add an `invisible' property to vertical lines of current table." + (interactive) + (let* ((beg (org-table-begin)) + (end (org-table-end)) + (end1)) + (save-excursion + (goto-char beg) + (while (< (point) end) + (setq end1 (point-at-eol)) + (if (looking-at org-table-dataline-regexp) + (while (re-search-forward "|" end1 t) + (add-text-properties (1- (point)) (point) + '(invisible org-table))) + (while (re-search-forward "[+|]" end1 t) + (add-text-properties (1- (point)) (point) + '(invisible org-table)))) + (beginning-of-line 2))))) + +(defun org-table-toggle-vline-visibility (&optional arg) + "Toggle the visibility of table vertical lines. +The effect is immediate and on all tables in the file. +With prefix ARG, make lines invisible when ARG is positive, make lines +visible when ARG is not positive." + (interactive "P") + (let ((action (cond + ((and arg (> (prefix-numeric-value arg) 0)) 'on) + ((and arg (< (prefix-numeric-value arg) 1)) 'off) + (t (if (org-in-invisibility-spec-p '(org-table)) + 'off + 'on))))) + (if (eq action 'off) + (progn + (org-remove-from-invisibility-spec '(org-table)) + (org-table-map-tables 'org-table-align) + (message "Vertical table lines visible") + (if (org-at-table-p) + (org-table-align))) + (org-add-to-invisibility-spec '(org-table)) + (org-table-map-tables 'org-table-align) + (message "Vertical table lines invisible")) + (redraw-frame (selected-frame)))) + +(defun org-table-map-tables (function) + "Apply FUNCTION to the start of all tables in the buffer." + (save-excursion + (save-restriction + (widen) + (goto-char (point-min)) + (while (re-search-forward org-table-any-line-regexp nil t) + (message "Mapping tables: %d%%" (/ (* 100.0 (point)) (buffer-size))) + (beginning-of-line 1) + (if (looking-at org-table-line-regexp) + (save-excursion (funcall function))) + (re-search-forward org-table-any-border-regexp nil 1))))) + +(defun org-table-sum (&optional beg end nlast) + "Sum numbers in region of current table column. +The result will be displayed in the echo area, and will be available +as kill to be inserted with \\[yank]. + +If there is an active region, it is interpreted as a rectangle and all +numbers in that rectangle will be summed. If there is no active +region and point is located in a table column, sum all numbers in that +column. + +If at least one number looks like a time HH:MM or HH:MM:SS, all other +numbers are assumed to be times as well (in decimal hours) and the +numbers are added as such. + +If NLAST is a number, only the NLAST fields will actually be summed." + (interactive) + (save-excursion + (let (col (timecnt 0) diff h m s org-table-clip) + (cond + ((and beg end)) ; beg and end given explicitly + ((org-region-active-p) + (setq beg (region-beginning) end (region-end))) + (t + (setq col (org-table-current-column)) + (goto-char (org-table-begin)) + (unless (re-search-forward "^[ \t]*|[^-]" nil t) + (error "No table data")) + (org-table-goto-column col) +;not needed? (skip-chars-backward "^|") + (setq beg (point)) + (goto-char (org-table-end)) + (unless (re-search-backward "^[ \t]*|[^-]" nil t) + (error "No table data")) + (org-table-goto-column col) +;not needed? (skip-chars-forward "^|") + (setq end (point)))) + (let* ((items (apply 'append (org-table-copy-region beg end))) + (items1 (cond ((not nlast) items) + ((>= nlast (length items)) items) + (t (setq items (reverse items)) + (setcdr (nthcdr (1- nlast) items) nil) + (nreverse items)))) + (numbers (delq nil (mapcar 'org-table-get-number-for-summing + items1))) + (res (apply '+ numbers)) + (sres (if (= timecnt 0) + (format "%g" res) + (setq diff (* 3600 res) + h (floor (/ diff 3600)) diff (mod diff 3600) + m (floor (/ diff 60)) diff (mod diff 60) + s diff) + (format "%d:%02d:%02d" h m s)))) + (kill-new sres) + (if (interactive-p) + (message "%s" + (substitute-command-keys + (format "Sum of %d items: %-20s (\\[yank] will insert result into buffer)" + (length numbers) sres)))) + sres)))) + +(defun org-table-get-number-for-summing (s) + (let (n) + (if (string-match "^ *|? *" s) + (setq s (replace-match "" nil nil s))) + (if (string-match " *|? *$" s) + (setq s (replace-match "" nil nil s))) + (setq n (string-to-number s)) + (cond + ((and (string-match "0" s) + (string-match "\\`[-+ \t0.edED]+\\'" s)) 0) + ((string-match "\\`[ \t]+\\'" s) nil) + ((string-match "\\`\\([0-9]+\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?\\'" s) + (let ((h (string-to-number (or (match-string 1 s) "0"))) + (m (string-to-number (or (match-string 2 s) "0"))) + (s (string-to-number (or (match-string 4 s) "0")))) + (if (boundp 'timecnt) (setq timecnt (1+ timecnt))) + (* 1.0 (+ h (/ m 60.0) (/ s 3600.0))))) + ((equal n 0) nil) + (t n)))) + +(defun org-table-get-vertical-vector (desc &optional tbeg col) + "Get a calc vector from a column, accorting to descriptor DESC. +Optional arguments TBEG and COL can give the beginning of the table and +the current column, to avoid unnecessary parsing." + (save-excursion + (or tbeg (setq tbeg (org-table-begin))) + (or col (setq col (org-table-current-column))) + (let (beg end nn n n1 n2 l (thisline (org-current-line)) hline-list) + (cond + ((string-match "\\(I+\\)\\(-\\(I+\\)\\)?" desc) + (setq n1 (- (match-end 1) (match-beginning 1))) + (if (match-beginning 3) + (setq n2 (- (match-end 2) (match-beginning 3)))) + (setq n (if n2 (max n1 n2) n1)) + (setq n1 (if n2 (min n1 n2))) + (setq nn n) + (while (and (> nn 0) + (re-search-backward org-table-hline-regexp tbeg t)) + (push (org-current-line) hline-list) + (setq nn (1- nn))) + (setq hline-list (nreverse hline-list)) + (goto-line (nth (1- n) hline-list)) + (when (re-search-forward org-table-dataline-regexp) + (org-table-goto-column col) + (setq beg (point))) + (goto-line (if n1 (nth (1- n1) hline-list) thisline)) + (when (re-search-backward org-table-dataline-regexp) + (org-table-goto-column col) + (setq end (point))) + (setq l (apply 'append (org-table-copy-region beg end))) + (concat "[" (mapconcat (lambda (x) (setq x (org-trim x)) + (if (equal x "") "0" x)) + l ",") "]")) + ((string-match "\\([0-9]+\\)-\\([0-9]+\\)" desc) + (setq n1 (string-to-number (match-string 1 desc)) + n2 (string-to-number (match-string 2 desc))) + (beginning-of-line 1) + (save-excursion + (when (re-search-backward org-table-dataline-regexp tbeg t n1) + (org-table-goto-column col) + (setq beg (point)))) + (when (re-search-backward org-table-dataline-regexp tbeg t n2) + (org-table-goto-column col) + (setq end (point))) + (setq l (apply 'append (org-table-copy-region beg end))) + (concat "[" (mapconcat + (lambda (x) (setq x (org-trim x)) + (if (equal x "") "0" x)) + l ",") "]")) + ((string-match "\\([0-9]+\\)" desc) + (beginning-of-line 1) + (when (re-search-backward org-table-dataline-regexp tbeg t + (string-to-number (match-string 0 desc))) + (org-table-goto-column col) + (org-trim (org-table-get-field)))))))) + +(defvar org-table-formula-history nil) + +(defvar org-table-column-names nil + "Alist with column names, derived from the `!' line.") +(defvar org-table-column-name-regexp nil + "Regular expression matching the current column names.") +(defvar org-table-local-parameters nil + "Alist with parameter names, derived from the `$' line.") +(defvar org-table-named-field-locations nil + "Alist with locations of named fields.") + +(defun org-table-get-formula (&optional equation named) + "Read a formula from the minibuffer, offer stored formula as default." + (let* ((name (car (rassoc (list (org-current-line) + (org-table-current-column)) + org-table-named-field-locations))) + (scol (if named + (if name name + (error "Not in a named field")) + (int-to-string (org-table-current-column)))) + (dummy (and name (not named) + (not (y-or-n-p "Replace named-field formula with column equation? " )) + (error "Abort"))) + (org-table-may-need-update nil) + (stored-list (org-table-get-stored-formulas)) + (stored (cdr (assoc scol stored-list))) + (eq (cond + ((and stored equation (string-match "^ *=? *$" equation)) + stored) + ((stringp equation) + equation) + (t (read-string + (format "%s formula $%s=" (if named "Field" "Column") scol) + (or stored "") 'org-table-formula-history + ;stored + )))) + mustsave) + (when (not (string-match "\\S-" eq)) + ;; remove formula + (setq stored-list (delq (assoc scol stored-list) stored-list)) + (org-table-store-formulas stored-list) + (error "Formula removed")) + (if (string-match "^ *=?" eq) (setq eq (replace-match "" t t eq))) + (if (string-match " *$" eq) (setq eq (replace-match "" t t eq))) + (if (and name (not named)) + ;; We set the column equation, delete the named one. + (setq stored-list (delq (assoc name stored-list) stored-list) + mustsave t)) + (if stored + (setcdr (assoc scol stored-list) eq) + (setq stored-list (cons (cons scol eq) stored-list))) + (if (or mustsave (not (equal stored eq))) + (org-table-store-formulas stored-list)) + eq)) + +(defun org-table-store-formulas (alist) + "Store the list of formulas below the current table." + (setq alist (sort alist (lambda (a b) (string< (car a) (car b))))) + (save-excursion + (goto-char (org-table-end)) + (if (looking-at "\\([ \t]*\n\\)*#\\+TBLFM:.*\n?") + (delete-region (point) (match-end 0))) + (insert "#+TBLFM: " + (mapconcat (lambda (x) + (concat "$" (car x) "=" (cdr x))) + alist "::") + "\n"))) + +(defun org-table-get-stored-formulas () + "Return an alist with the t=stored formulas directly after current table." + (interactive) + (let (scol eq eq-alist strings string seen) + (save-excursion + (goto-char (org-table-end)) + (when (looking-at "\\([ \t]*\n\\)*#\\+TBLFM: *\\(.*\\)") + (setq strings (org-split-string (match-string 2) " *:: *")) + (while (setq string (pop strings)) + (when (string-match "\\$\\([a-zA-Z0-9]+\\) *= *\\(.*[^ \t]\\)" string) + (setq scol (match-string 1 string) + eq (match-string 2 string) + eq-alist (cons (cons scol eq) eq-alist)) + (if (member scol seen) + (error "Double definition `$%s=' in TBLFM line, please fix by hand" scol) + (push scol seen)))))) + (nreverse eq-alist))) + +(defun org-table-modify-formulas (action &rest columns) + "Modify the formulas stored below the current table. +ACTION can be `remove', `insert', `swap'. For `swap', two column numbers are +expected, for the other actions only a single column number is needed." + (let ((list (org-table-get-stored-formulas)) + (nmax (length (org-split-string + (buffer-substring (point-at-bol) (point-at-eol)) + "|"))) + col col1 col2 scol si sc1 sc2) + (cond + ((null list)) ; No action needed if there are no stored formulas + ((eq action 'remove) + (setq col (car columns) + scol (int-to-string col)) + (org-table-replace-in-formulas list scol "INVALID") + (if (assoc scol list) (setq list (delq (assoc scol list) list))) + (loop for i from (1+ col) upto nmax by 1 do + (setq si (int-to-string i)) + (org-table-replace-in-formulas list si (int-to-string (1- i))) + (if (assoc si list) (setcar (assoc si list) + (int-to-string (1- i)))))) + ((eq action 'insert) + (setq col (car columns)) + (loop for i from nmax downto col by 1 do + (setq si (int-to-string i)) + (org-table-replace-in-formulas list si (int-to-string (1+ i))) + (if (assoc si list) (setcar (assoc si list) + (int-to-string (1+ i)))))) + ((eq action 'swap) + (setq col1 (car columns) col2 (nth 1 columns) + sc1 (int-to-string col1) sc2 (int-to-string col2)) + ;; Hopefully, ZqZ will never be a name in a table... FIXME: + (org-table-replace-in-formulas list sc1 "ZqZ") + (org-table-replace-in-formulas list sc2 sc1) + (org-table-replace-in-formulas list "ZqZ" sc2) + (if (assoc sc1 list) (setcar (assoc sc1 list) "ZqZ")) + (if (assoc sc2 list) (setcar (assoc sc2 list) sc1)) + (if (assoc "ZqZ" list) (setcar (assoc "ZqZ" list) sc2))) + (t (error "Invalid action in `org-table-modify-formulas'"))) + (if list (org-table-store-formulas list)))) + +(defun org-table-replace-in-formulas (list s1 s2) + (let (elt re s) + (setq s1 (concat "$" (if (integerp s1) (int-to-string s1) s1)) + s2 (concat "$" (if (integerp s2) (int-to-string s2) s2)) + re (concat (regexp-quote s1) "\\>")) + (while (setq elt (pop list)) + (setq s (cdr elt)) + (while (string-match re s) + (setq s (replace-match s2 t t s))) + (setcdr elt s)))) + +(defun org-table-get-specials () + "Get the column names and local parameters for this table." + (save-excursion + (let ((beg (org-table-begin)) (end (org-table-end)) + names name fields fields1 field cnt c v line col) + (setq org-table-column-names nil + org-table-local-parameters nil + org-table-named-field-locations nil) + (goto-char beg) + (when (re-search-forward "^[ \t]*| *! *\\(|.*\\)" end t) + (setq names (org-split-string (match-string 1) " *| *") + cnt 1) + (while (setq name (pop names)) + (setq cnt (1+ cnt)) + (if (string-match "^[a-zA-Z][a-zA-Z0-9]*$" name) + (push (cons name (int-to-string cnt)) org-table-column-names)))) + (setq org-table-column-names (nreverse org-table-column-names)) + (setq org-table-column-name-regexp + (concat "\\$\\(" (mapconcat 'car org-table-column-names "\\|") "\\)\\>")) + (goto-char beg) + (while (re-search-forward "^[ \t]*| *\\$ *\\(|.*\\)" end t) + (setq fields (org-split-string (match-string 1) " *| *")) + (while (setq field (pop fields)) + (if (string-match "^\\([a-zA-Z][a-zA-Z0-9]*\\|%\\) *= *\\(.*\\)" field) + (push (cons (match-string 1 field) (match-string 2 field)) + org-table-local-parameters)))) + (goto-char beg) + (while (re-search-forward "^[ \t]*| *\\([_^]\\) *\\(|.*\\)" end t) + (setq c (match-string 1) + fields (org-split-string (match-string 2) " *| *")) + (save-excursion + (beginning-of-line (if (equal c "_") 2 0)) + (setq line (org-current-line) col 1) + (and (looking-at "^[ \t]*|[^|]*\\(|.*\\)") + (setq fields1 (org-split-string (match-string 1) " *| *")))) + (while (and fields1 (setq field (pop fields))) + (setq v (pop fields1) col (1+ col)) + (when (and (stringp field) (stringp v) + (string-match "^[a-zA-Z][a-zA-Z0-9]*$" field)) + (push (cons field v) org-table-local-parameters) + (push (list field line col) org-table-named-field-locations))))))) + +(defun org-this-word () + ;; Get the current word + (save-excursion + (let ((beg (progn (skip-chars-backward "^ \t\n") (point))) + (end (progn (skip-chars-forward "^ \t\n") (point)))) + (buffer-substring-no-properties beg end)))) + +(defun org-table-maybe-eval-formula () + "Check if the current field starts with \"=\" or \":=\". +If yes, store the formula and apply it." + ;; We already know we are in a table. Get field will only return a formula + ;; when appropriate. It might return a separator line, but no problem. + (when org-table-formula-evaluate-inline + (let* ((field (org-trim (or (org-table-get-field) ""))) + named eq) + (when (string-match "^:?=\\(.*\\)" field) + (setq named (equal (string-to-char field) ?:) + eq (match-string 1 field)) + (if (fboundp 'calc-eval) + (org-table-eval-formula (if named '(4) nil) eq)))))) + +(defvar org-recalc-commands nil + "List of commands triggering the recalculation of a line. +Will be filled automatically during use.") + +(defvar org-recalc-marks + '((" " . "Unmarked: no special line, no automatic recalculation") + ("#" . "Automatically recalculate this line upon TAB, RET, and C-c C-c in the line") + ("*" . "Recalculate only when entire table is recalculated with `C-u C-c *'") + ("!" . "Column name definition line. Reference in formula as $name.") + ("$" . "Parameter definition line name=value. Reference in formula as $name.") + ("_" . "Names for values in row below this one.") + ("^" . "Names for values in row above this one."))) + +(defun org-table-rotate-recalc-marks (&optional newchar) + "Rotate the recalculation mark in the first column. +If in any row, the first field is not consistent with a mark, +insert a new column for the markers. +When there is an active region, change all the lines in the region, +after prompting for the marking character. +After each change, a message will be displayed indicating the meaning +of the new mark." + (interactive) + (unless (org-at-table-p) (error "Not at a table")) + (let* ((marks (append (mapcar 'car org-recalc-marks) '(" "))) + (beg (org-table-begin)) + (end (org-table-end)) + (l (org-current-line)) + (l1 (if (org-region-active-p) (org-current-line (region-beginning)))) + (l2 (if (org-region-active-p) (org-current-line (region-end)))) + (have-col + (save-excursion + (goto-char beg) + (not (re-search-forward "^[ \t]*|[^-|][^|]*[^#!$*_^| \t][^|]*|" end t)))) + (col (org-table-current-column)) + (forcenew (car (assoc newchar org-recalc-marks))) + epos new) + (when l1 + (message "Change region to what mark? Type # * ! $ or SPC: ") + (setq newchar (char-to-string (read-char-exclusive)) + forcenew (car (assoc newchar org-recalc-marks)))) + (if (and newchar (not forcenew)) + (error "Invalid NEWCHAR `%s' in `org-table-rotate-recalc-marks'" + newchar)) + (if l1 (goto-line l1)) + (save-excursion + (beginning-of-line 1) + (unless (looking-at org-table-dataline-regexp) + (error "Not at a table data line"))) + (unless have-col + (org-table-goto-column 1) + (org-table-insert-column) + (org-table-goto-column (1+ col))) + (setq epos (point-at-eol)) + (save-excursion + (beginning-of-line 1) + (org-table-get-field + 1 (if (looking-at "^[ \t]*| *\\([#!$*^_ ]\\) *|") + (concat " " + (setq new (or forcenew + (cadr (member (match-string 1) marks)))) + " ") + " # "))) + (if (and l1 l2) + (progn + (goto-line l1) + (while (progn (beginning-of-line 2) (not (= (org-current-line) l2))) + (and (looking-at org-table-dataline-regexp) + (org-table-get-field 1 (concat " " new " ")))) + (goto-line l1))) + (if (not (= epos (point-at-eol))) (org-table-align)) + (goto-line l) + (and (interactive-p) (message (cdr (assoc new org-recalc-marks)))))) + +(defun org-table-maybe-recalculate-line () + "Recompute the current line if marked for it, and if we haven't just done it." + (interactive) + (and org-table-allow-automatic-line-recalculation + (not (and (memq last-command org-recalc-commands) + (equal org-last-recalc-line (org-current-line)))) + (save-excursion (beginning-of-line 1) + (looking-at org-table-auto-recalculate-regexp)) + (fboundp 'calc-eval) + (org-table-recalculate) t)) + +(defvar org-table-formula-debug nil + "Non-nil means, debug table formulas. +When nil, simply write \"#ERROR\" in corrupted fields.") + +(defvar modes) +(defsubst org-set-calc-mode (var &optional value) + (if (stringp var) + (setq var (assoc var '(("D" calc-angle-mode deg) + ("R" calc-angle-mode rad) + ("F" calc-prefer-frac t) + ("S" calc-symbolic-mode t))) + value (nth 2 var) var (nth 1 var))) + (if (memq var modes) + (setcar (cdr (memq var modes)) value) + (cons var (cons value modes))) + modes) + +(defun org-table-eval-formula (&optional arg equation + suppress-align suppress-const + suppress-store) + "Replace the table field value at the cursor by the result of a calculation. + +This function makes use of Dave Gillespie's Calc package, in my view the +most exciting program ever written for GNU Emacs. So you need to have Calc +installed in order to use this function. + +In a table, this command replaces the value in the current field with the +result of a formula. It also installs the formula as the \"current\" column +formula, by storing it in a special line below the table. When called +with a `C-u' prefix, the current field must ba a named field, and the +formula is installed as valid in only this specific field. + +When called, the command first prompts for a formula, which is read in +the minibuffer. Previously entered formulas are available through the +history list, and the last used formula is offered as a default. +These stored formulas are adapted correctly when moving, inserting, or +deleting columns with the corresponding commands. + +The formula can be any algebraic expression understood by the Calc package. +For details, see the Org-mode manual. + +This function can also be called from Lisp programs and offers +additional arguments: EQUATION can be the formula to apply. If this +argument is given, the user will not be prompted. SUPPRESS-ALIGN is +used to speed-up recursive calls by by-passing unnecessary aligns. +SUPPRESS-CONST suppresses the interpretation of constants in the +formula, assuming that this has been done already outside the function. +SUPPRESS-STORE means the formula should not be stored, either because +it is already stored, or because it is a modified equation that should +not overwrite the stored one." + (interactive "P") + (require 'calc) + (org-table-check-inside-data-field) + (org-table-get-specials) + (let* (fields + (ndown (if (integerp arg) arg 1)) + (org-table-automatic-realign nil) + (case-fold-search nil) + (down (> ndown 1)) + (formula (if (and equation suppress-store) + equation + (org-table-get-formula equation (equal arg '(4))))) + (n0 (org-table-current-column)) + (modes (copy-sequence org-calc-default-modes)) + n form fmt x ev orig c) + ;; Parse the format string. Since we have a lot of modes, this is + ;; a lot of work. However, I think calc still uses most of the time. + (if (string-match ";" formula) + (let ((tmp (org-split-string formula ";"))) + (setq formula (car tmp) + fmt (concat (cdr (assoc "%" org-table-local-parameters)) + (nth 1 tmp))) + (while (string-match "[pnfse]\\(-?[0-9]+\\)" fmt) + (setq c (string-to-char (match-string 1 fmt)) + n (string-to-number (or (match-string 1 fmt) ""))) + (if (= c ?p) (setq modes (org-set-calc-mode 'calc-internal-prec n)) + (setq modes (org-set-calc-mode + 'calc-float-format + (list (cdr (assoc c '((?n . float) (?f . fix) + (?s . sci) (?e . eng)))) + n)))) + (setq fmt (replace-match "" t t fmt))) + (while (string-match "[DRFS]" fmt) + (setq modes (org-set-calc-mode (match-string 0 fmt))) + (setq fmt (replace-match "" t t fmt))) + (unless (string-match "\\S-" fmt) + (setq fmt nil)))) + (if (and (not suppress-const) org-table-formula-use-constants) + (setq formula (org-table-formula-substitute-names formula))) + (setq orig (or (get-text-property 1 :orig-formula formula) "?")) + (while (> ndown 0) + (setq fields (org-split-string + (buffer-substring + (point-at-bol) (point-at-eol)) " *| *")) + (if org-table-formula-numbers-only + (setq fields (mapcar + (lambda (x) (number-to-string (string-to-number x))) + fields))) + (setq ndown (1- ndown)) + (setq form (copy-sequence formula)) + ;; Insert the references to fields in same row + (while (string-match "\\$\\([0-9]+\\)?" form) + (setq n (if (match-beginning 1) + (string-to-number (match-string 1 form)) + n0) + x (nth (1- n) fields)) + (unless x (error "Invalid field specifier \"%s\"" + (match-string 0 form))) + (if (equal x "") (setq x "0")) + (setq form (replace-match (concat "(" x ")") t t form))) + ;; Insert ranges in current column + (while (string-match "\\&[-I0-9]+" form) + (setq form (replace-match + (save-match-data + (org-table-get-vertical-vector (match-string 0 form) + nil n0)) + t t form))) + (setq ev (calc-eval (cons form modes) + (if org-table-formula-numbers-only 'num))) + + (when org-table-formula-debug + (with-output-to-temp-buffer "*Help*" + (princ (format "Substitution history of formula +Orig: %s +$xyz-> %s +$1-> %s\n" orig formula form)) + (if (listp ev) + (princ (format " %s^\nError: %s" + (make-string (car ev) ?\-) (nth 1 ev))) + (princ (format "Result: %s\nFormat: %s\nFinal: %s" + ev (or fmt "NONE") + (if fmt (format fmt (string-to-number ev)) ev))))) + (shrink-window-if-larger-than-buffer (get-buffer-window "*Help*")) + (unless (and (interactive-p) (not ndown)) + (unless (let (inhibit-redisplay) + (y-or-n-p "Debugging Formula. Continue to next? ")) + (org-table-align) + (error "Abort")) + (delete-window (get-buffer-window "*Help*")) + (message ""))) + (if (listp ev) (setq fmt nil ev "#ERROR")) + (org-table-justify-field-maybe + (if fmt (format fmt (string-to-number ev)) ev)) + (if (and down (> ndown 0) (looking-at ".*\n[ \t]*|[^-]")) + (call-interactively 'org-return) + (setq ndown 0))) + (and down (org-table-maybe-recalculate-line)) + (or suppress-align (and org-table-may-need-update + (org-table-align))))) + +(defun org-table-recalculate (&optional all noalign) + "Recalculate the current table line by applying all stored formulas." + (interactive "P") + (or (memq this-command org-recalc-commands) + (setq org-recalc-commands (cons this-command org-recalc-commands))) + (unless (org-at-table-p) (error "Not at a table")) + (org-table-get-specials) + (let* ((eqlist (sort (org-table-get-stored-formulas) + (lambda (a b) (string< (car a) (car b))))) + (inhibit-redisplay t) + (line-re org-table-dataline-regexp) + (thisline (+ (if (bolp) 1 0) (count-lines (point-min) (point)))) + (thiscol (org-table-current-column)) + beg end entry eqlnum eqlname eql (cnt 0) eq a name) + ;; Insert constants in all formulas + (setq eqlist + (mapcar (lambda (x) + (setcdr x (org-table-formula-substitute-names (cdr x))) + x) + eqlist)) + ;; Split the equation list + (while (setq eq (pop eqlist)) + (if (<= (string-to-char (car eq)) ?9) + (push eq eqlnum) + (push eq eqlname))) + (setq eqlnum (nreverse eqlnum) eqlname (nreverse eqlname)) + (if all + (progn + (setq end (move-marker (make-marker) (1+ (org-table-end)))) + (goto-char (setq beg (org-table-begin))) + (if (re-search-forward org-table-calculate-mark-regexp end t) + ;; This is a table with marked lines, only compute selected lines + (setq line-re org-table-recalculate-regexp) + ;; Move forward to the first non-header line + (if (and (re-search-forward org-table-dataline-regexp end t) + (re-search-forward org-table-hline-regexp end t) + (re-search-forward org-table-dataline-regexp end t)) + (setq beg (match-beginning 0)) + nil))) ;; just leave beg where it is + (setq beg (point-at-bol) + end (move-marker (make-marker) (1+ (point-at-eol))))) + (goto-char beg) + (and all (message "Re-applying formulas to full table...")) + (while (re-search-forward line-re end t) + (unless (string-match "^ *[_^!$] *$" (org-table-get-field 1)) + ;; Unprotected line, recalculate + (and all (message "Re-applying formulas to full table...(line %d)" + (setq cnt (1+ cnt)))) + (setq org-last-recalc-line (org-current-line)) + (setq eql eqlnum) + (while (setq entry (pop eql)) + (goto-line org-last-recalc-line) + (org-table-goto-column (string-to-number (car entry)) nil 'force) + (org-table-eval-formula nil (cdr entry) 'noalign 'nocst 'nostore)))) + (goto-line thisline) + (org-table-goto-column thiscol) + (or noalign (and org-table-may-need-update (org-table-align)) + (and all (message "Re-applying formulas to %d lines...done" cnt))) + ;; Now do the names fields + (while (setq eq (pop eqlname)) + (setq name (car eq) + a (assoc name org-table-named-field-locations)) + (when a + (message "Re-applying formula to named field: %s" name) + (goto-line (nth 1 a)) + (org-table-goto-column (nth 2 a)) + (org-table-eval-formula nil (cdr eq) 'noalign 'nocst 'nostore))) + ;; back to initial position + (goto-line thisline) + (org-table-goto-column thiscol) + (or noalign (and org-table-may-need-update (org-table-align)) + (and all (message "Re-applying formulas...done"))))) + +(defun org-table-formula-substitute-names (f) + "Replace $const with values in string F." + (let ((start 0) a n1 n2 nn1 nn2 s (f1 f)) + ;; First, check for column names + (while (setq start (string-match org-table-column-name-regexp f start)) + (setq start (1+ start)) + (setq a (assoc (match-string 1 f) org-table-column-names)) + (setq f (replace-match (concat "$" (cdr a)) t t f))) + ;; Expand ranges to vectors + (while (string-match "\\$\\([0-9]+\\)\\.\\.\\.?\\$\\([0-9]+\\)" f) + (setq n1 (string-to-number (match-string 1 f)) + n2 (string-to-number (match-string 2 f)) + nn1 (1+ (min n1 n2)) nn2 (max n1 n2) + s (concat "[($" (number-to-string (1- nn1)) ")")) + (loop for i from nn1 upto nn2 do + (setq s (concat s ",($" (int-to-string i) ")"))) + (setq s (concat s "]")) + (if (< n2 n1) (setq s (concat "rev(" s ")"))) + (setq f (replace-match s t t f))) + ;; Parameters and constants + (setq start 0) + (while (setq start (string-match "\\$\\([a-zA-Z][a-zA-Z0-9]*\\)" f start)) + (setq start (1+ start)) + (if (setq a (save-match-data + (org-table-get-constant (match-string 1 f)))) + (setq f (replace-match (concat "(" a ")") t t f)))) + (if org-table-formula-debug + (put-text-property 0 (length f) :orig-formula f1 f)) + f)) + +(defun org-table-get-constant (const) + "Find the value for a parameter or constant in a formula. +Parameters get priority." + (or (cdr (assoc const org-table-local-parameters)) + (cdr (assoc const org-table-formula-constants)) + (and (fboundp 'constants-get) (constants-get const)) + "#UNDEFINED_NAME")) + +(defvar org-edit-formulas-map (make-sparse-keymap)) +(define-key org-edit-formulas-map "\C-c\C-c" 'org-finish-edit-formulas) +(define-key org-edit-formulas-map "\C-c\C-q" 'org-abort-edit-formulas) +(define-key org-edit-formulas-map "\C-c?" 'org-show-variable) + +(defvar org-pos) +(defvar org-window-configuration) + +(defun org-table-edit-formulas () + "Edit the formulas of the current table in a separate buffer." + (interactive) + (unless (org-at-table-p) + (error "Not at a table")) + (org-table-get-specials) + (let ((eql (org-table-get-stored-formulas)) + (pos (move-marker (make-marker) (point))) + (wc (current-window-configuration)) + entry loc s) + (switch-to-buffer-other-window "*Edit Formulas*") + (erase-buffer) + (fundamental-mode) + (set (make-local-variable 'org-pos) pos) + (set (make-local-variable 'org-window-configuration) wc) + (use-local-map org-edit-formulas-map) + (setq s "# Edit formulas and finish with `C-c C-c'. +# Use `C-u C-c C-c' to also appy them immediately to the entire table. +# Use `C-c ?' to get information about $name at point. +# To cancel editing, press `C-c C-q'.\n") + (put-text-property 0 (length s) 'face 'font-lock-comment-face s) + (insert s) + (while (setq entry (pop eql)) + (when (setq loc (assoc (car entry) org-table-named-field-locations)) + (setq s (format "# Named formula, referring to column %d in line %d\n" + (nth 2 loc) (nth 1 loc))) + (put-text-property 0 (length s) 'face 'font-lock-comment-face s) + (insert s)) + (setq s (concat "$" (car entry) "=" (cdr entry) "\n")) + (remove-text-properties 0 (length s) '(face nil) s) + (insert s)) + (goto-char (point-min)) + (message "Edit formulas and finish with `C-c C-c'."))) + +(defun org-show-variable () + "Show the location/value of the $ expression at point." + (interactive) + (let (var (pos org-pos) (win (selected-window)) e) + (save-excursion + (or (looking-at "\\$") (skip-chars-backward "$a-zA-Z0-9")) + (if (looking-at "\\$\\([a-zA-Z0-9]+\\)") + (setq var (match-string 1)) + (error "No variable at point"))) + (cond + ((setq e (assoc var org-table-named-field-locations)) + (switch-to-buffer-other-window (marker-buffer pos)) + (goto-line (nth 1 e)) + (org-table-goto-column (nth 2 e)) + (select-window win) + (message "Named field, column %d of line %d" (nth 2 e) (nth 1 e))) + ((setq e (assoc var org-table-column-names)) + (switch-to-buffer-other-window (marker-buffer pos)) + (goto-char pos) + (goto-char (org-table-begin)) + (if (re-search-forward (concat "^[ \t]*| *! *.*?| *\\(" var "\\) *|") + (org-table-end) t) + (progn + (goto-char (match-beginning 1)) + (message "Named column (column %s)" (cdr e))) + (error "Column name not found")) + (select-window win)) + ((string-match "^[0-9]$" var) + ;; column number + (switch-to-buffer-other-window (marker-buffer pos)) + (goto-char pos) + (goto-char (org-table-begin)) + (recenter 1) + (if (re-search-forward org-table-dataline-regexp + (org-table-end) t) + (progn + (goto-char (match-beginning 0)) + (org-table-goto-column (string-to-number var)) + (message "Column %s" var)) + (error "Column name not found")) + (select-window win)) + ((setq e (assoc var org-table-local-parameters)) + (switch-to-buffer-other-window (marker-buffer pos)) + (goto-char pos) + (goto-char (org-table-begin)) + (if (re-search-forward (concat "^[ \t]*| *\\$ *.*?| *\\(" var "=\\)") nil t) + (progn + (goto-char (match-beginning 1)) + (message "Local parameter.")) + (error "Parameter not found")) + (select-window win)) + (t + (cond + ((setq e (assoc var org-table-formula-constants)) + (message "Constant: $%s=%s in `org-table-formula-constants'." var (cdr e))) + ((setq e (and (fboundp 'constants-get) (constants-get var))) + (message "Constant: $%s=%s, retrieved from `constants.el'." var e)) + (t (error "Undefined name $%s" var))))))) + +(defun org-finish-edit-formulas (&optional arg) + "Parse the buffer for formula definitions and install them. +With prefix ARG, apply the new formulas to the table." + (interactive "P") + (let ((pos org-pos) eql) + (goto-char (point-min)) + (while (re-search-forward "^\\$\\([a-zA-Z0-9]+\\) *= *\\(.*?\\) *$" nil t) + (push (cons (match-string 1) (match-string 2)) eql)) + (set-window-configuration org-window-configuration) + (select-window (get-buffer-window (marker-buffer pos))) + (goto-char pos) + (unless (org-at-table-p) + (error "Lost table position - cannot install formulae")) + (org-table-store-formulas eql) + (move-marker pos nil) + (kill-buffer "*Edit Formulas*") + (if arg + (org-table-recalculate 'all) + (message "New formulas installed - press C-u C-c C-c to apply.")))) + +(defun org-abort-edit-formulas () + "Abort editing formulas, without installing the changes." + (interactive) + (let ((pos org-pos)) + (set-window-configuration org-window-configuration) + (select-window (get-buffer-window (marker-buffer pos))) + (goto-char pos) + (message "Formula editing aborted without installing changes"))) + +;;; The orgtbl minor mode + +;; Define a minor mode which can be used in other modes in order to +;; integrate the org-mode table editor. + +;; This is really a hack, because the org-mode table editor uses several +;; keys which normally belong to the major mode, for example the TAB and +;; RET keys. Here is how it works: The minor mode defines all the keys +;; necessary to operate the table editor, but wraps the commands into a +;; function which tests if the cursor is currently inside a table. If that +;; is the case, the table editor command is executed. However, when any of +;; those keys is used outside a table, the function uses `key-binding' to +;; look up if the key has an associated command in another currently active +;; keymap (minor modes, major mode, global), and executes that command. +;; There might be problems if any of the keys used by the table editor is +;; otherwise used as a prefix key. + +;; Another challenge is that the key binding for TAB can be tab or \C-i, +;; likewise the binding for RET can be return or \C-m. Orgtbl-mode +;; addresses this by checking explicitly for both bindings. + +;; The optimized version (see variable `orgtbl-optimized') takes over +;; all keys which are bound to `self-insert-command' in the *global map*. +;; Some modes bind other commands to simple characters, for example +;; AUCTeX binds the double quote to `Tex-insert-quote'. With orgtbl-mode +;; active, this binding is ignored inside tables and replaced with a +;; modified self-insert. + +(defcustom orgtbl-optimized (eq org-enable-table-editor 'optimized) + "Non-nil means, use the optimized table editor version for `orgtbl-mode'. +In the optimized version, the table editor takes over all simple keys that +normally just insert a character. In tables, the characters are inserted +in a way to minimize disturbing the table structure (i.e. in overwrite mode +for empty fields). Outside tables, the correct binding of the keys is +restored. + +The default for this option is t if the optimized version is also used in +Org-mode. See the variable `org-enable-table-editor' for details. Changing +this variable requires a restart of Emacs to become effective." + :group 'org-table + :type 'boolean) + +(defvar orgtbl-mode nil + "Variable controlling `orgtbl-mode', a minor mode enabling the `org-mode' +table editor in arbitrary modes.") +(make-variable-buffer-local 'orgtbl-mode) + +(defvar orgtbl-mode-map (make-keymap) + "Keymap for `orgtbl-mode'.") + +;;;###autoload +(defun turn-on-orgtbl () + "Unconditionally turn on `orgtbl-mode'." + (orgtbl-mode 1)) + +;;;###autoload +(defun orgtbl-mode (&optional arg) + "The `org-mode' table editor as a minor mode for use in other modes." + (interactive) + (if (eq major-mode 'org-mode) + ;; Exit without error, in case some hook functions calls this + ;; by accident in org-mode. + (message "Orgtbl-mode is not useful in org-mode, command ignored") + (setq orgtbl-mode + (if arg (> (prefix-numeric-value arg) 0) (not orgtbl-mode))) + (if orgtbl-mode + (progn + (and (orgtbl-setup) (defun orgtbl-setup () nil)) + ;; Make sure we are first in minor-mode-map-alist + (let ((c (assq 'orgtbl-mode minor-mode-map-alist))) + (and c (setq minor-mode-map-alist + (cons c (delq c minor-mode-map-alist))))) + (set (make-local-variable (quote org-table-may-need-update)) t) + (org-add-hook 'before-change-functions 'org-before-change-function + nil 'local) + (set (make-local-variable 'org-old-auto-fill-inhibit-regexp) + auto-fill-inhibit-regexp) + (set (make-local-variable 'auto-fill-inhibit-regexp) + (if auto-fill-inhibit-regexp + (concat "\\([ \t]*|\\|" auto-fill-inhibit-regexp) + "[ \t]*|")) + (easy-menu-add orgtbl-mode-menu) + (run-hooks 'orgtbl-mode-hook)) + (setq auto-fill-inhibit-regexp org-old-auto-fill-inhibit-regexp) + (remove-hook 'before-change-functions 'org-before-change-function t) + (easy-menu-remove orgtbl-mode-menu) + (force-mode-line-update 'all)))) + +;; Install it as a minor mode. +(put 'orgtbl-mode :included t) +(put 'orgtbl-mode :menu-tag "Org Table Mode") +(add-minor-mode 'orgtbl-mode " OrgTbl" orgtbl-mode-map) + +(defun orgtbl-make-binding (fun n &rest keys) + "Create a function for binding in the table minor mode. +FUN is the command to call inside a table. N is used to create a unique +command name. KEYS are keys that should be checked in for a command +to execute outside of tables." + (eval + (list 'defun + (intern (concat "orgtbl-hijacker-command-" (int-to-string n))) + '(arg) + (concat "In tables, run `" (symbol-name fun) "'.\n" + "Outside of tables, run the binding of `" + (mapconcat (lambda (x) (format "%s" x)) keys "' or `") + "'.") + '(interactive "p") + (list 'if + '(org-at-table-p) + (list 'call-interactively (list 'quote fun)) + (list 'let '(orgtbl-mode) + (list 'call-interactively + (append '(or) + (mapcar (lambda (k) + (list 'key-binding k)) + keys) + '('orgtbl-error)))))))) + +(defun orgtbl-error () + "Error when there is no default binding for a table key." + (interactive) + (error "This key is has no function outside tables")) + +(defun orgtbl-setup () + "Setup orgtbl keymaps." + (let ((nfunc 0) + (bindings + (list + '([(meta shift left)] org-table-delete-column) + '([(meta left)] org-table-move-column-left) + '([(meta right)] org-table-move-column-right) + '([(meta shift right)] org-table-insert-column) + '([(meta shift up)] org-table-kill-row) + '([(meta shift down)] org-table-insert-row) + '([(meta up)] org-table-move-row-up) + '([(meta down)] org-table-move-row-down) + '("\C-c\C-w" org-table-cut-region) + '("\C-c\M-w" org-table-copy-region) + '("\C-c\C-y" org-table-paste-rectangle) + '("\C-c-" org-table-insert-hline) +; '([(shift tab)] org-table-previous-field) + '("\C-m" org-table-next-row) + (list (org-key 'S-return) 'org-table-copy-down) + '([(meta return)] org-table-wrap-region) + '("\C-c\C-q" org-table-wrap-region) + '("\C-c?" org-table-current-column) + '("\C-c " org-table-blank-field) + '("\C-c+" org-table-sum) + '("\C-c|" org-table-toggle-vline-visibility) + '("\C-c=" org-table-eval-formula) + '("\C-c'" org-table-edit-formulas) + '("\C-c*" org-table-recalculate) + '("\C-c^" org-table-sort-lines) + '([(control ?#)] org-table-rotate-recalc-marks))) + elt key fun cmd) + (while (setq elt (pop bindings)) + (setq nfunc (1+ nfunc)) + (setq key (car elt) + fun (nth 1 elt) + cmd (orgtbl-make-binding fun nfunc key)) + (define-key orgtbl-mode-map key cmd)) + ;; Special treatment needed for TAB and RET + (define-key orgtbl-mode-map [(return)] + (orgtbl-make-binding 'orgtbl-ret 100 [(return)] "\C-m")) + (define-key orgtbl-mode-map "\C-m" + (orgtbl-make-binding 'orgtbl-ret 101 "\C-m" [(return)])) + (define-key orgtbl-mode-map [(tab)] + (orgtbl-make-binding 'orgtbl-tab 102 [(tab)] "\C-i")) + (define-key orgtbl-mode-map "\C-i" + (orgtbl-make-binding 'orgtbl-tab 103 "\C-i" [(tab)]))) + (define-key orgtbl-mode-map "\C-i" + (orgtbl-make-binding 'orgtbl-tab 104 [(shift tab)])) + (define-key orgtbl-mode-map "\C-c\C-c" + (orgtbl-make-binding 'org-ctrl-c-ctrl-c 105 "\C-c\C-c")) + (when orgtbl-optimized + ;; If the user wants maximum table support, we need to hijack + ;; some standard editing functions + (org-remap orgtbl-mode-map + 'self-insert-command 'orgtbl-self-insert-command + 'delete-char 'orgtbl-delete-char + 'delete-backward-char 'orgtbl-delete-backward-char) + (define-key orgtbl-mode-map "|" 'org-force-self-insert)) + (easy-menu-define orgtbl-mode-menu orgtbl-mode-map "OrgTbl menu" + '("OrgTbl" + ["Align" org-ctrl-c-ctrl-c :active (org-at-table-p) :keys "C-c C-c"] + ["Next Field" org-cycle :active (org-at-table-p) :keys "TAB"] + ["Previous Field" org-shifttab :active (org-at-table-p) :keys "S-TAB"] + ["Next Row" org-return :active (org-at-table-p) :keys "RET"] + "--" + ["Blank Field" org-table-blank-field :active (org-at-table-p) :keys "C-c SPC"] + ["Copy Field from Above" + org-table-copy-down :active (org-at-table-p) :keys "S-RET"] + "--" + ("Column" + ["Move Column Left" org-metaleft :active (org-at-table-p) :keys "M-"] + ["Move Column Right" org-metaright :active (org-at-table-p) :keys "M-"] + ["Delete Column" org-shiftmetaleft :active (org-at-table-p) :keys "M-S-"] + ["Insert Column" org-shiftmetaright :active (org-at-table-p) :keys "M-S-"]) + ("Row" + ["Move Row Up" org-metaup :active (org-at-table-p) :keys "M-"] + ["Move Row Down" org-metadown :active (org-at-table-p) :keys "M-"] + ["Delete Row" org-shiftmetaup :active (org-at-table-p) :keys "M-S-"] + ["Insert Row" org-shiftmetadown :active (org-at-table-p) :keys "M-S-"] + ["Sort lines in region" org-table-sort-lines (org-at-table-p) :keys "C-c ^"] + "--" + ["Insert Hline" org-table-insert-hline :active (org-at-table-p) :keys "C-c -"]) + ("Rectangle" + ["Copy Rectangle" org-copy-special :active (org-at-table-p)] + ["Cut Rectangle" org-cut-special :active (org-at-table-p)] + ["Paste Rectangle" org-paste-special :active (org-at-table-p)] + ["Fill Rectangle" org-table-wrap-region :active (org-at-table-p)]) + "--" + ["Set Column Formula" org-table-eval-formula :active (org-at-table-p) :keys "C-c ="] + ["Set Named Field Formula" (org-table-eval-formula '(4)) :active (org-at-table-p) :keys "C-u C-c ="] + ["Edit Formulas" org-table-edit-formulas :active (org-at-table-p) :keys "C-c '"] + ["Recalculate line" org-table-recalculate :active (org-at-table-p) :keys "C-c *"] + ["Recalculate all" (org-table-recalculate '(4)) :active (org-at-table-p) :keys "C-u C-c *"] + ["Toggle Recalculate Mark" org-table-rotate-recalc-marks :active (org-at-table-p) :keys "C-c #"] + ["Sum Column/Rectangle" org-table-sum + :active (or (org-at-table-p) (org-region-active-p)) :keys "C-c +"] + ["Which Column?" org-table-current-column :active (org-at-table-p) :keys "C-c ?"] + ["Debug Formulas" + (setq org-table-formula-debug (not org-table-formula-debug)) + :style toggle :selected org-table-formula-debug] + )) + t) + +(defun orgtbl-tab () + "Justification and field motion for `orgtbl-mode'." + (interactive) + (org-table-justify-field-maybe) + (org-table-next-field)) + +(defun orgtbl-ret () + "Justification and field motion for `orgtbl-mode'." + (interactive) + (org-table-justify-field-maybe) + (org-table-next-row)) + +(defun orgtbl-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 +overwritten, and the table is not marked as requiring realignment." + (interactive "p") + (if (and (org-at-table-p) + (or + (and org-table-auto-blank-field + (member last-command + '(orgtbl-hijacker-command-100 + orgtbl-hijacker-command-101 + orgtbl-hijacker-command-102 + orgtbl-hijacker-command-103 + orgtbl-hijacker-command-104 + orgtbl-hijacker-command-105)) + (org-table-blank-field)) + t) + (eq N 1) + (looking-at "[^|\n]* +|")) + (let (org-table-may-need-update) + (goto-char (1- (match-end 0))) + (delete-backward-char 1) + (goto-char (match-beginning 0)) + (self-insert-command N)) + (setq org-table-may-need-update t) + (let (orgtbl-mode) + (call-interactively (key-binding (vector last-input-event)))))) + +(defun org-force-self-insert (N) + "Needed to enforce self-insert under remapping." + (interactive "p") + (self-insert-command N)) + +(defun orgtbl-delete-backward-char (N) + "Like `delete-backward-char', insert whitespace at field end in tables. +When deleting backwards, in tables this function will insert whitespace in +front of the next \"|\" separator, to keep the table aligned. The table will +still be marked for re-alignment, because a narrow field may lead to a +reduced column width." + (interactive "p") + (if (and (org-at-table-p) + (eq N 1) + (string-match "|" (buffer-substring (point-at-bol) (point))) + (looking-at ".*?|")) + (let ((pos (point))) + (backward-delete-char N) + (skip-chars-forward "^|") + (insert " ") + (goto-char (1- pos))) + (delete-backward-char N))) + +(defun orgtbl-delete-char (N) + "Like `delete-char', but insert whitespace at field end in tables. +When deleting characters, in tables this function will insert whitespace in +front of the next \"|\" separator, to keep the table aligned. The table +will still be marked for re-alignment, because a narrow field may lead to +a reduced column width." + (interactive "p") + (if (and (org-at-table-p) + (not (bolp)) + (not (= (char-after) ?|)) + (eq N 1)) + (if (looking-at ".*?|") + (let ((pos (point))) + (replace-match (concat + (substring (match-string 0) 1 -1) + " |")) + (goto-char pos))) + (delete-char N))) + +;;; Exporting + +(defconst org-level-max 20) + +(defun org-export-find-first-heading-line (list) + "Remove all lines from LIST which are before the first headline." + (let ((orig-list list) + (re (concat "^" outline-regexp))) + (while (and list + (not (string-match re (car list)))) + (pop list)) + (or list orig-list))) + +(defun org-skip-comments (lines) + "Skip lines starting with \"#\" and subtrees starting with COMMENT." + (let ((re1 (concat "^\\(\\*+\\)[ \t]+" org-comment-string)) + (re2 "^\\(\\*+\\)[ \t\n\r]") + rtn line level) + (while (setq line (pop lines)) + (cond + ((and (string-match re1 line) + (setq level (- (match-end 1) (match-beginning 1)))) + ;; Beginning of a COMMENT subtree. Skip it. + (while (and (setq line (pop lines)) + (or (not (string-match re2 line)) + (> (- (match-end 1) (match-beginning 1)) level)))) + (setq lines (cons line lines))) + ((string-match "^#" line) + ;; an ordinary comment line + ) + ((and org-export-table-remove-special-lines + (string-match "^[ \t]*| *[!_^] *|" line)) + ;; a special table line that should be removed + ) + (t (setq rtn (cons line rtn))))) + (nreverse rtn))) + +;; ASCII + +(defconst org-ascii-underline '(?\$ ?\# ?^ ?\~ ?\= ?\-) + "Characters for underlining headings in ASCII export.") + +(defconst org-html-entities + '(("nbsp") + ("iexcl") + ("cent") + ("pound") + ("curren") + ("yen") + ("brvbar") + ("sect") + ("uml") + ("copy") + ("ordf") + ("laquo") + ("not") + ("shy") + ("reg") + ("macr") + ("deg") + ("plusmn") + ("sup2") + ("sup3") + ("acute") + ("micro") + ("para") + ("middot") + ("odot"."o") + ("star"."*") + ("cedil") + ("sup1") + ("ordm") + ("raquo") + ("frac14") + ("frac12") + ("frac34") + ("iquest") + ("Agrave") + ("Aacute") + ("Acirc") + ("Atilde") + ("Auml") + ("Aring") ("AA"."Å") + ("AElig") + ("Ccedil") + ("Egrave") + ("Eacute") + ("Ecirc") + ("Euml") + ("Igrave") + ("Iacute") + ("Icirc") + ("Iuml") + ("ETH") + ("Ntilde") + ("Ograve") + ("Oacute") + ("Ocirc") + ("Otilde") + ("Ouml") + ("times") + ("Oslash") + ("Ugrave") + ("Uacute") + ("Ucirc") + ("Uuml") + ("Yacute") + ("THORN") + ("szlig") + ("agrave") + ("aacute") + ("acirc") + ("atilde") + ("auml") + ("aring") + ("aelig") + ("ccedil") + ("egrave") + ("eacute") + ("ecirc") + ("euml") + ("igrave") + ("iacute") + ("icirc") + ("iuml") + ("eth") + ("ntilde") + ("ograve") + ("oacute") + ("ocirc") + ("otilde") + ("ouml") + ("divide") + ("oslash") + ("ugrave") + ("uacute") + ("ucirc") + ("uuml") + ("yacute") + ("thorn") + ("yuml") + ("fnof") + ("Alpha") + ("Beta") + ("Gamma") + ("Delta") + ("Epsilon") + ("Zeta") + ("Eta") + ("Theta") + ("Iota") + ("Kappa") + ("Lambda") + ("Mu") + ("Nu") + ("Xi") + ("Omicron") + ("Pi") + ("Rho") + ("Sigma") + ("Tau") + ("Upsilon") + ("Phi") + ("Chi") + ("Psi") + ("Omega") + ("alpha") + ("beta") + ("gamma") + ("delta") + ("epsilon") + ("varepsilon"."ε") + ("zeta") + ("eta") + ("theta") + ("iota") + ("kappa") + ("lambda") + ("mu") + ("nu") + ("xi") + ("omicron") + ("pi") + ("rho") + ("sigmaf") ("varsigma"."ς") + ("sigma") + ("tau") + ("upsilon") + ("phi") + ("chi") + ("psi") + ("omega") + ("thetasym") ("vartheta"."ϑ") + ("upsih") + ("piv") + ("bull") ("bullet"."•") + ("hellip") ("dots"."…") + ("prime") + ("Prime") + ("oline") + ("frasl") + ("weierp") + ("image") + ("real") + ("trade") + ("alefsym") + ("larr") ("leftarrow"."←") ("gets"."←") + ("uarr") ("uparrow"."↑") + ("rarr") ("to"."→") ("rightarrow"."→") + ("darr")("downarrow"."↓") + ("harr") ("leftrightarrow"."↔") + ("crarr") ("hookleftarrow"."↵") ; has round hook, not quite CR + ("lArr") ("Leftarrow"."⇐") + ("uArr") ("Uparrow"."⇑") + ("rArr") ("Rightarrow"."⇒") + ("dArr") ("Downarrow"."⇓") + ("hArr") ("Leftrightarrow"."⇔") + ("forall") + ("part") ("partial"."∂") + ("exist") ("exists"."∃") + ("empty") ("emptyset"."∅") + ("nabla") + ("isin") ("in"."∈") + ("notin") + ("ni") + ("prod") + ("sum") + ("minus") + ("lowast") ("ast"."∗") + ("radic") + ("prop") ("proptp"."∝") + ("infin") ("infty"."∞") + ("ang") ("angle"."∠") + ("and") ("vee"."∧") + ("or") ("wedge"."∨") + ("cap") + ("cup") + ("int") + ("there4") + ("sim") + ("cong") ("simeq"."≅") + ("asymp")("approx"."≈") + ("ne") ("neq"."≠") + ("equiv") + ("le") + ("ge") + ("sub") ("subset"."⊂") + ("sup") ("supset"."⊃") + ("nsub") + ("sube") + ("supe") + ("oplus") + ("otimes") + ("perp") + ("sdot") ("cdot"."⋅") + ("lceil") + ("rceil") + ("lfloor") + ("rfloor") + ("lang") + ("rang") + ("loz") ("Diamond"."◊") + ("spades") ("spadesuit"."♠") + ("clubs") ("clubsuit"."♣") + ("hearts") ("diamondsuit"."♥") + ("diams") ("diamondsuit"."♦") + ("quot") + ("amp") + ("lt") + ("gt") + ("OElig") + ("oelig") + ("Scaron") + ("scaron") + ("Yuml") + ("circ") + ("tilde") + ("ensp") + ("emsp") + ("thinsp") + ("zwnj") + ("zwj") + ("lrm") + ("rlm") + ("ndash") + ("mdash") + ("lsquo") + ("rsquo") + ("sbquo") + ("ldquo") + ("rdquo") + ("bdquo") + ("dagger") + ("Dagger") + ("permil") + ("lsaquo") + ("rsaquo") + ("euro") + + ("arccos"."arccos") + ("arcsin"."arcsin") + ("arctan"."arctan") + ("arg"."arg") + ("cos"."cos") + ("cosh"."cosh") + ("cot"."cot") + ("coth"."coth") + ("csc"."csc") + ("deg"."deg") + ("det"."det") + ("dim"."dim") + ("exp"."exp") + ("gcd"."gcd") + ("hom"."hom") + ("inf"."inf") + ("ker"."ker") + ("lg"."lg") + ("lim"."lim") + ("liminf"."liminf") + ("limsup"."limsup") + ("ln"."ln") + ("log"."log") + ("max"."max") + ("min"."min") + ("Pr"."Pr") + ("sec"."sec") + ("sin"."sin") + ("sinh"."sinh") + ("sup"."sup") + ("tan"."tan") + ("tanh"."tanh") + ) + "Entities for TeX->HTML translation. +Entries can be like (\"ent\"), in which case \"\\ent\" will be translated to +\"&ent;\". An entry can also be a dotted pair like (\"ent\".\"&other;\"). +In that case, \"\\ent\" will be translated to \"&other;\". +The list contains HTML entities for Latin-1, Greek and other symbols. +It is supplemented by a number of commonly used TeX macros with appropriate +translations. There is currently no way for users to extend this.") + +(defun org-cleaned-string-for-export (string) + "Cleanup a buffer substring so that links can be created safely." + (interactive) + (let* ((cb (current-buffer)) + (re-radio (and org-target-link-regexp + (concat "\\([^<]\\)\\(" org-target-link-regexp "\\)"))) + rtn) + (save-excursion + (set-buffer (get-buffer-create " org-mode-tmp")) + (erase-buffer) + (insert string) + (org-mode) + ;; Find targets in comments and move them out of comments, + ;; but mark them as targets that should be invisible + (goto-char (point-min)) + (while (re-search-forward "^#.*?\\(<<\r\n]+>>>?\\).*" nil t) + (replace-match "\\1(INVISIBLE)")) + ;; Find matches for radio targets and turn them into links + (goto-char (point-min)) + (when re-radio + (while (re-search-forward re-radio nil t) + (replace-match "\\1[[\\2]]"))) + ;; Find all links that contain a newline and put them into a single line + (goto-char (point-min)) + (while (re-search-forward "\\(\\[\\[[^]]*?\\)[ \t]*\n[ \t]*\\([^]]*\\]\\]\\)" nil t) + (replace-match "\\1 \\2") + (goto-char (match-beginning 0))) + ;; Remove comments + (goto-char (point-min)) + (while (re-search-forward "^#.*\n?" nil t) + (replace-match "")) + (setq rtn (buffer-string))) + (kill-buffer " org-mode-tmp") + rtn)) + +(defun org-solidify-link-text (s &optional alist) + "Take link text and make a safe target out of it." + (save-match-data + (let* ((rtn + (mapconcat + 'identity + (org-split-string s "[ \t\r\n]+") "--")) + (a (assoc rtn alist))) + (or (cdr a) rtn)))) + +(defun org-convert-to-odd-levels () + "Convert an org-mode file with all levels allowed to one with odd levels. +This will leave level 1 alone, convert level 2 to level 3, level 3 to +level 5 etc." + (interactive) + (when (yes-or-no-p "Are you sure you want to globally change levels to odd? ") + (let ((org-odd-levels-only nil) n) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^\\*\\*+" nil t) + (setq n (1- (length (match-string 0)))) + (while (>= (setq n (1- n)) 0) + (org-demote)) + (end-of-line 1)))))) + + +(defun org-convert-to-oddeven-levels () + "Convert an org-mode file with only odd levels to one with odd and even levels. +This promotes level 3 to level 2, level 5 to level 3 etc. If the file contains a +section with an even level, conversion would destroy the structure of the file. An error +is signaled in this case." + (interactive) + (goto-char (point-min)) + ;; First check if there are no even levels + (when (re-search-forward "^\\(\\*\\*\\)+[^*]" nil t) + (org-show-hierarchy-above) + (error "Not all levels are odd in this file. Conversion not possible.")) + (when (yes-or-no-p "Are you sure you want to globally change levels to odd-even? ") + (let ((org-odd-levels-only nil) n) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^\\*\\*+" nil t) + (setq n (/ (length (match-string 0)) 2)) + (while (>= (setq n (1- n)) 0) + (org-promote)) + (end-of-line 1)))))) + +(defun org-tr-level (n) + "Make N odd if required." + (if org-odd-levels-only (1+ (/ n 2)) n)) + +(defvar org-last-level nil) ; dynamically scoped variable + +(defun org-export-as-ascii (arg) + "Export the outline as a pretty ASCII file. +If there is an active region, export only the region. +The prefix ARG specifies how many levels of the outline should become +underlined headlines. The default is 3." + (interactive "P") + (setq-default org-todo-line-regexp org-todo-line-regexp) + (let* ((region + (buffer-substring + (if (org-region-active-p) (region-beginning) (point-min)) + (if (org-region-active-p) (region-end) (point-max)))) + (lines (org-export-find-first-heading-line + (org-skip-comments + (org-split-string + (org-cleaned-string-for-export region) + "[\r\n]")))) + (org-startup-with-deadline-check nil) + (level 0) line txt + (umax nil) + (case-fold-search nil) + (filename (concat (file-name-sans-extension buffer-file-name) + ".txt")) + (buffer (find-file-noselect filename)) + (levels-open (make-vector org-level-max nil)) + (date (format-time-string "%Y/%m/%d" (current-time))) + (time (format-time-string "%X" (org-current-time))) + (author user-full-name) + (title (buffer-name)) + (options nil) + (email user-mail-address) + (language org-export-default-language) + (text nil) + (todo nil) + (lang-words nil)) + + (setq org-last-level 1) + (org-init-section-numbers) + + (find-file-noselect filename) + + ;; Search for the export key lines + (org-parse-key-lines) + + (setq lang-words (or (assoc language org-export-language-setup) + (assoc "en" org-export-language-setup))) + (if org-export-ascii-show-new-buffer + (switch-to-buffer-other-window buffer) + (set-buffer buffer)) + (erase-buffer) + (fundamental-mode) + (if options (org-parse-export-options options)) + (setq umax (if arg (prefix-numeric-value arg) + org-export-headline-levels)) + + ;; File header + (if title (org-insert-centered title ?=)) + (insert "\n") + (if (or author email) + (insert (concat (nth 1 lang-words) ": " (or author "") + (if email (concat " <" email ">") "") + "\n"))) + (if (and date time) + (insert (concat (nth 2 lang-words) ": " date " " time "\n"))) + (if text (insert (concat (org-html-expand-for-ascii text) "\n\n"))) + + (insert "\n\n") + + (if org-export-with-toc + (progn + (insert (nth 3 lang-words) "\n" + (make-string (length (nth 3 lang-words)) ?=) "\n") + (mapcar '(lambda (line) + (if (string-match org-todo-line-regexp + line) + ;; This is a headline + (progn + (setq level (- (match-end 1) (match-beginning 1)) + level (org-tr-level level) + txt (match-string 3 line) + todo + (or (and (match-beginning 2) + (not (equal (match-string 2 line) + org-done-string))) + ; TODO, not DONE + (and (= level umax) + (org-search-todo-below + line lines level)))) + (setq txt (org-html-expand-for-ascii txt)) + + (if org-export-with-section-numbers + (setq txt (concat (org-section-number level) + " " txt))) + (if (<= level umax) + (progn + (insert + (make-string (* (1- level) 4) ?\ ) + (format (if todo "%s (*)\n" "%s\n") txt)) + (setq org-last-level level)) + )))) + lines))) + + (org-init-section-numbers) + (while (setq line (pop lines)) + ;; Remove the quoted HTML tags. + (setq line (org-html-expand-for-ascii line)) + ;; Remove targets + (while (string-match "<<]*>>>?[ \t]*\n?" line) + (setq line (replace-match "" t t line))) + ;; Replace internal links + (while (string-match org-bracket-link-regexp line) + (setq line (replace-match + (if (match-end 3) "[\\3]" "[\\1]") + t nil line))) + (cond + ((string-match "^\\(\\*+\\)[ \t]*\\(.*\\)" line) + ;; a Headline + (setq level (org-tr-level (- (match-end 1) (match-beginning 1))) + txt (match-string 2 line)) + (org-ascii-level-start level txt umax)) + (t (insert line "\n")))) + (normal-mode) + (save-buffer) + (goto-char (point-min)))) + +(defun org-search-todo-below (line lines level) + "Search the subtree below LINE for any TODO entries." + (let ((rest (cdr (memq line lines))) + (re org-todo-line-regexp) + line lv todo) + (catch 'exit + (while (setq line (pop rest)) + (if (string-match re line) + (progn + (setq lv (- (match-end 1) (match-beginning 1)) + todo (and (match-beginning 2) + (not (equal (match-string 2 line) + org-done-string)))) + ; TODO, not DONE + (if (<= lv level) (throw 'exit nil)) + (if todo (throw 'exit t)))))))) + +;; FIXME: Try to handle and as faces via text properties. +;; FIXME: Can I implement *bold*,/italic/ and _underline_ for ASCII export? +(defun org-html-expand-for-ascii (line) + "Handle quoted HTML for ASCII export." + (if org-export-html-expand + (while (string-match "@<[^<>\n]*>" line) + ;; We just remove the tags for now. + (setq line (replace-match "" nil nil line)))) + line) + +(defun org-insert-centered (s &optional underline) + "Insert the string S centered and underline it with character UNDERLINE." + (let ((ind (max (/ (- 80 (string-width s)) 2) 0))) + (insert (make-string ind ?\ ) s "\n") + (if underline + (insert (make-string ind ?\ ) + (make-string (string-width s) underline) + "\n")))) + +(defun org-ascii-level-start (level title umax) + "Insert a new level in ASCII export." + (let (char) + (if (> level umax) + (insert (make-string (* 2 (- level umax 1)) ?\ ) "* " title "\n") + (if (or (not (equal (char-before) ?\n)) + (not (equal (char-before (1- (point))) ?\n))) + (insert "\n")) + (setq char (nth (- umax level) (reverse org-ascii-underline))) + (if org-export-with-section-numbers + (setq title (concat (org-section-number level) " " title))) + (insert title "\n" (make-string (string-width title) char) "\n")))) + +(defun org-export-copy-visible () + "Copy the visible part of the buffer to another buffer, for printing. +Also removes the first line of the buffer if it specifies a mode, +and all options lines." + (interactive) + (let* ((filename (concat (file-name-sans-extension buffer-file-name) + ".txt")) + (buffer (find-file-noselect filename)) + (ore (concat + (org-make-options-regexp + '("CATEGORY" "SEQ_TODO" "PRI_TODO" "TYP_TODO" + "STARTUP" "ARCHIVE" + "TITLE" "AUTHOR" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE")) + (if org-noutline-p "\\(\n\\|$\\)" ""))) + s e) + (with-current-buffer buffer + (erase-buffer) + (text-mode)) + (save-excursion + (setq s (goto-char (point-min))) + (while (not (= (point) (point-max))) + (goto-char (org-find-invisible)) + (append-to-buffer buffer s (point)) + (setq s (goto-char (org-find-visible))))) + (switch-to-buffer-other-window buffer) + (newline) + (goto-char (point-min)) + (if (looking-at ".*-\\*- mode:.*\n") + (replace-match "")) + (while (re-search-forward ore nil t) + (replace-match "")) + (goto-char (point-min)))) + +(defun org-find-visible () + (if (featurep 'noutline) + (let ((s (point))) + (while (and (not (= (point-max) (setq s (next-overlay-change s)))) + (get-char-property s 'invisible))) + s) + (skip-chars-forward "^\n") + (point))) +(defun org-find-invisible () + (if (featurep 'noutline) + (let ((s (point))) + (while (and (not (= (point-max) (setq s (next-overlay-change s)))) + (not (get-char-property s 'invisible)))) + s) + (skip-chars-forward "^\r") + (point))) + +;; HTML + +(defun org-get-current-options () + "Return a string with current options as keyword options. +Does include HTML export options as well as TODO and CATEGORY stuff." + (format + "#+TITLE: %s +#+AUTHOR: %s +#+EMAIL: %s +#+LANGUAGE: %s +#+TEXT: Some descriptive text to be emitted. Several lines OK. +#+OPTIONS: H:%d num:%s toc:%s \\n:%s @:%s ::%s |:%s ^:%s *:%s TeX:%s +#+CATEGORY: %s +#+SEQ_TODO: %s +#+TYP_TODO: %s +#+STARTUP: %s %s %s %s +#+ARCHIVE: %s +" + (buffer-name) (user-full-name) user-mail-address org-export-default-language + org-export-headline-levels + org-export-with-section-numbers + org-export-with-toc + org-export-preserve-breaks + org-export-html-expand + org-export-with-fixed-width + org-export-with-tables + org-export-with-sub-superscripts + org-export-with-emphasize + org-export-with-TeX-macros + (file-name-nondirectory buffer-file-name) + (if (equal org-todo-interpretation 'sequence) + (mapconcat 'identity org-todo-keywords " ") + "TODO FEEDBACK VERIFY DONE") + (if (equal org-todo-interpretation 'type) + (mapconcat 'identity org-todo-keywords " ") + "Me Jason Marie DONE") + (cdr (assoc org-startup-folded + '((nil . "nofold")(t . "fold")(content . "content")))) + (if org-startup-with-deadline-check "dlcheck" "nodlcheck") + (if org-odd-levels-only "odd" "oddeven") + (if org-hide-leading-stars "hidestars" "showstars") + org-archive-location + )) + +(defun org-insert-export-options-template () + "Insert into the buffer a template with information for exporting." + (interactive) + (if (not (bolp)) (newline)) + (let ((s (org-get-current-options))) + (and (string-match "#\\+CATEGORY" s) + (setq s (substring s 0 (match-beginning 0)))) + (insert s))) + +(defun org-toggle-fixed-width-section (arg) + "Toggle the fixed-width export. +If there is no active region, the QUOTE keyword at the current headline is +inserted or removed. When present, it causes the text between this headline +and the next to be exported as fixed-width text, and unmodified. +If there is an active region, this command adds or removes a colon as the +first character of this line. If the first character of a line is a colon, +this line is also exported in fixed-width font." + (interactive "P") + (let* ((cc 0) + (regionp (org-region-active-p)) + (beg (if regionp (region-beginning) (point))) + (end (if regionp (region-end))) + (nlines (or arg (if (and beg end) (count-lines beg end) 1))) + (re "[ \t]*\\(:\\)") + off) + (if regionp + (save-excursion + (goto-char beg) + (setq cc (current-column)) + (beginning-of-line 1) + (setq off (looking-at re)) + (while (> nlines 0) + (setq nlines (1- nlines)) + (beginning-of-line 1) + (cond + (arg + (move-to-column cc t) + (insert ":\n") + (forward-line -1)) + ((and off (looking-at re)) + (replace-match "" t t nil 1)) + ((not off) (move-to-column cc t) (insert ":"))) + (forward-line 1))) + (save-excursion + (org-back-to-heading) + (if (looking-at (concat outline-regexp + "\\( +\\<" org-quote-string "\\>\\)")) + (replace-match "" t t nil 1) + (if (looking-at outline-regexp) + (progn + (goto-char (match-end 0)) + (insert " " org-quote-string)))))))) + +(defun org-export-as-html-and-open (arg) + "Export the outline as HTML and immediately open it with a browser. +If there is an active region, export only the region. +The prefix ARG specifies how many levels of the outline should become +headlines. The default is 3. Lower levels will become bulleted lists." + (interactive "P") + (org-export-as-html arg 'hidden) + (org-open-file buffer-file-name)) + +(defun org-export-as-html-batch () + "Call `org-export-as-html', may be used in batch processing as +emacs --batch + --load=$HOME/lib/emacs/org.el + --eval \"(setq org-export-headline-levels 2)\" + --visit=MyFile --funcall org-export-as-html-batch" + (org-export-as-html org-export-headline-levels 'hidden)) + +(defun org-export-as-html (arg &optional hidden) + "Export the outline as a pretty HTML file. +If there is an active region, export only the region. +The prefix ARG specifies how many levels of the outline should become +headlines. The default is 3. Lower levels will become bulleted lists." + (interactive "P") + (setq-default org-todo-line-regexp org-todo-line-regexp) + (setq-default org-deadline-line-regexp org-deadline-line-regexp) + (setq-default org-done-string org-done-string) + (let* ((style org-export-html-style) + (odd org-odd-levels-only) + (region-p (org-region-active-p)) + (region + (buffer-substring + (if region-p (region-beginning) (point-min)) + (if region-p (region-end) (point-max)))) + (all_lines + (org-skip-comments (org-split-string + (org-cleaned-string-for-export region) + "[\r\n]"))) + (lines (org-export-find-first-heading-line all_lines)) + (level 0) (line "") (origline "") txt todo + (umax nil) + (filename (concat (file-name-sans-extension buffer-file-name) + ".html")) + (buffer (find-file-noselect filename)) + (levels-open (make-vector org-level-max nil)) + (date (format-time-string "%Y/%m/%d" (current-time))) + (time (format-time-string "%X" (org-current-time))) + (author user-full-name) + (title (buffer-name)) + (options nil) + (quote-re (concat "^\\*+[ \t]*" org-quote-string "\\>")) + (inquote nil) + (infixed nil) + (in-local-list nil) + (local-list-num nil) + (local-list-indent nil) + (llt org-plain-list-ordered-item-terminator) + (email user-mail-address) + (language org-export-default-language) + (text nil) + (lang-words nil) + (target-alist nil) tg + (head-count 0) cnt + (start 0) + ;; FIXME: The following returns always nil under XEmacs + (coding-system (and (fboundp 'coding-system-get) + (boundp 'buffer-file-coding-system) + buffer-file-coding-system)) + (coding-system-for-write (or coding-system coding-system-for-write)) + (save-buffer-coding-system (or coding-system save-buffer-coding-system)) + (charset (and coding-system + (coding-system-get coding-system 'mime-charset))) + table-open type + table-buffer table-orig-buffer + ind start-is-num starter + ) + (message "Exporting...") + + (setq org-last-level 1) + (org-init-section-numbers) + + ;; Search for the export key lines + (org-parse-key-lines) + (setq lang-words (or (assoc language org-export-language-setup) + (assoc "en" org-export-language-setup))) + + ;; Switch to the output buffer + (if (or hidden (not org-export-html-show-new-buffer)) + (set-buffer buffer) + (switch-to-buffer-other-window buffer)) + (erase-buffer) + (fundamental-mode) + (let ((case-fold-search nil) + (org-odd-levels-only odd)) + (if options (org-parse-export-options options)) + (setq umax (if arg (prefix-numeric-value arg) + org-export-headline-levels)) + + ;; File header + (insert (format + " + +%s + + + + +%s + +" + language (org-html-expand title) (or charset "iso-8859-1") + date time author style)) + (if title (insert (concat "

" + (org-html-expand title) "

\n"))) + (if author (insert (concat (nth 1 lang-words) ": " author "\n"))) + (if email (insert (concat "<" + email ">\n"))) + (if (or author email) (insert "
\n")) + (if (and date time) (insert (concat (nth 2 lang-words) ": " + date " " time "
\n"))) + (if text (insert (concat "

\n" (org-html-expand text)))) + (if org-export-with-toc + (progn + (insert (format "

%s

\n" (nth 3 lang-words))) + (insert "
    \n") + (setq lines + (mapcar '(lambda (line) + (if (string-match org-todo-line-regexp line) + ;; This is a headline + (progn + (setq level (- (match-end 1) (match-beginning 1)) + level (org-tr-level level) + txt (save-match-data + (org-html-expand + (match-string 3 line))) + todo + (or (and (match-beginning 2) + (not (equal (match-string 2 line) + org-done-string))) + ; TODO, not DONE + (and (= level umax) + (org-search-todo-below + line lines level)))) + (if org-export-with-section-numbers + (setq txt (concat (org-section-number level) + " " txt))) + (if (<= level umax) + (progn + (setq head-count (+ head-count 1)) + (if (> level org-last-level) + (progn + (setq cnt (- level org-last-level)) + (while (>= (setq cnt (1- cnt)) 0) + (insert "
      ")) + (insert "\n"))) + (if (< level org-last-level) + (progn + (setq cnt (- org-last-level level)) + (while (>= (setq cnt (1- cnt)) 0) + (insert "
    ")) + (insert "\n"))) + ;; Check for targets + (while (string-match org-target-regexp line) + (setq tg (match-string 1 line) + line (replace-match + (concat "@" tg "@ ") + t t line)) + (push (cons (org-solidify-link-text tg) + (format "sec-%d" head-count)) + target-alist)) + (while (string-match "<\\(<\\)+\\|>\\(>\\)+" txt) + (setq txt (replace-match "" t t txt))) + (insert + (format + (if todo + "
  • %s\n" + "
  • %s\n") + head-count txt)) + + (setq org-last-level level)) + ))) + line) + lines)) + (while (> org-last-level 0) + (setq org-last-level (1- org-last-level)) + (insert "
\n")) + )) + (setq head-count 0) + (org-init-section-numbers) + + (while (setq line (pop lines) origline line) + (catch 'nextline + + ;; end of quote section? + (when (and inquote (string-match "^\\*+" line)) + (insert "\n") + (setq inquote nil)) + ;; inside a quote section? + (when inquote + (insert (org-html-protect line) "\n") + (throw 'nextline nil)) + + ;; verbatim lines + (when (and org-export-with-fixed-width + (string-match "^[ \t]*:\\(.*\\)" line)) + (when (not infixed) + (setq infixed t) + (insert "
\n"))
+	    (insert (org-html-protect (match-string 1 line)) "\n")
+	    (when (and lines
+		       (not (string-match "^[ \t]*\\(:.*\\)"
+					  (car lines))))
+	      (setq infixed nil)
+	      (insert "
\n")) + (throw 'nextline nil)) + + + ;; make targets to anchors + (while (string-match "<<]*\\)>>>?\\((INVISIBLE)\\)?[ \t]*\n?" line) + (cond + ((match-end 2) + (setq line (replace-match + (concat "@\\nbsp@") + t t line))) + ((and org-export-with-toc (equal (string-to-char line) ?*)) + (setq line (replace-match + (concat "@" (match-string 1 line) "@ ") +; (concat "@" (match-string 1 line) "@ ") + t t line))) + (t + (setq line (replace-match + (concat "@" (match-string 1 line) "@ ") + t t line))))) + ;; Replace internal links + (while (string-match org-bracket-link-regexp line) + (setq line (replace-match + (concat + "@" + (match-string (if (match-end 3) 3 1) line) + "@") + t t line))) + + ;; Protect the external links + (setq start 0) + (while (string-match org-link-maybe-angles-regexp line start) + (setq start (match-end 0)) + (setq line (replace-match + (concat "\000" (match-string 1 line) "\000") + t t line))) + + ;; replace "&" by "&", "<" and ">" by "<" and ">" + ;; handle @<..> HTML tags (replace "@>..<" by "<..>") + (setq line (org-html-expand line)) + + ;; Format the links + (setq start 0) + (while (string-match org-protected-link-regexp line start) + (setq start (- (match-end 0) 2)) + (setq type (match-string 1 line)) + (cond + ((member type '("http" "https" "ftp" "mailto" "news")) + ;; standard URL + (setq line (replace-match + ; "<\\1:\\2>" + "\\1:\\2" + nil nil line))) + ((string= type "file") + ;; FILE link + (let* ((filename (match-string 2 line)) + (abs-p (file-name-absolute-p filename)) + (thefile (if abs-p (expand-file-name filename) filename)) + (thefile (save-match-data + (if (string-match ":[0-9]+$" thefile) + (replace-match "" t t thefile) + thefile))) + (file-is-image-p + (save-match-data + (string-match (org-image-file-name-regexp) thefile)))) + (setq line (replace-match + (if (and org-export-html-inline-images + file-is-image-p) + (concat "") + (concat "\\1:\\2")) + nil nil line)))) + + ((member type '("bbdb" "vm" "wl" "mhe" "rmail" "gnus" "shell")) + (setq line (replace-match + "<\\1:\\2>" nil nil line))))) + + ;; TODO items + (if (and (string-match org-todo-line-regexp line) + (match-beginning 2)) + (if (equal (match-string 2 line) org-done-string) + (setq line (replace-match + "\\2" + nil nil line 2)) + (setq line (replace-match "\\2" + nil nil line 2)))) + + ;; DEADLINES + (if (string-match org-deadline-line-regexp line) + (progn + (if (save-match-data + (string-match "\\&" + nil nil line 1))))) + (cond + ((string-match "^\\(\\*+\\)[ \t]*\\(.*\\)" line) + ;; This is a headline + (setq level (org-tr-level (- (match-end 1) (match-beginning 1))) + txt (match-string 2 line)) + (if (<= level umax) (setq head-count (+ head-count 1))) + (when in-local-list + ;; Close any local lists before inserting a new header line + (while local-list-num + (insert (if (car local-list-num) "\n" "")) + (pop local-list-num)) + (setq local-list-indent nil + in-local-list nil)) + (org-html-level-start level txt umax + (and org-export-with-toc (<= level umax)) + head-count) + ;; QUOTES + (when (string-match quote-re line) + (insert "
")
+	      (setq inquote t)))
+
+	   ((and org-export-with-tables
+		 (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" line))
+	    (if (not table-open)
+		;; New table starts
+		(setq table-open t table-buffer nil table-orig-buffer nil))
+	    ;; Accumulate lines
+	    (setq table-buffer (cons line table-buffer)
+		  table-orig-buffer (cons origline table-orig-buffer))
+	    (when (or (not lines)
+		      (not (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)"
+					 (car lines))))
+	      (setq table-open nil
+		    table-buffer (nreverse table-buffer)
+		    table-orig-buffer (nreverse table-orig-buffer))
+	      (insert (org-format-table-html table-buffer table-orig-buffer))))
+	   (t
+	    ;; Normal lines
+	    (when (and (> org-export-plain-list-max-depth 0)
+		       (string-match
+			(cond
+			 ((eq llt t) "^\\([ \t]*\\)\\(\\([-+*]\\)\\|\\([0-9]+[.)]\\)\\)?\\( +[^ \t\n\r]\\|[ \t]*$\\)")
+			 ((= llt ?.) "^\\([ \t]*\\)\\(\\([-+*]\\)\\|\\([0-9]+\\.\\)\\)?\\( +[^ \t\n\r]\\|[ \t]*$\\)")
+			 ((= llt ?\)) "^\\( \t]*\\)\\(\\([-+*]\\)\\|\\([0-9]+)\\)\\)?\\( +[^ \t\n\r]\\|[ \t]*$\\)")
+			 (t (error "Invalid value of `org-plain-list-ordered-item-terminator'")))
+			line))
+	      (setq ind (org-get-string-indentation line)
+		    start-is-num (match-beginning 4)
+		    starter (if (match-beginning 2) (match-string 2 line))
+		    line (substring line (match-beginning 5)))
+	      (unless (string-match "[^ \t]" line)
+		;; empty line.  Pretend indentation is large.
+		(setq ind (1+ (or (car local-list-indent) 1))))
+	      (while (and in-local-list
+			  (or (and (= ind (car local-list-indent))
+				   (not starter))
+			      (< ind (car local-list-indent))))
+		(insert (if (car local-list-num) "\n" ""))
+		(pop local-list-num) (pop local-list-indent)
+		(setq in-local-list local-list-indent))
+	      (cond
+	       ((and starter
+		     (or (not in-local-list)
+			 (> ind (car local-list-indent)))
+		     (< (length local-list-indent)
+			org-export-plain-list-max-depth))
+		;; Start new (level of ) list
+		(insert (if start-is-num "
    \n
  1. \n" "
      \n
    • \n")) + (push start-is-num local-list-num) + (push ind local-list-indent) + (setq in-local-list t)) + (starter + ;; continue current list + (insert "
    • \n")))) + ;; Empty lines start a new paragraph. If hand-formatted lists + ;; are not fully interpreted, lines starting with "-", "+", "*" + ;; also start a new paragraph. + (if (string-match "^ [-+*]-\\|^[ \t]*$" line) (insert "

      ")) + (insert line (if org-export-preserve-breaks "
      \n" "\n")))) + )) + (if org-export-html-with-timestamp + (insert org-export-html-html-helper-timestamp)) + (insert "\n\n") + (normal-mode) + (save-buffer) + (goto-char (point-min))))) + +(defun org-format-table-html (lines olines) + "Find out which HTML converter to use and return the HTML code." + (if (string-match "^[ \t]*|" (car lines)) + ;; A normal org table + (org-format-org-table-html lines) + ;; Table made by table.el - test for spanning + (let* ((hlines (delq nil (mapcar + (lambda (x) + (if (string-match "^[ \t]*\\+-" x) x + nil)) + lines))) + (first (car hlines)) + (ll (and (string-match "\\S-+" first) + (match-string 0 first))) + (re (concat "^[ \t]*" (regexp-quote ll))) + (spanning (delq nil (mapcar (lambda (x) (not (string-match re x))) + hlines)))) + (if (and (not spanning) + (not org-export-prefer-native-exporter-for-tables)) + ;; We can use my own converter with HTML conversions + (org-format-table-table-html lines) + ;; Need to use the code generator in table.el, with the original text. + (org-format-table-table-html-using-table-generate-source olines))))) + +(defun org-format-org-table-html (lines) + "Format a table into HTML." + (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines))) + (setq lines (nreverse lines)) + (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines))) + (setq lines (nreverse lines)) + (when org-export-table-remove-special-lines + ;; Check if the table has a marking column. If yes remove the + ;; column and the special lines + (let* ((special + (not + (memq nil + (mapcar + (lambda (x) + (or (string-match "^[ \t]*|-" x) + (string-match "^[ \t]*| *\\([#!$*_^ ]\\) *|" x))) + lines))))) + (if special + (setq lines + (delq nil + (mapcar + (lambda (x) + (if (string-match "^[ \t]*| *[!_^] *|" x) + nil ; ignore this line + (and (or (string-match "^[ \t]*|-+\\+" x) + (string-match "^[ \t]*|[^|]*|" x)) + (replace-match "|" t t x)))) + lines)))))) + + (let ((head (and org-export-highlight-first-table-line + (delq nil (mapcar + (lambda (x) (string-match "^[ \t]*|-" x)) + (cdr lines))))) + line fields html) + (setq html (concat org-export-html-table-tag "\n")) + (while (setq line (pop lines)) + (catch 'next-line + (if (string-match "^[ \t]*|-" line) + (progn + (setq head nil) ;; head ends here, first time around + ;; ignore this line + (throw 'next-line t))) + ;; Break the line into fields + (setq fields (org-split-string line "[ \t]*|[ \t]*")) + (setq html (concat + html + "

" + (mapconcat (lambda (x) + (if head + (concat "") + (concat ""))) + fields "") + "\n")))) + (setq html (concat html "
" x "" x "
\n")) + html)) + +(defun org-fake-empty-table-line (line) + "Replace everything except \"|\" with spaces." + (let ((i (length line)) + (newstr (copy-sequence line))) + (while (> i 0) + (setq i (1- i)) + (if (not (eq (aref newstr i) ?|)) + (aset newstr i ?\ ))) + newstr)) + +(defun org-format-table-table-html (lines) + "Format a table generated by table.el into HTML. +This conversion does *not* use `table-generate-source' from table.el. +This has the advantage that Org-mode's HTML conversions can be used. +But it has the disadvantage, that no cell- or row-spanning is allowed." + (let (line field-buffer + (head org-export-highlight-first-table-line) + fields html empty) + (setq html (concat org-export-html-table-tag "\n")) + (while (setq line (pop lines)) + (setq empty " ") + (catch 'next-line + (if (string-match "^[ \t]*\\+-" line) + (progn + (if field-buffer + (progn + (setq html (concat + html + "" + (mapconcat + (lambda (x) + (if (equal x "") (setq x empty)) + (if head + (concat "" x "\n") + (concat "" x "\n"))) + field-buffer "\n") + "\n")) + (setq head nil) + (setq field-buffer nil))) + ;; Ignore this line + (throw 'next-line t))) + ;; Break the line into fields and store the fields + (setq fields (org-split-string line "[ \t]*|[ \t]*")) + (if field-buffer + (setq field-buffer (mapcar + (lambda (x) + (concat x "
" (pop fields))) + field-buffer)) + (setq field-buffer fields)))) + (setq html (concat html "\n")) + html)) + +(defun org-format-table-table-html-using-table-generate-source (lines) + "Format a table into html, using `table-generate-source' from table.el. +This has the advantage that cell- or row-spanning is allowed. +But it has the disadvantage, that Org-mode's HTML conversions cannot be used." + (require 'table) + (with-current-buffer (get-buffer-create " org-tmp1 ") + (erase-buffer) + (insert (mapconcat 'identity lines "\n")) + (goto-char (point-min)) + (if (not (re-search-forward "|[^+]" nil t)) + (error "Error processing table")) + (table-recognize-table) + (with-current-buffer (get-buffer-create " org-tmp2 ") (erase-buffer)) + (table-generate-source 'html " org-tmp2 ") + (set-buffer " org-tmp2 ") + (buffer-substring (point-min) (point-max)))) + +(defun org-html-protect (s) + ;; convert & to &, < to < and > to > + (let ((start 0)) + (while (string-match "&" s start) + (setq s (replace-match "&" t t s) + start (1+ (match-beginning 0)))) + (while (string-match "<" s) + (setq s (replace-match "<" t t s))) + (while (string-match ">" s) + (setq s (replace-match ">" t t s)))) + s) + +(defun org-html-expand (string) + "Prepare STRING for HTML export. Applies all active conversions." + ;; First check if there is a link in the line - if yes, apply conversions + ;; only before the start of the link. + ;; FIXME: This is no longer correct, because links now have an end. + (let* ((m (string-match org-link-regexp string)) + (s (if m (substring string 0 m) string)) + (r (if m (substring string m) ""))) + ;; convert & to &, < to < and > to > + (setq s (org-html-protect s)) + (if org-export-html-expand + (while (string-match "@<\\([^&]*\\)>" s) + (setq s (replace-match "<\\1>" nil nil s)))) + (if org-export-with-emphasize + (setq s (org-export-html-convert-emphasize s))) + (if org-export-with-sub-superscripts + (setq s (org-export-html-convert-sub-super s))) + (if org-export-with-TeX-macros + (let ((start 0) wd ass) + (while (setq start (string-match "\\\\\\([a-zA-Z]+\\)" s start)) + (setq wd (match-string 1 s)) + (if (setq ass (assoc wd org-html-entities)) + (setq s (replace-match (or (cdr ass) + (concat "&" (car ass) ";")) + t t s)) + (setq start (+ start (length wd))))))) + (concat s r))) + +(defun org-create-multibrace-regexp (left right n) + "Create a regular expression which will match a balanced sexp. +Opening delimiter is LEFT, and closing delimiter is RIGHT, both given +as single character strings. +The regexp returned will match the entire expression including the +delimiters. It will also define a single group which contains the +match except for the outermost delimiters. The maximum depth of +stacked delimiters is N. Escaping delimiters is not possible." + (let* ((nothing (concat "[^" "\\" left "\\" right "]*?")) + (or "\\|") + (re nothing) + (next (concat "\\(?:" nothing left nothing right "\\)+" nothing))) + (while (> n 1) + (setq n (1- n) + re (concat re or next) + next (concat "\\(?:" nothing left next right "\\)+" nothing))) + (concat left "\\(" re "\\)" right))) + +(defvar org-match-substring-regexp + (concat + "\\([^\\]\\)\\([_^]\\)\\(" + "\\(" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)" + "\\|" + "\\(" (org-create-multibrace-regexp "(" ")" org-match-sexp-depth) "\\)" + "\\|" + "\\(\\(?:\\*\\|[-+]?[^-+*!@#$%^_ \t\r\n,:\"?<>~;./{}=()]+\\)\\)\\)") + "The regular expression matching a sub- or superscript.") + +(defun org-export-html-convert-sub-super (string) + "Convert sub- and superscripts in STRING to HTML." + (let (key c) + (while (string-match org-match-substring-regexp string) + (setq key (if (string= (match-string 2 string) "_") "sub" "sup")) + (setq c (or (match-string 8 string) + (match-string 6 string) + (match-string 5 string))) + (setq string (replace-match + (concat (match-string 1 string) + "<" key ">" c "") + t t string))) + (while (string-match "\\\\\\([_^]\\)" string) + (setq string (replace-match (match-string 1 string) t t string)))) + string) + +(defun org-export-html-convert-emphasize (string) + (let (c (s 0)) + (while (string-match "\\(\\W\\|^\\)\\([*/_]\\)\\(\\w+\\)\\2\\(\\W\\|$\\)" string s) + (setq c (cdr (assoc (match-string 2 string) + '(("*" . "b") ("/" . "i") ("_" . "u")))) + s (+ (match-end 0) 3) + string (replace-match + (concat "\\1<" c ">\\3\\4") t nil string))) + string)) + +(defun org-parse-key-lines () + "Find the special key lines with the information for exporters." + (save-excursion + (goto-char 0) + (let ((re (org-make-options-regexp + '("TITLE" "AUTHOR" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE"))) + key) + (while (re-search-forward re nil t) + (setq key (match-string 1)) + (cond ((string-equal key "TITLE") + (setq title (match-string 2))) + ((string-equal key "AUTHOR") + (setq author (match-string 2))) + ((string-equal key "EMAIL") + (setq email (match-string 2))) + ((string-equal key "LANGUAGE") + (setq language (match-string 2))) + ((string-equal key "TEXT") + (setq text (concat text "\n" (match-string 2)))) + ((string-equal key "OPTIONS") + (setq options (match-string 2)))))))) + +(defun org-parse-export-options (s) + "Parse the export options line." + (let ((op '(("H" . org-export-headline-levels) + ("num" . org-export-with-section-numbers) + ("toc" . org-export-with-toc) + ("\\n" . org-export-preserve-breaks) + ("@" . org-export-html-expand) + (":" . org-export-with-fixed-width) + ("|" . org-export-with-tables) + ("^" . org-export-with-sub-superscripts) + ("*" . org-export-with-emphasize) + ("TeX" . org-export-with-TeX-macros))) + o) + (while (setq o (pop op)) + (if (string-match (concat (regexp-quote (car o)) ":\\([^ \t\n\r;,.]*\\)") + s) + (set (make-local-variable (cdr o)) + (car (read-from-string (match-string 1 s)))))))) + +(defun org-html-level-start (level title umax with-toc head-count) + "Insert a new level in HTML export." + (let ((l (1+ (max level umax)))) + (while (<= l org-level-max) + (if (aref levels-open (1- l)) + (progn + (org-html-level-close l) + (aset levels-open (1- l) nil))) + (setq l (1+ l))) + (if (> level umax) + (progn + (if (aref levels-open (1- level)) + (insert "
  • " title "

    \n") + (aset levels-open (1- level) t) + (insert "

    ")) + +;; Variable holding the vector with section numbers +(defvar org-section-numbers (make-vector org-level-max 0)) + +(defun org-init-section-numbers () + "Initialize the vector for the section numbers." + (let* ((level -1) + (numbers (nreverse (org-split-string "" "\\."))) + (depth (1- (length org-section-numbers))) + (i depth) number-string) + (while (>= i 0) + (if (> i level) + (aset org-section-numbers i 0) + (setq number-string (or (car numbers) "0")) + (if (string-match "\\`[A-Z]\\'" number-string) + (aset org-section-numbers i + (- (string-to-char number-string) ?A -1)) + (aset org-section-numbers i (string-to-number number-string))) + (pop numbers)) + (setq i (1- i))))) + +(defun org-section-number (&optional level) + "Return a string with the current section number. +When LEVEL is non-nil, increase section numbers on that level." + (let* ((depth (1- (length org-section-numbers))) idx n (string "")) + (when level + (when (> level -1) + (aset org-section-numbers + level (1+ (aref org-section-numbers level)))) + (setq idx (1+ level)) + (while (<= idx depth) + (if (not (= idx 1)) + (aset org-section-numbers idx 0)) + (setq idx (1+ idx)))) + (setq idx 0) + (while (<= idx depth) + (setq n (aref org-section-numbers idx)) + (setq string (concat string (if (not (string= string "")) "." "") + (int-to-string n))) + (setq idx (1+ idx))) + (save-match-data + (if (string-match "\\`\\([@0]\\.\\)+" string) + (setq string (replace-match "" nil nil string))) + (if (string-match "\\(\\.0\\)+\\'" string) + (setq string (replace-match "" nil nil string)))) + string)) + + +(defun org-export-icalendar-this-file () + "Export current file as an iCalendar file. +The iCalendar file will be located in the same directory as the Org-mode +file, but with extension `.ics'." + (interactive) + (org-export-icalendar nil buffer-file-name)) + +;;;###autoload +(defun org-export-icalendar-all-agenda-files () + "Export all files in `org-agenda-files' to iCalendar .ics files. +Each iCalendar file will be located in the same directory as the Org-mode +file, but with extension `.ics'." + (interactive) + (apply 'org-export-icalendar nil org-agenda-files)) + +;;;###autoload +(defun org-export-icalendar-combine-agenda-files () + "Export all files in `org-agenda-files' to a single combined iCalendar file. +The file is stored under the name `org-combined-agenda-icalendar-file'." + (interactive) + (apply 'org-export-icalendar t org-agenda-files)) + +(defun org-export-icalendar (combine &rest files) + "Create iCalendar files for all elements of FILES. +If COMBINE is non-nil, combine all calendar entries into a single large +file and store it under the name `org-combined-agenda-icalendar-file'." + (save-excursion + (let* (file ical-file ical-buffer category started org-agenda-new-buffers) + (when combine + (setq ical-file org-combined-agenda-icalendar-file + ical-buffer (org-get-agenda-file-buffer ical-file)) + (set-buffer ical-buffer) (erase-buffer)) + (while (setq file (pop files)) + (catch 'nextfile + (org-check-agenda-file file) + (unless combine + (setq ical-file (concat (file-name-sans-extension file) ".ics")) + (setq ical-buffer (org-get-agenda-file-buffer ical-file)) + (set-buffer ical-buffer) (erase-buffer)) + (set-buffer (org-get-agenda-file-buffer file)) + (setq category (or org-category + (file-name-sans-extension + (file-name-nondirectory buffer-file-name)))) + (if (symbolp category) (setq category (symbol-name category))) + (let ((standard-output ical-buffer)) + (if combine + (and (not started) (setq started t) + (org-start-icalendar-file org-icalendar-combined-name)) + (org-start-icalendar-file category)) + (org-print-icalendar-entries combine category) + (when (or (and combine (not files)) (not combine)) + (org-finish-icalendar-file) + (set-buffer ical-buffer) + (save-buffer) + (run-hooks 'org-after-save-iCalendar-file-hook))))) + (org-release-buffers org-agenda-new-buffers)))) + +(defvar org-after-save-iCalendar-file-hook nil + "Hook run after an iCalendar file has been saved. +The iCalendar buffer is still current when this hook is run. +A good way to use this is to tell a desktop calenndar application to re-read +the iCalendar file.") + +(defun org-print-icalendar-entries (&optional combine category) + "Print iCalendar entries for the current Org-mode file to `standard-output'. +When COMBINE is non nil, add the category to each line." + (let ((re2 (concat "--?-?\\(" org-ts-regexp "\\)")) + (dts (org-ical-ts-to-string + (format-time-string (cdr org-time-stamp-formats) (current-time)) + "DTSTART")) + hd ts ts2 state (inc t) pos scheduledp deadlinep tmp pri) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward org-ts-regexp nil t) + (setq pos (match-beginning 0) + ts (match-string 0) + inc t + hd (org-get-heading)) + (if (looking-at re2) + (progn + (goto-char (match-end 0)) + (setq ts2 (match-string 1) inc nil)) + (setq ts2 ts + tmp (buffer-substring (max (point-min) + (- pos org-ds-keyword-length)) + pos) + deadlinep (string-match org-deadline-regexp tmp) + scheduledp (string-match org-scheduled-regexp tmp) + ;; donep (org-entry-is-done-p) + )) + (if (or (string-match org-tr-regexp hd) + (string-match org-ts-regexp hd)) + (setq hd (replace-match "" t t hd))) + (if combine + (setq hd (concat hd " (category " category ")"))) + (if deadlinep (setq hd (concat "DL: " hd " This is a deadline"))) + (if scheduledp (setq hd (concat "S: " hd " Scheduled for this date"))) + (princ (format "BEGIN:VEVENT +%s +%s +SUMMARY:%s +END:VEVENT\n" + (org-ical-ts-to-string ts "DTSTART") + (org-ical-ts-to-string ts2 "DTEND" inc) + hd))) + (when org-icalendar-include-todo + (goto-char (point-min)) + (while (re-search-forward org-todo-line-regexp nil t) + (setq state (match-string 1)) + (unless (equal state org-done-string) + (setq hd (match-string 3)) + (if (string-match org-priority-regexp hd) + (setq pri (string-to-char (match-string 2 hd)) + hd (concat (substring hd 0 (match-beginning 1)) + (substring hd (- (match-end 1))))) + (setq pri org-default-priority)) + (setq pri (floor (1+ (* 8. (/ (float (- org-lowest-priority pri)) + (- org-lowest-priority ?A)))))) + + (princ (format "BEGIN:VTODO +%s +SUMMARY:%s +SEQUENCE:1 +PRIORITY:%d +END:VTODO\n" + dts hd pri)))))))) + +(defun org-start-icalendar-file (name) + "Start an iCalendar file by inserting the header." + (let ((user user-full-name) + (name (or name "unknown")) + (timezone (cadr (current-time-zone)))) + (princ + (format "BEGIN:VCALENDAR +VERSION:2.0 +X-WR-CALNAME:%s +PRODID:-//%s//Emacs with Org-mode//EN +X-WR-TIMEZONE:%s +CALSCALE:GREGORIAN\n" name user timezone)))) + +(defun org-finish-icalendar-file () + "Finish an iCalendar file by inserting the END statement." + (princ "END:VCALENDAR\n")) + +(defun org-ical-ts-to-string (s keyword &optional inc) + "Take a time string S and convert it to iCalendar format. +KEYWORD is added in front, to make a complete line like DTSTART.... +When INC is non-nil, increase the hour by two (if time string contains +a time), or the day by one (if it does not contain a time)." + (let ((t1 (org-parse-time-string s 'nodefault)) + t2 fmt have-time time) + (if (and (car t1) (nth 1 t1) (nth 2 t1)) + (setq t2 t1 have-time t) + (setq t2 (org-parse-time-string s))) + (let ((s (car t2)) (mi (nth 1 t2)) (h (nth 2 t2)) + (d (nth 3 t2)) (m (nth 4 t2)) (y (nth 5 t2))) + (when inc + (if have-time (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)))) + + +;;; Key bindings + +;; - Bindings in Org-mode map are currently +;; 0123456789abcdefghijklmnopqrstuvwxyz!?@#$%^&-+*/=()_{}[]:;"|,.<>~`'\t the alphabet +;; abcd fgh j lmnopqrstuvwxyz!? #$ ^ -+*/= [] ; |,.<>~ '\t necessary bindings +;; e (?) useful from outline-mode +;; i k @ expendable from outline-mode +;; 0123456789 % & ()_{} " ` free + +;; Make `C-c C-x' a prefix key +(define-key org-mode-map "\C-c\C-x" (make-sparse-keymap)) + +;; TAB key with modifiers +(define-key org-mode-map "\C-i" 'org-cycle) +(define-key org-mode-map [(tab)] 'org-cycle) +(define-key org-mode-map [(meta tab)] 'org-complete) +(define-key org-mode-map "\M-\C-i" 'org-complete) ; for tty emacs +;; The following line is necessary under Suse GNU/Linux +(unless org-xemacs-p + (define-key org-mode-map [S-iso-lefttab] 'org-shifttab)) +(define-key org-mode-map [(shift tab)] 'org-shifttab) + +(define-key org-mode-map (org-key 'S-return) 'org-table-copy-down) +(define-key org-mode-map "\C-c\C-xc" 'org-table-copy-down) ; tty +(define-key org-mode-map [(meta shift return)] 'org-insert-todo-heading) +(define-key org-mode-map "\C-c\C-xM" 'org-insert-todo-heading) ; tty +(define-key org-mode-map [(meta return)] 'org-meta-return) +(define-key org-mode-map "\C-c\C-xm" 'org-meta-return) ; tty emacs +(define-key org-mode-map [?\e (return)] 'org-meta-return) ; tty emacs + +;; Cursor keys with modifiers +(define-key org-mode-map [(meta left)] 'org-metaleft) +(define-key org-mode-map [?\e (left)] 'org-metaleft) ; for tty emacs +(define-key org-mode-map "\C-c\C-xl" 'org-metaleft) ; for tty emacs +(define-key org-mode-map [(meta right)] 'org-metaright) +(define-key org-mode-map [?\e (right)] 'org-metaright) ; for tty emacs +(define-key org-mode-map "\C-c\C-xr" 'org-metaright) ; for tty emacs +(define-key org-mode-map [(meta up)] 'org-metaup) +(define-key org-mode-map [?\e (up)] 'org-metaup) ; for tty emacs +(define-key org-mode-map "\C-c\C-xu" 'org-metaup) ; for tty emacs +(define-key org-mode-map [(meta down)] 'org-metadown) +(define-key org-mode-map [?\e (down)] 'org-metadown) ; for tty emacs +(define-key org-mode-map "\C-c\C-xd" 'org-metadown) ; for tty emacs + +(define-key org-mode-map [(meta shift left)] 'org-shiftmetaleft) +(define-key org-mode-map "\C-c\C-xL" 'org-shiftmetaleft) ; tty +(define-key org-mode-map [(meta shift right)] 'org-shiftmetaright) +(define-key org-mode-map "\C-c\C-xR" 'org-shiftmetaright) ; tty +(define-key org-mode-map [(meta shift up)] 'org-shiftmetaup) +(define-key org-mode-map "\C-c\C-xU" 'org-shiftmetaup) ; tty +(define-key org-mode-map [(meta shift down)] 'org-shiftmetadown) +(define-key org-mode-map "\C-c\C-xD" 'org-shiftmetadown) ; tty +(define-key org-mode-map (org-key 'S-up) 'org-shiftup) +(define-key org-mode-map [?\C-c ?\C-x (up)] 'org-shiftup) +(define-key org-mode-map (org-key 'S-down) 'org-shiftdown) +(define-key org-mode-map [?\C-c ?\C-x (down)] 'org-shiftdown) +(define-key org-mode-map (org-key 'S-left) 'org-shiftleft) +(define-key org-mode-map [?\C-c ?\C-x (left)] 'org-shiftleft) +(define-key org-mode-map (org-key 'S-right) 'org-shiftright) +(define-key org-mode-map [?\C-c ?\C-x (right)] 'org-shiftright) + +;; All the other keys +(define-key org-mode-map "\C-c$" 'org-archive-subtree) +(define-key org-mode-map "\C-c\C-j" 'org-goto) +(define-key org-mode-map "\C-c\C-t" 'org-todo) +(define-key org-mode-map "\C-c\C-s" 'org-schedule) +(define-key org-mode-map "\C-c\C-d" 'org-deadline) +(define-key org-mode-map "\C-c;" 'org-toggle-comment) +(define-key org-mode-map "\C-c\C-v" 'org-show-todo-tree) +(define-key org-mode-map "\C-c\C-w" 'org-check-deadlines) +(define-key org-mode-map "\C-c/" 'org-occur) ; Minor-mode reserved +(define-key org-mode-map "\C-c\\" 'org-tags-sparse-tree) ; Minor-mode res. +(define-key org-mode-map "\C-c\C-m" 'org-insert-heading) +(define-key org-mode-map "\M-\C-m" 'org-insert-heading) +(define-key org-mode-map "\C-c\C-l" 'org-insert-link) +(define-key org-mode-map "\C-c\C-o" 'org-open-at-point) +(define-key org-mode-map "\C-c%" 'org-mark-ring-push) +(define-key org-mode-map "\C-c&" 'org-mark-ring-goto) +(define-key org-mode-map "\C-c\C-z" 'org-time-stamp) ; Alternative binding +(define-key org-mode-map "\C-c." 'org-time-stamp) ; Minor-mode reserved +(define-key org-mode-map "\C-c!" 'org-time-stamp-inactive) ; Minor-mode r. +(define-key org-mode-map "\C-c," 'org-priority) ; Minor-mode reserved +(define-key org-mode-map "\C-c\C-y" 'org-evaluate-time-range) +(define-key org-mode-map "\C-c>" 'org-goto-calendar) +(define-key org-mode-map "\C-c<" 'org-date-from-calendar) +(define-key org-mode-map [(control ?,)] 'org-cycle-agenda-files) +(define-key org-mode-map "\C-c[" 'org-agenda-file-to-front) +(define-key org-mode-map "\C-c]" 'org-remove-file) +(define-key org-mode-map "\C-c\C-r" 'org-timeline) +(define-key org-mode-map "\C-c-" 'org-table-insert-hline) +(define-key org-mode-map "\C-c^" 'org-table-sort-lines) +(define-key org-mode-map "\C-c\C-c" 'org-ctrl-c-ctrl-c) +(define-key org-mode-map "\C-m" 'org-return) +(define-key org-mode-map "\C-c?" 'org-table-current-column) +(define-key org-mode-map "\C-c " 'org-table-blank-field) +(define-key org-mode-map "\C-c+" 'org-table-sum) +(define-key org-mode-map "\C-c|" 'org-table-toggle-vline-visibility) +(define-key org-mode-map "\C-c=" 'org-table-eval-formula) +(define-key org-mode-map "\C-c'" 'org-table-edit-formulas) +(define-key org-mode-map "\C-c*" 'org-table-recalculate) +(define-key org-mode-map [(control ?#)] 'org-table-rotate-recalc-marks) +(define-key org-mode-map "\C-c~" 'org-table-create-with-table.el) +(define-key org-mode-map "\C-c\C-q" 'org-table-wrap-region) +(define-key org-mode-map "\C-c\C-xa" 'org-export-as-ascii) +(define-key org-mode-map "\C-c\C-x\C-a" 'org-export-as-ascii) +(define-key org-mode-map "\C-c\C-xv" 'org-export-copy-visible) +(define-key org-mode-map "\C-c\C-x\C-v" 'org-export-copy-visible) +;; OPML support is only an option for the future +;(define-key org-mode-map "\C-c\C-xo" 'org-export-as-opml) +;(define-key org-mode-map "\C-c\C-x\C-o" 'org-export-as-opml) +(define-key org-mode-map "\C-c\C-xi" 'org-export-icalendar-this-file) +(define-key org-mode-map "\C-c\C-x\C-i" 'org-export-icalendar-all-agenda-files) +(define-key org-mode-map "\C-c\C-xc" 'org-export-icalendar-combine-agenda-files) +(define-key org-mode-map "\C-c\C-x\C-c" 'org-export-icalendar-combine-agenda-files) +(define-key org-mode-map "\C-c\C-xt" 'org-insert-export-options-template) +(define-key org-mode-map "\C-c:" 'org-toggle-fixed-width-section) +(define-key org-mode-map "\C-c\C-xh" 'org-export-as-html) +(define-key org-mode-map "\C-c\C-xb" 'org-export-as-html-and-open) +(define-key org-mode-map "\C-c\C-x\C-b" 'org-export-as-html-and-open) + +(define-key org-mode-map "\C-c\C-x\C-k" 'org-cut-special) +(define-key org-mode-map "\C-c\C-x\C-w" 'org-cut-special) +(define-key org-mode-map "\C-c\C-x\M-w" 'org-copy-special) +(define-key org-mode-map "\C-c\C-x\C-y" 'org-paste-special) + +(defsubst org-table-p () (org-at-table-p)) + +(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 +overwritten, and the table is not marked as requiring realignment." + (interactive "p") + (if (and (org-table-p) + (or + (and org-table-auto-blank-field + (member last-command + '(org-cycle org-return org-shifttab org-ctrl-c-ctrl-c)) + (org-table-blank-field)) + t) + (eq N 1) + (looking-at "[^|\n]* +|")) + (let (org-table-may-need-update) + (goto-char (1- (match-end 0))) + (delete-backward-char 1) + (goto-char (match-beginning 0)) + (self-insert-command N)) + (setq org-table-may-need-update t) + (self-insert-command N))) + +;; FIXME: +;; The following two functions might still be optimized to trigger +;; re-alignment less frequently. + +(defun org-delete-backward-char (N) + "Like `delete-backward-char', insert whitespace at field end in tables. +When deleting backwards, in tables this function will insert whitespace in +front of the next \"|\" separator, to keep the table aligned. The table will +still be marked for re-alignment, because a narrow field may lead to a +reduced column width." + (interactive "p") + (if (and (org-table-p) + (eq N 1) + (string-match "|" (buffer-substring (point-at-bol) (point))) + (looking-at ".*?|")) + (let ((pos (point))) + (backward-delete-char N) + (skip-chars-forward "^|") + (insert " ") + (goto-char (1- pos))) + (backward-delete-char N))) + +(defun org-delete-char (N) + "Like `delete-char', but insert whitespace at field end in tables. +When deleting characters, in tables this function will insert whitespace in +front of the next \"|\" separator, to keep the table aligned. The table +will still be marked for re-alignment, because a narrow field may lead to +a reduced column width." + (interactive "p") + (if (and (org-table-p) + (not (bolp)) + (not (= (char-after) ?|)) + (eq N 1)) + (if (looking-at ".*?|") + (let ((pos (point))) + (replace-match (concat + (substring (match-string 0) 1 -1) + " |")) + (goto-char pos))) + (delete-char N))) + +;; How to do this: Measure non-white length of current string +;; If equal to column width, we should realign. + +(defun org-remap (map &rest commands) + "In MAP, remap the functions given in COMMANDS. +COMMANDS is a list of alternating OLDDEF NEWDEF command names." + (let (new old) + (while commands + (setq old (pop commands) new (pop commands)) + (if (fboundp 'command-remapping) + (define-key map (vector 'remap old) new) + (substitute-key-definition old new map global-map))))) + +(when (eq org-enable-table-editor 'optimized) + ;; If the user wants maximum table support, we need to hijack + ;; some standard editing functions + (org-remap org-mode-map + 'self-insert-command 'org-self-insert-command + 'delete-char 'org-delete-char + 'delete-backward-char 'org-delete-backward-char) + (define-key org-mode-map "|" 'org-force-self-insert)) + +(defun org-shiftcursor-error () + "Throw an error because Shift-Cursor command was applied in wrong context." + (error "This command is active in special context like tables, headlines or timestamps")) + +(defun org-shifttab () + "Global visibility cycling or move to previous table field. +Calls `(org-cycle t)' or `org-table-previous-field', depending on context. +See the individual commands for more information." + (interactive) + (cond + ((org-at-table-p) (org-table-previous-field)) + (t (org-cycle '(4))))) + +(defun org-shiftmetaleft () + "Promote subtree or delete table column. +Calls `org-promote-subtree' or `org-table-delete-column', depending on context. +See the individual commands for more information." + (interactive) + (cond + ((org-at-table-p) (org-table-delete-column)) + ((org-on-heading-p) (org-promote-subtree)) + ((org-at-item-p) (call-interactively 'org-outdent-item)) + (t (org-shiftcursor-error)))) + +(defun org-shiftmetaright () + "Demote subtree or insert table column. +Calls `org-demote-subtree' or `org-table-insert-column', depending on context. +See the individual commands for more information." + (interactive) + (cond + ((org-at-table-p) (org-table-insert-column)) + ((org-on-heading-p) (org-demote-subtree)) + ((org-at-item-p) (call-interactively 'org-indent-item)) + (t (org-shiftcursor-error)))) + +(defun org-shiftmetaup (&optional arg) + "Move subtree up or kill table row. +Calls `org-move-subtree-up' or `org-table-kill-row' or +`org-move-item-up' depending on context. See the individual commands +for more information." + (interactive "P") + (cond + ((org-at-table-p) (org-table-kill-row)) + ((org-on-heading-p) (org-move-subtree-up arg)) + ((org-at-item-p) (org-move-item-up arg)) + (t (org-shiftcursor-error)))) +(defun org-shiftmetadown (&optional arg) + "Move subtree down or insert table row. +Calls `org-move-subtree-down' or `org-table-insert-row' or +`org-move-item-down', depending on context. See the individual +commands for more information." + (interactive "P") + (cond + ((org-at-table-p) (org-table-insert-row arg)) + ((org-on-heading-p) (org-move-subtree-down arg)) + ((org-at-item-p) (org-move-item-down arg)) + (t (org-shiftcursor-error)))) + +(defun org-metaleft (&optional arg) + "Promote heading or move table column to left. +Calls `org-do-promote' or `org-table-move-column', depending on context. +With no specific context, calls the Emacs default `backward-word'. +See the individual commands for more information." + (interactive "P") + (cond + ((org-at-table-p) (org-table-move-column 'left)) + ((or (org-on-heading-p) (org-region-active-p)) (org-do-promote)) + (t (backward-word (prefix-numeric-value arg))))) + +(defun org-metaright (&optional arg) + "Demote subtree or move table column to right. +Calls `org-do-demote' or `org-table-move-column', depending on context. +With no specific context, calls the Emacs default `forward-word'. +See the individual commands for more information." + (interactive "P") + (cond + ((org-at-table-p) (org-table-move-column nil)) + ((or (org-on-heading-p) (org-region-active-p)) (org-do-demote)) + (t (forward-word (prefix-numeric-value arg))))) + +(defun org-metaup (&optional arg) + "Move subtree up or move table row up. +Calls `org-move-subtree-up' or `org-table-move-row' or +`org-move-item-up', depending on context. See the individual commands +for more information." + (interactive "P") + (cond + ((org-at-table-p) (org-table-move-row 'up)) + ((org-on-heading-p) (org-move-subtree-up arg)) + ((org-at-item-p) (org-move-item-up arg)) + (t (org-shiftcursor-error)))) + +(defun org-metadown (&optional arg) + "Move subtree down or move table row down. +Calls `org-move-subtree-down' or `org-table-move-row' or +`org-move-item-down', depending on context. See the individual +commands for more information." + (interactive "P") + (cond + ((org-at-table-p) (org-table-move-row nil)) + ((org-on-heading-p) (org-move-subtree-down arg)) + ((org-at-item-p) (org-move-item-down arg)) + (t (org-shiftcursor-error)))) + +(defun org-shiftup (&optional arg) + "Increase item in timestamp or increase priority of current item. +Calls `org-timestamp-up' or `org-priority-up', depending on context. +See the individual commands for more information." + (interactive "P") + (cond + ((org-at-timestamp-p) (org-timestamp-up arg)) + (t (org-priority-up)))) + +(defun org-shiftdown (&optional arg) + "Decrease item in timestamp or decrease priority of current item. +Calls `org-timestamp-down' or `org-priority-down', depending on context. +See the individual commands for more information." + (interactive "P") + (cond + ((org-at-timestamp-p) (org-timestamp-down arg)) + (t (org-priority-down)))) + +(defun org-shiftright () + "Next TODO keyword or timestamp one day later, depending on context." + (interactive) + (cond + ((org-at-timestamp-p) (org-timestamp-up-day)) + ((org-on-heading-p) (org-todo 'right)) + (t (org-shiftcursor-error)))) + +(defun org-shiftleft () + "Previous TODO keyword or timestamp one day earlier, depending on context." + (interactive) + (cond + ((org-at-timestamp-p) (org-timestamp-down-day)) + ((org-on-heading-p) (org-todo 'left)) + (t (org-shiftcursor-error)))) + +(defun org-copy-special () + "Copy region in table or copy current subtree. +Calls `org-table-copy' or `org-copy-subtree', depending on context. +See the individual commands for more information." + (interactive) + (call-interactively + (if (org-at-table-p) 'org-table-copy-region 'org-copy-subtree))) + +(defun org-cut-special () + "Cut region in table or cut current subtree. +Calls `org-table-copy' or `org-cut-subtree', depending on context. +See the individual commands for more information." + (interactive) + (call-interactively + (if (org-at-table-p) 'org-table-cut-region 'org-cut-subtree))) + +(defun org-paste-special (arg) + "Paste rectangular region into table, or past subtree relative to level. +Calls `org-table-paste-rectangle' or `org-paste-subtree', depending on context. +See the individual commands for more information." + (interactive "P") + (if (org-at-table-p) + (org-table-paste-rectangle) + (org-paste-subtree arg))) + +(defun org-ctrl-c-ctrl-c (&optional arg) + "Call realign table, or recognize a table.el table, or update keywords. +When the cursor is inside a table created by the table.el package, +activate that table. Otherwise, if the cursor is at a normal table +created with org.el, re-align that table. This command works even if +the automatic table editor has been turned off. + +If the cursor is in a headline, prompt for tags and insert them into +the current line, aligned to `org-tags-column'. When in a headline and +called with prefix arg, realign all tags in the current buffer. + +If the cursor is in one of the special #+KEYWORD lines, this triggers +scanning the buffer for these lines and updating the information. +If the cursor is on a #+TBLFM line, re-apply the formulae to the table." + (interactive "P") + (let ((org-enable-table-editor t)) + (cond + ((and (boundp 'remember-buffer) (equal (buffer-name) remember-buffer)) + (remember-buffer)) + ((org-on-target-p) (org-update-radio-target-regexp)) + ((org-on-heading-p) (org-set-tags arg)) + ((org-at-table.el-p) + (require 'table) + (beginning-of-line 1) + (re-search-forward "|" (save-excursion (end-of-line 2) (point))) + (table-recognize-table)) + ((org-at-table-p) + (org-table-maybe-eval-formula) + (if arg + (org-table-recalculate t) + (org-table-maybe-recalculate-line)) + (org-table-align)) + ((org-at-item-p) + (org-renumber-ordered-list (prefix-numeric-value arg))) + ((save-excursion (beginning-of-line 1) (looking-at "#\\+\\([A-Z]+\\)")) + (cond + ((equal (match-string 1) "TBLFM") + ;; Recalculate the table before this line + (save-excursion + (beginning-of-line 1) + (skip-chars-backward " \r\n\t") + (if (org-at-table-p) (org-table-recalculate t)))) + (t + (org-mode-restart)))) + ((org-region-active-p) + (org-table-convert-region (region-beginning) (region-end) arg)) + ((condition-case nil + (and (region-beginning) (region-end)) + (error nil)) + (if (y-or-n-p "Convert inactive region to table? ") + (org-table-convert-region (region-beginning) (region-end) arg) + (error "Abort"))) + (t (error "C-c C-c can do nothing useful at this location."))))) + +(defun org-mode-restart () + "Restart Org-mode, to scan again for special lines. +Also updates the keyword regular expressions." + (interactive) + (let ((org-inhibit-startup t)) (org-mode)) + (message "Org-mode restarted to refresh keyword and special line setup")) + +(defun org-return () + "Goto next table row or insert a newline. +Calls `org-table-next-row' or `newline', depending on context. +See the individual commands for more information." + (interactive) + (cond + ((org-at-table-p) + (org-table-justify-field-maybe) + (org-table-next-row)) + (t (newline)))) + +(defun org-meta-return (&optional arg) + "Insert a new heading or wrap a region in a table. +Calls `org-insert-heading' or `org-table-wrap-region', depending on context. +See the individual commands for more information." + (interactive "P") + (cond + ((org-at-table-p) + (org-table-wrap-region arg)) + (t (org-insert-heading arg)))) + +;;; Menu entries + +;; Define the Org-mode menus +(easy-menu-define org-tbl-menu org-mode-map "Tbl menu" + '("Tbl" + ["Align" org-ctrl-c-ctrl-c (org-at-table-p)] + ["Next Field" org-cycle (org-at-table-p)] + ["Previous Field" org-shifttab (org-at-table-p)] + ["Next Row" org-return (org-at-table-p)] + "--" + ["Blank Field" org-table-blank-field (org-at-table-p)] + ["Copy Field from Above" org-table-copy-down (org-at-table-p)] + "--" + ("Column" + ["Move Column Left" org-metaleft (org-at-table-p)] + ["Move Column Right" org-metaright (org-at-table-p)] + ["Delete Column" org-shiftmetaleft (org-at-table-p)] + ["Insert Column" org-shiftmetaright (org-at-table-p)]) + ("Row" + ["Move Row Up" org-metaup (org-at-table-p)] + ["Move Row Down" org-metadown (org-at-table-p)] + ["Delete Row" org-shiftmetaup (org-at-table-p)] + ["Insert Row" org-shiftmetadown (org-at-table-p)] + ["Sort lines in region" org-table-sort-lines (org-at-table-p)] + "--" + ["Insert Hline" org-table-insert-hline (org-at-table-p)]) + ("Rectangle" + ["Copy Rectangle" org-copy-special (org-at-table-p)] + ["Cut Rectangle" org-cut-special (org-at-table-p)] + ["Paste Rectangle" org-paste-special (org-at-table-p)] + ["Fill Rectangle" org-table-wrap-region (org-at-table-p)]) + "--" + ("Calculate" + ["Set Column Formula" org-table-eval-formula (org-at-table-p)] + ["Set Named Field Formula" (org-table-eval-formula '(4)) :active (org-at-table-p) :keys "C-u C-c ="] + ["Edit Formulas" org-table-edit-formulas (org-at-table-p)] + "--" + ["Recalculate line" org-table-recalculate (org-at-table-p)] + ["Recalculate all" (lambda () (interactive) (org-table-recalculate '(4))) :active (org-at-table-p) :keys "C-u C-c *"] + ["Toggle Recalculate Mark" org-table-rotate-recalc-marks (org-at-table-p)] + "--" + ["Sum Column/Rectangle" org-table-sum + (or (org-at-table-p) (org-region-active-p))] + ["Which Column?" org-table-current-column (org-at-table-p)]) + ["Debug Formulas" + (setq org-table-formula-debug (not org-table-formula-debug)) + :style toggle :selected org-table-formula-debug] + "--" + ["Invisible Vlines" org-table-toggle-vline-visibility + :style toggle :selected (org-in-invisibility-spec-p '(org-table))] + "--" + ["Create" org-table-create (and (not (org-at-table-p)) + org-enable-table-editor)] + ["Convert Region" org-ctrl-c-ctrl-c (not (org-at-table-p 'any))] + ["Import from File" org-table-import (not (org-at-table-p))] + ["Export to File" org-table-export (org-at-table-p)] + "--" + ["Create/Convert from/to table.el" org-table-create-with-table.el t])) + +(easy-menu-define org-org-menu org-mode-map "Org menu" + '("Org" + ["Cycle Visibility" org-cycle (or (bobp) (outline-on-heading-p))] + ["Cycle Global Visibility" org-shifttab (not (org-at-table-p))] + ["Sparse Tree" org-occur t] + ["Show All" show-all t] + "--" + ["New Heading" org-insert-heading t] + ("Navigate Headings" + ["Up" outline-up-heading t] + ["Next" outline-next-visible-heading t] + ["Previous" outline-previous-visible-heading t] + ["Next Same Level" outline-forward-same-level t] + ["Previous Same Level" outline-backward-same-level t] + "--" + ["Jump" org-goto t]) + ("Edit Structure" + ["Move Subtree Up" org-shiftmetaup (not (org-at-table-p))] + ["Move Subtree Down" org-shiftmetadown (not (org-at-table-p))] + "--" + ["Copy Subtree" org-copy-special (not (org-at-table-p))] + ["Cut Subtree" org-cut-special (not (org-at-table-p))] + ["Paste Subtree" org-paste-special (not (org-at-table-p))] + "--" + ["Promote Heading" org-metaleft (not (org-at-table-p))] + ["Promote Subtree" org-shiftmetaleft (not (org-at-table-p))] + ["Demote Heading" org-metaright (not (org-at-table-p))] + ["Demote Subtree" org-shiftmetaright (not (org-at-table-p))] + "--" + ["Archive Subtree" org-archive-subtree t] + "--" + ["Convert to odd levels" org-convert-to-odd-levels t] + ["Convert to odd/even levels" org-convert-to-oddeven-levels t]) + "--" + ("TODO Lists" + ["TODO/DONE/-" org-todo t] + ["Show TODO Tree" org-show-todo-tree t] + ["Global TODO list" org-todo-list t] + "--" + ["Set Priority" org-priority t] + ["Priority Up" org-shiftup t] + ["Priority Down" org-shiftdown t]) + ("Dates and Scheduling" + ["Timestamp" org-time-stamp t] + ["Timestamp (inactive)" org-time-stamp-inactive t] + ("Change Date" + ["1 Day Later" org-timestamp-up-day t] + ["1 Day Earlier" org-timestamp-down-day t] + ["1 ... Later" org-shiftup t] + ["1 ... Earlier" org-shiftdown t]) + ["Compute Time Range" org-evaluate-time-range t] + ["Schedule Item" org-schedule t] + ["Deadline" org-deadline t] + "--" + ["Goto Calendar" org-goto-calendar t] + ["Date from Calendar" org-date-from-calendar t]) + "--" + ["Agenda Command" org-agenda t] + ("File List for Agenda") + ("Special views current file" + ["TODO Tree" org-show-todo-tree t] + ["Check Deadlines" org-check-deadlines t] + ["Timeline" org-timeline t] + ["Tags Tree" org-tags-sparse-tree t]) + "--" + ("Hyperlinks" + ["Store Link (Global)" org-store-link t] + ["Insert Link" org-insert-link t] + ["Follow Link" org-open-at-point t]) + "--" + ("Export" + ["ASCII" org-export-as-ascii t] + ["Extract Visible Text" org-export-copy-visible t] + ["HTML" org-export-as-html t] + ["HTML and Open" org-export-as-html-and-open t] +; ["OPML" org-export-as-opml nil] + "--" + ["iCalendar this file" org-export-icalendar-this-file t] + ["iCalendar all agenda files" org-export-icalendar-all-agenda-files + :active t :keys "C-c C-x C-i"] + ["iCalendar combined" org-export-icalendar-combine-agenda-files t] + "--" + ["Option Template" org-insert-export-options-template t] + ["Toggle Fixed Width" org-toggle-fixed-width-section t]) + "--" + ("Documentation" + ["Show Version" org-version t] + ["Info Documentation" org-info t]) + ("Customize" + ["Browse Org Group" org-customize t] + "--" + ["Build Full Customize Menu" org-create-customize-menu + (fboundp 'customize-menu-create)]) + "--" + ["Refresh setup" org-mode-restart t] + )) + +(defun org-info (&optional node) + "Read documentation for Org-mode in the info system. +With optional NODE, go directly to that node." + (interactive) + (require 'info) + (Info-goto-node (format "(org)%s" (or node "")))) + +(defun org-install-agenda-files-menu () + (easy-menu-change + '("Org") "File List for Agenda" + (append + (list + ["Edit File List" (customize-variable 'org-agenda-files) t] + ["Add/Move Current File to Front of List" org-agenda-file-to-front t] + ["Remove Current File from List" org-remove-file t] + ["Cycle through agenda files" org-cycle-agenda-files t] + "--") + (mapcar 'org-file-menu-entry org-agenda-files)))) + +;;; Documentation + +(defun org-customize () + "Call the customize function with org as argument." + (interactive) + (customize-browse 'org)) + +(defun org-create-customize-menu () + "Create a full customization menu for Org-mode, insert it into the menu." + (interactive) + (if (fboundp 'customize-menu-create) + (progn + (easy-menu-change + '("Org") "Customize" + `(["Browse Org group" org-customize t] + "--" + ,(customize-menu-create 'org) + ["Set" Custom-set t] + ["Save" Custom-save t] + ["Reset to Current" Custom-reset-current t] + ["Reset to Saved" Custom-reset-saved t] + ["Reset to Standard Settings" Custom-reset-standard t])) + (message "\"Org\"-menu now contains full customization menu")) + (error "Cannot expand menu (outdated version of cus-edit.el)"))) + +;;; Miscellaneous stuff + +(defun org-move-line-down (arg) + "Move the current line down. With prefix argument, move it past ARG lines." + (interactive "p") + (let ((col (current-column)) + beg end pos) + (beginning-of-line 1) (setq beg (point)) + (beginning-of-line 2) (setq end (point)) + (beginning-of-line (+ 1 arg)) + (setq pos (move-marker (make-marker) (point))) + (insert (delete-and-extract-region beg end)) + (goto-char pos) + (move-to-column col))) + +(defun org-move-line-up (arg) + "Move the current line up. With prefix argument, move it past ARG lines." + (interactive "p") + (let ((col (current-column)) + beg end pos) + (beginning-of-line 1) (setq beg (point)) + (beginning-of-line 2) (setq end (point)) + (beginning-of-line (- arg)) + (setq pos (move-marker (make-marker) (point))) + (insert (delete-and-extract-region beg end)) + (goto-char pos) + (move-to-column col))) + +;; Paragraph filling stuff. +;; We want this to be just right, so use the full arsenal. +;; FIXME: This very likely does not work correctly for XEmacs, because the +;; filladapt package works slightly differently. + +(defun org-set-autofill-regexps () + (interactive) + ;; In the paragraph separator we include headlines, because filling + ;; text in a line directly attached to a headline would otherwise + ;; fill the headline as well. + (set (make-local-variable 'paragraph-separate) "\f\\|\\*\\|[ ]*$\\|[ \t]*[:|]") + ;; The paragraph starter includes hand-formatted lists. + (set (make-local-variable 'paragraph-start) + "\f\\|[ ]*$\\|\\([*\f]+\\)\\|[ \t]*\\([-+*]\\|[0-9]+[.)][ \t]+\\)\\|[ \t]*[:|]") + ;; Inhibit auto-fill for headers, tables and fixed-width lines. + ;; But only if the user has not turned off tables or fixed-width regions + (set (make-local-variable 'auto-fill-inhibit-regexp) + (concat "\\*\\|#" + (if (or org-enable-table-editor org-enable-fixed-width-editor) + (concat + "\\|[ \t]*[" + (if org-enable-table-editor "|" "") + (if org-enable-fixed-width-editor ":" "") + "]")))) + ;; We use our own fill-paragraph function, to make sure that tables + ;; and fixed-width regions are not wrapped. That function will pass + ;; through to `fill-paragraph' when appropriate. + (set (make-local-variable 'fill-paragraph-function) 'org-fill-paragraph) + ;; Adaptive filling: To get full control, first make sure that + ;; `adaptive-fill-regexp' never matches. Then install our won matcher. + (setq adaptive-fill-regexp "\000") + (setq adaptive-fill-function 'org-adaptive-fill-function)) + +(defun org-fill-paragraph (&optional justify) + "Re-align a table, pass through to fill-paragraph if no table." + (let ((table-p (org-at-table-p)) + (table.el-p (org-at-table.el-p))) + (cond ((equal (char-after (point-at-bol)) ?*) t) ; skip headlines + (table.el-p t) ; skip table.el tables + (table-p (org-table-align) t) ; align org-mode tables + (t nil)))) ; call paragraph-fill + +;; For reference, this is the default value of adaptive-fill-regexp +;; "[ \t]*\\([-|#;>*]+[ \t]*\\|(?[0-9]+[.)][ \t]*\\)*" + +(defun org-adaptive-fill-function () + "Return a fill prefix for org-mode files. +In particular, this makes sure hanging paragraphs for hand-formatted lists +work correctly." + (if (looking-at " *\\([-*+] \\|[0-9]+[.)] \\)?") + (make-string (- (match-end 0) (match-beginning 0)) ?\ ))) + +;; Functions needed for Emacs/XEmacs region compatibility + +(defun org-add-hook (hook function &optional append local) + "Add-hook, compatible with both Emacsen." + (if (and local org-xemacs-p) + (add-local-hook hook function append) + (add-hook hook function append local))) + +(defun org-region-active-p () + "Is `transient-mark-mode' on and the region active? +Works on both Emacs and XEmacs." + (if org-ignore-region + nil + (if org-xemacs-p + (and zmacs-regions (region-active-p)) + (and transient-mark-mode mark-active)))) + +(defun org-add-to-invisibility-spec (arg) + "Add elements to `buffer-invisibility-spec'. +See documentation for `buffer-invisibility-spec' for the kind of elements +that can be added." + (cond + ((fboundp 'add-to-invisibility-spec) + (add-to-invisibility-spec arg)) + ((or (null buffer-invisibility-spec) (eq buffer-invisibility-spec t)) + (setq buffer-invisibility-spec (list arg))) + (t + (setq buffer-invisibility-spec + (cons arg buffer-invisibility-spec))))) + +(defun org-remove-from-invisibility-spec (arg) + "Remove elements from `buffer-invisibility-spec'." + (if (fboundp 'remove-from-invisibility-spec) + (remove-from-invisibility-spec arg) + (if (consp buffer-invisibility-spec) + (setq buffer-invisibility-spec + (delete arg buffer-invisibility-spec))))) + +(defun org-in-invisibility-spec-p (arg) + "Is ARG a member of `buffer-invisibility-spec'?" + (if (consp buffer-invisibility-spec) + (member arg buffer-invisibility-spec) + nil)) + +(defun org-image-file-name-regexp () + "Return regexp matching the file names of images." + (if (fboundp 'image-file-name-regexp) + (image-file-name-regexp) + (let ((image-file-name-extensions + '("png" "jpeg" "jpg" "gif" "tiff" "tif" + "xbm" "xpm" "pbm" "pgm" "ppm"))) + (concat "\\." + (regexp-opt (nconc (mapcar 'upcase + image-file-name-extensions) + image-file-name-extensions) + t) + "\\'")))) + +;; Functions needed for compatibility with old outline.el. + +;; Programming for the old outline.el (that uses selective display +;; instead of `invisible' text properties) is a nightmare, mostly +;; because regular expressions can no longer be anchored at +;; beginning/end of line. Therefore a number of function need special +;; treatment when the old outline.el is being used. + +;; The following functions capture almost the entire compatibility code +;; between the different versions of outline-mode. The only other +;; places where this is important are the font-lock-keywords, and in +;; `org-export-copy-visible'. Search for `org-noutline-p' to find them. + +;; C-a should go to the beginning of a *visible* line, also in the +;; new outline.el. I guess this should be patched into Emacs? +(defun org-beginning-of-line () + "Go to the beginning of the current line. If that is invisible, continue +to a visible line beginning. This makes the function of C-a more intuitive." + (interactive) + (beginning-of-line 1) + (if (bobp) + nil + (backward-char 1) + (if (org-invisible-p) + (while (and (not (bobp)) (org-invisible-p)) + (backward-char 1) + (beginning-of-line 1)) + (forward-char 1)))) + +(when org-noutline-p + (define-key org-mode-map "\C-a" 'org-beginning-of-line)) +;; FIXME: should I use substitute-key-definition to reach other bindings +;; of beginning-of-line? + +(defun org-invisible-p () + "Check if point is at a character currently not visible." + (if org-noutline-p + ;; Early versions of noutline don't have `outline-invisible-p'. + (if (fboundp 'outline-invisible-p) + (outline-invisible-p) + (get-char-property (point) 'invisible)) + (save-excursion + (skip-chars-backward "^\r\n") + (equal (char-before) ?\r)))) + +(defun org-invisible-p2 () + "Check if point is at a character currently not visible." + (save-excursion + (if org-noutline-p + (progn + (if (and (eolp) (not (bobp))) (backward-char 1)) + ;; Early versions of noutline don't have `outline-invisible-p'. + (if (fboundp 'outline-invisible-p) + (outline-invisible-p) + (get-char-property (point) 'invisible))) + (skip-chars-backward "^\r\n") + (equal (char-before) ?\r)))) + +(defun org-back-to-heading (&optional invisible-ok) + "Move to previous heading line, or beg of this line if it's a heading. +Only visible heading lines are considered, unless INVISIBLE-OK is non-nil." + (if org-noutline-p + (outline-back-to-heading invisible-ok) + (if (and (memq (char-before) '(?\n ?\r)) + (looking-at outline-regexp)) + t + (if (re-search-backward (concat (if invisible-ok "\\([\r\n]\\|^\\)" "^") + outline-regexp) + nil t) + (if invisible-ok + (progn (goto-char (match-end 1)) + (looking-at outline-regexp))) + (error "Before first heading"))))) + +(defun org-on-heading-p (&optional invisible-ok) + "Return t if point is on a (visible) heading line. +If INVISIBLE-OK is non-nil, an invisible heading line is ok too." + (if org-noutline-p + (outline-on-heading-p 'invisible-ok) + (save-excursion + (skip-chars-backward "^\n\r") + (and (looking-at outline-regexp) + (or invisible-ok + (bobp) + (equal (char-before) ?\n)))))) + +(defun org-on-target-p () + (let ((pos (point))) + (save-excursion + (skip-chars-forward "<") + (and (re-search-backward "<<" nil t) + (or (looking-at org-target-regexp) + (looking-at org-radio-target-regexp)) + (<= (match-beginning 0) pos) + (>= (match-end 0) pos))))) + +(defun org-up-heading-all (arg) + "Move to the heading line of which the present line is a subheading. +This function considers both visible and invisible heading lines. +With argument, move up ARG levels." + (if org-noutline-p + (if (fboundp 'outline-up-heading-all) + (outline-up-heading-all arg) ; emacs 21 version of outline.el + (outline-up-heading arg t)) ; emacs 22 version of outline.el + (org-back-to-heading t) + (looking-at outline-regexp) + (if (<= (- (match-end 0) (match-beginning 0)) arg) + (error "Cannot move up %d levels" arg) + (re-search-backward + (concat "[\n\r]" (regexp-quote + (make-string (- (match-end 0) (match-beginning 0) arg) + ?*)) + "[^*]")) + (forward-char 1)))) + +(defun org-show-hidden-entry () + "Show an entry where even the heading is hidden." + (save-excursion + (if (not org-noutline-p) + (progn + (org-back-to-heading t) + (org-flag-heading nil))) + (org-show-entry))) + +(defun org-check-occur-regexp (regexp) + "If REGEXP starts with \"^\", modify it to check for \\r as well. +Of course, only for the old outline mode." + (if org-noutline-p + regexp + (if (string-match "^\\^" regexp) + (concat "[\n\r]" (substring regexp 1)) + regexp))) + +(defun org-flag-heading (flag &optional entry) + "Flag the current heading. FLAG non-nil means make invisible. +When ENTRY is non-nil, show the entire entry." + (save-excursion + (org-back-to-heading t) + (if (not org-noutline-p) + ;; Make the current headline visible + (outline-flag-region (max 1 (1- (point))) (point) (if flag ?\r ?\n))) + ;; Check if we should show the entire entry + (if entry + (progn + (org-show-entry) + (save-excursion ;; FIXME: Is this the fix for points in the -| + ;; middle of text? | + (and (outline-next-heading) ;; | + (org-flag-heading nil)))) ; show the next heading _| + (outline-flag-region (max 1 (1- (point))) + (save-excursion (outline-end-of-heading) (point)) + (if org-noutline-p + flag + (if flag ?\r ?\n)))))) + +(defun org-end-of-subtree (&optional invisible-OK) + ;; This is an exact copy of the original function, but it uses + ;; `org-back-to-heading', to make it work also in invisible + ;; trees. And is uses an invisible-OK argument. + ;; Under Emacs this is not needed, but the old outline.el needs this fix. + (org-back-to-heading invisible-OK) + (let ((first t) + (level (funcall outline-level))) + (while (and (not (eobp)) + (or first (> (funcall outline-level) level))) + (setq first nil) + (outline-next-heading)) + (if (memq (preceding-char) '(?\n ?\^M)) + (progn + ;; Go to end of line before heading + (forward-char -1) + (if (memq (preceding-char) '(?\n ?\^M)) + ;; leave blank line before heading + (forward-char -1)))))) + +(defun org-show-subtree () + "Show everything after this heading at deeper levels." + (outline-flag-region + (point) + (save-excursion + (outline-end-of-subtree) (outline-next-heading) (point)) + (if org-noutline-p nil ?\n))) + +(defun org-show-entry () + "Show the body directly following this heading. +Show the heading too, if it is currently invisible." + (interactive) + (save-excursion + (org-back-to-heading t) + (outline-flag-region + (1- (point)) + (save-excursion + (re-search-forward (concat "[\r\n]\\(" outline-regexp "\\)") nil 'move) + (or (match-beginning 1) (point-max))) + (if org-noutline-p nil ?\n)))) + + +(defun org-make-options-regexp (kwds) + "Make a regular expression for keyword lines." + (concat + (if org-noutline-p "^" "[\n\r]") + "#?[ \t]*\\+\\(" + (mapconcat 'regexp-quote kwds "\\|") + "\\):[ \t]*" + (if org-noutline-p "\\(.+\\)" "\\([^\n\r]+\\)"))) + +;; Make `bookmark-jump' show the jump location if it was hidden. +(eval-after-load "bookmark" + '(if (boundp 'bookmark-after-jump-hook) + ;; We can use the hook + (add-hook 'bookmark-after-jump-hook 'org-bookmark-jump-unhide) + ;; Hook not available, use advice + (defadvice bookmark-jump (after org-make-visible activate) + "Make the position visible." + (org-bookmark-jump-unhide)))) + +(defun org-bookmark-jump-unhide () + "Unhide the current position, to show the bookmark location." + (and (eq major-mode 'org-mode) + (or (org-invisible-p) + (save-excursion (goto-char (max (point-min) (1- (point)))) + (org-invisible-p))) + (org-show-hierarchy-above))) + +;;; Finish up + +(provide 'org) + +(run-hooks 'org-load-hook) + +;; Experimental code + + + +;; arch-tag: e77da1a7-acc7-4336-b19e-efa25af3f9fd +;;; org.el ends here + diff --git a/org.pdf b/org.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7ed4b20c87f1bbb70419794f6120fbc717bd2754 GIT binary patch literal 442839 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∨JI$Dn!si%|F|tl>`~0?6Ow+i+nadxsw8%v} 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

    &?wjIzu~1Ts3wvFX|P>yteAKZybz$+%HR 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

    T%u(9B~0@Df@ldEXVM7!V+s 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%0A@$3wS*V&ZI6$vuM_kyDY_ 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