AutoHotkey Community

It is currently May 27th, 2012, 11:48 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: Simple Yaml Parser
PostPosted: July 25th, 2010, 9:21 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
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.


A subkey must be indented by 2 spaces (not Tab). If a key has got subkeys, it must not have values :!:
Code:
MainKey:
   SubKey:
      SubSubKey1: value1
      SubSubKey2: value2
      SubSubKeyList:
         - item1
         - item2
      'Subkey with non alphanumeric characters': "multiple
 lines
 value"

Simple example:
Code:
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
Code:
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
Code:
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
Code:
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
}

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Last edited by HotKeyIt on April 19th, 2011, 2:23 pm, edited 7 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 25th, 2010, 10:04 am 
Offline

Joined: May 27th, 2007, 9:41 am
Posts: 4999
Thanks for posting!

_________________
AHK FAQ
TF : Text files & strings lib, TF Forum


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 25th, 2010, 11:52 am 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
Am I late? Where is the wrapper? :roll:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 25th, 2010, 4:38 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Sorry, i've posted it now :roll:

Here is another example I played with :)
Code:
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

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Re: Simple Yaml Parser
PostPosted: March 14th, 2011, 9:46 pm 
Offline
User avatar

Joined: March 1st, 2011, 12:46 am
Posts: 254
HotKeyIt wrote:
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 18th, 2011, 2:10 pm 
Offline

Joined: April 17th, 2005, 7:47 pm
Posts: 289
Location: Sauerland
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.

Code:
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
Yaml_Delete(yml,"Settings.ButtonText.Button1") ;delete a key
MsgBox % Yaml_Save(yml) ;Show dump of database


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 18th, 2011, 11:02 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Please use new Yaml, I will not be working on this one anymore.

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 19th, 2011, 9:33 am 
Offline

Joined: April 17th, 2005, 7:47 pm
Posts: 289
Location: Sauerland
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 19th, 2011, 2:25 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Rabiator wrote:
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 ;)

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 19th, 2011, 3:05 pm 
Offline

Joined: April 17th, 2005, 7:47 pm
Posts: 289
Location: Sauerland
That's perfect!

Thanks a lot for your quick work 8) .


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: rrhuffy, Yahoo [Bot] and 45 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group