50604cf0创建于 2016年3月21日历史提交
;
; File encoding:  UTF-8
;

RetrieveDocs(file)
{
	Util_Status("Parsing AutoHotkey script...")
	o := { contents: [] }
	SplitPath, file,, fileDir
	tmpWD := A_WorkingDir
	SetWorkingDir, %fileDir%
	files := [file]
	try
	{
		while files.MaxIndex()
		{
			file := FileOpen(q :=files.Remove(1), "r")
			
			while !file.AtEOF
			{
				line := RTrim(file.ReadLine(), " `t`r`n")
				tline := LTrim(line)
				if StrStartsWith(tline, "/*!")
				{
					indent := SubStr(line, 1, InStr(line, "/*!")-1)
					ReadChunk(file, o, indent)
				}
				if RegExMatch(tline, "i)^;!GenDocs-Import\s+(.+)$", tmp)
				{
					IfNotExist, %tmp1%
						throw Exception("File does not exist!", 1, tmp1)
					files.Insert(tmp1)
				}
			}
		}
		PackClasses(o.contents)
		SetWorkingDir, %tmpWD%
		return o
	}catch e
	{
		Util_Status("An error happened (" e.what ")! " e.message " | " e.extra, 1)
		SetWorkingDir, %tmpWD%
		Exit
	}
}

ReadChunk(file, lib, beg_indent)
{
	ent := {}, type := ""
	while !file.AtEOF
	{
		line := RTrim(file.ReadLine(), " `t`r`n")
		tline := LTrim(line)
		if tline =
			continue
		else if StrStartsWith(tline, "*/")
			break
		else if !StrStartsWith(line, beg_indent)
			throw Exception("Line with wrong indentation!")
		else if StrStartsWith(tline, "@")
			ent["attr_" SubStr(tline,2)] := 1
		else if tline = End of class
			type := "EndClass"
		else if RegExMatch(line, "^" beg_indent "(\s+)([a-zA-Z]+):\s*(.*)$", o)
		{
			if o2 in Library,Function,Constructor,Class,Method,Property,Page
			{
				type := o2, o2 := ""
				if type = Library
					ent := lib
			}
			;value := o3
			ReadValue(value := "", file, beg_indent o1 o1)
			if o2 !=
			{
				if o3
					value := o3 "`n" value
				StringTrimRight, value, value, 1
				ent[o2] := value
			}else
			{
				StringTrimRight, value, value, 1
				ent.name := o3, ent.description := value
			}
		}
	}
	
	if type =
		throw Exception("Element type not specified!")
	
	ent.type := type
	if type != Library
		lib.contents.Insert(ent)
}

ReadValue(ByRef value, file, indent)
{
	while !file.AtEOF
	{
		pos := file.Pos
		line := RTrim(file.ReadLine(), "`r`n")
		tline := LTrim(line)
		if !StrStartsWith(line, indent)
		{
			file.Pos := pos
			break
		}
		value .= SubStr(line, StrLen(indent)+1) "`n"
	}
}

PackClasses(cont)
{
	i := 1
	while i <= cont.MaxIndex()
	{
		if cont[i].type != "Class"
			goto _PC_cont
		last := "", depth := 1, j := i
		while j <= cont.MaxIndex()
		{
			j ++
			if cont[j].type = "EndClass"
			  && !--depth
			{
				last := j
				break
			}else if cont[j].type = "Class"
				depth ++
		}
		if !last || depth
			throw Exception("Endless class!")
		arr := (cont[i].contents := [])
		i ++
		if count := last-i
		{
			Loop, %count%
				arr.Insert(cont[i+A_Index-1])
			PackClasses(arr)
			cont.Remove(i, last-1)
		}
		cont.Remove(i)
		continue
		_PC_cont:
		i ++
	}
}