;;; -*- mode: Lisp; Syntax: Common-Lisp; -*- ;;; ;;; Copyright (c) 2009 by the authors. ;;; ;;; See LICENCE for details. (in-package :hu.dwim.presentation) ;;;;;; ;;; t/lisp-form/inspector (def refresh-component t/lisp-form/inspector (bind (((:slots source-objects line-count component-value) -self-) (source-text:*source-readtable* (make-source-readtable))) (setf source-objects (with-input-from-string (stream component-value) (iter (for element = (source-text:source-read stream #f stream #f #t)) (until (eq element stream)) (collect element) (until (typep element 'source-text:source-lexical-error)))) line-count (+ (count #\Newline component-value) (if (char= #\Newline (last-elt component-value)) 0 1))))) (def function make-source-readtable () ;; TODO: use the original readtable (at least derive from it) (prog1-bind readtable (source-text::make-source-readtable) (source-text::enable-sharp-boolean-syntax readtable) (source-text::enable-shebang-syntax readtable))) ;;;;;; ;;; Render lisp form ;; TODO: some factoring could make this code shorter {with-quasi-quoted-xml-to-binary-emitting-form-syntax/preserve-whitespace (def layered-methods render-source-object (:method :in xhtml-layer ((instance source-text:source-token)) ) (:method :in xhtml-layer ((instance source-text:source-whitespace)) ) (:method :in xhtml-layer ((instance source-text:source-semicolon-comment)) ) (:method :in xhtml-layer ((instance source-text:source-boolean)) ) (:method :in xhtml-layer ((instance source-text:source-number)) ) (:method :in xhtml-layer ((instance source-text:source-character)) ) (:method :in xhtml-layer ((instance source-text:source-string)) ) (:method ((instance source-text:source-symbol)) (render-source-symbol (source-text:source-symbol-value instance) instance)) (:method :in xhtml-layer ((instance source-text:source-function)) (render-source-object (source-text:source-object-subform instance))) (:method :in xhtml-layer ((instance source-text:source-quote)) (render-source-object (source-text:source-object-subform instance))) (:method :in xhtml-layer ((instance source-text:source-backquote)) (render-source-object (source-text:source-object-subform instance))) (:method :in xhtml-layer ((instance source-text:source-unquote)) (render-source-object (source-text:source-object-subform instance))) (:method :in xhtml-layer ((instance source-text:source-splice)) (render-source-object (source-text:source-object-subform instance))) (:method :in xhtml-layer ((instance source-text:source-feature)) (render-source-object (source-text:source-object-subform instance))) (:method :in xhtml-layer ((instance source-text:source-not-feature)) (render-source-object (source-text:source-object-subform instance))) (:method :in xhtml-layer ((instance source-text:source-read-eval)) (render-source-object (source-text:source-object-subform instance))) (:method :in xhtml-layer ((instance source-text:source-bit-vector)) ) (:method :in xhtml-layer ((instance source-text:source-pathname)) (render-source-object (source-text:source-object-subform instance))) (:method ((instance source-text:source-list)) (render-source-list (first (source-text:source-sequence-elements instance)) instance)) (:method :in xhtml-layer ((instance source-text:source-vector)) ) (:method ((instance source-text:source-lexical-error)) (render-source-object-text instance)))} {with-quasi-quoted-xml-to-binary-emitting-form-syntax/preserve-whitespace (def layered-function render-source-list (first instance) (:method :in xhtml-layer (first (instance source-text:source-list)) ) (:method ((first source-text:source-symbol) (instance source-text:source-list)) (render-source-list (source-text:source-symbol-value first) instance)) (:method :in xhtml-layer ((first (eql 'def)) (instance source-text:source-list)) (bind ((elements (source-text:source-sequence-elements instance))) ,(render-source-object (pop elements)) ,(render-source-object (pop elements)) ,(foreach #'render-source-object elements) ")">)))} {with-quasi-quoted-xml-to-binary-emitting-form-syntax/preserve-whitespace (def layered-function render-source-symbol (value instance) (:method :in xhtml-layer (value (instance source-text:source-symbol)) (bind ((id (generate-unique-string)) (style-class (string+ (cond ((keywordp value) "keyword ") ((member value '(&optional &rest &allow-other-keys &key &aux &whole &body &environment)) "lambda-list-keyword ") ((member value '(if let let* progn prog1 block return-from tagbody go throw catch flet labels)) "special-form ") ((eq (symbol-package value) #.(find-package :common-lisp)) "common-lisp ") (t nil)) "symbol"))) (awhen (ignore-errors (symbol-function value)) (render-tooltip (make-action (make-component-rendering-response (tooltip/widget () (etypecase it (standard-generic-function (make-instance 'standard-method-sequence/lisp-form-list/inspector :component-value (generic-function-methods it))) (function (make-instance 'function/lisp-form/inspector :component-value it)))))) id)))))} (def function render-source-object-text (source-object) `xml,(source-text:source-object-text source-object))