1. Phil Hargett
  2. hh-web-tags

Commits

Phil Hargett  committed 58ba9c6

More documentation refinements, and fixed bug where tags inlined in a string could not use {} around attributes.

  • Participants
  • Parent commits d683f93
  • Branches default

Comments (0)

Files changed (5)

File README

View file
 for generating HTML, CSS, and Javascript in a modular fashion, making reuse of content across pages 
 much easier.
 
-See LICENSE for applicable licensing information
+See LICENSE for applicable licensing information.
+
+For documentation, load the package into your lisp (e.g, (require 'hh-web-tags) or (asdf:load-system 'hh-web-tags)), then
+invoke the following private function to generate documentation for HH-Web-Tags:
+
+  (hh-web-tags::generate-package-documentation)
+
+This should create a docs/ subdirectory inside the folder containing the package, and the index.html file there should
+be a starting point for understanding the library.
+
+Contact phil@haphazardhouse.net for any questions, comments, feedback, or contributions.
+
+Thanks!

File doctaglibraries/docs.lisp

View file
 (+tag-library :html)
 (+tag-library :script)
 
+(defun is-macro-p (symbol)
+  (macro-function symbol))
+
+(defun is-function-p (symbol)
+  (and (handler-case (symbol-function symbol) 
+	  (undefined-function () nil))
+       (not (is-macro-p symbol))))
+
+(defun is-variable-p (symbol)
+  (and (not (is-macro-p symbol))
+       (not (is-function-p symbol))
+       (equal #\* (elt (symbol-name symbol) 0))))
+
+(defun is-other-symbol-p (symbol)
+  (and (not (is-macro-p symbol))
+       (not (is-function-p symbol))
+       (not (is-variable-p symbol))))
+
+(defhtmltag package-reference
+    :content (em "hh-web-tags"))
+
+(defhtmltag symbol-reference
+    :attributes ((sym :initarg :sym)
+		 (type :initarg :type))
+    :content (with-slots (sym type) *current-tag*
+	       (let* ((name (string-downcase (symbol-name sym)))
+		      (anchor (format nil "_~a_~a" type name)))
+		 (a {:href anchor} (strong {:style "font-family:monospace" } 
+					   name)))))
+
+(defhtmltag package-symbol
+    :attributes ((sym :initarg :sym)
+		 (type :initarg :type))
+    :content (with-slots (sym type) *current-tag*
+	       (let* ((name (string-downcase (symbol-name sym)))
+		     (anchor (format nil "_~a_~a" type name)))
+		 (a {:name anchor} (strong {:style "font-family:monospace" } 
+			    name)))))
+
+(defhtmltag literal
+    :content (hunchentoot:escape-for-html (with-slots (_body) *current-tag* 
+					     (html _body))))
+
+(defhtmltag sidebar
+    :noendtag t)
+
 (defhtmltag macro-docs
-    :content "Macro documentation will go here")
+    :content (loop for sym being the external-symbols of :hh-web-tags
+		  when (is-macro-p sym)
+		  collect (list (p
+				   (package-symbol {:sym sym :type "macro" }))
+			       (p (documentation sym 'function)))))
 
 (defhtmltag function-docs
-    :content "Function documentation will go here")
-
-(defhtmltag generic-function-docs
-    :content "Generic function documentation will go here")
+    :content (loop for sym being the external-symbols of :hh-web-tags
+		when (is-function-p sym) 
+		collect (list (p (package-symbol {:sym sym :type "function" }))
+			      (p (documentation sym 'function)))))
 
 (defhtmltag variable-docs
-    :content "Variable documentation will go here")
+    :content (loop for sym being the external-symbols of :hh-web-tags
+		when (is-variable-p sym) 
+		collect (list (p (package-symbol { :sym sym :type "variable"} ))
+			      (p (documentation sym 'variable)))))
+
+(defhtmltag other-docs
+    :content (loop for sym being the external-symbols of :hh-web-tags
+		when (is-other-symbol-p sym) 
+		collect (list (p (let* ((name (string-downcase (symbol-name sym))))
+				   (strong {:style "font-family:monospace" } name))))))

File doctemplates/doc_index.lisp

View file
 (page 
  (+title "Documentation for hh-web-tags")
  (h1 "Overview")
- (p "Countless libraries exist to generate HTML, and so does " (em "hh-web-tags") ". But the latter generates not only HTML but CSS, 
+ (p "Countless libraries exist to generate HTML, and so does $(package-reference). But the latter generates not only HTML but CSS, 
      Javascript, and even some page metadata. And it generates it all in a modular fashion.")
- (p "A fundamental insight differentiates " (em "hh-web-tags") " from other such libraries: in Lisp terms, most libraries regard
+ (p "A fundamental insight differentiates $(package-reference) from other such libraries: in Lisp terms, most libraries regard
     HTML generation as a function with a single return value (the HTML).  Instead, hh-web-tags regards content generation
-    as a function returning multiple values" +mdash+ "a not unusual situation in Lisp, but uncommon (or unnatural) in
+    as a function returning multiple values $+mdash+ a not unusual situation in Lisp, but uncommon (or unnatural) in
     other languages.")
+ (p "Specifically, the central HTML generation facility of $(package-reference) (the $(html:a { :href \"#_macro_html\"} \"html\") macro) returns many values, of which the first is the HTML but also several
+  other values, some of which are fragments for inclusion in the final containing HTML document:")
+ (ul 
+  (li "Generated HTML content")
+  (li "Title for the containing document")
+  (li "Links to appear in the HEAD element of the containing document")
+  (li "Style sheets required by the tag")
+  (li "CSS style information required by the tag")
+  (li "References to script libraries required by the tag")
+  (li "Javascript fragments required by the tag")
+  (li "Scripts to run when the containing document is loaded in the browser for performing initialization requried by the tag"))
+ (p "In typical documents, tags contain other tags (e.g., $(code (literal (div (p \"text\")))), a paragraph tag inside a div tag).  Each of the values returned by 
+     the $(html:a { :href \"#_macro_html\"} \"html\") macro are always a proper aggregation of any corresponding values from tags inside the outer tag's body.  Thus,
+     if an interior tag references a script library, then now the outer tag will, too.  Same for any scripts produced by interior tags: now the outer tag will 
+     produce that script among it's scripts as well.")
+ (h2 "Example")
  (p "For example, imagine another language (such as ColdFusion, or JSP) that defined a custom tag to create a sidebar navigation element
      on a page:")
- (code +lt+ "sidebar/" +gt+)
- (p "In these other languages, that sidebar might result in a few divs added to a page:")
- (pre +lt+ "div id='sidebar'" +gt+ "
-  " +lt+ "div id='home_navigation_link'" +gt+ "
-"     "  " +lt+ "/div" +gt+ "
-"     "  " +lt+ "div id='products_navigation_link'" +gt+"
-"     "  " +lt+ "/div" +gt+ "
-"     "  " +lt+ "div id='services_navigation_link'" +gt+ "
-"     "  " +lt+ "/div" +gt+ "
-"     "  " +lt+ "div id='news_navigation_link'" +gt+ "
-"     "  " +lt+ "/div" +gt+ "
-"     "  " +lt+ "div id='contact_navigation_link'" +gt+ "
-"      "  " +lt+ "/div" +gt+ "
-"     +lt+ "/div" +gt+)
+ (code (literal (sidebar)))
+ (p "In these other languages, that sidebar custom tag might result in a few divs added to a page:")
+ (pre (literal (div {:id "sidebar"}
+		     (div {:id "home_navigation_link" :class "navigation_link"} "Home")
+		     (div {:id "products_navigation_link" :class "navigation_link"} "Products")
+		     (div {:id "services_navigation_link" :class "navigation_link"} "Services")
+		     (div {:id "news_navigation_link" :class "navigation_link"} "News")
+		     (div {:id "contact_navigation_link" :class "navigation_link"}  "Contact Us"))))
+ (p "With $(package-reference), the result includes not only the above HTML, but also the CSS:")
+ (pre "
+  .navigation_link {
+    color : black;    
+  }
 
+  .navigation_link:hover {
+    color : silver;
+  }
+
+  .navigation_link.selected {
+    color : white;
+    background-color : silver;
+  }
+  ")
+ (p "And the Javascript:")
+ (pre "
+   $$('.file-tree-files span').click(function(evt){
+         $$('.navigation_link.selected').toggleClass('selected');
+         $$(this).toggleClass('selected');
+         return false;        
+   });
+  ")
+ (p "Oh, and since this specific example uses jQuery, $(package-reference) also generates a reference to jQuery:")
+ (pre (literal (script {:src "/scripts/jquery/jquery-1.4.1.js"})))
  (h1 "Reference")
  (h2 "Macros")
  (macro-docs)
  (h2 "Functions")
  (function-docs)
- (h2 "Generic Functions")
- (generic-function-docs)
  (h2 "Variables")
- (variable-docs))
+ (variable-docs)
+ (h2 "Other")
+ (other-docs))

File taglibraries/html.lisp

View file
 		 (frameborder :initform nil :initarg :frameborder)
 		 (allowtransparency :initform nil :initarg :allowtransparency)
 		 (width :initform nil :initarg :width)
-		 (height :initform nil :initarg :height)))
+		 (height :initform nil :initarg :height)))
+
+(defhtmltag script
+    :attributes ((type :initform "text/javascript" :initarg :type)
+		 (src :initform nil :initarg :src)))

File tags.lisp

View file
   "Macro to simplify writing out html to correct stream"
   `(format *html-out* ,format-string ,@args))
 
+;; -------------
+;; tag reader
+
+(defun set-tag-reader ()
+  (set-macro-character #\{
+		     (lambda (str char)
+		       (declare (ignore char))
+		       (let
+			   ((*readtable* (copy-readtable *readtable* nil))
+			    (keep-going t))
+			 (set-macro-character #\} (lambda (stream char)
+						    (declare (ignore char) (ignore stream))
+						    (setf keep-going nil)))
+			 (let
+			     ((attributes (loop for key = (read str nil nil t)
+					while keep-going
+					for value = (read str nil nil t)
+					collect key
+					collect value)))
+			   `(+@ ,@attributes))))))
+
+(defmacro with-tag-reader ( () &rest body)
+  `(let ((*readtable* (copy-readtable *readtable* nil)))
+    (set-tag-reader)
+    ,@body))
+
 ;;;------------------------------------------------------------------------------------
 ;;; Dynamic variables
 ;;;------------------------------------------------------------------------------------
 	       do (cond ((and (equal c #\$)
 			      (peek-char nil is nil nil)
 			      (not (equal #\$ (peek-char nil is nil nil))))
-			 (format os "~a " (eval `(html ,(read is nil nil)))))
+			 (format os "~a " (eval `(html ,(with-tag-reader () (read is nil nil))))))
 			((and (equal c #\$)
 			      (equal #\$ (peek-char nil is nil nil)))
 			 (read-char is nil nil)
 		   (hout "</html>~%"))
 		 "text/html")
 	 (values nil nil))))
-
-;; -------------
-;; tag reader
-
-(defun set-tag-reader ()
-  (set-macro-character #\{
-		     (lambda (str char)
-		       (declare (ignore char))
-		       (let
-			   ((*readtable* (copy-readtable *readtable* nil))
-			    (keep-going t))
-			 (set-macro-character #\} (lambda (stream char)
-						    (declare (ignore char) (ignore stream))
-						    (setf keep-going nil)))
-			 (let
-			     ((attributes (loop for key = (read str nil nil t)
-					while keep-going
-					for value = (read str nil nil t)
-					collect key
-					collect value)))
-			   `(+@ ,@attributes))))))
-
-(defmacro with-tag-reader ( () &rest body)
-  `(let ((*readtable* (copy-readtable *readtable* nil)))
-    (set-tag-reader)
-    ,@body))