怎么粘贴文字到 org table 的新列?

假设有个表格:

| abc | def | ghi |
|-----+-----+-----|
|   4 |   5 |   8 |
| 333 |   2 |   1 |

另外有三行文字:

abc 
aaa
bbb 2

想把这三行加到表右边的新列内,像这样:

| abc | def | ghi | abc   |
|-----+-----+-----+-------|
|   4 |   5 |   8 | aaa   |
| 333 |   2 |   1 | bbb 2 |

两种情况,一种这三行文字在同一个 buffer 内,试过用选择三行 rectangular region copy & yank, 不过不会跳过水平线:

| abc | def | ghi | abc    |
|-----+-----+-----+-aaa  --|
|   4 |   5 |   8 | bbb 2  |
| 333 |   2 |   1 |   |

也试过选择文字 org-table-copy-region,接着org-table-paste-rectangle,不过提示First cut/copy a region to paste!

还有一种就是文字是从别的地方复制过来的,这种情况应该怎么处理呢?

  1. abc 后添加一空行;
  2. C-x SPC (rectangle-mark-mode) 下复制 M-w (kill-ring-save) 或剪切 C-w (kill-region) 这四行;
  3. 移动光标到表格第一行的末尾粘贴 C-y (yank);
  4. <tab> (org-cycle) 格式化这个表格。

注:第 3 步的结果是:

| abc | def | ghi |abc  
|-----+-----+-----|     
|   4 |   5 |   8 |aaa  
| 333 |   2 |   1 |bbb 2

代码

  (defun yank-to-table-base (killed transform)
    "Paste the text transformed from last killed into the table in Org-mode."
    (when (and (eq major-mode 'org-mode)
               (org-at-table-p)) 
      (if (and killed (not (org-at-table-hline-p)))
          (progn (setq org-table-clip
                       (mapcar #'list (funcall transform killed)))
                 ;; in the right side of the table
                 (when (looking-at "[ \t]*$")
                   (org-table-insert-column))                  
                 (org-table-paste-rectangle)
                 t)
        (user-error "At table hline or empty killed!"))))

  (defun yank-to-table ()
    "Paste the last killed text into the current table in Org-mode."
    (interactive)
    (yank-to-table-base (current-kill 0)
                        #'(lambda (text)
                            (split-string text "\n"))))

  (defun yank-rectangle-to-table ()
    "Paste the last killed rectangle text into the current table in Org-mode."
    (interactive)
    (yank-to-table-base killed-rectangle #'identity))

说明

光标在 表格单元格内 或者 右侧空白处 (如第一行最后) 且 水平分隔线的行 (如整个第二行 |-----+-- ), 插入 killed 内容并对齐,但在表格左侧空白处不能插入。

效果如下,I 表示光标

| abc | def | ghi |I   | abc | def | ghi | abc   |
|-----+-----+-----| => |-----+-----+-----+-------|
|   4 |   5 |   8 |    |   4 |   5 |   8 | aaa   |
| 333 |   2 |   1 |    | 333 |   2 |   1 | bbb 2 |

| abc | def | ghi |    | abc | def | ghi   |
|-----+-----+-----|    |-----+-----+-------|
|   4 |   5 | I 8 | => |   4 |   5 | abc   |
| 333 |   2 |   1 |    | 333 |   2 | aaa   |
                       |     |     | bbb 2 |

yank-to-table 对应普通的 kill-yank 操作,先把 killed 内容以行分割,再插入到表格中。

yank-rectangle-to-table 对应 kill-rectangleyank-rectangle 操作。

对于 yank-rectangle-to-table, 使用 (advice-add 'yank-rectangle :before-until #'yank-rectangle-to-table) 可以直接调用 yank-rectangle (不完全)“统一” 了表格内外的矩形粘贴。

但对于 yank-to-table ,由于文本分割和一些额外的判断会导致排版混乱,还是应该绑定该命令到新的按键。

一些改进

对于 yank-rectangle-to-table 上面提到的 advice-add 导致的问题有

复制某几列添加到最右侧

由于 --- 的出现会使表格变乱,如下所示:

| abc | def | ghi |I   | abc | def | ghi | abc |
|-----+-----+-----|    |-----+-----+-----+-----|
|   4 |   5 |   8 | => |   4 |   5 |   8 | --- |
| 333 |   2 |   1 |    | 333 |   2 |   1 |   4 |
                       |     |     |     | 333 |

解决方法:使用 org-copy-specialorg-table-copy-region 代替 copy-rectangle-as-kill, 用 org-paste-specialorg-table-paste-rectangle 代替 yank-rectangle

添加代码

(advice-add 'org-table-paste-rectangle
         :before #'(lambda ()
                     (when (and (not (org-at-table-hline-p))
                                (looking-at "[ \t]*$"))
                       (org-table-insert-column))))

并修改原来的 yank-to-table-base

(defun yank-to-table-base (killed transform)
  "Paste the text transformed from last killed into the table in Org-mode."
  (when (and (eq major-mode 'org-mode)
             (org-at-table-p)) 
    (if (and killed (not (org-at-table-hline-p)))
        (progn (setq org-table-clip
                     (mapcar #'list (funcall transform killed)))
               (org-table-paste-rectangle)
               t)
      (user-error "At table hline or empty killed!"))))

复制某几列到最右侧(不合并)类似于 ASCII 方式显示

这个功能在原版的 yank-rectangle 是可以用的。 advice-add yank-rectangle 之后,由于 --- 的出现会使表格变乱。 解决方法是使用注释或者代码块避免 (org-at-table-p) 为真,再使用 yank-rectangle

非表格环境下 org-table-paste-rectangle 会插入 |

解决方法:在 yank-to-table-base 函数中,把 (insert ?|) (backward-char) 改为 (org-table-insert-column)

存在的问题

好像没有发现能识别关于表格列格式(如列宽,列对齐和列分组)的函数和变量(类似于 org-at-table-hline-p),导致如下的表格用 org-table-paste-rectangle 时不能正确粘贴,只能手动调整了。

|  abc | def | ghi |I   |  abc | def | ghi | abc   |
|  <4> |     | <l> |	|  <4> |     | <l> | aaa   |
|------+-----+-----| =>	|------+-----+-----+-------|
|    4 |   5 | 8   |	|    4 |   5 | 8   | bbb 2 |
|  333 |   2 | 1   |	|  333 |   2 | 1   |       |
1 个赞