Function Index

Functions en detail

MaskString( Target, Needle [, _MatchName = "Match" [, MaskChar = "-" ] ])

Abstract

This function masks a given string by a passed regex with a special maskchar
and returns the masked string

Parameter

TargetA string containing the source
NeedleA string containing the regex needle
_MatchNameusefull for only replacing parts and not entire match
MaskCharJust for the case a different char is neccessary

Inline Comments

FunctionSource
MaskString( Target, Needle, _MatchName = "Match", MaskChar = "-")
{
    ; loop untill no matches are found
    while ( p := RegExMatch( Target, Needle, Match, ( !p ? 1 : p+StrLen( Match ) ) ) )
    {
        ; build replacement string, but keep linebreaks intact
        Replacement := RegExReplace( %_MatchName%, "ms)[^\r\n]", MaskChar )
        if ( StrLen(Replacement) != 0 )
        {
            ; Replace only one occurence in the target starting at position p
            Target := RegExReplace( Target,  "ms)\Q" RegExSafe( %_MatchName% ) "\E", Replacement, 0, 1, p )
        }
    }
    Return Target
}
Internal functions used

RegExSafe( Needle )

Abstract

Avoids preliminary ends of quotation regex

Parameter

NeedleNo definition available

Inline Comments

FunctionSource
RegExSafe( Needle )
{
    ; Mask any EscapeChars which might end preliminary an quotation RegEx
    Return RegExReplace( Needle, "ms)\\", "\E\\\Q" )
}
Internal functions used

TransScript( Function, Comments )

Abstract

Translates the entire found funtion to HTML

Parameter

Functionthe function name
commentsthe corresponding comments ahead the definition

Inline Comments

