Printing The Entire jQuery API As A PDF (Using CFDocument And XML Parsing)

<!---
	Create a ColdFusion XML document based on the jQuery XML
	documentation available at:
 
	http://visualjquery.com/index.xml
--->
<cfxml variable="xmlDoc">
	<cfinclude template="./documentation.xml" />
</cfxml>
 
 
<!---
	Get the root XML node of the XML document. This will
	contain all the categories for the documentation.
--->
<cfset xmlRoot = XmlDoc.XmlRoot />
 
 
<!--- Output basic CSS for the document. --->
<style type="text/css">
 
	body {
		font: 11px verdana ;
		}
 
	h2.categoryname {
		border-bottom: 2px solid #333333 ;
		font-size: 24px ;
		}
 
	h2.subcategoryname {
		border-bottom: 1px solid #333333 ;
		font-size: 18px ;
		}
 
	h3 {
		border-bottom: 1px solid #999999 ;
		font-size: 14px ;
		padding-bottom: 3px ;
		padding-top: 15px ;
		}
 
	h4 {
		font-style: italic ;
		margin: 0px 0px 5px 0px ;
		}
 
	h5 {
		font-size: 10px ;
		margin: 0px 0px 5px 0px ;
		}
 
	p,
	ol,
	ul {
		margin: 0px 0px 12px 0px ;
		}
 
	div.methodbody {
		margin-left: 20px ;
		}
 
	div.indent {
		margin-left: 20px ;
		}
 
