Anonymous committed f62f7f4

Extensive additions to documentation strings

Comments (0)

Files changed (4)


     :noendtag t)
 (defhtmltag macro-docs
-    :content (loop for sym in (sorted-package-symbols :hh-web-tags #'is-macro-p)
+    :attributes (package)
+    :content (loop for sym in (sorted-package-symbols package #'is-macro-p)
 		collect (list (p (package-symbol {:sym sym :type "macro" }))
 			      (p (documentation sym 'function)))))
 (defhtmltag function-docs
-    :content (loop for sym in (sorted-package-symbols :hh-web-tags #'is-function-p)
+    :attributes (package)
+    :content (loop for sym in (sorted-package-symbols package #'is-function-p)
 		collect (list (p (package-symbol {:sym sym :type "function" }))
 			      (p (documentation sym 'function)))))
 (defhtmltag variable-docs
-    :content (loop for sym  in (sorted-package-symbols :hh-web-tags #'is-variable-p)
+    :attributes (package)
+    :content (loop for sym  in (sorted-package-symbols package #'is-variable-p)
 		collect (list (p (package-symbol { :sym sym :type "variable"} ))
 			      (p (documentation sym 'variable)))))
 (defhtmltag other-docs
-    :content (loop for sym in (sorted-package-symbols :hh-web-tags #'is-other-symbol-p)
+    :attributes (package)
+    :content (loop for sym in (sorted-package-symbols package #'is-other-symbol-p)
 		collect (list (p (let* ((name (string-downcase (symbol-name sym))))
 				   (strong {:style "font-family:monospace" } name))))))


  (pre (literal (script {:src "/scripts/jquery/jquery-1.4.1.js"})))
  (h1 "Reference")
  (h2 "Macros")
- (macro-docs)
+ (macro-docs {:package :hh-web-tags})
  (h2 "Functions")
- (function-docs)
+ (function-docs {:package :hh-web-tags})
  (h2 "Variables")
- (variable-docs)
+ (variable-docs {:package :hh-web-tags})
  (h2 "Other")
- (other-docs))
+ (other-docs {:package :hh-web-tags}))


-   ))
+   )
+  (:documentation "HH-WEB-TAGS is an HTML generation library.  What separates this library from some others is
+   that the library coordinates in a modular fashion the generation of not just HTML, but also CSS, Javascript, 
+   and other meta-data on a page.  
+   It does so by defining the concept of a $(em \"tag\"), which may have associated HTML, CSS, Javascript,
+   etc.  Embedding the tag onto a page will cause the library to include the HTML, CSS, Javascript, etc., from the tag
+   into the final generated HTML output.  If the same tag appears multiple times, only a single copy of the relevant CSS
+   and Javascript appears in the output.  Tags use typical Lisp s-expression syntax (e.g., parentheses) with attributes
+   expressed as keyword arguments inside of braces (e.g., { }) instead of the angle brackets (e.g., < > ) of HTML.  Thus:
+    (div 
+     (p {:id \"description\"} 
+       \"A foo is the best widget for all your bar needs.\")))
+   instead of:
+   $(literal (div 
+     (p {:id \"description\"} 
+       \"A foo is the best widget for all your bar needs.\"))) 
+   TAGS
+   A tag provides a unit of modularity, allowing the developer to focus strictly on small units of functionality, and 
+   HH-WEB-TAGS makes composition of tags into a larger page a straightforward matter.  It's precisely this modularity
+   that's often missing from web development: to implement a portion of page, one has to insert HTML in the body, 
+   write script in the head, add a list of required script libraries, update CSS styles, etc.  HH-WEB-TAGS handles all
+   of that, extracting the relevant parts from a tag definition and inserting them intelligently in the final output.
+   The $(a {:href \"#_macro_defhtmltag\"} \"defhtmltag\") macro is used to define tags, and tags can refer to other tags
+   when describing the content the tag can generate.  Further, all attributes of a tag are available as variables (actually,
+   as symbol macros defined by symbol-macrolet) within the body of the content, so parameterized generation of content is 
+   straightforward.
+   In the context of HTML generation (e.g., within the body of a template, below, or in an s-expression passed to the
+   $(a {:href \"#_macro_html\"} \"html\") macro), using a tag is just like using any other function or macro.  Tags themselves
+   are evaluated as macros literally by wrapping a macrolet around the form from which one wishes to generate HTML.  An 
+   attribute list is completely optional, and can be placed inside either braces { } or a (+@ ) form.  HH-WEB-TAGS uses a 
+   custom readtable to expand the former representation into the latter.  Tags are macros (rather than functions) for the
+   simple reason that each 'outer' tag establishes some context in which each 'inner' tag is evaluated.  The body of a tag
+   (e.g., the rest of the tag's arguments, minus the attribute list) is eventually evaluated and becomes a list attached to the tag 
+   as it's content.  Any combination of lists, tags, strings, numbers, or other Lisp types are valid, provided they 
+   have a printable representation.  
+   As an aid to mixing text content and HTML markup, during HTML generation, any string is scanned for occurrences of a dollar-sign 
+   ($$) character: any such occurrence should be followed immediately by an s-expression, and the result of evaluating that expression 
+   will be written into the generated HTML, rather than the literal expression.  To use a dollar-sign literal instead, use 2 dollar-signs
+   in succession ($$$$).
+   In addition to tags, the other primary concepts that HH-WEB-TAGS defines are tag libraries and templates.  Tag libraries are just
+   collections of related tag definitions; a basic HTML library is included in HH-WEB-TAGS.  Every tag has an associated 
+   symbol, and each tag library defines a Lisp package containing those symbols.  A tag library is just an ordinary file
+   containing Lisp expressions (so defuns, defvars, and other standard Lisp expressions are all still valid), except that
+   any occurrences of $(a {:href \"_macro_defhtmltag\"} \"defhtmltag\") become tag definitions associated with that tag library.
+   Templates build up complete web pages from tags.  
+   Additionally, it defines the concept of a $(em \"template\"), a parameterizable description of a single web page
+   (or other web resource, actually; see images below).  Instead of writing a page (or template) in raw HTML, one writes
+   a template using tags, either from the built-in HTML tag library or a custom tag library.
+   HH-WEB-TAGS also supports HTML entities, and defines many standard HTML entities directly in the HTML tag library. Ideally,
+   all needed HTML entities are already available in the built-in tag library, but if not, one can use the $(a {:href \"_macro_defentity\"} \"defentity\") 
+   macro  to define new ones, or to add entities still missing from the HTML tag library.
 	    (loop for c = (read-char is nil nil)
 	       while c
 	       do (cond ((and (equal c #\$)
-			      (peek-char nil is nil nil)
-			      (not (equal #\$ (peek-char nil 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)
-			 (write-char c os))
+			      (peek-char nil is nil nil))
+			 (if (equal #\$ (peek-char nil is nil nil))
+			     (progn 
+			       (write-char c os)
+			       ;; consume the next character
+			       (read-char is nil nil))
+			     (format os "~a " (eval `(html ,(with-tag-reader () (read is nil nil)))))))
 			 (write-char c os))))))))
        (macrolet ((with-tag-attributes (() &rest body)
 		    (let ((attributes (find-all-tag-attributes ',attributes ',bases)))
-		      ;; Okay, challenge here is that this macro is expanded *before* the current tag's
-		      ;; definition has made it into the library (see a few lines down where the add-tag-to-library
-		      ;; call happens); so...we need to collect the attributes from the tag's bases, add in
+		      ;; Okay, challenge here is that this macro is expanded *before* the current tag library is assigned
+		      ;; to *tag-library; so...we need to collect the attributes from the tag's bases, add in
 		      ;; any defined here in the call to the macro, and then should be good.
-		      `(symbol-macrolet (,@(loop for attribute in attributes ;; attributes
+		      `(symbol-macrolet (,@(loop for attribute in attributes 
 					      collect `(,attribute (tag-attribute-value *this-tag* ',attribute))))
 			 (with-slots (_body) *this-tag*
      (export (list (quote ,name)))))
 (defmacro html (&rest body)
-  "Interpret the body as html markup, returning an HTML fragment"
+  "Interpret the body as html markup, return multiple values, the first of which is an HTML string. The full list of return values is:
+   $(ul
+     (li \"The intended title of the page containing this HTML fragment\")
+     (li \"Link elements that should appear in the head of the page containing this fragment\")
+     (li \"Style sheets required by the HTML fragment\")
+     (li \"Script libraries required by the HTML fragment\")
+     (li \"Sections of Javascript code required by the HTML fragment\")
+     (li \"Sections of Javascript code to be run on page initialization that are required by the HTML fragment\")
+     )
+  Any of these values may be null (including the fragment itself).  Care should be taken when nesting calls to this macro, as inline
+  expansion of $$ characters will occur in each invocation of it, and unexpected results may occur.
+   "
   `(let ((*page-title* ())
 	 (*page-links* ())
 	 (*page-style-sheets* ())
        (values content *page-title* *page-links* *page-style-sheets* *page-styles* *page-script-libraries* *page-scripts* *page-ready-scripts*))))
 (defmacro page (&rest raw-body)
-  "Interpret the raw body as html markup, and return a complete HTML page.  Remember, this is usually called in a loop of all available user agents"
+  "Interpret the raw body as html markup, and return a complete HTML page.  In combination with $(a {:href \"_macro_html\"} \"html\"), this macro weaves
+   the output of calls to $(em \"html\") into a complete page, with styles, scripts, references to script libraries, a page title, etc., all arranged
+   in the appropriate order."
   `(multiple-value-bind (page-content *page-title* *page-links* *page-style-sheets* *page-styles* *page-script-libraries* *page-scripts* *page-ready-scripts*) 
        (html-for-user-agent ,@raw-body)
      ;; now render the page