FunctionSource
TransScript( Function, Comments )
{
    local blah
    Local Pos, cLine, continuationSection, MaskedLine, commentLine, inlineComments, currentComment
    Local commentBlock, nComments, tableData, head, lemma, table, returnValue, out
    Local firstContLine, check0, hash
        
    function := RegExReplace( function, "\t", "    " )
    
    ; Strip comments to a nice list
    continuationSection := false
    Loop,Parse,function,`n,`r
    {
        MaskedLine := MaskString( A_LoopField, BalancedQuotes )
        if ( RegExMatch( A_LoopField, "^\s*\(" ) )
        {
            continuationSection := true
        }
        else if ( RegExMatch( A_LoopField, "^\s*\(" ) )
        {
            continuationSection := false
        }
    
        if ( Pos := RegExMatch( MaskedLine, "\s*;(?P<Comment>.*)", _ ) && ! continuationSection )
        {
            commentLine .= ( StrLen( CommentLine ) ? "`n" : "" ) A_Index "/" Pos
            currentComment := RegExReplace( SubStr( A_LoopField, Pos ), ".*?\s*;\s*" )
            if ( ! RegExMatch( currentComment, "^~" ) )
            {
                inlineComments .= ( StrLen( inlineComments ) ? "`n" : "" ) "<li>" htmlEncode( currentComment ) "</li>`n"
            }
        }
    }
    commentBlock := ( strlen( inlineComments ) ?  "<ul>" inlineComments "</ul>" : "" )
    
    ; build Lemma
    nComments := RegExReplace( Comments, "ms)(^\s*|\s*$)" )
    nComments := RegExReplace( nComments, "ms)\s*\*\/\s*" )
    nComments := RegExReplace( nComments, "ms)\s*\/\*\s*" )
    comments := ""
    Loop,Parse,nComments,`n,`r
    {
        comments .= ( StrLen( comments ) ? "`n" : "" ) trim( RegExReplace( A_LoopField, "^\s*\*+\s*" ) )
    }

    Loop,Parse,Comments,`n
    {
        if ( RegExMatch( A_LoopField, "i)@param", _ ) )
        {
            RegExMatch( A_LoopField, "i)\s*(@param)\s*(?P<Name>[^\s]+)(?P<Definition>.*)", Param )
            tableData .= "<tr><td class=params width=200 valign=top align=left>" 
                    . ParamName 
                    . "</td><td class=definition>" 
                    . ( strlen( trim( x:=RegExReplace( ParamDefinition, "^\s*-\s*" ) ) ) ? x : "No definition available" )
                    . "</td></tr>`n"
        }
        else if ( RegExMatch( A_LoopField, "i)@return", _ ) )
        {
            RegExMatch( A_LoopField, "i)\s*(@return)\s*(?P<Value>.*)", Return )
        }
        Else
        {
            head .= ( StrLen( trim(A_LoopField) ) ? "<div class=""text"">" htmlEncode(A_LoopField) "</div>`n" : "" )
        }
    }

    ; Build Header if any
    if ( StrLen( trim(head) ) )
    {
        lemma := "<p class=""extra"">Abstract</p>`n" head "`n"
    }

    ; Build Param Table if any
    if ( StrLen( trim( tableData ) ) )
    {
        table := "<p class=""extra"">Parameter</p>`n"
                 . "<table style=""background:#888;"" cellspacing=1 width=100% cellpadding=4>`n" 
                 . tableData
                 . "</table>`n"
    }

    ; Build commentBlock if any
    if ( StrLen( trim( CommentBlock ) ) )
    {
        commentBlock :=  "<p class=""extra"">Inline Comments</p>" commentBlock
    }

    ; Build ReturnValue information if any
    if ( StrLen( trim( ReturnValue ) ) )
    {
        returnValue := "<p class=""extra"">Returns</p>`n<div class=""text"">" htmlEncode( returnValue ) "</div>"
    }
    
    out := ""
    
    ; beautify function
    continuationSection := false
    Loop,Parse,Function,`n,`r
    {
        CurrentLine := A_LoopField
        MaskedLine := MaskString( CurrentLine, BalancedQuotes, "MatchBQ" )
        
        ; check for continuation section to skip the rest
        if ( RegExMatch( CurrentLine, "^\s*\(" ) )
        {
            continuationSection := true
            firstContLine := true
        }
        else if ( RegExMatch( CurrentLine, "^\s*\)" ) )
        {
            continuationSection := false
        }
        
        if ( !continuationSection || firstContLine )
        {
            firstContLine := false
            ; make line appear as inline comment
            if ( Pos := RegExMatch( CurrentLine, "(?P<Start>.*?\s+)(?P<Comment>;.*)", _ ) && !continuationComment )
            {
                Line := ElseMatches( _Start ) "<span class=comment>" htmlEncode( _Comment ) "</span>"
            }
            ; make line appear as inline comment
            else if ( RegExMatch( CurrentLine, "(?P<Start>^\s*)(?P<Comment>;.*)", _ ) && !continuationComment )
            {
                Line := ElseMatches( _Start ) "<span class=comment>" htmlEncode( _Comment ) "</span>"
            }
            else if ( Pos := RegExMatch( CurrentLine, "(?P<Start>.*?)(?P<Comment>\/\*.*)", _ ) )
            {
                continuationComment := true
                Line := ElseMatches( _Start ) "<span class=comment>" htmlEncode( _Comment ) "</span>"
            }
            else if ( Pos := RegExMatch( MaskedLine,  "\*\/" ) )
            {
                continuationComment := false
                line := RegExReplace( htmlEncode( CurrentLine ), "(^\s*)(.*)", "$1<span class=comment>$2</span>`n" )
            }
            else if ( continuationComment )
            {
                line := RegExReplace( htmlEncode( CurrentLine ), "(^\s*)(.*)", "$1<span class=comment>$2</span>`n" )
            }
            Else
            {
                line := ElseMatches( CurrentLine )
            }
        }
        else if ( ContinuationSection )
        {
            Content := htmlEncode( CurrentLine )
            Content := ArrayMatch( Content )
            
            /* 
             * FIXME: Content := getEscapes( Content )
             */
            
            Line := "<span class=continuation>" Content "</span>"
        }
    
        out .= "<pre class=""codeLine"">" line "</pre>`n"
    }
    out := "<div class=""extra2"">FunctionSource</div>`n<div class=""codeLine"">" out "</div>"
    
    ; return the styled definition
    return lemma table commentBlock returnValue out
}
Internal functions used

ArrayMatch( Line )

Abstract

Matches Percent Signs and AHK-Style-Arrays
FunctionSource
ArrayMatch( Line )
{
    While( Pos := RegExMatch( Line, "((?<!&#96;)&#37;)", Match, ( !pos ? 1 : pos+StrLen( Match )+27 ) ) )
    {
        Line := RegExReplace( Line, "((?<!&#96;)&#37;)", "<span class=percent>$1</span>", "", 1, Pos )
    }
    ArrayNeedle := "(\w*<span class=percent>&#37;</span>\w+<span class=percent>&#37;</span>)"
    While( Pos := RegExMatch( Line, ArrayNeedle, Match, ( !pos ? 1 : pos+StrLen( Match )+25 ) ) )
    {
        Line := RegExReplace( Line, ArrayNeedle, "<span class=array>$1</span>", "", 1, Pos )
    }
    return Line
}
Internal functions used

