If you read in the blocker and separator as symbols, you can make them work like this. (Feel like this code is rather clumsy though.)
Code: Select all
(defun apply-separators (tree separator blocker)
(let (here out sublist)
(flet ((add-here ()
(if sublist
(push (reverse here) out)
(setf out (append here out)))
(setf sublist nil)
(setf here nil)))
(dolist (el tree)
(cond
((eql el separator)
(setf sublist t)
(push (reverse here) out)
(setf here nil))
((eql el blocker)
(add-here))
(t
(push (if (listp el)
(apply-separators el separator blocker)el)
here))))
(unless (null here)
(add-here))
(reverse out))))
Code: Select all
(apply-separators '(1 2 3 s (4 5 s 6 7 b 1 2) 4 6 s 4 9 1 b 1 2 3 4 5 b 1 4 s 5 5) 's 'b) -> ((1 2 3) ((4 5) (6 7) 1 2) (4 6) (4 9) 1 2 3 4 (1 4) (5 5))
Code: Select all
<defmethod apply-separators> (tree list ; separator symbol ; blocker symbol)
(let (here out sublist)
(flet ((add-here () |
if sublist
(push (reverse here) out)
(setf out (append here out));
setf sublist nil;
setf here nil;))
(dolist (el tree)
(cond
(eql el separator;
setf sublist t;
push (reverse here) out;
setf here nil;)
(eql el blocker;
add-here;)
(t
push (if (listp el)
(apply-separators el separator blocker) el)
here;)))
(unless | null here;
add-here;)
(reverse out)))
</defmethod apply-separators>
It does cut down on a look of hooks. Although newbies are often scared of hooks, it might be a good idea to let them use the hooks because if they don't, they might not realize properly(or as fast) that there are lists in there.