28

我喜欢用 Markdown 写东西,经常发现自己需要表格。在 Emacs中编辑 Markdown 的管道表有什么好的方法吗?我指的是这种语法:

| Header | Header | Right |
|--------|--------|------:|
|  Cell  |  Cell  |  $10  |
|  Cell  |  Cell  |  $20  |

我首先尝试了 Emacs 的表格模式,它很好,但它是为 Markdown 不支持的“网格表格”而设计的(比如说在 Github 的 Markdown 中)。

还有org-mode 的 table 模式可以用作次要模式。这非常接近;但是交叉点现在被+字符替换,并且不支持对齐冒号。所以org-tblmode首先给我这样的东西:

| Header | Header | Right |
|--------+--------+-------|
| Cell   | Cell   | $10   |
| Cell   | Cell   | $20   |

然后我需要手动编辑以下内容(编辑交叉字符并添加对齐冒号):

| Header | Header | Right |
|--------|--------|------:|
| Cell   | Cell   | $10   |
| Cell   | Cell   | $20   |

是否有一些可能也org-tblmode可以处理这个问题?您还使用/建议在 Emacs 中编辑 Markdown 的管道表吗?

4

7 回答 7

11

OrgMode 具有很好的功能orgtbl-to-generic,可以将 orgmode 的表格转换为外来格式。我找到了基于以下定义自定义转换器的简单示例orgtbl-to-generichttps ://gist.github.com/yryozo/5807243 。另请参阅此处对 ORGTBL RECEIVE/SEND 功能的说明:http: //dynamic-thinking.blogspot.ru/2009/11/orgtbl-mode.html。您需要orgtbl-to-gfm在 Emacs 中定义自定义函数并将其放置到您的自动加载中,然后您可以使用次要模式orgtbl-mode来编辑表格。

小限制:仅支持左右列对齐,因为 Emacs OrgMode inside self 不支持中心对齐。

请参阅上面的示例 org-mode 源代码:

<!---
#+ORGTBL: SEND sample orgtbl-to-gfm
| Column 1      | Column 2 |
|---------------+----------|
|               | <l>      |
| Sample line 1 | 100      |
| Sample line 2 | 200      |
-->

并且从 org-mode 源转换为 markdown 的结果:

<!--- BEGIN RECEIVE ORGTBL sample -->
| Column 1 | Column 2 |
|---|---|
| Sample line 1 | 100 |
| Sample line 2 | 200 |
<!--- END RECEIVE ORGTBL sample -->

它们都放在同一个文件中。

于 2014-01-03T20:54:50.930 回答
8

这就是我用来处理降价模式下的表格的方法。可能有点hack,但对我来说效果很好。它将一个本地钩子添加到一个降价缓冲区,在保存时,将整个缓冲区中的“-+-”替换为“-|-”。

