miniblog

Miniblog: A command-line static blog system in Common Lisp
Log | Files | Refs | README | LICENSE

edit.lisp (2216B)


      1 (in-package :miniblog.edit)
      2 
      3 (defparameter *default-text-template*
      4 "Untitled post
      5 
      6 Text goes here"
      7 "Default template for a post")
      8 
      9 (defparameter *default-editor*
     10               "/usr/bin/vi"
     11               "Default editor, used as ultimate fallback if no other
     12               choice is available")
     13 
     14 (defun get-default-template ()
     15   *default-text-template*)
     16 
     17 (defun get-default-editor ()
     18   (or (getenv "EDITOR") *default-editor*))
     19 
     20 (defun edit-file (filename editor)
     21   "Run the specified editor against the given filename. Throws an error
     22    if the editor can't be launched."
     23   (run-program (list editor filename)
     24                :input :interactive
     25                :output :interactive))
     26 
     27 (defun edit-text (&key template editor)
     28   "Hand over text to the user to be edited in an external text editor,
     29    optionally taking a template and the path to the editor to be
     30    executed, otherwise providing a default template and either the
     31    user's EDITOR or some attempt at a reasonable default, respectively.
     32    Returns the edited text or nil if the user made no changes."
     33   (let* ((input-content (or template (get-default-template)))
     34          (fname
     35            (with-output-to-temporary-file (tempfile)
     36              (write-string input-content tempfile))))
     37     (edit-file (namestring fname) (or editor (get-default-editor)))
     38     (let ((edited-content
     39             (with-open-file (stream fname)
     40               (let ((contents (make-string (file-length stream))))
     41                 (read-sequence contents stream)
     42                 (delete-file stream)
     43                 contents))))
     44       (if (not (string= input-content edited-content))
     45         edited-content))))
     46 
     47 (defun get-title-and-content (text)
     48   "Extract the title and content from a post. Assumption is that if the
     49    text has a first line, then a bare second line, then more content,
     50    the first line is the title (git-ish semantics) otherwise the entire
     51    content is the body and the title is empty"
     52   (let* ((lines (lines text))
     53          (first-line (trim (nth 0 lines)))
     54          (second-line (trim (nth 1 lines)))
     55          (rest (nthcdr 2 lines)))
     56     (if (and first-line rest (string= second-line ""))
     57       (list (car lines) (unlines rest))
     58       (list () text))))