5
\$\begingroup\$

I wrote a simple emacs module that generates standard templates that I use for my blog's static site generator.

(defun hakyll-site-location ()
  "Return the location of the Hakyll files."
  "~/Sites/hblog/")

(defun hakyll-new-post (title tags)
  "Create a new Hakyll post for today with TITLE and TAGS."
  (interactive "sTitle: \nsTags: ")
  (let ((file-name (hakyll-post-title title)))
    (set-buffer (get-buffer-create file-name))
    (markdown-mode)
    (insert
     (format "---\ntitle: %s\ntags: %s\ndescription: \n---\n\n" title tags))
    (write-file
     (expand-file-name file-name (concat (hakyll-site-location) "posts")))
    (switch-to-buffer file-name)))

(defun hakyll-new-note (title)
  "Create a new Note with TITLE."
  (interactive "sTitle: ")
  (let ((file-name (hakyll-note-title title)))
    (set-buffer (get-buffer-create file-name))
    (markdown-mode)
    (insert (format "---\ntitle: %s\ndescription: \n---\n\n" title))
    (write-file
     (expand-file-name file-name (concat (hakyll-site-location) "notes")))
    (switch-to-buffer file-name)))

(defun hakyll-post-title (title)
  "Return a file name based on TITLE for the post."
  (concat
   (format-time-string "%Y-%m-%d")
   "-"
   (replace-regexp-in-string " " "-" (downcase title))
   ".markdown"))

(defun hakyll-note-title (title)
  "Return a file name based on TITLE for the note."
  (concat
   (replace-regexp-in-string " " "-" (downcase title))
   ".markdown"))

Now, this works, but it could do with DRYing up a little bit, but I don't know enough elisp to do it myself.

  • hakyll-new-post and hakyll-new-note are very similar and could do with DRYing up, but I'm not sure how to pass the correct parameter to any refactored function
  • I'm hard coding hakyll-site-location. Is there any way that I can request for and store a configuration in my emacs dotfiles?

Any help or pointers to documentation are welcome.

\$\endgroup\$
4
\$\begingroup\$

DRY-ing it up:

It looks like variation is in:

  • how the filename is obtained
  • the contents of the inserted text
  • the name of the file to write to.

Also note that if format is given extra arguments not needed by its format-spec that they are ignored.

So you could define a function which takes 3 arguments: the function to call to get the filename to read from, the file-name to write to, and a the format-spec string.

In order to pass a named function to a method you need to quote it as in the example:

(mapcar '1+ '(1 2 3))

If you want to pass an anonymous function to a function you defined it with #'(lambda ...). For example:

(mapcar #'(lambda (x) (1+ x)) '(1 2 3))

Making a configuration setting

I'd suggest changing your hakyll-site-location function into a variable. Use defvar to define it and then you can simply setq it in your emacs dotfiles.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.