| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701 | 
							- ;;; org-favtable.el --- Lookup table of favorite references and links
 
- ;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
 
- ;; Author: Marc-Oliver Ihm <org-favtable@ferntreffer.de>
 
- ;; Keywords: hypermedia, matching
 
- ;; Requires: org
 
- ;; Download: http://orgmode.org/worg/code/elisp/org-favtable.el
 
- ;; Version: 2.2.0
 
- ;; This file is not part of GNU Emacs.
 
- ;;; License:
 
- ;; This program is free software; you can redistribute it and/or modify
 
- ;; it under the terms of the GNU General Public License as published by
 
- ;; the Free Software Foundation; either version 3, or (at your option)
 
- ;; any later version.
 
- ;;
 
- ;; This program is distributed in the hope that it will be useful,
 
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
- ;; GNU General Public License for more details.
 
- ;;
 
- ;; You should have received a copy of the GNU General Public License
 
- ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
- ;;; Commentary:
 
- ;; Purpose:
 
- ;;
 
- ;;  Mark and find your favorite things and locations in org easily: Create
 
- ;;  and update a lookup table of your references and links. Often used
 
- ;;  entries bubble to the top and entering some keywords displays only the
 
- ;;  matching entries. That way the right entry one can be picked easily.
 
- ;;
 
- ;;  References are essentially small numbers (e.g. "R237" or "-455-"),
 
- ;;  which are created by this package; they are well suited to be used
 
- ;;  outside of org. Links are just normal org-mode links.
 
- ;;
 
- ;;
 
- ;; Setup:
 
- ;;
 
- ;;  - Add these lines to your .emacs:
 
- ;;
 
