|
@@ -48,27 +48,31 @@
|
48
|
48
|
(when (stringp tags)
|
49
|
49
|
(setf tags (mapcar #'make-tag (cl-ppcre:split "," tags))))))
|
50
|
50
|
|
|
51
|
+(defun parse-metadata (stream)
|
|
52
|
+ "Given a STREAM, parse metadata from it or signal an appropriate condition."
|
|
53
|
+ (flet ((parse-field (str)
|
|
54
|
+ (nth-value 1 (cl-ppcre:scan-to-strings "[a-zA-Z]+:\\s+(.*)" str)))
|
|
55
|
+ (field-name (line)
|
|
56
|
+ (make-keyword (string-upcase (subseq line 0 (position #\: line))))))
|
|
57
|
+ (unless (string= (read-line stream nil) (separator *config*))
|
|
58
|
+ (error "The provided file lacks the expected header."))
|
|
59
|
+ (loop for line = (read-line stream nil)
|
|
60
|
+ until (string= line (separator *config*))
|
|
61
|
+ appending (list (field-name line)
|
|
62
|
+ (aref (parse-field line) 0)))))
|
|
63
|
+
|
51
|
64
|
(defun read-content (file)
|
52
|
|
- "Returns a plist of metadata from FILE with :text holding the content as a string."
|
|
65
|
+ "Returns a plist of metadata from FILE with :text holding the content."
|
53
|
66
|
(flet ((slurp-remainder (stream)
|
54
|
67
|
(let ((seq (make-string (- (file-length stream)
|
55
|
68
|
(file-position stream)))))
|
56
|
69
|
(read-sequence seq stream)
|
57
|
|
- (remove #\Nul seq)))
|
58
|
|
- (parse-field (str)
|
59
|
|
- (nth-value 1 (cl-ppcre:scan-to-strings "[a-zA-Z]+:\\s+(.*)" str)))
|
60
|
|
- (field-name (line)
|
61
|
|
- (make-keyword (string-upcase (subseq line 0 (position #\: line))))))
|
|
70
|
+ (remove #\Nul seq))))
|
62
|
71
|
(with-open-file (in file :external-format '(:utf-8))
|
63
|
|
- (unless (string= (read-line in) (separator *config*))
|
64
|
|
- (error "The provided file lacks the expected header."))
|
65
|
|
- (let ((meta (loop for line = (read-line in nil)
|
66
|
|
- until (string= line (separator *config*))
|
67
|
|
- appending (list (field-name line)
|
68
|
|
- (aref (parse-field line) 0))))
|
69
|
|
- (filepath (enough-namestring file (repo *config*)))
|
70
|
|
- (content (slurp-remainder in)))
|
71
|
|
- (append meta (list :text content :file filepath))))))
|
|
72
|
+ (let ((metadata (parse-metadata in))
|
|
73
|
+ (content (slurp-remainder in))
|
|
74
|
+ (filepath (enough-namestring file (repo *config*))))
|
|
75
|
+ (append metadata (list :text content :file filepath))))))
|
72
|
76
|
|
73
|
77
|
;; Helper Functions
|
74
|
78
|
|