</style>
 
 
<cfoutput>
 
	<h1>
		jQuery API Documentation
	</h1>
 
	<!---
		Get the sections/categories that the documentation is
		broken up into. Be careful; the documentation has nested
		categories. By doing a // search, we will be finding all
		categories regardless of nesting.
	--->
	<cfset arrCategories = XmlSearch( xmlRoot, "//cat" ) />
 
 
	<!--- Loop over all the sections / categories in the documentation. --->
	<cfloop
		index="intCategory"
		from="1"
		to="#ArrayLen( arrCategories )#"
		step="1">
 
		<!--- Get category short hand. --->
		<cfset xmlCategory = arrCategories[ intCategory ] />
 
		<!--- Get methods for this category. --->
		<cfset arrMethods = XmlSearch( xmlCategory, "./method" ) />
 
		<!---
			Get all the sub categories. Remember, the documentation
			has categories within categories (at times).
		--->
		<cfset arrSubCategories = XmlSearch( xmlCategory, "./cat" ) />
 
 
		<!---
			Check to see if we are in a sub category. We will
			know this is true if the node name of the current
			node matches the node name of the parent node.
		--->
		<cfif (xmlCategory.XmlParent.XmlName EQ xmlCategory.XmlName)>
 
			<!--- We are in a sub category. --->
			<cfset blnSubCategory = true />
 
		<cfelse>
 
			<!--- We are NOT in a sub category. --->
			<cfset blnSubCategory = false />
 
		</cfif>
 
 
		<!--- Output the category name. --->
		<h2 class="<cfif blnSubCategory>sub</cfif>categoryname">
			#xmlCategory.XmlAttributes.Value#
		</h2>
 
 
		<!--- Loop over methods. --->
		<cfloop
			index="intMethod"
			from="1"
			to="#ArrayLen( arrMethods )#"
			step="1">
 
			<!--- Get method short hand. --->
			<cfset xmlMethod = arrMethods[ intMethod ] />
 
			<!--- Get method attributes. --->
			<cfset arrDescription = XmlSearch( xmlMethod, "./desc" ) />
			<cfset arrSee = XmlSearch( xmlMethod, "./see" ) />
			<cfset arrParams = XmlSearch( xmlMethod, "./params" ) />
			<cfset arrExamples = XmlSearch( xmlMethod, "./examples" ) />
			<cfset arrBefore = XmlSearch( xmlMethod, "./before" ) />
			<cfset arrCode = XmlSearch( xmlMethod, "./code" ) />
			<cfset arrResult = XmlSearch( xmlMethod, "./result" ) />
			<cfset arrOptions = XmlSearch( xmlMethod, "./options" ) />
 
 
			<!--- Ouptut the method name (with param names). --->
			<h3>
				#xmlMethod.XmlAttributes.Name#(
 
				<!--- Ouput parameters. --->
				<cfloop
					index="intParam"
					from="1"
					to="#ArrayLen( arrParams )#"
					step="1">
 
					<!--- Check to see if this parameter has a name. --->
					<cfif StructKeyExists( arrParams[ intParam ].XmlAttributes, "Name" )>
						#arrParams[ intParam ].XmlAttributes.Name#
					</cfif>
 
					<!---
						Check to see if we have more than one parameter.
						We only need a comma for mulitple params.
					--->
					<cfif (intParam LT ArrayLen( arrParams ))>
						,
					</cfif>
 
				</cfloop>
				)
			</h3>
 
 
			<div class="methodbody">
 
				<!--- Check to see if we have a metho description. --->
				<cfif ArrayLen( arrDescription )>
 
					<p class="methoddescription">
						#ToString( HtmlEditFormat( arrDescription[ 1 ].XmlText ) ).ReplaceAll(
							"(\r?\n){2,}",
							"</p><p class=""methoddescription"">"
							)#
					</p>
 
				</cfif>
 
 
				<!--- Check to see if we have any parameters. --->
				<cfif ArrayLen( arrParams )>
 
					<h4>
						Parameters
					</h4>
 
					<div class="indent">
 
						<p>
							<cfloop
								index="intParam"
								from="1"
								to="#ArrayLen( arrParams )#"
								step="1">
 
								<!--- Get a short hand for the parameters. --->
								<cfset xmlParameter = arrParams[ intParam ] />
 
								<!--- Get description. --->
								<cfset arrParamDescription = XmlSearch( xmlParameter, "./desc" ) />
 
								<p>
 
									<cfif StructKeyExists( xmlParameter.XmlAttributes, "Name" )>
										<strong>#xmlParameter.XmlAttributes.Name#</strong>:
									</cfif>
 
									<cfif StructKeyExists( xmlParameter.XmlAttributes, "Type" )>
										( #xmlParameter.XmlAttributes.Type# ):
									</cfif>
 
									<cfif ArrayLen( arrParamDescription )>
										#HtmlEditFormat( arrParamDescription[ 1 ].XmlText )#
									</cfif>
 
								</p>
 
							</cfloop>
						</p>
 
					</div>
 
				</cfif>
 
 
				<!--- Check to see if we have any method options. --->
				<cfif ArrayLen( arrOptions )>
 
					<h4>
						Hash Options
					</h4>
 
					<div class="indent">
 
						<!--- Loop over options. --->
						<cfloop
							index="intOption"
							from="1"
							to="#ArrayLen( arrOptions )#"
							step="1">
 
							<!--- Get a short hand for the option. --->
							<cfset xmlOption = arrOptions[ intOption ] />
 
							<!--- Get description. --->
							<cfset arrOptionDescription = XmlSearch( xmlOption, "./desc" ) />
 
							<p>
 
								<cfif StructKeyExists( xmlOption.XmlAttributes, "Name" )>
									<strong>#xmlOption.XmlAttributes.Name#</strong>:
								</cfif>
 
								<cfif StructKeyExists( xmlOption.XmlAttributes, "Type" )>
									( #xmlOption.XmlAttributes.Type# ):
								</cfif>
 
								<cfif ArrayLen( arrOptionDescription )>
									#HtmlEditFormat( arrOptionDescription[ 1 ].XmlText )#
								</cfif>
 
							</p>
 
						</cfloop>
 
					</div>
 
				</cfif>
 
 
				<!--- Check to see if are method has a return type. --->
				<cfif StructKeyExists( xmlMethod.XmlAttributes, "Type" )>
 
					<h4>
						Returns
					</h4>
 
					<div class="indent">
 
						<p>
							#xmlMethod.XmlAttributes.Type#
						</p>
 
					</div>
 
				</cfif>
 
 
				<!--- Check to see if we have any examples. --->
				<cfif ArrayLen( arrExamples )>
 
					<!--- Loop over examples. --->
					<cfloop
						index="intExample"
						from="1"
						to="#ArrayLen( arrExamples )#"
						step="1">
 
						<!--- Get short hand to example. --->
						<cfset xmlExample = arrExamples[ intExample ] />
 
						<!--- Get the example attributes. --->
						<cfset arrExampleDesc = XmlSearch( xmlExample, "./desc" ) />
						<cfset arrExampleBefore = XmlSearch( xmlExample, "./before" ) />
						<cfset arrExampleCode = XmlSearch( xmlExample, "./code" ) />
						<cfset arrExampleResult = XmlSearch( xmlExample, "./result" ) />
 
						<h4>
							Example
						</h4>
 
						<div class="indent">
 
							<cfif ArrayLen( arrExampleDesc )>
 
								<p>
									#HtmlEditFormat( arrExampleDesc[ 1 ].XmlText )#
								</p>
 
							</cfif>
 
							<cfif ArrayLen( arrExampleCode )>
 
								<p>
									#HtmlEditFormat( arrExampleCode[ 1 ].XmlText )#
								</p>
 
							</cfif>
 
							<cfif ArrayLen( arrExampleBefore )>
 
								<h5>
									Before:
								</h5>
 
								<p>
									#HtmlEditFormat( arrExampleBefore[ 1 ].XmlText )#
								</p>
 
							</cfif>
 
							<cfif ArrayLen( arrExampleResult )>
 
								<h5>
									Result:
								</h5>
 
								<p>
									#HtmlEditFormat( arrExampleResult[ 1 ].XmlText )#
								</p>
 
							</cfif>
 
						</div>
 
					</cfloop>
 
				</cfif>
 
 
				<!--- Check to see if we have any "See Also" examples. --->
				<cfif ArrayLen( arrSee )>
 
					<h4>
						See Also
					</h4>
 
					<div class="indent">
 
						<p>
							<cfloop
								index="intSee"
								from="1"
								to="#ArrayLen( arrSee )#"
								step="1">
 
								#arrSee[ intSee ].XmlText#<br />
 
							</cfloop>
						</p>
 
					</div>
 
				</cfif>
 
			</div>
 
		</cfloop>
 
	</cfloop>
 
</cfoutput>

For Cut-and-Paste