在组织模式下对混合的标题列表进行排序 [英] Sort a mixed list of headings in org mode

查看:18
本文介绍了在组织模式下对混合的标题列表进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 org-mode 中有很长的标题列表:

I have a long list of headings in org-mode:

* Tasks [/]
** TODO Foo
** TODO Bar
** DONE World
** DONE Abba

我想按如下方式排序:

* Tasks [/]
** TODO Bar
** TODO Foo
** DONE Abba
** DONE World

使用 org-sort-entries 我可以得到

* Tasks [/]
** DONE Abba
** TODO Bar
** TODO Foo
** DONE World

(即字母顺序),或

* Tasks [/]
** TODO Foo
** TODO Bar
** DONE World
** DONE Abba

(即根据状态分组).

换句话说,我想按字母顺序对 TODODONE 项进行排序,但将它们放在两个块中.我怎么能做到呢?我想将整个标题集保留在同一个子树中!

In other words, I want to sort the TODO and the DONE items alphabetically, but keep them in two blocks. How could I achieve it? I want to keep the whole set of headings in the same subtree!

我没有设法利用以下建议.因此,我尝试使用下面提供的提示来提出我需要的解决方案.这是我的代码:

I didn't manage to utilize the suggestions below. So, I tried to use the tips provided below to come up with the solution I need. Here is the code I have:

