(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload '(:yason
:alexandria
:fwoar.lisputils)))
(defun group (break lis)
(loop with result = (list)
for (key . val) in lis
when (equal key break) do (push () result)
do (push (cons key val) (car result))
finally (return result)))
(defun group-by-first (lis)
(group (caar lis) lis))
(defun collect-pairs (reader)
(loop for line = (funcall reader *standard-input* nil)
while line
for parts = (fwoar.string-utils:split #\space line :count 2)
collect (fw.lu:vector-destructuring-bind (key val) parts
(cons key val))))
(let* ((lines '("TITLE foo" "URL bar" "TITLE baz" "URL qwer" nil))
(cur lines))
(defun reader (&rest r)
(declare (ignore r))
(when (null cur)
(setf cur lines))
(prog1 (car cur)
(setf cur (cdr cur)))))
(defun main (&optional (reader 'read-line))
(yason:with-output (*standard-output* :indent t)
(yason:with-array ()
(apply 'yason:encode-array-elements
(mapcar 'alexandria:alist-hash-table
(group-by-first
(collect-pairs reader)))))))
(defun dump ()
(sb-ext:save-lisp-and-die "jsonifier" :toplevel 'main :executable t))
|