我使用emacs日记。
当我在日记文件中附加未来计划和每日评论时, 文件中的条目导致不遵循时间顺序。
当我在某些场合查看日记文件时,我希望对这些条目进行排序。 是否有任何命令或lisp可用于修改日记文件,以便条目按时间顺序排序?
答案 0 :(得分:2)
很久以前,我给自己写了一个排序函数:
(defun diary-sort-diary-keyfun nil
"Key function to order diary entries.
Entries sort in the groups: (days, anniversaries, cyclics, blocks, dates), with any unrecognised
forms before the groups.
Within each group, entries are in ascending date order.
You can prefix entries with `#' to comment them out without affecting sort order.
Prefixing with `&' also does not affect sort order."
(let ((number "\\s-+\\([0-9]+\\)")
(months '("Dec" "Nov" "Oct" "Sep" "Aug" "Jul" "Jun" "May" "Apr" "Mar" "Feb" "Jan"))
(days '("Saturday" "Friday" "Thursday" "Wednesday" "Tuesday" "Monday" "Sunday")))
(skip-chars-forward "#&")
(cond
((looking-at (concat "%%(diary-block" number number number number number number ")\\(.*\\)"))
(format "50%04d%02d%02d%04d%02d%02d%s"
(string-to-number (match-string 3))
(string-to-number (match-string 2)) (string-to-number (match-string 1))
(string-to-number (match-string 6))
(string-to-number (match-string 5)) (string-to-number (match-string 4))
(match-string 7)))
((looking-at (concat "%%(diary-cyclic" number number number number ")\\(.*\\)"))
(format "40%04d%02d%02d%05d%s"
(string-to-number (match-string 4))
(string-to-number (match-string 3)) (string-to-number (match-string 2))
(string-to-number (match-string 1))
(match-string 5)))
((looking-at (concat "%%(diary-anniversary" number number number ")\\(.*\\)"))
(format "30%04d%02d%02d%s"
(string-to-number (match-string 3))
(string-to-number (match-string 2)) (string-to-number (match-string 1))
(match-string 4)))
((looking-at "%%(\\(.*\\)") ; after all othe "%%()" rules
(format "20(%s" (match-string 1)))
((looking-at (concat "\\(" (mapconcat 'identity days "\\|") "\\)"
"\\( *[0-2 ][0-9]:[0-9][0-9]\\)?\\(.*\\)"))
(format "10%d%6s%s"
(length (member (match-string 1) days))
(or (match-string 2) "")
(match-string 3)))
((looking-at (concat "\\([0-9]+\\)\\s-+" "\\(" (mapconcat 'identity months "\\|") "\\)"
number "\\s-+\\([0-2 ][0-9]:[0-9][0-9]\\)?\\(.*\\)"))
(format "60%04d%02d%02d%6s%s"
(string-to-number (match-string 3))
(length (member (match-string 2) months))
(string-to-number (match-string 1))
(or (match-string 4) "")
(match-string 5)))
((looking-at (concat "\\(" (mapconcat 'identity months "\\|") "\\)"
number "," number "\\( *[0-2 ][0-9]:[0-9][0-9]\\)?\\(.*\\)"))
(format "60%04d%02d%02d%6s%s"
(string-to-number (match-string 3))
(length (member (match-string 1) months))
(string-to-number (match-string 2))
(or (match-string 4) "")
(match-string 5)))
((looking-at "[ \t\r]*$") ; blank line
(concat "99" (match-string 0)))
((looking-at ".*") ; last rule
(concat "00" (match-string 0))))))
(defun diary-sort-diary-file nil
"Sort the diary entries.
See `diary-sort-diary-keyfun' for the collation sequence."
(interactive "*")
;; sort-order:
;; randoms, days, anniversaries, cyclics, blocks, dates
(goto-char (point-min))
(let* ((locals-start (and (re-search-forward "\\(\n.*\\)Local variables:\\(.*\n\\)" nil t)
(match-beginning 0)))
(locals-end (and locals-start
(search-forward (concat (match-string 1) "End:" (match-string 2)) nil t)
(match-end 0)))
(locals (and locals-start locals-end
(buffer-substring-no-properties locals-start locals-end))))
(when locals
(delete-region locals-start locals-end))
(and (> (point-max) 1)
(/= (char-after (1- (point-max))) ?\n)
(goto-char (point-max))
(insert ?\n))
(goto-char (point-min))
(sort-subr nil 'forward-line 'end-of-line 'diary-sort-diary-keyfun)
(goto-char (point-max))
(insert "\n")
(delete-blank-lines)
(when locals
(insert locals))))
我可能已经假定欧洲日期订单,但如果您更喜欢不同的订单,那么应该不难对其进行调整。
它的工作方式是keyfun返回一个字符串,该字符串以条目类型的两位数开头(00
表示未知数,10
表示星期几条目,最多{{1对于非重复日期),后跟条目的大端表示,如ISO 8601。
交互式函数60
然后使用此密钥。它会保存任何diary-sort-diary-file
部分,并在文件末尾恢复它(当您从Local variables
插入条目时,这很好,因为它们会被追加)。如果您有任何calendar
行(对于Ispell),那么您可以使用类似的代码来保持完整,或者您可以调整keyfun以将它们放在最后。
样本结果(有些审查):
LocalWords
Xxxxxxx
&Sep 12
Xxxxxxx
&Monday 21:00
Xxxxxxx
#&Thursday
Xxxxxxx
%%(diary-float t 0 2)
Xxxxxxx
%%(diary-float t 6 1)
&%%(diary-phases-of-moon)
Xxxxxxx
&%%(diary-anniversary 26 6 1952)
Xxxxxxx
%%(diary-anniversary 1 6 1972)
Xxxxxxx
&%%(diary-anniversary 15 3 1975)
Xxxxxxx
&%%(diary-anniversary 7 2 1976)
国际星球大战日! :-)
%%(diary-anniversary 4 5 1977)
Xxxxxxx
&%%(diary-anniversary 13 8 1978)
Xxxxxxx
&%%(diary-anniversary 26 8 1980)
Xxxxxxx
&%%(diary-anniversary 16 10 1980)
Xxxxxxx
&%%(diary-anniversary 15 3 2010)
Xxxxxxx
&%%(diary-cyclic 1000 1 6 1972)
Xxxxxxx
&%%(diary-cyclic 1000 13 8 1978)
Xxxxxxx
&%%(diary-cyclic 1000 26 8 1980)
Xxxxxxx
%%(diary-cyclic 1000 9 9 2013)
Xxxxxxx
%%(diary-block 22 3 2013 24 3 2013)
Xxxxxxx
%%(diary-block 6 4 2013 7 4 2013)
Xxxxxxx
&%%(diary-block 20 4 2013 21 4 2013)
Xxxxxxx
%%(diary-block 27 4 2013 28 4 2013)
Xxxxxxx
%%(diary-block 18 5 2013 19 5 2013)
Xxxxxxx
%%(diary-block 1 6 2013 2 6 2013)
Xxxxxxx
%%(diary-block 1 6 2013 2 6 2013)
Xxxxxxx
%%(diary-block 15 6 2013 16 6 2013)
Xxxxxxx
%%(diary-block 22 6 2013 23 6 2013)
Xxxxxxx
%%(diary-block 22 6 2013 30 6 2013)
Xxxxxxx
%%(diary-block 6 7 2013 7 7 2013)
Xxxxxxx
%%(diary-block 20 7 2013 24 7 2013)
Xxxxxxx
%%(diary-block 9 8 2013 11 8 2013)
Xxxxxxx
%%(diary-block 23 4 2016 24 4 2016)
Xxxxxxx
%%(diary-block 13 8 2016 21 8 2016)
Xxxxxxx
%%(diary-block 26 8 2016 28 8 2016)
Xxxxxxx
22 Jun 2009 11:30
Xxxxxxx
30 Jun 2009 13:00
Xxxxxxx
&22 Jul 2009
Xxxxxxx
25 Jul 2009
Xxxxxxx
&14 Aug 2009 17:30
Xxxxxxx
&17 Aug 2009
Xxxxxxx
13 Mar 2010
Xxxxxxx
23 Mar 2010 10:50
Xxxxxxx
&17 Jan 2013 14:00
Xxxxxxx
1 Feb 2013
Xxxxxxx
&8 Feb 2013 16:00
Xxxxxxx
12 Feb 2013 18:30
Xxxxxxx
19 Feb 2013 18:00
Xxxxxxx
&12 Mar 2013 10:00
Xxxxxxx
16 Mar 2013
Xxxxxxx
&19 Mar 2013 13:50
Xxxxxxx
20 Mar 2016
Xxxxxxx
2 Apr 2016
Xxxxxxx
18 Jun 2016
Xxxxxxx
17 Jul 2016
Xxxxxxx
12 Nov 2016
Xxxxxxx
如果您希望整理日记文件,您可能也喜欢这些:
28 Mar 2017
答案 1 :(得分:1)
在 icalendar.el 中,使用 icalendar - datetime-to-iso-date ,更改"%d%s%d的格式%s%d" 到"%04d%s%02d%s%02d" 。
将其添加到初始化中:
(setq
diary-date-forms diary-iso-date-forms
calendar-date-style 'iso
)
将日记文件中的旧条目编辑为ISO标准,格式如上,即YYYY / MM / DD。 (ISO标准实际上是YYYY-MM-DD)。
现在进一步将其添加到初始化中:
(defun sort--diary (diary-filename)
(with-current-buffer
(set-buffer (find-file-noselect (expand-file-name diary-filename)))
(goto-char (point-min))
(while (search-forward "\C-j " nil t)
(replace-match "^j "))
(sort-lines nil (point-min) (point-max))
(goto-char (point-min))
(while (search-forward "^j" nil t)
(replace-match "\C-j"))
(save-buffer)))
(defvar sort--diary-filename (expand-file-name diary-file)
"History for sort--diary diary-filename")
(defun sort-diary (diary-filename)
"Sort diary file. Requires dates to use ISO standard"
(interactive (list (read-from-minibuffer
"diary file name: "
(car sort--diary-filename)
nil nil 'sort--diary-filename)))
(sort--diary diary-filename))
现在,您可以通过调用 sort-diary 来对日记进行排序。