org-mode table 转置

org-mode table 中度用户,时不时会遇到需要进行 table 转置的场景。

没找到现成的,自己 elisp 撸了一个。好玩。

(defun mhb-org-mode--help-transpose-org-table-region ()
  "把 region (org table) pivot 转置"
  (interactive)
  (let* ((region (buffer-substring-no-properties (region-beginning) (region-end)))
	 (region (string-replace "\n" "" region))
	 (region (replace-regexp-in-string "[ \t]+" "" region))
	 ;; index of all occurences of "|"
	 (idxs (cl-loop for c across region
			for idx from 0
			when (string= (char-to-string c) "|") 
			collect idx))
	 ;; 换行时两个 "|" 相邻,删除首个
	 (idxs (cl-loop for c in idxs
			for idx from 0
			when (and (< (+ 1 idx) (length idxs)) (> (nth (+ 1 idx) idxs) (+ 1 (nth idx idxs))))
			collect (nth idx idxs)))
	 (idxs (append idxs (list (length region))))
	 ;; 计算行数
	 (nRs (count-matches "\n" (region-beginning) (region-end)))
	 ;; 计算列数
	 (nCs (let* ((ntmp (count-matches "|" (region-beginning) (region-end))))
		(- (/ ntmp nRs) 1))))
    (message (format "%s rows, %s columns" nRs nCs))
    ;; 逐列遍历,打印成行
    (cl-loop for cidx from 0 to (- nCs 1)
	     do (progn
		  (message (format "column %s" cidx))
		  (insert "\n|")
		  (cl-loop for ridx from 0 to (- nRs 1)
			   do (let* ((beg (nth (+ (* ridx nCs) cidx) idxs))
				     (end (nth (+ 1 (* ridx nCs) cidx) idxs)))
				;; (message (format "row %s" ridx))
				(if (and beg end)
				    (progn
				      (message (substring region beg end))
				      (insert (string-replace "|" "" (substring region beg end)))
				      (insert "|")))))))))

效果: output

1 个赞

可以试试 org-table-transpose-table-at-point

1 个赞

你是对的。谢谢你的信息。 :grinning: