Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Simple Yaml Parser


  • Please log in to reply
9 replies to this topic
HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Yaml has got very simple syntax.
It is easy to read and use.
Yaml parser was build to give more possibilities than ini.
You can create Yaml database from text as well as from file, you can add, set get, delete keys, clone the database, insert existing sets of data to an existing database and much more.

If you never heard of yaml before, take a look here: Can you learn Yaml in five minutes?
:!: Note :!: - not all yaml syntax is suported.

DocumentationA subkey must be indented by 2 spaces (not Tab). If a key has got subkeys, it must not have values :!:
MainKey:
	SubKey:
		SubSubKey1: value1
		SubSubKey2: value2
		SubSubKeyList:
			- item1
			- item2
		[color=red]'[/color]Subkey with non alphanumeric characters[color=red]'[/color]: "multiple
 lines
 value"
Simple example:
yamlText= ;example yaml data
(
`%yaml 
--- testdata, this is a comment only
Settings:
  Size:
    width: 1
    height: 2
  Colors:
    background: blue
    foreground: black
    text: white
  ButtonText:
    Button1: AutoHotkey
    Button2: OK
)
yml:=Yaml_Init(yamlText) ;create database from text
MsgBox % Yaml_Get(yml,"Settings.Colors.background") ;get a key
Yaml_Add(yml,"Settings.ButtonText.Button3","Exit") ;add a key
MsgBox % Yaml_Save(yml) ;Show dump of database
Advanced Example
yamlText= ;example yaml data
(
`%yaml 
--- testdata, this is a comment only
Settings:
  Size:
    width: 1
    height: 2
  Colors:
    background: blue
    foreground: black
    text: white
  ButtonText:
    Button1: AutoHotkey
    Button2: OK
'Test with space':
  item: value
)

y:=Yaml_Init("") ;create empty Yaml database
Loop 2 ;a new Key will be added to the database and above data will be appended/inserted
	Yaml_Add(y,"yaml" A_Index),Yaml_Insert(y,YamlText,"yaml" A_Index)
Loop,2 ;read some data from each key
	MsgBox % Yaml_Get(y,"yaml" A_Index ".Settings.ButtonText.Button1")
MsgBox % Yaml_Dump(y,var) ;dump the database to a variable
MsgBox % Yaml_Save(y,"x:\Settings.yml") ;save database to a file
ExitApp
Yaml to Gui
yaml=
(
Gui:
  Add:
    Button:
      Test:
        - x0 y0 w100 h30 gTest
      Hello:
        - x200 y30 xs w200 h25 gTest
    ListView:
      'Test|new|other':
        - w200 r20 gTest vListView
)
y:=Yaml_Init(yaml)
Loop % Yaml_Get(y,"Gui.0"){
  p1:=Yaml_Get(y,"Gui." A_Index)
  Loop % Yaml_Get(y,"Gui." p1 "." 0){
    p2:=Yaml_Get(y,"Gui." p1 "." A_Index)
    Loop % Yaml_Get(y,"Gui." p1 "." p2 ".0")
    {
      p4:=Yaml_Get(y,"Gui." p1 "." p2 "." A_Index)
      p3:=Yaml_Get(y,"Gui." p1 "." p2 "." Yaml_Get(y,"Gui." p1 "." p2 "." A_Index) ".1")
      Gui,%p1%,%p2%,%p3%,%p4%
    }
  }
}
LV_Add("","test","test","test")
Gui,Show
Return
GuiClose:
ExitApp
Test:
MsgBox
Return


