emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* manipulate org tables using emacs-lisp
@ 2016-09-30  6:27 Alan Schmitt
  2016-09-30 20:52 ` Thorsten Jolitz
  0 siblings, 1 reply; 6+ messages in thread
From: Alan Schmitt @ 2016-09-30  6:27 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 413 bytes --]

Hello,

Are there functions for manipulating org-tables using emacs-lisp? More
precisely, I would like to refer to a table by its name, read some cells
(either by position or by matching some given text with some text in the
first row/column), and write in some cells.

Thanks,

Alan

-- 
OpenPGP Key ID : 040D0A3B4ED2E5C7
Monthly Athmospheric CO₂, Mauna Loa Obs. 2016-08: 402.25, 2015-08: 398.93

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 454 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: manipulate org tables using emacs-lisp
  2016-09-30  6:27 manipulate org tables using emacs-lisp Alan Schmitt
@ 2016-09-30 20:52 ` Thorsten Jolitz
  2016-10-01  8:44   ` Alan Schmitt
  0 siblings, 1 reply; 6+ messages in thread
From: Thorsten Jolitz @ 2016-09-30 20:52 UTC (permalink / raw)
  To: emacs-orgmode

Alan Schmitt <alan.schmitt@polytechnique.org> writes:

Hi Alan,

> Are there functions for manipulating org-tables using emacs-lisp? More
> precisely, I would like to refer to a table by its name, read some cells
> (either by position or by matching some given text with some text in the
> first row/column), and write in some cells.

,----[ C-h f org-table-to-lisp RET ]
| org-table-to-lisp is an autoloaded compiled Lisp function in
| ‘../org-mode/lisp/org-table.el’.
| 
| (org-table-to-lisp &optional TXT)
| 
| Convert the table at point to a Lisp structure.
| The structure will be a list.  Each item is either the symbol ‘hline’
| for a horizontal separator line, or a list of field values as strings.
| The table is taken from the parameter TXT, or from the buffer at point.
| 
| [back]
`----

returns the table as a nested list you can map with lots of Elisp
functions (like mapcar). 

Ex.:

| my | tab |
|  1 |   2 |

=>

(("my" "tab") ("1" "2"))

-- 
cheers,
Thorsten

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: manipulate org tables using emacs-lisp
  2016-09-30 20:52 ` Thorsten Jolitz
@ 2016-10-01  8:44   ` Alan Schmitt
  2016-10-01 16:32     ` Thorsten Jolitz
  2016-10-02  7:19     ` Heikki Lehvaslaiho
  0 siblings, 2 replies; 6+ messages in thread
From: Alan Schmitt @ 2016-10-01  8:44 UTC (permalink / raw)
  To: Thorsten Jolitz; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1336 bytes --]

Hi Thorsten,

On 2016-09-30 22:52, Thorsten Jolitz <tjolitz@gmail.com> writes:

>> Are there functions for manipulating org-tables using emacs-lisp? More
>> precisely, I would like to refer to a table by its name, read some cells
>> (either by position or by matching some given text with some text in the
>> first row/column), and write in some cells.
>
> ,----[ C-h f org-table-to-lisp RET ]
> | org-table-to-lisp is an autoloaded compiled Lisp function in
> | ‘../org-mode/lisp/org-table.el’.
> | 
> | (org-table-to-lisp &optional TXT)
> | 
> | Convert the table at point to a Lisp structure.
> | The structure will be a list.  Each item is either the symbol ‘hline’
> | for a horizontal separator line, or a list of field values as strings.
> | The table is taken from the parameter TXT, or from the buffer at point.
> | 
> | [back]
> `----
>
> returns the table as a nested list you can map with lots of Elisp
> functions (like mapcar). 
>
> Ex.:
>
> | my | tab |
> |  1 |   2 |
>
> =>
>
> (("my" "tab") ("1" "2"))

This is very useful, thank you. But how do I go to a named table? I
found org-babel-goto-named-block, but nothing for tables.

Thanks again,

Alan

-- 
OpenPGP Key ID : 040D0A3B4ED2E5C7
Monthly Athmospheric CO₂, Mauna Loa Obs. 2016-08: 402.25, 2015-08: 398.93

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 454 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: manipulate org tables using emacs-lisp
  2016-10-01  8:44   ` Alan Schmitt
