YAML(全称:YAML Ain't Markup Language)是一种人类可读的数据序列化格式。它常用来写配置文件、数据交换或者作为存储格式。YAML的设计目标是简洁、易读,且容易与其他编程语言和数据格式(比如JSON、XML)互操作。
YAML 的主要特点包括:
- 简洁和易读:相比JSON,YAML更加直观和简洁。比如,YAML使用缩进来表示层级关系,而JSON使用大括号和方括号。
- 支持多种数据类型:包括标量(字符串、整数、浮点数等)、列表、字典(键值对)、日期等。
- 支持复杂结构:可以用来表示复杂的数据结构,如多层嵌套的对象和数组。
- 注释支持:YAML文件可以包含注释,注释以
#
开头,帮助解释配置项的用途。
出处:https://github.com/HotKeyIt/Yaml/blob/master/Yaml.ahk
Yaml.ahk
Yaml(YamlText,IsFile=1,YamlObj=0){ ; Version 1.0.0.17 http://www.autohotkey.com/forum/viewtopic.php?t=70559 static static base:={Dump:"Yaml_Dump",Save:"Yaml_Save",Add:"Yaml_Add",Merge:"Yaml_Merge",__Delete:"__Delete",_Insert:"_Insert",_Remove:"_Remove",_GetCapacity:"_GetCapacity",_SetCapacity:"_SetCapacity",_GetAddress:"_GetAddress",_MaxIndex:"_MaxIndex",_MinIndex:"_MinIndex",_NewEnum:"_NewEnum",_HasKey:"_HasKey",_Clone:"_Clone",Insert:"Insert",Remove:"Remove",GetCapacity:"GetCapacity",SetCapacity:"SetCapacity",GetAddress:"GetAddress",MaxIndex:"MaxIndex",MinIndex:"MinIndex",NewEnum:"NewEnum",HasKey:"HasKey",Clone:"Clone",base:{__Call:"Yaml_Call"}} static BackupVars:="LVL,SEQ,KEY,SCA,TYP,VAL,CMT,LFL,CNT",IncompleteSeqMap local maxLVL:=0,LastContObj:=0,LastContKEY:=0,LinesAdded:=0,_LVLChanged:=0,_LVL,_SEQ,_KEY,_SCA,_TYP,_VAL,_CMT,_LFL,_CNT,_NXT,__LVL,__SEQ,__KEY,__SCA,__TYP,__VAL,__CMT,__LFL,__CNT,__NXT AutoTrim % ((AutoTrim:=A_AutoTrim)="On")?"Off":"Off" LVL0:=pYaml:=YamlObj?YamlObj:Object("base",base),__LVL:=0,__LVL0:=0 If IsFile FileRead,YamlText,%YamlText% Loop,Parse,YamlText,`n,`r { If (!_CNT && (A_LoopField=""||RegExMatch(A_LoopField,"^\s+$"))){ ;&&__KEY=""&&__SEQ="")){ If ((OBJ:=LVL%__LVL%[""].MaxIndex())&&IsObject(LVL%__LVL%["",OBJ])&&__SEQ){ If (__KEY!="") Yaml_Continue(LastContObj:=LVL%__LVL%["",Obj],LastContKEY:=__key,"",__SCA) else Yaml_Continue(LastContObj:=LVL%__LVL%[""],LastContKEY:=Obj,"",__SCA,__SEQ) } else If (__SEQ && OBJ){ Yaml_Continue(LastContObj:=LVL%__LVL%[""],LastContKEY:=OBJ,"",__SCA,__SEQ) } else If (OBJ){ Yaml_Continue(LastContObj:=LVL%__LVL%[""],LastContKEY:=OBJ,"",__SCA,1) } else if (__KEY!="") Yaml_Continue(LastContObj:=LVL%__LVL%,LastContKEY:=__KEY,"",__SCA) else LinesAdded-- LinesAdded++ Continue } else If (!_CNT && LastContObj && ( RegExMatch(A_LoopField,"^(---)?\s*?(-\s)?("".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)") || RegExMatch(A_LoopField,"^(---)|\s*(-\s)") )){ If !__SCA LastContObj[LastContKEY]:=SubStr(LastContObj[LastContKEY],1,-1*LinesAdded) LastContObj:=0,LastContKEY:=0,LinesAdded:=0 } If InStr(A_LoopField,"#"){ If (RegexMatch(A_LoopField,"^\s*#.*") || InStr(A_LoopField,"%YAML")=1) ;Comments only, do not parse continue else if Yaml_IsQuoted(LTrim(A_LoopField,"- ")) || RegExMatch(A_LoopField,"(---)?\s*?(-\s)?("".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)\s*([\|\>][+-]?)?\s*(!!\w+\s)?\s*("".+|'.+)$")&&!RegExMatch(A_LoopField,"[^\\]""\s+#") LoopField:=A_LoopField else if RegExMatch(A_LoopField,"\s+#.*$","",RegExMatch(A_LoopField,"(---)?\s*?(-\s)?("".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)?\s*([\|\>][+-]?)?\s*(!!\w+\s)?\s*("".+""|'.+')?\K")-1) LoopField:=SubStr(A_LoopField,1,RegExMatch(A_LoopField,"\s+#.*$","",RegExMatch(A_LoopField,"(---)?\s*?(-\s)?("".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)?\s*([\|\>][+-]?)?\s*(!!\w+\s)?\s*("".+""|'.+')?\K")-1)-1) else LoopField:=A_LoopField } else LoopField:=A_LoopField If _CNT { If Yaml_IsSeqMap(RegExReplace(IncompleteSeqMap LoopField,"^(\s+)?(-\s)?("".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)?")) LoopField:=IncompleteSeqMap LoopField,_CNT:=0,IncompleteSeqMap:="" else { IncompleteSeqMap.=LoopField continue } } If (LoopField="---"){ Loop % (maxLVL) LVL%A_Index%:="" Loop,Parse,BackupVars,`, __%A_LoopField%:="",__%A_LoopField%0:="" Loop,Parse,BackupVars,`, Loop % maxLVL __%A_LoopField%%A_Index%:="" maxLVL:=0 __LVL:=0,__LVL0:=0 If !IsObject(pYaml[""]) pYaml[""]:=LVL0:=Object("base",base) pYaml[""].Insert(LVL0:=Object("base",base)) Continue } else if (LoopField="..."){ LVL0:=pYaml Loop % maxLVL LVL%A_Index%:="" Loop,Parse,BackupVars,`, __%A_LoopField%:="",__%A_LoopField%0:="" Loop,Parse,BackupVars,`, Loop % maxLVL __%A_LoopField%%A_Index%:="" maxLVL:=0 __LVL:=0,__LVL0:=0 Continue } If (SubStr(LoopField,0)=":") LoopField.=A_Space ; add space to force RegEx to match even if the value and space after collon is missing e.g. Object:`n objects item RegExMatch(LoopField,"S)^(?<LVL>\s+)?(?<SEQ>-\s)?(?<KEY>"".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)?\s*(?<SCA>[\|\>][+-]?)?\s*(?<TYP>!!\w+\s)?\s*(?<VAL>"".+""|'.+'|.+)?\s*$",_) If _KEY ;cut off (:) StringTrimRight,_KEY,_KEY,2 _KEY:=Yaml_UnQuoteIfNeed(_KEY) If IsVal:=Yaml_IsQuoted(_VAL) _VAL:=Yaml_UnQuoteIfNeed(_VAL) ;determine current level _LVL:=Yaml_S2I(_LVL) If _LVL-__LVL>1||(_LVL>__LVL&&_LVLChanged) ;&&!(__SEQ&&__KEY!=""&&_KEY!="")) ; (__SEQ?2:1) { Loop % (_LVLChanged?_LVL-_LVLChanged:_LVL-__LVL-1) LoopField:=SubStr(LoopField,SubStr(LoopField,1,1)=A_Tab?1:2) _LVL:=_LVLChanged?_LVLChanged:__LVL+1,_LVLChanged:=_LVLChanged?_LVLChanged:_LVL ;__LVL%_LVL%:=__LVL%_NXT% ; (__SEQ?2:1) } else if _LVLChanged _LVL:=_LVLChanged else _LVLChanged:=0 If (maxLVL<_LVL) maxLVL:=_LVL+(_SEQ?1:0) ; Cut off the leading tabs/spaces conform _LVL SubStr:=0,Tabs:=0 Loop,Parse,LoopField If (_LVL*2=SubStr || !SubStr:=SubStr+(A_LoopField=A_Tab?2:1)), Tabs:=Tabs+(A_LoopField=A_Tab?1:0) break _LFL:=SubStr(LoopField,SubStr-Tabs+1+(_SEQ?2:0)) _LFL:=Yaml_UnQuoteIfNeed(_LFL) _NXT:=_LVL+1 ;next indentation level __NXT:=_NXT+1 _PRV:=_LVL=0?0:_LVL-1 Loop,Parse,BackupVars,`, __%A_LoopField%:=__%A_LoopField%%_PRV% If RegExMatch(_LFL,"^-\s*$"){ _SEQ:="-",_KEY:="",_VAL:="" } If (!IsVal && !_CNT && (_CNT:=Yaml_Incomplete(Trim(_LFL))||Yaml_Incomplete(Trim(_VAL)))){ IncompleteSeqMap:=LoopField continue } If (_LVL<__LVL){ ;Reset Objects and Backup vars Loop % (maxLVL) If (A_Index>_LVL){ Loop,Parse,BackupVars,`, __%A_LoopField%%maxLVL%:="" LVL%A_Index%:="",maxLVL:=maxLVL-1 } If (_LVL=0 && !__LVL:=__LVL0:=0) Loop,Parse,BackupVars,`, __%A_LoopField%:="",__%A_LoopField%0:="" } If (_SEQ&&_LVL>__LVL&&(__VAL!=""||__SCA)) _SEQ:="",_KEY:="",_VAL:="",_LFL:="- " _LFL If (__CNT)||(_LVL>__LVL&&(__KEY!=""&&_KEY="")&&(__VAL!=""||__SCA))||(__SEQ&&__SCA) _KEY:="",_VAL:="" If (__CNT||(_LVL>__LVL&&(__KEY!=""||(__SEQ&&(__LFL||__SCA)&&!Yaml_IsSeqMap(__LFL)))&&!(_SEQ||_KEY!=""))){ If ((OBJ:=LVL%__LVL%[""].MaxIndex())&&IsObject(LVL%__LVL%["",OBJ])&&__SEQ){ If __KEY!= Yaml_Continue(LVL%__LVL%["",Obj],__key,_LFL,__SCA),__CNT:=Yaml_SeqMap(LVL%__LVL%["",OBJ],__KEY,LVL%__LVL%["",OBJ,__KEY])?"":__CNT else Yaml_Continue(LVL%__LVL%[""],Obj,_LFL,__SCA,__SEQ),__CNT:=Yaml_SeqMap(LVL%__LVL%[""],OBJ,LVL%__LVL%["",OBJ],__SEQ)?"":__CNT } else If (__SEQ && OBJ){ Yaml_Continue(LVL%__LVL%[""],Obj,_LFL,__SCA,__SEQ) __CNT:=Yaml_SeqMap(LVL%__LVL%[""],OBJ,LVL%__LVL%["",OBJ],__SEQ)?"":__CNT } else If (OBJ && __KEY=""){ Yaml_Continue(LVL%__LVL%[""],OBJ,_LFL,__SCA,1) __CNT:=Yaml_SeqMap(LVL%__LVL%[""],OBJ,LVL%__LVL%["",OBJ],1)?"":__CNT } else { Yaml_Continue(LVL%__LVL%,__KEY,_LFL,__SCA) __CNT:=Yaml_SeqMap(LVL%__LVL%,__KEY,LVL%__LVL%[__KEY])?"":__CNT } Continue } ;Create sequence or map If (__SEQ&&(_LVL>__LVL)&&_KEY!=""&&__KEY!=""){ OBJ:=LVL%__LVL%[""].MaxIndex() If _SEQ { If !Yaml_SeqMap(LVL%_LVL%["",OBJ,__KEY,""],_KEY,_VAL){ If !IsObject(LVL%__LVL%["",OBJ,__KEY,""]) LVL%__LVL%["",OBJ,__KEY,""]:={base:base} LVL%__LVL%["",OBJ,__KEY,""].Insert({(_KEY):_VAL!=""?_VAL:(LVL%_NXT%:={base:base}),base:base}) } } else If !Yaml_SeqMap(LVL%_LVL%["",OBJ],_KEY,_VAL){ LVL%__LVL%["",OBJ,_KEY]:=_VAL!=""?_VAL:(LVL%_NXT%:={base:base}) } If _VAL!= continue } else If (_SEQ){ If !IsObject(LVL%_LVL%[""]) LVL%_LVL%[""]:=Object("base",base) While (SubStr(_LFL,1,2)="- "){ _LFL:=SubStr(_LFL,3),_KEY:=(_KEY!="")?_LFL:=SubStr(_KEY,3):_KEY,LVL%_LVL%[""].Insert(LVL%_NXT%:=Object("",Object("base",base),"base",base)),_LVL:=_LVL+1,_NXT:=_NXT+1,__NXT:=_NXT+1,_PRV:=_LVL-1,maxLVL:=(maxLVL<_LVL)?_LVL:maxLVL Loop,Parse,BackupVars,`, __%A_LoopField%:=_%A_LoopField% ,__%A_LoopField%%_PRV%:=_%A_LoopField% } If (_KEY="" && _VAL="" && !IsVal){ If !Yaml_SeqMap(LVL%_LVL%[""],"",_LFL) LVL%_LVL%[""].Insert(LVL%_NXT%:=Object("base",base)) } else If (_KEY!="") { LVL%_LVL%[""].Insert(LVL%__NXT%:=Object(_KEY,LVL%_NXT%:=Object("base",base),"base",base)) If !Yaml_SeqMap(LVL%__NXT%,_KEY,_VAL){ LVL%_LVL%[""].Remove() LVL%_LVL%[""].Insert(LVL%__NXT%:=Object(_KEY,(_VAL!=""||IsVal)?_VAL:LVL%_NXT%:=Object("base",base),"base",base)) } } else { If !Yaml_SeqMap(LVL%_LVL%[""],"",_LFL) LVL%_LVL%[""].Insert(_LFL) } If !LVL%_LVL%[""].MaxIndex() LVL%_LVL%.Remove("") } else if (_KEY!=""){ If (__SEQ && _LVL>__LVL) { If (OBJ:=LVL%_PRV%[""].MaxIndex())&&IsObject(LVL%_PRV%["",OBJ]){ If !Yaml_SeqMap(LVL%_PRV%["",OBJ],_KEY,_VAL) LVL%_PRV%["",OBJ,_KEY]:=(_VAL!=""||IsVal)?_VAL:(LVL%_NXT%:=Object("base",base)) } else { LVL%_PRV%[""].Insert(Object(_KEY,(_VAL!=""||IsVal)?_VAL:(LVL%_NXT%:=Object("base",base)),"base",base)) Yaml_SeqMap(LVL%_PRV%["",OBJ?OBJ+1:1],_KEY,_VAL) } } else If !Yaml_SeqMap(LVL%_LVL%,_KEY,_VAL) LVL%_LVL%[_KEY]:=_VAL!=""?_VAL:(LVL%_NXT%:=Object("base",base)) } else if (_LVL>__LVL && (__KEY!="")) { If (__VAL!="" || __SCA){ Yaml_Continue(LVL%__LVL%,__KEY,_LFL,__SCA) Yaml_SeqMap(LVL%__LVL%,__KEY,LVL%__LVL%[__KEY]) Continue } else { If !Yaml_SeqMap(LVL%__LVL%[__KEY],_KEY,_VAL) ;!!! no Scalar??? LVL%__LVL%[__KEY,_KEY]:=_VAL Continue } } else { If (_LVL>__LVL&&(OBJ:=LVL%__LVL%[""].MaxIndex())&&IsObject(LVL%__LVL%["",OBJ])&&__SEQ){ If __CNT Yaml_Continue(LVL%__LVL%[""],LVL%__LVL%[""].MaxIndex(),_LFL,__SCA,1) If (__CNT:=Yaml_SeqMap(LVL%__LVL%[""],"",_LFL)?"":1) LVL%__LVL%[""].Insert(_LFL) } else { If !IsObject(LVL%_LVL%[""]) LVL%_LVL%[""]:=Object("base",base) If __CNT Yaml_Continue(LVL%__LVL%[""],LVL%__LVL%[""].MaxIndex(),_LFL,__SCA,1) If (__CNT:=Yaml_SeqMap(LVL%_LVL%[""],"",_LFL)?"":1) LVL%_LVL%[""].Insert(_LFL) } Continue } Loop,Parse,BackupVars,`, __%A_LoopField%:=_%A_LoopField% ,__%A_LoopField%%_LVL%:=_%A_LoopField% } If (LastContObj && !__SCA) LastContObj[LastContKEY]:=SubStr(LastContObj[LastContKEY],1,-1*LinesAdded) AutoTrim %AutoTrim% Loop,Parse,BackupVars,`, If !(__%A_LoopField%:="") Loop % maxLVL __%A_LoopField%%A_Index%:="" Return pYaml,pYaml.base:=base } Yaml_Save(obj,file,level=""){ FileMove,% file,% file ".bakupyml",1 FileAppend,% obj.Dump(),% file If !ErrorLevel FileDelete,% file ".bakupyml" else { FileMove,% file ".bakupyml",% file MsgBox,0, Error creating file, old file was restored. } } Yaml_Call(NotSupported,f,p*){ If (p.MaxIndex()>1){ Loop % p.MaxIndex() If A_Index>1 f:=f[""][p[A_Index-1]] } Return (!p.MaxIndex()?f[""].MaxIndex():f[""][p[p.MaxIndex()]]) } Yaml_Merge(obj,merge){ for k,v in merge { If IsObject(v){ If obj.HasKey(k){ If IsObject(obj[k]) Yaml_Merge(obj[k],v) else obj[k]:=v } else obj[k]:=v } else obj[k]:=v } } Yaml_Add(O,Yaml="",IsFile=0){ static base:={Dump:"Yaml_Dump",Save:"Yaml_Save",Add:"Yaml_Add",Merge:"Yaml_Merge",__Delete:"__Delete",_Insert:"_Insert",_Remove:"_Remove",_GetCapacity:"_GetCapacity",_SetCapacity:"_SetCapacity",_GetAddress:"_GetAddress",_MaxIndex:"_MaxIndex",_MinIndex:"_MinIndex",_NewEnum:"_NewEnum",_HasKey:"_HasKey",_Clone:"_Clone",Insert:"Insert",Remove:"Remove",GetCapacity:"GetCapacity",SetCapacity:"SetCapacity",GetAddress:"GetAddress",MaxIndex:"MaxIndex",MinIndex:"MinIndex",NewEnum:"NewEnum",HasKey:"HasKey",Clone:"Clone",base:{__Call:"Yaml_Call"}} If Yaml_IsSeqMap(Trim(Yaml)){ If !IsObject(O[""]) O[""]:=Object("base",base) Yaml_SeqMap(O[""],"",Yaml) } else Yaml(Yaml,IsFile,O) } Yaml_Dump(O,J="",R=0,Q=0){ static M1:="{",M2:="}",S1:="[",S2:="]",N:="`n",C:=", ",S:="- ",E:="",K:=": " local dump:="",M,MX,F,I,key,value If (J=0&&!R) dump.= S1 for key in O M:=A_Index If IsObject(O[""]){ M-- for key in O[""] MX:=A_Index If IsObject(O[""][""]) MX-- If O[""].MaxIndex() for key, value in O[""] { If key= continue I++ F:=IsObject(value)?(IsObject(value[""])?"S":"M"):E If (J!=""&&J<=R){ dump.=(F?(%F%1 Yaml_Dump(value,J,R+1,F) %F%2):Yaml_EscIfNeed(value)) (I=MX&&!M?E:C) ;(Q="S"&&I=1?S1:E)(Q="S"&&I=MX?S2:E) } else if F,dump:=dump N Yaml_I2S(R) S dump.= (J!=""&&J<=(R+1)?%F%1:E) Yaml_Dump(value,J,R+1,F) (J!=""&&J<=(R+1)?%F%2:E) else { ; If RegexMatch(value,"[\x{007F}-\x{FFFF}""\{\[']|:\s|\s#") dump .= Yaml_EscIfNeed(value) ; else { ; value:= (value=""?"''":RegExReplace(RegExReplace(Value,"m)^(.*[\r\n].*)$","|" (SubStr(value,-1)="`n`n"?"+":SubStr(value,0)=N?"":"-") "`n$1"),"ms)(*ANYCRLF)\R",N Yaml_I2S(R+1))) ; StringReplace,value,value,% N Yaml_I2S(R+1) N Yaml_I2S(R+1),% N Yaml_I2S(R+1),A ; dump.=value ; } } } } I=0 for key, value in O { If key= continue I++ F:=IsObject(value)?(IsObject(value[""])?"S":"M"):E If (J=0&&!R) dump.= M1 If (J!=""&&J<=R){ dump.=(Q="S"&&I=1?M1:E) Yaml_EscIfNeed(key) K dump.=F?(%F%1 Yaml_Dump(value,J,R+1,F) %F%2):Yaml_EscIfNeed(value) dump.=(Q="S"&&I=M?M2:E) (J!=0||R?(I=M?E:C):E) } else if F,dump:=dump N Yaml_I2S(R) Yaml_EscIfNeed(key) K dump.= (J!=""&&J<=(R+1)?%F%1:E) Yaml_Dump(value,J,R+1,F) (J!=""&&J<=(R+1)?%F%2:E) else { ; If RegexMatch(value,"[\x{007F}-\x{FFFF}""\{\['\t]|:\s|\s#") dump .= Yaml_EscIfNeed(value) ; else { ; value:= (value=""?"''":RegExReplace(RegExReplace(Value,"m)^(.*[\r\n].*)$","|" (SubStr(value,-1)="`n`n"?"+":SubStr(value,0)="`n"?"":"-") "`n$1"),"ms)(*ANYCRLF)\R","`n" Yaml_I2S(R+1))) ; StringReplace,value,value,% "`n" Yaml_I2S(R+1) "`n" Yaml_I2S(R+1),% "`n" Yaml_I2S(R+1),A ; dump.= value ; } } If (J=0&&!R){ dump.=M2 (I<M?C:E) } } If (J=0&&!R) dump.=S2 If (R=0) dump:=RegExReplace(dump,"^\R+") Return dump } Yaml_UniChar( string ) { static a:="`a",b:="`b",t:="`t",n:="`n",v:="`v",f:="`f",r:="`r",e:=Chr(0x1B) Loop,Parse,string,\ { If (A_Index=1){ var.=A_LoopField continue } else If lastempty { var.="\" A_LoopField lastempty:=0 Continue } else if (A_LoopField=""){ lastempty:=1 Continue } If InStr("ux",SubStr(A_LoopField,1,1)) str:=SubStr(A_LoopField,1,RegExMatch(A_LoopField,"^[ux]?([\dA-F]{4})?([\dA-F]{2})?\K")-1) else str:=SubStr(A_LoopField,1,1) If (str=="N") str:="\x85" else if (str=="P") str:="\x2029" else if (str=0) str:="\x0" else if (str=="L") str:="\x2028" else if (str=="_") str:="\xA0" If RegexMatch(str,"i)^[ux][\da-f]+$") var.=Chr(Abs("0x" SubStr(str,2))) else If str in a,b,t,n,v,f,r,e var.=%str% else var.=str If InStr("ux",SubStr(A_LoopField,1,1)) var.=SubStr(A_LoopField,RegExMatch(A_LoopField,"^[ux]?([\dA-F]{4})?([\dA-F]{2})?\K")) else var.=SubStr(A_LoopField,2) } return var } Yaml_CharUni( string ) { static ascii:={"\":"\","`a": "a","`b": "b","`t": "t","`n": "n","`v": "v","`f": "f","`r": "r",Chr(0x1B): "e","""": """",Chr(0x85): "N",Chr(0x2029): "P",Chr(0x2028): "L","": "0",Chr(0xA0): "_"} If !RegexMatch(string,"[\x{007F}-\x{FFFF}]"){ Loop,Parse,string { If ascii[A_LoopField] var.="\" ascii[A_LoopField] else var.=A_LoopField } return var } format:=A_FormatInteger SetFormat,Integer,H Loop,Parse,string { If ascii[A_LoopField] var.="\" ascii[A_LoopField] else if Asc(A_LoopField)<128 var.=A_LoopField else { str:=SubStr(Asc(A_LoopField),3) var.="\u" (StrLen(str)<2?"000":StrLen(str)<3?"00":StrLen(str)<4?"0":"") str } } SetFormat,Integer,%Format% return var } Yaml_EscIfNeed(s){ If (s="") return "''" else If RegExMatch(s,"m)[\{\[""'\r\n]|:\s|,\s|\s#")||RegExMatch(s,"^[\s#\\\-:>]")||RegExMatch(s,"m)\s$")||RegExMatch(s,"m)[\x{7F}-\x{7FFFFFFF}]") return ("""" . Yaml_CharUni(s) . """") else return s } Yaml_IsQuoted(ByRef s){ return InStr(".''."""".","." SubStr(Trim(s),1,1) SubStr(Trim(s),0) ".")?1:0 } Yaml_UnQuoteIfNeed(s){ s:=Trim(s) If !(SubStr(s,1,1)=""""&&SubStr(s,0)="""") return (SubStr(s,1,1)="'"&&SubStr(s,0)="'")?SubStr(s,2,StrLen(s)-2):s else return Yaml_UniChar(SubStr(s,2,StrLen(s)-2)) } Yaml_S2I(str){ local idx:=0 Loop,Parse,str If (A_LoopField=A_Tab) idx++ else if !Mod(A_index,2) idx++ Return idx } Yaml_I2S(idx){ Loop % idx str .= " " Return str } Yaml_Continue(Obj,key,value,scalar="",isval=0){ If !IsObject(isObj:=obj[key]) v:=isObj If scalar { StringTrimLeft,scaopt,scalar,1 scalar:=Asc(scalar)=124?"`n":" " } else scalar:=" ",scaopt:="-" temp := (value=""?"`n":(SubStr(v,0)="`n"&&scalar="`n"?"":(v=""?"":scalar))) value (scaopt!="-"?(v&&value=""?"`n":""):"") obj[key]:=Yaml_UnQuoteIfNeed(v temp) } Yaml_Quote(ByRef L,F,Q,B,ByRef E){ Return (F="\"&&!E&&(E:=1))||(E&&!(E:=0)&&(L:=L ("\" F))) } Yaml_SeqMap(o,k,v,isVal=0){ v:=Trim(v,A_Tab A_Space "`n"),m:=SubStr(v,1,1) SubStr(v,0) If Yaml_IsSeqMap(v) return m="[]"?Yaml_Seq(o,k,SubStr(v,2,StrLen(v)-2),isVal):m="{}"?Yaml_Map(o,k,SubStr(v,2,StrLen(v)-2),isVal):0 } Yaml_Seq(obj,key,value,isVal=0){ static base:={Dump:"Yaml_Dump",Save:"Yaml_Save",Add:"Yaml_Add",Merge:"Yaml_Merge",__Delete:"__Delete",_Insert:"_Insert",_Remove:"_Remove",_GetCapacity:"_GetCapacity",_SetCapacity:"_SetCapacity",_GetAddress:"_GetAddress",_MaxIndex:"_MaxIndex",_MinIndex:"_MinIndex",_NewEnum:"_NewEnum",_HasKey:"_HasKey",_Clone:"_Clone",Insert:"Insert",Remove:"Remove",GetCapacity:"GetCapacity",SetCapacity:"SetCapacity",GetAddress:"GetAddress",MaxIndex:"MaxIndex",MinIndex:"MinIndex",NewEnum:"NewEnum",HasKey:"HasKey",Clone:"Clone",base:{__Call:"Yaml_Call"}} ContinueNext:=0 If (obj=""){ If (SubStr(value,0)!="]") Return 0 else value:=SubStr(value,2,StrLen(value)-2) } else { If (key=""){ obj.Insert(Object("",cObj:=Object("base",base),"base",base)) } else if (isval && IsObject(obj[key,""])){ cObj:=obj[key,""] } else obj[key]:=Object("",cObj:=Object("base",base),"base",base) } Count:=StrLen(value) Loop,Parse,value { If ((Quote=""""&&Yaml_Quote(LF,A_LoopField,Quote,Bracket,Escape)) || (ContinueNext && !ContinueNext:=0)) Continue If (Quote){ If (A_LoopField=Quote){ Quote= If Bracket LF.= A_LoopField else LF:=SubStr(LF,2) Continue } LF .= A_LoopField continue } else if (!Quote&&InStr("""'",A_LoopField)){ Quote:=A_LoopField If !Bracket VQ:=Quote LF.=A_LoopField Continue } else if (!Quote&&Bracket){ If (Asc(A_LoopField)=Asc(Bracket)+2) BCount-- else if (A_LoopField=Bracket) BCount++ If (BCount=0) Bracket= LF .= A_LoopField Continue } else if (!Quote&&!Bracket&&InStr("[{",A_LoopField)){ Bracket:=A_LoopField BCount:=1 LF.=A_LoopField Continue } If (A_Index=Count) LF .= A_LoopField else if (!Quote&&!Bracket&&A_LoopField=","&&(!InStr("0123456789",SubStr(value,A_Index-1,1)) | !InStr("0123456789",SubStr(value,A_Index+1,1)))){ ContinueNext:=SubStr(value,A_Index+1,1)=A_Space||SubStr(value,A_Index+1,1)=A_Tab LF:=LF } else { LF .= A_LoopField continue } If (obj=""){ If !VQ If (Asc(LF)=91 && !Yaml_Seq("","",LF)) ||(Asc(LF)=123 && !Yaml_Map("","",LF)) Return 0 } else { If (VQ || !Yaml_SeqMap(cObj,"",LF)) cObj.Insert(VQ?Yaml_UniChar(LF):Trim(LF)) } LF:="",VQ:="" } If (LF){ If (obj=""){ If !VQ If (Asc(LF)=91 && !Yaml_Seq("","",LF))||(Asc(LF)=123 && !Yaml_Map("","",LF)) Return 0 } else If (VQ || !Yaml_SeqMap(cObj,"",LF)) cObj.Insert(VQ?Yaml_UniChar(LF):Trim(LF)) } Return (obj=""?(Quote Bracket=""):1) } Yaml_Map(obj,key,value,isVal=0){ static base:={Dump:"Yaml_Dump",Save:"Yaml_Save",Add:"Yaml_Add",Merge:"Yaml_Merge",__Delete:"__Delete",_Insert:"_Insert",_Remove:"_Remove",_GetCapacity:"_GetCapacity",_SetCapacity:"_SetCapacity",_GetAddress:"_GetAddress",_MaxIndex:"_MaxIndex",_MinIndex:"_MinIndex",_NewEnum:"_NewEnum",_HasKey:"_HasKey",_Clone:"_Clone",Insert:"Insert",Remove:"Remove",GetCapacity:"GetCapacity",SetCapacity:"SetCapacity",GetAddress:"GetAddress",MaxIndex:"MaxIndex",MinIndex:"MinIndex",NewEnum:"NewEnum",HasKey:"HasKey",Clone:"Clone",base:{__Call:"Yaml_Call"}} ContinueNext:=0 If (obj=""){ If (SubStr(value,0)!="}") Return 0 else value:=SubStr(value,2,StrLen(value)-2) } else { If (key="") obj.Insert(cObj:=Object("base",base)) else obj[key]:=(cObj:=Object("base",base)) } Count:=StrLen(value) Loop,Parse,value { If ((Quote=""""&&Yaml_Quote(LF,A_LoopField,Quote,Bracket,Escape)) || (ContinueNext && !ContinueNext:=0)) Continue If (Quote){ If (A_LoopField=Quote){ Quote= LF.=A_LoopField } else LF .= A_LoopField continue } else if (!Quote&&(k=""||v="")&&InStr("""'",A_LoopField)){ Quote:=A_LoopField If (k && !Bracket) VQ:=Quote else if !Bracket KQ:=Quote LF.=Quote Continue } else If (k!=""&&LF=""&&InStr("`n`r `t",A_LoopField)){ Continue } If (!Quote&&Bracket){ If (Asc(A_LoopField)=Asc(Bracket)+2) BCount-- else if (A_LoopField=Bracket) BCount++ If (BCount=0) Bracket= LF .= A_LoopField Continue } else if (!Quote&&!Bracket&&InStr("[{",A_LoopField)){ Bracket:=A_LoopField BCount=1 LF.=A_LoopField Continue } If (A_Index=Count&&k!=""){ v:=LF A_LoopField v:=Trim(v) If (InStr("""'",SubStr(v,0))&&SubStr(v,1,1)=SubStr(v,0)) v:=SubStr(v,2,StrLen(v)-2) } else If (!Quote&&!Bracket&&k!=""&&A_LoopField=","&&SubStr(value,A_Index+1,1)=A_Space){ ContinueNext:=1 LF:=Trim(LF) If VQ LF:=SubStr(LF,2,StrLen(LF)-2) v:=LF,LF:="" } else if (!Quote&&!Bracket&&k=""&&A_LoopField=":"){ LF:=Trim(LF) If (InStr("""'",SubStr(LF,0))&&SubStr(LF,1,1)=SubStr(LF,0)) LF:=SubStr(LF,2,StrLen(LF)-2) k:=LF,LF:="" continue } else { LF .= A_LoopField continue } If (obj=""){ If VQ= If (Asc(v)=91 && !Yaml_Seq("","",v)) ||(Asc(v)=123 && !Yaml_Map("","",v)) Return 0 } else { If (VQ || !Yaml_SeqMap(cObj,k,v)) cObj[KQ?Yaml_UniChar(k):k]:=(VQ?Yaml_UniChar(v):Trim(v)) } k:="",v:="",VQ:="",KQ:="" } If (k){ If (obj=""){ If (Asc(LF)=91 && !Yaml_Seq("","",LF))||(Asc(LF)=123 && !Yaml_Map("","",LF)) Return 0 } else { LF:=Trim(LF) If (VQ) LF:=SubStr(LF,2,StrLen(LF)-2),cObj[k]:=Yaml_UniChar(LF) else If (!Yaml_SeqMap(cObj,k,LF)) cObj[k]:=Trim(LF) } } Return (obj=""?(Quote Bracket=""):1) } Yaml_Incomplete(value){ return (Asc(Trim(value,"`n" A_Tab A_Space))=91 && !Yaml_Seq("","",Trim(value,"`n" A_Tab A_Space))) || (Asc(Trim(value,"`n" A_Tab A_Space))=123 && !Yaml_Map("","",Trim(value,"`n" A_Tab A_Space))) } Yaml_IsSeqMap(value){ return (Asc(Trim(value,"`n" A_Tab A_Space))=91 && Yaml_Seq("","",Trim(value,"`n" A_Tab A_Space))) || (Asc(Trim(value,"`n" A_Tab A_Space))=123 && Yaml_Map("","",Trim(value,"`n" A_Tab A_Space))) }
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)