Pass around non-title fields as a plist.
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Sun, 30 Jul 2017 12:51:42 +0000 (14:51 +0200)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Sun, 30 Jul 2017 12:51:42 +0000 (14:51 +0200)
pelican-mode.el

index df0503f..e0f5223 100644 (file)
 
 ;;; Code:
 
 
 ;;; Code:
 
+(require 'seq)
 (require 'subr-x)
 
 (require 'subr-x)
 
+
 (defun pelican-timestamp (&optional time)
   "Generate a Pelican-compatible timestamp for TIME."
   (format-time-string "%Y-%m-%d %H:%M" time))
 
 (defun pelican-timestamp (&optional time)
   "Generate a Pelican-compatible timestamp for TIME."
   (format-time-string "%Y-%m-%d %H:%M" time))
 
-(defun pelican-is-markdown ()
-  "Check if the buffer is likely using Markdown."
-  (derived-mode-p 'markdown-mode))
-
 (defun pelican-field (name value)
 (defun pelican-field (name value)
-  "Format a line for a field NAME with a VALUE."
+  "Format a line for a field NAME with a VALUE.
+
+NAME may be a string or a symbol; if it is a symbol, the
+symbol name is used (removing a leading ':' if present).
+
+VALUE may be any value; except for the following special values,
+the unquoted printed representation of it is used:
+
+- `now' means the current time; see `pelican-timestamp'.
+
+- `slug' means the file's path relative to the document root sans
+  extension; see `pelican-default-slug'.
+
+- nil means return an empty string, without any name or value."
+  (setq value (pcase value
+                ('now (pelican-timestamp))
+                ('slug (pelican-default-slug))
+                (_ value)))
+  (when (symbolp name)
+    (setq name (string-remove-prefix ":" (symbol-name name))))
   (if value
       (cond ((derived-mode-p 'markdown-mode)
              (format "%s: %s\n" (capitalize name) value))
   (if value
       (cond ((derived-mode-p 'markdown-mode)
              (format "%s: %s\n" (capitalize name) value))
          (pelican-rst-title title))
         (t (error "Unsupported major mode %S" major-mode))))
 
          (pelican-rst-title title))
         (t (error "Unsupported major mode %S" major-mode))))
 
-(defun pelican-header (title date status category tags slug)
-  "Create a Pelican header."
-  ;; TODO: Use a property list (-> alist via seq-partition) instead.
-  (when (eq date t)
-    (setq date (pelican-timestamp)))
-  
+(defun pelican-header (title &rest fields)
+  "Generate a Pelican header for a post with a TITLE and metadata FIELDS."
   (concat (pelican-title title)
   (concat (pelican-title title)
-          (pelican-field "date" date)
-          (pelican-field "status" status)
-          (pelican-field "tags" tags)
-          (pelican-field "category" category)
-          (pelican-field "slug" slug)
+          (mapconcat (apply-partially #'apply #'pelican-field)
+                     (seq-partition fields 2) "")
           "\n"))
 
           "\n"))
 
+(defun pelican-insert-header (title &rest fields)
+  "Insert a Pelican header for a post with a TITLE and metadata FIELDS."
+  (save-excursion
+    (goto-char 0)
+    (insert (apply #'pelican-header (cons title fields)))))
+
 (defun pelican-insert-draft-post-header (title tags)
 (defun pelican-insert-draft-post-header (title tags)
-  "Insert a Pelican header for a draft post."
+  "Insert a Pelican header for a draft with a TITLE and TAGS."
   (interactive "sPost title: \nsTags: ")
   (interactive "sPost title: \nsTags: ")
-  (let ((slug (pelican-default-slug)))
-    (save-excursion
-      (goto-char 0)
-      (insert (pelican-header title 't "draft" nil tags slug)))))
-
-(defun pelican-insert-page-header (title hidden)
-  "Insert a Pelican header for a page."
+  (save-excursion
+    (goto-char 0)
+    (insert (pelican-header title
+                            :date 'now
+                            :status "draft"
+                            :tags tags
+                            :slug 'slug))))
+
+(defun pelican-insert-page-header (title &optional hidden)
+  "Insert a Pelican header for a page with a TITLE, potentially HIDDEN."
   (interactive
    (list (read-string "Page title: ")
          (y-or-n-p "Hidden? ")))
   (interactive
    (list (read-string "Page title: ")
          (y-or-n-p "Hidden? ")))
-  (let ((slug (pelican-default-slug))
-        (hidden (if hidden "hidden" nil)))
-    (save-excursion
-      (goto-char 0)
-      (insert (pelican-header title nil hidden nil nil slug)))))
+  (save-excursion
+    (goto-char 0)
+    (insert (pelican-header title
+                            :status (when hidden "hidden")
+                            :slug 'slug))))
 
 
-(defun pelican-insert-header ()
+(defun pelican-insert-auto-header ()
   "Insert a Pelican header for a page or post."
   (interactive)
   (call-interactively (if (pelican-is-page)
   "Insert a Pelican header for a page or post."
   (interactive)
   (call-interactively (if (pelican-is-page)
 (defun pelican-set-title (title)
   "Set the title to TITLE."
   (interactive "sTitle: ")
 (defun pelican-set-title (title)
   "Set the title to TITLE."
   (interactive "sTitle: ")
-  (if (pelican-is-markdown)
+  (if (derived-mode-p 'markdown-mode)
       (pelican-set-field "title" title)
     (save-excursion
       (goto-char 0)
       (pelican-set-field "title" title)
     (save-excursion
       (goto-char 0)
 (defconst pelican-keymap (make-sparse-keymap)
   "The default keymap used in Pelican mode.")
 (define-key pelican-keymap (kbd "C-c P n")
 (defconst pelican-keymap (make-sparse-keymap)
   "The default keymap used in Pelican mode.")
 (define-key pelican-keymap (kbd "C-c P n")
-  'pelican-insert-header)
+  'pelican-insert-auto-header)
 (define-key pelican-keymap (kbd "C-c P p")
   'pelican-publish-draft)
 (define-key pelican-keymap (kbd "C-c P t")
 (define-key pelican-keymap (kbd "C-c P p")
   'pelican-publish-draft)
 (define-key pelican-keymap (kbd "C-c P t")