(defun drorata-sort-TODO-DONE-headings ()
  (interactive)
  (save-excursion
    ;; Sort according to the TODO/DONE keywords
    (org-sort-entries t ?o)
    ;; Now there is a block of TODO's and a block of DONE's
    ;; Mark the TODO's
    (next-line)
    (beginning-of-line)
    (set-mark-command nil)
    (search-forward-regexp "[*].* DONE" nil t)
    (beginning-of-line)
    ;; Sort the marked region (of TODO's) alphabetically
    (org-sort-entries t ?a)
    ;; Now its time to sort the DONE's
    (search-forward "[*].* DONE" nil t)
    (beginning-of-line)
    (set-mark-command nil)
    ;; How can I find all headings labeled with DONE in the current level?
    )
)

我的想法是标记由 TODO 标记的标题并按字母顺序排序,然后对 DONE 标题执行相同操作.到目前为止,我只对 TODO 的 ...

My idea is to mark the headings that are labeled by TODO and sort them alphabetically and then do the same to the DONE headings. So far, I have it working only for the TODO's...

推荐答案

THE SHORT ANSWER

  • 第 1 步:将光标放在父级上.

第 2 步:M-x org-sort-entries RET a RET

第 3 步:M-x org-sort-entries RET o RET

第 4 步:打开您最喜欢的饮料,喝一杯.

STEP # 4:  Crack open your favorite beverage and have a drink.

冗长的答案

为了扩展@pmr 的答案(即对选定区域进行排序),您可能还希望考虑根据主标题来组织副标题.例如,我喜欢执行多重排序——首先按字母顺序,其次按待办事项顺序,第三个按优先级,第四个按时间.对于不包含截止日期且仅包含一种待办事项状态的副标题,仅按字母顺序排序就足以满足我的需求.下面列出了一个示例函数,我使用它对包含各种主标题和副标题的整个缓冲区进行排序.这是来自 org-sort-entries 的备忘单:

To expand upon the answer of @pmr (i.e., sorting a selected region), one may also wish to consider acting upon main headings to organize subheadings. For example, I like to perform a multi-sort -- first by alphabetic, second by todo-order, third by priority, and fourth by time. For subheadings that do not contain deadlines and contain only one type of todo status, it is sufficient for my needs to only sort by alphabetic. Set forth below is a sample function that I use to sort the entire buffer containing various main headings and subheadings. Here is the cheat-sheet from org-sort-entries:

Sort: [a]lpha  [n]umeric  [p]riority  p[r]operty  todo[o]rder  [f]unc
               [t]ime [s]cheduled  [d]eadline  [c]reated
               A/N/P/R/O/F/T/S/D/C means reversed.

<小时>

注意:org-sort-entries 在根据时间戳对条目进行排序时使用 current-time 如果条目不包含一个时间戳.使用 current-time 的结果是,当使用选项 t, c 排序时,未注明日期的条目将在包含时间戳的未来任务之前排序code>、sd.要对未注明日期的条目进行加权以便它们在注明日期的条目之后 排序,可以使用比 current-time 晚的日期.相关的 let-bound 变量定义为 (now (current-time)),它在函数中的用法写为 (org-float-time现在).这可以通过许多不同的方式来处理——例如,修改包含 (org-float-time now) 的代码,其中包含一个遥远的未来的人工日期——例如,(org-time-string-to-seconds "<2030-12-31 Tue>").


NOTE:  org-sort-entries uses the current-time when sorting entries based on time-stamp if the entry does not contain a time-stamp. The consequence of using the current-time is that undated entries will be sorted prior to future tasks containing time-stamps when sorting with the options t, c, s, or d. To weight the undated entries so that they are sorted after the dated entries, it is possible to use a later date than the current-time. The relevant let-bound variable is defined as (now (current-time)), and its usage within the function is written as (org-float-time now). This can be dealt with many different ways -- e.g., modifying the code containing (org-float-time now) with something containing an artificial date far off into the future -- e.g., (org-time-string-to-seconds "<2030-12-31 Tue>").

(defun lawlist-sort ()
  (when
      (save-excursion
        (goto-char (point-max))
        (re-search-backward "^\* CONTACTS" nil t)
        (re-search-forward  "^\*\* \(Planning\)" nil t))
    (goto-char (point-max))
    (re-search-backward "^\* CONTACTS" nil t)
    (org-sort-entries t ?a) )
  (when
      (save-excursion
        (goto-char (point-max))
        (re-search-backward "^\* DONE" nil t)
        (re-search-forward  "^\*\* \(None\)" nil t))
    (goto-char (point-max))
    (re-search-backward "^\* DONE" nil t)
    (org-sort-entries t ?a) )
  (when
      (save-excursion
        (goto-char (point-max))
        (re-search-backward "^\* UNDATED" nil t)
        (re-search-forward  "^\*\* \(Someday\)" nil t))
    (goto-char (point-max))
    (re-search-backward "^\* UNDATED" nil t)
    (org-sort-entries t ?a) )
  (when
      (save-excursion
        (goto-char (point-max))
        (re-search-backward "^\* EVENTS" nil t)
        (re-search-forward  "^\*\* \(Reference\|Delegated\|Postponed\|Waiting\)" nil t))
    (goto-char (point-max))
    (re-search-backward "^\* EVENTS" nil t)
    (org-sort-entries t ?a)
    (org-sort-entries t ?o)
    (org-sort-entries t ?p)
    (org-sort-entries t ?t) )
  (when
      (save-excursion
        (goto-char (point-max))
        (re-search-backward "^\* TASKS" nil t)
        (re-search-forward "^\*\* \(Active\|Next Action\|Hold\|Canceled\)" nil t))
    (goto-char (point-max))
    (re-search-backward "^\* TASKS" nil t)
    (org-sort-entries t ?a)
    (org-sort-entries t ?o)
    (org-sort-entries t ?p)
    (org-sort-entries t ?t) ) )

<小时>

以下示例说明了如何对包含主标题和副标题的整个缓冲区进行排序和重组.如果用户希望使用 org-toodledo 库与 Toodledo 服务器同步,这将特别有用:https://github.com/christopherjwhite/org-toodledo 要在重组包含数百个副标题的缓冲区时加快进程,用户可能希望考虑通过修改负责的函数来抑制消息——但是,这超出了本答案的范围.


Here is an example of how to sort and reorganize an entire buffer containing main headings and subheadings. This is especially useful if the user desires synchronization with the Toodledo server using the org-toodledo library: https://github.com/christopherjwhite/org-toodledo  To speed up the process when reorganizing a buffer containing hundreds of subheadings, the user may wish to consider suppressing the messages by modifying the functions responsible -- however, that is beyond the scope of this answer.

(setq org-todo-keywords '(
  (sequence
  "Active(a)"
  "Next Action(n)"
  "Canceled(c)"
  "Hold(h)"
  "Reference(r)"
  "Delegated(d)"
  "Waiting(w)"
  "Postponed(P)"
  "Someday(s)"
  "Planning(p)"
  "|"
  "None(N)") ))

(defun lawlist-reorganize ()
(interactive)
  (with-current-buffer (get-buffer "test.org")
    (setq buffer-read-only nil)
    (lawlist-refile-tasks)
    (lawlist-refile-events)
    (lawlist-refile-undated)
    (lawlist-refile-contacts)
    (lawlist-refile-done)
    (lawlist-sort)
    (goto-char (point-min))
    (save-buffer)
    (setq buffer-read-only t)))