Functions
Yaml_Add(pYaml,key1="",key2=""){
	If (recursive:=InStr(key1,".")=1 ? 1 : 0)
		StringTrimLeft,key1,key1,1
	If InStr(key1,".")
		parent:=SubStr(key1,1,InStr(key1,".",1,0)-1)
	StringTrimLeft,key,key1,% InStr(key1,".",1,0)
	If (parent!="" && !Yaml_Exist(pYaml,key1))
		Yaml_Add(pYaml,"." parent,key)
	If !Yaml_Exist(pYaml,key1){
		count:=Yaml_Get(pYaml,parent!="" ? (parent "." 0) : 0)
		count++
		Yaml_Assign(pYaml,parent!="" ? (parent "." 0) : 0,count)
		Yaml_Assign(pYaml,parent!="" ? (parent "." count) : count,key)
	} else if (!recursive){
		count:=Yaml_Get(pYaml,key1 "." 0)
		If (count=""){
			count=2
			Yaml_Assign(pYaml,key1 ".1",Yaml_Get(pYaml,key1))
		} else
			count++
		Yaml_Assign(pYaml,key1 "." 0,count)
		Yaml_Assign(pYaml,key1 "." count,key2)
	}
	key2:=(RegExMatch(Key2,"^\s?\w+\s?$") ? key2 : "'" key2 "'")
	Yaml_Assign(pYaml,key1,Yaml_Get(pYaml,key1)="" ? key2 : Yaml_Get(pYaml,key1) "," key2)
}
Yaml_Exist(pYaml,Key=""){
	VarSetCapacity(var,16,0),NumPut(8, var)
	If A_IsUnicode
		wStr:=Key
	else
		VarSetCapacity(wStr, StrLen(Key)*2+1,0)
		,DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "UInt",&Key, "Int",-1, "UInt",&wStr, "Int",StrLen(Key)+1)
	NumPut(DllCall("oleaut32\SysAllocString","Str",wStr),var,8)
	DllCall(NumGet(NumGet(pYaml+0)+48), "UInt",pYaml, "UInt",&var, "IntP",bExist)
	DllCall("oleaut32\SysFreeString", "UInt",NumGet(var,8)),NumPut(0,var,8)
	Return bExist
}

Yaml_Dump(pYaml,ByRef Output,key=""){
	If (key=""){
		Loop % Yaml_Get(pYaml,0)
		{
			mainkey:=Yaml_Get(pYaml,A_Index)
			Output .= Yaml_Get(pYaml,mainkey ".")="" ? "" : Yaml_Get(pYaml,mainkey ".") "`n" ;"---`r`n"
			value:=Yaml_Get(pYaml,mainkey)
			Output .= (RegExMatch(mainkey,"^\w+$") ? mainkey : ("'" mainkey "'")) ":"
			if (sub:=Yaml_Get(pYaml,mainkey "." 1)){
				if !Yaml_Exist(pYaml,mainkey "." sub){
					Output .= "`n"
					Loop % Yaml_Get(pYaml,mainkey ".0"){
						value:=Yaml_Get(pYaml,mainkey "." A_Index)
						Output .= "  - " (RegExMatch(value,"^\w+$") ? value : "'" value "'") "`n"
					}
					Continue
				} else Output .= "`n"
			} else Output .= " " value "`n"
			Yaml_Dump(pYaml,Output,"." mainkey)
		}
		return Output
	} else {
		If (-1 < (start:=RegExMatch(key,"[^\.]")-1)){
			Loop % start*2
				recurse .= A_Space
			StringTrimLeft,_key,key,%start%
		} else _key:=key
		Loop % Yaml_Get(pYaml,_key "." 0){
			key1:=Yaml_Get(pYaml,_key "." A_Index)
			Output .= Yaml_Get(pYaml,_key "." key1 ".")="" ? "" : Yaml_Get(pYaml,_key "." key1 ".") "`n"
			value:=Yaml_Get(pYaml,_key "." key1)
			Output .= recurse (RegExMatch(key1,"^\w+$") ? key1 : ("'" key1 "'")) ":"
			if (sub:=Yaml_Get(pYaml,_key "." key1 ".1")){
				if !Yaml_Exist(pYaml,_key "." key1 "." sub){
					Output .= "`n"
					Loop % Yaml_Get(pYaml,_key "." key1 ".0"){
						value:=Yaml_Get(pYaml,_key "." key1 "." A_Index)
						Output .= recurse "  - " value "`n"
					}
					Continue
				} else Output .= "`n"
			} else Output .= " " value "`n"
			Yaml_Dump(pYaml,Output, "." key "." key1)
		}
	}
	Return output
}

