lQuery Syntax Macro (v3)

Shinmera Jun 23rd, 2013 88 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (defmacro $ (&rest actions)
  2.   "The main lQuery function to select and manipulate the DOM. The base syntax is as follows:
  3.   ($ \"selector\" (function args*)*)
  4.   Strings will evaluate to selectors and always act on the current set of elements.
  5.   Function pointers will be called with the current set of elements passed to the function.
  6.   A single element or a list replaces the current set of elements.
  7.   An inline list represents a function call, although nodefun- and lquery functions take precedence.
  8.   ($ (serialize)) evaluates (basically) to (nodefun-serialize working-nodes). However, if the named
  9.   function is not a nodefun, packages are searched for a matching symbol in the following order:
  10.   lquery, *PACKAGE*, cl. If the function cannot be found in any of those, it is silently dropped."
  11.   `(let ((working-nodes (list *LQUERY-MASTER-DOCUMENT*)))
  12.      (progn
  13.        ,@(loop for action in actions collect
  14.               `(setf working-nodes
  15.                      ;Apparently function pointers are lists during macro expansion time so we need to catch that case.
  16.                      ,(if (and (listp action) (not (eq (first action) 'FUNCTION)))
  17.                           (let ((first (car action)))
  18.                             (cond ((dom:node-p first) action)
  19.                                   ((find-symbol (mkstr 'nodefun- first) :lquery)
  20.                                    `(,(find-symbol (mkstr 'nodefun- first) :lquery)
  21.                                       working-nodes
  22.                                       ,@(cdr action)))
  23.                                   (T (loop with name = (mkstr first)
  24.                                         for package in (list :lquery *PACKAGE* :cl)
  25.                                         for symbol = (find-symbol name package)
  26.                                         if symbol
  27.                                         do (return `(,symbol ,@(cdr action)))))))
  28.                           `($-helper ,action :working-nodes working-nodes)))))
  30.      working-nodes))
  32. (defgeneric $-helper (action &key &allow-other-keys)
  33.   (:documentation "Helper function to determine what to do with a given variable at execution of the $ statement."))
  34. (defmethod $-helper (action &key)
  35.   action)
  36. (defmethod $-helper ((action function) &key working-nodes)
  37.   (funcall action working-nodes))
  38. (defmethod $-helper ((action string) &key working-nodes)
  39.   (css:query action working-nodes))
  40. (defmethod $-helper ((action dom:node) &key)
  41.   (list action))
RAW Paste Data