(defun lawlist-refile-tasks ()
(interactive)
  (let* (
      (org-archive-location "/Users/HOME/Desktop/test.org::* TASKS")
      (org-archive-save-context-info nil))
    (goto-char (point-min))
    (unless (re-search-forward "^\* TASKS" nil t)
      (goto-char (point-max))
      (insert "* TASKS

"))
    (goto-char (point-max))
    (while
        (re-search-backward
          "^\*\* \(Active\|Next Action\|Hold\|Canceled\)" nil t)
      (org-archive-subtree))))

(defun lawlist-refile-events ()
  (let* (
      (org-archive-location "/Users/HOME/Desktop/test.org::* EVENTS")
      (org-archive-save-context-info nil))
    (goto-char (point-min))
    (unless (re-search-forward "^\* EVENTS" nil t)
      (goto-char (point-max))
      (insert "* EVENTS

"))
    (goto-char (point-max))
    (while
        (re-search-backward
          "^\*\* \(Reference\|Delegated\|Postponed\|Waiting\)" nil t)
      (org-archive-subtree))))

(defun lawlist-refile-undated ()
  (let* (
      (org-archive-location "/Users/HOME/Desktop/test.org::* UNDATED")
      (org-archive-save-context-info nil))
    (goto-char (point-min))
    (unless (re-search-forward "^\* UNDATED" nil t)
      (goto-char (point-max))
      (insert "* UNDATED

"))
    (goto-char (point-max))
    (while
        (re-search-backward
          "^\*\* \(Someday\)" nil t)
      (org-archive-subtree))))

(defun lawlist-refile-done ()
  (let* (
      (org-archive-location "/Users/HOME/Desktop/test.org::* DONE")
      (org-archive-save-context-info nil))
    (goto-char (point-min))
    (unless (re-search-forward "^\* DONE" nil t)
      (goto-char (point-max))
      (insert "* DONE

"))
    (goto-char (point-max))
    (while
        (re-search-backward
          "^\*\* \(None\)" nil t)
      (org-archive-subtree))))

(defun lawlist-refile-contacts ()
  (let* (
      (org-archive-location "/Users/HOME/Desktop/test.org::* CONTACTS")
      (org-archive-save-context-info nil))
    (goto-char (point-min))
    (unless (re-search-forward "^\* CONTACTS" nil t)
      (goto-char (point-max))
      (insert "* CONTACTS

"))
    (goto-char (point-max))
    (while
        (re-search-backward
          "^\*\* \(Planning\)" nil t)
      (org-archive-subtree))))

<小时>

这是一个示例清理函数,用于在条目之间放置适当的间距并删除缓冲区末尾的任何空行——正则表达式假定标题和副标题都向左对齐:


Here is a sample clean-up function to put proper spacing between entries and delete any empty lines at the end of the buffer -- the regexp assumes headings and subheadings are all flush-left:

(defun lawlist-cleanup ()
(interactive)
  (let ((query-replace-lazy-highlight nil))
    (replace-regexp "
+\*\* " "

** " nil (point-min) (point-max))
    (replace-regexp "
+\* " "


* " nil (point-min) (point-max))
    (goto-char (point-max))
    (delete-blank-lines)
    (let ((trailnewlines (abs (skip-chars-backward "
	"))))
      (if (> trailnewlines 0)
        (delete-char trailnewlines))) ))

<小时>

此解决方案不依赖于选择区域,而是根据每个主标题进行操作,并组织该主标题下的所有内容——即,组织所有子标题.此答案中的代码将通过在正确的主标题下重新排列条目来重新组合条目.例如——如果一个任务已经完成,完成的子标题将是 ** None -- 代码将查找所有带有 ** None 的子标题并将它们移动到* DONE 的主标题,然后按字母顺序排列.


This solution does not rely upon selecting regions, but instead acts upon each main heading and organizes everything under that main heading -- i.e., all subheadings are organized. The code in this answer will regroup entries by refiling them underneath the correct main heading. For example -- if a task has been completed, the completed subheading will be ** None -- the code will look for all subheadings with ** None and move them to the main heading of * DONE, and then sort them alphabetically.

主要标题为:* TASKS* 事件;* 某天;* 联系方式;* 完成.

The main headings are: * TASKS; * EVENTS; * SOMEDAY; * CONTACTS; * DONE.

选择以下副标题是因为它们是完成任务的一种方法,并且 Toodledo 服务器使用相同的方法:** Active** 下一步行动;** 保持;** 取消;** 参考;** 委托;** 推迟;** 等待;** 总有一天;** 规划;** 无.

The following subheadings were chosen because they are a method of Getting Things Done, and the Toodledo server uses this same methodology:  ** Active; ** Next Action; ** Hold; ** Canceled; ** Reference; ** Delegated; ** Postponed; ** Waiting; ** Someday; ** Planning; ** None.

* TASKS

  ** Active

  ** Next Action

  ** Hold

  ** Canceled

* EVENTS

  ** Reference

  ** Delegated

  ** Postponed

  ** Waiting

* SOMEDAY

  ** Someday

* CONTACTS

  ** Planning

* DONE

  ** None

这篇关于在组织模式下对混合的标题列表进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