@ 2016-10-01 16:32     ` Thorsten Jolitz
  2016-10-02  7:19     ` Heikki Lehvaslaiho
  1 sibling, 0 replies; 6+ messages in thread
From: Thorsten Jolitz @ 2016-10-01 16:32 UTC (permalink / raw)
  To: emacs-orgmode

Alan Schmitt <alan.schmitt@polytechnique.org> writes:

Hi Alan,

> On 2016-09-30 22:52, Thorsten Jolitz <tjolitz@gmail.com> writes:
>
>>> Are there functions for manipulating org-tables using emacs-lisp? More
>>> precisely, I would like to refer to a table by its name, read some cells
>>> (either by position or by matching some given text with some text in the
>>> first row/column), and write in some cells.
>>
>> ,----[ C-h f org-table-to-lisp RET ]
>> | org-table-to-lisp is an autoloaded compiled Lisp function in
>> | ‘../org-mode/lisp/org-table.el’.
>> | 
>> | (org-table-to-lisp &optional TXT)
>> | 
>> | Convert the table at point to a Lisp structure.
>> | The structure will be a list.  Each item is either the symbol ‘hline’
>> | for a horizontal separator line, or a list of field values as strings.
>> | The table is taken from the parameter TXT, or from the buffer at point.
>> | 
>> | [back]
>> `----
>>
>> returns the table as a nested list you can map with lots of Elisp
>> functions (like mapcar). 
>>
>> Ex.:
>>
>> | my | tab |
>> |  1 |   2 |
>>
>> =>
>>
>> (("my" "tab") ("1" "2"))
>
> This is very useful, thank you. But how do I go to a named table? I
> found org-babel-goto-named-block, but nothing for tables.

you can try

,----[ C-h f org-table-map-tables RET ]
| org-table-map-tables is a compiled Lisp function in
| ‘../org-mode/lisp/org.el’.
| 
| (org-table-map-tables FUNCTION &optional QUIETLY)
| 
| Apply FUNCTION to the start of all tables in the buffer.
| 
| [back]
`----

to go to all tables in the buffer, then inside FUNCTION you would need
to check first if the table is named and is the one your are looking
for. If so, get the table as list, work on the list, and insert the new
table replacing the old one (org-dp-create-table inserts a table when
given a nested list). 
Finally move point to the end of the inserted table, so the mapping
function can continue.

PS
org-element and org-dp allow you to do these things too, maybe even
more comfortably if you are familiar with these libraries. But right now
I'm not really able to give you a working example in reasonable time.

-- 
cheers,
Thorsten

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: manipulate org tables using emacs-lisp
  2016-10-01  8:44   ` Alan Schmitt
  2016-10-01 16:32     ` Thorsten Jolitz
@ 2016-10-02  7:19     ` Heikki Lehvaslaiho
  2016-10-03 12:58       ` Alan Schmitt
  1 sibling, 1 reply; 6+ messages in thread
From: Heikki Lehvaslaiho @ 2016-10-02  7:19 UTC (permalink / raw)
  To: Alan Schmitt; +Cc: emacs-orgmode, Thorsten Jolitz

