+++ /dev/null
-;;; org-refer-by-number.el --- Create and search numbers used as references\r
-\r
-;; Copyright (C) 2011,2012 Free Software Foundation, Inc.\r
-\r
-;; Author: Marc-Oliver Ihm <ihm@ferntreffer.de>\r
-;; Keywords: hypermedia, matching\r
-;; Requires: org\r
-;; Download: http://orgmode.org/worg/code/elisp/org-refer-by-number.el\r
-;; Version: 1.5.0\r
-\r
-;;; License:\r
-\r
-;; This program is free software; you can redistribute it and/or modify\r
-;; it under the terms of the GNU General Public License as published by\r
-;; the Free Software Foundation; either version 3, or (at your option)\r
-;; any later version.\r
-;;\r
-;; This program is distributed in the hope that it will be useful,\r
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-;; GNU General Public License for more details.\r
-;;\r
-;; You should have received a copy of the GNU General Public License\r
-;; along with GNU Emacs; see the file COPYING. If not, write to the\r
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
-;; Boston, MA 02110-1301, USA.\r
-\r
-;;; Commentary:\r
-\r
-;; Purpose:\r
-;;\r
-;; Refer to things by reference numbers, especially if direct linking is\r
-;; not possible. These reference numbers are added to and kept within a\r
-;; table along with the timestamp of their creation.\r
-;;\r
-;; These reference numbers may then be used to refer to things outside of\r
-;; or within Org. E.g. by writing them on a piece of paper or using them\r
-;; as part of a directory name or the heading of an Org node. Within Org\r
-;; you may then refer to these things by their reference number\r
-;; (e.g. "R153"); the numbers can be looked up and searched easily.\r
-;;\r
-;; The whole functionality is available through the function\r
-;; `org-refer-by-number'; the necessary setup is described in the\r
-;; docstring of the variable `org-refer-by-number-id'.\r
-;;\r
-;; org-refer-by-number.el is only a small add-on to Carsten Dominiks\r
-;; Org-mode, which must be installed as a prerequisite. See\r
-;; http://orgmode.org or elpa for Org-mode itself.\r
-;;\r
-;; Setup:\r
-;;\r
-;; - Adjust these lines and add them to your .emacs:\r
-;;\r
-;; (require 'org-refer-by-number)\r
-;; (setq org-refer-by-number-id "00e26bef-1929-4110-b8b4-7eb9c9ab1fd4")\r
-;; ;; Optionally assign a key\r
-;; (global-set-key (kbd "C-+") 'org-refer-by-number)\r
-;;\r
-;; - Create an Org-mode node with a reference table\r
-;; as described in the documentation of `org-refer-by-number-id'\r
-;;\r
-;; Further reading:\r
-;;\r
-;; For the necessary setup, see the variable `org-refer-by-number-id';\r
-;; for regular usage, see the function `org-refer-by-number'.\r
-;;\r
-\r
-;;; Change Log:\r
-\r
-;; [2012-09-22 Sa] Version 1.5.0:\r
-;; - New operation "sort" to sort a buffer or region by reference number\r
-;; - New operations "highlight" and "unhighlight" to mark references\r
-\r
-;; [2012-07-13 Fr] Version 1.4.0:\r
-;; - New operation "head" to find a headline with a reference number\r
-\r
-;; [2012-04-28 Sa] Version 1.3.0:\r
-;; - New operations occur and multi-occur\r
-;; - All operations can now be invoked explicitly\r
-;; - New documentation\r
-;; - Many bugfixes\r
-\r
-;; [2011-12-10 Sa] Version 1.2.0:\r
-;; - Fixed a bug, which lead to a loss of newly created reference numbers\r
-;; - Introduced single and double prefix arguments\r
-;; - Started this Change Log\r
-\r
-;;; Code:\r
-\r
-(require 'org-table)\r
-\r
-(defvar org-refer-by-number-id nil \r
- "Id of the Org-mode node, with the table of reference numbers.\r
-\r
-Read below, on how to set up things. See the documentation of\r
-`org-refer-by-number' for normal usage after setup.\r
-\r
-Setup requires two steps:\r
-\r
-- Create a suitable org-mode node\r
-- Adjust your .emacs initialization file\r
-\r
-\r
-Here is how you create the org-mode node, where your reference\r
-numbers will be stored. It may look like this:\r
-\r
-\r
- * My node for org-refer-by-number\r
- :PROPERTIES:\r
- :ID: 00e26bef-1929-4110-b8b4-7eb9c9ab1fd4\r
- :END:\r
- \r
- | Number | Date | Comment |\r
- |--------+-----------------+----------------------------|\r
- | R1 | [2012-04-28 Sa] | My first reference number |\r
-\r
-\r
-You may just want to copy this node into one of your org-files.\r
-Many things however can or should be adjusted:\r
-\r
-- The node needs not be a top level node.\r
-\r
-- Its name is completely at you choice. The node is found\r
- through its ID.\r
-\r
-- Column names can be changed.\r
-\r
-- You can add further columns or even remove the\r
- \"Comment\"-column. The columns \"Number\" and \"Date\" however\r
- are required.\r
-\r
-- Your references need not start at \"R1\"; and of course you can\r
- adjust date and comment. However, having an initial row is\r
- required (it servers a template for subsequent references).\r
-\r
-- Your reference need not have the form \"R1\"; you may just as\r
- well choose any text, that contains a single number,\r
- e.g. \"reference-{1}\" or \"#1\" or \"++1++\". The function\r
- `org-refer-by-number' will inspect your first reference and\r
- create all subsequent references in the same way.\r
- \r
-- You may want to change the ID-Property of the node above and\r
- create a new one, which is unique (and not just a copy of\r
- mine). You need to change it in the lines copied to your .emacs\r
- too. However, this is not strictly required to make things\r
- work, so you may do this later, after trying out this package.\r
-\r
-\r
-Having created the node with your reference table, you only need\r
-to add some lines to your .emacs:\r
-\r
- (require 'org-refer-by-number)\r
- (setq org-refer-by-number-id \"00e26bef-1929-4110-b8b4-7eb9c9ab1fd4\")\r
- ;; Optionally assign a key\r
- (global-set-key (kbd \"C-+\") 'org-refer-by-number)\r
-\r
-Do not forget to restart emacs to make these lines effective.\r
-\r
-\r
-After this two-step setup you may invoke `org-refer-by-number' to\r
-create a new reference number; read there for instructions on\r
-normal usage.\r
-\r
-")\r
-\r
-(defvar org-refer-by-number-windowconfig nil \r
- "Saved window-configuration for `org-refer-by-number'.\r
-This variable is only used internally.")\r
-\r
-(defvar org-refer-by-number-marker nil \r
- "Saved marker for `org-refer-by-number'.\r
-This variable is only used internally.")\r
-\r
-(defvar org-refer-by-number-last-action nil \r
- "Last action performed by `org-refer-by-number'.\r
-This variable is only used internally.")\r
-\r
-(defvar org-refer-by-number-occur-buffer nil\r
- "Buffer (if any) with result from occur or multi-occur.\r
-This variable is only used internally.")\r
-\r
-(defun org-refer-by-number (arg) \r
- "Add a new reference number or search for an existing one.\r
-\r
-These reference numbers may then be used to refer to things\r
-outside of Org in cases, where direct linking is not\r
-possible. E.g. you may write them on documents or letters you\r
-receive or use them on your computer as part of foldernames that\r
-you create.\r
-\r
-Read below for a detailed description of this function. See the\r
-documentation of `org-refer-by-number-id' for the necessary\r
-setup.\r
-\r
-\r
-The function `org-refer-by-number' operates on a dedicated\r
-table (called the reference table) within a special Org-mode\r
-node. The node has to be created as part of your initial\r
-setup. The reference table has at least two columns: The\r
-reference number (automatically increasing by one from row to\r
-row) and the date of creation. The table is found through the id\r
-of the containing node; this id must be stored within\r
-`org-refer-by-number-id' (see there for details).\r
-\r
-\r
-The function `org-refer-by-number' is the only interactive\r
-function of this package and its sole entry point; it offers seven\r
-different operations (short names in parens):\r
-\r
-- Add a new row with a new reference number and the\r
- date of creation (\"add\").\r
-\r
-- Search for an existing reference number within your reference\r
- table (\"search\").\r
-\r
-- Find all occurences of a particular string within your\r
- reference table; typically within the comment\r
- column (\"occur\").\r
-\r
-- Find all occurences of a particular reference number within all\r
- of your org-files (\"multi-occur\").\r
-\r
-- Go to the first heading, that contains a given reference\r
- number (\"heading\").\r
-\r
-- Enter the reference table and position the cursor at the\r
- top (\"enter\").\r
-\r
-- Leave the reference table and restore cursor position and\r
- window configuration, back to the state before entering\r
- it (\"leave\").\r
-\r
-- Sort lines in current buffer or active region by the first\r
- reference number, they contain, if any (\"sort\").\r
-\r
-- Highlight or unhighlight all occurences of reference number\r
- within current buffer (\"highlight\" or \"unhighlight\").\r
- \r
-The most straightforward way to select between these operations\r
-is to supply a negative or a a double prefix argument:\r
-\r
-`C-- \\[org-refer-by-number]' or `\\[universal-argument] \\[universal-argument] \\[org-refer-by-number]'\r
-\r
-You will then be prompted to type a single letter (\"a\", \"s\",\r
-\"o\", \"m\", \"h\", \"e\" or \"l\") to invoke the respective\r
-operation from the list above. If your type \"+\" you will be\r
-prompted a second time to choose among some of the less common\r
-operations (e.g. \"sort\").\r
-\r
-\r
-Some of the operations above can be invoked with less keystrokes. In that\r
-case the precise operation invoked depends on two things:\r
-\r
-- The kind of a prefix argument (or absence of such)\r
-\r
-- The location of point; either outside the reference table or\r
- within\r
-\r
-\r
-The following cases explain, which of the seven\r
-operations (\"add\", \"search\", \"occur\", \"multi-occur\",\r
-\"heading\", \"enter\" and \"leave\") is actually invoked\r
-depending on the conditions above:\r
-\r
-\r
- If no prefix argument is given (`\\[org-refer-by-number]') and\r
- point is withib the reference table, the operation \"leave\"\r
- will be invoked. If point is within reference table, a\r
- \"search\" will be done in most cases; if, however, there is an\r
- active region, the operation \"add\" is performed.\r
-\r
- If a numeric prefix argument is given (e.g. `153 \\[org-refer-by-number]'): \r
- The function does a \"search\" for this reference number, \r
- if point is outside and a \"multi-occur\", if point is within\r
- regardless of position of point.\r
-\r
- If a single prefix argument is given (e.g. `\\[universal-argument] \\[org-refer-by-number]')\r
- and point outside the reference table: \"add\" a new reference. \r
- If point within: Do a \"multi-occur\" for the given reference.\r
-\r
-\r
-In any case the function `org-refer-by-number' will give a short\r
-message to explain, what operation has actually been invoked.\r
-\r
-\r
-Before you can successfully use `org-refer-by-number' finally,\r
-you need to read the documentation of `org-refer-by-number-id'\r
-and complete the necessary setup decribed there.\r
-\r
-\r
-"\r
-\r
- (interactive "P")\r
-\r
- (let (within-node ; True, if we are within node with reference table\r
- ; (false otherwise, even if we are in the\r
- ; right buffer)\r
- result-is-visible ; True, if node or occur is visible in any window\r
- search-from-prefix ; search string from prefix-argument\r
- search-from-table ; search string from first column of table\r
- search-from-cursor ; search string from text below cursro\r
- search-from-user ; search string from user input\r
- below-cursor ; word below cursor\r
- active-region ; active region (if any)\r
- search ; final string to search for\r
- guarded-search ; with guard against additional digits\r
- what ; What are we supposed to do ? Will be stored in\r
- ; org-refer-by-number-last-action\r
- what-adjusted ; True, if we had to adjust what\r
- what-explicit ; True, if what has been specified explicitly\r
- parts ; Parts of a typical reference number (which\r
- ; need not be a plain number); these are:\r
- head ; Any header before number (e.g. "R")\r
- last-number ; Last number used in reference table (e.g. "153")\r
- tail ; Tail after number (e.g. "}" or "")\r
- ref-regex ; Regular expression to match a reference\r
- columns ; Number of columns in reference table\r
- kill-new-text ; Text that will be appended to kill ring\r
- message-text ; Text that will be issued as an explanation,\r
- ; what we have done\r
- node-marker ; Initial point within buffer with reference table\r
- )\r
- \r
- ;; Find out, if we are within reference table or not\r
- (setq within-node (string= (org-id-get) org-refer-by-number-id))\r
- ;; Find out, if point in any window is within node with reference table\r
- (mapc (lambda (x) (save-excursion \r
- (set-buffer (window-buffer x))\r
- (when (or \r
- (string= (org-id-get) org-refer-by-number-id)\r
- (eq (window-buffer x) \r
- org-refer-by-number-occur-buffer))\r
- (setq result-is-visible t))))\r
- (window-list))\r
-\r
- ;; Get the content of the active region or the word under cursor; do\r
- ;; this before examinig reference table\r
- (if (and transient-mark-mode\r
- mark-active)\r
- (setq active-region (buffer-substring (region-beginning) (region-end))))\r
- (setq below-cursor (thing-at-point 'symbol))\r
-\r
- ;; Find out, what we are supposed to do\r
- (cond ((equal arg nil)\r
- (setq what (if result-is-visible 'leave \r
- (if active-region 'add 'search))))\r
- ((equal arg '(4))\r
- (setq what (if within-node 'multi-occur 'add)))\r
- ((numberp arg)\r
- (setq what (if within-node 'multi-occur 'search)))\r
- (t ; C-- or C-u C-u\r
- (let (key)\r
- (while \r
- (progn \r
- (setq key (read-char-exclusive \r
- "Please choose: e=enter l=leave s=search a=add o=occur m=multi-occur h=heading +=more choices"))\r
- (not \r
- (setq what (case key\r
- (?l 'leave) (?e 'enter) (?a 'add) \r
- (?s 'search) (?o 'occur) (?m 'multi-occur) (?h 'heading) (?+ 'more)))))\r
- (message "Invalid key '%c'" key)\r
- (sleep-for 1))\r
- (if (eq what 'more)\r
- (setq what (cdr (assoc \r
- (org-icompleting-read "Please choose: " '("sort" "highlight" "unhighlight") nil t)\r
- '(("sort" . sort)("highlight" . highlight)("unhighlight" . unhighlight))))))\r
- (setq what-explicit t))))\r
-\r
- ;; Get decoration and number of last row from reference table\r
- (let ((m (org-id-find org-refer-by-number-id 'marker)))\r
- (unless m\r
- (org-refer-by-number-report-setup-error \r
- (format "Cannot find node with id \"%s\"" org-refer-by-number-id)))\r
- (with-current-buffer (marker-buffer m)\r
- (setq node-marker (point-marker))\r
- (setq node-buffer (marker-buffer node-marker))\r
- (goto-char m)\r
- (setq parts (org-refer-by-number-trim-table nil t))\r
- (goto-char node-marker))\r
- (move-marker m nil)\r
- (setq head (nth 0 parts))\r
- (setq last-number (nth 1 parts))\r
- (setq tail (nth 2 parts))\r
- (setq columns (nth 3 parts))\r
- (setq ref-regex (concat (regexp-quote head) "\\([0-9]+\\)" (regexp-quote tail))))\r
- \r
-\r
- ;; These actions need a search string:\r
- (when (memq what '(search occur multi-occur heading))\r
-\r
- ;; Search string can come from several sources:\r
- ;; From explicit numerical prefix\r
- (if (numberp arg) \r
- (setq search-from-prefix (format "%s%d%s" head arg tail)))\r
- ;; From first column of table\r
- (when within-node\r
- (save-excursion (setq search-from-table (org-table-get-field 1)))\r
- (if (string= search-from-table "") (setq search-from-table nil))) \r
- ;; From string below cursor\r
- (when (and (not within-node)\r
- below-cursor\r
- (string-match (concat "\\(" ref-regex "\\)") \r
- below-cursor))\r
- (setq search-from-cursor (match-string 1 below-cursor)))\r
- \r
- ;; Depending on requested action, get search from one of the sources above\r
- (cond ((eq what 'search)\r
- (setq search (or search-from-prefix search-from-cursor)))\r
- ((or (eq what 'multi-occur) (eq what 'heading))\r
- (setq search (or search-from-table search-from-cursor)))\r
- ((eq what 'occur)\r
- (setq search active-region)))\r
-\r
-\r
- ;; If we still do not have a search string, ask user explicitly\r
- (unless search\r
- (setq search (read-from-minibuffer\r
- (cond ((memq what '(search multi-occur heading))\r
- "Reference number to search for: ")\r
- ((eq what 'occur)\r
- "Text to search for: "))))\r
- (if (string-match "^\\s *[0-9]*\\s *$" search)\r
- (unless (string= search "")\r
- (setq search (format "%s%s%s" head (org-trim search) tail)))))\r
- \r
- ;; Clean up search string\r
- (if (string= search "") (setq search nil))\r
- (if search (setq search (org-trim search)))\r
-\r
- (setq guarded-search \r
- (concat (regexp-quote search)\r
- ;; if there is no tail in reference number, we\r
- ;; have to guard agains trailing digits\r
- (if (string= tail "") "\\($\\|[^0-9]\\)" "")))\r
-\r
- \r
- ;; Correct requested action, if nothing to search\r
- (when (and (not search)\r
- (memq what '(search occur multi-occur heading)))\r
- (setq what 'enter)\r
- (setq what-adjusted t))\r
- \r
- ;; Check for invalid combinations of arguments; try to be helpful\r
- (if (string-match ref-regex search)\r
- (if (eq what 'occur) \r
- (error "Can do 'occur' only for text, try 'search', 'multi-occur' or 'heading' for a number"))\r
- (if (memq what '(search multi-occur heading))\r
- (error "Can do '%s' only for a number, try 'occur' to search for text" what))))\r
- \r
- ;; Move into table, if outside ...\r
- (when (memq what '(enter add search occur multi-occur))\r
- ;; Save current window configuration\r
- (when (or (not result-is-visible)\r
- (not org-refer-by-number-windowconfig))\r
- (setq org-refer-by-number-windowconfig (current-window-configuration))\r
- (setq org-refer-by-number-marker node-marker))\r
- \r
- ;; Switch to reference table; this needs to duplicate some code from\r
- ;; org-id-goto, because point should be moved, if what equals 'enter\r
- (let ((m (org-id-find org-refer-by-number-id 'marker)))\r
- (org-pop-to-buffer-same-window (marker-buffer m))\r
- ;; After changing buffer we might be in table or not, so check again\r
- (setq within-node (string= (org-id-get) org-refer-by-number-id))\r
- ;; Be careful with position within table, if we should just enter it\r
- (unless within-node (goto-char m))\r
- (move-marker m nil)\r
- (show-subtree)\r
- (org-show-context)))\r
-\r
-\r
- ;; Actually do, what is requested\r
- (cond\r
- ((eq what 'multi-occur) \r
- \r
- ;; Position cursor on number to search for\r
- (org-refer-by-number-trim-table t)\r
- (let (found (initial (point)))\r
- (forward-line)\r
- (while (and (not found)\r
- (forward-line -1)\r
- (org-at-table-p))\r
- (save-excursion \r
- (setq found (string= search \r
- (org-trim (org-table-get-field 1))))))\r
- (if found \r
- (org-table-goto-column 1)\r
- (goto-char initial)))\r
-\r
- ;; Construct list of all org-buffers\r
- (let (buff org-buffers)\r
- (dolist (buff (buffer-list))\r
- (set-buffer buff)\r
- (if (string= major-mode "org-mode")\r
- (setq org-buffers (cons buff org-buffers))))\r
- \r
- ;; Do multi-occur\r
- (multi-occur org-buffers guarded-search)\r
- (if (get-buffer "*Occur*")\r
- (progn \r
- (setq message-text (format "multi-occur for '%s'" search))\r
- (setq org-refer-by-number-occur-buffer (get-buffer "*Occur*")))\r
- (setq message-text (format "Did not find '%s'" search)))))\r
-\r
-\r
- ((eq what 'heading)\r
- (message (format "Scanning headlines for '%s' ..." search))\r
- (let (buffer point)\r
- (if (catch 'found\r
- (progn\r
- (org-map-entries \r
- (lambda () \r
- (when (looking-at (concat ".*\\b" guarded-search))\r
- (setq buffer (current-buffer))\r
- (setq point (point))\r
- (throw 'found t))) \r
- nil 'agenda)\r
- nil))\r
- (progn\r
- (setq message-text (format "Found '%s'" search))\r
- (org-pop-to-buffer-same-window buffer)\r
- (goto-char point)\r
- (org-reveal))\r
- (setq message-text (format "Did not find '%s'" search)))))\r
-\r
-\r
- ((eq what 'leave)\r
-\r
- (when result-is-visible\r
-\r
- ;; if we are within the occur-buffer, switch over to get current line\r
- (if (and (string= (buffer-name) "*Occur*")\r
- (eq org-refer-by-number-last-action 'occur))\r
- (occur-mode-goto-occurrence))\r
- \r
- (if (org-at-table-p)\r
- (let ((column (org-table-current-column)))\r
- ;; Copy different things depending on the last action\r
- (if (and (eq org-refer-by-number-last-action 'search)\r
- (= column 1))\r
- ;; It does not help to copy the first field, because\r
- ;; thats what we just searched for, so take last one\r
- (setq column columns))\r
- (if (or (memq org-refer-by-number-last-action '(add occur))\r
- (< column 1))\r
- (setq column 1))\r
- \r
- ;; Add to kill ring\r
- (if (memq org-refer-by-number-last-action '(add enter search occur))\r
- ;; Got left to first nonempty column\r
- (while (progn \r
- (save-excursion \r
- (setq kill-new-text \r
- (org-trim (org-table-get-field column))))\r
- (and (> column 0)\r
- (string= kill-new-text "")))\r
- (setq column (- column 1))))))\r
- \r
- ;; Clean up table before leaving\r
- (with-current-buffer node-buffer \r
- (org-refer-by-number-trim-table t)\r
- (let ((buffer-modified (buffer-modified-p)))\r
- (org-table-align)\r
- (set-buffer-modified-p buffer-modified))))\r
-\r
- ;; Restore position within buffer with reference table\r
- (if org-refer-by-number-windowconfig \r
- (progn \r
- (with-current-buffer node-buffer\r
- (goto-char org-refer-by-number-marker)\r
- (set-marker org-refer-by-number-marker nil))\r
- ;; Restore initial window configuration\r
- (set-window-configuration org-refer-by-number-windowconfig)\r
- (setq org-refer-by-number-windowconfig nil)\r
- (recenter)\r
- (setq message-text "Back"))\r
- ;; We did not have a window-configuration to restore, so we cannot\r
- ;; pretend we have retturned back\r
- (setq message-text "Cannot leave; nowhere to go to")))\r
-\r
- \r
- ((eq what 'search)\r
- ;; Go upward in table within first column\r
- (org-refer-by-number-trim-table t)\r
- (let (found (initial (point)))\r
- (forward-line)\r
- (while (and (not found)\r
- (forward-line -1)\r
- (org-at-table-p))\r
- (save-excursion \r
- (setq found \r
- (string= search \r
- (org-trim (org-table-get-field 1))))))\r
- (if found\r
- (progn\r
- (setq message-text (format "Found '%s'" search))\r
- (org-table-goto-column 1)\r
- (if (looking-back " ") (backward-char)))\r
- (setq message-text (format "Did not find '%s'" search))\r
- (goto-char initial)\r
- (forward-line)\r
- (setq what 'missed))))\r
-\r
-\r
- ((eq what 'occur)\r
- ;; search for string: occur\r
- (org-narrow-to-subtree)\r
- (occur search)\r
- (widen)\r
- (if (get-buffer "*Occur*")\r
- (progn\r
- (put 'org-refer-by-number 'occur-buffer (current-buffer))\r
- (other-window 1)\r
- (toggle-truncate-lines 1)\r
- (forward-line 1)\r
- (occur-mode-display-occurrence)\r
- (setq message-text\r
- (format "Occur for '%s'" search)))\r
- (setq message-text\r
- (format "Did not find any matches for '%s'" search))))\r
-\r
- \r
- ((eq what 'add)\r
- ;; Nothing to search for, add a new row\r
- (org-refer-by-number-trim-table t)\r
- (let ((new (format "%s%d%s" head (1+ last-number) tail)))\r
- (org-table-insert-row 1)\r
- (insert new)\r
- (org-table-goto-column 2)\r
- (org-insert-time-stamp nil nil t)\r
- (org-table-goto-column 3)\r
- (org-table-align)\r
- (if active-region (setq kill-new-text active-region))\r
- (setq message-text (format "Adding a new row '%s'" new))))\r
- \r
- \r
- ((eq what 'enter)\r
- ;; Already there, not much to do left\r
- (show-subtree)\r
- (recenter)\r
- (if what-adjusted\r
- (setq message-text "Nothing to search for; at reference table")\r
- (setq message-text "At reference table")))\r
- \r
-\r
- ((eq what 'sort)\r
- (let (begin end where)\r
- (if (if (and transient-mark-mode\r
- mark-active)\r
- (progn\r
- (setq begin (region-beginning))\r
- (setq end (region-end))\r
- (setq where "region")\r
- t)\r
- (setq begin (point-min))\r
- (setq end (point-max))\r
- (setq where "whole buffer")\r
- (y-or-n-p "Sort whole buffer ")\r
- )\r
- (save-excursion\r
- (save-restriction\r
- (beginning-of-buffer)\r
- (narrow-to-region begin end)\r
- (sort-subr nil 'forward-line 'end-of-line \r
- (lambda ()\r
- (if (looking-at (concat "^.*\\b" ref-regex "\\b"))\r
- (string-to-number (match-string 1))\r
- 0))))\r
- (highlight-regexp ref-regex)\r
- (setq message-text (format "Sorted %s from character %d to %d, %d lines" \r
- where begin end\r
- (count-lines begin end))))\r
- (setq message-text "Sort aborted"))))\r
- \r
-\r
- ((memq what '(highlight unhighlight))\r
- (let ((where "buffer"))\r
- (save-excursion\r
- (save-restriction\r
- (when (and transient-mark-mode\r
- mark-active)\r
- (narrow-to-region (region-beginning) (region-end))\r
- (setq where "region")\r
- )\r
- (if (eq what 'highlight)\r
- (progn\r
- (highlight-regexp ref-regex)\r
- (setq message-text (format "Highlighted references in %s" where)))\r
- (unhighlight-regexp ref-regex)\r
- (setq message-text (format "Removed highlights for references in %s" where)))))))\r
- \r
-\r
- (t (error "This is a bug: Unmatched condition '%s'" what)))\r
-\r
- \r
- ;; Remember what we have done for next time\r
- (setq org-refer-by-number-last-action what)\r
- \r
- ;; Tell, what we have done and what can be yanked\r
- (if kill-new-text (setq kill-new-text \r
- (substring-no-properties kill-new-text)))\r
- (if (string= kill-new-text "") (setq kill-new-text nil))\r
- (let ((m (concat \r
- message-text\r
- (if (and message-text kill-new-text) \r
- " and r" \r
- (if kill-new-text "R" ""))\r
- (if kill-new-text (format "eady to yank '%s'" kill-new-text) "")\r
- )))\r
- (unless (string= m "") (message m)))\r
- (if kill-new-text (kill-new kill-new-text))))\r
-\r
-\r
-(defun org-refer-by-number-trim-table (&optional goto-end get-parts)\r
- "Trim reference table, only used internally"\r
- \r
- (let ((initial (point-marker))\r
- field\r
- parts\r
- columns)\r
-\r
- ;; Go to heading of node\r
- (while (not (org-at-heading-p)) (forward-line -1))\r
- (forward-line 1)\r
- ;; Go to table within node, but make sure we do not get into another node\r
- (while (and (not (org-at-heading-p))\r
- (not (org-at-table-p))\r
- (not (eq (point) (point-max)))) \r
- (forward-line 1))\r
- ;; Check, if there really is a table\r
- (unless (org-at-table-p)\r
- (org-refer-by-number-report-setup-error \r
- "Cannot find reference table within reference node" t))\r
-\r
- ;; Go beyond end of table\r
- (while (org-at-table-p) (forward-line 1))\r
-\r
- ;; Kill all empty rows at bottom\r
- (while (progn\r
- (forward-line -1)\r
- (org-table-goto-column 1)\r
- (string= "" (org-trim (org-table-get-field 1)))\r
- )\r
- (org-table-kill-row)\r
- )\r
-\r
- (when get-parts\r
-\r
- ;; Find out number of columns\r
- (org-table-goto-column 100)\r
- (setq columns (- (org-table-current-column) 1))\r
-\r
- ;; Check for right number of columns\r
- (unless (>= columns 2)\r
- (org-refer-by-number-report-setup-error \r
- "Table within reference node has less than two columns" t)\r
- )\r
-\r
- ;; Retrieve any decorations around the number within first field of\r
- ;; the last row\r
- (setq field (org-trim (org-table-get-field 1)))\r
- (or (string-match "^\\([^0-9]*\\)\\([0-9]+\\)\\([^0-9]*\\)$" field)\r
- (org-refer-by-number-report-setup-error \r
- (format "Last field of reference table '%s' does not contain a number" field) t)\r
- )\r
-\r
- ;; These are the decorations used within the last row of the\r
- ;; reference table\r
- (setq parts (list (match-string 1 field) \r
- (string-to-number (match-string 2 field)) \r
- (match-string 3 field) \r
- columns)))\r
-\r
- (unless goto-end (goto-char (marker-position initial)))\r
- (set-marker initial nil)\r
- \r
- parts))\r
-\r
-\r
-(defun org-refer-by-number-report-setup-error (text &optional switch-to-node)\r
- "Report error, which might be related with incomplete setup; offer help"\r
-\r
- (when switch-to-node \r
- (org-id-goto org-refer-by-number-id)\r
- (delete-other-windows)\r
- )\r
- \r
- (if (y-or-n-p (concat text \r
- "; "\r
- "the correct setup is explained in the documentation of 'org-refer-by-number-id'. " \r
- "Do you want to read it ? "))\r
- (describe-variable 'org-refer-by-number-id)\r
- )\r
- (error "")\r
- (setq org-refer-by-number-windowconfig nil)\r
- (setq org-refer-by-number-last-action 'leave))\r
-\r
-\r
-(provide 'org-refer-by-number)\r
-\r
-;; Local Variables:\r
-;; fill-column: 75\r
-;; comment-column: 50\r
-;; End:\r
-\r
-;;; org-refer-by-number.el ends here\r
-\r