getEscapes( Line )

Abstract

matches any escape sequences

Inline Comments

FunctionSource
getEscapes( Line )
{
    ; get escaped chars
    if ( Pos := RegExMatch( Line, "&#96;" ) )
    {
        Line := RegExReplace( Line, "(&#96;.)", "<span class=escapes>$1</span>" )
    }
    Return Line
}
Internal functions used

ElseMatches( CurrentLine )

Abstract

Repetitive Matches of same kind for different Hiliting Tasks

Parameter

CurrentLineNo definition available

Inline Comments

FunctionSource
ElseMatches( CurrentLine )
{
    Global BalancedQuotes
    
    MaskedLine := MaskString( CurrentLine, BalancedQuotes, "MatchBQ" )
    
    Line := htmlEncode(currentLine)
    
    Line := getEscapes( Line )

    ; match special chars
    SpecialCharsNeedle := "(((&#42;)?&#42;|\+|\-|\^|(&#60;)?&#60;"
                              . "|(&#62;)?&#62;|(&#38;)?&#38;|\:|\!|\.|&#61;)?&#61;|&#61;|&#44;"
                              . "|\.|\+?\+|\-?\-|(&#42;)?&#42;|\~|(&#60;)?&#60;|(&#62;)?&#62;"
                              . "|(&#47;)?&#47;|(&#38;)?&#38;|\!|\?|\[|\]|\{|\}|\(|\)|(\|)?\||\:)"

    if ( Pos := RegExMatch( MaskedLine, SpecialCharsNeedle ) )
    {
        Line := RegExReplace( Line, SpecialCharsNeedle, "<span class=specials>$1</span>" )
    }

    ; match quotes
    pos := ""
    While ( Pos := RegExMatch( Line, "(&#34;(&#34;&#34;|(?!&#34;).)*&#34;)", match, ( !pos ? 1 : pos+StrLen( Match )+25 ) ) )
    {
        Line := RegExReplace( Line, "(&#34;(&#34;&#34;|(?!&#34;).)*&#34;)", "<span class=quote>$1</span>", "", 1, Pos )
    }

    pos := ""
    NumberNeedle := "((&#48;|&#49;|&#50;|&#51;|&#52;|&#53;|&#54;|&#55;|&#56;|&#57;)+)"
    While ( Pos := RegExMatch( Line, NumberNeedle, match, ( !pos ? 1 : pos+StrLen( Match )+26 ) ) )
    {
        Line := RegExReplace( Line, NumberNeedle, "<span class=number>$1</span>", "", 1, Pos )
    }

    Line := ArrayMatch( Line )

    return Line
}
Internal functions used

htmlEncode(str)

Abstract

Encode a string to an html-Encoded String
basically all Chars not being in range of a to z, A to Z, 0 to 9 (and few others)
get 'translated' to an ASCII Value represented by a Numeric value of the char

Inline Comments

FunctionSource
htmlEncode(str)
{ ; v 0.4.2 / (w) 21.02.2010 by derRaphael / zLib-Style release
    Loop,Parse,str
        if ( ! InStr( "abcdefghijklmnopqrstuvwxyz@;:!?\|^'~ ()[]{}#+-_.", A_LoopField ) )
            data .= "&#" ASC(A_LoopField) ";"
        Else
            data .= A_LoopField
    return data
}
Internal functions used

trim( str )

Abstract

trims a string
FunctionSource
trim( str )
{
    return RegExReplace( str, "sm)^\s*|\s*$" )
}
Internal functions used

BuildHTML( ProjectTitle, index, OrgHTML [, InternalFunDefs = "" [, LibraryFunDefs = "" ] ])

Abstract

Builds the HTML according to the found data

Parameter

ProjectTitleThe title of the file or Project
indexthe previously generated ul-list
htmlthe previously generated html

Inline Comments