[-- Attachment #1: Type: text/plain, Size: 2263 bytes --]

Hi Alan,

Try this function. You can test if the table was found before manipulating
it. Table functions typically work only inside tables, but the #+NAME line
is part of it although it is before the table itself (as defined by
function org-table-begin).


  (defun my/org-table-find-by-name (str)
    "Move point to the first table of the buffer with STR in the name.

The point does not move if the table is not found.
Returns the new position if successful, nil otherwise.
"
    (interactive "sTable name substring: ")
    (let ((re (concat "#\\+NAME:.+" str))
          (loc-table nil))
      (setq loc-table (save-excursion
                        (goto-char (point-min))
                        (re-search-forward re nil t)))
      (if (number-or-marker-p loc-table)
          (goto-char loc-table))))

  -Heikki

Hi Thorsten,

>
> On 2016-09-30 22:52, Thorsten Jolitz <tjolitz@gmail.com> writes:
>
> >> Are there functions for manipulating org-tables using emacs-lisp? More
> >> precisely, I would like to refer to a table by its name, read some cells
> >> (either by position or by matching some given text with some text in the
> >> first row/column), and write in some cells.
> >
> > ,----[ C-h f org-table-to-lisp RET ]
> > | org-table-to-lisp is an autoloaded compiled Lisp function in
> > | ‘../org-mode/lisp/org-table.el’.
> > |
> > | (org-table-to-lisp &optional TXT)
> > |
> > | Convert the table at point to a Lisp structure.
> > | The structure will be a list.  Each item is either the symbol ‘hline’
> > | for a horizontal separator line, or a list of field values as strings.
> > | The table is taken from the parameter TXT, or from the buffer at point.
> > |
> > | [back]
> > `----
> >
> > returns the table as a nested list you can map with lots of Elisp
> > functions (like mapcar).
> >
> > Ex.:
> >
> > | my | tab |
> > |  1 |   2 |
> >
> > =>
> >
> > (("my" "tab") ("1" "2"))
>
> This is very useful, thank you. But how do I go to a named table? I
> found org-babel-goto-named-block, but nothing for tables.
>
> Thanks again,
>
> Alan
>
> --
> OpenPGP Key ID : 040D0A3B4ED2E5C7
> Monthly Athmospheric CO₂, Mauna Loa Obs. 2016-08: 402.25, 2015-08: 398.93
>

[-- Attachment #2: Type: text/html, Size: 3262 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: manipulate org tables using emacs-lisp
  2016-10-02  7:19     ` Heikki Lehvaslaiho
@ 2016-10-03 12:58       ` Alan Schmitt
  0 siblings, 0 replies; 6+ messages in thread
From: Alan Schmitt @ 2016-10-03 12:58 UTC (permalink / raw)
  To: Heikki Lehvaslaiho; +Cc: emacs-orgmode, Thorsten Jolitz

[-- Attachment #1: Type: text/plain, Size: 2639 bytes --]

Thanks a lot for all the suggestions. For the moment I’ve put the table
at the beginning of the file, but I’ll probably tweak the following
functions to use Heikki’s trick of using a regexp to find the named
table.

I don’t think I want to convert the table to a lisp structure, work on
it, and output back the table as I want to preserve the formulas at the
end of the table. So what I do instead is convert it to a lisp structure
to find the row and column numbers I’m interested in, then use org-table
functions to directly change the table.

Here is the code, if it’s helpful to others.

Thanks again,

Alan

#+BEGIN_SRC emacs-lisp
  (defun as/get-row-by-name (name)
    "This assumes the table is at the beginning of the file"
    (save-excursion
      (goto-char (point-min))
      (let ((tb (org-table-to-lisp))
            (row 1)
            (res))
        (while (and (not res) tb)
          (unless (equal (car tb) 'hline)
            (if (equal (caar tb) name)
                (setq res row)
              (setq row (+ row 1))))
          (setq tb (cdr tb)))
        res)))

  (defun as/get-column-by-name (name)
    "This assumes the table is at the beginning of the file"
    (save-excursion
      (goto-char (point-min))
      (let ((first-row (car (org-table-to-lisp)))
            (col 1)
            (res))
        (while (and (not res) first-row)
            (if (equal (car first-row) name)
                (setq res col)
              (setq col (+ col 1)))
          (setq first-row (cdr first-row)))
        res)))

  (defun as/get-clean-value (rowname colname)
    "This assumes the table is at the start of the file"
    (save-excursion
      (goto-char (point-min))
      (let ((row (as/get-row-by-name rowname))
            (col (as/get-column-by-name colname)))
        (unless (and row col) (error "row name or column name not found"))
        (let ((res (org-trim (org-table-get row col))))
          (set-text-properties 0 (length res) nil res)
          res))))

  (defun as/set-table-value (rowname colname value)
    "This assumes the table is at the start of the file"
    (save-excursion
      (goto-char (point-min))
      (let ((row (as/get-row-by-name rowname))
            (col (as/get-column-by-name colname)))
        (unless (and row col) (error "row name or column name not found"))
        (org-table-goto-line row)
        (org-table-get-field col value)
        (org-table-align))))
#+END_SRC

-- 
OpenPGP Key ID : 040D0A3B4ED2E5C7
Monthly Athmospheric CO₂, Mauna Loa Obs. 2016-08: 402.25, 2015-08: 398.93

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 454 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-10-03 12:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-30  6:27 manipulate org tables using emacs-lisp Alan Schmitt
2016-09-30 20:52 ` Thorsten Jolitz
2016-10-01  8:44   ` Alan Schmitt
2016-10-01 16:32     ` Thorsten Jolitz
2016-10-02  7:19     ` Heikki Lehvaslaiho
2016-10-03 12:58       ` Alan Schmitt

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).