MaskString( Target, Needle [, _MatchName = "Match" [, MaskChar = "-" ] ])
Abstract
Parameter
| Target | A string containing the source |
| Needle | A string containing the regex needle |
| _MatchName | usefull for only replacing parts and not entire match |
| MaskChar | Just for the case a different char is neccessary |
Inline Comments
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
}
RegExSafe( Needle )
Abstract
Parameter
| Needle | No definition available |
Inline Comments
RegExSafe( Needle )
{
; Mask any EscapeChars which might end preliminary an quotation RegEx
Return RegExReplace( Needle, "ms)\\", "\E\\\Q" )
}
TransScript( Function, Comments )
Abstract
Parameter
| Function | the function name |
| comments | the corresponding comments ahead the definition |
Inline Comments
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
}
ArrayMatch( Line )
Abstract
ArrayMatch( Line )
{
While( Pos := RegExMatch( Line, "((?<!`)%)", Match, ( !pos ? 1 : pos+StrLen( Match )+27 ) ) )
{
Line := RegExReplace( Line, "((?<!`)%)", "<span class=percent>$1</span>", "", 1, Pos )
}
ArrayNeedle := "(\w*<span class=percent>%</span>\w+<span class=percent>%</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
}
getEscapes( Line )
Abstract
Inline Comments
getEscapes( Line )
{
; get escaped chars
if ( Pos := RegExMatch( Line, "`" ) )
{
Line := RegExReplace( Line, "(`.)", "<span class=escapes>$1</span>" )
}
Return Line
}
ElseMatches( CurrentLine )
Abstract
Parameter
| CurrentLine | No definition available |
Inline Comments
ElseMatches( CurrentLine )
{
Global BalancedQuotes
MaskedLine := MaskString( CurrentLine, BalancedQuotes, "MatchBQ" )
Line := htmlEncode(currentLine)
Line := getEscapes( Line )
; match special chars
SpecialCharsNeedle := "(((*)?*|\+|\-|\^|(<)?<"
. "|(>)?>|(&)?&|\:|\!|\.|=)?=|=|,"
. "|\.|\+?\+|\-?\-|(*)?*|\~|(<)?<|(>)?>"
. "|(/)?/|(&)?&|\!|\?|\[|\]|\{|\}|\(|\)|(\|)?\||\:)"
if ( Pos := RegExMatch( MaskedLine, SpecialCharsNeedle ) )
{
Line := RegExReplace( Line, SpecialCharsNeedle, "<span class=specials>$1</span>" )
}
; match quotes
pos := ""
While ( Pos := RegExMatch( Line, "("(""|(?!").)*")", match, ( !pos ? 1 : pos+StrLen( Match )+25 ) ) )
{
Line := RegExReplace( Line, "("(""|(?!").)*")", "<span class=quote>$1</span>", "", 1, Pos )
}
pos := ""
NumberNeedle := "((0|1|2|3|4|5|6|7|8|9)+)"
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
}
htmlEncode(str)
Abstract
Inline Comments
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
}
trim( str )
Abstract
BuildHTML( ProjectTitle, index, OrgHTML [, InternalFunDefs = "" [, LibraryFunDefs = "" ] ])
Abstract
Parameter
| ProjectTitle | The title of the file or Project |
| index | the previously generated ul-list |
| html | the previously generated html |
Inline Comments
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
}
CRC(ByRef Buffer [, Bytes=0 [, Start=-1 ] ])
Abstract
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")
}
MCode(ByRef code, hex)
Abstract
Inline Comments
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")
}