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))))