I use Atom as my primary code editor of late and one thing I really like in it is the automatic code beautification of atom-beautifier. It works great on my html and javascript projects. However, that cool feature isn’t extended to ColdFusion. Fortunately, Austin Cheney, the guy who maintains the library that actually does the beautification showed a willingness to implement a beautifier for CF if someone would just tell him what the rules were for the various tags in regards to them needing to be closed.

There are three different tag types in CF - those that require an end tag, those that have an optional (free) end tag, and those that can not (prohibited) have an end tag.

Those tags with an optional end tag can be ended in any of the following three ways:

<cfstoredproc>
<cfstoredproc />
<cfstoredproc></cfstoredproc>

The other two categories are pretty self explanatory.

I tried to manually go through the list of tags at CFDocs but that was prone to mistakes on my part. Adam Cameron on twitter recommended I get help from Dom Watson and Dom pointed me to two helpful lucee functions; getTagList and getTagData which, when combined, provided me with the answers I needed.

PROTIP If you don’t have lucee installed you can put together quick cf scripts to run against all of the main CF engines at http://trycf.com/ - that’s how I ran this code.

Here is the code I used to get a definitive list:

<cfset tags = GetTagList() />


<cfset bodies = structNew() />
<cfset namespace  = "cf" />
<cfset tags = tags[namespace] />
<cfset maxLength = 0 >


<cfloop list="#StructKeyList(tags)#" index="tagname">
    <cfset tag = getTagData(namespace, tagname) />

    <cfif not structkeyExists(bodies, tag.bodyType)>
        <cfset bodies[tag.bodyType] = ArrayNew(1) />
    </cfif>

    <cfset ArrayAppend(bodies[tag.bodyType], tagname)>


</cfloop>


<cfoutput>
    <table>
        <tr>
            <cfloop list="#structKeyList(bodies)#" index="key">
                <th>#key# end tag</th>
                <cfif ArrayLen(bodies[key]) GT maxLength>
                    <cfset maxLength = ArrayLen(bodies[key])>
                </cfif>
                <cfset ArraySort(bodies[key], "text", "asc")>
            </cfloop>


            <cfloop from="1" to="#maxLength#" index="i">
                <tr>
                    <cfloop list="#structKeyList(bodies)#" index="key">
                        <td>
                            <cfif ArrayLen(bodies[key]) GTE i>
                                #bodies[key][i]#
                            <cfelse>
                                &nbsp;
                            </cfif>
                        </td>
                    </cfloop>
                </tr>
            </cfloop>
        </tr>
    </table>
</cfoutput>

And here is the final result:

required end tag free end tag prohibited end tag
case _ abort
catch ajaximport applet
component ajaxproxy application
defaultcase cache argument
execute chart associate
finally chartseries authenticate
form content break
function div chartdata
graph document col
if documentitem collection
interface documentsection continue
lock dump cookie
login file dbinfo
loop htmlbody directory
mail htmlhead else
mailpart http elseif
output invoke error
query layout exit
savecontent layoutarea feed
script map flush
select mapitem forward
silent mediaplayer ftp
static module graphdata
stopwatch pageencoding header
switch pdf httpparam
table processingdirective image
timer setting imap
transaction storedproc import
try thread include
while trace index
xml videoplayer input
  window insert
  zip invokeargument
    ldap
    location
    log
    loginuser
    logout
    mailparam
    object
    objectcache
    param
    pdfparam
    pop
    procparam
    procresult
    property
    queryparam
    registry
    rethrow
    retry
    return
    schedule
    search
    servlet
    servletparam
    set
    sleep
    slider
    throw
    update
    video
    videoplayerparam
    wddx
    x_
    zipparam

Comments