FunctionSource
BuildHTML( ProjectTitle, index, OrgHTML, InternalFunDefs = "", LibraryFunDefs = ""  )
{
    
    ; BuildHashTable of our Functions
    if ( StrLen( InternalFunDefs ) )
    {
        Loop,Parse,InternalFunDefs,`n,`r
        {
            name := RegExReplace( A_LoopField, "(.*)", "$L1" )
            hash := CRC( name , StrLen( name ) )
            _%hash% := A_LoopField
            _%hash%_link := "<a href=""#" RegExReplace( A_LoopField, "\W", "_" ) """>" A_LoopField "</a>"
        }
    }

    ; At this point we have a lexed function body    
    ; now lets tear apart all what is unneccessary to check agains our given referencelists
    
    Loop,Parse,OrgHTML,`n
    {
        Line := A_LoopField
        
        if ( RegExMatch( A_LoopField, "<pre class=""codeLine"">" ) )
        {
            ; set mark for function definition
            if ( RegExMatch( A_LoopField, "<div class=""codeLine""><pre class=""codeLine"">" ) )
            {
                functionStart := true
            }
            ; remove any HTML tags
            cLine := RegExReplace( A_LoopField, "<[^>]*>" )
            ; deHTML current line
            Loop,
                if ( pos := RegExMatch( cLine, "&#(?P<num>\d+);", match, ( !pos ? 1 : pos+1 ) ) )
                {
                    cLine := RegExReplace( cLine, "\Q" match "\E", chr(MatchNum), "", 1, pos )
                }
                else
                    break
            ; remove any ObscureChars and Quotes
            cLine := RegExReplace( cLine, BalancedQuotes )
            cLine := RegExReplace( cLine, "\W", " " )
            cLine := RegExReplace( cLine, "\s+", " " )
            cLine := trim( cLine )
            
            ; Now we only have plain ascii letters left, which we may parse easily agains our libs
            if ( StrLen( cLine ) )
            {
                cLine := RegExReplace( cLine, "(.*)", "$L1" )
                
                StringSplit,check,cLine,%A_Space%
                Loop, % check0
                {
                    if ( A_Index = 1 && functionStart )
                    {
                        cFun := RegExReplace( check1, "\W", "_" )
                        functionStart := false
                    }
                    
                    hash := CRC( check%A_Index%, Strlen( check%A_Index% ) )
                    if ( StrLen( _%hash% ) )
                    {
                        Line := RegExReplace( Line, "i)(" check%A_Index% ")", _%hash%_link )
                        if ( ! InStr( addenum%cFun%, _%hash%_link ) )
                        {
                            addenum%cFun% .= "<li class=""addenum"">" _%hash%_link "</li>"
                        }
                    }
                }
            }
        }
        HTML .= ( StrLen( HTML ) ? "`n" : "" ) Line
    }    
    Loop,Parse,InternalFunDefs,`n
    {
        cFun := RegExReplace( A_LoopField, "\W", "_" )
        if ( RegExMatch( HTML, "\Q<!-- PLACEHOLDER::" cFun "::INLINEREFERENCES -->\E" ) )
        {
            if ( StrLen( addenum%cFun% ) )
            {
                Replacement := "<div class=""extra"">Internal functions used</div>`n"
                                 . "<ul class=""addenum"">`n" addenum%cFun% "</ul>`n"
                                 . "<br style=""clear:both"">`n"
                HTML := RegExReplace( HTML, "\Q<!-- PLACEHOLDER::" cFun "::INLINEREFERENCES -->\E", Replacement )
            }
        }
    }
    
    FormatTime, Date, % A_Now " L1033", dddd MMMM d, yyyy HH:mm tt
Out=
(Join`n
<html>
<head>
    <title>%ProjectTitle%</title>
    <style type="text/css">
        body {
            font-family: Verdana, Arial, Helvetica, sans-serif, "MS sans serif";
            font-size: 75`%;
            border: 0;
            background-color: #000;
            color:#fff;
        }
        p {
            margin-top: 0.7em;
            margin-bottom: 0.7em;
        }
        ul { margin-top: 0.7em; margin-bottom: 0.7em; }
        ol { margin-top: 0.7em; margin-bottom: 0.7em; }
        li { margin-top: 0.2em; margin-bottom: 0.2em; }
        
        ul.addenum { list-style-type: none; margin: 0; padding:0; }
        li.addenum { float:left; margin:0; padding: 2px 5px; }
        a:link, a:active, a:visited
        {text-decoration: none;color:#88f}
        a:hover  {text-decoration: underline;}
        
        span.cmd, span.keyword, span.keys, span.var, span.func, span.quote, span.array, span.percent, span.specials
        { font-weight: normal }
        
        .cmd a:link, .cmd a:active, .cmd a:visited 
        { color: #08f; }
        .keyword a:link, .keyword a:active, .keyword a:visited  
        { color: #00f; }
        .keys a:link, .keys a:active, .keys a:visited   
        { color: #800; }
        .var a:link, .var a:active, .var a:visited   
        { color: #f0f; }
        .func a:link, .func a:active, .func a:visited   
        { color: #0ff; }
        .codeLine a:link, .codeLine a:active, .codeLine a:visited   
        { color: inherit, border-bottom: 1px dottet green }
        
        .quote { color:#8f0; }
        
        .percent { color: #f00; }
        .quote span.percent { color:#f8f; }
        
        .array { color:#f4f; }
        .array span.percent { color:#f8f; }
        
        .escapes { color: #f0a; }
        .quote span.escapes { color:#f8f; }
        
        .specials { color: #f6f; }
        .quote span.specials { color:#880; }
        
        .number { color:#f00; }
        .quote span.number { color:#880; }
        
        .continuation { color: #ff0; }
        .continuation .array { color:#f4f; }
        .continuation .array span.percent { color:#f8f; }
        
        p.CommandSyntax {
            border-left: 10px solid #fc0;
            background-color: #ffa;
            margin: 0 0 1.0em 0;
            padding: 12px 0 12px 4px;
        }
        .extra { color:#888; background:#222; font-weight:bold;padding:0.3em;margin-top:2em; }
        .extra2 { color:#f80; background:#420; font-weight:bold;padding:0.3em;margin-top:2em; }
    
        .funcname { background-color: #448;color:#fff;font-weight:bold;padding:0.3em;margin-top:2em; }
        .codeLine { font-family: Lucida Console, Courier New, Monospace; margin:0; padding: 0; }
        div.codeLine pre { font-family: Lucida Console, Courier New, Monospace; font-size: 8pt; margin:0; padding: 0; }
        div.codeLine { padding: 10px; }
        .comment { font-family: Lucida Console, Courier New, Monospace; font-style: italic; color: #666; }
        
        td.params { background:#000; color:#fff; font-weight: bold; font-size: 75`%;}
        td.definition { background:#000; color:#fff; font-size: 75`%; }
    </style>
</head>
<body>
    <a name="top"></a><h2>Function Index</h2>
    %index%
    <h2>Functions en detail</h2>
    %HTML%
    <div class="extra" style="text-align:center;">- End of Documentation -</div>
    <div style="margin:10px auto;padding:3px;font-size:8pt;color:#444;background:#111;border:1px solid #222;">
        Build on %Date% with <a href="http://www.autohotkey.com/forum/topic54846.html">dR's Doc-O-Matic %Version%</a>
    </div> 
</body>
</html>
)
return out
}
Internal functions used

CRC(ByRef Buffer [, Bytes=0 [, Start=-1 ] ])

Abstract

Code by Laszlo:
Taken from http://www.autohotkey.com/forum/viewtopic.php?p=242953#242953
FunctionSource
CRC(ByRef Buffer, Bytes=0, Start=-1) {
   Static CRC32, CRC32LookupTable
   If (CRC32 = "") {
      MCode(CRC32,"33c06a088bc85af6c101740ad1e981f12083b8edeb02d1e94a75ec8b542404890c82403d0001000072d8c3")
      VarSetCapacity(CRC32LookupTable, 1024)
      DllCall(&CRC32, "uint",&CRC32LookupTable, "cdecl")
      MCode(CRC32,"558bec33c039450c7627568b4d080fb60c08334d108b55108b751481e1ff000000c1ea0833148e403b450c89551072db5e8b4510f7d05dc3")
   }
   If Bytes <= 0
      Bytes := StrLen(Buffer)
   Return DllCall(&CRC32, "uint",&Buffer, "uint",Bytes, "int",Start, "uint",&CRC32LookupTable, "cdecl uint")
}
Internal functions used

MCode(ByRef code, hex)

Abstract

Code by Laszlo:
Taken from http://www.autohotkey.com/forum/viewtopic.php?p=242953#242953

Inline Comments

FunctionSource
MCode(ByRef code, hex) { ; allocate memory and write Machine Code there
   VarSetCapacity(code,StrLen(hex)//2)
   Loop % StrLen(hex)//2
      NumPut("0x" . SubStr(hex,2*A_Index-1,2), code, A_Index-1, "Char")
}
Internal functions used

- End of Documentation -
Build on Monday February 22, 2010 23:18 PM with dR's Doc-O-Matic