Редактирование таблиц труб Markdown в Emacs
Мне нравится писать в Markdown и часто мне нужны таблицы. Есть ли хорошие способы редактирования Markdown таблиц труб в Emacs? Я имею в виду такой синтаксис:
| Header | Header | Right |
|--------|--------|------:|
| Cell | Cell | $10 |
| Cell | Cell | $20 |
Я сначала попробовал Emacs режим таблицы, который хорош, но предназначен для "таблиц сетки", которые не поддерживаются Markdown (скажем, в Github Markdown).
Существует также режим таблицы org-mode, который может использоваться как второстепенный режим. Это довольно близко; но пересечения теперь заменяются символами +
, и нет поддержки выравнивания двоеточия. Поэтому org-tblmode
сначала дает мне что-то вроде этого:
| Header | Header | Right |
|--------+--------+-------|
| Cell | Cell | $10 |
| Cell | Cell | $20 |
который затем мне нужно вручную отредактировать к следующему (редактирование символов пересечения и добавление выравнивания двоеточия):
| Header | Header | Right |
|--------|--------|------:|
| Cell | Cell | $10 |
| Cell | Cell | $20 |
Возможно, некоторые из них могут org-tblmode
справиться с этим?
Что еще вы используете/предлагаете для редактирования таблиц труб Markdown в Emacs?
Ответы
Ответ 1
OrgMode имеет приятную функцию orgtbl-to-generic
для преобразования таблиц orgmode в чужие форматы. Я нашел простой пример, определяющий пользовательский преобразователь на основе orgtbl-to-generic
: https://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 внутри self не поддерживает центральное выравнивание.
См. выше пример источника org-mode:
<!---
#+ORGTBL: SEND sample orgtbl-to-gfm
| Column 1 | Column 2 |
|---------------+----------|
| | <l> |
| Sample line 1 | 100 |
| Sample line 2 | 200 |
-->
И результат в уценке преобразован из источника org-mode:
<!--- BEGIN RECEIVE ORGTBL sample -->
| Column 1 | Column 2 |
|---|---|
| Sample line 1 | 100 |
| Sample line 2 | 200 |
<!--- END RECEIVE ORGTBL sample -->
Оба они помещены в один и тот же файл.
Ответ 2
Это то, что я использую для обработки таблиц в режиме уценки. Может быть
немного взломать, но работает достаточно хорошо для меня. Он добавляет локальный
зацепите буфер уценки, который при сохранении заменяет "- + -"
с "- | -" во всем буфере.
(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)))
Ответ 3
Привяжите функцию к ключу для выравненного по правому краю области:
(defun markdown-regexp-right (beg end)
(interactive "r")
(replace-regexp "-\|[^-]" "-:|\n" nil beg end)
(replace-regexp "-\\+-" "-|-" nil beg end)
)
Это заменит -+-
на -|-
и заменит -|
на :|
в случае правильного выравнивания.
Обратите внимание, что \n включено, потому что это гарантирует, что другой -|-
не будет изменен на -:|
, но только -|
, за которым следует new-line
.
Ответ 4
Org-mode настолько соблазнительно близок, что я считаю, что это случай для его второстепенного режима orgtbl с произвольным синтаксисом для преобразования. Строка, содержащая: -, -: или: -: удаляет ее двоеточия, а вторая строка с <l>
, <c>
и <r>
, чтобы сообщить орг-режиме выравнивания. Тогда перевод не должен быть слишком жестким. К сожалению, я недостаточно хорош в Emacs, чтобы написать его прямо сейчас. Кстати, парсекс-анализатор pandoc принимает + как сгенерированный org-mode.
Посмотрев немного больше на это, я считаю, что существующие крючки в org-mode требуют немного крутого вокруг текста, и некоторые функции редактирования в порядке. Поскольку это моя первая попытка emacs lisp, мой emacs lisp для преобразования между orgtbl и уценкой - не что иное, как ужас, но я удалось преобразовать тестовую таблицу.
Ответ 5
Я столкнулся с этой точной проблемой (я недавний конвертер emacs), и я написал немного AWK script, которые могут преобразовать "таблицы сетки", которые вы упомянули (т.е. не используете таблицы org-mode), в Таблицы GFM.
Есть несколько способов использования этого script. Все, что вам нужно сделать, это пометить таблицу, а затем ввести C-u M-| name-of-awk-script RET
(я узнал этот трюк из fooobar.com/info/98051/...). Это будет использовать область как stdin AWK script и заменить область на выход. Я очень люблю писать 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))
Одна из опций этой script заключается в том, что она также может распознавать обоснование столбцов с помощью простых простых выражений. Другая функция 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;
}
}