Yaml_Save(pYaml,ToFile=""){
	Yaml_Dump(pYaml,file)
	If (ToFile!="" && FileExist(ToFile)){
		StringReplace,savefile,file,`n,`r`n,A
		FileMove,%ToFile%,%ToFile%.bkp.yaml
		If FileExist(ToFile){
			MsgBox Error Saving File
		}
		FileAppend,%savefile%,%ToFile%
		If (ErrorLevel){
			MsgBox Error Saving File
		}
		FileDelete,%ToFile%.bkp.yaml
		If (ErrorLevel){
			MsgBox Error Saving File
			FileDelete,%ToFile%.bkp
			FileMove,%ToFile%.bkp.yaml,%ToFile%
		}
	} else if (ToFile!=""){
		StringReplace,savefile,file,`n,`r`n,A
		FileAppend,%savefile%,%ToFile%
			If (ErrorLevel){
				MsgBox Error Saving File
			}
	}
	Return file
}

Yaml_Clone(pYaml){
	static CLSIDString:="{EE09B103-97E0-11CF-978F-00A02463E06F}", IIDString:="{42C642C1-97E1-11CF-978F-00A02463E06F}", StrGet:="StrGet"
	If (!Init && Init:=1){ ;Initialize COM and create database
		DllCall("ole32\CoInitialize", "UInt",0),VarSetCapacity(var1, 16),VarSetCapacity(var2, 16)
		NumPut(8, var1),NumPut(8, var2),VarSetCapacity(CLSID, 16),VarSetCapacity(wKey, 79),VarSetCapacity(IID, 16)
		If A_IsUnicode
			DllCall("ole32\CLSIDFromString", "Str",CLSIDString, "Str",CLSID)
			,DllCall("ole32\CLSIDFromString", "Str",IIDString, "Str",IID)
		else
			DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "UInt",&CLSIDString, "Int",-1, "UInt",&wKey, "Int",39)
			,DllCall("ole32\CLSIDFromString", "Str",wKey, "Str",CLSID)
			,DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "UInt",&IIDString, "Int",-1, "UInt",&wKey, "Int",39)
			,DllCall("ole32\CLSIDFromString", "Str",wKey, "Str",IID)
	}
	DllCall("ole32\CoCreateInstance", "Str",CLSID, "UInt",0, "UInt",5, "Str",IID, "UIntP",_pYaml) ; CLSCTX=5
	,DllCall(NumGet(NumGet(_pYaml+0)+72), "UInt",_pYaml, "Int",1)
	VarSetCapacity(var1, 16),VarSetCapacity(var2, 16),NumPut(8, var1),NumPut(8, var2)
	DllCall(NumGet(NumGet(pYaml+0)+80), "UInt",pYaml, "UIntP",penum) ; create key-list in penum
	Loop {
		If (DllCall(NumGet(NumGet(penum+0)+12), "UInt",penum, "UInt",1, "UInt",&var1, "UInt",0)) {
			DllCall(NumGet(NumGet(penum+0)+8), "UInt",penum)   ; END: destroy key-list
			penum=                                                  ; signal end of list
			ErrorLevel=                                                  ; empty
			Return _pYaml     		                                           
		}
		If A_IsUnicode
			wStr:=%StrGet%(NumGet(var1,8))
		else
			nLen := DllCall("WideCharToMultiByte", "UInt",0, "UInt",0, "UInt",NumGet(var1,8), "Int",-1, "UInt",0, "Int",0, "UInt",0, "UInt",0)
			,VarSetCapacity(wKey, nLen)
			,DllCall("WideCharToMultiByte", "UInt",0, "UInt",0, "UInt",NumGet(var1,8), "Int",-1, "Str",wKey, "Int",nLen, "UInt",0, "UInt",0)
		DllCall("oleaut32\SysFreeString", "UInt",NumGet(var1,8)),NumPut(0,var1,8)
		Yaml_Assign(_pYaml,wKey,Yaml_Get(pYaml,wKey))
	}
}

