Editing Tables in Emacs and Org Mode
Emacs Text-based Tables
Emacs has a built-in library called table.el (see info:emacs#Text Based
Tables for more details).
Creating a Table
To create a text-based table from scratch, type M-x table-insert. This command prompts for the number of table columns, the number of table rows, cell width and cell height.
For example, M-x table-insert 3 RET 3 RET 5 RET 1 RET creates a table which has 3 columns and 3 rows, and every column is 5-characters wide and every row is 1-character high.
+-----+-----+-----+
| | | |
+-----+-----+-----+
| | | |
+-----+-----+-----+
| | | |
+-----+-----+-----+And M-x table-insert 3 RET 3 RET 4 8 12 RET 1 2 3 RET creates a table which has 3 columns and 3 rows, and the columns are 4, 8, 12-character wide respectively and the rows are 1, 2, 3-character high respectively.
+----+--------+------------+
| | | |
+----+--------+------------+
| | | |
| | | |
+----+--------+------------+
| | | |
| | | |
| | | |
+----+--------+------------+Editing a Table
The table inserted by M-x table-insert contains special text properties, which tell Emacs to treat it specially as a text-based table. If you save the buffer to a file and visit it again later, those properties are lost, and the table appears to Emacs as an ordinary piece of text.
To apply those text properties to all tables (i.e., convert them back into a recognized tables), type M-x table-recognize, to discard them, type M-x
table-unrecognize.
You can also use the following commands to selectively recognize or unrecognize tables:
- in the current region:
table-recognize-region,table-unrecognize-region - at point:
table-recognize-table,table-unrecognize-table - only the cell at point:
table-recognize-cell,table-unrecognize-table
You can use the following commands to edit the cells. The key-bindings are activated only when the table is recognized.
- Move point to the next/previous cell:
table-forward-cell(TAB),table-backward-cell(S-TAB) -
Insert
- one or more rows before the current row:
table-insert-row - one or more columns before the current column:
table-insert-column - one or more columns or rows:
table-insert-row-column(C-c C-c +)
- one or more rows before the current row:
-
Delete
- one or more rows:
table-delete-row - one or more columns:
table-delete-column
- one or more rows:
-
Enlarge/Shrink the current cell
- vertically:
table-heighten-cell(C-c C-c }),table-shorten-cell(C-c C-c {) - horizontally:
table-widen-cell(C-c C-c >),table-narrow-cell(C-c C-c <)
- vertically:
column- and row-spanning
- Merge the current cell with the adjacent cell:
table-span-cell(C-c C-c *) -
Split the current cell
- vertically:
table-split-cell-vertically(C-c C-c -) - horizontally:
table-split-cell-horizontally(C-c C-c |) - vertically or horizontally:
table-split-cell
- vertically:
Alignment
- Justify cell, column, or row:
table-justify(C-c C-c :)
Automatic Line Wrapping
The built-in tables support automatic line wrapping in a cell as you type. The lines are treated as one cell and are preserved when exported to other formats such as HTML.
Other
- Traverse the cells and insert an incremental sequence into each cell:
table-insert-sequence - Report the layout of the table and table cell at point:
table-query-dimension(C-c C-c #) - Generate a table of a specific format:
table-generate-source(C-^)
Converting Between Plain Text and Tables
The command M-x table-capture captures plain text in a region and turns it into a table.
For example, suppose we have the following numbers, which are divided into three lines and separated horizontally by commas:
1, 2, 3, 4
5, 6, 7, 8
, 9, 10Invoking M-x table-capture , RET $ RET RET 5 on that text produces this table:
+-----+-----+-----+-----+
|1 |2 |3 |4 |
+-----+-----+-----+-----+
|5 |6 |7 |8 |
+-----+-----+-----+-----+
| |9 |10 | |
+-----+-----+-----+-----+M-x table-release does the opposite: it converts a table back to plain text, removing its cell borders.
1 2 3 4
5 6 7 8
9 10Org Mode Tables
Org comes with a fast and intuitive table editor.
Creating a Table
Org treats any line with | as the first non-whitespace character as part of a table. | is also the column separator. Moreover, a line starting with |- is a horizontal rule. It separates rows explicitly. Rows before the first horizontal rule are header lines.
To create a table of 3 columns you simply type |||| and then press TAB or C-c RET (org-ctrl-c-ret):
| | | |
| | | |To create a table of 3 columns with a horizontal rule type:
||||
|-and then press TAB, which gives you:
| | | |
|---+---+---|
| | | |A table is re-aligned automatically each time you press <TAB>, <RET> or C-c
C-c inside the table.
Using the command org-table-create-or-convert-from-region (C-c |):
It converts an active region to table. If every line contains at least one <TAB> character, the function assumes that the material is tab separated. If every line contains a comma, comma-separated values (CSV) are assumed. If not, lines are split at whitespace into fields.
You can use a prefix argument to force a specific separator: C-u forces CSV, C-u C-u forces <TAB>, C-u C-u C-u prompts for a regular expression to match the separator, and a numeric argument N indicates that at least N consecutive spaces, or alternatively a <TAB> will be the separator.
If there is no active region, it creates an empty Org table.
Editing a Table
-
Move point to the next/previous cell:
org-cycle(TAB),org-shifttab(S-TAB)This meanwhile re-aligns the table and creates a new row if in the last cell.
- Move point to the end or beginning of the cell content:
org-forward-sentence(M-e),org-backward-sentence(M-a) - Move the current column right or left:
org-metaright(<M-right>),org-metaleft(<M-left>) - Move the current row up or down:
org-metaup(<M-up>),org-metadown(<M-down>) - Re-align the table:
org-cycle(TAB),org-ctrl-c-ctrl-c(C-c C-c) -
Insert a horizontal rule
- below the current row:
org-ctrl-c-minus(C-c -),org-ctrl-c-ret(C-c RET) - above the current row:
org-ctrl-c-minus(C-u C-c -)
- below the current row:
-
Insert
- a row above the current row:
org-open-line(C-o),org-shiftmetadown(<M-S-down>) - a column to the left:
org-shiftmetaright(<M-S-right>)
- a row above the current row:
-
Go to the next row of the current column:
org-return-indent(C-j)It inserts a new row if point is at the last row.
- Copy the current cell content to the cell below:
org-table-copy-down(S-RET) -
Edit cell in a temporary buffer:
org-table-edit-field(C-c `)- To exit:
org-ctrl-c-ctrl-c(C-c C-c)
- To exit:
- Clear cell:
org-table-blank-field(C-c SPC) -
Delete
- the current row:
org-shiftmetaup(<M-S-up>) - the current column:
org-shiftmetaleft(<M-S-left>)
- the current row:
- Sort the table:
org-sort(C-c ^) - Toggle column width:
org-ctrl-c-tab(C-c TAB) - Format table according to column widths:
org-table-shrink(C-u C-c TAB) - Show field info:
org-table-field-info(C-c ?) - Toggle the display of Row/Column numbers in tables:
org-table-toggle-coordinate-overlays(C-c })
Automatic Line Wrapping
Currently there’s no automatic line wrapping in Org tables. But there’s the command org-table-wrap-region to manually wrap the contents in a cell.
-
Wrap the line at point to the next row:
org-meta-return(M-RET)This calls
org-table-wrap-regionwhen in a table cell. -
Append the line to the previous row (unwrap):
org-ctrl-return(C-RET)This is a custom command:
(defun org-ctrl-return (&optional arg) "Insert a new heading or unwrap a region in a table. Calls `org-insert-heading-respect-content', or `org-table-wrap-region' (with ARG), depending on context." (interactive "P") (org-fold-check-before-invisible-edit 'insert) (or (run-hook-with-args-until-success 'org-ctrl-return-hook) (cond ((org-at-table-p) (funcall #'org-table-wrap-region 1)) (t (call-interactively #'org-insert-heading-respect-content))))) (define-key org-mode-map (kbd "C-<return>") 'org-ctrl-return)
Working with Built-in Tables
Complex ASCII tables with automatic line wrapping, column- and row-spanning, and alignment can be created using the Emacs table.el package by Takaaki Ota. Org mode recognizes such tables and exports them properly. =C-c ‘= to edit these tables in a special buffer, much like Org’s code blocks. Because of interference with other Org mode functionality, Takaaki Ota tables cannot be edited directly in the Org buffer.
-
=C-c ‘= (
org-edit-special)Edit a
table.eltable. Works when point is in atable.eltable. -
C-c ~(org-table-create-with-table.el)Insert a
table.eltable. If there is already a table at point, this command converts it between thetable.elformat and the Org mode format. See the documentation string of the commandorg-convert-tablefor the restrictions under which this is possible.
Complex Tables in Minimal Mistakes Plus
While simple Org Mode tables can be parsed by org-ruby some advanced table features aren’t supported, and so we need to implement them on our own.
Check this documentation for more details.
Comments