http://www.angelfire.com/ca/redwards....calendar.html

HTML() bookmarklet library...

The HTML() builder functions are all capitalized to avoid naming conflicts with document model object identitifiers. Also, these functions are named after the HTML tags and attributes that they implement. Container tags are defined on the String.prototype, and elemental tags (without a close tag) are defined on window. Tag attributes are also defined on window. This supports the following syntax:
Code:
	INPUT(TYPE('submit')+VALUE('email!')).FORM(ACTION('mailto:'))
This example yields:
Code:
	<FORM ACTION="mailto:"><INPUT TYPE="submit" VALUE="email!"></FORM>
At first glance, it may not seem significant to save only a few characters. However, the more container tags that are used, the greater the savings. And since all of these constructs return strings, they can be saved in variables for efficient reuse.

Container tags and elemental tags are also defined on the Array.prototype for implementation across every element of an array. Consider this syntax:
Code:
	'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ').OPTION().SELECT().FORM()
This example yields:
Code:
	<FORM><SELECT><OPTION>Jan</OPTION><OPTION>Feb</OPTION><OPTION>Mar</OPTION><OPTION>Apr</OPTION><OPTION>May</OPTION><OPTION>Jun</OPTION><OPTION>Jul</OPTION><OPTION>Aug</OPTION><OPTION>Sep</OPTION><OPTION>Oct</OPTION><OPTION>Nov</OPTION><OPTION>Dec</OPTION></SELECT></FORM>
This can easily be changed to a list of radio buttons:
Code:
	'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ').INPUT(TYPE('radio')+NAME('R1')).FORM()
This example yields:
Code:
	<FORM><INPUT TYPE="radio" NAME="R1">Jan<INPUT TYPE="radio" NAME="R1">Feb<INPUT TYPE="radio" NAME="R1">Mar<INPUT TYPE="radio" NAME="R1">Apr<INPUT TYPE="radio" NAME="R1">May<INPUT TYPE="radio" NAME="R1">Jun<INPUT TYPE="radio" NAME="R1">Jul<INPUT TYPE="radio" NAME="R1">Aug<INPUT TYPE="radio" NAME="R1">Sep<INPUT TYPE="radio" NAME="R1">Oct<INPUT TYPE="radio" NAME="R1">Nov<INPUT TYPE="radio" NAME="R1">Dec</FORM>
Together, these functions implement a very powerful HTML building library. Click the link above for a quick demonstration.

The library itself is built from just five template functions. Although these functions are never called directly, they establish the patterns for how to build attributes, elemental tags, and containers; plus array-wide versions of attributes and containers.
Code:
	function Y(W){return' Y'+(W?('='+String.fromCharCode(34)+W+String.fromCharCode(34)):'')};
	function X(W){return'<X'+(W?W:'')+'>'};
	function Z(W){return'<Z'+(W?W:'')+'>'+this+'</'+'Z>'};
	function G(W){return'<G'+(W?W:'')+'>'+this.join('<G'+(W?W:'')+'>')};
	function R(W){return'<R'+(W?W:'')+'>'+this.join('</'+'R><R'+(W?W:'')+'>')+'</'+'R>'};
These functions are copied, renamed and reimplemented according to a list of space delimited tags and attributes. The case of these items determines their use. Tokens in all uppercase are containers. Tokens in all lowercase are attributes. Tokens in mixed case are elemental tags. Accepted as an existing string, these are utilized by the .J() function:
Code:
	'A action align alt B background Base bgcolor BIG BLINK BODY border bordercolor bordercolordark bordercolorlight Br cellpadding 
	cellspacing checked color cols colspan compact content dir DIV enctype face FONT FORM H1 H2 H3 H4 H5 H6 HEAD height Hr href 
	hspace HTML I id Img Input lang language leftmargin LI marginheight marginwidth maxlength Meta method name NOSCRIPT noshade 
	nowrap OL onblur onchange onclick onfocus onload onmouseout onmouseover onreset onselect onsubmit onunload OPTION P PRE 
	profile readonly rows rowspan SCRIPT SELECT size SMALL SPAN src start STRIKE STYLE style SUB SUP TABLE target TD TEXTAREA 
	TH TITLE title topmargin TR TT type U UL valign value vspace width wrap'.J();
Note that any additional HTML() functions can be defined in like manner.

In the calendar example, here is the code that builds the empty calendar:
Code:
	h=(m.OPTION().SELECT(NAME('m'))+INPUT(TYPE('text')+SIZE(4)+NAME('y'))+INPUT(TYPE('hidden')+NAME('date'))).TD(ALIGN('center'));
	r=new Array(7).INPUT(TYPE('button')+NAME('d')+STYLE('width:'+sz+';height:'+sz)).TD(ALIGN('right')+WIDTH(sz*7)+HEIGHT(sz));
	h=[h,r,r,r,r,r,r,r].TR().TABLE(BORDER('0')+CELLSPACING('0')+CELLPADDING('0')).FORM(NAME('frm'));
Above, an array of month names is built into select list m, which is concatenated with textbox y and hidden field date, before inclusion in a single table cell. Then, each of r's seven empty elements are defined as square buttons named d, and included in another table cell. Finally, h and seven copies of r (in an unnamed array) are defined as distinct table rows, included into a single table, for inclusion into form frm.

If you use this technique, let me know where and how. Thanks! :-)