Function: todo-convert-legacy-files
todo-convert-legacy-files is an interactive and byte-compiled function
defined in todo-mode.el.gz.
Signature
(todo-convert-legacy-files)
Documentation
Convert legacy todo files to the current Todo mode format.
The old-style files named by the variables todo-file-do and
todo-file-done from the old package are converted to the new
format and saved (the latter as a todo archive file) with a new
name in todo-directory. See also the documentation string of
todo-legacy-date-time-regexp for further details.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/todo-mode.el.gz
(defun todo-convert-legacy-files ()
"Convert legacy todo files to the current Todo mode format.
The old-style files named by the variables `todo-file-do' and
`todo-file-done' from the old package are converted to the new
format and saved (the latter as a todo archive file) with a new
name in `todo-directory'. See also the documentation string of
`todo-legacy-date-time-regexp' for further details."
(interactive)
;; If there are user customizations of legacy options, use them,
;; otherwise use the legacy default values.
(let ((todo-file-do-tem (if (boundp 'todo-file-do)
todo-file-do
(locate-user-emacs-file "todo-do" ".todo-do")))
(todo-file-done-tem (if (boundp 'todo-file-done)
todo-file-done
(locate-user-emacs-file "todo-done" ".todo-done")))
(todo-initials-tem (and (boundp 'todo-initials) todo-initials))
(todo-entry-prefix-function-tem (and (boundp 'todo-entry-prefix-function)
todo-entry-prefix-function))
todo-prefix-tem)
;; Convert `todo-file-do'.
(if (not (file-exists-p todo-file-do-tem))
(message "No legacy todo file exists")
(let ((default "todo-do-conv")
file archive-sexp)
(with-temp-buffer
(insert-file-contents todo-file-do-tem)
;; Eliminate old-style local variables list in first line.
(delete-region (line-beginning-position) (1+ (line-end-position)))
(search-forward " --- " nil t) ; Legacy todo-category-beg.
(setq todo-prefix-tem (buffer-substring-no-properties
(line-beginning-position) (match-beginning 0)))
(goto-char (point-min))
(while (not (eobp))
(cond
;; Old-style category start delimiter.
((looking-at (regexp-quote (concat todo-prefix-tem " --- ")))
(replace-match todo-category-beg))
;; Old-style category end delimiter.
((looking-at (regexp-quote "--- End"))
(replace-match ""))
;; Old-style category separator.
((looking-at (regexp-quote
(concat todo-prefix-tem " "
(make-string 75 ?-))))
(replace-match todo-category-done))
;; Old-style item header (date/time/initials).
((looking-at (concat (regexp-quote todo-prefix-tem) " "
(if todo-entry-prefix-function-tem
(funcall todo-entry-prefix-function-tem)
(concat todo-legacy-date-time-regexp " "
(if todo-initials-tem
(regexp-quote todo-initials-tem)
"[^:]*")
":"))))
(todo-convert-legacy-date-time)))
(forward-line))
(setq file (concat todo-directory
(read-string (format-prompt "Save file as" default)
nil nil default)
".todo"))
(unless (file-exists-p todo-directory)
(make-directory todo-directory))
(write-region (point-min) (point-max) file nil 'nomessage nil t))
(with-temp-buffer
(insert-file-contents file)
(let ((todo-categories (todo-make-categories-list t)))
(todo-update-categories-sexp)
(todo-check-format))
(write-region (point-min) (point-max) file nil 'nomessage))
(setq todo-files (funcall todo-files-function))
;; Convert `todo-file-done'.
(when (file-exists-p todo-file-done-tem)
(with-temp-buffer
(insert-file-contents todo-file-done-tem)
(let ((beg (make-marker))
(end (make-marker))
cat cats comment item)
(while (not (eobp))
(when (looking-at todo-legacy-date-time-regexp)
(set-marker beg (point))
(todo-convert-legacy-date-time)
(set-marker end (point))
(goto-char beg)
(insert "[" todo-done-string)
(goto-char end)
(insert "]")
(forward-char)
(when (looking-at todo-legacy-date-time-regexp)
(todo-convert-legacy-date-time))
(when (looking-at (concat " " (if todo-initials-tem
(regexp-quote
todo-initials-tem)
"[^:]*")
":"))
(replace-match "")))
(if (re-search-forward
(concat "^" todo-legacy-date-time-regexp) nil t)
(goto-char (match-beginning 0))
(goto-char (point-max)))
(backward-char)
(when (looking-back "\\[\\([^][]+\\)\\]"
(line-beginning-position))
(setq cat (match-string 1))
(goto-char (match-beginning 0))
(replace-match ""))
;; If the item ends with a non-comment parenthesis not
;; followed by a period, we lose (but we inherit that
;; problem from the legacy code).
;; FIXME: fails on multiline comment
(when (looking-back "(\\(.*\\)) " (line-beginning-position))
(setq comment (match-string 1))
(replace-match "")
(insert "[" todo-comment-string ": " comment "]"))
(set-marker end (point))
(if (member cat cats)
;; If item is already in its category, leave it there.
(unless (save-excursion
(re-search-backward
(concat "^" (regexp-quote todo-category-beg)
"\\(.*\\)$")
nil t)
(string= (match-string 1) cat))
;; Else move it to its category.
(setq item (buffer-substring-no-properties beg end))
(delete-region beg (1+ end))
(set-marker beg (point))
(re-search-backward
(concat "^"
(regexp-quote (concat todo-category-beg cat))
"$")
nil t)
(forward-line)
(if (re-search-forward
(concat "^" (regexp-quote todo-category-beg)
"\\(.*\\)$")
nil t)
(progn (goto-char (match-beginning 0))
(newline)
(forward-line -1))
(goto-char (point-max)))
(insert item "\n")
(goto-char beg))
(push cat cats)
(goto-char beg)
(insert todo-category-beg cat "\n\n"
todo-category-done "\n"))
(forward-line))
(set-marker beg nil)
(set-marker end nil))
(setq file (concat (file-name-sans-extension file) ".toda"))
(write-region (point-min) (point-max) file nil 'nomessage nil t))
(with-temp-buffer
(insert-file-contents file)
(let* ((todo-categories (todo-make-categories-list t)))
(todo-update-categories-sexp)
(todo-check-format))
(write-region (point-min) (point-max) file nil 'nomessage)
(setq archive-sexp (read (buffer-substring-no-properties
(line-beginning-position)
(line-end-position)))))
(setq file (concat (file-name-sans-extension file) ".todo"))
;; Update categories sexp of converted todo file again, adding
;; counts of archived items.
(with-temp-buffer
(insert-file-contents file)
(let ((sexp (read (buffer-substring-no-properties
(line-beginning-position)
(line-end-position))))
(print-length nil)
(print-level nil))
(dolist (cat sexp)
(let ((archive-cat (assoc (car cat) archive-sexp)))
(if archive-cat
(aset (cdr cat) 3 (aref (cdr archive-cat) 2)))))
(delete-region (line-beginning-position) (line-end-position))
(prin1 sexp (current-buffer)))
(write-region (point-min) (point-max) file nil 'nomessage))
(setq todo-archives (funcall todo-files-function t)))
(todo-update-filelist-defcustoms)
(when (y-or-n-p (concat "Format conversion done; do you want to "
"visit the converted file now? "))
(setq todo-current-todo-file file)
(unless todo-default-todo-file
;; We just initialized the first todo file, so make it the
;; default now to avoid an infinite recursion with todo-show.
(setq todo-default-todo-file (todo-short-file-name file)))
(todo-show))))))