For any problems with this package, please e-mail rlpowell@digitalkingdom.org Overview ======== SPath is a library for running search queries against s-expressions, intended to match parts of them that the user needs. It is inspired by s-query and loosely by XPath; not that it has the full expressive power of XPath, but some of the stylistic choices and ideas were taken from there. In particular, SPath finds all instances of a match in the same sort of way as XPath. The goal of SPath, like s-query, was to provide a means to easily dig around in XML structures, but unlike s-query I tried to do it in a fashion agnostic to the XML generation system in question. I also consider it of general utility, because I get sick of writing nests of list operations. It was created by Robin Lee Powell, and is in the public domain. Laziness ======== SPath uses Heresy (http://www.cliki.net/Heresy), a moderately obscure lazy list library. This shouldn't be something you notice, unless you decide to use a function as return type specifier, in which case it does need to accept lazy lists. However, it means that :first will do near to the minimum amount of work, which is nice. Operation ========= At any given step, a list of lists is being processed. New operations either trim the list (i.e. keep only those things that match) or modify every list, or both (in particular, modification commands always drop every list that can't be modified as requested). Usage ===== (spath [return-specifier] [list-of-lists] [command]...) Return Specifiers ================= :none Do nothing, which means you're going to get back Heresy-based lazy lists. :lists Return a normal list of lists. :first Return the first thing that matches all the commands. #'[some-function] Runs the function lazily against each value matched by all the commands. Commands ======== dig --- Digs into the list structure, find any instance of the following element, and returning that item and the rest if the list at that level of nesting. find ---- Like dig, but only works on the current top level. In other words, it's like member, but returns all matches. next ---- Runs "cdr" on every list. item ---- Runs "car" on every list. #'[anything] ------------ Runs the function against every top-level item in every list. Only those elements that match are kept (again, with tails as usual, as per find and dig). Examples ======== For comprehensive examples, see tests.lisp. Example 1 --------- (spath :lists '( (a (b 1) (c 1)) (b 3) (b a q (c 1)) ) find b) Returns: '( (b 3) (b a q (c 1)) ) Example 2 --------- (spath :lists '( (a (x 1) (c 1)) (x 3) (x a q (c 1)) ) find b) Returns nil. Example 3 --------- (spath :lists '( (a (x 1) (c 1)) (b 3) (b a q (c 1)) ) find b next item) Returns: '( 3 a ) Note that the use of "item" is the only way that anything other than a list of lists can get returned by spath. Example 4 --------- (spath :lists '( (a (b c 1 (d 8) (b 3) (e 2))) ) dig c next next item next item) Returns: '( 8 ) Example 5 --------- (spath :lists '( (a (b c 1 (d 1) (e 2))) ) dig b #'listp) Returns: '( (D 1) (E 2) )