水平線で組織モードテーブルを並べ替える


7

org-mode次の形式のテーブルがあります。

| Name       | email           | number |
|------------+-----------------+--------|
| Doe, John  | jod@example.org |      7 |
| Doe, Jane  | jod@example.org |        |
|------------+-----------------+--------|
| Foo, Pete  | pf@example.com  |      5 |
|------------+-----------------+--------|
| Bar, Mary  | maba@127.0.0.1  |      3 |
| Quux, Mike | bz@192.168.12.1 |        |
|------------+-----------------+--------|

しかし、テーブルを次のようにフォーマットする必要があります。

| Name       | email           | number |
|------------+-----------------+--------|
| Bar, Mary  | maba@127.0.0.1  |      3 |
| Quux, Mike | bz@192.168.12.1 |        |
|------------+-----------------+--------|
| Doe, John  | jod@example.org |      7 |
| Doe, Jane  | jod@example.org |        |
|------------+-----------------+--------|
| Foo, Pete  | pf@example.com  |      5 |
|------------+-----------------+--------|

このテーブルはアルファベット順にソートする必要があります。したがって、最後の2行が最初になります。水平線との分離は維持されます。グループ化された列に異なる単語がある場合、それらがどのように並べ替えられるかは問題ではありません。表中の最後のグループ以上のように、いずれかのことができますBarが続くBazBazが続きますBar。Emacsでこれを行うにはどうすればよいorg-modeですか?


1
次のように、テーブルの外観の例を追加する必要があります。
Luke Shimkus、2014年

2
ソートのルールがよくわかりません。各セクション内の最初の列だけで並べ替えてから、各セクションの最初の行の「名前」列に基づいてセクションを並べ替えますか?
rekado 2014年

回答:


4

残念ながら、org-mode変更を実行してテーブルに直接反映するために使用できるデータ構造を保持していません。そのため、行をリストにまとめ、リスト処理を実行し、結果のリストを変換して戻す必要があります。テキスト。

一般的なアプローチはこれです:

  • の情報からグループサイズを計算しorg-table-hlinesます。この変数は、水平線の行番号を保持します
  • 各グループに関連する行をリストに格納し、各グループをリストに入れる

    '(("| Doe, John...|" "| Doe, Jane...|")
      ("| Foo, Pete...|")
      ("| Bar, Mary...|" "| Quux, Mike...|"))
    
  • このリストcarを各項目のの値でソートして、次のようなものを取得します。

    '(("| Bar, Mary...|" "| Quux, Mike...|")
      ("| Doe, John...|" "| Doe, Jane...|")
      ("| Foo, Pete...|"))
    
  • 次に、各グループを反復して、このリストからテーブルを再構築します

編集:

ここから始めましょう。どちらかと言えば厄介ですが、アイデアを説明するためだけのものです。(rows-by-group実際には重複が含まれているため、これは完全には正しくありません。)

(defun my-org-sort-lines ()
  (interactive)
  (org-table-recalculate 'iterate)
  (let* ((hlines org-table-hlines)
         (rows-by-group (let* ((xs (cdr (append hlines nil)))
                               (xs2 (mapcar #'1+ xs))
                               (ys (mapcar #'1- (cdr (copy-sequence xs)))))
                          (mapcar* #'list (setcdr (last xs2) xs2) ys)))
         ;; fetch rows and store as nested list
         (groups (mapcar (lambda (group)
                           (mapcar (lambda (row-id)
                                     (goto-line row-id)
                                     (beginning-of-line)
                                     (let ((beg (point)))
                                       (end-of-line)
                                       (buffer-substring beg (point))))
                                   group))
                           rows-by-group))
         ;; sort groups by first row
         (sorted (sort groups (lambda (a b)
                                (string-lessp (car a) (car b))))))

    ;; remove existing table rows and rebuild from group list
    (goto-char (org-table-begin))
    (next-line 1)
    (kill-region (point) (org-table-end))
    (mapcar (lambda (group)
              (insert "|---")(org-table-recalculate)(next-line)
              (mapcar (lambda (row)
                        (insert row)(newline)) group))
            sorted))
  (insert "|---")
  (org-table-recalculate))

面白い。プログラムでテーブルを変更する方法について考えてきました。これは素晴らしいスタートです。
2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.