Jump to content

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

[AHK_L/v2] Yaml() - Yaml Parser (++JSON)


  • Please log in to reply
116 replies to this topic
HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

This is by design to allow following structure:

yaml:="
(
object:
  item: test
  1: hello
  - test
  - more
  - ahk
)"
MsgBox % ObjTree(Yaml(yaml,0))
ExitApp

If you like to keep your structure you would need to use integers:

item details:
  1:
    term: "term0"
    id: 7890
    type:
      1: typeA
      2: typeC


egocarib
  • Members
  • 42 posts
  • Last active: Nov 11 2016 07:10 PM
  • Joined: 17 Apr 2015

Shouldn't the parser still be able to identify the difference between this example:

object:
  item: test
  1:
  - test
  - more
  - ahk

and one like this:

object:
  item: test
  1:
    - test
    - more
    - ahk

because of the indentation difference?

 

A key with a simple block sequence value is pretty standard YAML (it's one of the very first examples given in the YAML specification).



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

It does, the first one creates 1 and {(""):["test",...]} on the same level as item and second contains {(""):["test",...]} as subobject of 1.

 

This Yaml Parser does not differentiate between your 2 examples.



egocarib
  • Members
  • 42 posts
  • Last active: Nov 11 2016 07:10 PM
  • Joined: 17 Apr 2015

Sorry, you're right - I should have tested the example I just used first.

 

What I mean to point out, though, is: shouldn't the parser be able to differentiate based on indentation in my original example?

item details:
  - term: "term0"
    id: 7890
    type: typeA
  - term:
      - "term1"
      - "term2"
    id: 1234
    type: typeB

should create ... {"term": ["term1", "term2"]} ...

 

and

item details:
  - term: "term0"
    id: 7890
    type: typeA
  - term:
    - "term1"
    - "term2"
    id: 1234
    type: typeB

should create ... {"term": ""}, {(""): ["term1", "term2"]} ...

 

 

 

Right now this parser interprets both as ... {"term": ""}, {(""): ["term1", "term2"]} ... unless I rearrange the key entries like so:

item details:
  - term: "term0"
    id: 7890
    type: typeA
  - id: 1234
    type: typeB
    term:
      - "term1"
      - "term2"

in which case, it interprets it as I expected: ... {"term": ["term1", "term2"]} ...   (but this also seems like inconsistent behavior).



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

I have just realized that function was not updated to latest version.

I have also moved download to github.

Try downloading again and see if it works.



egocarib
  • Members
  • 42 posts
  • Last active: Nov 11 2016 07:10 PM
  • Joined: 17 Apr 2015

Thanks for looking into it!

 

It still seems to be creating the same object structure, though:

 

test.yaml:

item details:
  - term: "term0"
    id: 7890
    type: typeA
  - term:
      - "term1"
      - "term2"
    id: 1234
    type: typeB

test.ahk

#Include Yaml.ahk

yamlObj := Yaml("test.yaml")

items := yamlObj["item details"][""]

OutputDebug, % "items[1][`"term`"]          = "   items[1]["term"]
OutputDebug, % "items[2][`"term`"][`"`"][1]   = " ;items[2]["term"][""][1] ;Error: No object to invoke (this is the expected location of term1)
OutputDebug, % "items[2][`"term`"][1]       = "   items[2]["term"][1]
OutputDebug, % "items[2][`"`"][1]           = "   items[2][""][1]
OutputDebug, % "items[2][`"`"][2]           = "   items[2][""][2]

output:

items[1]["term"]          = term0
items[2]["term"][""][1]   =
items[2]["term"][1]       =
items[2][""][1]           = term1
items[2][""][2]           = term2


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

This should be fixed, can you download and try again.



egocarib
  • Members
  • 42 posts
  • Last active: Nov 11 2016 07:10 PM
  • Joined: 17 Apr 2015

test yaml:

item details:
  - term: "term0"
    id: 7890
    type:
      - typeA
      - typeB
  - term:
      - "term1"
      - "term2"
    id: 1234
    type: typeC

output:

[8204] x["item details"][""][1]["id"] := 7890 
[8204] x["item details"][""][1]["term"] := "term0" 
[8204] x["item details"][""][1]["type"][""][1] := "typeA" 
[8204] x["item details"][""][1]["type"][""][2] := "typeB" 
[8204] x["item details"][""][2]["term"][""][1] := "term1 - term2" 
[8204] x["item details"][""][2]["term"][""][2]["id"] := 1234 
[8204] x["item details"][""][2]["term"][""][2]["type"] := "typeC" 


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

1.0.0.16 - another indentation correction fix.

 

Can you try again and let me know.



egocarib
  • Members
  • 42 posts
  • Last active: Nov 11 2016 07:10 PM
  • Joined: 17 Apr 2015

Thanks for the update! It works great on the example I've been tracking now:

 

Spoiler

 

 

However, if you still want it to parse sequence/mappings on the same level, it might need some additional tweaks:

 

Test2:

item details:
  - term: "term0"
    id: 7890
    type:
    - typeA
    - typeB
  - term:
    - "term1"
    - "term2"
    id: 1234
    type: typeC

Output2:

[7032] ["item details"][""][1]["id"] := 7890 
[7032] ["item details"][""][1]["term"] := "term0 - typeA - typeB" 
[7032] ["item details"][""][1]["type"] := [] 
[7032] ["item details"][""][2]["id"] := 1234 
[7032] ["item details"][""][2]["term"][""][1] := "term1" 
[7032] ["item details"][""][2]["term"][""][2] := "term2" 
[7032] ["item details"][""][2]["type"] := "typeC" 


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

Initially I designed Yaml to support AutoHotkey objects and did not care much about full yaml specs.

The biggest problem is that Yaml 1.2 does not support sequence and {key: value} on same level.

- itemA
key: value 

Also in my view following sits on the same level and sequence items should not be part of object.

object:
- itemA
- itemB

# in yaml 1.2 this is the same as above which makes no sense for me
object:
  - itemA
  - itemB

Further: {key: value} is not supported as sub-item of sequence in yaml 1.2

- itemA
  itemB: value

# While key: value in a sequence is supported
- itemA:
  itemB: value

My conclusion is that Yaml() would need to be rewritten completely to support yaml 1.2 properly and I do not intend to rewrite it.



egocarib
  • Members
  • 42 posts
  • Last active: Nov 11 2016 07:10 PM
  • Joined: 17 Apr 2015

Alright, well thanks for looking into it and giving it a try!