(require 'org-table)

(defun cleanup-org-tables ()
  (save-excursion
    (goto-char (point-min))
    (while (search-forward "-+-" nil t) (replace-match "-|-"))
    ))

(add-hook 'markdown-mode-hook 'orgtbl-mode)
(add-hook 'markdown-mode-hook
          (lambda()
            (add-hook 'after-save-hook 'cleanup-org-tables  nil 'make-it-local)))
于 2014-10-10T10:49:35.130 回答
4

将该函数绑定到一个键以实现区域的右对齐转换:

(defun markdown-regexp-right (beg end)
  (interactive "r")
  (replace-regexp "-\|[^-]" "-:|\n" nil beg end)    
  (replace-regexp "-\\+-" "-|-" nil beg end)
)

这将在右对齐情况下替换-+--|-和替换-|为。:|

请注意, \n 被包括在内,因为这样可以确保另一个-|-不会更改为-:|,但只有-|在它后面跟着 a 时才可以new-line

于 2013-01-11T14:54:02.207 回答
3

Org-mode 非常接近,我相信这是它的次要模式 orgtbl 的一种情况,它可以使用任意语法进行转换。因此,包含 :-、-: 或 :-: 的行将删除其冒号,并添加第二行<l>,<c><r>添加以通知 org-mode 对齐方式。那么翻译回来应该不会太难。遗憾的是,我现在还不够擅长 Emacs 来编写它。顺便说一句,pandoc 的降价解析器确实接受由 org-mode 生成的 +。

多看几眼后,我相信 org-mode 中的现有钩子需要在文本周围有点杂乱无章,并且一些编辑功能是有序的。由于这是我第一次尝试使用 emacs lisp,我的emacs lisp 在 orgtbl 和 markdown 之间进行转换简直是可怕的,但我已经设法转换了一个测试表。

于 2013-09-02T13:44:18.397 回答
2

markdown-modemarkdown-do命令(绑定到C-c C-d)。当点在表格中时,它会填充所有列,以便它们对齐。

https://github.com/jrblevin/markdown-mode#usage

于 2021-09-19T19:45:08.370 回答
1

我也遇到了这个确切的问题(我是最近的 emacs 转换),我编写了一个小 AWK 脚本,可以将您提到的“网格表”(即使用 org-mode 表)转换为 GFM 表。

有几种方法可以使用这个脚本。您所要做的就是标记表格,然后输入C-u M-| name-of-awk-script RET(我从这个 Stackoverflow 线程中学到了这个技巧)。这将使用该区域作为 AWK 脚本的标准输入,并用输出替换该区域。我非常不擅长编写 ELisp,但我也编写了几个辅助函数。该table-gfm-export函数当前不会以与交互方式替换文本相同的方式替换文本C-u M-|,因为它仍将原始表留在缓冲区中。

(defun table-gfm-capture (start end)
  "convert Markdown table to Emacs table
there should be no pipes beginning or ending the line,
although this is valid syntax. Loses justification."
  (interactive "r")
  ;; should prompt user for justification
  (table-capture start end "|"
         "[\n][:|-]*" 'center))

(defun table-gfm-export (start end)
  "uses AWK script to convert Emacs table to
GFM Markdown table"
  (interactive "r")
  ;; replace gfm_table_format if necessary
  (shell-command-on-region start end "gfm_table_format" t t)
  (table-unrecognize))

这个脚本的一个优点是它还可以使用一些简单的正则表达式来识别列的对齐方式。其他功能table-gfm-capture,无法保持对齐,所以不能自由来回切换。该系统非常适合在表格模式下进行所有编辑,然后在最后导出到 GFM。你会认为 Emacs 已经能够使用 生成 Markdown 表table-generate-source,但是,唉。

#!/usr/bin/env awk -f
# -*- mode: awk -*-

BEGIN {
    FS="|";
    first=1;
}

function detect_justification(f) {
    if (match(f, /^ .* $/)) {
        return 0;               # center-justified
    } else if (match(f, / $/)) {
        return -1;              # left-justified
    } else { return 1; }        # right-justified
}

function gen_field(len, just) {
    str = sprintf("%*s", len, "");
    gsub(/ /, "-", str);
    if (just <= 0) {
        # left or center, start with :
        sub(/-/, ":", str);
    }
    if (just >= 0) {
        # right or center, end with :
        sub(/-$/, ":", str);
    }
    return str;
}

function gen_rule() {
    str = "";
    # ignore first and last empty fields
    for (i=1; i < NF; i++) {
        len = length($i);
        just = detect_justification($i);
        str = sprintf("%s%s|", str, gen_field(len, just));
    }
    return str;
}

function sanitize_line(line) {
    # strip outer pipes and trailing whitespace
    if (index(line, "|") == 1) {
        line = substr(line, 2);
    }
    sub(/[ |]*$/, "", line);
    return line;
}

! /^\+/ {
    print(sanitize_line($0));
    if (first) {
        print(sanitize_line(gen_rule()));
        first = 0;
    }
}
于 2016-12-05T06:02:43.933 回答
0

Markdown-mode包为 GitHub 风格的 Markdown 提供表格支持。

Markdown-mode 是 Spacemacs 的一部分(可能还有其他社区配置)。请注意,如果在 Spacemacs 中使用 markdown 和 org 层,orgtbl 将劫持一些键绑定,即使用 org 语法的 TAB 和格式表。禁用 orgtbl-mode 删除了 orgtbl 劫持。

于 2022-01-03T13:21:41.103 回答