config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

org-table.el (245357B)


      1 ;;; org-table.el --- The Table Editor for Org        -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
      4 
      5 ;; Author: Carsten Dominik <carsten.dominik@gmail.com>
      6 ;; Keywords: outlines, hypermedia, calendar, text
      7 ;; URL: https://orgmode.org
      8 ;;
      9 ;; This file is part of GNU Emacs.
     10 ;;
     11 ;; GNU Emacs is free software: you can redistribute it and/or modify
     12 ;; it under the terms of the GNU General Public License as published by
     13 ;; the Free Software Foundation, either version 3 of the License, or
     14 ;; (at your option) any later version.
     15 
     16 ;; GNU Emacs is distributed in the hope that it will be useful,
     17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 ;; GNU General Public License for more details.
     20 
     21 ;; You should have received a copy of the GNU General Public License
     22 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
     23 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     24 ;;
     25 ;;; Commentary:
     26 
     27 ;; This file contains the table editor and spreadsheet for Org mode.
     28 
     29 ;; Watch out:  Here we are talking about two different kind of tables.
     30 ;; Most of the code is for the tables created with the Org mode table editor.
     31 ;; Sometimes, we talk about tables created and edited with the table.el
     32 ;; Emacs package.  We call the former org-type tables, and the latter
     33 ;; table.el-type tables.
     34 
     35 ;;; Code:
     36 
     37 (require 'org-macs)
     38 (org-assert-version)
     39 
     40 (require 'cl-lib)
     41 (require 'org-macs)
     42 (require 'org-compat)
     43 (require 'org-keys)
     44 (require 'org-fold-core)
     45 
     46 (declare-function calc-eval "calc" (str &optional separator &rest args))
     47 (declare-function face-remap-remove-relative "face-remap" (cookie))
     48 (declare-function face-remap-add-relative "face-remap" (face &rest specs))
     49 (declare-function org-at-timestamp-p "org" (&optional extended))
     50 (declare-function org-delete-backward-char "org" (N))
     51 (declare-function org-mode "org" ())
     52 (declare-function org-duration-p "org-duration" (duration &optional canonical))
     53 (declare-function org-duration-to-minutes "org-duration" (duration &optional canonical))
     54 (declare-function org-element-at-point "org-element" (&optional pom cached-only))
     55 (declare-function org-element-contents "org-element-ast" (node))
     56 (declare-function org-element-extract "org-element-ast" (node))
     57 (declare-function org-element-interpret-data "org-element" (data))
     58 (declare-function org-element-lineage "org-element-ast" (blob &optional types with-self))
     59 (declare-function org-element-map "org-element" (data types fun &optional info first-match no-recursion with-affiliated))
     60 (declare-function org-element-parse-buffer "org-element" (&optional granularity visible-only keep-deferred))
     61 (declare-function org-element-property "org-element-ast" (property node))
     62 (declare-function org-element-end "org-element" (node))
     63 (declare-function org-element-post-affiliated "org-element" (node))
     64 (declare-function org-element-type-p "org-element-ast" (node types))
     65 (declare-function org-element-cache-reset "org-element" (&optional all no-persistence))
     66 (declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
     67 (declare-function org-export-create-backend "ox" (&rest rest) t)
     68 (declare-function org-export-data-with-backend "ox" (data backend info))
     69 (declare-function org-export-filter-apply-functions "ox" (filters value info))
     70 (declare-function org-export-first-sibling-p "ox" (blob info))
     71 (declare-function org-export-get-backend "ox" (name))
     72 (declare-function org-export-get-environment "ox" (&optional backend subtreep ext-plist))
     73 (declare-function org-export-install-filters "ox" (info))
     74 (declare-function org-export-table-has-special-column-p "ox" (table))
     75 (declare-function org-export-table-row-is-special-p "ox" (table-row info))
     76 (declare-function org-forward-paragraph "org" (&optional arg))
     77 (declare-function org-id-find "org-id" (id &optional markerp))
     78 (declare-function org-indent-line "org" ())
     79 (declare-function org-load-modules-maybe "org" (&optional force))
     80 (declare-function org-restart-font-lock "org" ())
     81 (declare-function org-sort-remove-invisible "org" (s))
     82 (declare-function org-time-stamp-format "org" (&optional long inactive))
     83 (declare-function org-time-string-to-absolute "org" (s &optional daynr prefer buffer pos))
     84 (declare-function org-time-string-to-time "org" (s))
     85 (declare-function org-timestamp-up-day "org" (&optional arg))
     86 
     87 (defvar constants-unit-system)
     88 (defvar org-M-RET-may-split-line)
     89 (defvar org-element-use-cache)
     90 (defvar org-export-filters-alist)
     91 (defvar org-finish-function)
     92 (defvar org-inhibit-highlight-removal)
     93 (defvar org-inhibit-startup)
     94 (defvar org-selected-window)
     95 (defvar org-self-insert-cluster-for-undo)
     96 (defvar org-self-insert-command-undo-counter)
     97 (defvar org-ts-regexp)
     98 (defvar org-ts-regexp-both)
     99 (defvar org-ts-regexp-inactive)
    100 (defvar org-ts-regexp3)
    101 (defvar org-window-configuration)
    102 (defvar sort-fold-case)
    103 
    104 
    105 ;;; Customizables
    106 
    107 (defgroup org-table nil
    108   "Options concerning tables in Org mode."
    109   :tag "Org Table"
    110   :group 'org)
    111 
    112 (defcustom orgtbl-optimized t
    113   "Non-nil means use the optimized table editor version for `orgtbl-mode'.
    114 
    115 In the optimized version, the table editor takes over all simple keys that
    116 normally just insert a character.  In tables, the characters are inserted
    117 in a way to minimize disturbing the table structure (i.e. in overwrite mode
    118 for empty fields).  Outside tables, the correct binding of the keys is
    119 restored.
    120 
    121 Changing this variable requires a restart of Emacs to become
    122 effective."
    123   :group 'org-table
    124   :type 'boolean)
    125 
    126 (defcustom orgtbl-radio-table-templates
    127   '((latex-mode "% BEGIN RECEIVE ORGTBL %n
    128 % END RECEIVE ORGTBL %n
    129 \\begin{comment}
    130 #+ORGTBL: SEND %n orgtbl-to-latex :splice nil :skip 0
    131 | | |
    132 \\end{comment}\n")
    133     (texinfo-mode "@c BEGIN RECEIVE ORGTBL %n
    134 @c END RECEIVE ORGTBL %n
    135 @ignore
    136 #+ORGTBL: SEND %n orgtbl-to-html :splice nil :skip 0
    137 | | |
    138 @end ignore\n")
    139     (html-mode "<!-- BEGIN RECEIVE ORGTBL %n -->
    140 <!-- END RECEIVE ORGTBL %n -->
    141 <!--
    142 #+ORGTBL: SEND %n orgtbl-to-html :splice nil :skip 0
    143 | | |
    144 -->\n")
    145     (org-mode "#+ BEGIN RECEIVE ORGTBL %n
    146 #+ END RECEIVE ORGTBL %n
    147 
    148 #+ORGTBL: SEND %n orgtbl-to-orgtbl :splice nil :skip 0
    149 | | |
    150 "))
    151   "Templates for radio tables in different major modes.
    152 Each template must define lines that will be treated as a comment and that
    153 must contain the \"BEGIN RECEIVE ORGTBL %n\" and \"END RECEIVE ORGTBL\"
    154 lines where \"%n\" will be replaced with the name of the table during
    155 insertion of the template.  The transformed table will later be inserted
    156 between these lines.
    157 
    158 The template should also contain a minimal table in a multiline comment.
    159 If multiline comments are not possible in the buffer language,
    160 you can pack it into a string that will not be used when the code
    161 is compiled or executed.  Above the table will you need a line with
    162 the fixed string \"#+ORGTBL: SEND\", followed by instruction on how to
    163 convert the table into a data structure useful in the
    164 language of the buffer.  Check the manual for the section on
    165 \"Translator functions\", and more generally check out
    166 the Info node `(org)Tables in arbitrary syntax'.
    167 
    168 All occurrences of %n in a template will be replaced with the name of the
    169 table, obtained by prompting the user."
    170   :group 'org-table
    171   :type '(repeat
    172 	  (list (symbol :tag "Major mode")
    173 		(string :tag "Format"))))
    174 
    175 (defgroup org-table-settings nil
    176   "Settings for tables in Org mode."
    177   :tag "Org Table Settings"
    178   :group 'org-table)
    179 
    180 (defcustom org-table-header-line-p nil
    181   "Activate `org-table-header-line-mode' by default?"
    182   :type 'boolean
    183   :package-version '(Org . "9.4")
    184   :group 'org-table)
    185 
    186 (defcustom org-table-default-size "5x2"
    187   "The default size for newly created tables, Columns x Rows."
    188   :group 'org-table-settings
    189   :type 'string)
    190 
    191 (defcustom org-table-number-regexp
    192   "^\\([<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%:]*\\|[<>]?[-+]?0[xX][[:xdigit:].]+\\|[<>]?[-+]?[0-9]+#[0-9a-zA-Z.]+\\|nan\\|[-+u]?inf\\)$"
    193   "Regular expression for recognizing numbers in table columns.
    194 If a table column contains mostly numbers, it will be aligned to the
    195 right.  If not, it will be aligned to the left.
    196 
    197 The default value of this option is a regular expression which allows
    198 anything which looks remotely like a number as used in scientific
    199 context.  For example, all of the following will be considered a
    200 number:
    201     12    12.2    2.4e-08    2x10^12    4.034+-0.02    2.7(10)  >3.5
    202 
    203 Other options offered by the customize interface are more restrictive."
    204   :group 'org-table-settings
    205   :type '(choice
    206 	  (const :tag "Positive Integers"
    207 		 "^[0-9]+$")
    208 	  (const :tag "Integers"
    209 		 "^[-+]?[0-9]+$")
    210 	  (const :tag "Floating Point Numbers"
    211 		 "^[-+]?\\([0-9]*\\.[0-9]+\\|[0-9]+\\.[0-9]*\\)$")
    212 	  (const :tag "Floating Point Number or Integer"
    213 		 "^[-+]?\\([0-9]*\\.[0-9]+\\|[0-9]+\\.?[0-9]*\\)$")
    214 	  (const :tag "Exponential, Floating point, Integer"
    215 		 "^[-+]?[0-9.]+\\([eEdD][-+0-9]+\\)?$")
    216 	  (const :tag "Very General Number-Like, including hex and Calc radix"
    217 		 "^\\([<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%]*\\|[<>]?[-+]?0[xX][[:xdigit:].]+\\|[<>]?[-+]?[0-9]+#[0-9a-zA-Z.]+\\|nan\\|[-+u]?inf\\)$")
    218 	  (const :tag "Very General Number-Like, including hex and Calc radix, allows comma as decimal mark"
    219 		 "^\\([<>]?[-+^.,0-9]*[0-9][-+^.0-9eEdDx()%]*\\|[<>]?[-+]?0[xX][[:xdigit:].]+\\|[<>]?[-+]?[0-9]+#[0-9a-zA-Z.]+\\|nan\\|[-+u]?inf\\)$")
    220 	  (regexp :tag "Regexp:")))
    221 
    222 (defcustom org-table-number-fraction 0.5
    223   "Fraction of numbers in a column required to make the column align right.
    224 In a column all non-white fields are considered.  If at least
    225 this fraction of fields is matched by `org-table-number-regexp',
    226 alignment to the right border applies."
    227   :group 'org-table-settings
    228   :type 'number)
    229 
    230 (defcustom org-table-formula-field-format "%s"
    231   "Format for fields which contain the result of a formula.
    232 For example, using \"~%s~\" will display the result within tilde
    233 characters.  Beware that modifying the display can prevent the
    234 field from being used in another formula."
    235   :group 'org-table-settings
    236   :version "24.1"
    237   :type 'string)
    238 
    239 (defgroup org-table-editing nil
    240   "Behavior of tables during editing in Org mode."
    241   :tag "Org Table Editing"
    242   :group 'org-table)
    243 
    244 (defcustom org-table-automatic-realign t
    245   "Non-nil means automatically re-align table when pressing TAB or RETURN.
    246 When nil, aligning is only done with `\\[org-table-align]', or after column
    247 removal/insertion."
    248   :group 'org-table-editing
    249   :type 'boolean)
    250 
    251 (defcustom org-table-auto-blank-field t
    252   "Non-nil means automatically blank table field when starting to type into it.
    253 This only happens when typing immediately after a field motion
    254 command (TAB, S-TAB or RET)."
    255   :group 'org-table-editing
    256   :type 'boolean)
    257 
    258 (defcustom org-table-exit-follow-field-mode-when-leaving-table t
    259   "Non-nil means automatically exit the follow mode.
    260 When nil, the follow mode will stay on and be active in any table
    261 the cursor enters.  Since the table follow filed mode messes with the
    262 window configuration, it is not recommended to set this variable to nil,
    263 except maybe locally in a special file that has mostly tables with long
    264 fields."
    265   :group 'org-table
    266   :version "24.1"
    267   :type 'boolean)
    268 
    269 (defcustom org-table-fix-formulas-confirm nil
    270   "Whether the user should confirm when Org fixes formulas."
    271   :group 'org-table-editing
    272   :version "24.1"
    273   :type '(choice
    274 	  (const :tag "with yes-or-no" yes-or-no-p)
    275 	  (const :tag "with y-or-n" y-or-n-p)
    276 	  (const :tag "no confirmation" nil)))
    277 
    278 (defcustom org-table-tab-jumps-over-hlines t
    279   "Non-nil means tab in the last column of a table with jump over a hline.
    280 If a horizontal separator line is following the current line,
    281 `org-table-next-field' can either create a new row before that line, or jump
    282 over the line.  When this option is nil, a new line will be created before
    283 this line."
    284   :group 'org-table-editing
    285   :type 'boolean)
    286 
    287 (defcustom org-table-shrunk-column-indicator "…"
    288   "String to be displayed in a shrunk column."
    289   :group 'org-table-editing
    290   :type 'string
    291   :package-version '(Org . "9.2")
    292   :safe (lambda (v) (and (stringp v) (not (equal v "")))))
    293 
    294 (defgroup org-table-calculation nil
    295   "Options concerning tables in Org mode."
    296   :tag "Org Table Calculation"
    297   :group 'org-table)
    298 
    299 (defcustom org-table-use-standard-references 'from
    300   "Non-nil means using table references like B3 instead of @3$2.
    301 Possible values are:
    302 nil     never use them
    303 from    accept as input, do not present for editing
    304 t       accept as input and present for editing"
    305   :group 'org-table-calculation
    306   :type '(choice
    307 	  (const :tag "Never, don't even check user input for them" nil)
    308 	  (const :tag "Always, both as user input, and when editing" t)
    309 	  (const :tag "Convert user input, don't offer during editing" from)))
    310 
    311 (defcustom org-table-copy-increment t
    312   "Non-nil means increment when copying current field with \
    313 `\\[org-table-copy-down]'."
    314   :group 'org-table-calculation
    315   :version "26.1"
    316   :package-version '(Org . "8.3")
    317   :type '(choice
    318 	  (const :tag "Use the difference between the current and the above fields" t)
    319 	  (integer :tag "Use a number" 1)
    320 	  (const :tag "Don't increment the value when copying a field" nil)))
    321 
    322 (defcustom org-calc-default-modes
    323   '(calc-internal-prec 12
    324 		       calc-float-format  (float 8)
    325 		       calc-angle-mode    deg
    326 		       calc-prefer-frac   nil
    327 		       calc-symbolic-mode nil
    328 		       calc-date-format (YYYY "-" MM "-" DD " " Www (" " hh ":" mm))
    329 		       calc-display-working-message t)
    330   "List with Calc mode settings for use in `calc-eval' for table formulas.
    331 The list must contain alternating symbols (Calc modes variables and values).
    332 Don't remove any of the default settings, just change the values.  Org mode
    333 relies on the variables to be present in the list."
    334   :group 'org-table-calculation
    335   :type 'plist)
    336 
    337 (defcustom org-table-duration-custom-format 'hours
    338   "Format for the output of calc computations like $1+$2;t.
    339 The default value is `hours', and will output the results as a
    340 number of hours.  Other allowed values are `seconds', `minutes' and
    341 `days', and the output will be a fraction of seconds, minutes or
    342 days.  `hh:mm' selects to use hours and minutes, ignoring seconds.
    343 The `U' flag in a table formula will select this specific format for
    344 a single formula."
    345   :group 'org-table-calculation
    346   :version "24.1"
    347   :type '(choice (symbol :tag "Seconds" 'seconds)
    348 		 (symbol :tag "Minutes" 'minutes)
    349 		 (symbol :tag "Hours  " 'hours)
    350 		 (symbol :tag "Days   " 'days)
    351 		 (symbol :tag "HH:MM  " 'hh:mm)))
    352 
    353 (defcustom org-table-duration-hour-zero-padding t
    354   "Non-nil means hours in table duration computations should be zero-padded.
    355 So this is about 08:32:34 versus 8:33:34."
    356   :group 'org-table-calculation
    357   :version "26.1"
    358   :package-version '(Org . "9.1")
    359   :type 'boolean
    360   :safe #'booleanp)
    361 
    362 (defcustom org-table-formula-evaluate-inline t
    363   "Non-nil means TAB and RET evaluate a formula in current table field.
    364 If the current field starts with an equal sign, it is assumed to be a formula
    365 which should be evaluated as described in the manual and in the documentation
    366 string of the command `org-table-eval-formula'.  This feature requires the
    367 Emacs calc package.
    368 When this variable is nil, formula calculation is only available through
    369 the command `\\[org-table-eval-formula]'."
    370   :group 'org-table-calculation
    371   :type 'boolean)
    372 
    373 (defcustom org-table-formula-use-constants t
    374   "Non-nil means interpret constants in formulas in tables.
    375 A constant looks like `$c' or `$Grav' and will be replaced before evaluation
    376 by the value given in `org-table-formula-constants', or by a value obtained
    377 from the `constants.el' package."
    378   :group 'org-table-calculation
    379   :type 'boolean)
    380 
    381 (defcustom org-table-formula-constants nil
    382   "Alist with constant names and values, for use in table formulas.
    383 The car of each element is a name of a constant, without the `$' before it.
    384 The cdr is the value as a string.  For example, if you'd like to use the
    385 speed of light in a formula, you would configure
    386 
    387   (setq org-table-formula-constants \\='((\"c\" . \"299792458.\")))
    388 
    389 and then use it in an equation like `$1*$c'.
    390 
    391 Constants can also be defined on a per-file basis using a line like
    392 
    393 #+CONSTANTS: c=299792458. pi=3.14 eps=2.4e-6"
    394   :group 'org-table-calculation
    395   :type '(repeat
    396 	  (cons (string :tag "name")
    397 		(string :tag "value"))))
    398 
    399 (defcustom org-table-allow-automatic-line-recalculation t
    400   "Non-nil means lines marked with |#| or |*| will be recomputed automatically.
    401 \\<org-mode-map>\
    402 Automatically means when `TAB' or `RET' or `\\[org-ctrl-c-ctrl-c]' \
    403 are pressed in the line."
    404   :group 'org-table-calculation
    405   :type 'boolean)
    406 
    407 (defcustom org-table-relative-ref-may-cross-hline t
    408   "Non-nil means relative formula references may cross hlines.
    409 Here are the allowed values:
    410 
    411 nil    Relative references may not cross hlines.  They will reference the
    412        field next to the hline instead.  Coming from below, the reference
    413        will be to the field below the hline.  Coming from above, it will be
    414        to the field above.
    415 t      Relative references may cross hlines.
    416 error  An attempt to cross a hline will throw an error.
    417 
    418 It is probably good to never set this variable to nil, for the sake of
    419 portability of tables."
    420   :group 'org-table-calculation
    421   :type '(choice
    422           (const :tag "Allow crossing hline" t)
    423 	  (const :tag "Stick to hline" nil)
    424 	  (const :tag "Error on attempt to cross" error)))
    425 
    426 (defcustom org-table-formula-create-columns nil
    427   "Non-nil means evaluation of formula can add new columns.
    428 When non-nil, evaluating an out-of-bounds field can insert as
    429 many columns as needed.  When set to `warn', issue a warning when
    430 doing so.  When set to `prompt', ask user before creating a new
    431 column.  Otherwise, throw an error."
    432   :group 'org-table-calculation
    433   :package-version '(Org . "8.3")
    434   :type '(choice
    435 	  (const :tag "Out-of-bounds field generates an error (default)" nil)
    436 	  (const :tag "Out-of-bounds field silently adds columns as needed" t)
    437 	  (const :tag "Out-of-bounds field adds columns, but issues a warning" warn)
    438 	  (const :tag "Prompt user when setting an out-of-bounds field" prompt)))
    439 
    440 (defgroup org-table-import-export nil
    441   "Options concerning table import and export in Org mode."
    442   :tag "Org Table Import Export"
    443   :group 'org-table)
    444 
    445 (defcustom org-table-export-default-format "orgtbl-to-tsv"
    446   "Default export parameters for `org-table-export'.
    447 These can be overridden for a specific table by setting the
    448 TABLE_EXPORT_FORMAT property.  See the manual section on orgtbl
    449 radio tables for the different export transformations and
    450 available parameters."
    451   :group 'org-table-import-export
    452   :type 'string)
    453 
    454 (defcustom org-table-convert-region-max-lines 999
    455   "Max lines that `org-table-convert-region' will attempt to process.
    456 
    457 The function can be slow on larger regions; this safety feature
    458 prevents it from hanging Emacs."
    459   :group 'org-table-import-export
    460   :type 'integer
    461   :package-version '(Org . "8.3"))
    462 
    463 
    464 ;;; Org table header minor mode
    465 (defun org-table-row-get-visible-string (&optional pos)
    466   "Get the visible string of a table row.
    467 This may be useful when columns have been shrunk."
    468   (save-excursion
    469     (when pos (goto-char pos))
    470     (let* ((beg (line-beginning-position))
    471            (end (line-end-position))
    472            (str (buffer-substring beg end)))
    473       ;; FIXME: This does not handle intersecting overlays.
    474       (dolist (ov (overlays-in beg end))
    475         (when (overlay-get ov 'display)
    476           (put-text-property
    477            (- (overlay-start ov) beg) (- (overlay-end ov) beg)
    478            'display (overlay-get ov 'display)
    479            str)))
    480       str)))
    481 
    482 (defvar-local org-table-header-overlay nil)
    483 (put 'org-table-header-overlay 'permanent-local t)
    484 (defun org-table-header-set-header ()
    485   "Display the header of the table at point."
    486   (let ((gcol temporary-goal-column))
    487     (unwind-protect
    488         (progn
    489           (when (overlayp org-table-header-overlay)
    490             (delete-overlay org-table-header-overlay))
    491           ;; We might be called after scrolling but before display is
    492           ;; updated. Make sure that any queued redisplay is executed
    493           ;; before we look into `window-start'.
    494           (redisplay)
    495           (let* ((ws (window-start))
    496                  (beg (save-excursion
    497                         ;; Check table at window start, not at point.
    498                         ;; Point might be after the table, or at
    499                         ;; another table located below the one visible
    500                         ;; on top.
    501                         (goto-char ws)
    502                         (goto-char (org-table-begin))
    503                         (while (or (org-at-table-hline-p)
    504                                    (looking-at-p ".*|\\s-+<[rcl]?\\([0-9]+\\)?>"))
    505                           (move-beginning-of-line 2))
    506                         (line-beginning-position))))
    507             (if (pos-visible-in-window-p beg)
    508                 (when (overlayp org-table-header-overlay)
    509                   (delete-overlay org-table-header-overlay))
    510               (setq org-table-header-overlay
    511                     (make-overlay
    512                      (save-excursion (goto-char ws) (line-beginning-position))
    513                      (save-excursion (goto-char ws) (line-end-position))))
    514               (org-overlay-display
    515                org-table-header-overlay
    516                (org-table-row-get-visible-string beg)
    517                'org-table-header))))
    518       (setq temporary-goal-column gcol))))
    519 
    520 ;;;###autoload
    521 (define-minor-mode org-table-header-line-mode
    522   "Display the first row of the table at point in the header line."
    523   :lighter " TblHeader"
    524   (unless (eq major-mode 'org-mode)
    525     (user-error "Cannot turn org table header mode outside org-mode buffers"))
    526   (if org-table-header-line-mode
    527       (add-hook 'post-command-hook #'org-table-header-set-header nil t)
    528     (when (overlayp org-table-header-overlay)
    529       (delete-overlay org-table-header-overlay)
    530       (setq org-table-header-overlay nil))
    531     (remove-hook 'post-command-hook #'org-table-header-set-header t)))
    532 
    533 
    534 ;;; Regexps Constants
    535 
    536 (defconst org-table-any-line-regexp "^[ \t]*\\(|\\|\\+-[-+]\\)"
    537   "Detect an org-type or table-type table.")
    538 
    539 (defconst org-table-line-regexp "^[ \t]*|"
    540   "Detect an org-type table line.")
    541 
    542 (defconst org-table-dataline-regexp "^[ \t]*|[^-]"
    543   "Detect an org-type table line.")
    544 
    545 (defconst org-table-hline-regexp "^[ \t]*|-"
    546   "Detect an org-type table hline.")
    547 
    548 (defconst org-table1-hline-regexp "^[ \t]*\\+-[-+]"
    549   "Detect a table-type table hline.")
    550 
    551 (defconst org-table-any-border-regexp "^[ \t]*[^|+ \t]"
    552   "Detect the first line outside a table when searching from within it.
    553 This works for both table types.")
    554 
    555 (defconst org-TBLFM-regexp "^[ \t]*#\\+TBLFM: "
    556   "Detect a #+TBLFM line.")
    557 
    558 (defvar org-table-TBLFM-begin-regexp "^[ \t]*|.*\n[ \t]*#\\+TBLFM: ")
    559 
    560 (defconst org-table-auto-recalculate-regexp "^[ \t]*| *# *\\(|\\|$\\)"
    561   "Regexp matching a line marked for automatic recalculation.")
    562 
    563 (defconst org-table-recalculate-regexp "^[ \t]*| *[#*] *\\(|\\|$\\)"
    564   "Regexp matching a line marked for recalculation.")
    565 
    566 (defconst org-table-calculate-mark-regexp "^[ \t]*| *[!$^_#*] *\\(|\\|$\\)"
    567   "Regexp matching a line marked for calculation.")
    568 
    569 (defconst org-table-border-regexp "^[ \t]*[^| \t]"
    570   "Regexp matching any line outside an Org table.")
    571 
    572 (defconst org-table-range-regexp
    573   "@\\([-+]?I*[-+]?[0-9]*\\)\\(\\$[-+]?[0-9]+\\)?\\(\\.\\.@?\\([-+]?I*[-+]?[0-9]*\\)\\(\\$[-+]?[0-9]+\\)?\\)?"
    574   ;;   1                        2                    3          4                        5
    575   "Regular expression for matching ranges in formulas.")
    576 
    577 (defconst org-table-range-regexp2
    578   (concat
    579    "\\(" "@[-0-9I$&]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\|" "\\$[a-zA-Z0-9]+" "\\)"
    580    "\\.\\."
    581    "\\(" "@?[-0-9I$&]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\|" "\\$[a-zA-Z0-9]+" "\\)")
    582   "Match a range for reference display.")
    583 
    584 (defconst org-table-translate-regexp
    585   (concat "\\(" "@[-0-9I$]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\)")
    586   "Match a reference that needs translation, for reference display.")
    587 
    588 (defconst org-table--separator-space-pre
    589   (propertize " " 'display '(space :relative-width 1))
    590   "Space used in front of fields when aligning the table.
    591 This space serves as a segment separator for the purposes of the
    592 bidirectional reordering.
    593 Note that `org-table--separator-space-pre' is not `eq' to
    594 `org-table--separator-space-post'.  This is done to prevent Emacs from
    595 visually merging spaces in an empty table cell.  See bug#45915.")
    596 
    597 (defconst org-table--separator-space-post
    598   (propertize " " 'display '(space :relative-width 1.001))
    599   "Space used after fields when aligning the table.
    600 This space serves as a segment separator for the purposes of the
    601 bidirectional reordering.
    602 Note that `org-table--separator-space-pre' is not `eq' to
    603 `org-table--separator-space-post'.  This is done to prevent Emacs from
    604 visually merging spaces in an empty table cell.  See bug#45915.")
    605 
    606 
    607 ;;; Internal Variables
    608 
    609 (defvar org-table-last-highlighted-reference nil)
    610 
    611 (defvar org-table-formula-history nil)
    612 
    613 (defvar org-field-marker nil)
    614 (defvar org-table-buffer-is-an nil)
    615 
    616 (defvar-local org-table-formula-constants-local nil
    617   "Local version of `org-table-formula-constants'.")
    618 
    619 (defvar org-table-may-need-update t
    620   "Indicates that a table might need an update.
    621 This variable is set by `org-before-change-function'.
    622 `org-table-align' sets it back to nil.")
    623 
    624 (defvar orgtbl-after-send-table-hook nil
    625   "Hook for functions attaching to \\`C-c C-c', if the table is sent.
    626 This can be used to add additional functionality after the table is sent
    627 to the receiver position, otherwise, if table is not sent, the functions
    628 are not run.")
    629 
    630 (defvar org-table-column-names nil
    631   "Alist with column names, derived from the `!' line.
    632 This variable is initialized with `org-table-analyze'.")
    633 
    634 (defvar org-table-column-name-regexp nil
    635   "Regular expression matching the current column names.
    636 This variable is initialized with `org-table-analyze'.")
    637 
    638 (defvar org-table-local-parameters nil
    639   "Alist with parameter names, derived from the `$' line.
    640 This variable is initialized with `org-table-analyze'.")
    641 
    642 (defvar org-table-named-field-locations nil
    643   "Alist with locations of named fields.
    644 Associations follow the pattern (NAME LINE COLUMN) where
    645   NAME is the name of the field as a string,
    646   LINE is the number of lines from the beginning of the table,
    647   COLUMN is the column of the field, as an integer.
    648 This variable is initialized with `org-table-analyze'.")
    649 
    650 (defvar org-table-current-line-types nil
    651   "Table row types in current table.
    652 This variable is initialized with `org-table-analyze'.")
    653 
    654 (defvar org-table-current-begin-pos nil
    655   "Current table begin position, as a marker.
    656 This variable is initialized with `org-table-analyze'.")
    657 
    658 (defvar org-table-current-ncol nil
    659   "Number of columns in current table.
    660 This variable is initialized with `org-table-analyze'.")
    661 
    662 (defvar org-table-dlines nil
    663   "Vector of data line line numbers in the current table.
    664 Line numbers are counted from the beginning of the table.  This
    665 variable is initialized with `org-table-analyze'.")
    666 
    667 (defvar org-table-hlines nil
    668   "Vector of hline line numbers in the current table.
    669 Line numbers are counted from the beginning of the table.  This
    670 variable is initialized with `org-table-analyze'.")
    671 
    672 (defvar org-table-aligned-begin-marker (make-marker)
    673   "Marker at the beginning of the table last aligned.
    674 Used to check if cursor still is in that table, to minimize realignment.")
    675 
    676 (defvar org-table-aligned-end-marker (make-marker)
    677   "Marker at the end of the table last aligned.
    678 Used to check if cursor still is in that table, to minimize realignment.")
    679 
    680 (defvar org-table-last-alignment nil
    681   "List of flags for flushright alignment, from the last re-alignment.
    682 This is being used to correctly align a single field after TAB or RET.")
    683 
    684 (defvar org-table-last-column-widths nil
    685   "List of max width of fields in each column.
    686 This is being used to correctly align a single field after TAB or RET.")
    687 
    688 (defvar-local org-table-formula-debug nil
    689   "Non-nil means debug table formulas.
    690 When nil, simply write \"#ERROR\" in corrupted fields.")
    691 
    692 (defvar-local org-table-overlay-coordinates nil
    693   "Overlay coordinates after each align of a table.")
    694 
    695 (defvar org-last-recalc-line nil)
    696 
    697 (defvar org-show-positions nil)
    698 
    699 (defvar org-table-rectangle-overlays nil)
    700 
    701 (defvar org-table-clip nil
    702   "Clipboard for table regions.")
    703 
    704 (defvar org-timecnt nil)
    705 
    706 (defvar org-recalc-commands nil
    707   "List of commands triggering the recalculation of a line.
    708 Will be filled automatically during use.")
    709 
    710 (defvar org-recalc-marks
    711   '((" " . "Unmarked: no special line, no automatic recalculation")
    712     ("#" . "Automatically recalculate this line upon TAB, RET, and C-c C-c in the line")
    713     ("*" . "Recalculate only when entire table is recalculated with `C-u C-c *'")
    714     ("!" . "Column name definition line.  Reference in formula as $name.")
    715     ("$" . "Parameter definition line name=value.  Reference in formula as $name.")
    716     ("_" . "Names for values in row below this one.")
    717     ("^" . "Names for values in row above this one.")))
    718 
    719 (defvar org-pos nil)
    720 
    721 
    722 ;;; Macros and Inlined Functions
    723 
    724 (defmacro org-table-with-shrunk-columns (&rest body)
    725   "Expand all columns before executing BODY, then shrink them again."
    726   (declare (debug (body)))
    727   (org-with-gensyms (shrunk-columns begin end)
    728     `(let ((,begin (copy-marker (org-table-begin)))
    729 	   (,end (copy-marker (org-table-end) t))
    730 	   (,shrunk-columns (org-table--list-shrunk-columns)))
    731        (org-with-point-at ,begin (org-table-expand ,begin ,end))
    732        (unwind-protect
    733 	   (progn ,@body)
    734 	 (org-table--shrink-columns ,shrunk-columns ,begin ,end)
    735 	 (set-marker ,begin nil)
    736 	 (set-marker ,end nil)))))
    737 
    738 (defmacro org-table-with-shrunk-field (&rest body)
    739   "Save field shrunk state, execute BODY and restore state."
    740   (declare (debug (body)))
    741   (org-with-gensyms (end shrunk size)
    742     `(let* ((,shrunk (save-match-data (org-table--shrunk-field)))
    743 	    (,end (and ,shrunk (copy-marker (overlay-end ,shrunk) t)))
    744 	    (,size (and ,shrunk (- ,end (overlay-start ,shrunk)))))
    745        (when ,shrunk (delete-overlay ,shrunk))
    746        (unwind-protect (progn ,@body)
    747 	 (when ,shrunk (move-overlay ,shrunk (- ,end ,size) ,end))))))
    748 
    749 (defmacro org-table-save-field (&rest body)
    750   "Save current field; execute BODY; restore field.
    751 Field is restored even in case of abnormal exit."
    752   (declare (debug (body)))
    753   (org-with-gensyms (line column)
    754     `(let ((,line (copy-marker (line-beginning-position)))
    755 	   (,column (org-table-current-column)))
    756        (unwind-protect
    757 	   (progn ,@body)
    758 	 (goto-char ,line)
    759 	 (org-table-goto-column ,column)
    760 	 (set-marker ,line nil)))))
    761 
    762 
    763 ;;; Predicates
    764 
    765 (defun org-at-TBLFM-p (&optional pos)
    766   "Non-nil when point (or POS) is in #+TBLFM line."
    767   (save-excursion
    768     (goto-char (or pos (point)))
    769     (forward-line 0)
    770     (and (let ((case-fold-search t)) (looking-at org-TBLFM-regexp))
    771 	 (org-element-type-p (org-element-at-point) 'table))))
    772 
    773 (defun org-at-table-p (&optional table-type)
    774   "Non-nil if the cursor is inside an Org table.
    775 If TABLE-TYPE is non-nil, also check for table.el-type tables."
    776   (and (org-match-line (if table-type "[ \t]*[|+]" "[ \t]*|"))
    777        (or (not (derived-mode-p 'org-mode))
    778 	   (let ((e (org-element-lineage (org-element-at-point) 'table t)))
    779 	     (and e (or table-type
    780 			(eq 'org (org-element-property :type e))))))))
    781 
    782 (defun org-at-table.el-p ()
    783   "Non-nil when point is at a table.el table."
    784   (and (org-match-line "[ \t]*[|+]")
    785        (let ((element (org-element-at-point)))
    786 	 (and (org-element-type-p element 'table)
    787 	      (eq (org-element-property :type element) 'table.el)))))
    788 
    789 (defun org-at-table-hline-p ()
    790   "Non-nil when point is inside a hline in a table.
    791 Assume point is already in a table."
    792   (org-match-line org-table-hline-regexp))
    793 
    794 (defun org-table-check-inside-data-field (&optional noerror assume-table)
    795   "Non-nil when point is inside a table data field.
    796 Raise an error otherwise, unless NOERROR is non-nil.  In that
    797 case, return nil if point is not inside a data field.  When
    798 optional argument ASSUME-TABLE is non-nil, assume point is within
    799 a table."
    800   (cond ((and (or assume-table (org-at-table-p))
    801 	      (not (save-excursion (skip-chars-backward " \t") (bolp)))
    802 	      (not (org-at-table-hline-p))
    803 	      (not (looking-at-p "[ \t]*$"))))
    804 	(noerror nil)
    805 	(t (user-error "Not in table data field"))))
    806 
    807 
    808 ;;; Create, Import, and Convert Tables
    809 
    810 ;;;###autoload
    811 (defun org-table-create-with-table.el ()
    812   "Use the table.el package to insert a new table.
    813 If there is already a table at point, convert between Org tables
    814 and table.el tables."
    815   (interactive)
    816   (require 'table)
    817   (cond
    818    ((and (org-at-table.el-p)
    819 	 (y-or-n-p "Convert table to Org table? "))
    820     (org-table-convert))
    821    ((and (org-at-table-p)
    822 	 (y-or-n-p "Convert table to table.el table? "))
    823     (org-table-align)
    824     (org-table-convert))
    825    (t (call-interactively 'table-insert))))
    826 
    827 ;;;###autoload
    828 (defun org-table-create-or-convert-from-region (arg)
    829   "Convert region to table, or create an empty table.
    830 If there is an active region, convert it to a table, using the function
    831 `org-table-convert-region'.  See the documentation of that function
    832 to learn how the prefix argument is interpreted to determine the field
    833 separator.
    834 If there is no such region, create an empty table with `org-table-create'."
    835   (interactive "P")
    836   (if (org-region-active-p)
    837       (org-table-convert-region (region-beginning) (region-end) arg)
    838     (org-table-create arg)))
    839 
    840 ;;;###autoload
    841 (defun org-table-create (&optional size)
    842   "Query for a size and insert a table skeleton.
    843 SIZE is a string Columns x Rows like for example \"3x2\"."
    844   (interactive "P")
    845   (unless size
    846     (setq size (read-string
    847 		(concat "Table size Columns x Rows [e.g. "
    848 			org-table-default-size "]: ")
    849 		"" nil org-table-default-size)))
    850 
    851   (let* ((pos (point))
    852 	 (indent (make-string (current-column) ?\ ))
    853 	 (split (org-split-string size " *x *"))
    854 	 (rows (string-to-number (nth 1 split)))
    855 	 (columns (string-to-number (car split)))
    856 	 (line (concat (apply 'concat indent "|" (make-list columns "  |"))
    857 		       "\n")))
    858     (if (string-match "^[ \t]*$" (buffer-substring-no-properties
    859                                   (line-beginning-position) (point)))
    860 	(forward-line 0)
    861       (newline))
    862     ;; (mapcar (lambda (x) (insert line)) (make-list rows t))
    863     (dotimes (_ rows) (insert line))
    864     (goto-char pos)
    865     (when (> rows 1)
    866       ;; Insert a hline after the first row.
    867       (end-of-line 1)
    868       (insert "\n|-")
    869       (goto-char pos))
    870     (org-table-align)))
    871 
    872 ;;;###autoload
    873 (defun org-table-convert-region (beg0 end0 &optional separator)
    874   "Convert region to a table.
    875 
    876 The region goes from BEG0 to END0, but these borders will be moved
    877 slightly, to make sure a beginning of line in the first line is
    878 included.
    879 
    880 Throw an error when the region has more than
    881 `org-table-convert-region-max-lines' lines.
    882 
    883 SEPARATOR specifies the field separator in the lines.  It can have the
    884 following values:
    885 
    886 (4)     Use the comma as a field separator
    887 (16)    Use a TAB as field separator
    888 (64)    Prompt for a regular expression as field separator
    889 integer  When a number, use that many spaces, or a TAB, as field separator
    890 regexp   When a regular expression, use it to match the separator
    891 nil      When nil, the command tries to be smart and figure out the
    892          separator in the following way:
    893          - when each line contains a TAB, assume TAB-separated material
    894          - when each line contains a comma, assume CSV material
    895          - else, assume one or more SPACE characters as separator.
    896 `babel-auto'
    897        Use the same rules as nil, but do not try any separator when
    898        the region contains a single line and has no commas or tabs."
    899   (interactive "r\nP")
    900   (let* ((beg (min beg0 end0))
    901 	 (end (max beg0 end0))
    902 	 re)
    903     (when (> (count-lines beg end) org-table-convert-region-max-lines)
    904       (user-error "Region is longer than `org-table-convert-region-max-lines' (%s) lines; not converting"
    905 		  org-table-convert-region-max-lines))
    906     (when (equal separator '(64))
    907       (setq separator (read-regexp "Regexp for field separator")))
    908     (goto-char beg)
    909     (forward-line 0)
    910     (setq beg (point-marker))
    911     (goto-char end)
    912     (if (bolp) (backward-char 1) (end-of-line 1))
    913     (setq end (point-marker))
    914     ;; Get the right field separator
    915     (when (or (not separator) (eq separator 'babel-auto))
    916       (goto-char beg)
    917       (setq separator
    918 	    (cond
    919 	     ((not (save-excursion (re-search-forward "^[^\n\t]+$" end t))) '(16))
    920 	     ((not (save-excursion (re-search-forward "^[^\n,]+$" end t))) '(4))
    921              ((and (eq separator 'babel-auto)
    922                    (= 1 (count-lines beg end)))
    923               (rx unmatchable))
    924 	     (t 1))))
    925     (goto-char beg)
    926     (if (equal separator '(4))
    927 	(while (< (point) end)
    928 	  ;; parse the csv stuff
    929 	  (cond
    930 	   ((looking-at "^") (insert "| "))
    931 	   ((looking-at "[ \t]*$") (replace-match " |") (forward-line 1))
    932 	   ((looking-at "[ \t]*\"\\([^\"\n]*\\)\"")
    933 	    (replace-match "\\1")
    934 	    (if (looking-at "\"") (insert "\"")))
    935 	   ((looking-at "[^,\n]+") (goto-char (match-end 0)))
    936 	   ((looking-at "[ \t]*,") (replace-match " | "))
    937 	   (t (forward-line 1))))
    938       (setq re (cond
    939 		((equal separator '(4)) "^\\|\"?[ \t]*,[ \t]*\"?")
    940 		((equal separator '(16)) "^\\|\t")
    941 		((integerp separator)
    942 		 (if (< separator 1)
    943 		     (user-error "Number of spaces in separator must be >= 1")
    944 		   (format "^ *\\| *\t *\\| \\{%d,\\}" separator)))
    945 		((stringp separator)
    946 		 (format "^ *\\|%s" separator))
    947 		(t (error "This should not happen"))))
    948       (while (re-search-forward re end t)
    949 	(replace-match "| " t t)))
    950     (goto-char beg)
    951     (org-table-align)))
    952 
    953 ;;;###autoload
    954 (defun org-table-import (file separator)
    955   "Import FILE as a table.
    956 
    957 The command tries to be smart and figure out the separator in the
    958 following way:
    959 
    960 - when each line contains a TAB, assume TAB-separated material;
    961 - when each line contains a comma, assume CSV material;
    962 - else, assume one or more SPACE characters as separator.
    963 
    964 When non-nil, SEPARATOR specifies the field separator in the
    965 lines.  It can have the following values:
    966 
    967 - (4)     Use the comma as a field separator.
    968 - (16)    Use a TAB as field separator.
    969 - (64)    Prompt for a regular expression as field separator.
    970 - integer When a number, use that many spaces, or a TAB, as field separator.
    971 - regexp  When a regular expression, use it to match the separator."
    972   (interactive "f\nP")
    973   (when (and (called-interactively-p 'any)
    974 	     (not (string-match-p (rx "." (or "txt" "tsv" "csv") eos) file))
    975              (not (yes-or-no-p "The file's extension is not .txt, .tsv or .csv.  Import? ")))
    976     (user-error "Cannot import such file"))
    977   (unless (bolp) (insert "\n"))
    978   (let ((beg (point))
    979 	(pm (point-max)))
    980     (insert-file-contents file)
    981     (org-table-convert-region beg (+ (point) (- (point-max) pm)) separator)))
    982 
    983 (defun org-table-convert ()
    984   "Convert from Org table to table.el and back.
    985 Obviously, this only works within limits.  When an Org table is converted
    986 to table.el, all horizontal separator lines get lost, because table.el uses
    987 these as cell boundaries and has no notion of horizontal lines.  A table.el
    988 table can be converted to an Org table only if it does not do row or column
    989 spanning.  Multiline cells will become multiple cells.  Beware, Org mode
    990 does not test if the table can be successfully converted - it blindly
    991 applies a recipe that works for simple tables."
    992   (interactive)
    993   (require 'table)
    994   (if (org-at-table.el-p)
    995       ;; convert to Org table
    996       (let ((beg (copy-marker (org-table-begin t)))
    997 	    (end (copy-marker (org-table-end t))))
    998 	(table-unrecognize-region beg end)
    999 	(goto-char beg)
   1000 	(while (re-search-forward "^\\([ \t]*\\)\\+-.*\n" end t)
   1001 	  (replace-match ""))
   1002 	(goto-char beg))
   1003     (if (org-at-table-p)
   1004 	;; convert to table.el table
   1005 	(let ((beg (copy-marker (org-table-begin)))
   1006 	      (end (copy-marker (org-table-end))))
   1007 	  ;; first, get rid of all horizontal lines
   1008 	  (goto-char beg)
   1009 	  (while (re-search-forward "^\\([ \t]*\\)|-.*\n" end t)
   1010 	    (replace-match ""))
   1011 	  ;; insert a hline before first
   1012 	  (goto-char beg)
   1013 	  (org-table-insert-hline 'above)
   1014 	  (forward-line -2)
   1015 	  ;; insert a hline after each line
   1016 	  (while (progn (forward-line 2) (< (point) end))
   1017 	    (org-table-insert-hline))
   1018 	  (goto-char beg)
   1019 	  (setq end (move-marker end (org-table-end)))
   1020 	  ;; replace "+" at beginning and ending of hlines
   1021 	  (while (re-search-forward "^\\([ \t]*\\)|-" end t)
   1022 	    (replace-match "\\1+-"))
   1023 	  (goto-char beg)
   1024 	  (while (re-search-forward "-|[ \t]*$" end t)
   1025 	    (replace-match "-+"))
   1026 	  (goto-char beg)))))
   1027 
   1028 
   1029 ;;; Navigation and Structure Editing
   1030 
   1031 ;;;###autoload
   1032 (defun org-table-begin (&optional table-type)
   1033   "Find the beginning of the table and return its position.
   1034 With a non-nil optional argument TABLE-TYPE, return the beginning
   1035 of a table.el-type table.  This function assumes point is on
   1036 a table."
   1037   (cond (table-type
   1038 	 (org-element-post-affiliated (org-element-at-point)))
   1039 	((save-excursion
   1040 	   (and (re-search-backward org-table-border-regexp nil t)
   1041 		(line-beginning-position 2))))
   1042 	(t (point-min))))
   1043 
   1044 ;;;###autoload
   1045 (defun org-table-end (&optional table-type)
   1046   "Find the end of the table and return its position.
   1047 With a non-nil optional argument TABLE-TYPE, return the end of
   1048 a table.el-type table.  This function assumes point is on
   1049 a table."
   1050   (save-excursion
   1051     (cond (table-type
   1052 	   (goto-char (org-element-end (org-element-at-point)))
   1053 	   (skip-chars-backward " \t\n")
   1054 	   (line-beginning-position 2))
   1055 	  ((re-search-forward org-table-border-regexp nil t)
   1056 	   (match-beginning 0))
   1057 	  ;; When the line right after the table is the last line in
   1058 	  ;; the buffer with trailing spaces but no final newline
   1059 	  ;; character, be sure to catch the correct ending at its
   1060 	  ;; beginning.  In any other case, ending is expected to be
   1061 	  ;; at point max.
   1062 	  (t (goto-char (point-max))
   1063 	     (skip-chars-backward " \t")
   1064 	     (if (bolp) (point) (line-end-position))))))
   1065 
   1066 ;;;###autoload
   1067 (defun org-table-next-field ()
   1068   "Go to the next field in the current table, creating new lines as needed.
   1069 Before doing so, re-align the table if necessary."
   1070   (interactive)
   1071   (org-table-maybe-eval-formula)
   1072   (org-table-maybe-recalculate-line)
   1073   (when (and org-table-automatic-realign
   1074 	     org-table-may-need-update)
   1075     (org-table-align))
   1076   (let ((end (org-table-end)))
   1077     (if (org-at-table-hline-p)
   1078 	(end-of-line 1))
   1079     (condition-case nil
   1080 	(progn
   1081 	  (re-search-forward "|" end)
   1082 	  (if (looking-at "[ \t]*$")
   1083 	      (re-search-forward "|" end))
   1084 	  (if (and (looking-at "-")
   1085 		   org-table-tab-jumps-over-hlines
   1086 		   (re-search-forward "^[ \t]*|\\([^-]\\)" end t))
   1087 	      (goto-char (match-beginning 1)))
   1088 	  (if (looking-at "-")
   1089 	      (progn
   1090 		(forward-line -1)
   1091 		(org-table-insert-row 'below))
   1092 	    (if (looking-at " ") (forward-char 1))))
   1093       (error
   1094        (org-table-insert-row 'below)))))
   1095 
   1096 ;;;###autoload
   1097 (defun org-table-previous-field ()
   1098   "Go to the previous field in the table.
   1099 Before doing so, re-align the table if necessary."
   1100   (interactive)
   1101   (org-table-justify-field-maybe)
   1102   (org-table-maybe-recalculate-line)
   1103   (when (and org-table-automatic-realign
   1104 	     org-table-may-need-update)
   1105     (org-table-align))
   1106   (when (org-at-table-hline-p)
   1107     (end-of-line))
   1108   (let ((start (org-table-begin))
   1109 	(origin (point)))
   1110     (condition-case nil
   1111 	(progn
   1112 	  (search-backward "|" start nil 2)
   1113 	  (while (looking-at-p "|\\(?:-\\|[ \t]*$\\)")
   1114 	    (search-backward "|" start)))
   1115       (error
   1116        (goto-char origin)
   1117        (user-error "Cannot move to previous table field"))))
   1118   (when (looking-at "| ?")
   1119     (goto-char (match-end 0))))
   1120 
   1121 (defun org-table-beginning-of-field (&optional n)
   1122   "Move to the beginning of the current table field.
   1123 If already at or before the beginning, move to the beginning of the
   1124 previous field.
   1125 With numeric argument N, move N-1 fields backward first."
   1126   (interactive "p")
   1127   (let ((pos (point)))
   1128     (while (> n 1)
   1129       (setq n (1- n))
   1130       (org-table-previous-field))
   1131     (if (not (re-search-backward "|" (line-beginning-position 0) t))
   1132 	(user-error "No more table fields before the current")
   1133       (goto-char (match-end 0))
   1134       (and (looking-at " ") (forward-char 1)))
   1135     (when (>= (point) pos) (org-table-beginning-of-field 2))))
   1136 
   1137 (defun org-table-end-of-field (&optional n)
   1138   "Move to the end of the current table field.
   1139 If already at or after the end, move to the end of the next table field.
   1140 With numeric argument N, move N-1 fields forward first."
   1141   (interactive "p")
   1142   (let ((pos (point)))
   1143     (while (> n 1)
   1144       (setq n (1- n))
   1145       (org-table-next-field))
   1146     (when (re-search-forward "|" (line-end-position 1) t)
   1147       (backward-char 1)
   1148       (skip-chars-backward " ")
   1149       (when (and (equal (char-before (point)) ?|) (equal (char-after (point)) ?\s))
   1150 	(forward-char 1)))
   1151     (when (<= (point) pos) (org-table-end-of-field 2))))
   1152 
   1153 ;;;###autoload
   1154 (defun org-table-next-row ()
   1155   "Go to the next row (same column) in the current table.
   1156 When next row is an hline or outside the table, create a new empty
   1157 row.  Before doing so, re-align the table if necessary."
   1158   (interactive)
   1159   (org-table-maybe-eval-formula)
   1160   (org-table-maybe-recalculate-line)
   1161   (if (and org-table-automatic-realign
   1162 	   org-table-may-need-update)
   1163       (org-table-align))
   1164   (let ((col (org-table-current-column)))
   1165     (forward-line 1)
   1166     (unless (bolp) (insert "\n"))	;missing newline at eob
   1167     (when (or (not (org-at-table-p))
   1168 	      (org-at-table-hline-p))
   1169       (forward-line -1)
   1170       (org-table-insert-row 'below))
   1171     (org-table-goto-column col)
   1172     (skip-chars-backward "^|\n\r")
   1173     (when (looking-at " ") (forward-char))))
   1174 
   1175 (defun org-table-get (line column)
   1176   "Get the field in table line LINE, column COLUMN.
   1177 If LINE is larger than the number of data lines in the table, the function
   1178 returns nil.  However, if COLUMN is too large, we will simply return an
   1179 empty string.
   1180 If LINE is nil, use the current line.
   1181 If COLUMN is nil, use the current column."
   1182   (setq column (or column (org-table-current-column)))
   1183   (save-excursion
   1184     (and (or (not line) (org-table-goto-line line))
   1185 	 (org-trim (org-table-get-field column)))))
   1186 
   1187 (defun org-table-put (line column value &optional align)
   1188   "Put VALUE into line LINE, column COLUMN.
   1189 When ALIGN is set, also realign the table."
   1190   (setq column (or column (org-table-current-column)))
   1191   (prog1 (save-excursion
   1192 	   (and (or (not line) (org-table-goto-line line))
   1193 		(progn (org-table-goto-column column nil 'force) t)
   1194 		(org-table-get-field column value)))
   1195     (and align (org-table-align))))
   1196 
   1197 (defun org-table-current-line ()
   1198   "Return the index of the current data line."
   1199   (let ((pos (point)) (end (org-table-end)) (cnt 0))
   1200     (save-excursion
   1201       (goto-char (org-table-begin))
   1202       (while (and (re-search-forward org-table-dataline-regexp end t)
   1203 		  (setq cnt (1+ cnt))
   1204                   (< (line-end-position) pos))))
   1205     cnt))
   1206 
   1207 (defun org-table-current-column ()
   1208   "Return current column number."
   1209   (interactive)
   1210   (save-excursion
   1211     (let ((pos (point)))
   1212       (forward-line 0)
   1213       (if (not (search-forward "|" pos t)) 0
   1214 	(let ((column 1)
   1215 	      (separator (if (org-at-table-hline-p) "[+|]" "|")))
   1216 	  (while (re-search-forward separator pos t) (cl-incf column))
   1217 	  column)))))
   1218 
   1219 (defun org-table-current-dline ()
   1220   "Find out what table data line we are in.
   1221 Only data lines count for this."
   1222   (save-excursion
   1223     (let ((c 0)
   1224 	  (pos (line-beginning-position)))
   1225       (goto-char (org-table-begin))
   1226       (while (<= (point) pos)
   1227 	(when (looking-at org-table-dataline-regexp) (cl-incf c))
   1228 	(forward-line))
   1229       c)))
   1230 
   1231 (defun org-table-goto-line (N)
   1232   "Go to the Nth data line in the current table.
   1233 Return t when the line exists, nil if it does not exist."
   1234   (goto-char (org-table-begin))
   1235   (let ((end (org-table-end)) (cnt 0))
   1236     (while (and (re-search-forward org-table-dataline-regexp end t)
   1237 		(< (setq cnt (1+ cnt)) N)))
   1238     (= cnt N)))
   1239 
   1240 ;;;###autoload
   1241 (defun org-table-blank-field ()
   1242   "Blank the current table field or active region."
   1243   (interactive)
   1244   (org-table-check-inside-data-field)
   1245   (if (and (called-interactively-p 'any) (org-region-active-p))
   1246       (let (org-table-clip)
   1247 	(org-table-cut-region (region-beginning) (region-end)))
   1248     (skip-chars-backward "^|")
   1249     (backward-char 1)
   1250     (if (looking-at "|[^|\n]+")
   1251 	(let* ((pos (match-beginning 0))
   1252 	       (match (match-string 0))
   1253 	       (len (save-match-data (org-string-width match nil 'org-table))))
   1254 	  (replace-match (concat "|" (make-string (1- len) ?\ )))
   1255 	  (goto-char (+ 2 pos))
   1256 	  (substring match 1)))))
   1257 
   1258 (defun org-table-get-field (&optional n replace)
   1259   "Return the value of the field in column N of current row.
   1260 N defaults to current column.  If REPLACE is a string, replace
   1261 field with this value.  The return value is always the old
   1262 value."
   1263   (when n (org-table-goto-column n))
   1264   (skip-chars-backward "^|\n")
   1265   (if (or (bolp) (looking-at-p "[ \t]*$"))
   1266       ;; Before first column or after last one.
   1267       ""
   1268     (looking-at "[^|\r\n]*")
   1269     (let* ((pos (match-beginning 0))
   1270 	   (val (buffer-substring pos (match-end 0))))
   1271       (when replace
   1272 	(org-table-with-shrunk-field
   1273 	 (replace-match (if (equal replace "") " " replace) t t)))
   1274       (goto-char (min (line-end-position) (1+ pos)))
   1275       val)))
   1276 
   1277 ;;;###autoload
   1278 (defun org-table-field-info (_arg)
   1279   "Show info about the current field, and highlight any reference at point."
   1280   (interactive "P")
   1281   (unless (org-at-table-p) (user-error "Not at a table"))
   1282   (org-table-analyze)
   1283   (save-excursion
   1284     (let* ((pos (point))
   1285 	   (col (org-table-current-column))
   1286 	   (cname (car (rassoc (number-to-string col) org-table-column-names)))
   1287 	   (name (car (rassoc (list (count-lines org-table-current-begin-pos
   1288 						 (line-beginning-position))
   1289 				    col)
   1290 			      org-table-named-field-locations)))
   1291 	   (eql (org-table-expand-lhs-ranges
   1292 		 (mapcar
   1293 		  (lambda (e)
   1294 		    (cons (org-table-formula-handle-first/last-rc (car e))
   1295 			  (cdr e)))
   1296 		  (org-table-get-stored-formulas))))
   1297 	   (dline (org-table-current-dline))
   1298 	   (ref (format "@%d$%d" dline col))
   1299 	   (ref1 (org-table-convert-refs-to-an ref))
   1300 	   ;; Prioritize field formulas over column formulas.
   1301 	   (fequation (or (assoc name eql) (assoc ref eql)))
   1302 	   (cequation (assoc (format "$%d" col) eql))
   1303 	   (eqn (or fequation cequation)))
   1304       (let ((p (and eqn (get-text-property 0 :orig-eqn (car eqn)))))
   1305 	(when p (setq eqn p)))
   1306       (goto-char pos)
   1307       (ignore-errors (org-table-show-reference 'local))
   1308       (message "line @%d, col $%s%s, ref @%d$%d or %s%s%s"
   1309 	       dline col
   1310 	       (if cname (concat " or $" cname) "")
   1311 	       dline col ref1
   1312 	       (if name (concat " or $" name) "")
   1313 	       ;; FIXME: formula info not correct if special table line
   1314 	       (if eqn
   1315 		   (concat ", formula: "
   1316 			   (org-table-formula-to-user
   1317 			    (concat
   1318 			     (if (or (string-prefix-p "$" (car eqn))
   1319 				     (string-prefix-p "@" (car eqn)))
   1320 				 ""
   1321 			       "$")
   1322 			     (car eqn) "=" (cdr eqn))))
   1323 		 "")))))
   1324 
   1325 (defun org-table-goto-field (ref &optional create-column-p)
   1326   "Move point to a specific field in the current table.
   1327 
   1328 REF is either the name of a field its absolute reference, as
   1329 a string.  No column is created unless CREATE-COLUMN-P is
   1330 non-nil.  If it is a function, it is called with the column
   1331 number as its argument as is used as a predicate to know if the
   1332 column can be created.
   1333 
   1334 This function assumes the table is already analyzed (i.e., using
   1335 `org-table-analyze')."
   1336   (let* ((coordinates
   1337 	  (cond
   1338 	   ((cdr (assoc ref org-table-named-field-locations)))
   1339 	   ((string-match "\\`@\\([1-9][0-9]*\\)\\$\\([1-9][0-9]*\\)\\'" ref)
   1340 	    (list (condition-case nil
   1341 		      (aref org-table-dlines
   1342 			    (string-to-number (match-string 1 ref)))
   1343 		    (error (user-error "Invalid row number in %s" ref)))
   1344 		  (string-to-number (match-string 2 ref))))
   1345 	   (t (user-error "Unknown field: %s" ref))))
   1346 	 (line (car coordinates))
   1347 	 (column (nth 1 coordinates))
   1348 	 (create-new-column (if (functionp create-column-p)
   1349 				(funcall create-column-p column)
   1350 			      create-column-p)))
   1351     (when coordinates
   1352       (goto-char org-table-current-begin-pos)
   1353       (forward-line line)
   1354       (org-table-goto-column column nil create-new-column))))
   1355 
   1356 ;;;###autoload
   1357 (defun org-table-goto-column (n &optional on-delim force)
   1358   "Move the cursor to the Nth column in the current table line.
   1359 With optional argument ON-DELIM, stop with point before the left delimiter
   1360 of the field.
   1361 If there are less than N fields, just go to after the last delimiter.
   1362 However, when FORCE is non-nil, create new columns if necessary."
   1363   (interactive "p")
   1364   (forward-line 0)
   1365   (when (> n 0)
   1366     (while (and (> (setq n (1- n)) -1)
   1367                 (or (search-forward "|" (line-end-position) t)
   1368 		    (and force
   1369 			 (progn (end-of-line 1)
   1370 				(skip-chars-backward "^|")
   1371 				(insert " | ")
   1372 				t)))))
   1373     (when (and force (not (looking-at ".*|")))
   1374       (save-excursion (end-of-line 1) (insert " | ")))
   1375     (if on-delim
   1376 	(backward-char 1)
   1377       (if (looking-at " ") (forward-char 1)))))
   1378 
   1379 ;;;###autoload
   1380 (defun org-table-insert-column ()
   1381   "Insert a new column into the table."
   1382   (interactive)
   1383   (unless (org-at-table-p) (user-error "Not at a table"))
   1384   (when (eobp) (save-excursion (insert "\n")))
   1385   (unless (string-match-p "|[ \t]*$" (org-current-line-string))
   1386     (org-table-align))
   1387   (org-table-find-dataline)
   1388   (let ((col (max 1 (org-table-current-column)))
   1389 	(beg (org-table-begin))
   1390 	(end (copy-marker (org-table-end)))
   1391 	(shrunk-columns (org-table--list-shrunk-columns)))
   1392     (org-table-expand beg end)
   1393     (save-excursion
   1394       (goto-char beg)
   1395       (while (< (point) end)
   1396 	(unless (org-at-table-hline-p)
   1397 	  (org-table-goto-column col t)
   1398 	  (insert "|"))
   1399 	(forward-line)))
   1400     (org-table-goto-column col)
   1401     (org-table-align)
   1402     ;; Shift appropriately stored shrunk column numbers, then hide the
   1403     ;; columns again.
   1404     (org-table--shrink-columns (mapcar (lambda (c) (if (< c col) c (1+ c)))
   1405 				       shrunk-columns)
   1406 			       beg end)
   1407     (set-marker end nil)
   1408     ;; Fix TBLFM formulas, if desirable.
   1409     (when (or (not org-table-fix-formulas-confirm)
   1410 	      (funcall org-table-fix-formulas-confirm "Fix formulas? "))
   1411       (org-table-fix-formulas "$" nil (1- col) 1))))
   1412 
   1413 (defun org-table-find-dataline ()
   1414   "Find a data line in the current table, which is needed for column commands.
   1415 This function assumes point is in a table.  Raise an error when
   1416 there is no data row below."
   1417   (or (not (org-at-table-hline-p))
   1418       (let ((col (current-column))
   1419 	    (end (org-table-end)))
   1420 	(forward-line)
   1421 	(while (and (< (point) end) (org-at-table-hline-p))
   1422 	  (forward-line))
   1423 	(when (>= (point) end)
   1424 	  (user-error "Cannot find data row for column operation"))
   1425 	(org-move-to-column col)
   1426 	t)))
   1427 
   1428 (defun org-table-line-to-dline (line &optional above)
   1429   "Turn a buffer line number into a data line number.
   1430 
   1431 If there is no data line in this line, return nil.
   1432 
   1433 If there is no matching dline (most likely the reference was
   1434 a hline), the first dline below it is used.  When ABOVE is
   1435 non-nil, the one above is used."
   1436   (let ((min 1)
   1437 	(max (1- (length org-table-dlines))))
   1438     (cond ((or (> (aref org-table-dlines min) line)
   1439 	       (< (aref org-table-dlines max) line))
   1440 	   nil)
   1441 	  ((= line (aref org-table-dlines max)) max)
   1442 	  (t (catch 'exit
   1443 	       (while (> (- max min) 1)
   1444 		 (let* ((mean (/ (+ max min) 2))
   1445 			(v (aref org-table-dlines mean)))
   1446 		   (cond ((= v line) (throw 'exit mean))
   1447 			 ((> v line) (setq max mean))
   1448 			 (t (setq min mean)))))
   1449 	       (cond ((= line (aref org-table-dlines max)) max)
   1450 		     ((= line (aref org-table-dlines min)) min)
   1451 		     (above min)
   1452 		     (t max)))))))
   1453 
   1454 (defun org-table--swap-cells (row1 col1 row2 col2)
   1455   "Swap two cells indicated by the coordinates provided.
   1456 ROW1, COL1, ROW2, COL2 are integers indicating the row/column
   1457 position of the two cells that will be swapped in the table."
   1458   (let ((content1 (org-table-get row1 col1))
   1459 	(content2 (org-table-get row2 col2)))
   1460     (org-table-put row1 col1 content2)
   1461     (org-table-put row2 col2 content1)))
   1462 
   1463 (defun org-table--move-cell (direction)
   1464   "Move the current cell in a cardinal direction.
   1465 DIRECTION is a symbol among `up', `down', `left', and `right'.
   1466 The contents the current cell are swapped with cell in the
   1467 indicated direction.  Raise an error if the move cannot be done."
   1468   (let ((row-shift (pcase direction (`up -1) (`down 1) (_ 0)))
   1469 	(column-shift (pcase direction (`left -1) (`right 1) (_ 0))))
   1470     (when (and (= 0 row-shift) (= 0 column-shift))
   1471       (error "Invalid direction: %S" direction))
   1472     ;; Initialize `org-table-current-ncol' and `org-table-dlines'.
   1473     (org-table-analyze)
   1474     (let* ((row (org-table-current-line))
   1475 	   (column (org-table-current-column))
   1476 	   (target-row (+ row row-shift))
   1477 	   (target-column (+ column column-shift))
   1478 	   (org-table-current-nrow (1- (length org-table-dlines))))
   1479       (when (or (< target-column 1)
   1480 		(< target-row 1)
   1481 		(> target-column org-table-current-ncol)
   1482 		(> target-row org-table-current-nrow))
   1483 	(user-error "Cannot move cell further"))
   1484       (org-table--swap-cells row column target-row target-column)
   1485       (org-table-goto-line target-row)
   1486       (org-table-goto-column target-column))))
   1487 
   1488 ;;;###autoload
   1489 (defun org-table-move-cell-up ()
   1490   "Move a single cell up in a table.
   1491 Swap with anything in target cell."
   1492   (interactive)
   1493   (unless (org-table-check-inside-data-field)
   1494     (error "No table at point"))
   1495   (org-table--move-cell 'up)
   1496   (org-table-align))
   1497 
   1498 ;;;###autoload
   1499 (defun org-table-move-cell-down ()
   1500   "Move a single cell down in a table.
   1501 Swap with anything in target cell."
   1502   (interactive)
   1503   (unless (org-table-check-inside-data-field)
   1504     (error "No table at point"))
   1505   (org-table--move-cell 'down)
   1506   (org-table-align))
   1507 
   1508 ;;;###autoload
   1509 (defun org-table-move-cell-left ()
   1510   "Move a single cell left in a table.
   1511 Swap with anything in target cell."
   1512   (interactive)
   1513   (unless (org-table-check-inside-data-field)
   1514     (error "No table at point"))
   1515   (org-table--move-cell 'left)
   1516   (org-table-align))
   1517 
   1518 ;;;###autoload
   1519 (defun org-table-move-cell-right ()
   1520   "Move a single cell right in a table.
   1521 Swap with anything in target cell."
   1522   (interactive)
   1523   (unless (org-table-check-inside-data-field)
   1524     (error "No table at point"))
   1525   (org-table--move-cell 'right)
   1526   (org-table-align))
   1527 
   1528 ;;;###autoload
   1529 (defun org-table-delete-column ()
   1530   "Delete a column from the table."
   1531   (interactive)
   1532   (unless (org-at-table-p) (user-error "Not at a table"))
   1533   (org-table-find-dataline)
   1534   (when (save-excursion (skip-chars-forward " \t") (eolp))
   1535     (search-backward "|"))		;snap into last column
   1536   (org-table-check-inside-data-field nil t)
   1537   (let* ((col (org-table-current-column))
   1538 	 (beg (org-table-begin))
   1539 	 (end (copy-marker (org-table-end)))
   1540 	 (shrunk-columns (remq col (org-table--list-shrunk-columns))))
   1541     (org-table-expand beg end)
   1542     (org-table-save-field
   1543      (goto-char beg)
   1544      (while (< (point) end)
   1545        (if (org-at-table-hline-p)
   1546 	   nil
   1547 	 (org-table-goto-column col t)
   1548 	 (and (looking-at "|[^|\n]+|")
   1549 	      (replace-match "|")))
   1550        (forward-line)))
   1551     (org-table-align)
   1552     ;; Shift appropriately stored shrunk column numbers, then hide the
   1553     ;; columns again.
   1554     (org-table--shrink-columns (mapcar (lambda (c) (if (< c col) c (1- c)))
   1555 				       shrunk-columns)
   1556 			       beg end)
   1557     (set-marker end nil)
   1558     ;; Fix TBLFM formulas, if desirable.
   1559     (when (or (not org-table-fix-formulas-confirm)
   1560 	      (funcall org-table-fix-formulas-confirm "Fix formulas? "))
   1561       (org-table-fix-formulas
   1562        "$" (list (cons (number-to-string col) "INVALID")) col -1 col))))
   1563 
   1564 ;;;###autoload
   1565 (defun org-table-move-column-right ()
   1566   "Move column to the right."
   1567   (interactive)
   1568   (org-table-move-column nil))
   1569 
   1570 ;;;###autoload
   1571 (defun org-table-move-column-left ()
   1572   "Move column to the left."
   1573   (interactive)
   1574   (org-table-move-column 'left))
   1575 
   1576 ;;;###autoload
   1577 (defun org-table-move-column (&optional left)
   1578   "Move the current column to the right.  With arg LEFT, move to the left."
   1579   (interactive "P")
   1580   (unless (org-at-table-p) (user-error "Not at a table"))
   1581   (org-table-find-dataline)
   1582   (org-table-check-inside-data-field nil t)
   1583   (let* ((col (org-table-current-column))
   1584 	 (col1 (if left (1- col) col))
   1585 	 (colpos (if left (1- col) (1+ col)))
   1586 	 (beg (org-table-begin))
   1587 	 (end (copy-marker (org-table-end))))
   1588     (when (and left (= col 1))
   1589       (user-error "Cannot move column further left"))
   1590     (when (and (not left) (looking-at "[^|\n]*|[^|\n]*$"))
   1591       (user-error "Cannot move column further right"))
   1592     (let ((shrunk-columns (org-table--list-shrunk-columns)))
   1593       (org-table-expand beg end)
   1594       (org-table-save-field
   1595        (goto-char beg)
   1596        (while (< (point) end)
   1597 	 (unless (org-at-table-hline-p)
   1598 	   (org-table-goto-column col1 t)
   1599 	   (when (looking-at "|\\([^|\n]+\\)|\\([^|\n]+\\)|")
   1600 	     (transpose-regions
   1601 	      (match-beginning 1) (match-end 1)
   1602 	      (match-beginning 2) (match-end 2))))
   1603 	 (forward-line)))
   1604       (org-table-goto-column colpos)
   1605       (org-table-align)
   1606       ;; Shift appropriately stored shrunk column numbers, then shrink
   1607       ;; the columns again.
   1608       (org-table--shrink-columns
   1609        (mapcar (lambda (c)
   1610 		 (cond ((and (= col c) left) (1- c))
   1611 		       ((= col c) (1+ c))
   1612 		       ((and (= col (1+ c)) left) (1+ c))
   1613 		       ((and (= col (1- c)) (not left) (1- c)))
   1614 		       (t c)))
   1615 	       shrunk-columns)
   1616        beg end)
   1617       (set-marker end nil)
   1618       ;; Fix TBLFM formulas, if desirable.
   1619       (when (or (not org-table-fix-formulas-confirm)
   1620 		(funcall org-table-fix-formulas-confirm "Fix formulas? "))
   1621 	(org-table-fix-formulas
   1622 	 "$" (list (cons (number-to-string col) (number-to-string colpos))
   1623 		   (cons (number-to-string colpos) (number-to-string col))))))))
   1624 
   1625 ;;;###autoload
   1626 (defun org-table-move-row-down ()
   1627   "Move table row down."
   1628   (interactive)
   1629   (org-table-move-row nil))
   1630 
   1631 ;;;###autoload
   1632 (defun org-table-move-row-up ()
   1633   "Move table row up."
   1634   (interactive)
   1635   (org-table-move-row 'up))
   1636 
   1637 ;;;###autoload
   1638 (defun org-table-move-row (&optional up)
   1639   "Move the current table line down.  With arg UP, move it up."
   1640   (interactive "P")
   1641   (let* ((col (current-column))
   1642 	 (pos (point))
   1643 	 (hline1p (save-excursion (forward-line 0)
   1644 				  (looking-at org-table-hline-regexp)))
   1645 	 (dline1 (org-table-current-dline))
   1646 	 (dline2 (+ dline1 (if up -1 1)))
   1647 	 (tonew (if up -1 1))
   1648 	 hline2p)
   1649     (when (and up (= (point-min) (line-beginning-position)))
   1650       (user-error "Cannot move row further"))
   1651     (forward-line tonew)
   1652     (when (or (and (not up) (eobp)) (not (org-at-table-p)))
   1653       (goto-char pos)
   1654       (user-error "Cannot move row further"))
   1655     (org-table-with-shrunk-columns
   1656      (setq hline2p (looking-at org-table-hline-regexp))
   1657      (goto-char pos)
   1658      (let ((row (delete-and-extract-region (line-beginning-position)
   1659 					   (line-beginning-position 2))))
   1660        (forward-line tonew)
   1661        (unless (bolp) (insert "\n"))	;at eob without a newline
   1662        (insert row)
   1663        (unless (bolp) (insert "\n"))	;missing final newline in ROW
   1664        (forward-line -1)
   1665        (org-move-to-column col)
   1666        (unless (or hline1p hline2p
   1667 		   (not (or (not org-table-fix-formulas-confirm)
   1668 			  (funcall org-table-fix-formulas-confirm
   1669 				   "Fix formulas? "))))
   1670 	 (org-table-fix-formulas
   1671 	  "@" (list
   1672 	       (cons (number-to-string dline1) (number-to-string dline2))
   1673 	       (cons (number-to-string dline2) (number-to-string dline1)))))))))
   1674 
   1675 ;;;###autoload
   1676 (defun org-table-insert-row (&optional arg)
   1677   "Insert a new row above the current line into the table.
   1678 With prefix ARG, insert below the current line."
   1679   (interactive "P")
   1680   (unless (org-at-table-p) (user-error "Not at a table"))
   1681   (when (eobp) (save-excursion (insert "\n")))
   1682   (unless (string-match-p "|[ \t]*$" (org-current-line-string))
   1683     (org-table-align))
   1684   (org-table-with-shrunk-columns
   1685    (let* ((line (buffer-substring (line-beginning-position) (line-end-position)))
   1686 	  (new (org-table-clean-line line)))
   1687      ;; Fix the first field if necessary
   1688      (when (string-match "^[ \t]*| *[#*$] *|" line)
   1689        (setq new (replace-match (match-string 0 line) t t new)))
   1690      (forward-line (if arg 1 0))
   1691      ;; Buffer may not end of a newline character, so ensure
   1692      ;; (forward-line 1) moves point to a new line.
   1693      (unless (bolp) (insert "\n"))
   1694      (let (org-table-may-need-update) (insert-before-markers new "\n"))
   1695      (forward-line -1)
   1696      (re-search-forward "| ?" (line-end-position) t)
   1697      (when (or org-table-may-need-update org-table-overlay-coordinates)
   1698        (org-table-align))
   1699      (when (or (not org-table-fix-formulas-confirm)
   1700 	       (funcall org-table-fix-formulas-confirm "Fix formulas? "))
   1701        (org-table-fix-formulas "@" nil (1- (org-table-current-dline)) 1)))))
   1702 
   1703 ;;;###autoload
   1704 (defun org-table-insert-hline (&optional above)
   1705   "Insert a horizontal-line below the current line into the table.
   1706 With prefix ABOVE, insert above the current line."
   1707   (interactive "P")
   1708   (unless (org-at-table-p) (user-error "Not at a table"))
   1709   (when (eobp) (save-excursion (insert "\n")))
   1710   (unless (string-match-p "|[ \t]*$" (org-current-line-string))
   1711     (org-table-align))
   1712   (org-table-with-shrunk-columns
   1713    (let ((line (org-table-clean-line
   1714                 (buffer-substring (line-beginning-position) (line-end-position))))
   1715 	 (col (current-column)))
   1716      (while (string-match "|\\( +\\)|" line)
   1717        (setq line (replace-match
   1718 		   (concat "+" (make-string (- (match-end 1) (match-beginning 1))
   1719 					    ?-) "|") t t line)))
   1720      (and (string-match "\\+" line) (setq line (replace-match "|" t t line)))
   1721      (forward-line (if above 0 1))
   1722      (insert line "\n")
   1723      (forward-line (if above 0 -2))
   1724      (org-move-to-column col)
   1725      (when org-table-overlay-coordinates (org-table-align)))))
   1726 
   1727 ;;;###autoload
   1728 (defun org-table-hline-and-move (&optional same-column)
   1729   "Insert a hline and move to the row below that line."
   1730   (interactive "P")
   1731   (let ((col (org-table-current-column)))
   1732     (org-table-maybe-eval-formula)
   1733     (org-table-maybe-recalculate-line)
   1734     (org-table-insert-hline)
   1735     (end-of-line 2)
   1736     (if (looking-at "\n[ \t]*|-")
   1737 	(progn (insert "\n|") (org-table-align))
   1738       (org-table-next-field))
   1739     (if same-column (org-table-goto-column col))))
   1740 
   1741 (defun org-table-clean-line (s)
   1742   "Convert a table line S into a string with only \"|\" and space.
   1743 In particular, this does handle wide and invisible characters."
   1744   (if (string-match "^[ \t]*|-" s)
   1745       ;; It's a hline, just map the characters
   1746       (setq s (mapconcat (lambda (x) (if (member x '(?| ?+)) "|" " ")) s ""))
   1747     (while (string-match "|\\([ \t]*?[^ \t\r\n|][^\r\n|]*\\)|" s)
   1748       (setq s (replace-match
   1749 	       (concat "|"
   1750                        (make-string
   1751                         (save-match-data
   1752                           (org-string-width (match-string 1 s) nil 'org-table))
   1753 			?\ )
   1754                        "|")
   1755 	       t t s)))
   1756     s))
   1757 
   1758 ;;;###autoload
   1759 (defun org-table-kill-row ()
   1760   "Delete the current row or horizontal line from the table."
   1761   (interactive)
   1762   (unless (org-at-table-p) (user-error "Not at a table"))
   1763   (let ((col (current-column))
   1764 	(dline (and (not (org-match-line org-table-hline-regexp))
   1765 		    (org-table-current-dline))))
   1766     (org-table-with-shrunk-columns
   1767      (kill-region (line-beginning-position)
   1768                   (min (1+ (line-end-position)) (point-max)))
   1769      (if (not (org-at-table-p)) (forward-line -1))
   1770      (org-move-to-column col)
   1771      (when (and dline
   1772 		(or (not org-table-fix-formulas-confirm)
   1773 		    (funcall org-table-fix-formulas-confirm "Fix formulas? ")))
   1774        (org-table-fix-formulas
   1775 	"@" (list (cons (number-to-string dline) "INVALID")) dline -1 dline)))))
   1776 
   1777 ;;;###autoload
   1778 (defun org-table-cut-region (beg end)
   1779   "Copy region in table to the clipboard and blank all relevant fields.
   1780 If there is no active region, use just the field at point."
   1781   (interactive (list
   1782 		(if (org-region-active-p) (region-beginning) (point))
   1783 		(if (org-region-active-p) (region-end) (point))))
   1784   (org-table-copy-region beg end 'cut))
   1785 
   1786 (defun org-table--increment-field (field previous)
   1787   "Increment string FIELD according to PREVIOUS field.
   1788 
   1789 Increment FIELD only if it is a string representing a number, per
   1790 Emacs Lisp syntax, a timestamp, or is either prefixed or suffixed
   1791 with a number.  In any other case, return FIELD as-is.
   1792 
   1793 If PREVIOUS has the same structure as FIELD, e.g.,
   1794 a number-prefixed string with the same pattern, the increment
   1795 step is the difference between numbers (or timestamps, measured
   1796 in days) in PREVIOUS and FIELD.  Otherwise, it uses
   1797 `org-table-copy-increment', if the variable contains a number, or
   1798 default to 1.
   1799 
   1800 The function assumes `org-table-copy-increment' is non-nil."
   1801   (let* ((default-step (if (numberp org-table-copy-increment)
   1802 			   org-table-copy-increment
   1803 			 1))
   1804 	 (number-regexp			;Lisp read syntax for numbers
   1805 	  (rx (and string-start
   1806 		   (opt (any "+-"))
   1807 		   (or (and (one-or-more digit) (opt "."))
   1808 		       (and (zero-or-more digit) "." (one-or-more digit)))
   1809 		   (opt (any "eE") (opt (opt (any "+-")) (one-or-more digit)))
   1810 		   string-end)))
   1811 	 (number-prefix-regexp (rx (and string-start (one-or-more digit))))
   1812 	 (number-suffix-regexp (rx (and (one-or-more digit) string-end)))
   1813 	 (analyze
   1814 	  (lambda (field)
   1815 	    ;; Analyze string FIELD and return information related to
   1816 	    ;; increment or nil.  When non-nil, return value has the
   1817 	    ;; following scheme: (TYPE VALUE PATTERN) where
   1818 	    ;; - TYPE is a symbol among `number', `prefix', `suffix'
   1819 	    ;;   and `timestamp',
   1820 	    ;; - VALUE is a timestamp if TYPE is `timestamp', or
   1821 	    ;;   a number otherwise,
   1822 	    ;; - PATTERN is the field without its prefix, or suffix if
   1823 	    ;;   TYPE is either `prefix' or `suffix' , or nil
   1824 	    ;;   otherwise.
   1825 	    (cond ((not (org-string-nw-p field)) nil)
   1826 		  ((string-match-p number-regexp field)
   1827 		   (list 'number
   1828 			 (string-to-number field)
   1829 			 nil))
   1830 		  ((string-match number-prefix-regexp field)
   1831 		   (list 'prefix
   1832 			 (string-to-number (match-string 0 field))
   1833 			 (substring field (match-end 0))))
   1834 		  ((string-match number-suffix-regexp field)
   1835 		   (list 'suffix
   1836 			 (string-to-number (match-string 0 field))
   1837 			 (substring field 0 (match-beginning 0))))
   1838 		  ((string-match-p org-ts-regexp3 field)
   1839 		   (list 'timestamp field nil))
   1840 		  (t nil))))
   1841 	 (next-number-string
   1842 	  (lambda (n1 &optional n2)
   1843 	    ;; Increment number N1 and return it as a string.  If N2
   1844 	    ;; is also a number, deduce increment step from the
   1845 	    ;; difference between N1 and N2.  Otherwise, increment
   1846 	    ;; step is `default-step'.
   1847 	    (number-to-string (if n2 (+ n1 (- n1 n2)) (+ n1 default-step)))))
   1848 	 (shift-timestamp
   1849 	  (lambda (t1 &optional t2)
   1850 	    ;; Increment timestamp T1 and return it.  If T2 is also
   1851 	    ;; a timestamp, deduce increment step from the difference,
   1852 	    ;; in days, between T1 and T2.  Otherwise, increment by
   1853 	    ;; `default-step' days.
   1854 	    (with-temp-buffer
   1855 	      (insert t1)
   1856 	      (org-timestamp-up-day (if (not t2) default-step
   1857 				      (- (org-time-string-to-absolute t1)
   1858 					 (org-time-string-to-absolute t2))))
   1859 	      (buffer-string)))))
   1860     ;; Check if both PREVIOUS and FIELD have the same type.  Also, if
   1861     ;; the case of prefixed or suffixed numbers, make sure their
   1862     ;; pattern, i.e., the part of the string without the prefix or the
   1863     ;; suffix, is the same.
   1864     (pcase (cons (funcall analyze field) (funcall analyze previous))
   1865       (`((number ,n1 ,_) . (number ,n2 ,_))
   1866        (funcall next-number-string n1 n2))
   1867       (`((number ,n ,_) . ,_)
   1868        (funcall next-number-string n))
   1869       (`((prefix ,n1 ,p1) . (prefix ,n2 ,p2))
   1870        (concat (funcall next-number-string n1 (and (equal p1 p2) n2)) p1))
   1871       (`((prefix ,n ,p) . ,_)
   1872        (concat (funcall next-number-string n) p))
   1873       (`((suffix ,n1 ,p1) . (suffix ,n2 ,p2))
   1874        (concat p1 (funcall next-number-string n1 (and (equal p1 p2) n2))))
   1875       (`((suffix ,n ,p) . ,_)
   1876        (concat p (funcall next-number-string n)))
   1877       (`((timestamp ,t1 ,_) . (timestamp ,t2 ,_))
   1878        (funcall shift-timestamp t1 t2))
   1879       (`((timestamp ,t1 ,_) . ,_)
   1880        (funcall shift-timestamp t1))
   1881       (_ field))))
   1882 
   1883 ;;;###autoload
   1884 (defun org-table-copy-down (n)
   1885   "Copy the value of the current field one row below.
   1886 
   1887 If the field at the cursor is empty, copy the content of the
   1888 nearest non-empty field above.  With argument N, use the Nth
   1889 non-empty field.
   1890 
   1891 If the current field is not empty, it is copied down to the next
   1892 row, and the cursor is moved with it.  Therefore, repeating this
   1893 command causes the column to be filled row-by-row.
   1894 
   1895 If the variable `org-table-copy-increment' is non-nil and the
   1896 field is a number, a timestamp, or is either prefixed or suffixed
   1897 with a number, it will be incremented while copying.  By default,
   1898 increment by the difference between the value in the current
   1899 field and the one in the field above, if any.  To increment using
   1900 a fixed integer, set `org-table-copy-increment' to a number.  In
   1901 the case of a timestamp, increment by days.
   1902 
   1903 However, when N is 0, do not increment the field at all."
   1904   (interactive "p")
   1905   (org-table-check-inside-data-field)
   1906   (let* ((beg (org-table-begin))
   1907 	 (column (org-table-current-column))
   1908 	 (initial-field (save-excursion
   1909 			  (let ((f (org-string-nw-p (org-table-get-field))))
   1910 			    (and f (org-trim f)))))
   1911 	 field field-above next-field)
   1912     (save-excursion
   1913       ;; Get reference field.
   1914       (if initial-field (setq field initial-field)
   1915 	(forward-line 0)
   1916 	(setq field
   1917 	      (catch :exit
   1918 		(while (re-search-backward org-table-dataline-regexp beg t)
   1919 		  (let ((f (org-string-nw-p (org-table-get-field column))))
   1920 		    (cond ((and (> n 1) f) (cl-decf n))
   1921 			  (f (throw :exit (org-trim f)))
   1922 			  (t nil))
   1923 		    (forward-line 0)))
   1924 		(user-error "No non-empty field found"))))
   1925       ;; Check if increment is appropriate, and how it should be done.
   1926       (when (and org-table-copy-increment (/= n 0))
   1927 	;; If increment step is not explicit, get non-empty field just
   1928 	;; above the field being incremented to guess it.
   1929 	(unless (numberp org-table-copy-increment)
   1930 	  (setq field-above
   1931 		(let ((f (unless (= beg (line-beginning-position))
   1932 			   (forward-line -1)
   1933 			   (not (org-at-table-hline-p))
   1934 			   (org-table-get-field column))))
   1935 		  (and (org-string-nw-p f)
   1936 		       (org-trim f)))))
   1937 	;; Compute next field.
   1938 	(setq next-field (org-table--increment-field field field-above))))
   1939     ;; Since initial field in not empty, we modify row below instead.
   1940     ;; Skip alignment since we do it at the end of the process anyway.
   1941     (when initial-field
   1942       (let ((org-table-may-need-update nil)) (org-table-next-row))
   1943       (org-table-blank-field))
   1944     ;; Insert the new field.  NEW-FIELD may be nil if
   1945     ;; `org-table-copy-increment' is nil, or N = 0.  In that case,
   1946     ;; copy FIELD.
   1947     (insert (or next-field field))
   1948     (org-table-maybe-recalculate-line)
   1949     (org-table-align)))
   1950 
   1951 ;;;###autoload
   1952 (defun org-table-copy-region (beg end &optional cut)
   1953   "Copy rectangular region in table to clipboard.
   1954 A special clipboard is used which can only be accessed with
   1955 `org-table-paste-rectangle'.  Return the region copied, as a list
   1956 of lists of fields."
   1957   (interactive (list
   1958 		(if (org-region-active-p) (region-beginning) (point))
   1959 		(if (org-region-active-p) (region-end) (point))
   1960 		current-prefix-arg))
   1961   (goto-char (min beg end))
   1962   (org-table-check-inside-data-field)
   1963   (let ((beg (line-beginning-position))
   1964 	(c01 (org-table-current-column))
   1965 	region)
   1966     (goto-char (max beg end))
   1967     (org-table-check-inside-data-field nil t)
   1968     (let* ((end (copy-marker (line-end-position)))
   1969 	   (c02 (org-table-current-column))
   1970 	   (column-start (min c01 c02))
   1971 	   (column-end (max c01 c02))
   1972 	   (column-number (1+ (- column-end column-start)))
   1973 	   (rpl (and cut "  ")))
   1974       (goto-char beg)
   1975       (while (< (point) end)
   1976 	(unless (org-at-table-hline-p)
   1977 	  ;; Collect every cell between COLUMN-START and COLUMN-END.
   1978 	  (let (cols)
   1979 	    (dotimes (c column-number)
   1980 	      (push (org-table-get-field (+ c column-start) rpl) cols))
   1981 	    (push (nreverse cols) region)))
   1982 	(forward-line))
   1983       (set-marker end nil))
   1984     (when cut (org-table-align))
   1985     (when (called-interactively-p 'any)
   1986       (message (substitute-command-keys "Cells in the region copied, use \
   1987 \\[org-table-paste-rectangle] to paste them in a table.")))
   1988     (setq org-table-clip (nreverse region))))
   1989 
   1990 ;;;###autoload
   1991 (defun org-table-paste-rectangle ()
   1992   "Paste a rectangular region into a table.
   1993 The upper right corner ends up in the current field.  All involved fields
   1994 will be overwritten.  If the rectangle does not fit into the present table,
   1995 the table is enlarged as needed.  The process ignores horizontal separator
   1996 lines."
   1997   (interactive)
   1998   (unless (consp org-table-clip)
   1999     (user-error "First cut/copy a region to paste!"))
   2000   (org-table-check-inside-data-field)
   2001   (let* ((column (org-table-current-column))
   2002 	 (org-table-automatic-realign nil))
   2003     (org-table-save-field
   2004      (dolist (row org-table-clip)
   2005        (while (org-at-table-hline-p) (forward-line))
   2006        ;; If we left the table, create a new row.
   2007        (when (and (bolp) (not (looking-at "[ \t]*|")))
   2008 	 (end-of-line 0)
   2009 	 (org-table-next-field))
   2010        (let ((c column))
   2011 	 (dolist (field row)
   2012 	   (org-table-goto-column c nil 'force)
   2013 	   (org-table-get-field nil field)
   2014 	   (cl-incf c)))
   2015        (forward-line)))
   2016     (org-table-align)))
   2017 
   2018 
   2019 ;;; Follow Field minor mode
   2020 
   2021 (define-minor-mode org-table-follow-field-mode
   2022   "Minor mode to make the table field editor window follow the cursor.
   2023 When this mode is active, the field editor window will always show the
   2024 current field.  The mode exits automatically when the cursor leaves the
   2025 table (but see `org-table-exit-follow-field-mode-when-leaving-table')."
   2026   :lighter " TblFollow"
   2027   (if org-table-follow-field-mode
   2028       (add-hook 'post-command-hook 'org-table-follow-fields-with-editor
   2029 		'append 'local)
   2030     (remove-hook 'post-command-hook 'org-table-follow-fields-with-editor 'local)
   2031     (let* ((buf (get-buffer "*Org Table Edit Field*"))
   2032 	   (win (and buf (get-buffer-window buf))))
   2033       (when win (delete-window win))
   2034       (when buf
   2035 	(with-current-buffer buf
   2036 	  (move-marker org-field-marker nil))
   2037 	(kill-buffer buf)))))
   2038 
   2039 ;;;###autoload
   2040 (defun org-table-edit-field (arg)
   2041   "Edit table field in a different window.
   2042 This is mainly useful for fields that contain hidden parts.
   2043 
   2044 When called with a `\\[universal-argument]' prefix, just make the full field
   2045 visible so that it can be edited in place.
   2046 
   2047 When called with a `\\[universal-argument] \\[universal-argument]' prefix, \
   2048 toggle `org-table-follow-field-mode'."
   2049   (interactive "P")
   2050   (unless (org-at-table-p) (user-error "Not at a table"))
   2051   (cond
   2052    ((equal arg '(16))
   2053     (org-table-follow-field-mode (if org-table-follow-field-mode -1 1)))
   2054    (arg
   2055     (let ((b (save-excursion (skip-chars-backward "^|") (point)))
   2056 	  (e (save-excursion (skip-chars-forward "^|\r\n") (point))))
   2057       (remove-text-properties b e '(invisible t intangible t))
   2058       (if font-lock-mode
   2059 	  (font-lock-fontify-block))))
   2060    (t
   2061     (let ((pos (point-marker))
   2062 	  (coord
   2063 	   (if (eq org-table-use-standard-references t)
   2064 	       (concat (org-number-to-letters (org-table-current-column))
   2065 		       (number-to-string (org-table-current-dline)))
   2066 	     (concat "@" (number-to-string (org-table-current-dline))
   2067 		     "$" (number-to-string (org-table-current-column)))))
   2068 	  (field (org-table-get-field))
   2069 	  (cw (current-window-configuration))
   2070 	  p)
   2071       (goto-char pos)
   2072       (switch-to-buffer-other-window "*Org Table Edit Field*")
   2073       (when (and (local-variable-p 'org-field-marker)
   2074 		 (markerp org-field-marker))
   2075 	(move-marker org-field-marker nil))
   2076       (erase-buffer)
   2077       (insert "#\n# Edit field " coord " and finish with C-c C-c\n#\n")
   2078       (let ((org-inhibit-startup t)) (org-mode))
   2079       (auto-fill-mode -1)
   2080       (setq truncate-lines nil)
   2081       (setq word-wrap t)
   2082       (goto-char (setq p (point-max)))
   2083       (insert (org-trim field))
   2084       (remove-text-properties p (point-max) '(invisible t intangible t))
   2085       (goto-char p)
   2086       (setq-local org-finish-function 'org-table-finish-edit-field)
   2087       (setq-local org-window-configuration cw)
   2088       (setq-local org-field-marker pos)
   2089       (message "Edit and finish with C-c C-c")))))
   2090 
   2091 (defun org-table-follow-fields-with-editor ()
   2092   (if (and org-table-exit-follow-field-mode-when-leaving-table
   2093 	   (not (org-at-table-p)))
   2094       ;; We have left the table, exit the follow mode
   2095       (org-table-follow-field-mode -1)
   2096     (when (org-table-check-inside-data-field 'noerror)
   2097       (let ((win (selected-window)))
   2098 	(org-table-edit-field nil)
   2099 	(org-fit-window-to-buffer)
   2100 	(select-window win)))))
   2101 
   2102 (defun org-table-finish-edit-field ()
   2103   "Finish editing a table data field.
   2104 Remove all newline characters, insert the result into the table, realign
   2105 the table and kill the editing buffer."
   2106   (let ((pos org-field-marker)
   2107 	(cw org-window-configuration)
   2108 	(cb (current-buffer))
   2109 	text)
   2110     (goto-char (point-min))
   2111     (while (re-search-forward "^#.*\n?" nil t) (replace-match ""))
   2112     (while (re-search-forward "[ \t]*\n[ \t\n]*" nil t)
   2113       (replace-match " "))
   2114     (setq text (org-trim (buffer-string)))
   2115     (set-window-configuration cw)
   2116     (kill-buffer cb)
   2117     (select-window (get-buffer-window (marker-buffer pos)))
   2118     (goto-char pos)
   2119     (move-marker pos nil)
   2120     (org-table-check-inside-data-field)
   2121     (org-table-get-field nil text)
   2122     (org-table-align)
   2123     (message "New field value inserted")))
   2124 
   2125 
   2126 ;;; Formulas
   2127 
   2128 (defun org-table-current-field-formula (&optional key noerror)
   2129   "Return the formula active for the current field.
   2130 
   2131 Assumes that table is already analyzed.  If KEY is given, return
   2132 the key to this formula.  Otherwise return the formula preceded
   2133 with \"=\" or \":=\"."
   2134   (let* ((line (count-lines org-table-current-begin-pos
   2135 			    (line-beginning-position)))
   2136 	 (row (org-table-line-to-dline line)))
   2137     (cond
   2138      (row
   2139       (let* ((col (org-table-current-column))
   2140 	     (name (car (rassoc (list line col)
   2141 				org-table-named-field-locations)))
   2142 	     (scol (format "$%d" col))
   2143 	     (ref (format "@%d$%d" (org-table-current-dline) col))
   2144 	     (stored-list (org-table-get-stored-formulas noerror))
   2145 	     (ass (or (assoc name stored-list)
   2146 		      (assoc ref stored-list)
   2147 		      (assoc scol stored-list))))
   2148 	(cond (key (car ass))
   2149 	      (ass (concat (if (string-match-p "^[0-9]+$" (car ass)) "=" ":=")
   2150 			   (cdr ass))))))
   2151      (noerror nil)
   2152      (t (error "No formula active for the current field")))))
   2153 
   2154 (defun org-table-get-formula (&optional equation named)
   2155   "Read a formula from the minibuffer, offer stored formula as default.
   2156 When NAMED is non-nil, look for a named equation."
   2157   (let* ((stored-list (org-table-get-stored-formulas))
   2158 	 (name (car (rassoc (list (count-lines org-table-current-begin-pos
   2159 					       (line-beginning-position))
   2160 				  (org-table-current-column))
   2161 			    org-table-named-field-locations)))
   2162 	 (ref (format "@%d$%d"
   2163 		      (org-table-current-dline)
   2164 		      (org-table-current-column)))
   2165 	 (scol (cond
   2166 		((not named) (format "$%d" (org-table-current-column)))
   2167 		(name)
   2168 		(t ref)))
   2169 	 (name (or name ref))
   2170 	 (org-table-may-need-update nil)
   2171 	 (stored (cdr (assoc scol stored-list)))
   2172 	 (eq (cond
   2173 	      ((and stored equation (string-match-p "^ *=? *$" equation))
   2174 	       stored)
   2175 	      ((stringp equation) equation)
   2176 	      (t
   2177 	       (org-table-formula-from-user
   2178 		(read-string
   2179 		 (org-table-formula-to-user
   2180 		  (format "%s formula %s=" (if named "Field" "Column") scol))
   2181 		 (if stored (org-table-formula-to-user stored) "")
   2182 		 'org-table-formula-history)))))
   2183 	 mustsave)
   2184     (unless (org-string-nw-p eq)
   2185       ;; Remove formula.
   2186       (setq stored-list (delq (assoc scol stored-list) stored-list))
   2187       (org-table-store-formulas stored-list)
   2188       (user-error "Formula removed"))
   2189     (when (string-match "^ *=?" eq) (setq eq (replace-match "" t t eq)))
   2190     (when (string-match " *$" eq) (setq eq (replace-match "" t t eq)))
   2191     (when (and name (not named))
   2192       ;; We set the column equation, delete the named one.
   2193       (setq stored-list (delq (assoc name stored-list) stored-list)
   2194 	    mustsave t))
   2195     (if stored
   2196 	(setcdr (assoc scol stored-list) eq)
   2197       (setq stored-list (cons (cons scol eq) stored-list)))
   2198     (when (or mustsave (not (equal stored eq)))
   2199       (org-table-store-formulas stored-list))
   2200     eq))
   2201 
   2202 (defun org-table-store-formulas (alist &optional location)
   2203   "Store the list of formulas below the current table.
   2204 If optional argument LOCATION is a buffer position, insert it at
   2205 LOCATION instead."
   2206   (save-excursion
   2207     (if location
   2208 	(progn (goto-char location) (forward-line 0))
   2209       (goto-char (org-table-end)))
   2210     (let ((case-fold-search t))
   2211       (if (looking-at "\\([ \t]*\n\\)*[ \t]*\\(#\\+TBLFM:\\)\\(.*\n?\\)")
   2212 	  (progn
   2213 	    ;; Don't overwrite TBLFM, we might use text properties to
   2214 	    ;; store stuff.
   2215 	    (goto-char (match-beginning 3))
   2216 	    (delete-region (match-beginning 3) (match-end 0)))
   2217 	(org-indent-line)
   2218 	(insert "#+TBLFM:"))
   2219       (insert " "
   2220 	      (mapconcat (lambda (x) (concat (car x) "=" (cdr x)))
   2221 			 (sort alist #'org-table-formula-less-p)
   2222 			 "::")
   2223 	      "\n"))))
   2224 
   2225 (defsubst org-table-formula-make-cmp-string (a)
   2226   (when (string-match "\\`\\$[<>]" a)
   2227     (let ((arrow (string-to-char (substring a 1))))
   2228       ;; Fake a high number to make sure this is sorted at the end.
   2229       (setq a (org-table-formula-handle-first/last-rc a))
   2230       (setq a (format "$%d" (+ 10000
   2231 			       (if (= arrow ?<) -1000 0)
   2232 			       (string-to-number (substring a 1)))))))
   2233   (when (string-match
   2234 	 "^\\(@\\([0-9]+\\)\\)?\\(\\$?\\([0-9]+\\)\\)?\\(\\$?[a-zA-Z0-9]+\\)?"
   2235 	 a)
   2236     (concat
   2237      (if (match-end 2)
   2238 	 (format "@%05d" (string-to-number (match-string 2 a))) "")
   2239      (if (match-end 4)
   2240 	 (format "$%05d" (string-to-number (match-string 4 a))) "")
   2241      (if (match-end 5)
   2242 	 (concat "@@" (match-string 5 a))))))
   2243 
   2244 (defun org-table-formula-less-p (a b)
   2245   "Compare two formulas for sorting."
   2246   (let ((as (org-table-formula-make-cmp-string (car a)))
   2247 	(bs (org-table-formula-make-cmp-string (car b))))
   2248     (and as bs (string< as bs))))
   2249 
   2250 ;;;###autoload
   2251 (defun org-table-get-stored-formulas (&optional noerror location)
   2252   "Return an alist with the stored formulas directly after current table.
   2253 By default, only return active formulas, i.e., formulas located
   2254 on the first line after the table.  However, if optional argument
   2255 LOCATION is a buffer position, consider the formulas there."
   2256   (save-excursion
   2257     (if location
   2258 	(progn (goto-char location) (forward-line 0))
   2259       (goto-char (org-table-end)))
   2260     (let ((case-fold-search t))
   2261       (when (looking-at "\\([ \t]*\n\\)*[ \t]*#\\+TBLFM: *\\(.*\\)")
   2262 	(let ((strings (org-split-string (match-string-no-properties 2)
   2263 					 " *:: *"))
   2264 	      eq-alist seen)
   2265 	  (dolist (string strings (nreverse eq-alist))
   2266 	    (when (string-match "\\`\\(@[-+I<>0-9.$@]+\\|\\$\\([_a-zA-Z0-9]+\\|\
   2267 \[<>]+\\)\\) *= *\\(.*[^ \t]\\)"
   2268 				string)
   2269 	      (let ((lhs
   2270 		     (let ((m (match-string 1 string)))
   2271 		       (cond
   2272 			((not (match-end 2)) m)
   2273 			;; Is it a column reference?
   2274 			((string-match-p "\\`\\$\\([0-9]+\\|[<>]+\\)\\'" m) m)
   2275 			;; Since named columns are not possible in
   2276 			;; LHS, assume this is a named field.
   2277 			(t (match-string 2 string)))))
   2278 		    (rhs (match-string 3 string)))
   2279 		(push (cons lhs rhs) eq-alist)
   2280 		(cond
   2281 		 ((not (member lhs seen)) (push lhs seen))
   2282 		 (noerror
   2283 		  (message
   2284 		   "Double definition `%s=' in TBLFM line, please fix by hand"
   2285 		   lhs)
   2286 		  (ding)
   2287 		  (sit-for 2))
   2288 		 (t
   2289 		  (user-error
   2290 		   "Double definition `%s=' in TBLFM line, please fix by hand"
   2291 		   lhs)))))))))))
   2292 
   2293 (defun org-table-fix-formulas (key replace &optional limit delta remove)
   2294   "Modify the equations after the table structure has been edited.
   2295 KEY is \"@\" or \"$\".  REPLACE is an alist of numbers to replace.
   2296 For all numbers larger than LIMIT, shift them by DELTA."
   2297   (save-excursion
   2298     (goto-char (org-table-end))
   2299     (while (let ((case-fold-search t)) (looking-at "[ \t]*#\\+tblfm:"))
   2300       (let ((re (concat key "\\([0-9]+\\)"))
   2301 	    (re2
   2302 	     (when remove
   2303 	       (if (equal key "$")
   2304 		   (format "\\(@[0-9]+\\)?%s%d=.*?\\(::\\|$\\)"
   2305 			   (regexp-quote key) remove)
   2306 		 (format "@%d\\$[0-9]+=.*?\\(::\\|$\\)" remove))))
   2307 	    s n a)
   2308 	(when remove
   2309           (save-excursion
   2310             (while (re-search-forward re2 (line-end-position) t)
   2311 	      (unless (save-match-data (org-in-regexp "remote([^)]+?)"))
   2312 	        (if (equal (char-before (match-beginning 0)) ?.)
   2313 		    (user-error
   2314 		     "Change makes TBLFM term %s invalid, use undo to recover"
   2315 		     (match-string 0))
   2316 		  (replace-match ""))))))
   2317         (while (re-search-forward re (line-end-position) t)
   2318 	  (unless (save-match-data (org-in-regexp "remote([^)]+?)"))
   2319 	    (setq s (match-string 1) n (string-to-number s))
   2320 	    (cond
   2321 	     ((setq a (assoc s replace))
   2322 	      (replace-match (concat key (cdr a)) t t))
   2323 	     ((and limit (> n limit))
   2324 	      (replace-match (concat key (number-to-string (+ n delta))) t t)))))
   2325 	(message "The formulas in #+TBLFM have been updated"))
   2326       (forward-line))))
   2327 
   2328 ;;;###autoload
   2329 (defun org-table-maybe-eval-formula ()
   2330   "Check if the current field starts with \"=\" or \":=\".
   2331 If yes, store the formula and apply it."
   2332   ;; We already know we are in a table.  Get field will only return a formula
   2333   ;; when appropriate.  It might return a separator line, but no problem.
   2334   (when org-table-formula-evaluate-inline
   2335     (let* ((field (org-trim (or (org-table-get-field) "")))
   2336 	   named eq)
   2337       (when (string-match "^:?=\\(.*[^=]\\)$" field)
   2338 	(setq named (equal (string-to-char field) ?:)
   2339 	      eq (match-string 1 field))
   2340 	(org-table-eval-formula (and named '(4))
   2341 				(org-table-formula-from-user eq))))))
   2342 
   2343 ;;;###autoload
   2344 (defun org-table-rotate-recalc-marks (&optional newchar)
   2345   "Rotate the recalculation mark in the first column.
   2346 If in any row, the first field is not consistent with a mark,
   2347 insert a new column for the markers.
   2348 When there is an active region, change all the lines in the region,
   2349 after prompting for the marking character.
   2350 After each change, a message will be displayed indicating the meaning
   2351 of the new mark."
   2352   (interactive)
   2353   (unless (org-at-table-p) (user-error "Not at a table"))
   2354   (let* ((region (org-region-active-p))
   2355 	 (l1 (and region
   2356 		  (save-excursion (goto-char (region-beginning))
   2357 				  (copy-marker (line-beginning-position)))))
   2358 	 (l2 (and region
   2359 		  (save-excursion (goto-char (region-end))
   2360 				  (copy-marker (line-beginning-position)))))
   2361 	 (l (copy-marker (line-beginning-position)))
   2362 	 (col (org-table-current-column))
   2363 	 (newchar (if region
   2364 		      (char-to-string
   2365 		       (read-char-exclusive
   2366 			"Change region to what mark?  Type # * ! $ or SPC: "))
   2367 		    newchar))
   2368 	 (no-special-column
   2369 	  (save-excursion
   2370 	    (goto-char (org-table-begin))
   2371 	    (re-search-forward
   2372 	     "^[ \t]*|[^-|][^|]*[^#!$*_^| \t][^|]*|" (org-table-end) t))))
   2373     (when (and newchar (not (assoc newchar org-recalc-marks)))
   2374       (user-error "Invalid character `%s' in `org-table-rotate-recalc-marks'"
   2375 		  newchar))
   2376     (when l1 (goto-char l1))
   2377     (save-excursion
   2378       (forward-line 0)
   2379       (unless (looking-at org-table-dataline-regexp)
   2380 	(user-error "Not at a table data line")))
   2381     (when no-special-column
   2382       (org-table-goto-column 1)
   2383       (org-table-insert-column))
   2384     (let ((previous-line-end (line-end-position))
   2385 	  (newchar
   2386 	   (save-excursion
   2387 	     (forward-line 0)
   2388 	     (cond ((not (looking-at "^[ \t]*| *\\([#!$*^_ ]\\) *|")) "#")
   2389 		   (newchar)
   2390 		   (t (cadr (member (match-string 1)
   2391 				    (append (mapcar #'car org-recalc-marks)
   2392 					    '(" ")))))))))
   2393       ;; Rotate mark in first row.
   2394       (org-table-get-field 1 (format " %s " newchar))
   2395       ;; Rotate marks in additional rows if a region is active.
   2396       (when region
   2397 	(save-excursion
   2398 	  (forward-line)
   2399 	  (while (<= (point) l2)
   2400 	    (when (looking-at org-table-dataline-regexp)
   2401 	      (org-table-get-field 1 (format " %s " newchar)))
   2402 	    (forward-line))))
   2403       ;; Only align if rotation actually changed lines' length.
   2404       (when (/= previous-line-end (line-end-position)) (org-table-align)))
   2405     (goto-char l)
   2406     (org-table-goto-column (if no-special-column (1+ col) col))
   2407     (when l1 (set-marker l1 nil))
   2408     (when l2 (set-marker l2 nil))
   2409     (set-marker l nil)
   2410     (when (called-interactively-p 'interactive)
   2411       (message "%s" (cdr (assoc newchar org-recalc-marks))))))
   2412 
   2413 ;;;###autoload
   2414 (defun org-table-maybe-recalculate-line ()
   2415   "Recompute the current line if marked for it, and if we haven't just done it."
   2416   (interactive)
   2417   (and org-table-allow-automatic-line-recalculation
   2418        (not (and (memq last-command org-recalc-commands)
   2419 	       (eq org-last-recalc-line (line-beginning-position))))
   2420        (save-excursion (forward-line 0)
   2421 		       (looking-at org-table-auto-recalculate-regexp))
   2422        (org-table-recalculate) t))
   2423 
   2424 ;;;###autoload
   2425 (defun org-table-eval-formula (&optional arg equation
   2426 					 suppress-align suppress-const
   2427 					 suppress-store suppress-analysis)
   2428   "Replace the table field value at the cursor by the result of a calculation.
   2429 
   2430 In a table, this command replaces the value in the current field with the
   2431 result of a formula.  It also installs the formula as the \"current\" column
   2432 formula, by storing it in a special line below the table.  When called
   2433 with a `\\[universal-argument]' prefix the formula is installed as a \
   2434 field formula.
   2435 
   2436 When called with a `\\[universal-argument] \\[universal-argument]' prefix, \
   2437 insert the active equation for the field
   2438 back into the current field, so that it can be edited there.  This is \
   2439 useful
   2440 in order to use \\<org-table-fedit-map>`\\[org-table-show-reference]' to \
   2441 check the referenced fields.
   2442 
   2443 When called, the command first prompts for a formula, which is read in
   2444 the minibuffer.  Previously entered formulas are available through the
   2445 history list, and the last used formula is offered as a default.
   2446 These stored formulas are adapted correctly when moving, inserting, or
   2447 deleting columns with the corresponding commands.
   2448 
   2449 The formula can be any algebraic expression understood by the Calc package.
   2450 For details, see the Org mode manual.
   2451 
   2452 This function can also be called from Lisp programs and offers
   2453 additional arguments: EQUATION can be the formula to apply.  If this
   2454 argument is given, the user will not be prompted.
   2455 
   2456 SUPPRESS-ALIGN is used to speed-up recursive calls by by-passing
   2457 unnecessary aligns.
   2458 
   2459 SUPPRESS-CONST suppresses the interpretation of constants in the
   2460 formula, assuming that this has been done already outside the
   2461 function.
   2462 
   2463 SUPPRESS-STORE means the formula should not be stored, either
   2464 because it is already stored, or because it is a modified
   2465 equation that should not overwrite the stored one.
   2466 
   2467 SUPPRESS-ANALYSIS prevents analyzing the table and checking
   2468 location of point."
   2469   (interactive "P")
   2470   (unless suppress-analysis
   2471     (org-table-check-inside-data-field nil t)
   2472     (org-table-analyze))
   2473   (if (equal arg '(16))
   2474       (let ((eq (org-table-current-field-formula)))
   2475 	(org-table-get-field nil eq)
   2476 	(org-table-align)
   2477 	(setq org-table-may-need-update t))
   2478     (let* (fields
   2479 	   (ndown (if (integerp arg) arg 1))
   2480 	   (org-table-automatic-realign nil)
   2481 	   (case-fold-search nil)
   2482 	   (down (> ndown 1))
   2483 	   (formula (if (and equation suppress-store)
   2484 			equation
   2485 		      (org-table-get-formula equation (equal arg '(4)))))
   2486 	   (n0 (org-table-current-column))
   2487 	   (calc-modes (copy-sequence org-calc-default-modes))
   2488 	   (numbers nil)	   ; was a variable, now fixed default
   2489 	   (keep-empty nil)
   2490 	   form form0 formrpl formrg bw fmt ev orig lispp literal
   2491 	   duration duration-output-format)
   2492       ;; Parse the format string.  Since we have a lot of modes, this is
   2493       ;; a lot of work.  However, I think calc still uses most of the time.
   2494       (if (string-match "\\(.*\\);\\(.*\\)" formula)
   2495 	  (progn
   2496 	    (setq fmt (concat (cdr (assoc "%" org-table-local-parameters))
   2497 			      (match-string-no-properties 2 formula)))
   2498 	    (setq formula (match-string-no-properties 1 formula))
   2499 	    (while (string-match "\\([pnfse]\\)\\(-?[0-9]+\\)" fmt)
   2500 	      (let ((c (string-to-char (match-string 1 fmt)))
   2501 		    (n (string-to-number (match-string 2 fmt))))
   2502 		(cl-case c
   2503 		  (?p (setf (cl-getf calc-modes 'calc-internal-prec) n))
   2504 		  (?n (setf (cl-getf calc-modes 'calc-float-format) (list 'float n)))
   2505 		  (?f (setf (cl-getf calc-modes 'calc-float-format) (list 'fix n)))
   2506 		  (?s (setf (cl-getf calc-modes 'calc-float-format) (list 'sci n)))
   2507 		  (?e (setf (cl-getf calc-modes 'calc-float-format) (list 'eng n)))))
   2508 	      ;; Remove matched flags from the mode string.
   2509 	      (setq fmt (replace-match "" t t fmt)))
   2510 	    (while (string-match "\\([tTUNLEDRFSu]\\)" fmt)
   2511 	      (let ((c (string-to-char (match-string 1 fmt))))
   2512 		(cl-case c
   2513 		  (?t (setq duration t numbers t
   2514                             duration-output-format org-table-duration-custom-format))
   2515 		  (?T (setq duration t numbers t duration-output-format nil))
   2516 		  (?U (setq duration t numbers t duration-output-format 'hh:mm))
   2517 		  (?N (setq numbers t))
   2518 		  (?L (setq literal t))
   2519 		  (?E (setq keep-empty t))
   2520 		  (?D (setf (cl-getf calc-modes 'calc-angle-mode) 'deg))
   2521 		  (?R (setf (cl-getf calc-modes 'calc-angle-mode) 'rad))
   2522 		  (?F (setf (cl-getf calc-modes 'calc-prefer-frac) t))
   2523 		  (?S (setf (cl-getf calc-modes 'calc-symbolic-mode) t))
   2524 		  (?u (setf (cl-getf calc-modes 'calc-simplify-mode) 'units))))
   2525 	      ;; Remove matched flags from the mode string.
   2526 	      (setq fmt (replace-match "" t t fmt)))
   2527 	    (unless (string-match "\\S-" fmt)
   2528 	      (setq fmt nil))))
   2529       (when (and (not suppress-const) org-table-formula-use-constants)
   2530 	(setq formula (org-table-formula-substitute-names formula)))
   2531       (setq orig (or (get-text-property 1 :orig-formula formula) "?"))
   2532       (setq formula (org-table-formula-handle-first/last-rc formula))
   2533       (while (> ndown 0)
   2534 	(setq fields (org-split-string
   2535 		      (org-trim
   2536 		       (buffer-substring-no-properties
   2537 			(line-beginning-position) (line-end-position)))
   2538 		      " *| *"))
   2539 	;; replace fields with duration values if relevant
   2540 	(if duration
   2541 	    (setq fields
   2542 		  (mapcar (lambda (x) (org-table-time-string-to-seconds x))
   2543 			  fields)))
   2544 	(if (eq numbers t)
   2545 	    (setq fields (mapcar
   2546 			  (lambda (x)
   2547 			    (if (string-match "\\S-" x)
   2548 				(number-to-string (string-to-number x))
   2549 			      x))
   2550 			  fields)))
   2551 	(setq ndown (1- ndown))
   2552 	(setq form (copy-sequence formula)
   2553 	      lispp (and (> (length form) 2) (equal (substring form 0 2) "'(")))
   2554 	(if (and lispp literal) (setq lispp 'literal))
   2555 
   2556 	;; Insert row and column number of formula result field
   2557 	(while (string-match "[@$]#" form)
   2558 	  (setq form
   2559 		(replace-match
   2560 		 (format "%d"
   2561 			 (save-match-data
   2562 			   (if (equal (substring form (match-beginning 0)
   2563 						 (1+ (match-beginning 0)))
   2564 				      "@")
   2565 			       (org-table-current-dline)
   2566 			     (org-table-current-column))))
   2567 		 t t form)))
   2568 
   2569 	;; Check for old vertical references
   2570 	(org-table--error-on-old-row-references form)
   2571 	;; Insert remote references
   2572 	(setq form (org-table-remote-reference-indirection form))
   2573 	(while (string-match "\\<remote([ \t]*\\([^,)]+\\)[ \t]*,[ \t]*\\([^\n)]+\\))" form)
   2574 	  (setq form
   2575 		(replace-match
   2576 		 (save-match-data
   2577 		   (org-table-make-reference
   2578 		    (let ((rmtrng (org-table-get-remote-range
   2579 				   (match-string 1 form) (match-string 2 form))))
   2580 		      (if duration
   2581 			  (if (listp rmtrng)
   2582 			      (mapcar (lambda(x) (org-table-time-string-to-seconds x)) rmtrng)
   2583 			    (org-table-time-string-to-seconds rmtrng))
   2584 			rmtrng))
   2585 		    keep-empty numbers lispp))
   2586 		 t t form)))
   2587 	;; Insert complex ranges
   2588 	(while (and (string-match org-table-range-regexp form)
   2589 		    (> (length (match-string 0 form)) 1))
   2590 	  (setq formrg
   2591 		(save-match-data
   2592 		  (org-table-get-range
   2593 		   (match-string 0 form) org-table-current-begin-pos n0)))
   2594 	  (setq formrpl
   2595 		(save-match-data
   2596 		  (org-table-make-reference
   2597 		   ;; possibly handle durations
   2598 		   (if duration
   2599 		       (if (listp formrg)
   2600 			   (mapcar (lambda(x) (org-table-time-string-to-seconds x)) formrg)
   2601 			 (org-table-time-string-to-seconds formrg))
   2602 		     formrg)
   2603 		   keep-empty numbers lispp)))
   2604 	  (if (not (save-match-data
   2605 		     (string-match (regexp-quote form) formrpl)))
   2606 	      (setq form (replace-match formrpl t t form))
   2607 	    (user-error "Spreadsheet error: invalid reference \"%s\"" form)))
   2608 	;; Insert simple ranges, i.e. included in the current row.
   2609 	(while (string-match
   2610 		"\\$\\(\\([-+]\\)?[0-9]+\\)\\.\\.\\$\\(\\([-+]\\)?[0-9]+\\)"
   2611 		form)
   2612 	  (setq form
   2613 		(replace-match
   2614 		 (save-match-data
   2615 		   (org-table-make-reference
   2616 		    (cl-subseq fields
   2617 			       (+ (if (match-end 2) n0 0)
   2618 				  (string-to-number (match-string 1 form))
   2619 				  -1)
   2620 			       (+ (if (match-end 4) n0 0)
   2621 				  (string-to-number (match-string 3 form))))
   2622 		    keep-empty numbers lispp))
   2623 		 t t form)))
   2624 	(setq form0 form)
   2625 	;; Insert the references to fields in same row
   2626 	(while (string-match "\\$\\(\\([-+]\\)?[0-9]+\\)" form)
   2627 	  (let* ((n (+ (string-to-number (match-string 1 form))
   2628 		       (if (match-end 2) n0 0)))
   2629 		 (x (nth (1- (if (= n 0) n0 (max n 1))) fields)))
   2630 	    (setq formrpl (save-match-data
   2631 			    (org-table-make-reference
   2632 			     x keep-empty numbers lispp)))
   2633 	    (when (or (not x)
   2634 		      (save-match-data
   2635 			(string-match (regexp-quote formula) formrpl)))
   2636 	      (user-error "Invalid field specifier \"%s\""
   2637 			  (match-string 0 form))))
   2638 	  (setq form (replace-match formrpl t t form)))
   2639 
   2640 	(if lispp
   2641 	    (setq ev (condition-case nil
   2642                          ;; FIXME: Arbitrary code evaluation.
   2643 			 (eval (eval (read form)))
   2644 		       (error "#ERROR"))
   2645 		  ev (if (numberp ev) (number-to-string ev) ev)
   2646 		  ev (if duration (org-table-time-seconds-to-string
   2647 				   (string-to-number ev)
   2648 				   duration-output-format)
   2649 		       ev))
   2650 
   2651 	  ;; Use <...> timestamps so that Calc can handle them.
   2652 	  (setq form
   2653 		(replace-regexp-in-string org-ts-regexp-inactive "<\\1>" form))
   2654 	  ;; Internationalize local timestamps by setting locale to
   2655 	  ;; "C".
   2656 	  (setq form
   2657 		(replace-regexp-in-string
   2658 		 org-ts-regexp
   2659 		 (lambda (ts)
   2660 		   (let ((system-time-locale "C"))
   2661 		     (format-time-string
   2662 		      (org-time-stamp-format
   2663 		       (string-match-p "[0-9]\\{1,2\\}:[0-9]\\{2\\}" ts))
   2664 		      (save-match-data (org-time-string-to-time ts)))))
   2665 		 form t t))
   2666 
   2667 	  (setq ev (if (and duration (string-match "^[0-9]+:[0-9]+\\(?::[0-9]+\\)?$" form))
   2668 		       form
   2669 		     (calc-eval (cons form calc-modes)
   2670 				(when (and (not keep-empty) numbers) 'num)))
   2671 		ev (if (and duration
   2672                             ;; When the result is an empty string,
   2673                             ;; keep it empty.
   2674                             ;; See https://list.orgmode.org/orgmode/CAF_DUeEFpNU5UXjE80yB1MB9xj5oVLqG=XadnkqCdzWtakWdPg@mail.gmail.com/
   2675                             (not (string-empty-p ev)))
   2676                        (org-table-time-seconds-to-string
   2677 			(if (string-match "^[0-9]+:[0-9]+\\(?::[0-9]+\\)?$" ev)
   2678 			    (string-to-number (org-table-time-string-to-seconds ev))
   2679 			  (string-to-number ev))
   2680 			duration-output-format)
   2681 		     ev)))
   2682 
   2683 	(when org-table-formula-debug
   2684 	  (let ((wcf (current-window-configuration)))
   2685 	    (with-output-to-temp-buffer "*Substitution History*"
   2686 	      (princ (format "Substitution history of formula
   2687 Orig:   %s
   2688 $xyz->  %s
   2689 @r$c->  %s
   2690 $1->    %s\n" orig formula form0 form))
   2691 	      (if (consp ev)
   2692 		  (princ (format "        %s^\nError:  %s"
   2693 				 (make-string (car ev) ?\-) (nth 1 ev)))
   2694 		(princ (format "Result: %s\nFormat: %s\nFinal:  %s"
   2695 			       ev (or fmt "NONE")
   2696 			       (if fmt (format fmt (string-to-number ev)) ev)))))
   2697 	    (setq bw (get-buffer-window "*Substitution History*"))
   2698 	    (org-fit-window-to-buffer bw)
   2699 	    (unless (and (called-interactively-p 'any) (not ndown))
   2700 	      (unless (let (inhibit-redisplay)
   2701 			(y-or-n-p "Debugging Formula.  Continue to next? "))
   2702 		(org-table-align)
   2703 		(user-error "Abort"))
   2704 	      (delete-window bw)
   2705 	      (message "")
   2706 	      (set-window-configuration wcf))))
   2707 	(when (consp ev) (setq fmt nil ev "#ERROR"))
   2708 	(org-table-justify-field-maybe
   2709 	 (format org-table-formula-field-format
   2710 		 (cond
   2711 		  ((not (stringp ev)) ev)
   2712 		  (fmt (format fmt (string-to-number ev)))
   2713 		  ;; Replace any active time stamp in the result with
   2714 		  ;; an inactive one.  Dates in tables are likely
   2715 		  ;; piece of regular data, not meant to appear in the
   2716 		  ;; agenda.
   2717 		  (t (replace-regexp-in-string org-ts-regexp "[\\1]" ev)))))
   2718 	(if (and down (> ndown 0) (looking-at ".*\n[ \t]*|[^-]"))
   2719 	    (call-interactively 'org-return)
   2720 	  (setq ndown 0)))
   2721       (and down (org-table-maybe-recalculate-line))
   2722       (or suppress-align (and org-table-may-need-update
   2723 			      (org-table-align))))))
   2724 
   2725 (defun org-table-put-field-property (prop value)
   2726   (save-excursion
   2727     (put-text-property (progn (skip-chars-backward "^|") (point))
   2728 		       (progn (skip-chars-forward "^|") (point))
   2729 		       prop value)))
   2730 
   2731 (defun org-table-get-range (desc &optional tbeg col highlight corners-only)
   2732   "Get a calc vector from a column, according to descriptor DESC.
   2733 
   2734 Optional arguments TBEG and COL can give the beginning of the table and
   2735 the current column, to avoid unnecessary parsing.
   2736 
   2737 HIGHLIGHT means just highlight the range.
   2738 
   2739 When CORNERS-ONLY is set, only return the corners of the range as
   2740 a list (line1 column1 line2 column2) where line1 and line2 are
   2741 line numbers relative to beginning of table, or TBEG, and column1
   2742 and column2 are table column numbers."
   2743   (let* ((desc (if (string-match-p "\\`\\$[0-9]+\\.\\.\\$[0-9]+\\'" desc)
   2744 		   (replace-regexp-in-string "\\$" "@0$" desc)
   2745 		 desc))
   2746 	 (col (or col (org-table-current-column)))
   2747 	 (tbeg (or tbeg (org-table-begin)))
   2748 	 (thisline (count-lines tbeg (line-beginning-position))))
   2749     (unless (string-match org-table-range-regexp desc)
   2750       (user-error "Invalid table range specifier `%s'" desc))
   2751     (let ((rangep (match-end 3))
   2752 	  (r1 (let ((r (and (match-end 1) (match-string 1 desc))))
   2753 		(or (save-match-data
   2754 		      (and (org-string-nw-p r)
   2755 			   (org-table--descriptor-line r thisline)))
   2756 		    thisline)))
   2757 	  (r2 (let ((r (and (match-end 4) (match-string 4 desc))))
   2758 		(or (save-match-data
   2759 		      (and (org-string-nw-p r)
   2760 			   (org-table--descriptor-line r thisline)))
   2761 		    thisline)))
   2762 	  (c1 (let ((c (and (match-end 2) (substring (match-string 2 desc) 1))))
   2763 		(if (or (not c) (= (string-to-number c) 0)) col
   2764 		  (+ (string-to-number c)
   2765 		     (if (memq (string-to-char c) '(?- ?+)) col 0)))))
   2766 	  (c2 (let ((c (and (match-end 5) (substring (match-string 5 desc) 1))))
   2767 		(if (or (not c) (= (string-to-number c) 0)) col
   2768 		  (+ (string-to-number c)
   2769 		     (if (memq (string-to-char c) '(?- ?+)) col 0))))))
   2770       (save-excursion
   2771 	(if (and (not corners-only)
   2772 		 (or (not rangep) (and (= r1 r2) (= c1 c2))))
   2773 	    ;; Just one field.
   2774 	    (progn
   2775 	      (forward-line (- r1 thisline))
   2776 	      (while (not (looking-at org-table-dataline-regexp))
   2777 		(forward-line))
   2778 	      (prog1 (org-trim (org-table-get-field c1))
   2779 		(when highlight (org-table-highlight-rectangle))))
   2780 	  ;; A range, return a vector.  First sort the numbers to get
   2781 	  ;; a regular rectangle.
   2782 	  (let ((first-row (min r1 r2))
   2783 		(last-row (max r1 r2))
   2784 		(first-column (min c1 c2))
   2785 		(last-column (max c1 c2)))
   2786 	    (if corners-only (list first-row first-column last-row last-column)
   2787 	      ;; Copy the range values into a list.
   2788 	      (forward-line (- first-row thisline))
   2789 	      (while (not (looking-at org-table-dataline-regexp))
   2790 		(forward-line)
   2791 		(cl-incf first-row))
   2792 	      (org-table-goto-column first-column)
   2793 	      (let ((beg (point)))
   2794 		(forward-line (- last-row first-row))
   2795 		(while (not (looking-at org-table-dataline-regexp))
   2796 		  (forward-line -1))
   2797 		(org-table-goto-column last-column)
   2798 		(let ((end (point)))
   2799 		  (when highlight
   2800 		    (org-table-highlight-rectangle
   2801 		     beg (progn (skip-chars-forward "^|\n") (point))))
   2802 		  ;; Return string representation of calc vector.
   2803 		  (mapcar #'org-trim
   2804 			  (apply #'append
   2805 				 (org-table-copy-region beg end))))))))))))
   2806 
   2807 (defun org-table--descriptor-line (desc cline)
   2808   "Return relative line number corresponding to descriptor DESC.
   2809 The cursor is currently in relative line number CLINE."
   2810   (if (string-match "\\`[0-9]+\\'" desc)
   2811       (aref org-table-dlines (string-to-number desc))
   2812     (when (or (not (string-match
   2813 		    "^\\(\\([-+]\\)?\\(I+\\)\\)?\\(\\([-+]\\)?\\([0-9]+\\)\\)?"
   2814 		    ;;  1  2          3           4  5          6
   2815 		    desc))
   2816 	      (and (not (match-end 3)) (not (match-end 6)))
   2817 	      (and (match-end 3) (match-end 6) (not (match-end 5))))
   2818       (user-error "Invalid row descriptor `%s'" desc))
   2819     (let* ((hn (and (match-end 3) (- (match-end 3) (match-beginning 3))))
   2820 	   (hdir (match-string 2 desc))
   2821 	   (odir (match-string 5 desc))
   2822 	   (on (and (match-end 6) (string-to-number (match-string 6 desc))))
   2823 	   (rel (and (match-end 6)
   2824 		     (or (and (match-end 1) (not (match-end 3)))
   2825 			 (match-end 5)))))
   2826       (when (and hn (not hdir))
   2827 	(setq cline 0)
   2828 	(setq hdir "+")
   2829 	(when (eq (aref org-table-current-line-types 0) 'hline) (cl-decf hn)))
   2830       (when (and (not hn) on (not odir)) (user-error "Should never happen"))
   2831       (when hn
   2832 	(setq cline
   2833 	      (org-table--row-type 'hline hn cline (equal hdir "-") nil desc)))
   2834       (when on
   2835 	(setq cline
   2836 	      (org-table--row-type 'dline on cline (equal odir "-") rel desc)))
   2837       cline)))
   2838 
   2839 (defun org-table--row-type (type n i backwards relative desc)
   2840   "Return relative line of Nth row with type TYPE.
   2841 Search starts from relative line I.  When BACKWARDS in non-nil,
   2842 look before I.  When RELATIVE is non-nil, the reference is
   2843 relative.  DESC is the original descriptor that started the
   2844 search, as a string."
   2845   (let ((l (length org-table-current-line-types)))
   2846     (catch :exit
   2847       (dotimes (_ n)
   2848 	(while (and (cl-incf i (if backwards -1 1))
   2849 		    (>= i 0)
   2850 		    (< i l)
   2851 		    (not (eq (aref org-table-current-line-types i) type))
   2852 		    ;; We are going to cross a hline.  Check if this is
   2853 		    ;; an authorized move.
   2854 		    (cond
   2855 		     ((not relative))
   2856 		     ((not (eq (aref org-table-current-line-types i) 'hline)))
   2857 		     ((eq org-table-relative-ref-may-cross-hline t))
   2858 		     ((eq org-table-relative-ref-may-cross-hline 'error)
   2859 		      (user-error "Row descriptor %s crosses hline" desc))
   2860 		     (t (cl-decf i (if backwards -1 1)) ; Step back.
   2861 			(throw :exit nil)))))))
   2862     (cond ((or (< i 0) (>= i l))
   2863 	   (user-error "Row descriptor %s leads outside table" desc))
   2864 	  ;; The last hline doesn't exist.  Instead, point to last row
   2865 	  ;; in table.
   2866 	  ((= i (1- l)) (1- i))
   2867 	  (t i))))
   2868 
   2869 (defun org-table--error-on-old-row-references (s)
   2870   (when (string-match "&[-+0-9I]" s)
   2871     (user-error "Formula contains old &row reference, please rewrite using @-syntax")))
   2872 
   2873 (defun org-table-make-reference (elements keep-empty numbers lispp)
   2874   "Convert list ELEMENTS to something appropriate to insert into formula.
   2875 KEEP-EMPTY indicated to keep empty fields, default is to skip them.
   2876 NUMBERS indicates that everything should be converted to numbers.
   2877 LISPP non-nil means to return something appropriate for a Lisp
   2878 list, `literal' is for the format specifier L."
   2879   ;; Calc nan (not a number) is used for the conversion of the empty
   2880   ;; field to a reference for several reasons: (i) It is accepted in a
   2881   ;; Calc formula (e. g. "" or "()" would result in a Calc error).
   2882   ;; (ii) In a single field (not in range) it can be distinguished
   2883   ;; from "(nan)" which is the reference made from a single field
   2884   ;; containing "nan".
   2885   (if (stringp elements)
   2886       ;; field reference
   2887       (if lispp
   2888 	  (if (eq lispp 'literal)
   2889 	      elements
   2890             ;; Ignore KEEP-EMPTY here.
   2891             ;; When ELEMENTS="" and NUMBERS=t, (string-to-number "")
   2892             ;; returns 0 - consistent with (0) for Calc branch.
   2893             ;; When ELEMENTS="" and NUMBERS=nil, `prin1-to-string' will
   2894             ;; return "\"\"" - historical behavior that also does not
   2895             ;; leave missing arguments in formulas like (string< $1 $2)
   2896             ;; when $2 cell is empty.
   2897             (prin1-to-string
   2898 	     (if numbers (string-to-number elements) elements)))
   2899 	(if (string-match "\\S-" elements)
   2900 	    (progn
   2901 	      (when numbers (setq elements (number-to-string
   2902 					    (string-to-number elements))))
   2903 	      (concat "(" elements ")"))
   2904 	  (if (or (not keep-empty) numbers) "(0)" "nan")))
   2905     ;; range reference
   2906     (unless keep-empty
   2907       (setq elements
   2908 	    (delq nil
   2909 		  (mapcar (lambda (x) (if (string-match "\\S-" x) x nil))
   2910 			  elements))))
   2911     (setq elements (or elements '()))  ; if delq returns nil then we need '()
   2912     (if lispp
   2913 	(mapconcat
   2914 	 (lambda (x)
   2915 	   (if (eq lispp 'literal)
   2916 	       x
   2917 	     (prin1-to-string (if numbers (string-to-number x) x))))
   2918 	 elements " ")
   2919       (concat "[" (mapconcat
   2920 		   (lambda (x)
   2921 		     (if (string-match "\\S-" x)
   2922 			 (if numbers
   2923 			     (number-to-string (string-to-number x))
   2924 			   x)
   2925 		       (if (or (not keep-empty) numbers) "0" "nan")))
   2926 		   elements
   2927 		   ",") "]"))))
   2928 
   2929 (defun org-table-message-once-per-second (t1 &rest args)
   2930   "If there has been more than one second since T1, display message.
   2931 ARGS are passed as arguments to the `message' function.  Returns
   2932 current time if a message is printed, otherwise returns T1.  If
   2933 T1 is nil, always messages."
   2934   (let ((curtime (current-time)))
   2935     (if (or (not t1) (time-less-p 1 (time-subtract curtime t1)))
   2936 	(progn (apply 'message args)
   2937 	       curtime)
   2938       t1)))
   2939 
   2940 ;;;###autoload
   2941 (defun org-table-recalculate (&optional all noalign)
   2942   "Recalculate the current table line by applying all stored formulas.
   2943 
   2944 With prefix arg ALL, do this for all lines in the table.
   2945 
   2946 When called with a `\\[universal-argument] \\[universal-argument]' prefix, or \
   2947 if ALL is the symbol `iterate',
   2948 recompute the table until it no longer changes.
   2949 
   2950 If NOALIGN is not nil, do not re-align the table after the computations
   2951 are done.  This is typically used internally to save time, if it is
   2952 known that the table will be realigned a little later anyway."
   2953   (interactive "P")
   2954   (unless (memq this-command org-recalc-commands)
   2955     (push this-command org-recalc-commands))
   2956   (unless (org-at-table-p) (user-error "Not at a table"))
   2957   (if (or (eq all 'iterate) (equal all '(16)))
   2958       (org-table-iterate)
   2959     (org-table-analyze)
   2960     (let* ((eqlist (sort (org-table-get-stored-formulas)
   2961 			 (lambda (a b) (string< (car a) (car b)))))
   2962 	   (inhibit-redisplay (not debug-on-error))
   2963 	   (line-re org-table-dataline-regexp)
   2964 	   (log-first-time (current-time))
   2965 	   (log-last-time log-first-time)
   2966 	   (cnt 0)
   2967 	   beg end eqlcol eqlfield)
   2968       ;; Insert constants in all formulas.
   2969       (when eqlist
   2970 	(org-table-with-shrunk-columns
   2971 	 (org-table-save-field
   2972 	  ;; Expand equations, then split the equation list between
   2973 	  ;; column formulas and field formulas.
   2974 	  (dolist (eq eqlist)
   2975 	    (let* ((rhs (org-table-formula-substitute-names
   2976 			 (org-table-formula-handle-first/last-rc (cdr eq))))
   2977 		   (old-lhs (car eq))
   2978 		   (lhs
   2979 		    (org-table-formula-handle-first/last-rc
   2980 		     (cond
   2981 		      ((string-match "\\`@-?I+" old-lhs)
   2982 		       (user-error "Can't assign to hline relative reference"))
   2983 		      ((string-match "\\`\\$[<>]" old-lhs)
   2984 		       (let ((new (org-table-formula-handle-first/last-rc
   2985 				   old-lhs)))
   2986 			 (when (assoc new eqlist)
   2987 			   (user-error "\"%s=\" formula tries to overwrite \
   2988 existing formula for column %s"
   2989 				       old-lhs
   2990 				       new))
   2991 			 new))
   2992 		      (t old-lhs)))))
   2993 	      (if (string-match-p "\\`\\$[0-9]+\\'" lhs)
   2994 		  (push (cons lhs rhs) eqlcol)
   2995 		(push (cons lhs rhs) eqlfield))))
   2996 	  (setq eqlcol (nreverse eqlcol))
   2997 	  ;; Expand ranges in lhs of formulas
   2998 	  (setq eqlfield (org-table-expand-lhs-ranges (nreverse eqlfield)))
   2999 	  ;; Get the correct line range to process.
   3000 	  (if all
   3001 	      (progn
   3002 		(setq end (copy-marker (org-table-end)))
   3003 		(goto-char (setq beg org-table-current-begin-pos))
   3004 		(cond
   3005 		 ((re-search-forward org-table-calculate-mark-regexp end t)
   3006 		  ;; This is a table with marked lines, compute selected
   3007 		  ;; lines.
   3008 		  (setq line-re org-table-recalculate-regexp))
   3009 		 ;; Move forward to the first non-header line.
   3010 		 ((and (re-search-forward org-table-dataline-regexp end t)
   3011 		       (re-search-forward org-table-hline-regexp end t)
   3012 		       (re-search-forward org-table-dataline-regexp end t))
   3013 		  (setq beg (match-beginning 0)))
   3014 		 ;; Just leave BEG at the start of the table.
   3015 		 (t nil)))
   3016 	    (setq beg (line-beginning-position)
   3017 		  end (copy-marker (line-beginning-position 2))))
   3018 	  (goto-char beg)
   3019 	  ;; Mark named fields untouchable.  Also check if several
   3020 	  ;; field/range formulas try to set the same field.
   3021 	  (remove-text-properties beg end '(:org-untouchable t))
   3022 	  (let ((current-line (count-lines org-table-current-begin-pos
   3023 					   (line-beginning-position)))
   3024 		seen-fields)
   3025 	    (dolist (eq eqlfield)
   3026 	      (let* ((name (car eq))
   3027 		     (location (assoc name org-table-named-field-locations))
   3028 		     (eq-line (or (nth 1 location)
   3029 				  (and (string-match "\\`@\\([0-9]+\\)" name)
   3030 				       (aref org-table-dlines
   3031 					     (string-to-number
   3032 					      (match-string 1 name))))))
   3033 		     (reference
   3034 		      (if location
   3035 			  ;; Turn field coordinates associated to NAME
   3036 			  ;; into an absolute reference.
   3037 			  (format "@%d$%d"
   3038 				  (org-table-line-to-dline eq-line)
   3039 				  (nth 2 location))
   3040 			name)))
   3041 		(when (member reference seen-fields)
   3042 		  (user-error "Several field/range formulas try to set %s"
   3043 			      reference))
   3044 		(push reference seen-fields)
   3045 		(when (or all (eq eq-line current-line))
   3046 		  (org-table-goto-field name)
   3047 		  (org-table-put-field-property :org-untouchable t)))))
   3048 	  ;; Evaluate the column formulas, but skip fields covered by
   3049 	  ;; field formulas.
   3050 	  (goto-char beg)
   3051 	  (while (re-search-forward line-re end t)
   3052 	    (unless (string-match "\\` *[_^!$/] *\\'" (org-table-get-field 1))
   3053 	      ;; Unprotected line, recalculate.
   3054 	      (cl-incf cnt)
   3055 	      (when all
   3056 		(setq log-last-time
   3057 		      (org-table-message-once-per-second
   3058 		       log-last-time
   3059 		       "Re-applying formulas to full table...(line %d)" cnt)))
   3060 	      (if (markerp org-last-recalc-line)
   3061 		  (move-marker org-last-recalc-line (line-beginning-position))
   3062 		(setq org-last-recalc-line
   3063 		      (copy-marker (line-beginning-position))))
   3064 	      (dolist (entry eqlcol)
   3065 		(goto-char org-last-recalc-line)
   3066 		(org-table-goto-column
   3067 		 (string-to-number (substring (car entry) 1)) nil 'force)
   3068 		(unless (get-text-property (point) :org-untouchable)
   3069 		  (org-table-eval-formula
   3070 		   nil (cdr entry) 'noalign 'nocst 'nostore 'noanalysis)))))
   3071 	  ;; Evaluate the field formulas.
   3072 	  (dolist (eq eqlfield)
   3073 	    (let ((reference (car eq))
   3074 		  (formula (cdr eq)))
   3075 	      (setq log-last-time
   3076 		    (org-table-message-once-per-second
   3077 		     (and all log-last-time)
   3078 		     "Re-applying formula to field: %s" (car eq)))
   3079 	      (org-table-goto-field
   3080 	       reference
   3081 	       ;; Possibly create a new column, as long as
   3082 	       ;; `org-table-formula-create-columns' allows it.
   3083 	       (let ((column-count (progn (end-of-line)
   3084 					  (1- (org-table-current-column)))))
   3085 		 (lambda (column)
   3086 		   (when (> column 1000)
   3087 		     (user-error "Formula column target too large"))
   3088 		   (and (> column column-count)
   3089 			(or (eq org-table-formula-create-columns t)
   3090 			    (and (eq org-table-formula-create-columns 'warn)
   3091 				 (progn
   3092 				   (org-display-warning
   3093 				    "Out-of-bounds formula added columns")
   3094 				   t))
   3095 			    (and (eq org-table-formula-create-columns 'prompt)
   3096 				 (yes-or-no-p
   3097 				  "Out-of-bounds formula.  Add columns? "))
   3098 			    (user-error
   3099 			     "Missing columns in the table.  Aborting"))))))
   3100 	      (org-table-eval-formula nil formula t t t t)))
   3101 	  ;; Clean up marker.
   3102 	  (set-marker end nil)))
   3103 	(unless noalign
   3104 	  (when org-table-may-need-update (org-table-align))
   3105 	  (when all
   3106 	    (org-table-message-once-per-second
   3107 	     log-first-time "Re-applying formulas to %d lines... done" cnt)))
   3108 	(org-table-message-once-per-second
   3109 	 (and all log-first-time) "Re-applying formulas... done")))))
   3110 
   3111 ;;;###autoload
   3112 (defun org-table-iterate (&optional arg)
   3113   "Recalculate the table until it does not change anymore.
   3114 The maximum number of iterations is 10, but you can choose a different value
   3115 with the prefix ARG."
   3116   (interactive "P")
   3117   (let ((imax (if arg (prefix-numeric-value arg) 10))
   3118 	(i 0)
   3119 	(lasttbl (buffer-substring (org-table-begin) (org-table-end)))
   3120 	thistbl)
   3121     (catch 'exit
   3122       (while (< i imax)
   3123 	(setq i (1+ i))
   3124 	(org-table-recalculate 'all)
   3125 	(setq thistbl (buffer-substring (org-table-begin) (org-table-end)))
   3126 	(if (not (string= lasttbl thistbl))
   3127 	    (setq lasttbl thistbl)
   3128 	  (if (> i 1)
   3129 	      (message "Convergence after %d iterations" i)
   3130 	    (message "Table was already stable"))
   3131 	  (throw 'exit t)))
   3132       (user-error "No convergence after %d iterations" i))))
   3133 
   3134 ;;;###autoload
   3135 (defun org-table-recalculate-buffer-tables ()
   3136   "Recalculate all tables in the current buffer."
   3137   (interactive)
   3138   (org-with-wide-buffer
   3139    (org-table-map-tables
   3140     (lambda ()
   3141       ;; Reason for separate `org-table-align': When repeating
   3142       ;; (org-table-recalculate t) `org-table-may-need-update' gets in
   3143       ;; the way.
   3144       (org-table-recalculate t t)
   3145       (org-table-align))
   3146     t)))
   3147 
   3148 ;;;###autoload
   3149 (defun org-table-iterate-buffer-tables ()
   3150   "Iterate all tables in the buffer, to converge inter-table dependencies."
   3151   (interactive)
   3152   (let* ((imax 10)
   3153 	 (i imax)
   3154 	 (checksum (md5 (buffer-string)))
   3155 	 c1)
   3156     (org-with-wide-buffer
   3157      (catch 'exit
   3158        (while (> i 0)
   3159 	 (setq i (1- i))
   3160 	 (org-table-map-tables (lambda () (org-table-recalculate t t)) t)
   3161 	 (if (equal checksum (setq c1 (md5 (buffer-string))))
   3162 	     (progn
   3163 	       (org-table-map-tables #'org-table-align t)
   3164 	       (message "Convergence after %d iterations" (- imax i))
   3165 	       (throw 'exit t))
   3166 	   (setq checksum c1)))
   3167        (org-table-map-tables #'org-table-align t)
   3168        (user-error "No convergence after %d iterations" imax)))))
   3169 
   3170 (defun org-table-calc-current-TBLFM (&optional arg)
   3171   "Apply the #+TBLFM in the line at point to the table."
   3172   (interactive "P")
   3173   (unless (org-at-TBLFM-p) (user-error "Not at a #+TBLFM line"))
   3174   (let ((formula (buffer-substring
   3175 		  (line-beginning-position)
   3176 		  (line-end-position))))
   3177     (save-excursion
   3178       ;; Insert a temporary formula at right after the table
   3179       (goto-char (org-table-TBLFM-begin))
   3180       (let ((s (point-marker)))
   3181 	(insert formula "\n")
   3182 	(let ((e (point-marker)))
   3183 	  ;; Recalculate the table.
   3184 	  (forward-line -1)		; move to the inserted line
   3185 	  (skip-chars-backward " \r\n\t")
   3186 	  (unwind-protect
   3187 	      (org-call-with-arg #'org-table-recalculate (or arg t))
   3188 	    ;; Delete the formula inserted temporarily.
   3189 	    (delete-region s e)
   3190 	    (set-marker s nil)
   3191 	    (set-marker e nil)))))))
   3192 
   3193 (defun org-table-TBLFM-begin ()
   3194   "Find the beginning of the TBLFM lines and return its position.
   3195 Return nil when the beginning of TBLFM line was not found."
   3196   (save-excursion
   3197     (when (progn (forward-line 1)
   3198 		 (re-search-backward org-table-TBLFM-begin-regexp nil t))
   3199       (line-beginning-position 2))))
   3200 
   3201 (defun org-table-expand-lhs-ranges (equations)
   3202   "Expand list of formulas.
   3203 If some of the RHS in the formulas are ranges or a row reference,
   3204 expand them to individual field equations for each field.  This
   3205 function assumes the table is already analyzed (i.e., using
   3206 `org-table-analyze')."
   3207   (let (res)
   3208     (dolist (e equations (nreverse res))
   3209       (let ((lhs (car e))
   3210 	    (rhs (cdr e)))
   3211 	(cond
   3212 	 ((string-match-p "\\`@[-+0-9]+\\$-?[0-9]+\\'" lhs)
   3213 	  ;; This just refers to one fixed field.
   3214 	  (push e res))
   3215 	 ((string-match-p "\\`[a-zA-Z][_a-zA-Z0-9]*\\'" lhs)
   3216 	  ;; This just refers to one fixed named field.
   3217 	  (push e res))
   3218 	 ((string-match-p "\\`\\$[0-9]+\\'" lhs)
   3219 	  ;; Column formulas are treated specially and are not
   3220 	  ;; expanded.
   3221 	  (push e res))
   3222 	 ((string-match "\\`@[0-9]+\\'" lhs)
   3223 	  (dotimes (ic org-table-current-ncol)
   3224 	    (push (cons (propertize (format "%s$%d" lhs (1+ ic)) :orig-eqn e)
   3225 			rhs)
   3226 		  res)))
   3227 	 (t
   3228 	  (let* ((range (org-table-get-range
   3229 			 lhs org-table-current-begin-pos 1 nil 'corners))
   3230 		 (r1 (org-table-line-to-dline (nth 0 range)))
   3231 		 (c1 (nth 1 range))
   3232 		 (r2 (org-table-line-to-dline (nth 2 range) 'above))
   3233 		 (c2 (nth 3 range)))
   3234 	    (cl-loop for ir from r1 to r2 do
   3235 		     (cl-loop for ic from c1 to c2 do
   3236 			      (push (cons (propertize
   3237 					   (format "@%d$%d" ir ic) :orig-eqn e)
   3238 					  rhs)
   3239 				    res))))))))))
   3240 
   3241 (defun org-table-formula-handle-first/last-rc (s)
   3242   "Replace @<, @>, $<, $> with first/last row/column of the table.
   3243 So @< and $< will always be replaced with @1 and $1, respectively.
   3244 The advantage of these special markers are that structure editing of
   3245 the table will not change them, while @1 and $1 will be modified
   3246 when a line/row is swapped out of that privileged position.  So for
   3247 formulas that use a range of rows or columns, it may often be better
   3248 to anchor the formula with \"I\" row markers, or to offset from the
   3249 borders of the table using the @< @> $< $> makers."
   3250   (let (n nmax len char (start 0))
   3251     (while (string-match "\\([@$]\\)\\(<+\\|>+\\)\\|\\(remote([^)]+)\\)"
   3252 			 s start)
   3253       (if (match-end 3)
   3254 	  (setq start (match-end 3))
   3255 	(setq nmax (if (equal (match-string 1 s) "@")
   3256 		       (1- (length org-table-dlines))
   3257 		     org-table-current-ncol)
   3258 	      len (- (match-end 2) (match-beginning 2))
   3259 	      char (string-to-char (match-string 2 s))
   3260 	      n (if (= char ?<)
   3261 		    len
   3262 		  (- nmax len -1)))
   3263 	(if (or (< n 1) (> n nmax))
   3264 	    (user-error "Reference \"%s\" in expression \"%s\" points outside table"
   3265 			(match-string 0 s) s))
   3266 	(setq start (match-beginning 0))
   3267 	(setq s (replace-match (format "%s%d" (match-string 1 s) n) t t s)))))
   3268   s)
   3269 
   3270 (defun org-table-formula-substitute-names (f)
   3271   "Replace $const with values in string F."
   3272   (let ((start 0)
   3273 	(pp (/= (string-to-char f) ?'))
   3274 	(duration (string-match-p ";.*[Tt].*\\'" f))
   3275 	(new (replace-regexp-in-string	; Check for column names.
   3276 	      org-table-column-name-regexp
   3277 	      (lambda (m)
   3278 		(concat "$" (cdr (assoc (match-string 1 m)
   3279 					org-table-column-names))))
   3280 	      f t t)))
   3281     ;; Parameters and constants.
   3282     (while (setq start
   3283 		 (string-match
   3284 		  "\\$\\([a-zA-Z][_a-zA-Z0-9]*\\)\\|\\(\\<remote([^)]*)\\)"
   3285 		  new start))
   3286       (if (match-end 2) (setq start (match-end 2))
   3287 	(cl-incf start)
   3288 	;; When a duration is expected, convert value on the fly.
   3289 	(let ((value
   3290 	       (save-match-data
   3291 		 (let ((v (org-table-get-constant (match-string 1 new))))
   3292 		   (if (and (org-string-nw-p v) duration)
   3293 		       (org-table-time-string-to-seconds v)
   3294 		     v)))))
   3295 	  (when value
   3296 	    (setq new (replace-match
   3297 		       (concat (and pp "(") value (and pp ")")) t t new))))))
   3298     (if org-table-formula-debug (propertize new :orig-formula f) new)))
   3299 
   3300 (defun org-table-get-constant (const)
   3301   "Find the value for a parameter or constant in a formula.
   3302 Parameters get priority."
   3303   (or (cdr (assoc const org-table-local-parameters))
   3304       (cdr (assoc const org-table-formula-constants-local))
   3305       (cdr (assoc const org-table-formula-constants))
   3306       (and (fboundp 'constants-get) (constants-get const))
   3307       (and (string= (substring const 0 (min 5 (length const))) "PROP_")
   3308 	   (org-entry-get nil (substring const 5) 'inherit))
   3309       "#UNDEFINED_NAME"))
   3310 
   3311 (defvar org-table-fedit-map
   3312   (let ((map (make-sparse-keymap)))
   3313     (org-defkey map "\C-x\C-s"      'org-table-fedit-finish)
   3314     (org-defkey map "\C-c\C-s"      'org-table-fedit-finish)
   3315     (org-defkey map "\C-c\C-c"      'org-table-fedit-finish)
   3316     (org-defkey map "\C-c'"         'org-table-fedit-finish)
   3317     (org-defkey map "\C-c\C-q"      'org-table-fedit-abort)
   3318     (org-defkey map "\C-c?"	    'org-table-show-reference)
   3319     (org-defkey map [(meta shift up)]    'org-table-fedit-line-up)
   3320     (org-defkey map [(meta shift down)]  'org-table-fedit-line-down)
   3321     (org-defkey map [(shift up)]    'org-table-fedit-ref-up)
   3322     (org-defkey map [(shift down)]  'org-table-fedit-ref-down)
   3323     (org-defkey map [(shift left)]  'org-table-fedit-ref-left)
   3324     (org-defkey map [(shift right)] 'org-table-fedit-ref-right)
   3325     (org-defkey map [(meta up)]     'org-table-fedit-scroll-down)
   3326     (org-defkey map [(meta down)]   'org-table-fedit-scroll)
   3327     (org-defkey map [(meta tab)]    'lisp-complete-symbol)
   3328     (org-defkey map "\M-\C-i"       'lisp-complete-symbol)
   3329     (org-defkey map [(tab)]	    'org-table-fedit-lisp-indent)
   3330     (org-defkey map "\C-i"	    'org-table-fedit-lisp-indent)
   3331     (org-defkey map "\C-c\C-r" 'org-table-fedit-toggle-ref-type)
   3332     (org-defkey map "\C-c}"    'org-table-fedit-toggle-coordinates)
   3333     map))
   3334 
   3335 (easy-menu-define org-table-fedit-menu org-table-fedit-map "Org Edit Formulas Menu."
   3336   '("Edit-Formulas"
   3337     ["Finish and Install" org-table-fedit-finish t]
   3338     ["Finish, Install, and Apply" (org-table-fedit-finish t) :keys "C-u C-c C-c"]
   3339     ["Abort" org-table-fedit-abort t]
   3340     "--"
   3341     ["Pretty-Print Lisp Formula" org-table-fedit-lisp-indent t]
   3342     ["Complete Lisp Symbol" lisp-complete-symbol t]
   3343     "--"
   3344     "Shift Reference at Point"
   3345     ["Up" org-table-fedit-ref-up t]
   3346     ["Down" org-table-fedit-ref-down t]
   3347     ["Left" org-table-fedit-ref-left t]
   3348     ["Right" org-table-fedit-ref-right t]
   3349     "-"
   3350     "Change Test Row for Column Formulas"
   3351     ["Up" org-table-fedit-line-up t]
   3352     ["Down" org-table-fedit-line-down t]
   3353     "--"
   3354     ["Scroll Table Window" org-table-fedit-scroll t]
   3355     ["Scroll Table Window down" org-table-fedit-scroll-down t]
   3356     ["Show Table Grid" org-table-fedit-toggle-coordinates
   3357      :style toggle :selected (with-current-buffer (marker-buffer org-pos)
   3358 			       org-table-overlay-coordinates)]
   3359     "--"
   3360     ["Standard Refs (B3 instead of @3$2)" org-table-fedit-toggle-ref-type
   3361      :style toggle :selected org-table-buffer-is-an]))
   3362 
   3363 (defvar org-table--fedit-source nil
   3364   "Position of the TBLFM line being edited.")
   3365 
   3366 ;;;###autoload
   3367 (defun org-table-edit-formulas ()
   3368   "Edit the formulas of the current table in a separate buffer."
   3369   (interactive)
   3370   (let ((at-tblfm (org-at-TBLFM-p)))
   3371     (unless (or at-tblfm (org-at-table-p))
   3372       (user-error "Not at a table"))
   3373     (save-excursion
   3374       ;; Move point within the table before analyzing it.
   3375       (when at-tblfm (re-search-backward "^[ \t]*|"))
   3376       (org-table-analyze))
   3377     (let ((key (org-table-current-field-formula 'key 'noerror))
   3378 	  (eql (sort (org-table-get-stored-formulas t (and at-tblfm (point)))
   3379 		     #'org-table-formula-less-p))
   3380 	  (pos (point-marker))
   3381 	  (source (copy-marker (line-beginning-position)))
   3382 	  (startline 1)
   3383 	  (wc (current-window-configuration))
   3384 	  (sel-win (selected-window))
   3385 	  (titles '((column . "# Column Formulas\n")
   3386 		    (field . "# Field and Range Formulas\n")
   3387 		    (named . "# Named Field Formulas\n"))))
   3388       (let ((pop-up-frames nil))
   3389         ;; We explicitly prohibit creating edit buffer in a new frame
   3390         ;; - such configuration is not supported.
   3391         (switch-to-buffer-other-window "*Edit Formulas*"))
   3392       (erase-buffer)
   3393       ;; Keep global-font-lock-mode from turning on font-lock-mode
   3394       (let ((font-lock-global-modes '(not fundamental-mode)))
   3395 	(fundamental-mode))
   3396       (setq-local font-lock-global-modes (list 'not major-mode))
   3397       (setq-local org-pos pos)
   3398       (setq-local org-table--fedit-source source)
   3399       (setq-local org-window-configuration wc)
   3400       (setq-local org-selected-window sel-win)
   3401       (use-local-map org-table-fedit-map)
   3402       (add-hook 'post-command-hook #'org-table-fedit-post-command t t)
   3403       (setq startline (org-current-line))
   3404       (dolist (entry eql)
   3405 	(let* ((type (cond
   3406 		      ((string-match "\\`\\$\\([0-9]+\\|[<>]+\\)\\'"
   3407 				     (car entry))
   3408 		       'column)
   3409 		      ((equal (string-to-char (car entry)) ?@) 'field)
   3410 		      (t 'named)))
   3411 	       (title (assq type titles)))
   3412 	  (when title
   3413 	    (unless (bobp) (insert "\n"))
   3414 	    (insert
   3415 	     (org-add-props (cdr title) nil 'face font-lock-comment-face))
   3416 	    (setq titles (remove title titles)))
   3417 	  (when (equal key (car entry)) (setq startline (org-current-line)))
   3418 	  (let ((s (concat
   3419 		    (if (memq (string-to-char (car entry)) '(?@ ?$)) "" "$")
   3420 		    (car entry) " = " (cdr entry) "\n")))
   3421 	    (remove-text-properties 0 (length s) '(face nil) s)
   3422 	    (insert s))))
   3423       (when (eq org-table-use-standard-references t)
   3424 	(org-table-fedit-toggle-ref-type))
   3425       (org-goto-line startline)
   3426       (message "%s" (substitute-command-keys "\\<org-mode-map>\
   3427 Edit formulas, finish with `\\[org-ctrl-c-ctrl-c]' or `\\[org-edit-special]'.  \
   3428 See menu for more commands.")))))
   3429 
   3430 (defun org-table-fedit-post-command ()
   3431   (when (not (memq this-command '(lisp-complete-symbol)))
   3432     (let ((win (selected-window)))
   3433       (save-excursion
   3434 	(ignore-errors (org-table-show-reference))
   3435 	(select-window win)))))
   3436 
   3437 (defun org-table-formula-to-user (s)
   3438   "Convert a formula from internal to user representation."
   3439   (if (eq org-table-use-standard-references t)
   3440       (org-table-convert-refs-to-an s)
   3441     s))
   3442 
   3443 (defun org-table-formula-from-user (s)
   3444   "Convert a formula from user to internal representation."
   3445   (if org-table-use-standard-references
   3446       (org-table-convert-refs-to-rc s)
   3447     s))
   3448 
   3449 (defun org-table-convert-refs-to-rc (s)
   3450   "Convert spreadsheet references from A7 to @7$28.
   3451 Works for single references, but also for entire formulas and even the
   3452 full TBLFM line."
   3453   (let ((start 0))
   3454     (while (string-match "\\<\\([a-zA-Z]+\\)\\([0-9]+\\>\\|&\\)\\|\\(;[^\r\n:]+\\|\\<remote([^,)]*)\\)" s start)
   3455       (cond
   3456        ((match-end 3)
   3457 	;; format match, just advance
   3458 	(setq start (match-end 0)))
   3459        ((and (> (match-beginning 0) 0)
   3460 	     (equal ?. (aref s (max (1- (match-beginning 0)) 0)))
   3461 	     (not (equal ?. (aref s (max (- (match-beginning 0) 2) 0)))))
   3462 	;; 3.e5 or something like this.
   3463 	(setq start (match-end 0)))
   3464        ((or (> (- (match-end 1) (match-beginning 1)) 2)
   3465 	    ;; (member (match-string 1 s)
   3466 	    ;;	    '("arctan" "exp" "expm" "lnp" "log" "stir"))
   3467 	    )
   3468 	;; function name, just advance
   3469 	(setq start (match-end 0)))
   3470        (t
   3471 	(setq start (match-beginning 0)
   3472 	      s (replace-match
   3473 		 (if (equal (match-string 2 s) "&")
   3474 		     (format "$%d" (org-letters-to-number (match-string 1 s)))
   3475 		   (format "@%d$%d"
   3476 			   (string-to-number (match-string 2 s))
   3477 			   (org-letters-to-number (match-string 1 s))))
   3478 		 t t s)))))
   3479     s))
   3480 
   3481 (defun org-table-convert-refs-to-an (s)
   3482   "Convert spreadsheet references from to @7$28 to AB7.
   3483 Works for single references, but also for entire formulas and even the
   3484 full TBLFM line.
   3485 
   3486 Leave the relative references unchanged."
   3487   (while (string-match "@\\([0-9]+\\)\\$\\([0-9]+\\)" s)
   3488     (setq s (replace-match
   3489 	     (format "%s%d"
   3490 		     (org-number-to-letters
   3491 		      (string-to-number (match-string 2 s)))
   3492 		     (string-to-number (match-string 1 s)))
   3493 	     t t s)))
   3494   (while (string-match "\\(^\\|[^0-9a-zA-Z]\\)\\$\\([1-9][0-9]*\\)" s)
   3495     (setq s (replace-match (concat "\\1"
   3496 				   (org-number-to-letters
   3497 				    (string-to-number (match-string 2 s))) "&")
   3498 			   t nil s)))
   3499   s)
   3500 
   3501 (defun org-letters-to-number (s)
   3502   "Convert a base 26 number represented by letters into an integer.
   3503 For example:  AB -> 28."
   3504   (let ((n 0))
   3505     (setq s (upcase s))
   3506     (while (> (length s) 0)
   3507       (setq n (+ (* n 26) (string-to-char s) (- ?A) 1)
   3508 	    s (substring s 1)))
   3509     n))
   3510 
   3511 (defun org-number-to-letters (n)
   3512   "Convert an integer into a base 26 number represented by letters.
   3513 For example:  28 -> AB."
   3514   (let ((s ""))
   3515     (while (> n 0)
   3516       (setq s (concat (char-to-string (+ (mod (1- n) 26) ?A)) s)
   3517 	    n (/ (1- n) 26)))
   3518     s))
   3519 
   3520 (defun org-table-time-string-to-seconds (s)
   3521   "Convert a time string into numerical duration in seconds.
   3522 S can be a string matching either -?HH:MM:SS or -?HH:MM.
   3523 If S is a string representing a number, keep this number."
   3524   (if (equal s "")
   3525       s
   3526     (let (hour minus min sec res)
   3527       (cond
   3528        ((and (string-match "\\(-?\\)\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)" s))
   3529 	(setq minus (< 0 (length (match-string 1 s)))
   3530 	      hour (string-to-number (match-string 2 s))
   3531 	      min (string-to-number (match-string 3 s))
   3532 	      sec (string-to-number (match-string 4 s)))
   3533 	(if minus
   3534 	    (setq res (- (+ (* hour 3600) (* min 60) sec)))
   3535 	  (setq res (+ (* hour 3600) (* min 60) sec))))
   3536        ((and (not (string-match org-ts-regexp-both s))
   3537 	     (string-match "\\(-?\\)\\([0-9]+\\):\\([0-9]+\\)" s))
   3538 	(setq minus (< 0 (length (match-string 1 s)))
   3539 	      hour (string-to-number (match-string 2 s))
   3540 	      min (string-to-number (match-string 3 s)))
   3541 	(if minus
   3542 	    (setq res (- (+ (* hour 3600) (* min 60))))
   3543 	  (setq res (+ (* hour 3600) (* min 60)))))
   3544        (t (setq res (string-to-number s))))
   3545       (number-to-string res))))
   3546 
   3547 (defun org-table-time-seconds-to-string (secs &optional output-format)
   3548   "Convert a number of seconds to a time string.
   3549 If OUTPUT-FORMAT is non-nil, return a number of days, hours,
   3550 minutes or seconds."
   3551   (let* ((secs0 (abs secs))
   3552 	 (res
   3553 	  (cond ((eq output-format 'days)
   3554 		 (format "%.3f" (/ (float secs0) 86400)))
   3555 		((eq output-format 'hours)
   3556 		 (format "%.2f" (/ (float secs0) 3600)))
   3557 		((eq output-format 'minutes)
   3558 		 (format "%.1f" (/ (float secs0) 60)))
   3559 		((eq output-format 'seconds)
   3560 		 (format "%d" secs0))
   3561 		((eq output-format 'hh:mm)
   3562 		 ;; Ignore seconds
   3563 		 (substring (format-seconds
   3564 			     (if org-table-duration-hour-zero-padding
   3565 				 "%.2h:%.2m:%.2s" "%h:%.2m:%.2s")
   3566 			     secs0)
   3567 			    0 -3))
   3568 		(t (format-seconds
   3569 		    (if org-table-duration-hour-zero-padding
   3570 			"%.2h:%.2m:%.2s" "%h:%.2m:%.2s")
   3571 		    secs0)))))
   3572     (if (< secs 0) (concat "-" res) res)))
   3573 
   3574 (defun org-table-fedit-convert-buffer (function)
   3575   "Convert all references in this buffer, using FUNCTION."
   3576   (let ((origin (copy-marker (line-beginning-position))))
   3577     (goto-char (point-min))
   3578     (while (not (eobp))
   3579       (insert (funcall function (buffer-substring (point) (line-end-position))))
   3580       (delete-region (point) (line-end-position))
   3581       (forward-line))
   3582     (goto-char origin)
   3583     (set-marker origin nil)))
   3584 
   3585 (defun org-table-fedit-toggle-ref-type ()
   3586   "Convert all references in the buffer from B3 to @3$2 and back."
   3587   (interactive)
   3588   (setq-local org-table-buffer-is-an (not org-table-buffer-is-an))
   3589   (org-table-fedit-convert-buffer
   3590    (if org-table-buffer-is-an
   3591        'org-table-convert-refs-to-an 'org-table-convert-refs-to-rc))
   3592   (message "Reference type switched to %s"
   3593 	   (if org-table-buffer-is-an "A1 etc" "@row$column")))
   3594 
   3595 (defun org-table-fedit-ref-up ()
   3596   "Shift the reference at point one row/hline up."
   3597   (interactive)
   3598   (org-table-fedit-shift-reference 'up))
   3599 
   3600 (defun org-table-fedit-ref-down ()
   3601   "Shift the reference at point one row/hline down."
   3602   (interactive)
   3603   (org-table-fedit-shift-reference 'down))
   3604 
   3605 (defun org-table-fedit-ref-left ()
   3606   "Shift the reference at point one field to the left."
   3607   (interactive)
   3608   (org-table-fedit-shift-reference 'left))
   3609 
   3610 (defun org-table-fedit-ref-right ()
   3611   "Shift the reference at point one field to the right."
   3612   (interactive)
   3613   (org-table-fedit-shift-reference 'right))
   3614 
   3615 (defun org-table--rematch-and-replace (n &optional decr hline)
   3616   "Re-match the group N, and replace it with the shifted reference."
   3617   (or (match-end n) (user-error "Cannot shift reference in this direction"))
   3618   (goto-char (match-beginning n))
   3619   (and (looking-at (regexp-quote (match-string n)))
   3620        (replace-match (org-table-shift-refpart (match-string 0) decr hline)
   3621 		      t t)))
   3622 
   3623 (defun org-table-fedit-shift-reference (dir)
   3624   (cond
   3625    ((org-in-regexp "\\(\\<[a-zA-Z]\\)&")
   3626     (if (memq dir '(left right))
   3627 	(org-table--rematch-and-replace 1 (eq dir 'left))
   3628       (user-error "Cannot shift reference in this direction")))
   3629    ((org-in-regexp "\\(\\<[a-zA-Z]\\{1,2\\}\\)\\([0-9]+\\)")
   3630     ;; A B3-like reference
   3631     (if (memq dir '(up down))
   3632 	(org-table--rematch-and-replace 2 (eq dir 'up))
   3633       (org-table--rematch-and-replace 1 (eq dir 'left))))
   3634    ((org-in-regexp
   3635      "\\(@\\|\\.\\.\\)\\([-+]?\\(I+\\>\\|[0-9]+\\)\\)\\(\\$\\([-+]?[0-9]+\\)\\)?")
   3636     ;; An internal reference
   3637     (if (memq dir '(up down))
   3638 	(org-table--rematch-and-replace 2 (eq dir 'up) (match-end 3))
   3639       (org-table--rematch-and-replace 5 (eq dir 'left))))))
   3640 
   3641 (defun org-table-shift-refpart (ref &optional decr hline)
   3642   "Shift a reference part REF.
   3643 If DECR is set, decrease the references row/column, else increase.
   3644 If HLINE is set, this may be a hline reference, it certainly is not
   3645 a translation reference."
   3646   (save-match-data
   3647     (let* ((sign (string-match "^[-+]" ref)) n)
   3648 
   3649       (if sign (setq sign (substring ref 0 1) ref (substring ref 1)))
   3650       (cond
   3651        ((and hline (string-match "^I+" ref))
   3652 	(setq n (string-to-number (concat sign (number-to-string (length ref)))))
   3653 	(setq n (+ n (if decr -1 1)))
   3654 	(if (= n 0) (setq n (+ n (if decr -1 1))))
   3655 	(if sign
   3656 	    (setq sign (if (< n 0) "-" "+") n (abs n))
   3657 	  (setq n (max 1 n)))
   3658 	(concat sign (make-string n ?I)))
   3659 
   3660        ((string-match "^[0-9]+" ref)
   3661 	(setq n (string-to-number (concat sign ref)))
   3662 	(setq n (+ n (if decr -1 1)))
   3663 	(if sign
   3664 	    (concat (if (< n 0) "-" "+") (number-to-string (abs n)))
   3665 	  (number-to-string (max 1 n))))
   3666 
   3667        ((string-match "^[a-zA-Z]+" ref)
   3668 	(org-number-to-letters
   3669 	 (max 1 (+ (org-letters-to-number ref) (if decr -1 1)))))
   3670 
   3671        (t (user-error "Cannot shift reference"))))))
   3672 
   3673 (defun org-table-fedit-toggle-coordinates ()
   3674   "Toggle the display of coordinates in the referenced table."
   3675   (interactive)
   3676   (let ((pos (marker-position org-pos)))
   3677     (with-current-buffer (marker-buffer org-pos)
   3678       (save-excursion
   3679 	(goto-char pos)
   3680 	(org-table-toggle-coordinate-overlays)))))
   3681 
   3682 (defun org-table-fedit-finish (&optional arg)
   3683   "Parse the buffer for formula definitions and install them.
   3684 With prefix ARG, apply the new formulas to the table."
   3685   (interactive "P")
   3686   (org-table-remove-rectangle-highlight)
   3687   (when org-table-use-standard-references
   3688     (org-table-fedit-convert-buffer 'org-table-convert-refs-to-rc)
   3689     (setq org-table-buffer-is-an nil))
   3690   (let ((pos org-pos)
   3691 	(sel-win org-selected-window)
   3692 	(source org-table--fedit-source)
   3693 	eql)
   3694     (goto-char (point-min))
   3695     (while (re-search-forward
   3696 	    "^\\(@[-+I<>0-9.$@]+\\|@?[0-9]+\\|\\$\\([a-zA-Z0-9]+\\|[<>]+\\)\\) *= *\\(.*\\(\n[ \t]+.*$\\)*\\)"
   3697 	    nil t)
   3698       (let ((var (match-string 1))
   3699 	    (form (org-trim (match-string 3))))
   3700 	(unless (equal form "")
   3701 	  (while (string-match "[ \t]*\n[ \t]*" form)
   3702 	    (setq form (replace-match " " t t form)))
   3703 	  (when (assoc var eql)
   3704 	    (user-error "Double formulas for %s" var))
   3705 	  (push (cons var form) eql))))
   3706     (set-window-configuration org-window-configuration)
   3707     (select-window sel-win)
   3708     (goto-char source)
   3709     (org-table-store-formulas eql)
   3710     (set-marker pos nil)
   3711     (set-marker source nil)
   3712     (when-let* ((window (get-buffer-window "*Edit Formulas*" t)))
   3713       (quit-window 'kill window))
   3714     (when (get-buffer "*Edit Formulas*") (kill-buffer "*Edit Formulas*"))
   3715     (if arg
   3716 	(org-table-recalculate 'all)
   3717       (message "New formulas installed - press C-u C-c C-c to apply."))))
   3718 
   3719 (defun org-table-fedit-abort ()
   3720   "Abort editing formulas, without installing the changes."
   3721   (interactive)
   3722   (org-table-remove-rectangle-highlight)
   3723   (let ((pos org-pos) (sel-win org-selected-window))
   3724     (set-window-configuration org-window-configuration)
   3725     (select-window sel-win)
   3726     (goto-char pos)
   3727     (move-marker pos nil)
   3728     (message "Formula editing aborted without installing changes")))
   3729 
   3730 (defun org-table-fedit-lisp-indent ()
   3731   "Pretty-print and re-indent Lisp expressions in the Formula Editor."
   3732   (interactive)
   3733   (let ((pos (point)) beg end ind)
   3734     (forward-line 0)
   3735     (cond
   3736      ((looking-at "[ \t]")
   3737       (goto-char pos)
   3738       (call-interactively 'lisp-indent-line))
   3739      ((looking-at "[$&@0-9a-zA-Z]+ *= *[^ \t\n']") (goto-char pos))
   3740      ((looking-at "[$&@0-9a-zA-Z]+ *= *'(")
   3741       (goto-char (- (match-end 0) 2))
   3742       (setq beg (point))
   3743       (setq ind (make-string (current-column) ?\ ))
   3744       (condition-case nil (forward-sexp 1)
   3745 	(error
   3746 	 (user-error "Cannot pretty-print Lisp expression: Unbalanced parenthesis")))
   3747       (setq end (point))
   3748       (save-restriction
   3749 	(narrow-to-region beg end)
   3750 	(if (eq last-command this-command)
   3751 	    (progn
   3752 	      (goto-char (point-min))
   3753 	      (setq this-command nil)
   3754 	      (while (re-search-forward "[ \t]*\n[ \t]*" nil t)
   3755 		(replace-match " ")))
   3756 	  (pp-buffer)
   3757 	  (untabify (point-min) (point-max))
   3758 	  (goto-char (1+ (point-min)))
   3759 	  (while (re-search-forward "^." nil t)
   3760 	    (forward-line 0)
   3761 	    (insert ind))
   3762 	  (goto-char (point-max))
   3763 	  (org-delete-backward-char 1)))
   3764       (goto-char beg))
   3765      (t nil))))
   3766 
   3767 (defun org-table-fedit-line-up ()
   3768   "Move cursor one line up in the window showing the table."
   3769   (interactive)
   3770   (org-table-fedit-move 'previous-line))
   3771 
   3772 (defun org-table-fedit-line-down ()
   3773   "Move cursor one line down in the window showing the table."
   3774   (interactive)
   3775   (org-table-fedit-move 'next-line))
   3776 
   3777 (defun org-table-fedit-move (command)
   3778   "Move the cursor in the window showing the table.
   3779 Use COMMAND to do the motion, repeat if necessary to end up in a data line."
   3780   (let ((org-table-allow-automatic-line-recalculation nil)
   3781 	(pos org-pos) (win (selected-window)) p)
   3782     (select-window (get-buffer-window (marker-buffer org-pos)))
   3783     (setq p (point))
   3784     (call-interactively command)
   3785     (while (and (org-at-table-p)
   3786 		(org-at-table-hline-p))
   3787       (call-interactively command))
   3788     (or (org-at-table-p) (goto-char p))
   3789     (move-marker pos (point))
   3790     (select-window win)))
   3791 
   3792 (defun org-table-fedit-scroll (N)
   3793   (interactive "p")
   3794   (let ((other-window-scroll-buffer (marker-buffer org-pos)))
   3795     (scroll-other-window N)))
   3796 
   3797 (defun org-table-fedit-scroll-down (N)
   3798   (interactive "p")
   3799   (org-table-fedit-scroll (- N)))
   3800 
   3801 (defun org-table-add-rectangle-overlay (beg end &optional face)
   3802   "Add a new overlay."
   3803   (let ((ov (make-overlay beg end)))
   3804     (overlay-put ov 'face (or face 'secondary-selection))
   3805     (push ov org-table-rectangle-overlays)))
   3806 
   3807 (defun org-table-highlight-rectangle (&optional beg end face)
   3808   "Highlight rectangular region in a table.
   3809 When buffer positions BEG and END are provided, use them to
   3810 delimit the region to highlight.  Otherwise, refer to point.  Use
   3811 FACE, when non-nil, for the highlight."
   3812   (let* ((beg (or beg (point)))
   3813 	 (end (or end (point)))
   3814 	 (b (min beg end))
   3815 	 (e (max beg end))
   3816 	 (start-coordinates
   3817 	  (save-excursion
   3818 	    (goto-char b)
   3819 	    (cons (line-beginning-position) (org-table-current-column))))
   3820 	 (end-coordinates
   3821 	  (save-excursion
   3822 	    (goto-char e)
   3823 	    (cons (line-beginning-position) (org-table-current-column)))))
   3824     (when (boundp 'org-show-positions)
   3825       (setq org-show-positions (cons b (cons e org-show-positions))))
   3826     (goto-char (car start-coordinates))
   3827     (let ((column-start (min (cdr start-coordinates) (cdr end-coordinates)))
   3828 	  (column-end (max (cdr start-coordinates) (cdr end-coordinates)))
   3829 	  (last-row (car end-coordinates)))
   3830       (while (<= (point) last-row)
   3831 	(when (looking-at org-table-dataline-regexp)
   3832 	  (org-table-goto-column column-start)
   3833 	  (skip-chars-backward "^|\n")
   3834 	  (let ((p (point)))
   3835 	    (org-table-goto-column column-end)
   3836 	    (skip-chars-forward "^|\n")
   3837 	    (org-table-add-rectangle-overlay p (point) face)))
   3838 	(forward-line)))
   3839     (goto-char (car start-coordinates)))
   3840   (add-hook 'before-change-functions #'org-table-remove-rectangle-highlight))
   3841 
   3842 (defun org-table-remove-rectangle-highlight (&rest _ignore)
   3843   "Remove the rectangle overlays."
   3844   (unless org-inhibit-highlight-removal
   3845     (remove-hook 'before-change-functions 'org-table-remove-rectangle-highlight)
   3846     (mapc 'delete-overlay org-table-rectangle-overlays)
   3847     (setq org-table-rectangle-overlays nil)))
   3848 
   3849 (defvar-local org-table-coordinate-overlays nil
   3850   "Collects the coordinate grid overlays, so that they can be removed.")
   3851 (put 'org-table-coordinate-overlays 'permanent-local t)
   3852 
   3853 (defun org-table-overlay-coordinates ()
   3854   "Add overlays to the table at point, to show row/column coordinates."
   3855   (interactive)
   3856   (mapc 'delete-overlay org-table-coordinate-overlays)
   3857   (setq org-table-coordinate-overlays nil)
   3858   (save-excursion
   3859     (let ((id 0) (ih 0) hline eol str ov)
   3860       (goto-char (org-table-begin))
   3861       (while (org-at-table-p)
   3862         (setq eol (line-end-position))
   3863         (setq ov (make-overlay (line-beginning-position)
   3864                                (1+ (line-beginning-position))))
   3865 	(push ov org-table-coordinate-overlays)
   3866 	(setq hline (looking-at org-table-hline-regexp))
   3867 	(setq str (if hline (format "I*%-2d" (setq ih (1+ ih)))
   3868 		    (format "%4d" (setq id (1+ id)))))
   3869 	(org-overlay-before-string ov str 'org-special-keyword 'evaporate)
   3870 	(when hline
   3871 	  (let ((ic 0))
   3872 	    (while (re-search-forward "[+|]\\(-+\\)" eol t)
   3873 	      (cl-incf ic)
   3874 	      (let* ((beg (1+ (match-beginning 0)))
   3875 		     (s1 (format "$%d" ic))
   3876 		     (s2 (org-number-to-letters ic))
   3877 		     (str (if (eq t org-table-use-standard-references) s2 s1))
   3878 		     (ov (make-overlay beg (+ beg (length str)))))
   3879 		(push ov org-table-coordinate-overlays)
   3880 		(org-overlay-display ov str 'org-special-keyword 'evaporate)))))
   3881 	(forward-line)))))
   3882 
   3883 ;;;###autoload
   3884 (defun org-table-toggle-coordinate-overlays ()
   3885   "Toggle the display of Row/Column numbers in tables."
   3886   (interactive)
   3887   (if (not (org-at-table-p))
   3888       (user-error "Not on a table")
   3889     (setq org-table-overlay-coordinates (not org-table-overlay-coordinates))
   3890     (when (and (org-at-table-p) org-table-overlay-coordinates)
   3891       (org-table-align))
   3892     (unless org-table-overlay-coordinates
   3893       (mapc 'delete-overlay org-table-coordinate-overlays)
   3894       (setq org-table-coordinate-overlays nil))
   3895     (message "Tables Row/Column numbers display turned %s"
   3896 	     (if org-table-overlay-coordinates "on" "off"))))
   3897 
   3898 ;;;###autoload
   3899 (defun org-table-toggle-formula-debugger ()
   3900   "Toggle the formula debugger in tables."
   3901   (interactive)
   3902   (setq org-table-formula-debug (not org-table-formula-debug))
   3903   (message "Formula debugging has been turned %s"
   3904 	   (if org-table-formula-debug "on" "off")))
   3905 
   3906 
   3907 ;;; Columns Shrinking
   3908 
   3909 (defun org-table--shrunk-field ()
   3910   "Non-nil if current field is narrowed.
   3911 When non-nil, return the overlay narrowing the field."
   3912   (cl-some (lambda (o)
   3913 	     (and (eq 'table-column-hide (overlay-get o 'org-overlay-type))
   3914 		  o))
   3915 	   (overlays-at (save-excursion
   3916 			  (skip-chars-forward (if (org-at-table-hline-p) "^+|"
   3917 						"^|")
   3918 					      (line-end-position))
   3919 			  (1- (point))))))
   3920 
   3921 (defun org-table--list-shrunk-columns ()
   3922   "List currently shrunk columns in table at point."
   3923   (save-excursion
   3924     ;; We really check shrunk columns in current row only.  It could
   3925     ;; be wrong if all rows do not contain the same number of columns
   3926     ;; (i.e. the table is not properly aligned).  As a consequence,
   3927     ;; some columns may not be shrunk again upon aligning the table.
   3928     ;;
   3929     ;; For example, in the following table, cursor is on first row and
   3930     ;; "<>" indicates a shrunk column.
   3931     ;;
   3932     ;; | |
   3933     ;; | | <> |
   3934     ;;
   3935     ;; Aligning table from the first row will not shrink again the
   3936     ;; second row, which was not visible initially.
   3937     ;;
   3938     ;; However, fixing it requires checking every row, which may be
   3939     ;; slow on large tables.  Moreover, the hindrance of this
   3940     ;; pathological case is very limited.
   3941     (forward-line 0)
   3942     (search-forward "|")
   3943     (let ((separator (if (org-at-table-hline-p) "+" "|"))
   3944 	  (column 1)
   3945 	  (shrunk (and (org-table--shrunk-field) (list 1)))
   3946 	  (end (line-end-position)))
   3947       (while (search-forward separator end t)
   3948 	(cl-incf column)
   3949 	(when (org-table--shrunk-field) (push column shrunk)))
   3950       (nreverse shrunk))))
   3951 
   3952 (defun org-table--make-shrinking-overlay (start end display field &optional pre)
   3953   "Create an overlay to shrink text between START and END.
   3954 
   3955 Use string DISPLAY instead of the real text between the two
   3956 buffer positions.  FIELD is the real contents of the field, as
   3957 a string, or nil.  It is meant to be displayed upon moving the
   3958 mouse onto the overlay.
   3959 
   3960 When optional argument PRE is non-nil, assume the overlay is
   3961 located at the beginning of the field, and prepend
   3962 `org-table--separator-space-pre' to it.  Otherwise, concatenate
   3963 `org-table-shrunk-column-indicator' at its end.
   3964 
   3965 Return the overlay."
   3966   (let ((show-before-edit
   3967 	 (lambda (o &rest _)
   3968 	   ;; Removing one overlay removes all other overlays in the
   3969 	   ;; same column.
   3970 	   (mapc #'delete-overlay
   3971 		 (cdr (overlay-get o 'org-table-column-overlays)))))
   3972 	(o (make-overlay start end)))
   3973     (overlay-put o 'insert-behind-hooks (list show-before-edit))
   3974     (overlay-put o 'insert-in-front-hooks (list show-before-edit))
   3975     (overlay-put o 'modification-hooks (list show-before-edit))
   3976     (overlay-put o 'org-overlay-type 'table-column-hide)
   3977     (when (stringp field) (overlay-put o 'help-echo field))
   3978     ;; Make sure overlays stays on top of table coordinates overlays.
   3979     ;; See `org-table-overlay-coordinates'.
   3980     (overlay-put o 'priority 1)
   3981     (let ((d (if pre (concat org-table--separator-space-pre display)
   3982 	       (concat display org-table-shrunk-column-indicator))))
   3983       (org-overlay-display o d 'org-table t))
   3984     o))
   3985 
   3986 (defun org-table--shrink-field (width align start end contents)
   3987   "Shrink a table field to a specified width.
   3988 
   3989 WIDTH is an integer representing the number of characters to
   3990 display, in addition to `org-table-shrunk-column-indicator'.
   3991 ALIGN is the alignment of the current column, as either \"l\",
   3992 \"c\" or \"r\".  START and END are, respectively, the beginning
   3993 and ending positions of the field.  CONTENTS is its trimmed
   3994 contents, as a string, or `hline' for table rules.
   3995 
   3996 Real field is hidden under one or two overlays.  They have the
   3997 following properties:
   3998 
   3999   `org-overlay-type'
   4000 
   4001     Set to `table-column-hide'.  Used to identify overlays
   4002     responsible for shrinking columns in a table.
   4003 
   4004   `org-table-column-overlays'
   4005 
   4006     It is a list with the pattern (siblings . COLUMN-OVERLAYS)
   4007     where COLUMN-OVERLAYS is the list of all overlays hiding the
   4008     same column.
   4009 
   4010 Whenever the text behind or next to the overlay is modified, all
   4011 the overlays in the column are deleted, effectively displaying
   4012 the column again.
   4013 
   4014 Return a list of overlays hiding the field, or nil if field is
   4015 already hidden."
   4016   (cond
   4017    ((= start end) nil)			;no field to narrow
   4018    ((org-table--shrunk-field) nil)	;already shrunk
   4019    ((= 0 width)				;shrink to one character
   4020     (list (org-table--make-shrinking-overlay
   4021 	   start end "" (if (eq 'hline contents) "" contents))))
   4022    ((eq contents 'hline)
   4023     (list (org-table--make-shrinking-overlay
   4024 	   start end (make-string (1+ width) ?-) "")))
   4025    ((equal contents "")			;no contents to hide
   4026     (list
   4027      (let ((w (org-string-width (buffer-substring start end) nil 'org-table))
   4028 	   ;; We really want WIDTH + 2 whitespace, to include blanks
   4029 	   ;; around fields.
   4030 	   (full (+ 2 width)))
   4031        (if (<= w full)
   4032 	   (org-table--make-shrinking-overlay
   4033 	    (1- end) end (make-string (- full w) ?\s) "")
   4034 	 (org-table--make-shrinking-overlay (- end (- w full) 1) end "" "")))))
   4035    (t
   4036     ;; If the field is not empty, display exactly WIDTH characters.
   4037     ;; It can mean to partly hide the field, or extend it with virtual
   4038     ;; blanks.  To that effect, we use one or two overlays.  The
   4039     ;; first, optional, one may add or hide white spaces before the
   4040     ;; contents of the field.  The other, mandatory, one cuts the
   4041     ;; field or displays white spaces at the end of the field.  It
   4042     ;; also always displays `org-table-shrunk-column-indicator'.
   4043     (let* ((lead (org-with-point-at start (skip-chars-forward " ")))
   4044 	   (trail (org-with-point-at end (abs (skip-chars-backward " "))))
   4045 	   (contents-width (org-string-width
   4046 			    (buffer-substring (+ start lead) (- end trail))
   4047                             nil 'org-table)))
   4048       (cond
   4049        ;; Contents are too large to fit in WIDTH character.  Limit, if
   4050        ;; possible, blanks at the beginning of the field to a single
   4051        ;; white space, and cut the field at an appropriate location.
   4052        ((<= width contents-width)
   4053 	(let ((pre
   4054 	       (and (> lead 0)
   4055 		    (org-table--make-shrinking-overlay
   4056 		     start (+ start lead) "" contents t)))
   4057 	      (post
   4058 	       (org-table--make-shrinking-overlay
   4059 		;; Find cut location so that WIDTH characters are
   4060 		;; visible using dichotomy.
   4061 		(let* ((begin (+ start lead))
   4062 		       (lower begin)
   4063 		       (upper (1- end))
   4064 		       ;; Compensate the absence of leading space,
   4065 		       ;; thus preserving alignment.
   4066 		       (width (if (= lead 0) (1+ width) width)))
   4067 		  (catch :exit
   4068 		    (while (> (- upper lower) 1)
   4069 		      (let ((mean (+ (ash lower -1)
   4070 				     (ash upper -1)
   4071 				     (logand lower upper 1))))
   4072 			(pcase (org-string-width (buffer-substring begin mean) nil 'org-table)
   4073 			  ((pred (= width)) (throw :exit mean))
   4074 			  ((pred (< width)) (setq upper mean))
   4075 			  (_ (setq lower mean)))))
   4076 		    upper))
   4077 		end "" contents)))
   4078 	  (if pre (list pre post) (list post))))
   4079        ;; Contents fit it WIDTH characters.  First compute number of
   4080        ;; white spaces needed on each side of contents, then expand or
   4081        ;; compact blanks on each side of the field in order to
   4082        ;; preserve width and obey to alignment constraints.
   4083        (t
   4084 	(let* ((required (- width contents-width))
   4085 	       (before
   4086 		(pcase align
   4087 		  ;; Compensate the absence of leading space, thus
   4088 		  ;; preserving alignment.
   4089 		  ((guard (= lead 0)) -1)
   4090 		  ("l" 0)
   4091 		  ("r" required)
   4092 		  ("c" (/ required 2))))
   4093 	       (after (- required before))
   4094 	       (pre
   4095 		(pcase (1- lead)
   4096 		  ((or (guard (= lead 0)) (pred (= before))) nil)
   4097 		  ((pred (< before))
   4098 		   (org-table--make-shrinking-overlay
   4099 		    start (+ start (- lead before)) "" contents t))
   4100 		  (_
   4101 		   (org-table--make-shrinking-overlay
   4102 		    start (1+ start)
   4103 		    (make-string (- before (1- lead)) ?\s)
   4104 		    contents t))))
   4105 	       (post
   4106 		(pcase (1- trail)
   4107 		  ((pred (= after))
   4108 		   (org-table--make-shrinking-overlay (1- end) end "" contents))
   4109 		  ((pred (< after))
   4110 		   (org-table--make-shrinking-overlay
   4111 		    (+ after (- end trail)) end "" contents))
   4112 		  (_
   4113 		   (org-table--make-shrinking-overlay
   4114 		    (1- end) end
   4115 		    (make-string (- after (1- trail)) ?\s)
   4116 		    contents)))))
   4117 	  (if pre (list pre post) (list post)))))))))
   4118 
   4119 (defun org-table--read-column-selection (select max)
   4120   "Read column selection select as a list of numbers.
   4121 
   4122 SELECT is a string containing column ranges, separated by white
   4123 space characters, see `org-table-toggle-column-width' for details.
   4124 MAX is the maximum column number.
   4125 
   4126 Return value is a sorted list of numbers.  Ignore any number
   4127 outside of the [1;MAX] range."
   4128   (catch :all
   4129     (sort
   4130      (delete-dups
   4131       (cl-mapcan
   4132        (lambda (s)
   4133 	 (cond
   4134 	  ((member s '("-" "1-")) (throw :all (number-sequence 1 max)))
   4135 	  ((string-match-p "\\`[0-9]+\\'" s)
   4136 	   (let ((n (string-to-number s)))
   4137 	     (and (> n 0) (<= n max) (list n))))
   4138 	  ((string-match "\\`\\([0-9]+\\)?-\\([0-9]+\\)?\\'" s)
   4139 	   (let ((n (match-string 1 s))
   4140 		 (m (match-string 2 s)))
   4141 	     (number-sequence (if n (max 1 (string-to-number n))
   4142 				1)
   4143 			      (if m (min max (string-to-number m))
   4144 				max))))
   4145 	  (t nil)))			;invalid specification
   4146        (split-string select)))
   4147      #'<)))
   4148 
   4149 (defun org-table--shrink-columns (columns beg end)
   4150   "Shrink COLUMNS in a table.
   4151 COLUMNS is a sorted list of column numbers.  BEG and END are,
   4152 respectively, the beginning position and the end position of the
   4153 table."
   4154   (org-with-wide-buffer
   4155    (font-lock-ensure beg end)
   4156    (dolist (c columns)
   4157      (goto-char beg)
   4158      (let ((align nil)
   4159 	   (width nil)
   4160 	   (fields nil))
   4161        (while (< (point) end)
   4162 	 (catch :continue
   4163 	   (let* ((hline? (org-at-table-hline-p))
   4164 		  (separator (if hline? "+" "|")))
   4165 	     ;; Move to COLUMN.
   4166 	     (search-forward "|")
   4167 	     (or (= c 1)		;already there
   4168 		 (search-forward separator (line-end-position) t (1- c))
   4169 		 (throw :continue nil)) ;skip invalid columns
   4170 	     ;; Extract boundaries and contents from current field.
   4171 	     ;; Also set the column's width if we encounter a width
   4172 	     ;; cookie for the first time.
   4173 	     (let* ((start (point))
   4174 		    (end (progn
   4175 			   (skip-chars-forward (concat "^|" separator)
   4176 					       (line-end-position))
   4177 			   (point)))
   4178 		    (contents (if hline? 'hline
   4179 				(org-trim (buffer-substring start end)))))
   4180 	       (push (list start end contents) fields)
   4181 	       (when (and (not hline?)
   4182 			  (string-match "\\`<\\([lrc]\\)?\\([0-9]+\\)>\\'"
   4183 					contents))
   4184 		 (unless align (setq align (match-string 1 contents)))
   4185 		 (unless width
   4186 		   (setq width (string-to-number (match-string 2 contents))))))))
   4187 	 (forward-line))
   4188        ;; Link overlays for current field to the other overlays in the
   4189        ;; same column.
   4190        (let ((chain (list 'siblings)))
   4191 	 (dolist (field fields)
   4192 	   (dolist (new (apply #'org-table--shrink-field
   4193 			       (or width 0) (or align "l") field))
   4194 	     (push new (cdr chain))
   4195 	     (overlay-put new 'org-table-column-overlays chain))))))))
   4196 
   4197 ;;;###autoload
   4198 (defun org-table-toggle-column-width (&optional arg)
   4199   "Shrink or expand current column in an Org table.
   4200 
   4201 If a width cookie specifies a width W for the column, the first
   4202 W visible characters are displayed.  Otherwise, the column is
   4203 shrunk to a single character.
   4204 
   4205 When point is before the first column or after the last one, ask
   4206 for the columns to shrink or expand, as a list of ranges.
   4207 A column range can be one of the following patterns:
   4208 
   4209   N    column N only
   4210   N-M  every column between N and M (both inclusive)
   4211   N-   every column between N (inclusive) and the last column
   4212   -M   every column between the first one and M (inclusive)
   4213   -    every column
   4214 
   4215 When optional argument ARG is a string, use it as white space
   4216 separated list of column ranges.
   4217 
   4218 When called with `\\[universal-argument]' prefix, call \
   4219 `org-table-shrink', i.e.,
   4220 shrink columns with a width cookie and expand the others.
   4221 
   4222 When called with `\\[universal-argument] \\[universal-argument]' \
   4223 prefix, expand all columns."
   4224   (interactive "P")
   4225   (unless (org-at-table-p) (user-error "Not in a table"))
   4226   (let* ((begin (org-table-begin))
   4227 	 (end (org-table-end))
   4228 	 ;; Compute an upper bound for the number of columns.
   4229 	 ;; Nonexistent columns are ignored anyway.
   4230 	 (max-columns (/ (- (line-end-position) (line-beginning-position)) 2))
   4231 	 (shrunk (org-table--list-shrunk-columns))
   4232 	 (columns
   4233 	  (pcase arg
   4234 	    (`nil
   4235 	     (if (save-excursion
   4236 		   (skip-chars-backward "^|" (line-beginning-position))
   4237 		   (or (bolp) (looking-at-p "[ \t]*$")))
   4238 		 ;; Point is either before first column or past last
   4239 		 ;; one.  Ask for columns to operate on.
   4240 		 (org-table--read-column-selection
   4241 		  (read-string "Column ranges (e.g. 2-4 6-): ")
   4242 		  max-columns)
   4243 	       (list (org-table-current-column))))
   4244 	    ((pred stringp) (org-table--read-column-selection arg max-columns))
   4245 	    ((or `(4) `(16)) nil)
   4246 	    (_ (user-error "Invalid argument: %S" arg)))))
   4247     (pcase arg
   4248       (`(4) (org-table-shrink begin end))
   4249       (`(16) (org-table-expand begin end))
   4250       (_
   4251        (org-table-expand begin end)
   4252        (org-table--shrink-columns
   4253 	(cl-set-exclusive-or columns shrunk) begin end)))))
   4254 
   4255 ;;;###autoload
   4256 (defun org-table-shrink (&optional begin end)
   4257   "Shrink all columns with a width cookie in the table at point.
   4258 
   4259 Columns without a width cookie are expanded.
   4260 
   4261 Optional arguments BEGIN and END, when non-nil, specify the
   4262 beginning and end position of the current table."
   4263   (interactive)
   4264   (unless (or begin (org-at-table-p)) (user-error "Not at a table"))
   4265   (org-with-wide-buffer
   4266    (let ((begin (or begin (org-table-begin)))
   4267 	 (end (or end (org-table-end)))
   4268 	 (regexp "|[ \t]*<[lrc]?[0-9]+>[ \t]*\\(|\\|$\\)")
   4269 	 (columns))
   4270      (goto-char begin)
   4271      (while (re-search-forward regexp end t)
   4272        (goto-char (match-beginning 1))
   4273        (cl-pushnew (org-table-current-column) columns))
   4274      (org-table-expand begin end)
   4275      ;; Make sure invisible characters in the table are at the right
   4276      ;; place since column widths take them into account.
   4277      (font-lock-ensure begin end)
   4278      (org-table--shrink-columns (sort columns #'<) begin end))))
   4279 
   4280 ;;;###autoload
   4281 (defun org-table-expand (&optional begin end)
   4282   "Expand all columns in the table at point.
   4283 Optional arguments BEGIN and END, when non-nil, specify the
   4284 beginning and end position of the current table."
   4285   (interactive)
   4286   (unless (or begin (org-at-table-p)) (user-error "Not at a table"))
   4287   (org-with-wide-buffer
   4288    (let ((begin (or begin (org-table-begin)))
   4289 	 (end (or end (org-table-end))))
   4290      (remove-overlays begin end 'org-overlay-type 'table-column-hide))))
   4291 
   4292 
   4293 ;;; Generic Tools
   4294 
   4295 ;;;###autoload
   4296 (defun org-table-map-tables (f &optional quietly)
   4297   "Apply function F to the start of all tables in the buffer."
   4298   (org-with-point-at 1
   4299     (while (re-search-forward org-table-line-regexp nil t)
   4300       (let ((table (org-element-lineage (org-element-at-point) 'table t)))
   4301 	(when table
   4302 	  (unless quietly
   4303 	    (message "Mapping tables: %d%%"
   4304 		     (floor (* 100.0 (point)) (buffer-size))))
   4305 	  (goto-char (org-element-post-affiliated table))
   4306 	  (let ((end (copy-marker (org-element-end table))))
   4307 	    (unwind-protect
   4308 		(progn (funcall f) (goto-char end))
   4309 	      (set-marker end nil)))))))
   4310   (unless quietly (message "Mapping tables: done")))
   4311 
   4312 ;;;###autoload
   4313 (defun org-table-export (&optional file format)
   4314   "Export table to a file, with configurable format.
   4315 Such a file can be imported into usual spreadsheet programs.
   4316 
   4317 FILE can be the output file name.  If not given, it will be taken
   4318 from a TABLE_EXPORT_FILE property in the current entry or higher
   4319 up in the hierarchy, or the user will be prompted for a file
   4320 name.  FORMAT can be an export format, of the same kind as it
   4321 used when `-mode' sends a table in a different format.
   4322 
   4323 The command suggests a format depending on TABLE_EXPORT_FORMAT,
   4324 whether it is set locally or up in the hierarchy, then on the
   4325 extension of the given file name, and finally on the variable
   4326 `org-table-export-default-format'."
   4327   (interactive)
   4328   (unless (org-at-table-p) (user-error "No table at point"))
   4329   (org-table-align)	       ; Make sure we have everything we need.
   4330   (let ((file (or file (org-entry-get (point) "TABLE_EXPORT_FILE" t))))
   4331     (unless file
   4332       (setq file (read-file-name "Export table to: "))
   4333       (unless (or (not (file-exists-p file))
   4334 		  (y-or-n-p (format "Overwrite file %s? " file)))
   4335 	(user-error "File not written")))
   4336     (when (file-directory-p file)
   4337       (user-error "This is a directory path, not a file"))
   4338     (when (and (buffer-file-name (buffer-base-buffer))
   4339 	       (file-equal-p
   4340 		(file-truename file)
   4341 		(file-truename (buffer-file-name (buffer-base-buffer)))))
   4342       (user-error "Please specify a file name that is different from current"))
   4343     (let ((fileext (concat (file-name-extension file) "$"))
   4344 	  (format (or format (org-entry-get (point) "TABLE_EXPORT_FORMAT" t))))
   4345       (unless format
   4346 	(let* ((formats '("orgtbl-to-tsv" "orgtbl-to-csv" "orgtbl-to-latex"
   4347 			  "orgtbl-to-html" "orgtbl-to-generic"
   4348 			  "orgtbl-to-texinfo" "orgtbl-to-orgtbl"
   4349 			  "orgtbl-to-unicode"))
   4350 	       (deffmt-readable
   4351 		 (replace-regexp-in-string
   4352 		  "\t" "\\t"
   4353 		  (replace-regexp-in-string
   4354 		   "\n" "\\n"
   4355 		   (or (car (delq nil
   4356 				  (mapcar
   4357 				   (lambda (f)
   4358 				     (and (string-match-p fileext f) f))
   4359 				   formats)))
   4360 		       org-table-export-default-format)
   4361 		   t t)
   4362 		  t t)))
   4363 	  (setq format
   4364 		(org-completing-read
   4365 		 "Format: " formats nil nil deffmt-readable))))
   4366       (if (string-match "\\([^ \t\r\n]+\\)\\( +.*\\)?" format)
   4367 	  (let ((transform (intern (match-string 1 format)))
   4368 		(params (and (match-end 2)
   4369 			     (read (concat "(" (match-string 2 format) ")"))))
   4370 		(table (org-table-to-lisp)))
   4371 	    (unless (fboundp transform)
   4372 	      (user-error "No such transformation function %s" transform))
   4373             (with-temp-file file
   4374               (insert (funcall transform table params) "\n"))
   4375 	    (message "Export done."))
   4376 	(user-error "TABLE_EXPORT_FORMAT invalid")))))
   4377 
   4378 ;;;###autoload
   4379 (defun org-table--align-field (field width align)
   4380   "Format FIELD according to column WIDTH and alignment ALIGN.
   4381 FIELD is a string.  WIDTH is a number.  ALIGN is either \"c\",
   4382 \"l\" or\"r\"."
   4383   (let* ((spaces (- width (org-string-width field nil 'org-table)))
   4384 	 (prefix (pcase align
   4385 		   ("l" "")
   4386 		   ("r" (make-string spaces ?\s))
   4387 		   ("c" (make-string (/ spaces 2) ?\s))))
   4388 	 (suffix (make-string (- spaces (length prefix)) ?\s)))
   4389     (concat org-table--separator-space-pre
   4390 	    prefix
   4391 	    field
   4392 	    suffix
   4393 	    org-table--separator-space-post)))
   4394 
   4395 (defun org-table-align ()
   4396   "Align the table at point by aligning all vertical bars."
   4397   (interactive)
   4398   (let ((beg (org-table-begin))
   4399 	(end (copy-marker (org-table-end))))
   4400     (org-table-save-field
   4401      ;; Make sure invisible characters in the table are at the right
   4402      ;; place since column widths take them into account.
   4403      (font-lock-ensure beg end)
   4404      (move-marker org-table-aligned-begin-marker beg)
   4405      (move-marker org-table-aligned-end-marker end)
   4406      (goto-char beg)
   4407      (org-table-with-shrunk-columns
   4408       (let* ((table (org-table-to-lisp))
   4409              (rows (remq 'hline table))
   4410 	     (widths nil)
   4411 	     (alignments nil)
   4412 	     (columns-number 1))
   4413 	(if (null rows)
   4414 	    ;; Table contains only horizontal rules.  Compute the
   4415 	    ;; number of columns anyway, and choose an arbitrary width
   4416 	    ;; and alignment.
   4417 	    (let ((end (line-end-position)))
   4418 	      (save-excursion
   4419 		(while (search-forward "+" end t)
   4420 		  (cl-incf columns-number)))
   4421 	      (setq widths (make-list columns-number 1))
   4422 	      (setq alignments (make-list columns-number "l")))
   4423 	  ;; Compute alignment and width for each column.
   4424 	  (setq columns-number (apply #'max (mapcar #'length rows)))
   4425 	  (dotimes (i columns-number)
   4426 	    (let ((max-width 1)
   4427 		  (fixed-align? nil)
   4428 		  (numbers 0)
   4429 		  (non-empty 0))
   4430 	      (dolist (row rows)
   4431 		(let ((cell (or (nth i row) "")))
   4432 		  (setq max-width (max max-width (org-string-width cell nil 'org-table)))
   4433 		  (cond (fixed-align? nil)
   4434 			((equal cell "") nil)
   4435 			((string-match "\\`<\\([lrc]\\)[0-9]*>\\'" cell)
   4436 			 (setq fixed-align? (match-string 1 cell)))
   4437 			(t
   4438 			 (cl-incf non-empty)
   4439 			 (when (string-match-p org-table-number-regexp cell)
   4440 			   (cl-incf numbers))))))
   4441 	      (push max-width widths)
   4442 	      (push (cond
   4443 		     (fixed-align?)
   4444 		     ((>= numbers (* org-table-number-fraction non-empty)) "r")
   4445 		     (t "l"))
   4446 		    alignments)))
   4447 	  (setq widths (nreverse widths))
   4448 	  (setq alignments (nreverse alignments)))
   4449 	;; Store alignment of this table, for later editing of single
   4450 	;; fields.
   4451 	(setq org-table-last-alignment alignments)
   4452 	(setq org-table-last-column-widths widths)
   4453 	;; Build new table rows.  Only replace rows that actually
   4454 	;; changed.
   4455 	(let ((rule (and (memq 'hline table)
   4456 			 (mapconcat (lambda (w) (make-string (+ 2 w) ?-))
   4457 				    widths
   4458 				    "+")))
   4459               (indent (progn (looking-at "[ \t]*|") (match-string 0))))
   4460 	  (dolist (row table)
   4461 	    (let ((previous (buffer-substring (point) (line-end-position)))
   4462 		  (new
   4463                    (concat indent
   4464 		           (if (eq row 'hline) rule
   4465 		             (let* ((offset (- columns-number (length row)))
   4466 			            (fields (if (= 0 offset) row
   4467                                               ;; Add missing fields.
   4468 				              (append row
   4469 						      (make-list offset "")))))
   4470 			       (mapconcat #'identity
   4471 				          (cl-mapcar #'org-table--align-field
   4472 					             fields
   4473 					             widths
   4474 					             alignments)
   4475 				          "|")))
   4476 		           "|")))
   4477 	      (if (equal new previous)
   4478 		  (forward-line)
   4479 		(insert new "\n")
   4480 		(delete-region (point) (line-beginning-position 2))))))
   4481 	(set-marker end nil)
   4482 	(when org-table-overlay-coordinates (org-table-overlay-coordinates))
   4483 	(setq org-table-may-need-update nil))))))
   4484 
   4485 ;;;###autoload
   4486 (defun org-table-justify-field-maybe (&optional new)
   4487   "Justify the current field, text to left, number to right.
   4488 Optional argument NEW may specify text to replace the current field content."
   4489   ;; FIXME: Prevent newlines inside field.  They are currently not
   4490   ;; supported.
   4491   (when (and (stringp new) (string-match-p "\n" new))
   4492     (message "Removing newlines from formula result: %S" new)
   4493     (setq new (replace-regexp-in-string
   4494                "\n" " "
   4495                (replace-regexp-in-string "\\(^\n+\\)\\|\\(\n+$\\)" "" new))))
   4496   (cond
   4497    ((and (not new) org-table-may-need-update)) ; Realignment will happen anyway
   4498    ((org-at-table-hline-p))
   4499    (t
   4500     (when (or (not (eq (marker-buffer org-table-aligned-begin-marker)
   4501 		     (current-buffer)))
   4502 	      (< (point) org-table-aligned-begin-marker)
   4503 	      (>= (point) org-table-aligned-end-marker))
   4504       ;; This is not the same table, force a full re-align.
   4505       (setq org-table-may-need-update t
   4506             org-table-last-alignment nil
   4507             org-table-last-column-widths nil))
   4508     (when new
   4509       ;; Realign the current field, based on previous full realign.
   4510       (let ((pos (point))
   4511 	    (col (org-table-current-column)))
   4512         (when (> col 0)
   4513 	  (skip-chars-backward "^|")
   4514 	  (if (not (looking-at " *\\(?:\\([^|\n]*?\\) *\\(|\\)\\|\\([^|\n]+?\\) *\\($\\)\\)"))
   4515 	      (setq org-table-may-need-update t)
   4516 	    (let* ((align (nth (1- col) org-table-last-alignment))
   4517 		   (width (nth (1- col) org-table-last-column-widths))
   4518 		   (cell (match-string 0))
   4519 		   (field (match-string 1))
   4520 		   (properly-closed? (/= (match-beginning 2) (match-end 2)))
   4521 		   (new-cell
   4522 		    (save-match-data
   4523 		      (cond (org-table-may-need-update
   4524 			     (format " %s |" (or new field)))
   4525 			    ((not properly-closed?)
   4526 			     (setq org-table-may-need-update t)
   4527 			     (format " %s |" (or new field)))
   4528 			    ((not new)
   4529 			     (concat (org-table--align-field field width align)
   4530 				     "|"))
   4531 			    ((and width (<= (org-string-width new nil 'org-table) width))
   4532 			     (concat (org-table--align-field new width align)
   4533 				     "|"))
   4534 			    (t
   4535 			     (setq org-table-may-need-update t)
   4536 			     (format " %s |" new))))))
   4537 	      (unless (equal new-cell cell)
   4538 	        (let (org-table-may-need-update)
   4539 		  (replace-match new-cell t t)))
   4540 	      (goto-char pos)))))))))
   4541 
   4542 ;;;###autoload
   4543 (defun org-table-sort-lines
   4544     (&optional with-case sorting-type getkey-func compare-func interactive?)
   4545   "Sort table lines according to the column at point.
   4546 
   4547 The position of point indicates the column to be used for
   4548 sorting, and the range of lines is the range between the nearest
   4549 horizontal separator lines, or the entire table of no such lines
   4550 exist.  If point is before the first column, you will be prompted
   4551 for the sorting column.  If there is an active region, the mark
   4552 specifies the first line and the sorting column, while point
   4553 should be in the last line to be included into the sorting.
   4554 
   4555 The command then prompts for the sorting type which can be
   4556 alphabetically, numerically, or by time (as given in a time stamp
   4557 in the field, or as a HH:MM value).  Sorting in reverse order is
   4558 also possible.
   4559 
   4560 With prefix argument WITH-CASE, alphabetic sorting will be case-sensitive
   4561 if the locale allows for it.
   4562 
   4563 If SORTING-TYPE is specified when this function is called from a Lisp
   4564 program, no prompting will take place.  SORTING-TYPE must be a character,
   4565 any of (?a ?A ?n ?N ?t ?T ?f ?F) where the capital letters indicate that
   4566 sorting should be done in reverse order.
   4567 
   4568 If the SORTING-TYPE is ?f or ?F, then GETKEY-FUNC specifies
   4569 a function to be called to extract the key.  It must return a value
   4570 that is compatible with COMPARE-FUNC, the function used to compare
   4571 entries.
   4572 
   4573 A non-nil value for INTERACTIVE? is used to signal that this
   4574 function is being called interactively."
   4575   (interactive (list current-prefix-arg nil nil nil t))
   4576   (when (org-region-active-p) (goto-char (region-beginning)))
   4577   ;; Point must be either within a field or before a data line.
   4578   (save-excursion
   4579     (skip-chars-backward " \t")
   4580     (when (bolp) (search-forward "|" (line-end-position) t))
   4581     (org-table-check-inside-data-field))
   4582   ;; Set appropriate case sensitivity and column used for sorting.
   4583   (let ((column (let ((c (org-table-current-column)))
   4584 		  (cond ((> c 0) c)
   4585 			(interactive?
   4586 			 (read-number "Use column N for sorting: "))
   4587 			(t 1))))
   4588 	(sorting-type
   4589 	 (or sorting-type
   4590 	     (read-char-exclusive "Sort Table: [a]lphabetic, [n]umeric, \
   4591 \[t]ime, [f]unc.  A/N/T/F means reversed: ")))
   4592 	(start (org-table-begin))
   4593 	(end (org-table-end)))
   4594     (save-restriction
   4595       ;; Narrow buffer to appropriate sorting area.
   4596       (if (org-region-active-p)
   4597 	  (progn (goto-char (region-beginning))
   4598 		 (narrow-to-region
   4599 		  (point)
   4600 		  (save-excursion (goto-char (region-end))
   4601 				  (line-beginning-position 2))))
   4602 	(narrow-to-region
   4603 	 (save-excursion
   4604 	   (if (re-search-backward org-table-hline-regexp start t)
   4605 	       (line-beginning-position 2)
   4606 	     start))
   4607 	 (if (save-excursion (re-search-forward org-table-hline-regexp end t))
   4608 	     (match-beginning 0)
   4609 	   end)))
   4610       ;; Determine arguments for `sort-subr'.  Also record original
   4611       ;; position.  `org-table-save-field' cannot help here since
   4612       ;; sorting is too much destructive.
   4613       (let* ((coordinates
   4614 	      (cons (count-lines (point-min) (line-beginning-position))
   4615 		    (current-column)))
   4616 	     (extract-key-from-field
   4617 	      ;; Function to be called on the contents of the field
   4618 	      ;; used for sorting in the current row.
   4619 	      (cl-case sorting-type
   4620 		((?n ?N) #'string-to-number)
   4621 		((?a ?A) #'org-sort-remove-invisible)
   4622 		((?t ?T)
   4623 		 (lambda (f)
   4624 		   (cond ((string-match org-ts-regexp-both f)
   4625 			  (float-time
   4626 			   (org-time-string-to-time (match-string 0 f))))
   4627 			 ((org-duration-p f) (org-duration-to-minutes f))
   4628 			 ((string-match "\\<[0-9]+:[0-9]\\{2\\}\\>" f)
   4629 			  (org-duration-to-minutes (match-string 0 f)))
   4630 			 (t 0))))
   4631 		((?f ?F)
   4632 		 (or getkey-func
   4633 		     (and interactive?
   4634 			  (org-read-function "Function for extracting keys: "))
   4635 		     (error "Missing key extractor to sort rows")))
   4636 		(t (user-error "Invalid sorting type `%c'" sorting-type))))
   4637 	     (predicate
   4638 	      (cl-case sorting-type
   4639 		((?n ?N ?t ?T) #'<)
   4640 		((?a ?A) (if with-case #'org-string<
   4641 			   (lambda (s1 s2) (org-string< s1 s2 nil t))))
   4642 		((?f ?F)
   4643 		 (or compare-func
   4644 		     (and interactive?
   4645 			  (org-read-function
   4646 			   "Function for comparing keys (empty for default \
   4647 `sort-subr' predicate): "
   4648 			   'allow-empty))))))
   4649 	     (shrunk-columns (remq column (org-table--list-shrunk-columns))))
   4650 	(goto-char (point-min))
   4651 	(sort-subr (memq sorting-type '(?A ?N ?T ?F))
   4652 		   (lambda ()
   4653 		     (forward-line)
   4654 		     (while (and (not (eobp))
   4655 				 (not (looking-at org-table-dataline-regexp)))
   4656 		       (forward-line)))
   4657 		   #'end-of-line
   4658 		   (lambda ()
   4659 		     (funcall extract-key-from-field
   4660 			      (org-trim (org-table-get-field column))))
   4661 		   nil
   4662 		   predicate)
   4663 	;; Hide all columns but the one being sorted.
   4664 	(org-table--shrink-columns shrunk-columns start end)
   4665 	;; Move back to initial field.
   4666 	(forward-line (car coordinates))
   4667 	(move-to-column (cdr coordinates))))))
   4668 
   4669 (defun org-table-transpose-table-at-point ()
   4670   "Transpose Org table at point and eliminate hlines.
   4671 So a table like
   4672 
   4673 | 1 | 2 | 4 | 5 |
   4674 |---+---+---+---|
   4675 | a | b | c | d |
   4676 | e | f | g | h |
   4677 
   4678 will be transposed as
   4679 
   4680 | 1 | a | e |
   4681 | 2 | b | f |
   4682 | 4 | c | g |
   4683 | 5 | d | h |
   4684 
   4685 Note that horizontal lines disappear."
   4686   (interactive)
   4687   (let* ((table (delete 'hline (org-table-to-lisp)))
   4688 	 (dline_old (org-table-current-line))
   4689 	 (col_old (org-table-current-column))
   4690 	 (contents (mapcar (lambda (_)
   4691 			     (let ((tp table))
   4692 			       (mapcar
   4693 				(lambda (_)
   4694 				  (prog1
   4695 				      (pop (car tp))
   4696 				    (setq tp (cdr tp))))
   4697 				table)))
   4698 			   (car table))))
   4699     (goto-char (org-table-begin))
   4700     (re-search-forward "|")
   4701     (backward-char)
   4702     (delete-region (point) (org-table-end))
   4703     (insert (mapconcat
   4704 	     (lambda(x)
   4705 	       (concat "| " (mapconcat 'identity x " | " ) "  |\n" ))
   4706 	     contents ""))
   4707     (org-table-goto-line col_old)
   4708     (org-table-goto-column dline_old))
   4709   (org-table-align))
   4710 
   4711 ;;;###autoload
   4712 (defun org-table-wrap-region (arg)
   4713   "Wrap several fields in a column like a paragraph.
   4714 This is useful if you'd like to spread the contents of a field over several
   4715 lines, in order to keep the table compact.
   4716 
   4717 If there is an active region, and both point and mark are in the same column,
   4718 the text in the column is wrapped to minimum width for the given number of
   4719 lines.  Generally, this makes the table more compact.  A prefix ARG may be
   4720 used to change the number of desired lines.  For example, \
   4721 `C-2 \\[org-table-wrap-region]'
   4722 formats the selected text to two lines.  If the region was longer than two
   4723 lines, the remaining lines remain empty.  A negative prefix argument reduces
   4724 the current number of lines by that amount.  The wrapped text is pasted back
   4725 into the table.  If you formatted it to more lines than it was before, fields
   4726 further down in the table get overwritten - so you might need to make space in
   4727 the table first.
   4728 
   4729 If there is no region, the current field is split at the cursor position and
   4730 the text fragment to the right of the cursor is prepended to the field one
   4731 line down.
   4732 
   4733 If there is no region, but you specify a prefix ARG, the current field gets
   4734 blank, and the content is appended to the field above."
   4735   (interactive "P")
   4736   (org-table-check-inside-data-field)
   4737   (if (org-region-active-p)
   4738       ;; There is a region: fill as a paragraph.
   4739       (let ((start (region-beginning)))
   4740         (save-restriction
   4741           (narrow-to-region
   4742            (save-excursion (goto-char start) (move-beginning-of-line 1))
   4743            (save-excursion (org-forward-paragraph) (point)))
   4744           (org-table-cut-region (region-beginning) (region-end))
   4745 	  (when (> (length (car org-table-clip)) 1)
   4746 	    (user-error "Region must be limited to single column"))
   4747 	  (let ((nlines (cond ((not arg) (length org-table-clip))
   4748 			      ((< arg 1) (+ (length org-table-clip) arg))
   4749 			      (t arg))))
   4750 	    (setq org-table-clip
   4751 		  (mapcar #'list
   4752 			  (org-wrap (mapconcat #'car org-table-clip " ")
   4753 				    nil
   4754 				    nlines))))
   4755 	  (goto-char start)
   4756 	  (org-table-paste-rectangle))
   4757         (org-table-align))
   4758     ;; No region, split the current field at point.
   4759     (unless (org-get-alist-option org-M-RET-may-split-line 'table)
   4760       (skip-chars-forward "^\r\n|"))
   4761     (cond
   4762      (arg				; Combine with field above.
   4763       (let ((s (org-table-blank-field))
   4764 	    (col (org-table-current-column)))
   4765 	(forward-line -1)
   4766 	(while (org-at-table-hline-p) (forward-line -1))
   4767 	(org-table-goto-column col)
   4768 	(skip-chars-forward "^|")
   4769 	(skip-chars-backward " ")
   4770 	(insert " " (org-trim s))
   4771 	(org-table-align)))
   4772      ((looking-at "\\([^|]+\\)|")	; Split field.
   4773       (let ((s (match-string 1)))
   4774 	(replace-match " |")
   4775 	(goto-char (match-beginning 0))
   4776 	(org-table-next-row)
   4777 	(insert (org-trim s) " ")
   4778 	(org-table-align)))
   4779      (t (org-table-next-row)))))
   4780 
   4781 (defun org-table--number-for-summing (s)
   4782   (let (n)
   4783     (if (string-match "^ *|? *" s)
   4784 	(setq s (replace-match "" nil nil s)))
   4785     (if (string-match " *|? *$" s)
   4786 	(setq s (replace-match "" nil nil s)))
   4787     (setq n (string-to-number s))
   4788     (cond
   4789      ((and (string-match "0" s)
   4790 	   (string-match "\\`[-+ \t0.edED]+\\'" s)) 0)
   4791      ((string-match "\\`[ \t]+\\'" s) nil)
   4792      ((string-match "\\`\\([0-9]+\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?\\'" s)
   4793       (let ((h (string-to-number (or (match-string 1 s) "0")))
   4794 	    (m (string-to-number (or (match-string 2 s) "0")))
   4795 	    (s (string-to-number (or (match-string 4 s) "0"))))
   4796 	(if (boundp 'org-timecnt) (setq org-timecnt (1+ org-timecnt)))
   4797 	(* 1.0 (+ h (/ m 60.0) (/ s 3600.0)))))
   4798      ((equal n 0) nil)
   4799      (t n))))
   4800 
   4801 ;;;###autoload
   4802 (defun org-table-sum (&optional beg end nlast)
   4803   "Sum numbers in region of current table column.
   4804 The result will be displayed in the echo area, and will be available
   4805 as kill to be inserted with \\[yank].
   4806 
   4807 If there is an active region, it is interpreted as a rectangle and all
   4808 numbers in that rectangle will be summed.  If there is no active
   4809 region and point is located in a table column, sum all numbers in that
   4810 column.
   4811 
   4812 If at least one number looks like a time HH:MM or HH:MM:SS, all other
   4813 numbers are assumed to be times as well (in decimal hours) and the
   4814 numbers are added as such.
   4815 
   4816 If NLAST is a number, only the NLAST fields will actually be summed."
   4817   (interactive)
   4818   (save-excursion
   4819     (let (col (org-timecnt 0) diff h m s org-table-clip)
   4820       (cond
   4821        ((and beg end))			; beg and end given explicitly
   4822        ((org-region-active-p)
   4823 	(setq beg (region-beginning) end (region-end)))
   4824        (t
   4825 	(setq col (org-table-current-column))
   4826 	(goto-char (org-table-begin))
   4827 	(unless (re-search-forward "^[ \t]*|[^-]" nil t)
   4828 	  (user-error "No table data"))
   4829 	(org-table-goto-column col)
   4830 	(setq beg (point))
   4831 	(goto-char (org-table-end))
   4832 	(unless (re-search-backward "^[ \t]*|[^-]" nil t)
   4833 	  (user-error "No table data"))
   4834 	(org-table-goto-column col)
   4835 	(setq end (point))))
   4836       (let* ((items (apply 'append (org-table-copy-region beg end)))
   4837 	     (items1 (cond ((not nlast) items)
   4838 			   ((>= nlast (length items)) items)
   4839 			   (t (setq items (reverse items))
   4840 			      (setcdr (nthcdr (1- nlast) items) nil)
   4841 			      (nreverse items))))
   4842 	     (numbers (delq nil (mapcar #'org-table--number-for-summing
   4843 					items1)))
   4844 	     (res (apply '+ numbers))
   4845 	     (sres (if (= org-timecnt 0)
   4846 		       (number-to-string res)
   4847 		     (setq diff (* 3600 res)
   4848 			   h (floor diff 3600) diff (mod diff 3600)
   4849 			   m (floor diff 60) diff (mod diff 60)
   4850 			   s diff)
   4851 		     (format "%.0f:%02.0f:%02.0f" h m s))))
   4852 	(kill-new sres)
   4853 	(when (called-interactively-p 'interactive)
   4854 	  (message (substitute-command-keys
   4855 		    (format "Sum of %d items: %-20s     \
   4856 \(\\[yank] will insert result into buffer)"
   4857 			    (length numbers)
   4858 			    sres))))
   4859 	sres))))
   4860 
   4861 ;;;###autoload
   4862 (defun org-table-analyze ()
   4863   "Analyze table at point and store results.
   4864 
   4865 This function sets up the following dynamically scoped variables:
   4866 
   4867  `org-table-column-name-regexp',
   4868  `org-table-column-names',
   4869  `org-table-current-begin-pos',
   4870  `org-table-current-line-types',
   4871  `org-table-current-ncol',
   4872  `org-table-dlines',
   4873  `org-table-hlines',
   4874  `org-table-local-parameters',
   4875  `org-table-named-field-locations'."
   4876   (let ((beg (org-table-begin))
   4877 	(end (org-table-end)))
   4878     (save-excursion
   4879       (goto-char beg)
   4880       ;; Extract column names.
   4881       (setq org-table-column-names nil)
   4882       (when (save-excursion
   4883 	      (re-search-forward "^[ \t]*| *! *\\(|.*\\)" end t))
   4884 	(let ((c 1))
   4885 	  (dolist (name (org-split-string (match-string 1) " *| *"))
   4886 	    (cl-incf c)
   4887 	    (when (string-match "\\`[a-zA-Z][_a-zA-Z0-9]*\\'" name)
   4888 	      (push (cons name (number-to-string c)) org-table-column-names)))))
   4889       (setq org-table-column-names (nreverse org-table-column-names))
   4890       (setq org-table-column-name-regexp
   4891 	    (format "\\$\\(%s\\)\\>"
   4892 		    (regexp-opt (mapcar #'car org-table-column-names) t)))
   4893       ;; Extract local parameters.
   4894       (setq org-table-local-parameters nil)
   4895       (save-excursion
   4896 	(while (re-search-forward "^[ \t]*| *\\$ *\\(|.*\\)" end t)
   4897 	  (dolist (field (org-split-string (match-string 1) " *| *"))
   4898 	    (when (string-match
   4899 		   "\\`\\([a-zA-Z][_a-zA-Z0-9]*\\|%\\) *= *\\(.*\\)" field)
   4900 	      (push (cons (match-string 1 field) (match-string 2 field))
   4901 		    org-table-local-parameters)))))
   4902       ;; Update named fields locations.  We minimize `count-lines'
   4903       ;; processing by storing last known number of lines in LAST.
   4904       (setq org-table-named-field-locations nil)
   4905       (save-excursion
   4906 	(let ((last (cons (point) 0)))
   4907 	  (while (re-search-forward "^[ \t]*| *\\([_^]\\) *\\(|.*\\)" end t)
   4908 	    (let ((c (match-string 1))
   4909 		  (fields (org-split-string (match-string 2) " *| *")))
   4910 	      (save-excursion
   4911 		(forward-line (if (equal c "_") 1 -1))
   4912 		(let ((fields1
   4913 		       (and (looking-at "^[ \t]*|[^|]*\\(|.*\\)")
   4914 			    (org-split-string (match-string 1) " *| *")))
   4915 		      (line (cl-incf (cdr last) (count-lines (car last) (point))))
   4916 		      (col 1))
   4917 		  (setcar last (point))	; Update last known position.
   4918 		  (while (and fields fields1)
   4919 		    (let ((field (pop fields))
   4920 			  (v (pop fields1)))
   4921 		      (cl-incf col)
   4922 		      (when (and (stringp field)
   4923 				 (stringp v)
   4924 				 (string-match "\\`[a-zA-Z][_a-zA-Z0-9]*\\'"
   4925 					       field))
   4926 			(push (cons field v) org-table-local-parameters)
   4927 			(push (list field line col)
   4928 			      org-table-named-field-locations))))))))))
   4929       ;; Reuse existing markers when possible.
   4930       (if (markerp org-table-current-begin-pos)
   4931 	  (move-marker org-table-current-begin-pos (point))
   4932 	(setq org-table-current-begin-pos (point-marker)))
   4933       ;; Analyze the line types.
   4934       (let ((l 0) hlines dlines types)
   4935 	(while (looking-at "[ \t]*|\\(-\\)?")
   4936 	  (push (if (match-end 1) 'hline 'dline) types)
   4937 	  (if (match-end 1) (push l hlines) (push l dlines))
   4938 	  (forward-line)
   4939 	  (cl-incf l))
   4940 	(push 'hline types) ; Add an imaginary extra hline to the end.
   4941 	(setq org-table-current-line-types (apply #'vector (nreverse types)))
   4942 	(setq org-table-dlines (apply #'vector (cons nil (nreverse dlines))))
   4943 	(setq org-table-hlines (apply #'vector (cons nil (nreverse hlines)))))
   4944       ;; Get the number of columns from the first data line in table.
   4945       (goto-char beg)
   4946       (forward-line (aref org-table-dlines 1))
   4947       (setq org-table-current-ncol
   4948 	    (length (org-split-string
   4949 		     (buffer-substring (line-beginning-position) (line-end-position))
   4950 		     "[ \t]*|[ \t]*"))))))
   4951 
   4952 (defun org-table--force-dataline ()
   4953   "Move point to the closest data line in a table.
   4954 Raise an error if the table contains no data line.  Preserve
   4955 column when moving point."
   4956   (unless (org-match-line org-table-dataline-regexp)
   4957     (let* ((re org-table-dataline-regexp)
   4958 	   (column (current-column))
   4959 	   (p1 (save-excursion (re-search-forward re (org-table-end) t)))
   4960 	   (p2 (save-excursion (re-search-backward re (org-table-begin) t))))
   4961       (cond ((and p1 p2)
   4962 	     (goto-char (if (< (abs (- p1 (point))) (abs (- p2 (point))))
   4963 			    p1
   4964 			  p2)))
   4965 	    ((or p1 p2) (goto-char (or p1 p2)))
   4966 	    (t (user-error "No table data line around here")))
   4967       (org-move-to-column column))))
   4968 
   4969 (defun org-table-show-reference (&optional local)
   4970   "Show the location/value of the $ expression at point.
   4971 When LOCAL is non-nil, show references for the table at point."
   4972   (interactive)
   4973   (org-table-remove-rectangle-highlight)
   4974   (when local (org-table-analyze))
   4975   (catch 'exit
   4976     (let ((pos (if local (point) org-pos))
   4977 	  (face2 'highlight)
   4978 	  (org-inhibit-highlight-removal t)
   4979 	  (win (selected-window))
   4980 	  (org-show-positions nil)
   4981 	  var name e what match dest)
   4982       (setq what (cond
   4983 		  ((org-in-regexp "^@[0-9]+[ \t=]")
   4984 		   (setq match (concat (substring (match-string 0) 0 -1)
   4985 				       "$1.."
   4986 				       (substring (match-string 0) 0 -1)
   4987 				       "$100"))
   4988 		   'range)
   4989 		  ((or (org-in-regexp org-table-range-regexp2)
   4990 		       (org-in-regexp org-table-translate-regexp)
   4991 		       (org-in-regexp org-table-range-regexp))
   4992 		   (setq match
   4993 			 (save-match-data
   4994 			   (org-table-convert-refs-to-rc (match-string 0))))
   4995 		   'range)
   4996 		  ((org-in-regexp "\\$[a-zA-Z][a-zA-Z0-9]*") 'name)
   4997 		  ((org-in-regexp "\\$[0-9]+") 'column)
   4998 		  ((not local) nil)
   4999 		  (t (user-error "No reference at point")))
   5000 	    match (and what (or match (match-string 0))))
   5001       (when (and  match (not (equal (match-beginning 0) (line-beginning-position))))
   5002 	(org-table-add-rectangle-overlay (match-beginning 0) (match-end 0)
   5003 					 'secondary-selection))
   5004       (add-hook 'before-change-functions
   5005 		#'org-table-remove-rectangle-highlight)
   5006       (when (eq what 'name) (setq var (substring match 1)))
   5007       (when (eq what 'range)
   5008 	(unless (eq (string-to-char match) ?@) (setq match (concat "@" match)))
   5009 	(setq match (org-table-formula-substitute-names match)))
   5010       (unless local
   5011 	(save-excursion
   5012 	  (end-of-line)
   5013 	  (re-search-backward "^\\S-" nil t)
   5014 	  (forward-line 0)
   5015 	  (when (looking-at "\\(\\$[0-9a-zA-Z]+\\|@[0-9]+\\$[0-9]+\\|[a-zA-Z]+\
   5016 \\([0-9]+\\|&\\)\\) *=")
   5017 	    (setq dest
   5018 		  (save-match-data
   5019 		    (org-table-convert-refs-to-rc (match-string 1))))
   5020 	    (org-table-add-rectangle-overlay
   5021 	     (match-beginning 1) (match-end 1) face2))))
   5022       (if (and (markerp pos) (marker-buffer pos))
   5023 	  (if (get-buffer-window (marker-buffer pos))
   5024 	      (select-window (get-buffer-window (marker-buffer pos)))
   5025 	    (switch-to-buffer-other-window (get-buffer-window
   5026 					    (marker-buffer pos)))))
   5027       (goto-char pos)
   5028       (org-table--force-dataline)
   5029       (let ((table-start
   5030 	     (if local org-table-current-begin-pos (org-table-begin))))
   5031 	(when dest
   5032 	  (setq name (substring dest 1))
   5033 	  (cond
   5034 	   ((string-match-p "\\`\\$[a-zA-Z][a-zA-Z0-9]*" dest)
   5035 	    (org-table-goto-field dest))
   5036 	   ((string-match-p "\\`@\\([1-9][0-9]*\\)\\$\\([1-9][0-9]*\\)\\'"
   5037 			    dest)
   5038 	    (org-table-goto-field dest))
   5039 	   (t (org-table-goto-column (string-to-number name))))
   5040 	  (move-marker pos (point))
   5041 	  (org-table-highlight-rectangle nil nil face2))
   5042 	(cond
   5043 	 ((equal dest match))
   5044 	 ((not match))
   5045 	 ((eq what 'range)
   5046 	  (ignore-errors (org-table-get-range match table-start nil 'highlight)))
   5047 	 ((setq e (assoc var org-table-named-field-locations))
   5048 	  (org-table-goto-field var)
   5049 	  (org-table-highlight-rectangle)
   5050 	  (message "Named field, column %d of line %d" (nth 2 e) (nth 1 e)))
   5051 	 ((setq e (assoc var org-table-column-names))
   5052 	  (org-table-goto-column (string-to-number (cdr e)))
   5053 	  (org-table-highlight-rectangle)
   5054 	  (goto-char table-start)
   5055 	  (if (re-search-forward (concat "^[ \t]*| *! *.*?| *\\(" var "\\) *|")
   5056 				 (org-table-end) t)
   5057 	      (progn
   5058 		(goto-char (match-beginning 1))
   5059 		(org-table-highlight-rectangle)
   5060 		(message "Named column (column %s)" (cdr e)))
   5061 	    (user-error "Column name not found")))
   5062 	 ((eq what 'column)
   5063 	  ;; Column number.
   5064 	  (org-table-goto-column (string-to-number (substring match 1)))
   5065 	  (org-table-highlight-rectangle)
   5066 	  (message "Column %s" (substring match 1)))
   5067 	 ((setq e (assoc var org-table-local-parameters))
   5068 	  (goto-char table-start)
   5069 	  (if (re-search-forward (concat "^[ \t]*| *\\$ *.*?| *\\(" var "=\\)") nil t)
   5070 	      (progn
   5071 		(goto-char (match-beginning 1))
   5072 		(org-table-highlight-rectangle)
   5073 		(message "Local parameter."))
   5074 	    (user-error "Parameter not found")))
   5075 	 ((not var) (user-error "No reference at point"))
   5076 	 ((setq e (assoc var org-table-formula-constants-local))
   5077 	  (message "Local Constant: $%s=%s in #+CONSTANTS line."
   5078 		   var (cdr e)))
   5079 	 ((setq e (assoc var org-table-formula-constants))
   5080 	  (message "Constant: $%s=%s in `org-table-formula-constants'."
   5081 		   var (cdr e)))
   5082 	 ((setq e (and (fboundp 'constants-get) (constants-get var)))
   5083 	  (message "Constant: $%s=%s, from `constants.el'%s."
   5084 		   var e (format " (%s units)" constants-unit-system)))
   5085 	 (t (user-error "Undefined name $%s" var)))
   5086 	(goto-char pos)
   5087 	(when (and org-show-positions
   5088 		   (not (memq this-command '(org-table-fedit-scroll
   5089 					     org-table-fedit-scroll-down))))
   5090 	  (push pos org-show-positions)
   5091 	  (push table-start org-show-positions)
   5092 	  (let ((min (apply 'min org-show-positions))
   5093 		(max (apply 'max org-show-positions)))
   5094 	    (set-window-start (selected-window) min)
   5095 	    (goto-char max)
   5096 	    (or (pos-visible-in-window-p max)
   5097 		(set-window-start (selected-window) max)))))
   5098       (select-window win))))
   5099 
   5100 
   5101 ;;; The Orgtbl minor mode
   5102 
   5103 ;; Define a minor mode which can be used in other modes in order to
   5104 ;; integrate the Org table editor.
   5105 
   5106 ;; This is really a hack, because the Org table editor uses several
   5107 ;; keys which normally belong to the major mode, for example the TAB
   5108 ;; and RET keys.  Here is how it works: The minor mode defines all the
   5109 ;; keys necessary to operate the table editor, but wraps the commands
   5110 ;; into a function which tests if the cursor is currently inside
   5111 ;; a table.  If that is the case, the table editor command is
   5112 ;; executed.  However, when any of those keys is used outside a table,
   5113 ;; the function uses `key-binding' to look up if the key has an
   5114 ;; associated command in another currently active keymap (minor modes,
   5115 ;; major mode, global), and executes that command.  There might be
   5116 ;; problems if any of the keys used by the table editor is otherwise
   5117 ;; used as a prefix key.
   5118 
   5119 ;; Another challenge is that the key binding for TAB can be tab or \C-i,
   5120 ;; likewise the binding for RET can be return or \C-m.  Orgtbl-mode
   5121 ;; addresses this by checking explicitly for both bindings.
   5122 
   5123 ;; The optimized version (see variable `orgtbl-optimized') takes over
   5124 ;; all keys which are bound to `self-insert-command' in the *global map*.
   5125 ;; Some modes bind other commands to simple characters, for example
   5126 ;; AUCTeX binds the double quote to `Tex-insert-quote'.  With orgtbl-mode
   5127 ;; active, this binding is ignored inside tables and replaced with a
   5128 ;; modified self-insert.
   5129 
   5130 (defvar orgtbl-mode-map (make-keymap)
   5131   "Keymap for `orgtbl-mode'.")
   5132 
   5133 (defvar org-old-auto-fill-inhibit-regexp nil
   5134   "Local variable used by `orgtbl-mode'.")
   5135 
   5136 (defconst orgtbl-line-start-regexp
   5137   "[ \t]*\\(|\\|#\\+\\(tblfm\\|orgtbl\\|tblname\\):\\)"
   5138   "Matches a line belonging to an orgtbl.")
   5139 
   5140 (defconst orgtbl-extra-font-lock-keywords
   5141   (list (list (concat "^" orgtbl-line-start-regexp ".*")
   5142 	      0 (quote 'org-table) 'prepend))
   5143   "Extra `font-lock-keywords' to be added when `orgtbl-mode' is active.")
   5144 
   5145 ;;;###autoload
   5146 (defun turn-on-orgtbl ()
   5147   "Unconditionally turn on `orgtbl-mode'."
   5148   (require 'org-table)
   5149   (orgtbl-mode 1))
   5150 
   5151 ;; Install it as a minor mode.
   5152 (put 'orgtbl-mode :included t)
   5153 (put 'orgtbl-mode :menu-tag "Org Table Mode")
   5154 
   5155 (easy-menu-define orgtbl-mode-menu orgtbl-mode-map "OrgTbl menu."
   5156   '("OrgTbl"
   5157     ["Create or convert" org-table-create-or-convert-from-region
   5158      :active (not (org-at-table-p)) :keys "C-c |" ]
   5159     "--"
   5160     ["Align" org-ctrl-c-ctrl-c :active (org-at-table-p) :keys "C-c C-c"]
   5161     ["Next Field" org-cycle :active (org-at-table-p) :keys "TAB"]
   5162     ["Previous Field" org-shifttab :active (org-at-table-p) :keys "S-TAB"]
   5163     ["Next Row" org-return :active (org-at-table-p) :keys "RET"]
   5164     "--"
   5165     ["Blank Field" org-table-blank-field :active (org-at-table-p) :keys "C-c SPC"]
   5166     ["Edit Field" org-table-edit-field :active (org-at-table-p) :keys "C-c ` "]
   5167     ["Copy Field from Above"
   5168      org-table-copy-down :active (org-at-table-p) :keys "S-RET"]
   5169     "--"
   5170     ("Column"
   5171      ["Move Column Left" org-metaleft :active (org-at-table-p) :keys "M-<left>"]
   5172      ["Move Column Right" org-metaright :active (org-at-table-p) :keys "M-<right>"]
   5173      ["Delete Column" org-shiftmetaleft :active (org-at-table-p) :keys "M-S-<left>"]
   5174      ["Insert Column" org-shiftmetaright :active (org-at-table-p) :keys "M-S-<right>"])
   5175     ("Row"
   5176      ["Move Row Up" org-metaup :active (org-at-table-p) :keys "M-<up>"]
   5177      ["Move Row Down" org-metadown :active (org-at-table-p) :keys "M-<down>"]
   5178      ["Delete Row" org-shiftmetaup :active (org-at-table-p) :keys "M-S-<up>"]
   5179      ["Insert Row" org-shiftmetadown :active (org-at-table-p) :keys "M-S-<down>"]
   5180      ["Sort lines in region" org-table-sort-lines :active (org-at-table-p) :keys "C-c ^"]
   5181      "--"
   5182      ["Insert Hline" org-table-insert-hline :active (org-at-table-p) :keys "C-c -"])
   5183     ("Rectangle"
   5184      ["Copy Rectangle" org-copy-special :active (org-at-table-p)]
   5185      ["Cut Rectangle" org-cut-special :active (org-at-table-p)]
   5186      ["Paste Rectangle" org-paste-special :active (org-at-table-p)]
   5187      ["Fill Rectangle" org-table-wrap-region :active (org-at-table-p)])
   5188     "--"
   5189     ("Radio tables"
   5190      ["Insert table template" orgtbl-insert-radio-table
   5191       (cl-assoc-if #'derived-mode-p orgtbl-radio-table-templates)]
   5192      ["Comment/uncomment table" orgtbl-toggle-comment t])
   5193     "--"
   5194     ["Set Column Formula" org-table-eval-formula :active (org-at-table-p) :keys "C-c ="]
   5195     ["Set Field Formula" (org-table-eval-formula '(4)) :active (org-at-table-p) :keys "C-u C-c ="]
   5196     ["Edit Formulas" org-table-edit-formulas :active (org-at-table-p) :keys "C-c '"]
   5197     ["Recalculate line" org-table-recalculate :active (org-at-table-p) :keys "C-c *"]
   5198     ["Recalculate all" (org-table-recalculate '(4)) :active (org-at-table-p) :keys "C-u C-c *"]
   5199     ["Iterate all" (org-table-recalculate '(16)) :active (org-at-table-p) :keys "C-u C-u C-c *"]
   5200     ["Toggle Recalculate Mark" org-table-rotate-recalc-marks :active (org-at-table-p) :keys "C-c #"]
   5201     ["Sum Column/Rectangle" org-table-sum
   5202      :active (or (org-at-table-p) (org-region-active-p)) :keys "C-c +"]
   5203     ["Which Column?" org-table-current-column :active (org-at-table-p) :keys "C-c ?"]
   5204     ["Debug Formulas"
   5205      org-table-toggle-formula-debugger :active (org-at-table-p)
   5206      :keys "C-c {"
   5207      :style toggle :selected org-table-formula-debug]
   5208     ["Show Col/Row Numbers"
   5209      org-table-toggle-coordinate-overlays :active (org-at-table-p)
   5210      :keys "C-c }"
   5211      :style toggle :selected org-table-overlay-coordinates]
   5212     "--"
   5213     ("Plot"
   5214      ["Ascii plot" orgtbl-ascii-plot :active (org-at-table-p) :keys "C-c \" a"]
   5215      ["Gnuplot" org-plot/gnuplot :active (org-at-table-p) :keys "C-c \" g"])))
   5216 
   5217 ;;;###autoload
   5218 (define-minor-mode orgtbl-mode
   5219   "The Org mode table editor as a minor mode for use in other modes."
   5220   :lighter " OrgTbl"
   5221   (org-load-modules-maybe)
   5222   (cond
   5223    ((derived-mode-p 'org-mode)
   5224     ;; Exit without error, in case some hook functions calls this by
   5225     ;; accident in Org mode.
   5226     (message "Orgtbl mode is not useful in Org mode, command ignored"))
   5227    (orgtbl-mode
   5228     (orgtbl-setup)
   5229     ;; Make sure we are first in minor-mode-map-alist
   5230     (let ((c (assq 'orgtbl-mode minor-mode-map-alist)))
   5231       ;; FIXME: maybe it should use emulation-mode-map-alists?
   5232       (and c (setq minor-mode-map-alist
   5233                    (cons c (delq c minor-mode-map-alist)))))
   5234     (setq-local org-table-may-need-update t)
   5235     (add-hook 'before-change-functions 'org-before-change-function
   5236 	      nil 'local)
   5237     (setq-local org-old-auto-fill-inhibit-regexp
   5238 		auto-fill-inhibit-regexp)
   5239     (setq-local auto-fill-inhibit-regexp
   5240 		(if auto-fill-inhibit-regexp
   5241 		    (concat orgtbl-line-start-regexp "\\|"
   5242 			    auto-fill-inhibit-regexp)
   5243 		  orgtbl-line-start-regexp))
   5244     (font-lock-add-keywords nil orgtbl-extra-font-lock-keywords)
   5245     (org-restart-font-lock))
   5246    (t
   5247     (setq auto-fill-inhibit-regexp org-old-auto-fill-inhibit-regexp)
   5248     (remove-hook 'before-change-functions 'org-before-change-function t)
   5249     (font-lock-remove-keywords nil orgtbl-extra-font-lock-keywords)
   5250     (org-restart-font-lock)
   5251     (force-mode-line-update 'all))))
   5252 
   5253 (defun orgtbl-make-binding (fun n &rest keys)
   5254   "Create a function for binding in the table minor mode.
   5255 FUN is the command to call inside a table.  N is used to create a unique
   5256 command name.  KEYS are keys that should be checked in for a command
   5257 to execute outside of tables."
   5258   (eval
   5259    (list 'defun
   5260 	 (intern (concat "orgtbl-hijacker-command-" (number-to-string n)))
   5261 	 '(arg)
   5262 	 (concat "In tables, run `" (symbol-name fun) "'.\n"
   5263 		 "Outside of tables, run the binding of `"
   5264 		 (mapconcat #'key-description keys "' or `")
   5265 		 "'.")
   5266 	 '(interactive "p")
   5267 	 (list 'if
   5268 	       '(org-at-table-p)
   5269 	       (list 'call-interactively (list 'quote fun))
   5270 	       (list 'let '(orgtbl-mode)
   5271 		     (list 'call-interactively
   5272 			   (append '(or)
   5273 				   (mapcar (lambda (k)
   5274 					     (list 'key-binding k))
   5275 					   keys)
   5276 				   '('orgtbl-error))))))))
   5277 
   5278 (defun orgtbl-error ()
   5279   "Error when there is no default binding for a table key."
   5280   (interactive)
   5281   (user-error "This key has no function outside tables"))
   5282 
   5283 ;; Fill in orgtbl keymap.
   5284 (let ((nfunc 0)
   5285       (bindings
   5286        '(([(meta shift left)]  org-table-delete-column)
   5287 	 ([(meta left)]	 org-table-move-column-left)
   5288 	 ([(meta right)]       org-table-move-column-right)
   5289 	 ([(meta shift right)] org-table-insert-column)
   5290 	 ([(meta shift up)]    org-table-kill-row)
   5291 	 ([(meta shift down)]  org-table-insert-row)
   5292 	 ([(meta up)]		 org-table-move-row-up)
   5293 	 ([(meta down)]	 org-table-move-row-down)
   5294 	 ("\C-c\C-w"		 org-table-cut-region)
   5295 	 ("\C-c\M-w"		 org-table-copy-region)
   5296 	 ("\C-c\C-y"		 org-table-paste-rectangle)
   5297 	 ("\C-c\C-w"           org-table-wrap-region)
   5298 	 ("\C-c-"		 org-table-insert-hline)
   5299 	 ("\C-c}"		 org-table-toggle-coordinate-overlays)
   5300 	 ("\C-c{"		 org-table-toggle-formula-debugger)
   5301 	 ("\C-m"		 org-table-next-row)
   5302 	 ([(shift return)]	 org-table-copy-down)
   5303 	 ("\C-c?"		 org-table-field-info)
   5304 	 ("\C-c "		 org-table-blank-field)
   5305 	 ("\C-c+"		 org-table-sum)
   5306 	 ("\C-c="		 org-table-eval-formula)
   5307 	 ("\C-c'"		 org-table-edit-formulas)
   5308 	 ("\C-c`"		 org-table-edit-field)
   5309 	 ("\C-c*"		 org-table-recalculate)
   5310 	 ("\C-c^"		 org-table-sort-lines)
   5311 	 ("\M-a"		 org-table-beginning-of-field)
   5312 	 ("\M-e"		 org-table-end-of-field)
   5313 	 ([(control ?#)]       org-table-rotate-recalc-marks)))
   5314       elt key fun cmd)
   5315   (while (setq elt (pop bindings))
   5316     (setq nfunc (1+ nfunc))
   5317     (setq key (org-key (car elt))
   5318 	  fun (nth 1 elt)
   5319 	  cmd (orgtbl-make-binding fun nfunc key))
   5320     (org-defkey orgtbl-mode-map key cmd))
   5321 
   5322   ;; Special treatment needed for TAB, RET and DEL
   5323   (org-defkey orgtbl-mode-map [(return)]
   5324 	      (orgtbl-make-binding 'orgtbl-ret 100 [(return)] "\C-m"))
   5325   (org-defkey orgtbl-mode-map "\C-m"
   5326 	      (orgtbl-make-binding 'orgtbl-ret 101 "\C-m" [(return)]))
   5327   (org-defkey orgtbl-mode-map [(tab)]
   5328 	      (orgtbl-make-binding 'orgtbl-tab 102 [(tab)] "\C-i"))
   5329   (org-defkey orgtbl-mode-map "\C-i"
   5330 	      (orgtbl-make-binding 'orgtbl-tab 103 "\C-i" [(tab)]))
   5331   (org-defkey orgtbl-mode-map [(shift tab)]
   5332 	      (orgtbl-make-binding 'org-table-previous-field 104
   5333 				   [(shift tab)] [(tab)] "\C-i"))
   5334   (org-defkey orgtbl-mode-map [backspace]
   5335 	      (orgtbl-make-binding 'org-delete-backward-char 109
   5336 				   [backspace] (kbd "DEL")))
   5337 
   5338   (org-defkey orgtbl-mode-map [S-iso-lefttab]
   5339 	      (orgtbl-make-binding 'org-table-previous-field 107
   5340 				   [S-iso-lefttab] [backtab] [(shift tab)]
   5341 				   [(tab)] "\C-i"))
   5342 
   5343   (org-defkey orgtbl-mode-map [backtab]
   5344 	      (orgtbl-make-binding 'org-table-previous-field 108
   5345 				   [backtab] [S-iso-lefttab] [(shift tab)]
   5346 				   [(tab)] "\C-i"))
   5347 
   5348   (org-defkey orgtbl-mode-map "\M-\C-m"
   5349 	      (orgtbl-make-binding 'org-table-wrap-region 105
   5350 				   "\M-\C-m" [(meta return)]))
   5351   (org-defkey orgtbl-mode-map [(meta return)]
   5352 	      (orgtbl-make-binding 'org-table-wrap-region 106
   5353 				   [(meta return)] "\M-\C-m"))
   5354 
   5355   (org-defkey orgtbl-mode-map "\C-c\C-c" 'orgtbl-ctrl-c-ctrl-c)
   5356   (org-defkey orgtbl-mode-map "\C-c|" 'orgtbl-create-or-convert-from-region))
   5357 
   5358 (defun orgtbl-setup ()
   5359   "Setup orgtbl keymaps."
   5360   ;; If the user wants maximum table support, we need to hijack
   5361   ;; some standard editing functions
   5362   (org-remap orgtbl-mode-map
   5363 	     'self-insert-command (and orgtbl-optimized 'orgtbl-self-insert-command)
   5364 	     'delete-char (and orgtbl-optimized 'org-delete-char)
   5365              'delete-forward-char (and orgtbl-optimized 'org-delete-char)
   5366 	     'delete-backward-char (and orgtbl-optimized 'org-delete-backward-char))
   5367   (org-defkey orgtbl-mode-map "|" (and orgtbl-optimized 'org-force-self-insert)))
   5368 
   5369 (defun orgtbl-ctrl-c-ctrl-c (arg)
   5370   "If the cursor is inside a table, realign the table.
   5371 If it is a table to be sent away to a receiver, do it.
   5372 With prefix arg, also recompute table."
   5373   (interactive "P")
   5374   (let ((case-fold-search t) (pos (point)) action)
   5375     (save-excursion
   5376       (forward-line 0)
   5377       (setq action (cond
   5378 		    ((looking-at "[ \t]*#\\+ORGTBL:.*\n[ \t]*|") (match-end 0))
   5379 		    ((looking-at "[ \t]*|") pos)
   5380 		    ((looking-at "[ \t]*#\\+tblfm:") 'recalc))))
   5381     (cond
   5382      ((integerp action)
   5383       (goto-char action)
   5384       (org-table-maybe-eval-formula)
   5385       (if arg
   5386 	  (call-interactively 'org-table-recalculate)
   5387 	(org-table-maybe-recalculate-line))
   5388       (call-interactively 'org-table-align)
   5389       (when (orgtbl-send-table 'maybe)
   5390 	(run-hooks 'orgtbl-after-send-table-hook)))
   5391      ((eq action 'recalc)
   5392       (save-excursion
   5393 	(forward-line 0)
   5394 	(skip-chars-backward " \r\n\t")
   5395 	(if (org-at-table-p)
   5396 	    (org-call-with-arg 'org-table-recalculate t))))
   5397      (t (let (orgtbl-mode)
   5398 	  (call-interactively (key-binding "\C-c\C-c")))))))
   5399 
   5400 (defun orgtbl-create-or-convert-from-region (_arg)
   5401   "Create table or convert region to table, if no conflicting binding.
   5402 This installs the table binding `C-c |', but only if there is no
   5403 conflicting binding to this key outside `orgtbl-mode'."
   5404   (interactive "P")
   5405   (let* (orgtbl-mode (cmd (key-binding "\C-c|")))
   5406     (if cmd
   5407 	(call-interactively cmd)
   5408       (call-interactively 'org-table-create-or-convert-from-region))))
   5409 
   5410 (defun orgtbl-tab (arg)
   5411   "Justification and field motion for `orgtbl-mode'."
   5412   (interactive "P")
   5413   (if arg (org-table-edit-field t)
   5414     (org-table-justify-field-maybe)
   5415     (org-table-next-field)))
   5416 
   5417 (defun orgtbl-ret ()
   5418   "Justification and field motion for `orgtbl-mode'."
   5419   (interactive)
   5420   (if (bobp)
   5421       (newline)
   5422     (org-table-justify-field-maybe)
   5423     (org-table-next-row)))
   5424 
   5425 (defun orgtbl-self-insert-command (N)
   5426   "Like `self-insert-command', use `overwrite-mode' for whitespace in tables.
   5427 If the cursor is in a table looking at whitespace, the whitespace is
   5428 overwritten, and the table is not marked as requiring realignment."
   5429   (interactive "p")
   5430   (if (and (org-at-table-p)
   5431 	   (or
   5432 	    (and org-table-auto-blank-field
   5433 		 (member last-command
   5434 			 '(orgtbl-hijacker-command-100
   5435 			   orgtbl-hijacker-command-101
   5436 			   orgtbl-hijacker-command-102
   5437 			   orgtbl-hijacker-command-103
   5438 			   orgtbl-hijacker-command-104
   5439 			   orgtbl-hijacker-command-105
   5440 			   yas/expand))
   5441 		 (org-table-blank-field))
   5442 	    t)
   5443 	   (eq N 1)
   5444 	   (looking-at "[^|\n]* \\( \\)|"))
   5445       (let (org-table-may-need-update)
   5446 	(delete-region (match-beginning 1) (match-end 1))
   5447 	(self-insert-command N))
   5448     (setq org-table-may-need-update t)
   5449     (let* (orgtbl-mode
   5450 	   (cmd (or (key-binding
   5451 		     (or (and (listp function-key-map)
   5452 			      (cdr (assoc last-command-event function-key-map)))
   5453 			 (vector last-command-event)))
   5454 		    'self-insert-command)))
   5455       (call-interactively cmd)
   5456       (if (and org-self-insert-cluster-for-undo
   5457 	       (eq cmd 'self-insert-command))
   5458 	  (if (not (eq last-command 'orgtbl-self-insert-command))
   5459 	      (setq org-self-insert-command-undo-counter 1)
   5460 	    (if (>= org-self-insert-command-undo-counter 20)
   5461 		(setq org-self-insert-command-undo-counter 1)
   5462 	      (and (> org-self-insert-command-undo-counter 0)
   5463 		   buffer-undo-list
   5464 		   (not (cadr buffer-undo-list)) ; remove nil entry
   5465 		   (setcdr buffer-undo-list (cddr buffer-undo-list)))
   5466 	      (setq org-self-insert-command-undo-counter
   5467 		    (1+ org-self-insert-command-undo-counter))))))))
   5468 
   5469 ;;;###autoload
   5470 (defvar orgtbl-exp-regexp "^\\([-+]?[0-9][0-9.]*\\)[eE]\\([-+]?[0-9]+\\)$"
   5471   "Regular expression matching exponentials as produced by calc.")
   5472 
   5473 (defun orgtbl-gather-send-defs ()
   5474   "Gather a plist of :name, :transform, :params for each destination before
   5475 a radio table."
   5476   (save-excursion
   5477     (goto-char (org-table-begin))
   5478     (let (rtn)
   5479       (forward-line -1)
   5480       (catch :bob
   5481         (while (looking-at "[ \t]*#\\+ORGTBL[: \t][ \t]*SEND[ \t]+\\([^ \t\r\n]+\\)[ \t]+\\([^ \t\r\n]+\\)\\([ \t]+.*\\)?")
   5482 	  (let ((name (org-no-properties (match-string 1)))
   5483 	        (transform (intern (match-string 2)))
   5484 	        (params (if (match-end 3)
   5485 			    (read (concat "(" (match-string 3) ")")))))
   5486 	    (push (list :name name :transform transform :params params)
   5487 		  rtn)
   5488             (when (bobp) (throw :bob nil))
   5489 	    (forward-line -1))))
   5490       rtn)))
   5491 
   5492 (defun orgtbl-send-replace-tbl (name text)
   5493   "Find and replace table NAME with TEXT."
   5494   (save-excursion
   5495     (goto-char (point-min))
   5496     (let* ((location-flag nil)
   5497 	   (name (regexp-quote name))
   5498 	   (begin-re (format "BEGIN +RECEIVE +ORGTBL +%s\\([ \t]\\|$\\)" name))
   5499 	   (end-re (format "END +RECEIVE +ORGTBL +%s\\([ \t]\\|$\\)" name)))
   5500       (while (re-search-forward begin-re nil t)
   5501 	(unless location-flag (setq location-flag t))
   5502 	(let ((beg (line-beginning-position 2)))
   5503 	  (unless (re-search-forward end-re nil t)
   5504 	    (user-error "Cannot find end of receiver location at %d" beg))
   5505 	  (forward-line 0)
   5506 	  (delete-region beg (point))
   5507 	  (insert text "\n")))
   5508       (unless location-flag
   5509 	(user-error "No valid receiver location found in the buffer")))))
   5510 
   5511 ;;;###autoload
   5512 (defun org-table-to-lisp (&optional txt)
   5513   "Convert the table at point to a Lisp structure.
   5514 
   5515 The structure will be a list.  Each item is either the symbol `hline'
   5516 for a horizontal separator line, or a list of field values as strings.
   5517 The table is taken from the parameter TXT, or from the buffer at point."
   5518   (if txt
   5519       (with-temp-buffer
   5520 	(buffer-disable-undo)
   5521         (insert txt)
   5522         (goto-char (point-min))
   5523         (org-table-to-lisp))
   5524     (save-excursion
   5525       (goto-char (org-table-begin))
   5526       (let (table)
   5527         (while (progn (skip-chars-forward " \t")
   5528                       (eq (following-char) ?|))
   5529 	  (forward-char)
   5530 	  (push
   5531 	   (if (eq (following-char) ?-)
   5532 	       'hline
   5533 	     (let (row)
   5534 	       (while (progn
   5535                         (skip-chars-forward " \t")
   5536                         (not (eolp)))
   5537                  (let ((q (point)))
   5538                    (skip-chars-forward "^|\n")
   5539                    (goto-char
   5540                     (prog1
   5541                         (let ((p (point)))
   5542                           (unless (eolp) (setq p (1+ p)))
   5543                           p)
   5544 	              (skip-chars-backward " \t" q)
   5545                       ;; Preserve text properties.  They are used when
   5546                       ;; calculating cell width.
   5547 	              (push (buffer-substring q (point)) row)))))
   5548 	       (nreverse row)))
   5549 	   table)
   5550 	  (forward-line))
   5551 	(nreverse table)))))
   5552 
   5553 (defun org-table-collapse-header (table &optional separator max-header-lines)
   5554   "Collapse the lines before `hline' into a single header.
   5555 
   5556 The given TABLE is a list of lists as returned by `org-table-to-lisp'.
   5557 The leading lines before the first `hline' symbol are considered
   5558 forming the table header.  This function collapses all leading header
   5559 lines into a single header line, followed by the `hline' symbol, and
   5560 the rest of the TABLE.  Header cells are glued together with a space,
   5561 or the given SEPARATOR."
   5562   (while (eq (car table) 'hline) (pop table))
   5563   (let* ((separator (or separator " "))
   5564 	 (max-header-lines (or max-header-lines 4))
   5565 	 (trailer table)
   5566 	 (header-lines (cl-loop for line in table
   5567 				until (eq 'hline line)
   5568 				collect (pop trailer))))
   5569     (if (and trailer (<= (length header-lines) max-header-lines))
   5570 	(cons (apply #'cl-mapcar
   5571 		     (lambda (&rest x)
   5572 		       (org-trim
   5573 			(mapconcat #'identity x separator)))
   5574 		     header-lines)
   5575 	      trailer)
   5576       table)))
   5577 
   5578 (defun orgtbl-send-table (&optional maybe)
   5579   "Send a transformed version of table at point to the receiver position.
   5580 With argument MAYBE, fail quietly if no transformation is defined
   5581 for this table."
   5582   (interactive)
   5583   (catch 'exit
   5584     (unless (org-at-table-p) (user-error "Not at a table"))
   5585     ;; when non-interactive, we assume align has just happened.
   5586     (when (called-interactively-p 'any) (org-table-align))
   5587     (let ((dests (orgtbl-gather-send-defs))
   5588 	  (table (org-table-to-lisp))
   5589 	  (ntbl 0))
   5590       (unless dests
   5591 	(if maybe (throw 'exit nil)
   5592 	  (user-error "Don't know how to transform this table")))
   5593       (dolist (dest dests)
   5594 	(let ((name (plist-get dest :name))
   5595 	      (transform (plist-get dest :transform))
   5596 	      (params (plist-get dest :params)))
   5597 	  (unless (fboundp transform)
   5598 	    (user-error "No such transformation function %s" transform))
   5599 	  (orgtbl-send-replace-tbl name (funcall transform table params)))
   5600 	(cl-incf ntbl))
   5601       (message "Table converted and installed at %d receiver location%s"
   5602 	       ntbl (if (> ntbl 1) "s" ""))
   5603       (and (> ntbl 0) ntbl))))
   5604 
   5605 (defun org-remove-by-index (list indices &optional i0)
   5606   "Remove the elements in LIST with indices in INDICES.
   5607 First element has index 0, or I0 if given."
   5608   (if (not indices)
   5609       list
   5610     (if (integerp indices) (setq indices (list indices)))
   5611     (setq i0 (1- (or i0 0)))
   5612     (delq :rm (mapcar (lambda (x)
   5613 			(setq i0 (1+ i0))
   5614 			(if (memq i0 indices) :rm x))
   5615 		      list))))
   5616 
   5617 (defun orgtbl-toggle-comment ()
   5618   "Comment or uncomment the orgtbl at point."
   5619   (interactive)
   5620   (let* ((case-fold-search t)
   5621 	 (re1 (concat "^" (regexp-quote comment-start) orgtbl-line-start-regexp))
   5622 	 (re2 (concat "^" orgtbl-line-start-regexp))
   5623 	 (commented (save-excursion (forward-line 0)
   5624 				    (cond ((looking-at re1) t)
   5625 					  ((looking-at re2) nil)
   5626 					  (t (user-error "Not at an org table")))))
   5627 	 (re (if commented re1 re2))
   5628 	 beg end)
   5629     (save-excursion
   5630       (forward-line 0)
   5631       (while (and (not (eq (point) (point-min)))
   5632                   (looking-at re))
   5633         (forward-line -1))
   5634       (unless (eq (point) (point-min)) (forward-line 1))
   5635       (setq beg (point))
   5636       (while (and (not (eq (point) (point-max)))
   5637                   (looking-at re))
   5638         (forward-line 1))
   5639       (setq end (point)))
   5640     (comment-region beg end (if commented '(4) nil))))
   5641 
   5642 (defun orgtbl-insert-radio-table ()
   5643   "Insert a radio table template appropriate for this major mode."
   5644   (interactive)
   5645   (let* ((e (cl-assoc-if #'derived-mode-p orgtbl-radio-table-templates))
   5646 	 (txt (nth 1 e))
   5647 	 name pos)
   5648     (unless e (user-error "No radio table setup defined for %s" major-mode))
   5649     (setq name (read-string "Table name: "))
   5650     (while (string-match "%n" txt)
   5651       (setq txt (replace-match name t t txt)))
   5652     (or (bolp) (insert "\n"))
   5653     (setq pos (point))
   5654     (insert txt)
   5655     (goto-char pos)))
   5656 
   5657 ;;;###autoload
   5658 (defun orgtbl-to-generic (table params)
   5659   "Convert the `orgtbl-mode' TABLE to some other format.
   5660 
   5661 This generic routine can be used for many standard cases.
   5662 
   5663 TABLE is a list, each entry either the symbol `hline' for
   5664 a horizontal separator line, or a list of fields for that
   5665 line.  PARAMS is a property list of parameters that can
   5666 influence the conversion.
   5667 
   5668 Valid parameters are:
   5669 
   5670 :backend, :raw
   5671 
   5672   Export backend used as a basis to transcode elements of the
   5673   table, when no specific parameter applies to it.  It is also
   5674   used to translate cells contents.  You can prevent this by
   5675   setting :raw property to a non-nil value.
   5676 
   5677 :splice
   5678 
   5679   When non-nil, only convert rows, not the table itself.  This is
   5680   equivalent to setting to the empty string both :tstart
   5681   and :tend, which see.
   5682 
   5683 :skip
   5684 
   5685   When set to an integer N, skip the first N lines of the table.
   5686   Horizontal separation lines do count for this parameter!
   5687 
   5688 :skipcols
   5689 
   5690   List of columns that should be skipped.  If the table has
   5691   a column with calculation marks, that column is automatically
   5692   discarded beforehand.
   5693 
   5694 :hline
   5695 
   5696   String to be inserted on horizontal separation lines.  May be
   5697   nil to ignore these lines altogether.
   5698 
   5699 :sep
   5700 
   5701   Separator between two fields, as a string.
   5702 
   5703 Each in the following group may be either a string or a function
   5704 of no arguments returning a string:
   5705 
   5706 :tstart, :tend
   5707 
   5708   Strings to start and end the table.  Ignored when :splice is t.
   5709 
   5710 :lstart, :lend
   5711 
   5712   Strings to start and end a new table line.
   5713 
   5714 :llstart, :llend
   5715 
   5716   Strings to start and end the last table line.  Default,
   5717   respectively, to :lstart and :lend.
   5718 
   5719 Each in the following group may be a string or a function of one
   5720 argument (either the cells in the current row, as a list of
   5721 strings, or the current cell) returning a string:
   5722 
   5723 :lfmt
   5724 
   5725   Format string for an entire row, with enough %s to capture all
   5726   fields.  When non-nil, :lstart, :lend, and :sep are ignored.
   5727 
   5728 :llfmt
   5729 
   5730   Format for the entire last line, defaults to :lfmt.
   5731 
   5732 :fmt
   5733 
   5734   A format to be used to wrap the field, should contain %s for
   5735   the original field value.  For example, to wrap everything in
   5736   dollars, you could use :fmt \"$%s$\".  This may also be
   5737   a property list with column numbers and format strings, or
   5738   functions, e.g.,
   5739 
   5740     (:fmt (2 \"$%s$\" 4 (lambda (c) (format \"$%s$\" c))))
   5741 
   5742   The format is ignored for empty fields.  Use :raw t with non-nil
   5743   :backend option to force formatting empty fields.
   5744 
   5745 :hlstart :hllstart :hlend :hllend :hsep :hlfmt :hllfmt :hfmt
   5746 
   5747  Same as above, specific for the header lines in the table.
   5748  All lines before the first hline are treated as header.  If
   5749  any of these is not present, the data line value is used.
   5750 
   5751 This may be either a string or a function of two arguments:
   5752 
   5753 :efmt
   5754 
   5755   Use this format to print numbers with exponential.  The format
   5756   should have %s twice for inserting mantissa and exponent, for
   5757   example \"%s\\\\times10^{%s}\".  This may also be a property
   5758   list with column numbers and format strings or functions.
   5759   :fmt will still be applied after :efmt."
   5760   ;; Make sure `org-export-create-backend' is available.
   5761   (require 'ox)
   5762   (let* ((backend (plist-get params :backend))
   5763 	 (custom-backend
   5764 	  ;; Build a custom backend according to PARAMS.  Before
   5765 	  ;; defining a translator, check if there is anything to do.
   5766 	  ;; When there isn't, let BACKEND handle the element.
   5767 	  (org-export-create-backend
   5768 	   :parent (or backend 'org)
   5769 	   :transcoders
   5770 	   `((table . ,(org-table--to-generic-table params))
   5771 	     (table-row . ,(org-table--to-generic-row params))
   5772 	     (table-cell . ,(org-table--to-generic-cell params))
   5773 	     ;; Macros are not going to be expanded.  However, no
   5774 	     ;; regular backend has a transcoder for them.  We
   5775 	     ;; provide one so they are not ignored, but displayed
   5776 	     ;; as-is instead.
   5777 	     (macro . (lambda (m c i) (org-element-macro-interpreter m nil))))))
   5778 	 data info)
   5779     ;; Store TABLE as Org syntax in DATA.  Tolerate non-string cells.
   5780     ;; Initialize communication channel in INFO.
   5781     (with-temp-buffer
   5782       (let ((org-inhibit-startup t)) (org-mode))
   5783       (org-fold-core-ignore-modifications
   5784         (let ((standard-output (current-buffer))
   5785 	      (org-element-use-cache nil))
   5786 	  (dolist (e table)
   5787 	    (cond ((eq e 'hline) (princ "|--\n"))
   5788 		  ((consp e)
   5789 		   (princ "| ") (dolist (c e) (princ c) (princ " |"))
   5790 		   (princ "\n")))))
   5791         (org-element-cache-reset)
   5792         ;; Add backend specific filters, but not user-defined ones.  In
   5793         ;; particular, make sure to call parse-tree filters on the
   5794         ;; table.
   5795         (setq info
   5796 	      (let ((org-export-filters-alist nil))
   5797 	        (org-export-install-filters
   5798 	         (org-combine-plists
   5799 		  (org-export-get-environment backend nil params)
   5800 		  `(:back-end ,(org-export-get-backend backend))))))
   5801         (setq data
   5802 	      (org-export-filter-apply-functions
   5803 	       (plist-get info :filter-parse-tree)
   5804 	       (org-element-map (org-element-parse-buffer) 'table
   5805 	         #'identity nil t)
   5806 	       info))
   5807         (when (and backend (symbolp backend) (not (org-export-get-backend backend)))
   5808           (user-error "Unknown :backend value"))))
   5809     (when (or (not backend) (plist-get info :raw)) (require 'ox-org))
   5810     ;; Handle :skip parameter.
   5811     (let ((skip (plist-get info :skip)))
   5812       (when skip
   5813 	(unless (wholenump skip) (user-error "Wrong :skip value"))
   5814 	(let ((n 0))
   5815 	  (org-element-map data 'table-row
   5816 	    (lambda (row)
   5817 	      (if (>= n skip) t
   5818 		(org-element-extract row)
   5819 		(cl-incf n)
   5820 		nil))
   5821 	    nil t))))
   5822     ;; Handle :skipcols parameter.
   5823     (let ((skipcols (plist-get info :skipcols)))
   5824       (when skipcols
   5825 	(unless (consp skipcols) (user-error "Wrong :skipcols value"))
   5826 	(org-element-map data 'table
   5827 	  (lambda (table)
   5828 	    (let ((specialp (org-export-table-has-special-column-p table)))
   5829 	      (dolist (row (org-element-contents table))
   5830 		(when (eq (org-element-property :type row) 'standard)
   5831 		  (let ((c 1))
   5832 		    (dolist (cell (nthcdr (if specialp 1 0)
   5833 					  (org-element-contents row)))
   5834 		      (when (memq c skipcols)
   5835 			(org-element-extract cell))
   5836 		      (cl-incf c))))))))))
   5837     ;; Since we are going to export using a low-level mechanism,
   5838     ;; ignore special column and special rows manually.
   5839     (let ((special? (org-export-table-has-special-column-p data))
   5840 	  ignore)
   5841       (org-element-map data (if special? '(table-cell table-row) 'table-row)
   5842 	(lambda (datum)
   5843 	  (when (if (org-element-type-p datum 'table-row)
   5844 		    (org-export-table-row-is-special-p datum nil)
   5845 		  (org-export-first-sibling-p datum nil))
   5846 	    (push datum ignore))))
   5847       (setq info (plist-put info :ignore-list ignore)))
   5848     ;; We use a low-level mechanism to export DATA so as to skip all
   5849     ;; usual pre-processing and post-processing, i.e., hooks, Babel
   5850     ;; code evaluation, include keywords and macro expansion.  Only
   5851     ;; backend specific filters are retained.
   5852     (let ((output (org-export-data-with-backend data custom-backend info)))
   5853       ;; Remove final newline.
   5854       (if (org-string-nw-p output) (substring-no-properties output 0 -1) ""))))
   5855 
   5856 (defun org-table--generic-apply (value name &optional with-cons &rest args)
   5857   (cond ((null value) nil)
   5858         ((functionp value) `(funcall ',value ,@args))
   5859         ((stringp value)
   5860 	 (cond ((consp (car args)) `(apply #'format ,value ,@args))
   5861 	       (args `(format ,value ,@args))
   5862 	       (t value)))
   5863 	((and with-cons (consp value))
   5864 	 `(let ((val (cadr (memq column ',value))))
   5865 	    (cond ((null val) contents)
   5866 		  ((stringp val) (format val ,@args))
   5867 		  ((functionp val) (funcall val ,@args))
   5868 		  (t (user-error "Wrong %s value" ,name)))))
   5869         (t (user-error "Wrong %s value" name))))
   5870 
   5871 (defun org-table--to-generic-table (params)
   5872   "Return custom table transcoder according to PARAMS.
   5873 PARAMS is a plist.  See `orgtbl-to-generic' for more
   5874 information."
   5875   (let ((backend (plist-get params :backend))
   5876 	(splice (plist-get params :splice))
   5877 	(tstart (plist-get params :tstart))
   5878 	(tend (plist-get params :tend)))
   5879     `(lambda (table contents info)
   5880        (concat
   5881 	,(and tstart (not splice)
   5882 	      `(concat ,(org-table--generic-apply tstart ":tstart") "\n"))
   5883 	,(if (or (not backend) tstart tend splice) 'contents
   5884 	   `(org-export-with-backend ',backend table contents info))
   5885 	,(org-table--generic-apply (and (not splice) tend) ":tend")))))
   5886 
   5887 (defun org-table--to-generic-row (params)
   5888   "Return custom table row transcoder according to PARAMS.
   5889 PARAMS is a plist.  See `orgtbl-to-generic' for more
   5890 information."
   5891   (let* ((backend (plist-get params :backend))
   5892 	 (lstart (plist-get params :lstart))
   5893 	 (llstart (plist-get params :llstart))
   5894 	 (hlstart (plist-get params :hlstart))
   5895 	 (hllstart (plist-get params :hllstart))
   5896 	 (lend (plist-get params :lend))
   5897 	 (llend (plist-get params :llend))
   5898 	 (hlend (plist-get params :hlend))
   5899 	 (hllend (plist-get params :hllend))
   5900 	 (lfmt (plist-get params :lfmt))
   5901 	 (llfmt (plist-get params :llfmt))
   5902 	 (hlfmt (plist-get params :hlfmt))
   5903 	 (hllfmt (plist-get params :hllfmt)))
   5904     `(lambda (row contents info)
   5905        (if (eq (org-element-property :type row) 'rule)
   5906 	   ,(cond
   5907 	     ((plist-member params :hline)
   5908 	      (org-table--generic-apply (plist-get params :hline) ":hline"))
   5909 	     (backend `(org-export-with-backend ',backend row nil info)))
   5910 	 (let ((headerp ,(and (or hlfmt hlstart hlend)
   5911 			      '(org-export-table-row-in-header-p row info)))
   5912 	       (last-header-p
   5913 		,(and (or hllfmt hllstart hllend)
   5914 		      '(org-export-table-row-ends-header-p row info)))
   5915 	       (lastp (not (org-export-get-next-element row info))))
   5916 	   (when contents
   5917 	     ;; Check if we can apply `:lfmt', `:llfmt', `:hlfmt', or
   5918 	     ;; `:hllfmt' to CONTENTS.  Otherwise, fallback on
   5919 	     ;; `:lstart', `:lend' and their relatives.
   5920 	     ,(let ((cells
   5921 		     '(org-element-map row 'table-cell
   5922 			(lambda (cell)
   5923 			  ;; Export all cells, without separators.
   5924 			  ;;
   5925 			  ;; Use `org-export-data-with-backend'
   5926 			  ;; instead of `org-export-data' to eschew
   5927 			  ;; cached values, which
   5928 			  ;; ignore :orgtbl-ignore-sep parameter.
   5929 			  (org-export-data-with-backend
   5930 			   cell
   5931 			   (plist-get info :back-end)
   5932 			   (org-combine-plists info '(:orgtbl-ignore-sep t))))
   5933 			info)))
   5934 		`(cond
   5935 		  ,(and hllfmt
   5936 			`(last-header-p ,(org-table--generic-apply
   5937 					  hllfmt ":hllfmt" nil cells)))
   5938 		  ,(and hlfmt
   5939 			`(headerp ,(org-table--generic-apply
   5940 				    hlfmt ":hlfmt" nil cells)))
   5941 		  ,(and llfmt
   5942 			`(lastp ,(org-table--generic-apply
   5943 				  llfmt ":llfmt" nil cells)))
   5944 		  (t
   5945 		   ,(if lfmt (org-table--generic-apply lfmt ":lfmt" nil cells)
   5946 		      `(concat
   5947 			(cond
   5948 			 ,(and
   5949 			   (or hllstart hllend)
   5950 			   `(last-header-p
   5951 			     (concat
   5952 			      ,(org-table--generic-apply hllstart ":hllstart")
   5953 			      contents
   5954 			      ,(org-table--generic-apply hllend ":hllend"))))
   5955 			 ,(and
   5956 			   (or hlstart hlend)
   5957 			   `(headerp
   5958 			     (concat
   5959 			      ,(org-table--generic-apply hlstart ":hlstart")
   5960 			      contents
   5961 			      ,(org-table--generic-apply hlend ":hlend"))))
   5962 			 ,(and
   5963 			   (or llstart llend)
   5964 			   `(lastp
   5965 			     (concat
   5966 			      ,(org-table--generic-apply llstart ":llstart")
   5967 			      contents
   5968 			      ,(org-table--generic-apply llend ":llend"))))
   5969 			 (t
   5970 			  ,(cond
   5971 			    ((or lstart lend)
   5972 			     `(concat
   5973 			       ,(org-table--generic-apply lstart ":lstart")
   5974 			       contents
   5975 			       ,(org-table--generic-apply lend ":lend")))
   5976 			    (backend
   5977 			     `(org-export-with-backend
   5978 			       ',backend row contents info))
   5979 			    (t 'contents)))))))))))))))
   5980 
   5981 (defun org-table--to-generic-cell (params)
   5982   "Return custom table cell transcoder according to PARAMS.
   5983 PARAMS is a plist.  See `orgtbl-to-generic' for more
   5984 information."
   5985   (let* ((backend (plist-get params :backend))
   5986 	 (efmt (plist-get params :efmt))
   5987 	 (fmt (plist-get params :fmt))
   5988 	 (hfmt (plist-get params :hfmt))
   5989 	 (sep (plist-get params :sep))
   5990 	 (hsep (plist-get params :hsep)))
   5991     `(lambda (cell contents info)
   5992        ;; Make sure that contents are exported as Org data when :raw
   5993        ;; parameter is non-nil.
   5994        ,(when (and backend (plist-get params :raw))
   5995 	  `(setq contents
   5996 		 ;; Since we don't know what are the pseudo object
   5997 		 ;; types defined in backend, we cannot pass them to
   5998 		 ;; `org-element-interpret-data'.  As a consequence,
   5999 		 ;; they will be treated as pseudo elements, and will
   6000 		 ;; have newlines appended instead of spaces.
   6001 		 ;; Therefore, we must make sure :post-blank value is
   6002 		 ;; really turned into spaces.
   6003 		 (replace-regexp-in-string
   6004 		  "\n" " "
   6005 		  (org-trim
   6006 		   (org-element-interpret-data
   6007 		    (org-element-contents cell))))))
   6008 
   6009        (let ((headerp ,(and (or hfmt hsep)
   6010 			    '(org-export-table-row-in-header-p
   6011 			      (org-element-parent-element cell) info)))
   6012 	     (column
   6013 	      ;; Call costly `org-export-table-cell-address' only if
   6014 	      ;; absolutely necessary, i.e., if one
   6015 	      ;; of :fmt :efmt :hfmt has a "plist type" value.
   6016 	      ,(and (cl-some (lambda (v) (integerp (car-safe v)))
   6017 			     (list efmt hfmt fmt))
   6018 		    '(1+ (cdr (org-export-table-cell-address cell info))))))
   6019 	 (when contents
   6020 	   ;; Check if we can apply `:efmt' on CONTENTS.
   6021 	   ,(when efmt
   6022 	      `(when (string-match orgtbl-exp-regexp contents)
   6023 		 (let ((mantissa (match-string 1 contents))
   6024 		       (exponent (match-string 2 contents)))
   6025 		   (setq contents ,(org-table--generic-apply
   6026 				    efmt ":efmt" t 'mantissa 'exponent)))))
   6027 	   ;; Check if we can apply FMT (or HFMT) on CONTENTS.
   6028 	   (cond
   6029 	    ,(and hfmt `(headerp (setq contents ,(org-table--generic-apply
   6030 						  hfmt ":hfmt" t 'contents))))
   6031 	    ,(and fmt `(t (setq contents ,(org-table--generic-apply
   6032 					   fmt ":fmt" t 'contents))))))
   6033 	 ;; If a separator is provided, use it instead of BACKEND's.
   6034 	 ;; Separators are ignored when LFMT (or equivalent) is
   6035 	 ;; provided.
   6036 	 ,(cond
   6037 	   ((or hsep sep)
   6038 	    `(if (or ,(and (not sep) '(not headerp))
   6039 		     (plist-get info :orgtbl-ignore-sep)
   6040 		     (not (org-export-get-next-element cell info)))
   6041 		 ,(if (not backend) 'contents
   6042 		    `(org-export-with-backend ',backend cell contents info))
   6043 	       (concat contents
   6044 		       ,(if (and sep hsep) `(if headerp ,hsep ,sep)
   6045 			  (or hsep sep)))))
   6046 	   (backend `(org-export-with-backend ',backend cell contents info))
   6047 	   (t 'contents))))))
   6048 
   6049 ;;;###autoload
   6050 (defun orgtbl-to-tsv (table params)
   6051   "Convert the `orgtbl-mode' TABLE to TAB separated material."
   6052   (orgtbl-to-generic table (org-combine-plists '(:sep "\t") params)))
   6053 
   6054 ;;;###autoload
   6055 (defun orgtbl-to-csv (table params)
   6056   "Convert the `orgtbl-mode' TABLE to CSV material.
   6057 This does take care of the proper quoting of fields with comma or quotes."
   6058   (orgtbl-to-generic table
   6059 		     (org-combine-plists '(:sep "," :fmt org-quote-csv-field)
   6060 					 params)))
   6061 
   6062 ;;;###autoload
   6063 (defun orgtbl-to-latex (table params)
   6064   "Convert the `orgtbl-mode' TABLE to LaTeX.
   6065 
   6066 TABLE is a list, each entry either the symbol `hline' for
   6067 a horizontal separator line, or a list of fields for that line.
   6068 PARAMS is a property list of parameters that can influence the
   6069 conversion.  All parameters from `orgtbl-to-generic' are
   6070 supported.  It is also possible to use the following ones:
   6071 
   6072 :booktabs
   6073 
   6074   When non-nil, use formal \"booktabs\" style.
   6075 
   6076 :environment
   6077 
   6078   Specify environment to use, as a string.  If you use
   6079   \"longtable\", you may also want to specify :language property,
   6080   as a string, to get proper continuation strings."
   6081   (require 'ox-latex)
   6082   (orgtbl-to-generic
   6083    table
   6084    (org-combine-plists
   6085     ;; Provide sane default values.
   6086     (list :backend 'latex
   6087 	  :latex-default-table-mode 'table
   6088 	  :latex-tables-centered nil
   6089 	  :latex-tables-booktabs (plist-get params :booktabs)
   6090 	  :latex-table-scientific-notation nil
   6091 	  :latex-default-table-environment
   6092 	  (or (plist-get params :environment) "tabular"))
   6093     params)))
   6094 
   6095 ;;;###autoload
   6096 (defun orgtbl-to-html (table params)
   6097   "Convert the `orgtbl-mode' TABLE to HTML.
   6098 
   6099 TABLE is a list, each entry either the symbol `hline' for
   6100 a horizontal separator line, or a list of fields for that line.
   6101 PARAMS is a property list of parameters that can influence the
   6102 conversion.  All parameters from `orgtbl-to-generic' are
   6103 supported.  It is also possible to use the following one:
   6104 
   6105 :attributes
   6106 
   6107   Attributes and values, as a plist, which will be used in
   6108   <table> tag."
   6109   (require 'ox-html)
   6110   (orgtbl-to-generic
   6111    table
   6112    (org-combine-plists
   6113     ;; Provide sane default values.
   6114     (list :backend 'html
   6115 	  :html-table-data-tags '("<td%s>" . "</td>")
   6116 	  :html-table-use-header-tags-for-first-column nil
   6117 	  :html-table-align-individual-fields t
   6118 	  :html-table-row-tags '("<tr>" . "</tr>")
   6119 	  :html-table-attributes
   6120 	  (if (plist-member params :attributes)
   6121 	      (plist-get params :attributes)
   6122 	    '(:border "2" :cellspacing "0" :cellpadding "6" :rules "groups"
   6123 		      :frame "hsides")))
   6124     params)))
   6125 
   6126 ;;;###autoload
   6127 (defun orgtbl-to-texinfo (table params)
   6128   "Convert the `orgtbl-mode' TABLE to Texinfo.
   6129 
   6130 TABLE is a list, each entry either the symbol `hline' for
   6131 a horizontal separator line, or a list of fields for that line.
   6132 PARAMS is a property list of parameters that can influence the
   6133 conversion.  All parameters from `orgtbl-to-generic' are
   6134 supported.  It is also possible to use the following one:
   6135 
   6136 :columns
   6137 
   6138   Column widths, as a string.  When providing column fractions,
   6139   \"@columnfractions\" command can be omitted."
   6140   (require 'ox-texinfo)
   6141   (let ((output
   6142 	 (orgtbl-to-generic
   6143 	  table
   6144 	  (org-combine-plists
   6145 	   (list :backend 'texinfo
   6146 		 :texinfo-tables-verbatim nil
   6147 		 :texinfo-table-scientific-notation nil)
   6148 	   params)))
   6149 	(columns (let ((w (plist-get params :columns)))
   6150 		   (cond ((not w) nil)
   6151 			 ((string-match-p "{\\|@columnfractions " w) w)
   6152 			 (t (concat "@columnfractions " w))))))
   6153     (if (not columns) output
   6154       (replace-regexp-in-string
   6155        "@multitable \\(.*\\)" columns output t nil 1))))
   6156 
   6157 ;;;###autoload
   6158 (defun orgtbl-to-orgtbl (table params)
   6159   "Convert the `orgtbl-mode' TABLE into another `orgtbl-mode' table.
   6160 
   6161 TABLE is a list, each entry either the symbol `hline' for
   6162 a horizontal separator line, or a list of fields for that line.
   6163 PARAMS is a property list of parameters that can influence the
   6164 conversion.  All parameters from `orgtbl-to-generic' are
   6165 supported.
   6166 
   6167 Useful when slicing one table into many.  The :hline, :sep,
   6168 :lstart, and :lend provide orgtbl framing.  :tstart and :tend can
   6169 be set to provide ORGTBL directives for the generated table."
   6170   (require 'ox-org)
   6171   (orgtbl-to-generic table (org-combine-plists params (list :backend 'org))))
   6172 
   6173 (defun orgtbl-to-table.el (table params)
   6174   "Convert the `orgtbl-mode' TABLE into a table.el table.
   6175 TABLE is a list, each entry either the symbol `hline' for
   6176 a horizontal separator line, or a list of fields for that line.
   6177 PARAMS is a property list of parameters that can influence the
   6178 conversion.  All parameters from `orgtbl-to-generic' are
   6179 supported."
   6180   (with-temp-buffer
   6181     (insert (orgtbl-to-orgtbl table params))
   6182     (org-table-align)
   6183     (goto-char (point-min))
   6184     (while (search-forward "-|" nil t)
   6185       (replace-match "-+"))
   6186     (goto-char (point-min))
   6187     (while (search-forward "|-" nil t)
   6188       (replace-match "+-"))
   6189     (buffer-string)))
   6190 
   6191 (defun orgtbl-to-unicode (table params)
   6192   "Convert the `orgtbl-mode' TABLE into a table with unicode characters.
   6193 
   6194 TABLE is a list, each entry either the symbol `hline' for
   6195 a horizontal separator line, or a list of fields for that line.
   6196 PARAMS is a property list of parameters that can influence the
   6197 conversion.  All parameters from `orgtbl-to-generic' are
   6198 supported.  It is also possible to use the following ones:
   6199 
   6200 :ascii-art
   6201 
   6202   When non-nil, use \"ascii-art-to-unicode\" package to translate
   6203   the table.  You can download it here:
   6204   https://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el.
   6205 
   6206 :narrow
   6207 
   6208   When non-nil, narrow columns width than provided width cookie,
   6209   using \"=>\" as an ellipsis, just like in an Org mode buffer."
   6210   (require 'ox-ascii)
   6211   (orgtbl-to-generic
   6212    table
   6213    (org-combine-plists
   6214     (list :backend 'ascii
   6215 	  :ascii-charset 'utf-8
   6216 	  :ascii-table-widen-columns (not (plist-get params :narrow))
   6217 	  :ascii-table-use-ascii-art (plist-get params :ascii-art))
   6218     params)))
   6219 
   6220 ;; Put the cursor in a column containing numerical values
   6221 ;; of an Org table,
   6222 ;; type C-c " a
   6223 ;; A new column is added with a bar plot.
   6224 ;; When the table is refreshed (C-u C-c *),
   6225 ;; the plot is updated to reflect the new values.
   6226 
   6227 (defun orgtbl-ascii-draw (value min max &optional width characters)
   6228   "Draw an ascii bar in a table.
   6229 VALUE is the value to plot, it determines the width of the bar to draw.
   6230 MIN is the value that will be displayed as empty (zero width bar).
   6231 MAX is the value that will draw a bar filling all the WIDTH.
   6232 WIDTH is the span in characters from MIN to MAX.
   6233 CHARACTERS is a string that will compose the bar, with shades of grey
   6234 from pure white to pure black.  It defaults to a 10 characters string
   6235 of regular ascii characters."
   6236   (let* ((width      (ceiling (or width 12)))
   6237 	 (characters (or characters " .:;c!lhVHW"))
   6238 	 (len        (1- (length characters)))
   6239 	 (value      (float (if (numberp value)
   6240 				value (string-to-number value))))
   6241 	 (relative   (/ (- value min) (- max min)))
   6242 	 (steps      (round (* relative width len))))
   6243     (cond ((< steps             0) "too small")
   6244 	  ((> steps (* width len)) "too large")
   6245 	  (t (let* ((int-division (/ steps len))
   6246 		    (remainder    (- steps (* int-division len))))
   6247 	       (concat (make-string int-division (elt characters len))
   6248 		       (string (elt characters remainder))))))))
   6249 
   6250 ;;;###autoload
   6251 (defun orgtbl-ascii-plot (&optional ask)
   6252   "Draw an ASCII bar plot in a column.
   6253 
   6254 With cursor in a column containing numerical values, this function
   6255 will draw a plot in a new column.
   6256 
   6257 ASK, if given, is a numeric prefix to override the default 12
   6258 characters width of the plot.  ASK may also be the `\\[universal-argument]' \
   6259 prefix,
   6260 which will prompt for the width."
   6261   (interactive "P")
   6262   (let ((col (org-table-current-column))
   6263 	(min  1e999)		 ; 1e999 will be converted to infinity
   6264 	(max -1e999)		 ; which is the desired result
   6265 	(table (org-table-to-lisp))
   6266 	(length
   6267 	 (cond ((consp ask)
   6268 		(read-number "Length of column " 12))
   6269 	       ((numberp ask) ask)
   6270 	       (t 12))))
   6271     ;; Skip any hline a the top of table.
   6272     (while (eq (car table) 'hline) (pop table))
   6273     ;; Skip table header if any.
   6274     (dolist (x (or (cdr (memq 'hline table)) table))
   6275       (when (consp x)
   6276 	(setq x (nth (1- col) x))
   6277 	(when (string-match
   6278 	       "^[-+]?\\([0-9]*[.]\\)?[0-9]*\\([eE][+-]?[0-9]+\\)?$"
   6279 	       x)
   6280 	  (setq x (string-to-number x))
   6281 	  (when (> min x) (setq min x))
   6282 	  (when (< max x) (setq max x)))))
   6283     (org-table-insert-column)
   6284     (org-table-move-column-right)
   6285     (org-table-store-formulas
   6286      (cons
   6287       (cons
   6288        (concat "$" (number-to-string (1+ col)))
   6289        (format "'(%s $%s %s %s %s)"
   6290 	       "orgtbl-ascii-draw" col min max length))
   6291       (org-table-get-stored-formulas)))
   6292     (org-table-recalculate t)))
   6293 
   6294 ;; Example of extension: unicode characters
   6295 ;; Here are two examples of different styles.
   6296 
   6297 ;; Unicode block characters are used to give a smooth effect.
   6298 ;; See https://en.wikipedia.org/wiki/Block_Elements
   6299 ;; Use one of those drawing functions
   6300 ;; - orgtbl-ascii-draw   (the default ascii)
   6301 ;; - orgtbl-uc-draw-grid (unicode with a grid effect)
   6302 ;; - orgtbl-uc-draw-cont (smooth unicode)
   6303 
   6304 ;; This is best viewed with the "DejaVu Sans Mono" font
   6305 ;; (use M-x set-frame-font).
   6306 
   6307 (defun orgtbl-uc-draw-grid (value min max &optional width)
   6308   "Draw a bar in a table using block unicode characters.
   6309 It is a variant of `orgtbl-ascii-draw' with Unicode block
   6310 characters, for a smooth display.  Bars appear as grids (to the
   6311 extent the font allows)."
   6312   ;; https://en.wikipedia.org/wiki/Block_Elements
   6313   ;; best viewed with the "DejaVu Sans Mono" font.
   6314   (orgtbl-ascii-draw value min max width
   6315 		     " \u258F\u258E\u258D\u258C\u258B\u258A\u2589"))
   6316 
   6317 (defun orgtbl-uc-draw-cont (value min max &optional width)
   6318   "Draw a bar in a table using block unicode characters.
   6319 It is a variant of `orgtbl-ascii-draw' with Unicode block
   6320 characters, for a smooth display.  Bars are solid (to the extent
   6321 the font allows)."
   6322   (orgtbl-ascii-draw value min max width
   6323 		     " \u258F\u258E\u258D\u258C\u258B\u258A\u2589\u2588"))
   6324 
   6325 (defun org-table-get-remote-range (name-or-id form)
   6326   "Get a field value or a list of values in a range from table at ID.
   6327 
   6328 NAME-OR-ID may be the name of a table in the current file as set
   6329 by a \"#+NAME:\" directive.  The first table following this line
   6330 will then be used.  Alternatively, it may be an ID referring to
   6331 any entry, also in a different file.  In this case, the first
   6332 table in that entry will be referenced.
   6333 FORM is a field or range descriptor like \"@2$3\" or \"B3\" or
   6334 \"@I$2..@II$2\".  All the references must be absolute, not relative.
   6335 
   6336 The return value is either a single string for a single field, or a
   6337 list of the fields in the rectangle."
   6338   (save-match-data
   6339     (let ((case-fold-search t) (id-loc nil)
   6340 	  ;; Protect a bunch of variables from being overwritten by
   6341 	  ;; the context of the remote table.
   6342 	  org-table-column-names org-table-column-name-regexp
   6343 	  org-table-local-parameters org-table-named-field-locations
   6344 	  org-table-current-line-types
   6345 	  org-table-current-begin-pos org-table-dlines
   6346 	  org-table-current-ncol
   6347 	  org-table-hlines
   6348 	  org-table-last-column-widths
   6349 	  org-table-last-alignment
   6350 	  buffer loc)
   6351       (setq form (org-table-convert-refs-to-rc form))
   6352       (org-with-wide-buffer
   6353        (goto-char (point-min))
   6354        (if (re-search-forward
   6355 	    (concat "^[ \t]*#\\+\\(tbl\\)?name:[ \t]*"
   6356 		    (regexp-quote name-or-id) "[ \t]*$")
   6357 	    nil t)
   6358 	   (setq buffer (current-buffer) loc (match-beginning 0))
   6359 	 (setq id-loc (org-id-find name-or-id 'marker))
   6360 	 (unless (and id-loc (markerp id-loc))
   6361 	   (user-error "Can't find remote table \"%s\"" name-or-id))
   6362 	 (setq buffer (marker-buffer id-loc)
   6363 	       loc (marker-position id-loc))
   6364 	 (move-marker id-loc nil))
   6365        (with-current-buffer buffer
   6366 	 (org-with-wide-buffer
   6367 	  (goto-char loc)
   6368 	  (forward-char 1)
   6369 	  (unless (and (re-search-forward "^\\(\\*+ \\)\\|^[ \t]*|" nil t)
   6370 		       (not (match-beginning 1)))
   6371 	    (user-error "Cannot find a table at NAME or ID %s" name-or-id))
   6372 	  (org-table-analyze)
   6373 	  (setq form (org-table-formula-substitute-names
   6374 		      (org-table-formula-handle-first/last-rc form)))
   6375 	  (if (and (string-match org-table-range-regexp form)
   6376 		   (> (length (match-string 0 form)) 1))
   6377 	      (org-table-get-range
   6378 	       (match-string 0 form) org-table-current-begin-pos 1)
   6379 	    form)))))))
   6380 
   6381 (defun org-table-remote-reference-indirection (form)
   6382   "Return formula with table remote references substituted by indirection.
   6383 For example \"remote($1, @>$2)\" => \"remote(year_2013, @>$1)\".
   6384 This indirection works only with the format @ROW$COLUMN.  The
   6385 format \"B3\" is not supported because it can not be
   6386 distinguished from a plain table name or ID."
   6387   (let ((regexp
   6388 	 ;; Same as in `org-table-eval-formula'.
   6389 	 (concat "\\<remote([ \t]*\\("
   6390 		 ;; Allow "$1", "@<", "$-1", "@<<$1" etc.
   6391 		 "[@$][^ \t,]+"
   6392 		 "\\)[ \t]*,[ \t]*\\([^\n)]+\\))")))
   6393     (replace-regexp-in-string
   6394      regexp
   6395      (lambda (m)
   6396        (save-match-data
   6397 	 (let ((eq (org-table-formula-handle-first/last-rc (match-string 1 m))))
   6398 	   (org-table-get-range
   6399 	    (if (string-match-p "\\`\\$[0-9]+\\'" eq)
   6400 		(concat "@0" eq)
   6401 	      eq)))))
   6402      form t t 1)))
   6403 
   6404 (defmacro org-define-lookup-function (mode)
   6405   (let ((mode-str (symbol-name mode))
   6406 	(first-p (eq mode 'first))
   6407 	(all-p (eq mode 'all)))
   6408     (let ((plural-str (if all-p "s" "")))
   6409       `(defun ,(intern (format "org-lookup-%s" mode-str)) (val s-list r-list &optional predicate)
   6410 	 ,(format "Find %s occurrence%s of VAL in S-LIST; return corresponding element%s of R-LIST.
   6411 If R-LIST is nil, return matching element%s of S-LIST.
   6412 If PREDICATE is not nil, use it instead of `equal' to match VAL.
   6413 Matching is done by (PREDICATE VAL S), where S is an element of S-LIST.
   6414 This function is generated by a call to the macro `org-define-lookup-function'."
   6415 		  mode-str plural-str plural-str plural-str)
   6416 	 (let ,(let ((lvars '((p (or predicate 'equal))
   6417 			      (sl s-list)
   6418 			      (rl (or r-list s-list))
   6419 			      (ret nil))))
   6420 		 (if first-p (cons '(match-p nil) lvars) lvars))
   6421 	   (while ,(if first-p '(and (not match-p) sl) 'sl)
   6422 	     (when (funcall p val (car sl))
   6423 	       ,(when first-p '(setq match-p t))
   6424 	       (let ((rval (car rl)))
   6425 		 (setq ret ,(if all-p '(append ret (list rval)) 'rval))))
   6426 	     (setq sl (cdr sl) rl (cdr rl)))
   6427 	   ret)))))
   6428 
   6429 (org-define-lookup-function first)
   6430 (org-define-lookup-function last)
   6431 (org-define-lookup-function all)
   6432 
   6433 (provide 'org-table)
   6434 
   6435 ;; Local variables:
   6436 ;; generated-autoload-file: "org-loaddefs.el"
   6437 ;; End:
   6438 
   6439 ;;; org-table.el ends here