格式化代码

;Change indentation and case of commands according to syntax
;by toralf & hajos
;requires AHK 1.0.44.09
;www.autohotkey.com/forum/topic7810.html

Version = v12
ScriptName =  Auto-Syntax-Tidy %Version%

; Known limitations:; Known limitations:
;  - a space is required after the last ":" for hotkeys, hotstrings and subroutine
;  - comments might not have the right indentation in certain strongly
;      encapsulated block-structures, due to not knowing what the next line will bring.
;  - case correction only works for words longer than 4 characters,
;      (except: (in all cases) If, Loop, Else
;               (optional)     Goto, Gui, Run, Exit, Send, Sort, Menu
;                              Parse, Read, Mouse, SendAndMouse, Default, Permit, Screen, Relative
;                              Pixel, Toggle, UseErrorLevel, AlwaysOn, AlwaysOff
;      !!! caution !!! case correction is dangerous, since WinTitles in commands are case sensitive
;
;  - after doing indentation in an editor the cursor jumps
;      to the first position in the last line
;  - Indentation might fail, if a "{" is the last character of a Loop or If statement that
;      doesn't support OTB. E.g. "If x = {" or "Loop, Parse, Var, {"
;
; Functionality:
;  - Gui: For drag&drop of files, setting of options and feedback
;  - command line option "/in" for file and "/log" for log file
;  - command line option "/hidden" to start script with hidden GUI
;  - command line option "/watch hwnd" to start script with hidden GUI, closes itself when hwnd closes
;  - command line option "/toggle" checks if another instance is running and closes both scripts
;  - command line option "/hidden" to start script without GUI
;  - Options:
;          - custom hotkey for indenation
;          - custom file extension             (overwrites old file if nothing is specified)
;          - custom indentation                (one tab or a number of spaces)
;          - different indentation styles      (Rajat, Toralf or BoBo)
;          - indentation of continuation lines (a number of tabs or spaces)
;          - indentation preservation of block continuation lines (round brackets) On/Off
;          - indentation preservation of block comments           (/* ... */)      On/Off
;          - case correction for syntax words with more than 4 characters  (thanks Rajat)
;          - statistics for script (lines of code, comments, total and empty an time needed)
;  - Dropped Files: Contents will be indented and copied to a new file with a user
;                   defined extension (overwrites old file if nothing is specified).
;  - Hotkey (F2): Highlighted syntax in an editor will be indented, if nothing is
;                 highlighted all text will be indented. (thanks ChrisM)
;  - Gui remembers last position and settings between sessions (thanks Rajat)
;  - The case of subroutine calls and function calls is adjusted to the case
;        of their respective definitions
;  - Ctrl-d toggles debug mode
;  - 12% faster then version 7 (due to shortened loop cycles) but 90 lines longer
;
; !!! Not heavily tested !!!!  ---- !!!!!! Backup your data !!!!!
;
; Suggestions are appreciated
;
; Wish:
;  - Option to strip code: Remove empty lines, all comments, and join split expressions (&&/AND/OR/||)

/*
changes since version 11:
- tray icon allows to toggle show/hide of GUI and to exit script
- added progressbar if identation is done inside an editor and blockinput is used to limit interference
- shortend code with functions, with new features the line numbers stay equal
- log text is scrolled to the end
- on /hidden, gui is created but hidden, tray icon is visible in both cases.
- on "/watch hwnd" , gui is hidden and closes itself when hwnd closes
- on /toggle, script checks if another instance is running and closes both scripts
- improved possibilty to find path of AHK
- added warning message if syntax files do not exist
- OwnHotKey is stored in INI file and has a control in the GUI

2013.11.21
修改AHKPath为脚本目录,语法文件目录为%AHKPath%Syntax。
采用截止今日最新的SCITE4AHK的ahk.api文件,与1.0.48.5的语法文件进行合并。
保留旧的哪怕被移除了的命令,例如REPEAT。
这样做的目的是为了支持代码格式化的正常工作。
修改默认不对KEYWORDS进行大小写纠错。因为目前程序不够智能,当DLLCALL中函数名符合KEYWORDS时,也会进行纠错,而DLLCALL对大小写是敏感的,因此非常容易造成问题。

2013.11.22
修改代码,使其运行时直接格式化选中的或全部代码。

2014.03.06
修改代码,使其支持对for语句的格式化。

2014.03.07
修改代码,使其支持中文函数的格式化。
修改默认格式化风格。
修改代码,使其支持对While,Until,Try,Catch,Finally语句的格式化。

2014.03.15
修改代码,Until后面一句不应该缩进

2014.03.26
修改代码,改进大小写纠正的问题,以下单词总被纠正为全小写。
if
else
goto

*/

#SingleInstance ignore
SetBatchLines, -1

;set working dir, in case this script is called from some other script in a different dir
SetWorkingDir, %A_ScriptDir%
/*
;process command line parameters   ;by Ace_NoOne - www.autohotkey.com/forum/viewtopic.php?t=7556
If %0%{
Loop, %0% { ; for each command line parameter
next := A_Index + 1           ;get next parameters number
; check if known command line parameter exists
If (%A_Index% = "/in")
param_in := %next%   ;assign next command line parameter as value
Else If (%A_Index% = "/log")
param_log := %next%
Else If (%A_Index% = "/hidden")
param_hidden = Hide
Else If (%A_Index% = "/watch"){
param_hidden = Hide
param_watch := %next%
}Else If (%A_Index% = "/Toggle")
Gosub, CheckAndToggleRunState
}
}

;Turn DebugMode on (=1) to show MsgBox with Debug Info
DebugMode = 0

;location of icon file
If ( A_OSType = "WIN32_WINDOWS" )  ; Windows 9x
IconFile = %A_WinDir%systemshell32.dll
Else
IconFile = %A_WinDir%system32shell32.dll

;tray menu
Menu, Tray, Icon, %IconFile%, 56   ;icon for taskbar and for Process in task manager
Menu, Tray, Tip, %ScriptName%
Menu, Tray, NoStandard
Menu, Tray, Add, Show/Hide, ShowHideGui
Menu, Tray, Add, Exit, ExitApp
Menu, Tray, Default, Show/Hide
Menu, Tray, Click, 1
*/
SplitPath, A_ScriptName, , , , OutNameNoExt
IniFile = %OutNameNoExt%.ini
gosub, ReadDataFromIni


;find path to AHK
AHKPath:=A_ScriptDir
IfNotExist %AHKPath%
{ MsgBox,,, Could not find the AutoHotkey folder.`nPlease edit the script:`n%A_ScriptFullPath%`nin Linenumber: %A_LineNumber%
	ExitApp
}

gosub, ReadSyntaxFiles
/*
If FileExist(param_in){
Gosub, IndentFile
ExitApp
}

Gosub, BuildGui

If param_watch
SetTimer, WatchWindow, On
*/
gosub,IndentHighlightedText
ExitApp
return
/*
;disable hotkey in its own gui
Hotkey, IfWinNotActive, %GuiUniqueID%
;set hotkey and remember it
Hotkey, %OwnHotKey%, IndentHighlightedText
OldHtk = %OwnHotKey%
Hotkey, IfWinNotActive,
Return
*/
;#############   End of autoexec section   ####################################

;#############   Toogle debug modus   #########################################
^d::
	DebugMode := not DebugMode
	ToolTip, DebugMode = %DebugMode%
	Sleep, 1000
	ToolTip
return

;#############   Close script when watch window doesn't exist   ###############
WatchWindow:
	DetectHiddenWindows, On
	if !WinExist("ahk_id " param_watch)  ;check if watch window exists
		gosub, GuiClose                  ;if not close this script
	DetectHiddenWindows, Off
return

;#############   Toogle run status - close on second run   ####################
CheckAndToggleRunState:
	;get own PID
	Process, Exist
	OwnPID := ErrorLevel

	;get own title
	if A_IsCompiled
		OwnTitle := A_ScriptFullPath
	else
		OwnTitle := A_ScriptFullPath " - AutoHotkey v" A_AhkVersion

	;get list of all windows
	DetectHiddenWindows, On
	WinGet, WinIDs, List

	;go through list and get their titles
	Loop, %WinIDs% {
		UniqueID := "ahk_id " WinIDs%A_Index%
		WinGetTitle, winTitle, %UniqueID%

		;check if there is a window with the same title as this script but not itself
		if (winTitle = OwnTitle ) {
			WinGet, winPID, PID, %UniqueID%
			if (winPID  OwnPID) {
				;close it and itself
				Process, Close, %winPID%
				ExitApp
			}
		}
	}
	DetectHiddenWindows, off
return

;#############   Read directives and commands from syntax file   ##############
ReadSyntaxFiles:
	;path to syntax files
	PathSyntaxFiles = %AHKPath%Syntax

	;clear lists
	ListOfDirectives =
	;这个列表从文件中读取类似 IfInString 的以If开头的命令,然后进行缩进。
	;所以可以直接把后期没被支持的流程命令添加到这里面,让程序识别以进行缩进……
	;当时改for的缩进时就没想到这一点……
	ListOfIFCommands = ,For,while,Try,catch,finally,class

	;read each line of syntax file and search for directives and if-keywords
	CommandNamesFile = %PathSyntaxFiles%CommandNames.txt
	IfNotExist %CommandNamesFile%
	{ MsgBox,,, Could not find the "CommandNames.txt" file.`nPlease edit the script:`n%A_ScriptFullPath%`nin Linenumber: %A_LineNumber%
		ExitApp
	}
	Loop, Read , %CommandNamesFile%   ;Read syntax file
	{ ;remove spaces from read line
		Line = %A_LoopReadLine%

		;get first character and first 2 characters of line
		StringLeft,FirstChar, Line ,1
		StringLeft,FirstTwoChars, Line ,2

		;if line is comment, continue with next line
		if (FirstChar = ";")
			continue
		;otherwise if keyword is directive or if-keyword add it to list
		else if (FirstChar = "#")
			ListOfDirectives=%ListOfDirectives%,%Line%
		else if (FirstTwoChars = "if") {
			;get first word, since If-keywords in the syntax file have more words
			StringSplit, Array, Line, %A_Space%
			Line = %Array1%
			if (StrLen(Line) > 4)
				ListOfIFCommands=%ListOfIFCommands%,%Line%
		}
	}
	;remove first comma and change to lower char
	StringTrimLeft,ListOfIFCommands,ListOfIFCommands,1
	StringTrimLeft,ListOfDirectives,ListOfDirectives,1

	;remove multiple If
	Sort, ListOfIFCommands, U D,

	;read in all variable names
	FileRead, Variables, *t %PathSyntaxFiles%Variables.txt
	StringReplace , Variables , Variables , `n , | , All

	FilesSyntax = CommandNames|Keywords|Keys

	;Loop over all syntax files
	Loop, Parse, FilesSyntax,|
	{ String =
		SyntaxFile = %PathSyntaxFiles%%A_LoopField%.txt
		IfNotExist %SyntaxFile%
		{ MsgBox,,, Could not find the syntax file "%A_LoopField%.txt".`nPlease edit the script:`n%A_ScriptFullPath%`nin Linenumber: %A_LineNumber%
			ExitApp
		}
		;read each line of syntax file
		Loop, Read , %SyntaxFile%
		{
			;remove spaces from read line
			Line = %A_LoopReadLine%

			;get first character, length of line and look for spaces
			StringLeft,FirstChar, Line ,1

			;if line contains spaces, continue with next line
			if InStr(Line," ")
				continue
			;if line is empty, continue with next line
			else if Line is Space
				continue
			;if line is comment, continue with next line
			else if (FirstChar = ";")
				continue
			;otherwise if word is longer than 4 character, remember it
			else if (StrLen(Line) > 4 )
				String = %String%,%Line%
		}
		;remove first pipe
		StringTrimLeft,String,String,1
		;store remembered string in var which has same name as syntaxfile
		%A_LoopField% := String
	}

	CommandNames = %CommandNames%,goto,Gui,Run,Exit,Send,Sort,Menu
		,Parse,Read,Mouse,SendAndMouse,Default,Permit,Screen,Relative
		,Pixel,Toggle,UseErrorLevel,AlwaysOn,AlwaysOff

	;read in all function names
	BuildInFunctions =
	;read each line of syntax file
	FunctionsFile = %PathSyntaxFiles%Functions.txt
	IfNotExist %SyntaxFile%
	{ MsgBox,,, Could not find the "Functions.txt" file.`nPlease edit the script:`n%A_ScriptFullPath%`nin Linenumber: %A_LineNumber%
		ExitApp
	}
	Loop, Read , %FunctionsFile%
	{ ;remove spaces from read line
		Line = %A_LoopReadLine%

		;get first character, and name of function plus its braket, e.g. "ATan("
		StringLeft,FirstChar, Line ,1
		StringSplit, Line, Line, (

		;if line is empty, continue with next line
		if Line is Space
			continue
		;if line is comment, continue with next line
		else if (FirstChar = ";")
			continue
		;otherwise remember it with braket
		else
			BuildInFunctions = %BuildInFunctions%,%Line1%(
	}
	;don't remove first comma, it will be done just before correction

return

;#############   Read Data from Ini file   ####################################
ReadDataFromIni:
	IniRead, Extension, %IniFile%, Settings, Extension, _autoindent_%Version%.ahk
	IniRead, Indentation, %IniFile%, Settings, Indentation, 1
	IniRead, NumberSpaces, %IniFile%, Settings, NumberSpaces, 2
	IniRead, NumberIndentCont, %IniFile%, Settings, NumberIndentCont, 1
	IniRead, IndentCont, %IniFile%, Settings, IndentCont, 1
	IniRead, Style, %IniFile%, Settings, Style, 1
	IniRead, CaseCorrectCommands, %IniFile%, Settings, CaseCorrectCommands, 1
	IniRead, CaseCorrectVariables, %IniFile%, Settings, CaseCorrectVariables, 1
	IniRead, CaseCorrectBuildInFunctions, %IniFile%, Settings, CaseCorrectBuildInFunctions, 1
	IniRead, CaseCorrectKeys, %IniFile%, Settings, CaseCorrectKeys, 1
	IniRead, CaseCorrectKeywords, %IniFile%, Settings, CaseCorrectKeywords, 0
	IniRead, CaseCorrectDirectives, %IniFile%, Settings, CaseCorrectDirectives, 1
	IniRead, Statistic, %IniFile%, Settings, Statistic, 1
	IniRead, ChkSpecialTabIndent, %IniFile%, Settings, ChkSpecialTabIndent, 1
	IniRead, KeepBlockCommentIndent, %IniFile%, Settings, KeepBlockCommentIndent, 0
	IniRead, AHKPath, %IniFile%, Settings, AHKPath, %A_Space%
	IniRead, OwnHotkey, %IniFile%, Settings, OwnHotKey, F2
return

OwnHotKey:
	;deacticate old hotkey
	Hotkey, IfWinNotActive, %GuiUniqueID%
	Hotkey, %OldHtk%, IndentHighlightedText, Off
	;Don't allow no hotkey
	if OwnHotkey is Space
	{
		Hotkey, %OldHtk%, IndentHighlightedText
		GuiControl, , OwnHotkey, %OldHtk%
	}else{
		Hotkey, %OwnHotKey%, IndentHighlightedText
		OldHtk = %OwnHotkey%
	}
	Hotkey, IfWinNotActive,
return

;#############   Build GUI for Auto-Syntax-Tidy   #############################
BuildGui:
	LogText = Drop your files for indentation on this Gui.`nOr highlight AHK syntax in script and press %OwnHotkey%.`n`n

	Gui, +ToolWindow +AlwaysOnTop
	Gui, Add, Text, xm Section ,Hotkey
	Gui, Add, Hotkey, ys-3 r1 w165 vOwnHotkey gOwnHotKey, %OwnHotKey%

	Gui, Add, Text, xm Section ,Extension for files
	Gui, Add, Edit, ys-3 r1 w117 vExtension, %Extension%

	Gui, Add, GroupBox, xm w210 r6.3,Indentation
	Gui, Add, Text, xp+8 yp+15 Section,Type:
	Gui, Add, Radio, ys vIndentation,1xTab or
	Gui, Add, Radio, ys Checked,Spaces
	Gui, Add, Edit, ys-3 r1 Limit1 Number w15 vNumberSpaces, %NumberSpaces%
	Gui, Add, Text, xs Section,Style:
	Gui, Add, Radio, x+8 ys vStyle,Rajat
	Gui, Add, Radio, x+8 ys Checked,Toralf
	Gui, Add, Radio, x+8 ys ,BoBo
	Gui, Add, Text, xs Section,Indentation of Method1 continuation Lines:
	Gui, Add, Edit, xs ys+15 Section r1 Limit2 Number w20 vNumberIndentCont, %NumberIndentCont%
	Gui, Add, Radio, ys+4 vIndentCont ,Tabs or
	Gui, Add, Radio, ys+4 Checked,Spaces
	Gui, Add, Checkbox, xs vKeepBlockCommentIndent Checked%KeepBlockCommentIndent%, Preserve indent. in Block comments
	Gui, Add, Checkbox, xs vChkSpecialTabIndent Checked%ChkSpecialTabIndent%, Special "Gui,Tab" indent

	Gui, Add, GroupBox, xm w210 r3,Case-Correction for
	Gui, Add, Checkbox, xp+8 yp+18 Section vCaseCorrectCommands Checked%CaseCorrectCommands%,Commands
	Gui, Add, Checkbox, vCaseCorrectVariables Checked%CaseCorrectVariables%,Variables
	Gui, Add, Checkbox, vCaseCorrectBuildInFunctions Checked%CaseCorrectBuildInFunctions%,Build in functions
	Gui, Add, Checkbox, ys vCaseCorrectKeys Checked%CaseCorrectKeys%,Keys
	Gui, Add, Checkbox, vCaseCorrectKeywords Checked%CaseCorrectKeywords%,Keywords
	Gui, Add, Checkbox, vCaseCorrectDirectives Checked%CaseCorrectDirectives%,Directives
	Gui, Add, Text, xm Section, Information
	Gui, Add, Checkbox, ys vStatistic Checked%Statistic%, Statistic
	Gui, Add, Edit, xm r10 w210 vlog ReadOnly, %LogText%

	if (Indentation = 1)
		GuiControl,,1xTab or,1
	if (Style = 1)
		GuiControl,,Rajat,1
	else if (Style = 3)
		GuiControl,,BoBo,1
	if (IndentCont = 1)
		GuiControl,, IndentCont, 1

	;get previous position and show Gui
	IniRead, Pos_Gui, %IniFile%, General, Pos_Gui,CEnter
	Gui, Show, %Pos_Gui% %param_Hidden% ,%ScriptName%
	Gui, +LastFound
	GuiUniqueID := "ahk_id " WinExist()

	;get classNN of log control
	GuiControl, Focus, Log
	ControlGetFocus, ClassLog, %GuiUniqueID%
	GuiControl, Focus, Extension
return

;#############   Toggle show / hide of Gui from tray icon   ###################
ShowHideGui:
	if param_Hidden {
		Gui, Show
		param_Hidden =
	}else{
		param_Hidden = Hide
		Gui, Show, %param_Hidden%
	}
return

;#############   Function iif: returns a or b depending on expression   #######
iif(exp,a,b=""){
if exp
	return a
return b
}

;#############   Shortcut F? - indent highlighted text   ######################
IndentHighlightedText:
	;store time for speed measurement
	StartTime = %A_TickCount%

	;Save and clear clipboard
	ClipSaved := ClipboardAll
	Clipboard =

	;Cut highlight to clipboard
	Send, ^c

	;get window UID of current window
	WinUniqueID := WinExist("A")

	;If nothing is highlighted, select all and copy
	if Clipboard is Space
	{ ;Select all and copy to clipboard
		Send, ^a^c
	}

	;get rid of all carriage returns (`r).
	StringReplace, ClipboardString, Clipboard, `r`n, `n, All

	;restore the original clipboard and free memory
	Clipboard := ClipSaved
	ClipSaved =

	;If something is selected, do the indentation and put it back in again
	if ClipboardString is Space
		MsgBox, 0 , %ScriptName%,
	(LTrim
		Couldn't get anything to indent.
		Please try again.
	), 1
	else {
		;get Options
		Gui, Submit, NoHide

		;create progress bar and block input
		StringReplace, x, ClipboardString, `n, `n, All UseErrorLevel
		NumberOfLines = %ErrorLevel%
		Progress, R0-%NumberOfLines% FM10 WM8000 FS8 WS400, `n, Please wait`, auto-syntax-tidy is Running, %ScriptName%
		BlockInput, On

		;set words for case correction
		gosub, SetCaseCorrectionSyntax

		;create indentation
		gosub, CreateIndentSize

		;reset all values
		gosub, SetStartValues

		;Read each line form clipboard
		Loop, Parse, ClipboardString, `n
		{ ;remember original line with its identation
			AutoTrim, Off
			Original_Line = %A_LoopField%
			AutoTrim, On

			;do the indentation
			gosub, DoSyntaxIndentation

			;update progress bar every 10th line
			if (Mod(A_Index, 10)=0)
				Progress, %A_Index%, Line: %A_Index% of %NumberOfLines%
		}

		CaseCorrectSubsAndFuncNames()

		;remove last `n
		StringTrimRight,String,String,1

		;Save and clear clipboard
		ClipSaved := ClipboardAll
		Clipboard =

		;put String into clipboard
		;StringReplace, String, String, `n, `r`n, All
		Clipboard = %String%

		;close progress bar and activate old window again
		Progress, Off
		WinActivate, ahk_id %WinUniqueID%

		;paste clipboard
		Send, ^v{HOME}
		;restore the original clipboard and free memory
		Clipboard := ClipSaved
		ClipSaved =

		;turn off block input
		BlockInput, Off

		;write information
		LogText = %LogText%Indentation done for text in editor.`n
		if Statistic
			gosub, AddStatisticToLog
		else
			LogText = %LogText%`n
		GuiControl, ,Log , %LogText%
		ControlSend, %ClassLog%, ^{End}, %GuiUniqueID%
	}
return

;#############   Set words for case correction   ##############################
SetCaseCorrectionSyntax:
	CaseCorrectionSyntax =
	if CaseCorrectCommands
		CaseCorrectionSyntax = ,%CommandNames%
	if CaseCorrectVariables
		CaseCorrectionSyntax = %CaseCorrectionSyntax%,%Variables%
	if CaseCorrectKeys
		CaseCorrectionSyntax = %CaseCorrectionSyntax%,%Keys%
	if CaseCorrectKeywords
		CaseCorrectionSyntax = %CaseCorrectionSyntax%,%Keywords%
	if CaseCorrectDirectives
		CaseCorrectionSyntax = %CaseCorrectionSyntax%,%ListOfDirectives%
	;remove first pipe
	StringTrimLeft, CaseCorrectionSyntax, CaseCorrectionSyntax, 1
return

;#############   Create indentation size depending on options   ###############
CreateIndentSize:
	;clear
	IndentSize =
	IndentContLine =

	;turn of autotrim to be able to assign Spaces and tabs
	AutoTrim, Off

	;Create indentation size depending on option
	if Indentation = 1
		IndentSize = %A_Tab%
	else
		Loop, %NumberSpaces%
			IndentSize = %IndentSize%%A_Space%

		;Create indentation for line continuation
	if IndentCont = 1
		Loop, %NumberIndentCont%
			IndentContLine = %IndentContLine%%A_Tab%
	else
		Loop, %NumberIndentCont%
			IndentContLine = %IndentContLine%%A_Space%

		;set autotrim to default
	AutoTrim, On
return

;#############   Reset all start values   #####################################
SetStartValues:
	String =                 ;string that holds temporarely the file content (with auto-indentation)
	Indent =                 ;indentation string
	IndentIndex = 0          ;Index of array IndentIncrement and IndentCommand
	InBlockComment := False  ;Status if loop is in a Blockcomment
	InsideContinuation := False
	InsideTab = 0
	EmptyLineCount = 0       ;Counts the Number of empty Lines for statistics
	TotalLineCount = 0       ;Counts the Number of total Lines for statistics
	CommentLineCount = 0     ;Counts the Number of comments Lines for statistics
	if CaseCorrectBuildInFunctions
		CaseCorrectFuncList = %BuildInFunctions%  ;CSV list of function names in current script including build in functions
	else
		CaseCorrectFuncList =                     ;CSV list of function names in current script
	CaseCorrectSubsList=     ;CSV list of subroutine names in current script
	Loop, 11{
		IndentIncrement%A_Index% =
		IndentCommand%A_Index% =
	}
return

;#############   Indent all dropped files   ###################################
GuiDropFiles:
	;store time for speed measurement
	OverAllStartTime = %A_TickCount%

	;get options
	Gui, Submit,NoHide

	;set words for case correction
	gosub, SetCaseCorrectionSyntax

	;create indentation
	gosub, CreateIndentSize

	OverAllCodeLineCount = 0
	OverAllTotalLineCount = 0
	OverAllCommentLineCount = 0
	OverAllCommentLineCount = 0

	;for each dropped file, read file line by line and indent each line
	Loop, Parse, A_GuiControlEvent, `n
	{ ;store time for speed measurement
		StartTime = %A_TickCount%

		;file
		FileToautoIndent = %A_LoopField%

		;reset start values
		gosub, SetStartValues

		;Read each line in the file and do indentation
		Loop, Read, %FileToautoIndent%
		{ ;remember original line with its identation
			AutoTrim, Off
			Original_Line = %A_LoopReadLine%
			AutoTrim, On

			;do indentation
			gosub, DoSyntaxIndentation
		}

		CaseCorrectSubsAndFuncNames()

		;paste file with auto-indentation into new file
		;  if Extension is empty, old file will be overwritten
		FileDelete, %FileToautoIndent%%Extension%
		FileAppend, %String%,%FileToautoIndent%%Extension%

		;write information
		LogText = %LogText%Indentation done for: %FileToautoIndent%`n
		if Statistic
			gosub, AddStatisticToLog
		else
			LogText = %LogText%`n
		GuiControl, ,Log , %LogText%
		ControlSend, %ClassLog%, ^{End}, %GuiUniqueID%
	}
	if Statistic {
		LogText = %LogText%=====Statistics:=======`n
		LogText = %LogText%=====over all files====`n
		LogText = %LogText%Lines with code: %A_Tab%%A_Tab%%OverAllCodeLineCount%`n
		LogText = %LogText%Lines with comments: %A_Tab%%OverAllCommentLineCount%`n
		LogText = %LogText%Empty Lines: %A_Tab%%A_Tab%%OverAllEmptyLineCount%`n
		LogText = %LogText%Total Number of Lines: %A_Tab%%OverAllTotalLineCount%`n
		;time for speed measurement
		OverAllTimeNeeded := (A_TickCount - OverAllStartTime) / 1000
		LogText = %LogText%Total Process time: %A_Tab%%OverAllTimeNeeded%[s]`n`n
		GuiControl, ,Log , %LogText%
		ControlSend, %ClassLog%, ^{End}, %GuiUniqueID%
	}
return

;#############   Add statistics to log   ######################################
AddStatisticToLog:
	;calculate lines of code
	CodeLineCount := TotalLineCount - CommentLineCount - EmptyLineCount

	OverAllCodeLineCount    += CodeLineCount
	OverAllTotalLineCount   += TotalLineCount
	OverAllCommentLineCount += CommentLineCount
	OverAllEmptyLineCount   += EmptyLineCount

	;add information
	LogText = %LogText%=====Statistics:=====`n
	LogText = %LogText%Lines with code: %A_Tab%%A_Tab%%CodeLineCount%`n
	LogText = %LogText%Lines with comments: %A_Tab%%CommentLineCount%`n
	LogText = %LogText%Empty Lines: %A_Tab%%A_Tab%%EmptyLineCount%`n
	LogText = %LogText%Total Number of Lines: %A_Tab%%TotalLineCount%`n
	;time for speed measurement
	TimeNeeded := (A_TickCount - StartTime) / 1000
	LogText = %LogText%Process time: %A_Tab%%TimeNeeded%[s]`n`n
return

;#############   Indent file from command line   ##############################
IndentFile:
	;set words for case correction
	gosub, SetCaseCorrectionSyntax

	;create indentation
	gosub, CreateIndentSize

	;file
	FileToautoIndent = %param_in%

	;reset start values
	gosub, SetStartValues

	;Read each line in the file and do indentation
	Loop, Read, %FileToautoIndent%
	{ ;remember original line with its identation
		AutoTrim, Off
		Original_Line = %A_LoopReadLine%
		AutoTrim, On

		;do indentation
		gosub, DoSyntaxIndentation
	}

	CaseCorrectSubsAndFuncNames()

	;remove old file and paste with auto-indentation into same file
	FileDelete, %FileToautoIndent%
	FileAppend, %String%, %FileToautoIndent%

	;write information to log file
	LogText = Indentation done for: %FileToautoIndent%`n
	if Statistic
		gosub, AddStatisticToLog
	FileAppend , %LogText%, %param_log%
return

;#############   Create indentation for next loop depending on IndentIndex   ##
SetIndentForNextLoop:
	;clear
	Indent =
	if IndentIndex  1) {
		;the following is not very robust but it will serve for most cases that a ";" is inside an := or () expression
		; limitations:
		; - comments that include a " on an := expression line
		; - comments that include a ") on an ()expression line
		StringMid,CharBeforeSemiColon, Line, StartPos - 1 , 1
		if (CharBeforeSemiColon = "``")            ;semicolon is Escaped
			continue
		else if ( 0  StartPos
			AND 0  0)
	IndentIndex += %Index%
else if (Index  "{" AND IndentIndex = 1 AND   FunctionName  "") {
		FunctionName =         ; then that previous line is not a function definition.
		IndentIndex = 0         ; set back the indentation, which was previously set.
		gosub, SetIndentForNextLoop
	}

	;Assume line is not a function
	FirstWordIsFunction := False
	;If no indentation and bracket not as first character it might be a function
	if ( IndentIndex = 0 And InStr(FirstWord,"(") > 0 )
		FirstWordIsFunction := ExtractFunctionName(FirstWord,InStr(FirstWord,"("),FunctionName)

	LineIsTabSpecialIndentStart := False
	LineIsTabSpecialIndent      := False
	LineIsTabSpecialIndentEnd   := False
	if (ChkSpecialTabIndent AND FirstWord = "Gui") {
		if (InStr(SecondWord,"add") And ThirdWord = "tab")
			LineIsTabSpecialIndentStart := True
		else if (InStr(SecondWord,"tab")) {
			if ThirdWord is Space
				LineIsTabSpecialIndentEnd := True
			else
				LineIsTabSpecialIndent := True
		}
	}

	;turn AutoTrim off, to be able to process tabs and spaces
	AutoTrim, Off

	;###### Start to adjust indentation ##########

	if FirstWord in %ListOfDirectives%         ;line is directive
	{ Loop, Parse, CaseCorrectionSyntax, `,
			StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All
		String = %String%%Line%`n
	}
	else if FirstChar in #,!,^,+,,*,~,$     ;line is Hotkey (has be be after directives due to the #)
	{ if InStr(FirstWord,"::"){
			String = %String%%Line%`n
			MemorizeIndent("Sub",1,-1)
		}
	}
	else if (FirstChar = "," OR FirstTwoChars = "||" OR FirstTwoChars = "&&"
		OR FirstWord = "and" OR FirstWord = "or" )                     ;line is a implicit continuation
		String = %String%%Indent%%IndentContLine%%Line%`n
	else if (FirstChar = ")" and InsideContinuation) {  ;line is end of a continuation block
		gosub, SetIndentOfLastBracket
		String := String . Indent . iif(Style=1,"",IndentSize) . Line . "`n"
		;IndentIndex doesn't need to be reduced, this is done inside SetIndentOfLastBracket
		InsideContinuation := False
	}
	else if InsideContinuation {                ; line is inside a continuation block
		if AdjustContinuation
			String = %String%%Indent%%Line%`n
		else
			String = %String%%Original_Line%`n
	}
	else if (FirstChar = "(") {                 ;line is beginning of a continuation block
		String := String . Indent . iif(Style>1,IndentSize) . Line . "`n"
		MemorizeIndent("(",iif(Style=2,2,1),+1)
		AdjustContinuation := False
		if ( InStr(StripedLine, "LTrim") > 0 AND InStr(StripedLine, "RTrim0") = 0)
			AdjustContinuation := True
		InsideContinuation := True                  ;allow nested cont's
	}
	else if LineIsTabSpecialIndentStart {                   ;line is a "Gui, Add, Tab" line
		String = %String%%Indent%%Line%`n
		MemorizeIndent("AddTab",1,+1)
	}
	else if LineIsTabSpecialIndent {                        ;line is a "Gui, Tab, TabName" line
		gosub, SetIndentOfLastAddTaborBracket
		String = %String%%Indent%%IndentSize%%Line%`n
		MemorizeIndent("Tab",1,+2)
	}
	else if LineIsTabSpecialIndentEnd {                     ;line is a "Gui, Tab" line
		gosub, SetIndentOfLastAddTaborBracket
		String = %String%%Indent%%Line%`n
	}
	else if (FirstWordLastChar = ":") {   ;line is start of subroutine or Hotkey
		if (InStr(FirstWord,"::") = 0) {     ;line is start of a subroutine
			StringTrimRight, SubroutineName, Line, 1
			if SubroutineName not in %CaseCorrectSubsList%
				CaseCorrectSubsList = %CaseCorrectSubsList%,%SubroutineName%
		}
		String = %String%%Line%`n
		MemorizeIndent("Sub",1,-1)
	}
	else if (FirstChar = "}") {             ;line is end bracket block
		if (FirstWord = "else"){            ;it uses OTB and must be a "}[ ]else [xxx] [{]"
			;do the case correction
			StringReplace, Line, Line, else, else
			Loop, Parse, CaseCorrectionSyntax, `,
				StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All

			gosub, SetIndentOfLastCurledBracket
			IndentIndex --
			gosub, SetIndentOfLastIfOrOneLineIf

			;else line is also start of If-Statement
			if SecondWord in %ListOfIFCommands%          ;Line is an old  If-statement
			{
				StringReplace, Line, Line, if, if
				StringReplace, ParsedCommand, StripedLine, ```, ,,All
				;Search if a third comma exists
				StringGetPos, ParsedCommand, ParsedCommand , `, ,L3
				if ErrorLevel                           ;Line is an old If-statement
					MemorizeIndent("If",iif(Style=1,0,1),+1)
			}else if (SecondWord = "if") {              ;Line is a Normal if-statement
				StringReplace, Line, Line, if, if
				MemorizeIndent("If",iif(Style=1,0,1),+1)
				if (LastChar = "{")                     ;it uses OTB
					MemorizeIndent("{",iif(Style=3,0,1),+1)
			}else if (SecondWord = "loop"){             ;Line is the begining of a loop
				StringReplace, Line, Line, loop, Loop
				MemorizeIndent("Loop",iif(Style=1,0,1),+1)
				if (LastChar = "{")                     ;it uses OTB
					MemorizeIndent("{",iif(Style=3,0,1),+1)
			}else if SecondWord is Space                 ;just a plain Else
			{
				MemorizeIndent("Else",iif(Style=1,0,1),+1)
				if (LastChar = "{")                     ;it uses OTB
					MemorizeIndent("{",iif(Style=3,0,1),+1)
			}
			;if all the previous if didn't satisfy,
			; the Line is an else with any command following,
			;  then nothing has to be done
			String = %String%%Indent%%Line%`n
		}else {                               ;line is end bracket block without OTB
			gosub, SetIndentOfLastCurledBracket
			String = %String%%Indent%%Line%`n
			IndentIndex --
		}
	}
	else if (FirstChar = "{") {                   ;line is start of bracket block
		;check if line is start of a function implementation
		if ( IndentIndex = 1 AND  FunctionName  "" )
		;then add function name to list if not in it already
			if FunctionName not in %CaseCorrectFuncList%
				CaseCorrectFuncList = %CaseCorrectFuncList%,%FunctionName%(
			;clear function name
		FunctionName =

		IndentIndex ++
		IndentCommand%IndentIndex% = {
		IndentIncrement%IndentIndex% := iif(Style=3,0,1)

		;check if command after { is if or loop
		if (FirstWord = "loop"){                   ;line is start of Loop block after the {
			;do the case correction
			StringReplace, Line, Line, loop, Loop
			Loop, Parse, CaseCorrectionSyntax, `,
				StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All

			MemorizeIndent("Loop",iif(Style=1,0,1),+1)
			if (LastChar = "{")                     ;it uses OTB
				MemorizeIndent("{",iif(Style=3,0,1),+1)
			;assuming that there are no old one-line if-statements following a {
		}else if FirstWord in %ListOfIFCommands%  ;line is start of old If-Statement after the {
		{
			;do the case correction
			StringReplace, Line, Line, if, if, 1
			Loop, Parse, CaseCorrectionSyntax, `,
				StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All

			MemorizeIndent("If",iif(Style=1,0,1),+1)
		}else if (FirstWord = "if"){                ;line is start of If-Statement after the {
			;do the case correction
			StringReplace, Line, Line, if, if, 1
			Loop, Parse, CaseCorrectionSyntax, `,
				StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All

			MemorizeIndent("If",iif(Style=1,0,1),+1)
			if (LastChar = "{")                     ;it uses OTB
				MemorizeIndent("{",iif(Style=3,0,1),+1)
		}
		String = %String%%Indent%%Line%`n
	}
	else if FirstWordIsFunction {                ;line is function
		String = %String%%Line%`n
		;注释掉这一行可使函数后面的花括号不缩进(花括号包围的内容依然缩进)
		;~ MemorizeIndent("Func",1,-1)

		if (LastChar = "{") {                 ;it uses OTB
			if FunctionName not in %CaseCorrectFuncList%
				CaseCorrectFuncList = %CaseCorrectFuncList%,%FunctionName%(
			;clear function name
			FunctionName =

			MemorizeIndent("{",iif(Style=3,0,1),+1)
		}
	}
	else if (FirstWord = "loop") {         ;line is start of Loop block
		;do the case correction
		StringReplace, Line, Line, loop, Loop
		Loop, Parse, CaseCorrectionSyntax, `,
			StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All

		PrevCommand := IndentCommand%IndentIndex%
		if (PrevCommand = "If"){               ;line is First line of a one-line If-block
			String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
			MemorizeIndent("OneLineIf",iif(Style=2,2,1))
		}else if (PrevCommand = "Else"){         ;Line is First line of a one-line Else-block
			String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
			MemorizeIndent("OneLineElse",iif(Style=2,2,1))
		}else if (PrevCommand = "Loop"){         ;Line is First line of a one-line loop-block
			String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
			MemorizeIndent("OneLineLoop",iif(Style=2,2,1))
		}else {                              ;it follows a Sub , { , OneLineCommand or nothing
			gosub, SetIndentToLastSubBracketOrTab
			String = %String%%Indent%%Line%`n
		}
		MemorizeIndent("Loop",iif(Style=1,0,1),+1)
		if (LastChar = "{")                  ;it uses OTB
			MemorizeIndent("{",iif(Style=3,0,1),+1)
	}
	else if FirstWord in %ListOfIFCommands% ;line is start of old If-Statement
	{
		;do the case correction
		StringReplace, Line, Line, if, if
		Loop, Parse, CaseCorrectionSyntax, `,
			StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All

		PrevCommand := IndentCommand%IndentIndex%

		;eliminate comments and escaped commas
		ParsedCommand := StripCommentsFromLine(Line)
		StringReplace, ParsedCommand, ParsedCommand, ```, ,,All
		;Search if a third comma exists
		StringGetPos, ParsedCommand, ParsedCommand , `, ,L3
		if ( ErrorLevel = 0 ){                 ;Line is a old one-line If-statement
			if (PrevCommand = "If"){           ;Line is a one-line command of an If-block
				String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
				MemorizeIndent("OneLineIf",0)
				MemorizeIndent("OneLineCommand",0,+1)
			}else if (PrevCommand = "Else"){       ;Line is a one-line command of an Else-block
				String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
				MemorizeIndent("OneLineElse",0)
				MemorizeIndent("OneLineCommand",0,+1)
			}else if (PrevCommand = "Loop"){       ;Line is a one-line command of a loop-block
				String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
				MemorizeIndent("OneLineLoop",0)
				MemorizeIndent("OneLineCommand",0,+1)
			}else {                            ;line is Normal one-line if-statement
				gosub, SetIndentToLastSubBracketOrTab
				String = %String%%Indent%%Line%`n
			}
		}else {                              ;Line is not an one-line if-statement
			if (PrevCommand = "If"){              ;Line is First line of an one-line If-block
				String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
				MemorizeIndent("OneLineIf",iif(Style=2,2,1))
			} else if (PrevCommand = "Else"){       ;Line is First line of a one-line Else-block
				String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
				MemorizeIndent("OneLineElse",iif(Style=2,2,1))
			} else if (PrevCommand = "Loop"){       ;Line is First line of a one-line loop-block
				String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
				MemorizeIndent("OneLineLoop",iif(Style=2,2,1))
			} else {                             ;it follows a Sub , { , OneLineCommand or nothing
				gosub, SetIndentToLastSubBracketOrTab
				String = %String%%Indent%%Line%`n
			}
			MemorizeIndent("If",iif(Style=1,0,1),+1)
		}
	}
	else if (FirstWord = "if"){                  ;line is start of a Normal If-Statement
		;do the case correction
		StringReplace, Line, Line, if, if
		Loop, Parse, CaseCorrectionSyntax, `,
			StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All

		PrevCommand := IndentCommand%IndentIndex%
		if (PrevCommand = "If"){              ;Line is First line of a one-line If-block
			String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
			MemorizeIndent("OneLineIf",iif(Style=2,2,1))
		} else if (PrevCommand = "Else"){       ;Line is First line of a one-line Else-block
			String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
			MemorizeIndent("OneLineElse",iif(Style=2,2,1))
		} else if (PrevCommand = "Loop"){       ;Line is First line of a one-line loop-block
			String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
			MemorizeIndent("OneLineLoop",iif(Style=2,2,1))
		} else {                             ;it follows a Sub , { , OneLineCommand or nothing
			gosub, SetIndentToLastSubBracketOrTab
			String = %String%%Indent%%Line%`n
		}
		MemorizeIndent("If",iif(Style=1,0,1),+1)
		if (LastChar = "{")                  ;it uses OTB
			MemorizeIndent("{",iif(Style=3,0,1),+1)
	}
	else if (FirstWord = "Else") {         ;line is a Else block
		;do the case correction
		StringReplace, Line, Line, else, else
		Loop, Parse, CaseCorrectionSyntax, `,
			StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All

		PrevCommand := IndentCommand%IndentIndex%
		if PrevCommand in OneLineCommand,Else
			gosub, SetIndentOfLastIfOrOneLineIf

		;else line is also start of If-Statement
		if SecondWord in %ListOfIFCommands%          ;Line is an old  If-statement
		{
			StringReplace, Line, Line, if, if
			StringReplace, ParsedCommand, StripedLine, ```, ,,All
			;Search if a third comma exists
			StringGetPos, ParsedCommand, ParsedCommand , `, ,L3
			if ErrorLevel {                         ;Line is an old one-line If-statement
				MemorizeIndent("If",1,+1)
			}
		}else if (SecondWord = "if"){               ;Line is a Normal if-statement
			StringReplace, Line, Line, if, if
			MemorizeIndent("If",iif(Style=1,0,1),+1)
			if (LastChar = "{")                  ;it uses OTB
				MemorizeIndent("{",iif(Style=3,0,1),+1)
		}else if (Secondword = "loop"){             ;else is followed by a loop command
			;do the case correction
			StringReplace, Line, Line, loop, Loop
			MemorizeIndent("Loop",iif(Style=1,0,1),+1)
			if (LastChar = "{")                  ;it uses OTB
				MemorizeIndent("{",iif(Style=3,0,1),+1)
		}else if SecondWord is Space                 ;just a plain Else
		{ MemorizeIndent("Else",iif(Style=1,0,1),+1)
			if (LastChar = "{")                  ;it uses OTB
				MemorizeIndent("{",iif(Style=3,0,1),+1)
		}
		;if all the previous if didn't satisfy,
		; the Line is an else with any command following,
		;  then nothing has to be done
		String = %String%%Indent%%Line%`n
	}
	else {                                        ;line is a Normal command or return
		;do the case correction
		Loop, Parse, CaseCorrectionSyntax, `,
			StringReplace, Line, Line, %A_LoopField%, %A_LoopField%, All

		PrevCommand := IndentCommand%IndentIndex%
		if (PrevCommand = "If"){             ;Line is a one-line command of an If-block
			String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
			MemorizeIndent("OneLineIf",0)
			MemorizeIndent("OneLineCommand",0,+1)
		}else if (PrevCommand = "Else"){      ;Line is a one-line command of an Else-block
			String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
			MemorizeIndent("OneLineElse",0)
			MemorizeIndent("OneLineCommand",0,+1)
		}else if (PrevCommand = "Loop"){      ;Line is a one-line command of a loop-block
			String := String . Indent . iif(Style3,IndentSize) . Line . "`n"
			MemorizeIndent("OneLineLoop",0)
			MemorizeIndent("OneLineCommand",0,+1)
		}else if (PrevCommand = "Func"){      ;Line follows a function call   ??? is this ever True?
			String = %String%%Line%`n
			IndentIndex = 0
		}else {                               ;line is Normal command or return
			gosub, SetIndentToLastSubBracketOrTab
			PrevCommand := IndentCommand%IndentIndex%

			;if command is end of subroutine (return) no indentation, otherwise keep indentation
			if (FirstWord = "return" AND PrevCommand = "Sub") {
				String = %String%%Line%`n
				IndentIndex = 0
			}else
			;String := String . Indent . iif(Style=2,IndentSize) . Line . "`n"
				String = %String%%Indent%%Line%`n
		}
	}
	gosub, FinishThisLine
return

FinishThisLine:
	;###### End of change in indentation ##########

	;turn AutoTrim on, to get back to default behaviour
	AutoTrim, On

	;Show MsgBox for debug
	if DebugMode
		gosub, ShowDebugStrings

	;get Indentation for next loop
	gosub, SetIndentForNextLoop
return


;#############   Show MsgBox for debug   ######################################
ShowDebugStrings:
	msgtext = line#: %TotalLineCount%`n
	msgtext = %msgtext%Style: %Style%`n
	msgtext = %msgtext%line: %Line%`n
	msgtext = %msgtext%stripped line: %CommandLine%`n
	msgtext = %msgtext%Indent: |%Indent%|`n
	msgtext = %msgtext%1stChar: >%FirstChar%%FirstWord%%SecondWord%%ThirdWord%%FirstWordLastChar%%FunctionName%StrLen(FunctionName))
	FunctionName =

return StrLen(FunctionName)
}

;#############   Do CaseCorrection for Functions and Subroutines   ############
CaseCorrectSubsAndFuncNames() {
global
LenString := StrLen(String)

;remove first comma
StringTrimLeft, CaseCorrectFuncList, CaseCorrectFuncList, 1
StringTrimLeft, CaseCorrectSubsList, CaseCorrectSubsList, 1

;loop over all remembered function names
Loop, Parse, CaseCorrectFuncList, CSV
{ FuncName := A_LoopField
	LenFuncName := StrLen(FuncName)

	;Loop through string to find all occurances of function names
	StartPos = 0
	Loop {
		StartPos := InStr(String,FuncName,0,StartPos + 1)
		if (StartPos > 0) {
			StringMid,PrevChar, String, StartPos - 1 , 1
			if PrevChar is not Alnum
				ReplaceName( String, FuncName, StartPos-1, LenString - StartPos + 1 - LenFuncName )
		} else
			break
	}
}

;loop over all remembered subroutine names
Loop, Parse, CaseCorrectSubsList, CSV
{ SubName := A_LoopField
	LenSubName := StrLen(SubName)

	;Loop through string to find all occurances of function names
	StartPos = 0
	Loop {
		StartPos := InStr(String,SubName,"",StartPos + 1)
		if (StartPos > 0) {
			StringMid,PrevChar, String, StartPos - 1 , 1
			StringMid,NextChar, String, StartPos + LenSubName, 1

			;if it is an exact match the char after the subroutine names has not to be a char
			if NextChar is not Alnum
			{ ;If previous character is a "g" and has TestStrings in same line replace the name.
				if ( PrevChar = "g" ) {
					TestAndReplaceSubName( String, SubName, "Gui,", LenString, LenSubName, StartPos)
					TestAndReplaceSubName( String, SubName, "Gui ", LenString, LenSubName, StartPos)

					;If previous character is something else then Alnum and has TestStrings in same line replace the name.
				}else if PrevChar is not Alnum
				{ TestAndReplaceSubName( String, SubName, "Gosub" , LenString, LenSubName, StartPos )
					TestAndReplaceSubName( String, SubName, "Menu"  , LenString, LenSubName, StartPos )
					TestAndReplaceSubName( String, SubName, "`:`:"  , LenString, LenSubName, StartPos )
					TestAndReplaceSubName( String, SubName, "Hotkey", LenString, LenSubName, StartPos )
				}
			}
		} else
			break
	}
}
}

TestAndReplaceSubName( ByRef string, Name, TestString, LenString, LenSubName, StartPos ) {
;find Positions of Teststring and LineFeed in String from the right side starting at routine position
StringGetPos, PosTestString, String, %TestString%, R , LenString - StartPos + 1
StringGetPos, PosLineFeed  , String,     `n      , R , LenString - StartPos + 1

;If %TestString% is in the same line do replace name
if ( PosLineFeed 

给TA捐赠
共{{data.count}}人
人已捐赠
其他

根据程序配置输入法V1.1505

2020-3-9 3:41:44

其他教程

桌面背景定时更换

2020-3-9 3:43:44

个人中心
购物车
优惠劵
有新私信 私信列表
搜索