Factor out parse-metadata in preparation for real error-handling.

This commit is contained in:
Brit Butler 2014-09-03 14:34:53 -04:00
parent 2bd647207a
commit 2ed12c5bce
2 changed files with 20 additions and 16 deletions

View file

@ -248,7 +248,7 @@ at best, especially for anyone not coming from the lisp world.
We need to start handling errors and reporting errors in ways
that are useful to the user. Example errors users have encountered:
1. Loading of Content. If `read-content` fails to parse a file, wen
1. Loading of Content. If `read-content` fails to parse a file, we
should tell the user what file failed and why. We also should
probably enforce more constraints about metadata. E.g. Empty
metadata is not allowed/meaningful. Trailing space after separator, etc.

View file

@ -48,27 +48,31 @@
(when (stringp tags)
(setf tags (mapcar #'make-tag (cl-ppcre:split "," tags))))))
(defun parse-metadata (stream)
"Given a STREAM, parse metadata from it or signal an appropriate condition."
(flet ((parse-field (str)
(nth-value 1 (cl-ppcre:scan-to-strings "[a-zA-Z]+:\\s+(.*)" str)))
(field-name (line)
(make-keyword (string-upcase (subseq line 0 (position #\: line))))))
(unless (string= (read-line stream nil) (separator *config*))
(error "The provided file lacks the expected header."))
(loop for line = (read-line stream nil)
until (string= line (separator *config*))
appending (list (field-name line)
(aref (parse-field line) 0)))))
(defun read-content (file)
"Returns a plist of metadata from FILE with :text holding the content as a string."
"Returns a plist of metadata from FILE with :text holding the content."
(flet ((slurp-remainder (stream)
(let ((seq (make-string (- (file-length stream)
(file-position stream)))))
(read-sequence seq stream)
(remove #\Nul seq)))
(parse-field (str)
(nth-value 1 (cl-ppcre:scan-to-strings "[a-zA-Z]+:\\s+(.*)" str)))
(field-name (line)
(make-keyword (string-upcase (subseq line 0 (position #\: line))))))
(remove #\Nul seq))))
(with-open-file (in file :external-format '(:utf-8))
(unless (string= (read-line in) (separator *config*))
(error "The provided file lacks the expected header."))
(let ((meta (loop for line = (read-line in nil)
until (string= line (separator *config*))
appending (list (field-name line)
(aref (parse-field line) 0))))
(filepath (enough-namestring file (repo *config*)))
(content (slurp-remainder in)))
(append meta (list :text content :file filepath))))))
(let ((metadata (parse-metadata in))
(content (slurp-remainder in))
(filepath (enough-namestring file (repo *config*))))
(append metadata (list :text content :file filepath))))))
;; Helper Functions