Yesterday I wrote about Vivek Haldar’s Deft patch that allowed him to integrate his previous notes into Deft. Recall that Deft uses the first line of a note as its subject and names the file for a note deft-XXX
whereas Haldar used the filename to describe the subject of the note. After I published that post I thought that it might have been easier to simply convert the existing notes to Deft format by making the file name the first line of the note.
It turns out that it is pretty simple to do that. Let’s assume that the file names are something like /Users/jcs/notes/ideas-for-Hercules-project.txt
. We want to take the file name and convert it into a subject line by removing the directory information, removing the extension, changing the dashes to spaces and inserting the result as the first line of the file. Here’s a bit of Emacs Lisp that does that for one file:
(defun file-to-subject (filen) (let ((subject (replace-regexp-in-string "-" " " (file-name-sans-extension (file-name-nondirectory filen))))) (with-temp-buffer (insert-file-contents filen) (goto-char 1) (insert (concat subject "\n")) (write-file filen))))
The let
at the beginning of the function converts the file name to a subject line. Then the file is read into a temporary buffer and the subject line is inserted at the beginning of the buffer. Finally the new file is written over the old.
To process all the files in, say, the ~/notes
directory we could use the line
(mapc 'file-to-subject (directory-file "~/notes" nil "\\.txt$"))
or for more complicated directory structures we could use Dired
to mark the files we want to convert and then use 【w】 (bound to dired-copy-filename-as-kill
) to put the file names in the kill ring. Then we could just yank them right into the mapc
in place of the (directory-file "~/notes" nil "\\.txt$")
.
That leaves changing ideas-for-Hercules-project.txt
to deft-XXX
. That could be done in several ways, with or without Emacs, but if you want to do it in Emacs here’s what you need for one file
(defvar deft-num 0) (defun deft-name (filen) (rename-file filen (format "deft-%03d" (incf deft-num))))
The incf
function1 increments deft-num
and returns the incremented value so that the first time deft-name
is called the format
will return deft-001
and then deft-002
and so on.
You can do all the files with a mapc
similar to what we used above. Alternatively, we could place the call to deft-name
after the call to write-file
in the file-to-subject
function.
Footnotes:
1 incf
is part of the Common Lisp package so you’ll need a (require 'cl)
if you don’t already have it.