只是为了练习:
(defun transpose-table (begin end &optional numcols)
(interactive "r\nP")
(save-excursion
(goto-char begin)
(move-beginning-of-line 1)
(let ((separators
(if numcols
(loop for i from 0 upto
(if (numberp numcols) numcols (car numcols))
for sep =
(read-string
(format "%d'th column separator (RET to terminate): " i))
until (string= sep "")
collect sep)
(let ((x (list " "))) (nconc x x))))
(end (save-excursion
(goto-char end)
(move-end-of-line 1)
(point))) lines)
(loop while (< (point) end)
for start = (point)
for line = (buffer-substring
start
(progn (move-end-of-line 1) (point)))
for numlines from 0
with numrows = 0
with longest-word = 0
collect (loop for i from 0 below (length line)
with last-pos = 0
with rows = 0
with sep = separators
for sep-length = (length (car sep))
if (and (< (+ sep-length i) (length line))
(string= (car sep)
(substring line i (+ i sep-length))))
collect (substring line last-pos i) into words
and do (setf longest-word (max longest-word (- i last-pos))
last-pos (+ i sep-length)
sep (cdr sep) rows (1+ rows))
end
finally (return
(progn
(setf numrows (max rows numrows))
(if (< last-pos (length line))
(append words (list (substring line last-pos)))
words))))
into lines
collect longest-word into word-lengths
do (unless (eobp) (forward-char))
finally
(loop initially (delete-region begin end)
for i from 0 to numrows do
(loop for line on lines
for cell-length in word-lengths do
(if (caar line)
(let ((insertion (caar line)))
(insert insertion
(make-string
(- cell-length (length insertion) -1) ?\ ))
(rplaca line (cdar line)))
(insert (make-string (1+ cell-length) ?\ ))))
(insert "\n"))))))
也许使用 fromcsv-mode
实际上会更好,但无论如何你都可以尝试这个:)
它是如何工作的:如果您将其称为M-xtranspose-table
,那么它将假定表格列由单个空格分隔,但是,如果您使用数字参数调用它(例如,M-3M-xtranspose-table
,那么它将提示您收集 3 个列分隔符。您也可以将其称为,并在被要求提供额外分隔符时C-uC-uM-xtranspose-table
选择不提供所有 16 个分隔符。RET
我找不到正确的数字功能的序数打印......所以,对不起“1'th”和“2'th”英文:)