Emacs & LaTeX: number of columns for tables / matrices / arrays

Anyone have a suggestion on how to do this for:

\begin{array}{cc} Lorem & Ipsum \\ More & Stuff \\ \end{array} 

When you add or remove c , l or r in the part after the array, & will be added or removed from all rows in the array environment.

In principle, the same trick can be applied to matrices or tabular environments.

At least, I would be interested in how others will be engaged in this task of "easy to make mistakes," "hard-to-change."

+8
arrays matrix emacs latex
source share
4 answers

As suggested , you can make YASnippet , which according to the number of letters in the second argument of array automatically adds the corresponding number & to the first line of the array:

 # -*- mode: snippet -*- # name: array # key: arr # expand-env: ((yas/indent-line 'fixed)) # -- \begin{array}{${1:cc}}$0 ${1:$ (let ((row "")) (dotimes (i (- (string-width yas/text) 1) row) (setq row (concat row "& ")))) }\\\\ \end{array} 

A guide is an example of this technique . The line with (yas/indent-line 'fixed) is to avoid AUCTeX backing away from the line. The reason for placing the exit point of the fragment ( $0 ) at the end of the array declaration, and not at the beginning of the first line, is that when placed at the beginning of the first line, the exit point does not behave as expected.

The following snippet will add as many rows as there are columns:

 # -*- mode: snippet -*- # name: array # key: arr # expand-env: ((yas/indent-line 'fixed)) # -- \begin{array}{${1:cc}}$0 ${1:$ (let ((row "") (allrows "")) (dotimes (i (- (string-width yas/text) 1)) (setq row (concat row "& "))) (dotimes (i (string-width yas/text) allrows) (setq allrows (concat allrows row "\\\\\\\\\n")))) }\end{array} 

The problem with this fragment is that it adds \\ , even if there is only one column, but such arrays can be rare.

It seems to be having problems adding lisp comments to the built-in lisp code in fragments, so I just add a commented version of lisp code only to explain this:

 ;; Make an empty row with as many columns as symbols in $1 (the $1 in ;; the snippet which is what yas/text refer to) (let ((row "") (allrows "")) ;; Make an empty row with as many columns as symbols in $1 (dotimes (i (- (string-width yas/text) 1)) (setq row (concat row "& "))) ;; Make as many rows as symbols in $1 (dotimes (i (string-width yas/text) allrows) (setq allrows (concat allrows row "\\\\\\\\\n")))) 
+1
source share

I usually generate tables from a different format (tab-delimited values ​​or org-mode tables) in which such operations are simpler.

+3
source share

This is not quite the answer, but here is how I did it:

  • Align with &, for example: Cx. & .

  • Select the entire column that I need with regular selection commands.

  • Cut a rectangular area using Cx rk .

This is not super automatic, but with some exercises it is not an obstacle, except, perhaps, if you need to reformat the old document and make many changes at once.

EDIT

 (defun latex-merge-next-column (start end column) "Works on selected region, removes COLUMN'th ampersand in every line in the selected region" (interactive "r\nnColumn to merge: ") (labels ((%nth-index-of (line) (let ((i -1) (times 0)) (while (and (< times column) i) (setq i (position ?\& line :start (1+ i)) times (1+ times))) i))) (let ((region (split-string (buffer-substring start end) "\n")) amp-pos replacement) (dolist (line region) (setq amp-pos (%nth-index-of line) replacement (cons (if amp-pos (concat (subseq line 0 amp-pos) (subseq line (1+ amp-pos))) line) replacement))) (kill-region start end) (insert (mapconcat #'identity (reverse replacement) "\n"))))) 

This will work in the selected region and remove the nth ampersand in each line. You can associate it with a key convenient for you, say:

 (global-set-key (kbd "Cc Cn") 'latex-merge-next-column) 

Then Cc Cn 2 removes every second ampersand in the selected rows.

+2
source share

Based on @wvxvw's solution, how about using Mx align-current in a table / matrix / array environment, and then manipulating with block / insert select commands? This seems to work reasonably with shielded ampersands. I find it helpful to disable packaging during this operation. I don’t find it hard to edit at all, since relatively regular re-alignment makes everything readable.

+1
source share

All Articles