- ;;    (require 'org-favtable)
 
- ;;    ;; Good enough to start, but later you should probably
 
- ;;    ;; change this id, as will be explained below
 
- ;;    (setq org-favtable-id "00e26bef-1929-4110-b8b4-7eb9c9ab1fd4")
 
- ;;    ;; Optionally assign a key. Pick your own favorite.
 
- ;;    (global-set-key (kbd "C-+") 'org-favtable)
 
- ;;
 
- ;;  - Just invoke `org-favtable', which will explain how to complete your
 
- ;;    setup by creating the necessary table of favorites.
 
- ;;
 
- ;;
 
- ;; Further reading:
 
- ;;
 
- ;;  Invoke `org-favtable' and pick one of its help options. You may also
 
- ;;  read the documentation of `org-favtable-id' for setup instructions, of
 
- ;;  `org-favtable' for regular usage and of `org-favtable--commands' for a
 
- ;;  list of available commands.
 
- ;;
 
- ;;; Change Log:
 
- ;;   [2013-02-28 Th] Version 2.2.0:
 
- ;;    - Allowed shortcuts like "h237" for command "head" with argument "237"
 
- ;;    - Integrated with org-mark-ring-goto
 
- ;;
 
- ;;   [2013-01-25 Fr] Version 2.1.0:
 
- ;;    - Added full support for links
 
- ;;    - New commands "missing" and "statistics"
 
- ;;    - Renamed the package from "org-reftable" to "org-favtable"
 
- ;;    - Additional columns are required (e.g. "link"). Error messages will
 
- ;;      guide you
 
- ;;
 
- ;;   [2012-12-07 Fr] Version 2.0.0:
 
- ;;    - The format of the table of favorites has changed ! You need to bring
 
- ;;      your existing table into the new format by hand (which however is
 
- ;;      easy and explained below)
 
- ;;    - Reference table can be sorted after usage count or date of last access
 
- ;;    - Ask user explicitly, which command to invoke
 
- ;;    - Renamed the package from "org-refer-by-number" to "org-reftable"
 
- ;;   [2012-09-22 Sa] Version 1.5.0:
 
- ;;    - New command "sort" to sort a buffer or region by reference number
 
- ;;    - New commands "highlight" and "unhighlight" to mark references
 
- ;;   [2012-07-13 Fr] Version 1.4.0:
 
- ;;    - New command "head" to find a headline with a reference number
 
- ;;   [2012-04-28 Sa] Version 1.3.0:
 
- ;;    - New commands occur and multi-occur
 
- ;;    - All commands can now be invoked explicitly
 
- ;;    - New documentation
 
- ;;    - Many bugfixes
 
- ;;   [2011-12-10 Sa] Version 1.2.0:
 
- ;;    - Fixed a bug, which lead to a loss of newly created reference numbers
 
- ;;    - Introduced single and double prefix arguments
 
- ;;    - Started this Change Log
 
- ;;; Code:
 
- (require 'org-table)
 
- (require 'cl)
 
- (defvar org-favtable--version "2.2.0")
 
- (defvar org-favtable--preferred-command nil)
 
- (defvar org-favtable--commands '(occur head ref link enter leave goto + help reorder fill sort update highlight unhighlight missing statistics)
 
-   "List of commands known to org-favtable:
 
- Commands known:
 
-   occur: If you supply a keyword (text): Apply emacs standard
 
-     occur operation on the table of favorites; ask for a
 
-     string (keyword) to select lines. Occur will only show you
 
-     lines which contain the given keyword, so you can easily find
 
-     the right one. You may supply a list of words seperated by
 
-     comma (\",\"), to select lines that contain any or all of the
 
-     given words.
 
-     If you supply a reference number: Apply emacs standard
 
-     multi-occur operation all org-mode buffers to search for a
 
-     specific reference.
 
-     You may also read the note at the end of this help on saving
 
-     the keystroke RET to accept this frequent default command.
 
-   head: If invoked outside the table of favorites, ask for a
 
-     reference number and search for a heading containing it. If
 
-     invoked within favtable dont ask; rather use the reference or
 
-     link from the current line.
 
-   ref: Create a new reference, copy any previously selected text.
 
-     If already within reftable, fill in ref-column.
 
-   link: Create a new line in reftable with a link to the current node.
 
-     Do not populate the ref column; this can later be populated by
 
-     calling the \"fill\" command from within the reftable.
 
-   leave: Leave the table of favorites. If the last command has
 
-     been \"ref\", the new reference is copied and ready to yank.
 
-     This \"org-mark-ring-goto\" and can be called several times
 
-     in succession.
 
-   enter: Just enter the node with the table of favorites.
 
-   goto: Search for a specific reference within the table of
 
-     favorites.
 
-   help: Show this list of commands.
 
-   +: Show all commands including the less frequently used ones
 
-     given below. If \"+\" is followd by enough letters of such a
 
-     command (e.g. \"+fi\"), then this command is invoked
 
-     directly.
 
-   reorder: Temporarily reorder the table of favorites, e.g. by
 
-     count, reference or last access.
 
-   fill: If either ref or link is missing, fill it.
 
-   sort: Sort a set of lines (either the active region or the
 
-     whole buffer) by the references found in each line.
 
-   update: For the given reference, update the line in the
 
-     favtable.
 
-   highlight: Highlight references in region or buffer.
 
-   unhighlight: Remove highlights.
 
-   missing : Search for missing reference numbers (which do not
 
-     appear in the reference table). If requested, add additional
 
-     lines for them, so that the command \"new\" is able to reuse
 
-     them.
 
-   statistics : Show some statistics (e.g. minimum and maximum
 
-     reference) about favtable.
 
- Two ways to save keystrokes:
 
- When prompting for a command, org-favtable puts the most likely
 
- one (e.g. \"occur\" or \"ref\") at the front of the list, so that
 
- you may just type RET.
 
- If this command needs additional input (like e.g. \"occur\"), you
 
- may supply this input right away, although you are still beeing
 
- prompted for the command. So do an occur for the string \"foo\",
 
- you can just enter \"foo\" without even entering \"occur\".
 
- Another way to save keystrokes applies if you want to choose a
 
- command, that requrires a reference number (and would normally
 
- prompt for it): In that case you may just enter enough characters
 
- from your command, so that it appears first in the list of
 
- matches; then immediately enter the number of the reference you
 
- are searching for. So the input \"h237\" would execute the
 
- command \"head\" for reference \"237\" right away.
 
- ")
 
- (defvar org-favtable--commands-some '(occur head ref link leave enter goto + help))
 
- (defvar org-favtable--columns nil)
 
- (defvar org-favtable-id nil
 
-   "Id of the Org-mode node, which contains the favorite table.
 
- Read below, on how to set up things. See the help options
 
- \"usage\" and \"commands\" for normal usage after setup.
 
- Setup requires two steps:
 
-  - Adjust your .emacs initialization file
 
-  - Create a suitable org-mode node
 
- Here are the lines, you need to add to your .emacs:
 
-   (require 'org-favtable)
 
-   ;; Good enough to start, but later you should probably
 
-   ;; change this id, as will be explained below
 
-   (setq org-favtable-id \"00e26bef-1929-4110-b8b4-7eb9c9ab1fd4\")
 
-   ;; Optionally assign a key. Pick your own favorite.
 
-   (global-set-key (kbd \"C-+\") 'org-favtable)
 
- Do not forget to restart emacs to make these lines effective.
 
- As a second step you need to create the org-mode node, where your
 
- reference numbers and links will be stored. It may look like
 
- this:
 
-   * org-favtable
 
-     :PROPERTIES:
 
-     :ID:       00e26bef-1929-4110-b8b4-7eb9c9ab1fd4
 
-     :END:
 
-     |     |      | Comment, description, details  |         |         |               |
 
-     | ref | link | ;c                             | count;s | created | last-accessed |
 
-     |     | <4>  | <30>                           |         |         |               |
 
-     |-----+------+--------------------------------+---------+---------+---------------|
 
-     | R1  |      | My first reference             |         |         |               |
 
- You may just copy this node into one of your org-files.  Many
 
- things however can or should be adjusted:
 
-  - The node needs not be a top level node.
 
-  - Its name is completely at you choice. The node is found
 
-    through its ID.
 
-  - There are three lines of headings above the first hline. The
 
-    first one is ignored by org-favtable, and you can use them to
 
-    give meaningful names to columns; the second line contains
 
-    configuration information for org-favtable; please read
 
-    further below for its format. The third line is optional and
 
-    may contain width-informations (e.g. <30>) only.
 
-  - The sequence of columns does not matter. You may reorder them
 
-    any way you like; e.g. make the comment-column the last
 
-    columns within the table. Columns ar found by their name,
 
-    which appears in the second heading-line.
 
-  - You can add further columns or even remove the
 
-    \"Comment\"-column. All other columns from the
 
-    example (e.g. \"ref\", \"link\", \"count\", \"created\" and
 
-    \"last-accessed\") are required.
 
-  - Your references need not start at \"R1\"; However, having an
 
-    initial row is required (it serves as a template for subsequent
 
-    references).
 
-  - Your reference need not have the form \"R1\"; you may just as
 
-    well choose any text, that contains a single number,
 
-    e.g. \"reference-{1}\" or \"#7\" or \"++17++\" or \"-344-\". The
 
-    function `org-favtable' will inspect your first reference and
 
-    create all subsequent references in the same way.
 
-  - You may want to change the ID-Property of the node above and
 
-    create a new one, which is unique (and not just a copy of
 
-    mine). You need to change it in the lines copied to your .emacs
 
-    too. However, this is not strictly required to make things
 
-    work, so you may do this later, after trying out this package.
 
- Optionally you may tweak the second header line to adjust
 
- `org-favtable' a bit. In the example above it looks like this
 
-  (with spaces collapsed):
 
-     | ref | link | ;c | count;s | created | last-accessed |
 
- The different fields have different meanings:
 
-  - ref : This denotes the column which contains you references
 
-  - link : Column for org-mode links, which can be used to access
 
-    locations within your files.
 
-  - ;c : The flag \"c\" (\"c\" for \"copy\") denotes this column
 
-    as the one beeing copied on command \"leave\". In the example
 
-    above, it is also the comment-column.
 
-  - count;s : this is the column which counts, how many time this
 
-    line has been accessed (which is the key-feature of this
 
-    package). The flag \"s\" stands for \"sort\", so the table is
 
-    sorted after this column. You may also sort after columns
 
-    \"ref\" or \"last-accessed\".
 
-  - created : Date when this line was created.
 
-  - last-accessed : Date and time, when this line was last accessed.
 
- After this two-step setup process you may invoke `org-favtable'
 
- to create a new favorite. Read the help option \"usage\" for
 
- instructions on normal usage, read the help option \"commands\"
 
- for help on single commands.
 
- ")
 
- (defvar org-favtable--text-to-yank nil)
 
- (defvar org-favtable--last-action nil)
 
- (defvar org-favtable--occur-buffer nil)
 
- (defvar org-favtable--ref-regex nil)
 
- (defvar org-favtable--ref-format nil)
 
- (defun org-favtable  (&optional what search search-is-link)
 
-   "Mark and find your favorite items and org-locations easily:
 
- Create and update a lookup table of your favorite references and
 
- links. Often used entries automatically bubble to the top of the
 
- table; entering some keywords narrows it to just the matching
 
- entries; that way the right one can be picked easily.
 
- References are essentially small numbers (e.g. \"R237\" or
 
- \"-455-\"), as created by this package; links are normal org-mode
 
- links. Within org-favtable, both are denoted as favorites.
 
- Read below for a detailed description of this function. See the
 
- help option \"setup\" or read the documentation of
 
- `org-favtable-id' for setup instructions.
 
- The function `org-favtable' operates on a dedicated table (called
 
- the table or favorites or favtable, for short) within a special
 
- Org-mode node. The node has to be created as part of your initial
 
- setup. Each line of the favorite table contains:
 
-  - A reference (optional)
 
-  - A link (optional)
 
-  - A number; counting, how often each reference has been
 
-    used. This number is updated automatically and the table can
 
-    be sorted according to it, so that most frequently used
 
-    references appear at the top of the table and can be spotted
 
-    easily.
 
-  - Its respective creation date
 
-  - Date and time of last access. This column can alternatively be
 
-    used to sort the table.
 
- To be useful, your table of favorites should probably contain a
 
- column with comments too, which allows lines to be selected by
 
- keywords.
 
- The table of favorites is found through the id of the containing
 
- node; this id should be stored within `org-favtable-id' (see there
 
- for details).
 
- The function `org-favtable' is the only interactive function of
 
- this package and its sole entry point; it offers several commands
 
- to create, find and look up these favorites (references and
 
- links). All of them are explained within org-favtable's help.
 
- Finally, org-favtable can also be invoked from elisp; the two
 
- optional arguments accepted are:
 
-          search : string to search for
 
-            what : symbol of the command to invoke
 
-  search-is-link : t, if argument search is actually a link
 
- An example would be:
 
-  (org-favtable \"237\" 'head)   ;; find heading with ref 237
 
- "
 
-   (interactive "P")
 
-   (let (within-node        ; True, if we are within node with favtable
 
-         result-is-visible  ; True, if node or occur is visible in any window
 
-         ref-node-buffer-and-point ; cons with buffer and point of favorites node
 
-         below-cursor              ; word below cursor
 
-         active-region             ; active region (if any)
 
-         link-id                   ; link of starting node, if required
 
-         guarded-search            ; with guard against additional digits
 
-         search-is-ref             ; true, if search is a reference
 
-         commands                ; currently active set of selectable commands
 
-         what-adjusted           ; True, if we had to adjust what
 
-         what-input    ; Input on what question (need not necessary be "what")
 
-         reorder-once  ; Column to use for single time sorting
 
-         parts         ; Parts of a typical reference number (which
 
-                                                   ; need not be a plain number); these are:
 
-         head               ; Any header before number (e.g. "R")
 
-         maxref             ; Maximum number from reference table (e.g. "153")
 
-         tail               ; Tail after number (e.g. "}" or "")
 
-         ref-regex          ; Regular expression to match a reference
 
-         has-reuse          ; True, if table contains a line for reuse
 
-         numcols            ; Number of columns in favtable
 
-         kill-new-text      ; Text that will be appended to kill ring
 
-         message-text       ; Text that will be issued as an explanation,
 
-                            ; what we have done
 
-         initial-ref-or-link      ; Initial position in reftable
 
-         )
 
-     ;;
 
-     ;; Examine current buffer and location, before turning to favtable
 
-     ;;
 
-     ;; Get the content of the active region or the word under cursor
 
-     (if (and transient-mark-mode
 
-              mark-active)
 
-         (setq active-region (buffer-substring (region-beginning) (region-end))))
 
-     (setq below-cursor (thing-at-point 'symbol))
 
-     ;; Find out, if we are within favable or not
 
-     (setq within-node (string= (org-id-get) org-favtable-id))
 
-     ;; Find out, if point in any window is within node with favtable
 
-     (mapc (lambda (x) (with-current-buffer (window-buffer x)
 
-                         (when (or
 
-                                (string= (org-id-get) org-favtable-id)
 
-                                (eq (window-buffer x)
 
-                                    org-favtable--occur-buffer))
 
-                           (setq result-is-visible t))))
 
-           (window-list))
 
-     ;;
 
-     ;; Get decoration of references and highest reference from favtable
 
-     ;;
 
-     ;; Save initial ref or link
 
-     (if (and within-node
 
-              (org-at-table-p))
 
-         (setq initial-ref-or-link
 
-               (or (org-favtable--get-field 'ref)
 
-                   (org-favtable--get-field 'link))))
 
-     ;; Find node
 
-     (setq ref-node-buffer-and-point (org-favtable--id-find))
 
-     (unless ref-node-buffer-and-point
 
-       (org-favtable--report-setup-error
 
-        (format "Cannot find node with id \"%s\"" org-favtable-id)))
 
-     ;; Get configuration of reftable; catch errors
 
-     (let ((error-message
 
-            (catch 'content-error
 
-              (with-current-buffer (car ref-node-buffer-and-point)
 
-                (save-excursion
 
-                  (unless (string= (org-id-get) org-favtable-id)
 
-                    (goto-char (cdr ref-node-buffer-and-point)))
 
-                  ;; parse table while still within buffer
 
-                  (setq parts (org-favtable--parse-and-adjust-table)))
 
-                nil))))
 
-       (when error-message
 
-         (org-pop-to-buffer-same-window (car ref-node-buffer-and-point))
 
-         (org-reveal)
 
-         (error error-message)))
 
-     ;; Give names to parts of configuration
 
-     (setq head (nth 0 parts))
 
-     (setq maxref (nth 1 parts))
 
-     (setq tail (nth 2 parts))
 
-     (setq numcols (nth 3 parts))
 
-     (setq ref-regex (nth 4 parts))
 
-     (setq has-reuse (nth 5 parts))
 
-     (setq org-favtable--ref-regex ref-regex)
 
-     (setq org-favtable--ref-format (concat head "%d" tail))
 
-     ;;
 
-     ;; Find out, what we are supposed to do
 
-     ;;
 
-     (if (equal what '(4)) (setq what 'leave))
 
-     ;; Set preferred action, that will be the default choice
 
-     (setq org-favtable--preferred-command
 
-           (if within-node
 
-               (if (memq org-favtable--last-action '(ref link))
 
-                   'leave
 
-                 'occur)
 
-             (if active-region
 
-                 'ref
 
-               (if (and below-cursor (string-match ref-regex below-cursor))
 
-                   'occur
 
-                 nil))))
 
-     ;; Ask user, what to do
 
-     (unless what
 
-       (setq commands (copy-list org-favtable--commands-some))
 
-       (while (progn
 
-                (setq what-input
 
-                      (org-icompleting-read
 
-                       "Please choose: "
 
-                       (mapcar 'symbol-name
 
-                               ;; Construct unique list of commands with
 
-                               ;; preferred one at front
 
-                               (delq nil (delete-dups
 
-                                          (append
 
-                                           (list org-favtable--preferred-command)
 
-                                           commands))))
 
-                       nil nil))
 
-                ;; if input starts with "+", any command (not only some) may follow
 
-                ;; this allows input like "+sort" to be accepted
 
-                (when (string= (substring what-input 0 1) "+")
 
-                  ;; make all commands available for selection
 
-                  (setq commands (copy-list org-favtable--commands))
 
-                  (unless (string= what-input "+")
 
-                    ;; not just "+", use following string
 
-                    (setq what-input (substring what-input 1))
 
-                    (let ((completions
 
-                           ;; get list of possible completions for what-input
 
-                           (all-completions what-input (mapcar 'symbol-name commands))))
 
-                      ;; use it, if unambigously
 
-                      (if (= (length completions) 1)
 
-                          (setq what-input (car completions))))))
 
-                ;; if input ends in digits, save them away and do completions on head of input
 
-                ;; this allows input like "h224" to be accepted
 
-                (when (string-match "^\\([^0-9+]\\)\\([0-9]+\\)\\s *$" what-input)
 
-                  ;; use first match as input, even if ambigously
 
-                  (setq org-favtable--preferred-command
 
-                        (intern (first (all-completions (match-string 1 what-input)
 
-                                                        (mapcar 'symbol-name commands)))))
 
-                  ;; use digits as argument to commands
 
-                  (setq what-input (format org-favtable--ref-format
 
-                                           (string-to-number (match-string 2 what-input)))))
 
-                (setq what (intern what-input))
 
-                ;; user is not required to input one of the commands; if
 
-                ;; not, take the first one and use the original input for
 
-                ;; next question
 
-                (if (memq what commands)
 
-                    ;; input matched one element of list, dont need original
 
-                    ;; input any more
 
-                    (setq what-input nil)
 
-                  ;; what-input will be used for next question, use first
 
-                  ;; command for what
 
-                  (setq what (or org-favtable--preferred-command
 
-                                 (first commands)))
 
-                  ;; remove any trailing dot, that user might have added to
 
-                  ;; disambiguate his input
 
-                  (if (equal (substring what-input -1) ".")
 
-                      ;; but do this only, if dot was really necessary to
 
-                      ;; disambiguate
 
-                      (let ((shortened-what-input (substring what-input 0 -1)))
 
-                        (unless (test-completion shortened-what-input
 
-                                                 (mapcar 'symbol-name
 
-                                                         commands))
 
-                          (setq what-input shortened-what-input)))))
 
-                ;; ask for reorder in loop, because we have to ask for
 
-                ;; what right again
 
-                (if (eq what 'reorder)
 
-                    (setq reorder-once
 
-                          (intern
 
-                           (org-icompleting-read
 
-                            "Please choose column to reorder reftable once: "
 
-                            (mapcar 'symbol-name '(ref count last-accessed))
 
-                            nil t))))
 
-                ;; maybe ask initial question again
 
-                (memq what '(reorder +)))))
 
-     ;;
 
-     ;; Get search, if required
 
-     ;;
 
-     ;; These actions need a search string:
 
-     (when (memq what '(goto occur head update))
 
-       ;; Maybe we've got a search string from the arguments
 
-       (unless search
 
-         (let (search-from-table
 
-               search-from-cursor)
 
-           ;; Search string can come from several sources:
 
-           ;; From ref column of table
 
-           (when within-node
 
-             (setq search-from-table (org-favtable--get-field 'ref)))
 
-           ;; From string below cursor
 
-           (when (and (not within-node)
 
-                      below-cursor
 
-                      (string-match (concat "\\(" ref-regex "\\)")
 
-                                    below-cursor))
 
-             (setq search-from-cursor (match-string 1 below-cursor)))
 
-           ;; Depending on requested action, get search from one of the sources above
 
-           (cond ((eq what 'goto)
 
-                  (setq search (or what-input search-from-cursor)))
 
-                 ((memq what '(head occur))
 
-                  (setq search (or what-input search-from-table search-from-cursor))))))
 
-       ;; If we still do not have a search string, ask user explicitly
 
-       (unless search
 
-         (if what-input
 
-             (setq search what-input)
 
-           (setq search (read-from-minibuffer
 
-                         (cond ((memq what '(occur head))
 
-                                "Text or reference number to search for: ")
 
-                               ((eq what 'goto)
 
-                                "Reference number to search for, or enter \".\" for id of current node: ")
 
-                               ((eq what 'update)
 
-                                "Reference number to update: ")))))
 
-         (if (string-match "^\\s *[0-9]+\\s *$" search)
 
-             (setq search (format "%s%s%s" head (org-trim search) tail))))
 
-       ;; Clean up and examine search string
 
-       (if search (setq search (org-trim search)))
 
-       (if (string= search "") (setq search nil))
 
-       (setq search-is-ref (string-match ref-regex search))
 
-       ;; Check for special case
 
-       (when (and (memq what '(head goto))
 
-                  (string= search "."))
 
-         (setq search (org-id-get))
 
-         (setq search-is-link t))
 
-       (when search-is-ref
 
-         (setq guarded-search (org-favtable--make-guarded-search search)))
 
-       ;;
 
-       ;; Do some sanity checking before really starting
 
-       ;;
 
-       ;; Correct requested action, if nothing to search
 
-       (when (and (not search)
 
-                  (memq what '(search occur head)))
 
-         (setq what 'enter)
 
-         (setq what-adjusted t))
 
-       ;; For a proper reference as input, we do multi-occur
 
-       (if (and (string-match ref-regex search)
 
-                (eq what 'occur))
 
-           (setq what 'multi-occur))
 
-       ;; Check for invalid combinations of arguments; try to be helpful
 
-       (when (and (memq what '(head goto))
 
-                  (not search-is-link)
 
-                  (not search-is-ref))
 
-         (error "Can do '%s' only for a reference or link (not '%s'), try 'occur' to search for text" what search)))
 
-     ;;
 
-     ;; Prepare
 
-     ;;
 
-     ;; Get link if required before moving in
 
-     (if (eq what 'link)
 
-         (setq link-id (org-id-get-create)))
 
-     ;; Move into table, if outside
 
-     (when (memq what '(enter ref link goto occur multi-occur missing statistics))
 
-       ;; Support orgmode-standard of going back (buffer and position)
 
-       (org-mark-ring-push)
 
-       ;; Switch to favtable
 
-       (org-pop-to-buffer-same-window (car ref-node-buffer-and-point))
 
-       (goto-char (cdr ref-node-buffer-and-point))
 
-       (show-subtree)
 
-       (org-show-context)
 
-       ;; sort favtable
 
-       (org-favtable--sort-table reorder-once))
 
-     ;; Goto back to initial ref, because reformatting of table above might
 
-     ;; have moved point
 
-     (when initial-ref-or-link
 
-       (while (and (org-at-table-p)
 
-                   (not (or
 
-                         (string= initial-ref-or-link (org-favtable--get-field 'ref))
 
-                         (string= initial-ref-or-link (org-favtable--get-field 'link)))))
 
-         (forward-line))
 
-       ;; did not find ref, go back to top
 
-       (if (not (org-at-table-p)) (goto-char top)))
 
-     ;;
 
-     ;; Actually do, what is requested
 
-     ;;
 
-     (cond
 
-      ((eq what 'help)
 
-       (let ((help-what
 
-              ;; which sort of help ?
 
-              (intern
 
-               (concat
 
-                "help-"
 
-                (org-icompleting-read
 
-                 "Help on: "
 
-                 (mapcar 'symbol-name '(commands usage setup version example))
 
-                 nil t)))))
 
-         ;; help is taken from docstring of functions or variables
 
-         (cond ((eq help-what 'help-commands)
 
-                (org-favtable--show-help 'org-favtable--commands))
 
-               ((eq help-what 'help-usage)
 
-                (org-favtable--show-help 'org-favtable))
 
-               ((eq help-what 'help-setup)
 
-                (org-favtable--show-help 'org-favtable-id))
 
-               ((eq help-what 'help-version)
 
-                (org-favtable-version)))))
 
-      ((eq what 'multi-occur)
 
-       ;; Conveniently position cursor on number to search for
 
-       (org-favtable--goto-top)
 
-       (let (found (initial (point)))
 
-         (while (and (not found)
 
-                     (forward-line)
 
-                     (org-at-table-p))
 
-           (save-excursion
 
-             (setq found (string= search
 
-                                  (org-favtable--get-field 'ref)))))
 
-         (if found
 
-             (org-favtable--update-line nil)
 
-           (goto-char initial)))
 
-       ;; Construct list of all org-buffers
 
-       (let (buff org-buffers)
 
-         (dolist (buff (buffer-list))
 
-           (set-buffer buff)
 
-           (if (string= major-mode "org-mode")
 
-               (setq org-buffers (cons buff org-buffers))))
 
-         ;; Do multi-occur
 
-         (multi-occur org-buffers guarded-search)
 
-         (if (get-buffer "*Occur*")
 
-             (progn
 
-               (setq message-text (format "multi-occur for '%s'" search))
 
-               (setq org-favtable--occur-buffer (get-buffer "*Occur*"))
 
-               (other-window 1)
 
-               (toggle-truncate-lines 1))
 
-           (setq message-text (format "Did not find '%s'" search)))))
 
-      ((eq what 'head)
 
-       (let (link)
 
-         ;; link either from table or passed in as argument
 
-         ;; try to get link
 
-         (if search-is-link
 
-             (setq link (org-trim search))
 
-           (if (and within-node
 
-                    (org-at-table-p))
 
-               (setq link (org-favtable--get-field 'link))))
 
-         ;; use link if available
 
-         (if (and link
 
-                  (not (string= link "")))
 
-             (progn
 
-               (org-id-goto link)
 
-               (org-favtable--update-line search)
 
-               (setq message-text "Followed link"))
 
-           (message (format "Scanning headlines for '%s' ..." search))
 
-           (let (buffer point)
 
-             (if (catch 'found
 
-                   (progn
 
-                     ;; loop over all headlines, stop on first match
 
-                     (org-map-entries
 
-                      (lambda ()
 
-                        (when (looking-at (concat ".*" guarded-search))
 
-                          ;; remember location and bail out
 
-                          (setq buffer (current-buffer))
 
-                          (setq point (point))
 
-                          (throw 'found t)))
 
-                      nil 'agenda)
 
-                     nil))
 
-                 (progn
 
-                   (org-favtable--update-line search)
 
-                   (setq message-text (format "Found '%s'" search))
 
-                   (org-pop-to-buffer-same-window buffer)
 
-                   (goto-char point)
 
-                   (org-reveal))
 
-               (setq message-text (format "Did not find '%s'" search)))))))
 
-      ((eq what 'leave)
 
-       (when result-is-visible
 
-         ;; If we are within the occur-buffer, switch over to get current line
 
-         (if (and (string= (buffer-name) "*Occur*")
 
-                  (eq org-favtable--last-action 'occur))
 
-             (occur-mode-goto-occurrence)))
 
-       (setq kill-new-text org-favtable--text-to-yank)
 
-       (setq org-favtable--text-to-yank nil)
 
-       ;; If "leave" has been called two times in succession, make
 
-       ;; org-mark-ring-goto believe it has been called two times too
 
-       (if (eq org-favtable--last-action 'leave)
 
-           (let ((this-command nil) (last-command nil))
 
-             (org-mark-ring-goto 1))
 
-         (org-mark-ring-goto 0)))
 
-      ((eq what 'goto)
 
-       ;; Go downward in table to requested reference
 
-       (let (found (initial (point)))
 
-         (org-favtable--goto-top)
 
-         (while (and (not found)
 
-                     (forward-line)
 
-                     (org-at-table-p))
 
-           (save-excursion
 
-             (setq found
 
-                   (string= search
 
-                            (org-favtable--get-field
 
-                             (if search-is-link 'link 'ref))))))
 
-         (if found
 
-             (progn
 
-               (setq message-text (format "Found '%s'" search))
 
-               (org-favtable--update-line nil)
 
-               (org-table-goto-column (org-favtable--column-num 'ref))
 
-               (if (looking-back " ") (backward-char))
 
-               ;; remember string to copy
 
-               (setq org-favtable--text-to-yank
 
-                     (org-trim (org-table-get-field (org-favtable--column-num 'copy)))))
 
-           (setq message-text (format "Did not find '%s'" search))
 
-           (goto-char initial)
 
-           (forward-line)
 
-           (setq what 'missed))))
 
-      ((eq what 'occur)
 
-       ;; search for string: occur
 
-       (let (search-regexp
 
-             all-or-any
 
-             (search-words (split-string search "," t)))
 
-         (if (< (length search-words) 2)
 
-             ;; only one word to search; use it as is
 
-             (setq search-regexp search)
 
-           ;; construct regexp to match any of the words (maybe throw out some matches later)
 
-           (setq search-regexp
 
-                 (mapconcat (lambda (x) (concat "\\(" x "\\)")) search-words "\\|"))
 
-           (setq all-or-any
 
-                 (intern
 
-                  (org-icompleting-read
 
-                   "Two or more words have been specified; show lines, that match: " '("all" "any")))))
 
-         (save-restriction
 
-           (org-narrow-to-subtree)
 
-           (occur search-regexp)
 
-           (widen)
 
-           (if (get-buffer "*Occur*")
 
-               (with-current-buffer "*Occur*"
 
-                 ;; install helpful keyboard-shortcuts within occur-buffer
 
-                 (let ((keymap (make-sparse-keymap)))
 
-                   (set-keymap-parent keymap occur-mode-map)
 
-                   (define-key keymap (kbd "RET")
 
-                     (lambda () (interactive)
 
-                       (org-favtable--occur-helper 'head)))
 
-                   (define-key keymap (kbd "<C-return>")
 
-                     (lambda () (interactive)
 
-                       (org-favtable--occur-helper 'multi-occur)))
 
-                   (define-key keymap (kbd "<M-return>")
 
-                     (lambda () (interactive)
 
-                       (org-favtable--occur-helper 'goto)))
 
-                   (define-key keymap (kbd "<C-M-return>")
 
-                     (lambda () (interactive)
 
-                       (org-favtable--occur-helper 'update)))
 
-                   (use-local-map keymap))
 
-                 ;; Brush up occur buffer
 
-                 (other-window 1)
 
-                 (toggle-truncate-lines 1)
 
-                 (let ((inhibit-read-only t))
 
-                   ;; insert some help text
 
-                   (insert (substitute-command-keys
 
-                            "Type RET to find heading, C-RET for multi-occur, M-RET to go to occurence and C-M-RET to update line in reftable.\n\n"))
 
-                   (forward-line 1)
 
-                   ;; when matching all of multiple words, remove all lines that do not match one of the words
 
-                   (when (eq all-or-any 'all)
 
-                     (mapc (lambda (x) (keep-lines x)) search-words))
 
-                   ;; replace description from occur
 
-                   (when all-or-any
 
-                     (forward-line -1)
 
-                     (kill-line)
 
-                     (let ((count (- (count-lines (point) (point-max)) 1)))
 
-                       (insert (format "%d %s for %s of %s"
 
-                                       count
 
-                                       (if (= count 1) "match" "matches")
 
-                                       all-or-any
 
-                                       search)))
 
-                     (forward-line)
 
-                     (beginning-of-line))
 
-                   ;; Record link or reference for each line in
 
-                   ;; occur-buffer, that is linked into reftable. Because if
 
-                   ;; we later realign the reftable and then reuse the occur
 
-                   ;; buffer, the original links might point nowehere.
 
-                   (save-excursion
 
-                     (while (not (eq (point) (point-max)))
 
-                       (let ((beg (line-beginning-position))
 
-                             (end (line-end-position))
 
-                             pos ref link)
 
-                         ;; occur has saved the position into a special property
 
-                         (setq pos (get-text-property (point) 'occur-target))
 
-                         (when pos
 
-                           ;; but this property might soon point nowhere; so retrieve ref-or-link instead
 
-                           (with-current-buffer (marker-buffer pos)
 
-                             (goto-char pos)
 
-                             (setq ref (org-favtable--get-field 'ref))
 
-                             (setq link (org-favtable--get-field 'link))))
 
-                         ;; save as text property
 
-                         (put-text-property beg end 'org-favtable--ref ref)
 
-                         (put-text-property beg end 'org-favtable--link link))
 
-                       (forward-line))))
 
-                 (setq message-text
 
-                       (format  "Occur for '%s'" search)))
 
-             (setq message-text
 
-                   (format "Did not find any matches for '%s'" search))))))
 
-      ((memq what '(ref link))
 
-       ;; add a new row (or reuse existing one)
 
-       (let (new)
 
-         (when (eq what 'ref)
 
-             ;; go through table to find first entry to be reused
 
-           (when has-reuse
 
-             (org-favtable--goto-top)
 
-             ;; go through table
 
-             (while (and (org-at-table-p)
 
-                         (not new))
 
-               (when (string=
 
-                      (org-favtable--get-field 'count)
 
-                      ":reuse:")
 
-                 (setq new (org-favtable--get-field 'ref))
 
-                 (if new (org-table-kill-row)))
 
-               (forward-line)))
 
-           ;; no ref to reuse; construct new reference
 
-           (unless new
 
-             (setq new (format "%s%d%s" head (1+ maxref) tail)))
 
-           ;; remember for org-mark-ring-goto
 
-           (setq org-favtable--text-to-yank new))
 
-         ;; insert ref or link as very first row
 
-         (org-favtable--goto-top)
 
-         (org-table-insert-row)
 
-         ;; fill special columns with standard values
 
-         (when (eq what 'ref)
 
-           (org-table-goto-column (org-favtable--column-num 'ref))
 
-           (insert new))
 
-         (when (eq what 'link)
 
-           (org-table-goto-column (org-favtable--column-num 'link))
 
-           (insert link-id))
 
-         (org-table-goto-column (org-favtable--column-num 'created))
 
-         (org-insert-time-stamp nil nil t)
 
-         ;; goto first empty field
 
-         (unless (catch 'empty
 
-                   (dotimes (col numcols)
 
-                     (org-table-goto-column (+ col 1))
 
-                     (if (string= (org-trim (org-table-get-field)) "")
 
-                         (throw 'empty t))))
 
-           ;; none found, goto first
 
-           (org-table-goto-column 1))
 
-         (org-table-align)
 
-         (if active-region (setq kill-new-text active-region))
 
-         (if (eq what 'ref)
 
-             (setq message-text (format "Adding a new row with ref '%s'" new))
 
-           (setq message-text (format "Adding a new row linked to '%s'" link-id)))))
 
-      ((eq what 'enter)
 
-       ;; simply go into table
 
-       (org-favtable--goto-top)
 
-       (show-subtree)
 
-       (recenter)
 
-       (if what-adjusted
 
-           (setq message-text "Nothing to search for; at favtable")
 
-         (setq message-text "At favtable")))
 
-      ((eq what 'fill)
 
-       ;; check, if within reftable
 
-       (unless (and within-node
 
-                    (org-at-table-p))
 
-         (error "Not within table of favorites"))
 
-       ;; applies to missing refs and missing links alike
 
-       (let ((ref (org-favtable--get-field 'ref))
 
-             (link (org-favtable--get-field 'link)))
 
-         (if (and (not ref)
 
-                  (not link))
 
-             ;; have already checked this during parse, check here anyway
 
-             (error "Columns ref and link are both empty in this line"))
 
-         ;; fill in new ref
 
-         (if (not ref)
 
-             (progn
 
-               (setq kill-new-text (format "%s%d%s" head (1+ maxref) tail))
 
-               (org-favtable--get-field 'ref kill-new-text)
 
-               ;; remember for org-mark-ring-goto
 
-               (setq org-favtable--text-to-yank kill-new-text)
 
-               (org-id-goto link)
 
-               (setq message-text "Filled reftable field with new reference"))
 
-           ;; fill in new link
 
-           (if (not link)
 
-               (progn
 
-                 (setq guarded-search (org-favtable--make-guarded-search ref))
 
-                 (message (format "Scanning headlines for '%s' ..." ref))
 
-                 (let (link)
 
-                   (if (catch 'found
 
-                         (org-map-entries
 
-                          (lambda ()
 
-                            (when (looking-at (concat ".*" guarded-search))
 
-                              (setq link (org-id-get-create))
 
-                              (throw 'found t)))
 
-                          nil 'agenda)
 
-                         nil)
 
-                       (progn
 
-                         (org-favtable--get-field 'link link)
 
-                         (setq message-text "Inserted link"))
 
-                     (setq message-text (format "Did not find reference '%s'" ref)))))
 
-             ;; nothing is missing
 
-             (setq message-text "Columns 'ref' and 'link' are already filled; nothing to do")))))
 
-      ((eq what 'sort)
 
-       ;; sort lines according to contained reference
 
-       (let (begin end where)
 
-         (catch 'aborted
 
-           ;; either active region or whole buffer
 
-           (if (and transient-mark-mode
 
-                    mark-active)
 
-               ;; sort only region
 
-               (progn
 
-                 (setq begin (region-beginning))
 
-                 (setq end (region-end))
 
-                 (setq where "region"))
 
-             ;; sort whole buffer
 
-             (setq begin (point-min))
 
-             (setq end (point-max))
 
-             (setq where "whole buffer")
 
-             ;; make sure
 
-             (unless (y-or-n-p "Sort whole buffer ")
 
-               (setq message-text "Sort aborted")
 
-               (throw 'aborted nil)))
 
-           (save-excursion
 
-             (save-restriction
 
-               (goto-char (point-min))
 
-               (narrow-to-region begin end)
 
-               (sort-subr nil 'forward-line 'end-of-line
 
-                          (lambda ()
 
-                            (if (looking-at (concat ".*"
 
-                                                    (org-favtable--make-guarded-search ref-regex 'dont-quote)))
 
-                                (string-to-number (match-string 1))
 
-                              0))))
 
-             (highlight-regexp ref-regex)
 
-             (setq message-text (format "Sorted %s from character %d to %d, %d lines"
 
-                                        where begin end
 
-                                        (count-lines begin end)))))))
 
-      ((eq what 'update)
 
-       ;; simply update line in reftable
 
-       (save-excursion
 
-         (let ((ref-or-link (if search-is-link "link" "reference")))
 
-           (beginning-of-line)
 
-           (if (org-favtable--update-line search)
 
-               (setq message-text (format "Updated %s '%s'" ref-or-link search))
 
-             (setq message-text (format "Did not find %s '%s'" ref-or-link search))))))
 
-      ((eq what 'parse)
 
-       ;; Just parse the reftable, which is already done, so nothing to do
 
-       )
 
-      ((memq what '(highlight unhighlight))
 
-       (let ((where "buffer"))
 
-         (save-excursion
 
-           (save-restriction
 
-             (when (and transient-mark-mode
 
-                        mark-active)
 
-               (narrow-to-region (region-beginning) (region-end))
 
-               (setq where "region"))
 
-             (if (eq what 'highlight)
 
-                 (progn
 
-                   (highlight-regexp ref-regex)
 
-                   (setq message-text (format "Highlighted references in %s" where)))
 
-               (unhighlight-regexp ref-regex)
 
-               (setq message-text (format "Removed highlights for references in %s" where)))))))
 
-      ((memq what '(missing statistics))
 
-       (org-favtable--goto-top)
 
-       (let (missing
 
-             ref-field
 
-             ref
 
-             min
 
-             max
 
-             (total 0))
 
-         ;; start with list of all references
 
-         (setq missing (mapcar (lambda (x) (format "%s%d%s" head x tail))
 
-                               (number-sequence 1 maxref)))
 
-         ;; go through table and remove all refs, that we see
 
-         (while (and (forward-line)
 
-                     (org-at-table-p))
 
-           ;; get ref-field and number
 
-           (setq ref-field (org-favtable--get-field 'ref))
 
-           (if (and ref-field
 
-                    (string-match ref-regex ref-field))
 
-               (setq ref (string-to-number (match-string 1 ref-field))))
 
-           ;; remove existing refs from list
 
-           (if ref-field (setq missing (delete ref-field missing)))
 
-           ;; record min and max
 
-           (if (or (not min) (< ref min)) (setq min ref))
 
-           (if (or (not max) (> ref max)) (setq max ref))
 
-           ;; count
 
-           (setq total (1+ total)))
 
-         ;; insert them, if requested
 
-         (forward-line -1)
 
-         (if (eq what 'statistics)
 
-             (setq message-text (format "Found %d references from %s to %s. %d references below highest do not appear in table. "
 
-                                        total
 
-                                        (format org-favtable--format min)
 
-                                        (format org-favtable--format max)
 
-                                        (length missing)))
 
-           (if (y-or-n-p (format "Found %d missing references; do you wish to append them to the table of favorites"
 
-                                 (length missing)))
 
-               (let (type)
 
-                 (setq type (org-icompleting-read
 
-                             "Insert new lines for reuse by command \"new\" or just as missing ? " '("reuse" "missing")))
 
-                 (mapc (lambda (x)
 
-                         (let (org-table-may-need-update) (org-table-insert-row t))
 
-                         (org-favtable--get-field 'ref x)
 
-                         (org-favtable--get-field 'count (format ":%s:" type)))
 
-                       missing)
 
-                 (org-table-align)
 
-                 (setq message-text (format "Inserted %d new lines for missing refernces" (length missing))))
 
-             (setq message-text (format "%d missing references." (length missing)))))))
 
-      (t (error "This is a bug: unmatched case '%s'" what)))
 
-     ;; remember what we have done for next time
 
-     (setq org-favtable--last-action what)
 
-     ;; tell, what we have done and what can be yanked
 
-     (if kill-new-text (setq kill-new-text
 
-                             (substring-no-properties kill-new-text)))
 
-     (if (string= kill-new-text "") (setq kill-new-text nil))
 
-     (let ((m (concat
 
-               message-text
 
-               (if (and message-text kill-new-text)
 
-                   " and r"
 
-                 (if kill-new-text "R" ""))
 
-               (if kill-new-text (format "eady to yank '%s'" kill-new-text) ""))))
 
-       (unless (string= m "") (message m)))
 
-     (if kill-new-text (kill-new kill-new-text))))
 
- (defun org-favtable--parse-and-adjust-table ()
 
-   (let ((maxref 0)
 
-         top
 
-         bottom
 
-         ref-field
 
-         link-field
 
-         parts
 
-         numcols
 
-         head
 
-         tail
 
-         ref-regex
 
-         has-reuse
 
-         initial-point)
 
-     (setq initial-point (point))
 
-     (org-favtable--goto-top)
 
-     (setq top (point))
 
-     (goto-char top)
 
-     ;; count columns
 
-     (org-table-goto-column 100)
 
-     (setq numcols (- (org-table-current-column) 1))
 
-     ;; get contents of columns
 
-     (forward-line -2)
 
-     (unless (org-at-table-p)
 
-       (org-favtable--report-setup-error
 
-        "Table of favorites starts with a hline" t))
 
-     ;; check for optional line consisting solely of width specifications
 
-     (beginning-of-line)
 
-     (if (looking-at "\\s *|\\(\\(\\s *|\\)\\|\\(\\s *<[0-9]+>\\s *|\\)\\)+\\s *$")
 
-         (forward-line -1))
 
-     (org-table-goto-column 1)
 
-     (setq org-favtable--columns (org-favtable--parse-headings numcols))
 
-     ;; Go beyond end of table
 
-     (while (org-at-table-p) (forward-line 1))
 
-     ;; Kill all empty rows at bottom
 
-     (while (progn
 
-              (forward-line -1)
 
-              (org-table-goto-column 1)
 
-              (and
 
-               (not (org-favtable--get-field 'ref))
 
-               (not (org-favtable--get-field 'link))))
 
-       (org-table-kill-row))
 
-     (forward-line)
 
-     (setq bottom (point))
 
-     (forward-line -1)
 
-     ;; Retrieve any decorations around the number within the first nonempty ref-field
 
-     (goto-char top)
 
-     (while (and (org-at-table-p)
 
-                 (not (setq ref-field (org-favtable--get-field 'ref))))
 
-       (forward-line))
 
-     ;; Some Checking
 
-     (unless ref-field
 
-       (org-favtable--report-setup-error
 
-        "No line of reference column contains a number" t))
 
-     (unless (string-match "^\\([^0-9]*\\)\\([0-9]+\\)\\([^0-9]*\\)$" ref-field)
 
-       (org-favtable--report-setup-error
 
-        (format "First reference in table table of favorites ('%s') does not contain a number" ref-field) t))
 
-     ;; These are the decorations used within the first ref of favtable
 
-     (setq head (match-string 1 ref-field))
 
-     (setq tail (match-string 3 ref-field))
 
-     (setq ref-regex (concat (regexp-quote head)
 
-                             "\\([0-9]+\\)"
 
-                             (regexp-quote tail)))
 
-     ;; Go through table to find maximum number and do some checking
 
-     (let ((ref 0))
 
-       (while (org-at-table-p)
 
-         (setq ref-field (org-favtable--get-field 'ref))
 
-         (setq link-field (org-favtable--get-field 'link))
 
-         (if (and (not ref-field)
 
-                  (not link-field))
 
-             (throw 'content-error "Columns ref and link are both empty in this line"))
 
-         (if ref-field
 
-             (if (string-match ref-regex ref-field)
 
-                 ;; grab number
 
-                 (setq ref (string-to-number (match-string 1 ref-field)))
 
-               (throw 'content-error "Column ref does not contain a number")))
 
-         ;; check, if higher ref
 
-         (if (> ref maxref) (setq maxref ref))
 
-         ;; check if ref is ment for reuse
 
-         (if (string= (org-favtable--get-field 'count) ":reuse:")
 
-             (setq has-reuse 1))
 
-         (forward-line 1)))
 
-     ;; sort used to be here
 
-     (setq parts (list head maxref tail numcols ref-regex has-reuse))
 
-     ;; go back to top of table
 
-     (goto-char top)
 
-     parts))
 
- (defun org-favtable--sort-table (sort-column)
 
-   (unless sort-column (setq sort-column (org-favtable--column-num 'sort)))
 
-   (let (top
 
-         bottom
 
-         ref-field
 
-         count-field
 
-         count-special)
 
-     ;; get boundaries of table
 
-     (org-favtable--goto-top)
 
-     (forward-line 0)
 
-     (setq top (point))
 
-     (while (org-at-table-p) (forward-line))
 
-     (setq bottom (point))
 
-     (save-restriction
 
-       (narrow-to-region top bottom)
 
-       (goto-char top)
 
-       (sort-subr t
 
-                  'forward-line
 
-                  'end-of-line
 
-                  (lambda ()
 
-                    (let (ref
 
-                          (ref-field (or (org-favtable--get-field 'ref) ""))
 
-                          (count-field (or (org-favtable--get-field 'count) ""))
 
-                          (count-special 0))
 
-                      ;; get reference with leading zeroes, so it can be
 
-                      ;; sorted as text
 
-                      (string-match org-favtable--ref-regex ref-field)
 
-                      (setq ref (format
 
-                                 "%06d"
 
-                                 (string-to-number
 
-                                  (or (match-string 1 ref-field)
 
-                                      "0"))))
 
-                      ;; find out, if special token in count-column
 
-                      (setq count-special (format "%d"
 
-                                                  (- 2
 
-                                                     (length (member count-field '(":missing:" ":reuse:"))))))
 
-                      ;; Construct different sort-keys according to
 
-                      ;; requested sort column; prepend count-special to
 
-                      ;; sort special entries at bottom of table, append ref
 
-                      ;; as a secondary sort key
 
-                      (cond
 
-                       ((eq sort-column 'count)
 
-                        (concat count-special
 
-                                (format
 
-                                 "%08d"
 
-                                 (string-to-number (or (org-favtable--get-field 'count)
 
-                                                       "")))
 
-                                ref))
 
-                       ((eq sort-column 'last-accessed)
 
-                        (concat count-special
 
-                                (org-favtable--get-field 'last-accessed)
 
-                                " "
 
-                                ref))
 
-                       ((eq sort-column 'ref)
 
-                        (concat count-special
 
-                                ref))
 
-                       (t (error "This is a bug: unmatched case '%s'" sort-column)))))
 
-                  nil 'string<)))
 
-   ;; align table
 
-   (org-table-align))
 
- (defun org-favtable--goto-top ()
 
-   ;; go to heading of node
 
-   (while (not (org-at-heading-p)) (forward-line -1))
 
-   (forward-line 1)
 
-   ;; go to table within node, but make sure we do not get into another node
 
-   (while (and (not (org-at-heading-p))
 
-               (not (org-at-table-p))
 
-               (not (eq (point) (point-max))))
 
-     (forward-line 1))
 
-   ;; check, if there really is a table
 
-   (unless (org-at-table-p)
 
-     (org-favtable--report-setup-error
 
-      (format "Cannot find favtable within node %s" org-favtable-id) t))
 
-   ;; go to first hline
 
-   (while (and (not (org-at-table-hline-p))
 
-               (org-at-table-p))
 
-     (forward-line 1))
 
-   ;; and check
 
-   (unless (org-at-table-hline-p)
 
-     (org-favtable--report-setup-error
 
-      "Cannot find hline within table of favorites" t))
 
-   (forward-line 1)
 
-   (org-table-goto-column 1))
 
- (defun org-favtable--id-find ()
 
-   "Find org-favtable-id"
 
-   (let ((marker (org-id-find org-favtable-id 'marker))
 
-         marker-and-buffer)
 
-     (if marker
 
-         (progn
 
-           (setq marker-and-buffer (cons (marker-buffer marker) (marker-position marker)))
 
-           (move-marker marker nil)
 
-           marker-and-buffer)
 
-       nil)))
 
- (defun org-favtable--parse-headings (numcols)
 
-   (let (columns)
 
-     ;; Associate names of special columns with column-numbers
 
-     (setq columns (copy-tree '((ref . 0) (link . 0) (created . 0) (last-accessed . 0)
 
-                                (count . 0) (sort . nil) (copy . nil))))
 
-     ;; For each column
 
-     (dotimes (col numcols)
 
-       (let* (field-flags ;; raw heading, consisting of file name and maybe
 
-                          ;; flags (seperated by ";")
 
-              field       ;; field name only
 
-              field-symbol ;; and as a symbol
 
-              flags       ;; flags from field-flags
 
-              found)
 
-         ;; parse field-flags into field and flags
 
-         (setq field-flags (org-trim (org-table-get-field (+ col 1))))
 
-         (if (string-match "^\\([^;]*\\);\\([a-z]+\\)$" field-flags)
 
-             (progn
 
-               (setq field (downcase (or (match-string 1 field-flags) "")))
 
-               ;; get flags as list of characters
 
-               (setq flags (mapcar 'string-to-char
 
-                                   (split-string
 
-                                    (downcase (match-string 2 field-flags))
 
-                                    "" t))))
 
-           ;; no flags
 
-           (setq field field-flags))
 
-         (unless (string= field "") (setq field-symbol (intern (downcase field))))
 
-         ;; Check, that no flags appear twice
 
-         (mapc (lambda (x)
 
-                 (when (memq (car x) flags)
 
-                   (if (cdr (assoc (cdr x) columns))
 
-                       (org-favtable--report-setup-error
 
-                        (format "More than one heading is marked with flag '%c'" (car x)) t))))
 
-               '((?s . sort)
 
-                 (?c . copy)))
 
-         ;; Process flags
 
-         (if (memq ?s flags)
 
-             (setcdr (assoc 'sort columns) field-symbol))
 
-         (if (memq ?c flags)
 
-             (setcdr (assoc 'copy columns) (+ col 1)))
 
-         ;; Store columns in alist
 
-         (setq found (assoc field-symbol columns))
 
-         (when found
 
-           (if (> (cdr found) 0)
 
-               (org-favtable--report-setup-error
 
-                (format "'%s' appears two times as column heading" (downcase field)) t))
 
-           (setcdr found (+ col 1)))))
 
-     ;; check if all necessary informations have been specified
 
-     (mapc (lambda (col)
 
-             (unless (> (cdr (assoc col columns)) 0)
 
-               (org-favtable--report-setup-error
 
-                (format "column '%s' has not been set" col) t)))
 
-           '(ref link count created last-accessed))
 
-     ;; use ref as a default sort-column
 
-     (unless (cdr (assoc 'sort columns))
 
-       (setcdr (assoc 'sort columns) 'ref))
 
-     columns))
 
- (defun org-favtable--report-setup-error (text &optional switch-to-node)
 
-   (when switch-to-node
 
-     (org-id-goto org-favtable-id)
 
-     (delete-other-windows))
 
-   (when (y-or-n-p (concat
 
-                    text
 
-                    ";\n"
 
-                    "the correct setup is explained in the documentation of 'org-favtable-id'.\n"
 
-                    "Do you want to read it ? "))
 
-     (org-favtable--show-help 'org-favtable-id))
 
-   (error "")
 
-   (setq org-favtable--last-action 'leave))
 
- (defun org-favtable--show-help (function-or-variable)
 
-   (let ((isfun (functionp function-or-variable)))
 
-     ;; bring up help-buffer for function or variable
 
-     (if isfun
 
-         (describe-function function-or-variable)
 
-       (describe-variable function-or-variable))
 
-     ;; clean up help-buffer
 
-     (pop-to-buffer "*Help*")
 
-     (let ((inhibit-read-only t))
 
-       (goto-char (point-min))
 
-       (while (progn
 
-                (kill-line 1)
 
-                (not (looking-at
 
-                      (if isfun
 
-                          "("
 
-                        "Documentation:")))))
 
-       (kill-line (if isfun 2 3))
 
-       (goto-char (point-max))
 
-       (kill-line -2)
 
-       (goto-char (point-min)))))
 
- (defun org-favtable--update-line (ref-or-link)
 
-   (let (initial
 
-         found
 
-         count-field
 
-         (ref-node-buffer-and-point (org-favtable--id-find)))
 
-     (with-current-buffer (car ref-node-buffer-and-point)
 
-       ;; search reference or link, if given (or assume, that we are already positioned right)
 
-       (when ref-or-link
 
-         (setq initial (point))
 
-         (goto-char (cdr ref-node-buffer-and-point))
 
-         (org-favtable--goto-top)
 
-         (while (and (org-at-table-p)
 
-                     (not (or (string= ref-or-link (org-favtable--get-field 'ref))
 
-                              (string= ref-or-link (org-favtable--get-field 'link)))))
 
-           (forward-line)))
 
-       (if (not (org-at-table-p))
 
-           (error "Did not find reference or link '%s'" ref-or-link)
 
-         (setq count-field (org-favtable--get-field 'count))
 
-         ;; update count field only if number or empty; leave :missing: and :reuse: as is
 
-         (if (or (not count-field)
 
-                 (string-match "^[0-9]+$" count-field))
 
-             (org-favtable--get-field 'count
 
-                                     (number-to-string
 
-                                      (+ 1 (string-to-number (or count-field "0"))))))
 
-         ;; update timestamp
 
-         (org-table-goto-column (org-favtable--column-num 'last-accessed))
 
-         (org-table-blank-field)
 
-         (org-insert-time-stamp nil t t)
 
-         (setq found t))
 
-       (if initial (goto-char initial))
 
-       found)))
 
- (defun org-favtable--occur-helper (action)
 
-   (let ((line-beg (line-beginning-position))
 
-         key search link ref)
 
-     ;; extract reference or link from text property (as put there before)
 
-     (setq ref (get-text-property line-beg 'org-favtable--ref))
 
-     (if (string= ref "") (setq ref nil))
 
-     (setq link (get-text-property line-beg 'org-favtable--link))
 
-     (if (string= link "") (setq link nil))
 
-     (org-favtable action
 
-                   (or link ref) ;; prefer link
 
-                   (if link t nil))))
 
- (defun org-favtable--get-field (key &optional value)
 
-   (let (field)
 
-     (setq field (org-trim (org-table-get-field (cdr (assoc key org-favtable--columns)) value)))
 
-     (if (string= field "") (setq field nil))
 
-     field))
 
- (defun org-favtable--column-num (key)
 
-   (cdr (assoc key org-favtable--columns)))
 
- (defun org-favtable-version ()
 
-   "Show version of org-favtable" (interactive)
 
-   (message "org-favtable %s" org-favtable--version))
 
- (defun org-favtable--make-guarded-search (ref &optional dont-quote)
 
-   (concat "\\b" (if dont-quote ref (regexp-quote ref)) "\\b"))
 
- (defun org-favtable-get-ref-regex-format ()
 
-   "return cons-cell with regular expression and format for references"
 
-   (unless org-favtable--ref-regex
 
-     (org-favtable 'parse))
 
-   (cons (org-favtable--make-guarded-search org-favtable--ref-regex 'dont-quote) org-favtable--ref-format))
 
- (defadvice org-mark-ring-goto (after org-favtable--advice-text-to-yank activate)
 
-   "Make text from the favtable available for yank."
 
-   (when org-favtable--text-to-yank
 
-       (kill-new org-favtable--text-to-yank)
 
-       (message (format "Ready to yank '%s'" org-favtable--text-to-yank))
 
-       (setq org-favtable--text-to-yank nil)))
 
- (provide 'org-favtable)
 
- ;; Local Variables:
 
- ;; fill-column: 75
 
- ;; comment-column: 50
 
- ;; End:
 
- ;;; org-favtable.el ends here
 
 
  |