Yaml_Get(pYaml,key1=""){
	static StrGet:="StrGet"
	VarSetCapacity(var1, 16),VarSetCapacity(var2, 16),NumPut(8, var1),NumPut(8, var2)
	If A_IsUnicode
		wStr:=key1
	else
		VarSetCapacity(wStr, StrLen(Key1)*2+1,0)
		,DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "UInt",&Key1, "Int",-1, "UInt",&wStr, "Int",StrLen(Key1)+1)
	NumPut(DllCall("oleaut32\SysAllocString","Str",wStr),var1,8)
	DllCall(NumGet(NumGet(pYaml+0)+48), "UInt",pYaml, "UInt",&var1, "IntP",bExist)
	If bExist {
		DllCall(NumGet(NumGet(pYaml+0)+36), "UInt",pYaml, "UInt",&var1, "UInt",&var2)
		If (NumGet(var2,8)=0xcdcdcdcd) ;uninitialized = empty string
			Return
		If A_IsUnicode
			Key2:=%StrGet%(NumGet(var2,8))
		else
			nLen := DllCall("WideCharToMultiByte", "UInt",0, "UInt",0, "UInt",NumGet(var2,8), "Int",-1, "UInt",0, "Int",0, "UInt",0, "UInt",0)
			,VarSetCapacity(Key2, nLen,0)
			,DllCall("WideCharToMultiByte", "UInt",0, "UInt",0, "UInt",NumGet(var2,8), "Int",-1, "Str",Key2, "Int",nLen, "UInt",0, "UInt",0)
		DllCall("oleaut32\SysFreeString", "UInt",NumGet(var2,8)),NumPut(0,var2,8)
	}
	DllCall("oleaut32\SysFreeString", "UInt",NumGet(var1,8)),NumPut(0,var1,8)
	Return Key2
}
Yaml_Set(pYaml,key1="",key2=""){
	If !Yaml_Exist(pYaml,key1){
		Yaml_Add(pYaml,key1,key2)
		return
	}
	Yaml_Assign(pYaml,key1,key2)
	Return
}
Yaml_Assign(pYaml,key1,key2=""){
	Loop % (2){
		VarSetCapacity(var%A_Index%,16,0),NumPut(8,var%A_Index%)
		If A_IsUnicode
			wStr:=Key%A_Index%
		else
			VarSetCapacity(wStr, StrLen(Key%A_Index%)*2+1,0)
			,DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "UInt",&Key%A_Index%, "Int",-1, "UInt",&wStr, "Int",StrLen(Key%A_Index%)+1)
		NumPut(DllCall("oleaut32\SysAllocString","Str",wStr),var%A_Index%,8)
	}
	DllCall(NumGet(NumGet(pYaml+0)+32), "UInt",pYaml, "UInt",&var1, "UInt",&var2)  ; 8 (Set0 -> 7)
	Loop 2
		DllCall("oleaut32\SysFreeString", "UInt",NumGet(var%A_Index%,8)),NumPut(0,var%A_Index%,8)
}
Yaml_Insert(_pYaml,Yaml_File,MainItem0){
	If FileExist(Yaml_File){
		FileRead,Yaml_File_,%Yaml_File%
		If (ErrorLevel){
			MsgBox Error Reading File
			Return
		}
	} else Yaml_File_:=Yaml_File
	Loop,Parse,MainItem0,.
	{
		space.=A_Space A_Space
		_depth:=A_Index-1
		MainItem%_depth%:=A_LoopField
	}
	Loop,Parse,Yaml_File_,`n,`r
	{
		If A_LoopField=
			Continue
		if !create
			Key1:="",Key2:="",Key3:="",Item:=""
		If (!create){
			RegExMatch(A_LoopField,"^\s+-\s(.*)$",Key)
			If (Key1!=""){
				count:=Yaml_Get(_pYaml,LastItem ".0")
				count++
				Yaml_Assign(_pYaml,LastItem "." count,Key1)
				Yaml_Assign(_pYaml,LastItem ".0", count)
				item:=Yaml_Get(_pYaml,LastItem)
				Yaml_Assign(_pYaml,LastItem,item="" ? Key1 : item "," key1)
				Continue
			}
			Loop 3
				Key%A_Index%=
			RegExMatch(A_LoopField,"^(\s*)(\w+)\s?:\s?(.*)\s?$",Key)
			If (Key2=""){
				Loop 3
					 Key%A_Index%=
				RegExMatch(A_LoopField,"^(\s*)'(.+)':\s?(.*)\s?$",Key)
			}
			If (Key2=""){
				LastLine.=Space A_LoopField "`n"
				Continue
			}
			If (SubStr(LastLine,0)="`n")
				StringTrimRight,LastLine,LastLine,1
			depth:=Round(Strlen(Key1)/2,0)+_depth+1
			MainItem%depth%:=Key2
			Item:=MainItem0
			While % ((i:=A_Index) && depth>A_Index)
				Item.= "." . MainItem%i%
			If !Yaml_Exist(_pYaml,Item "." key2){
				MainItem:=Yaml_Get(_pYaml,Item)
				count:=Yaml_Get(_pYaml,Item . ".0")
				count++
				Yaml_Assign(_pYaml,Item . ".0",count)
				Yaml_Assign(_pYaml,Item . "." . count,key2)
				Yaml_Assign(_pYaml,Item,MainItem . (MainItem="" ? "" : ",") . (RegExMatch(Key2,"^\s?\w+\s?$") ? key2 : "'" key2 "'"))
			}
			Item.="." . key2
			Yaml_Assign(_pYaml,Item,key3)
			LastItem:=Item
			If LastLine!=
				Yaml_Assign(_pYaml,Item . ".",LastLine),LastLine:=""
		} else 
			Yaml_Assign(_pYaml,Item,Yaml_Get(_pYaml,Item) . A_LoopField)
		If RegExMatch(Key3,"^\s*""")
			create:=1
		if (create && RegExMatch(A_LoopField,"""\s*$"))
			create:=0
	}
}
Yaml_DeleteAll(pYaml){
	DllCall(NumGet(NumGet(pYaml+0)+68), "UInt",pYaml) ;delete all keys
}
Yaml_DeleteItem(pYaml,key){
	VarSetCapacity(var1,16,0),NumPut(8,var1)
   If A_IsUnicode
      wStr:=key
   else
      VarSetCapacity(wStr, StrLen(Key)*2+1,0)
      ,DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "UInt",&Key, "Int",-1, "UInt",&wStr, "Int",StrLen(Key)+1)
   NumPut(DllCall("oleaut32\SysAllocString","Str",wStr),var1,8)
   DllCall(NumGet(NumGet(pYaml+0)+64), "UInt",pYaml, "UInt",&var1)
   DllCall("oleaut32\SysFreeString", "UInt",NumGet(var1,8)),NumPut(0,var1,8)
}
Yaml_Delete(pYaml,key){
   Yaml_DeleteItem(pYaml,key)
	 MainItem:=SubStr(key,1,InStr(key,".",1,0)-1)
	 If !(count:=Yaml_Get(pYaml,MainItem ".0"))
		Return
	 Key:=SubStr(key,InStr(key,".",1,0)+1)
	 Yaml_Set(pYaml,MainItem,RegExReplace(Yaml_Get(pYaml,MainItem),"^" key "$|^" key ",|," key "|" key "$",""))
	 Loop % count
		If (Key=Yaml_Get(pYaml,MainItem "." A_Index)){
			Yaml_Set(pYaml,MainItem "." A_Index,Yaml_Get(pYaml,MainItem "." count))
			Yaml_DeleteItem(pYaml,MainItem "." count)
			Yaml_Set(pYaml,MainItem ".0",Yaml_Get(pYaml,MainItem ".0")-1)
			break
		}
}
Yaml_Init(Yaml_File="?",pointerYaml=""){
	static pYaml, CLSID,IID,Init,FileIndex
	static CLSIDString:="{EE09B103-97E0-11CF-978F-00A02463E06F}", IIDString:="{42C642C1-97E1-11CF-978F-00A02463E06F}"
	If (!Init && Init:=1){ ;Initialize COM and create database
		DllCall("ole32\CoInitialize", "UInt",0),VarSetCapacity(var1, 16),VarSetCapacity(var2, 16)
		NumPut(8, var1),NumPut(8, var2),VarSetCapacity(CLSID, 16),VarSetCapacity(wKey, 79),VarSetCapacity(IID, 16)
		If A_IsUnicode
			DllCall("ole32\CLSIDFromString", "Str",CLSIDString, "Str",CLSID)
			,DllCall("ole32\CLSIDFromString", "Str",IIDString, "Str",IID)
		else
			DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "UInt",&CLSIDString, "Int",-1, "UInt",&wKey, "Int",39)
			,DllCall("ole32\CLSIDFromString", "Str",wKey, "Str",CLSID)
			,DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "UInt",&IIDString, "Int",-1, "UInt",&wKey, "Int",39)
			,DllCall("ole32\CLSIDFromString", "Str",wKey, "Str",IID)
		DllCall("ole32\CoCreateInstance", "Str",CLSID, "UInt",0, "UInt",5, "Str",IID, "UIntP",pYaml) ; CLSCTX=5
		DllCall(NumGet(NumGet(pYaml+0)+72), "UInt",pYaml, "Int",0) ; Set compare mode binary (casesensitive)
	}
	If (Yaml_File="?"){
		Loop % Yaml_Get(pYaml,0)
			Yaml_Save(Yaml_Get(pYaml,Yaml_Get(pYaml,A_Index)),Yaml_Get(pYaml,A_Index))
		Return
	}
	Loop,%Yaml_File%
		Yaml_File:=A_LoopFileLongPath
	If (!Yaml_Exist(_pYaml,Yaml_File) && !Yaml_Exist(pointerYaml))
		DllCall("ole32\CoCreateInstance", "Str",CLSID, "UInt",0, "UInt",5, "Str",IID, "UIntP",_pYaml) ; CLSCTX=5
		,DllCall(NumGet(NumGet(_pYaml+0)+72), "UInt",_pYaml, "Int",1) ; Set compare mode text (caseinsensitive)
	else if (pointerYaml)
		_pYaml:=pointerYaml
	else
		return Yaml_Get(pYaml,Yaml_File)
	If FileExist(Yaml_File){
		FileRead,Yaml_File_,%Yaml_File%
		If (ErrorLevel){
			MsgBox Error Reading File
			Return
		}
		FileIndex++
		Yaml_Assign(pYaml,0,FileIndex)
		Yaml_Assign(pYaml,FileIndex,Yaml_File)
		Yaml_Assign(pYaml,Yaml_File,_pYaml)
	} else Yaml_File_:=Yaml_File
	Loop,Parse,Yaml_File_,`n,`r
	{
		If A_LoopField=
			Continue
		if !create
			Key1:="",Key2:="",Key3:="",Item:=""
		If (MainItem0="" || (!create && !RegExMatch(A_LoopField,"^\s"))){
			If !RegExMatch(A_LoopField,"^(\w+)\s?:\s?(.*)\s*$",MainItem)
				If !RegExMatch(A_LoopField,"^'(.+)'\s?:\s?(.*)\s*$",MainItem){
					Key1=
					RegExMatch(A_LoopField,"^\s+-\s(.*)$",Key)
					If (Key1!=""){
						count:=Yaml_Get(_pYaml,MainItem0 ".0")
						count++
						Yaml_Assign(_pYaml,MainItem0 "." count,Key1)
						Yaml_Assign(_pYaml,MainItem0 ".0", count)
						item:=Yaml_Get(_pYaml,MainItem0)
						Yaml_Assign(_pYaml,MainItem0,item="" ? Key1 : item "," key1)
						Continue
					}
					LastLine.=A_LoopField "`n"
					Continue
				}
			MainItem0:=MainItem1
			ItemCount++
			MainItem:=Yaml_Get(_pYaml,"") . (Yaml_Get(_pYaml,"")!="" ? "," : "") . (RegExMatch(MainItem0,"^\s?\w+\s?$") ? MainItem0 : "'" MainItem0 "'")
			Yaml_Assign(_pYaml,"",MainItem)
			Yaml_Assign(_pYaml,0,ItemCount)
			Yaml_Assign(_pYaml,ItemCount,MainItem0)
			Yaml_Assign(_pYaml,MainItem0,MainItem2)
			If (SubStr(LastLine,0)="`n")
				StringTrimRight,LastLine,LastLine,1
			Yaml_Assign(_pYaml,MainItem0 ".",LastLine)
			MainItem:="",MainItem1:="",MainItem2:="",LastLine:=""
			LastItem:=MainItem0
			Continue
		}
		If (!create){
			Key1=
			RegExMatch(A_LoopField,"^\s+-\s(.*)$",Key)
			If (Key1!=""){
				count:=Yaml_Get(_pYaml,LastItem ".0")
				count++
				Yaml_Assign(_pYaml,LastItem "." count,Key1)
				Yaml_Assign(_pYaml,LastItem ".0", count)
				item:=Yaml_Get(_pYaml,LastItem)
				Yaml_Assign(_pYaml,LastItem,item="" ? Key1 : item "," key1)
				Continue
			}
			Loop 3
				Key%A_Index%=
			RegExMatch(A_LoopField,"^(\s+)(\w+)\s?:\s?(.*)\s?$",Key)
			If (Key2=""){
				Loop 3
					 Key%A_Index%=
				RegExMatch(A_LoopField,"^(\s+)'(.+)':\s?(.*)\s?$",Key)
			}
			If (Key2=""){
				LastLine.=A_LoopField "`n"
				Continue
			}
			If (SubStr(LastLine,0)="`n")
				StringTrimRight,LastLine,LastLine,1
			depth:=Round(Strlen(Key1)/2,0)
			MainItem%depth%:=Key2
			Item:=MainItem0
			While % ((i:=A_Index) && depth>A_Index)
				Item.= "." . MainItem%i%
			If !Yaml_Exist(_pYaml,Item "." key2){
				MainItem:=Yaml_Get(_pYaml,Item)
				count:=Yaml_Get(_pYaml,Item . ".0")
				count++
				Yaml_Assign(_pYaml,Item . ".0",count)
				Yaml_Assign(_pYaml,Item . "." . count,key2)
				Yaml_Assign(_pYaml,Item,MainItem . (MainItem="" ? "" : ",") . (RegExMatch(Key2,"^\s?\w+\s?$") ? key2 : "'" key2 "'"))
			}
			Item.="." . key2
			Yaml_Assign(_pYaml,Item,key3)
			LastItem:=Item
			If LastLine!=
				Yaml_Assign(_pYaml,Item . ".",LastLine),LastLine:=""
		} else 
			Yaml_Assign(_pYaml,Item,Yaml_Get(_pYaml,Item) . A_LoopField)
		If RegExMatch(Key3,"^\s*""")
			create:=1
		if (create && RegExMatch(A_LoopField,"""\s*$"))
			create:=0
	}
	Return _pYaml
}


SoLong&Thx4AllTheFish
  • Members
  • 4999 posts
  • Last active:
  • Joined: 27 May 2007
Thanks for posting!

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Am I late? Where is the wrapper? :roll:

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Sorry, i've posted it now :roll:

Here is another example I played with :)
yaml=
(
Gui:
  Add:
    Button:
      Test:
        - x0 y0 w100 h30 gTest
      Hello:
        - x200 y30 xs w200 h25 gTest
    ListView:
      'Test|new|other':
        - w200 r20 gTest vListView
)
y:=Yaml_Init(yaml)
Loop % Yaml_Get(y,"Gui.0"){
  p1:=Yaml_Get(y,"Gui." A_Index)
  Loop % Yaml_Get(y,"Gui." p1 "." 0){
    p2:=Yaml_Get(y,"Gui." p1 "." A_Index)
    Loop % Yaml_Get(y,"Gui." p1 "." p2 ".0")
    {
      p4:=Yaml_Get(y,"Gui." p1 "." p2 "." A_Index)
      p3:=Yaml_Get(y,"Gui." p1 "." p2 "." Yaml_Get(y,"Gui." p1 "." p2 "." A_Index) ".1")
      Gui,%p1%,%p2%,%p3%,%p4%
    }
  }
}
LV_Add("","test","test","test")
Gui,Show
Return
GuiClose:
ExitApp
Test:
MsgBox
Return


R3gX
  • Members
  • 307 posts
  • Last active: Dec 29 2013 04:50 PM
  • Joined: 28 Feb 2011

If you never heard of yaml before, take a look here: Can you learn Yaml in five minutes?

Here is the new URL : YAML in 5 minutes

Rabiator
  • Members
  • 292 posts
  • Last active: Aug 29 2016 09:29 PM
  • Joined: 17 Apr 2005
When Yaml_Delete() shall delete the first item of an associated list, it doesn't do this, but it deletes the values of all items of this list instead. Deleting another item than the first one works good.

yamlText= ;example yaml data
(
`%yaml
--- testdata, this is a comment only
Settings:
  Size:
    width: 1
    height: 2
  Colors:
    background: blue
    foreground: black
    text: white
  ButtonText:
    Button1: AutoHotkey
    Button2: OK
)
yml:=Yaml_Init(yamlText) ;create database from text
MsgBox % Yaml_Get(yml,"Settings.Colors.background") ;get a key
Yaml_Add(yml,"Settings.ButtonText.Button3","Exit") ;add a key
MsgBox % Yaml_Save(yml) ;Show dump of database
[color=red]Yaml_Delete(yml,"Settings.ButtonText.Button1") ;delete a key
MsgBox % Yaml_Save(yml) ;Show dump of database[/color]


HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Please use new Yaml, I will not be working on this one anymore.

Rabiator
  • Members
  • 292 posts
  • Last active: Aug 29 2016 09:29 PM
  • Joined: 17 Apr 2005
Thanks for your answer!
Too bad that your script is useles for me. I don't want to use AHK_L.
Perhaps I'll try to fix it myself.

Never mind.

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

Thanks for your answer!
Too bad that your script is useles for me. I don't want to use AHK_L.
Perhaps I'll try to fix it myself.

Never mind.

What a pity, i would really encourage you to use AHK_L.

Anyway I have fixed Yaml_Delete(), should work properly now ;)

Rabiator
  • Members
  • 292 posts
  • Last active: Aug 29 2016 09:29 PM
  • Joined: 17 Apr 2005
That's perfect!

Thanks a lot for your quick work 8) .