YAML and LiveCode
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller
YAML and LiveCode
I found a reference to one or more JSON libraries for LC. Are there any libraries for YAML?
-
- VIP Livecode Opensource Backer
- Posts: 9823
- Joined: Sat Apr 08, 2006 7:05 am
- Location: Los Angeles
- Contact:
Re: YAML and LiveCode
There might be, but I don't recall recent mention of one. I was tempted to write such a library myself, but truth be told, fun as YAML is I have no actual need for it.
What are you looking to do?
What are you looking to do?
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
Re: YAML and LiveCode
I want to use a text file to record all of the steps necessary for a project. The basic format would be a long list of nodes with links to other nodes. Then that text file could be read out and displayed in a bunch of different ways, like as a graphical network, or as a step-by-step list of instructions, or certain pieces of information could be pulled out like the bill of materials could be calculated.
At first I designed the syntax as just what I needed, but as I get closer to trying to implement it I realized that I should probably try to use an existing data serialization format. YAML seems to have the same balance between human readability and machine readability that I was going for. It's important that people be able to understand and work with the raw file if they want to, but it's also important that a rendering engine be able to make the raw file easier to work with in different ways.
At first I designed the syntax as just what I needed, but as I get closer to trying to implement it I realized that I should probably try to use an existing data serialization format. YAML seems to have the same balance between human readability and machine readability that I was going for. It's important that people be able to understand and work with the raw file if they want to, but it's also important that a rendering engine be able to make the raw file easier to work with in different ways.
-
- VIP Livecode Opensource Backer
- Posts: 9823
- Joined: Sat Apr 08, 2006 7:05 am
- Location: Los Angeles
- Contact:
Re: YAML and LiveCode
Sounds like a cool project. I wish I had a YAML library, and if I stumble across one for LC I'll post a link here, but as far as I know at the moment you're on your own.
That said, if you'd be inclined to open source it I'd be happy to lend a hand if needed. It would be nice to see YamlToArray and ArrayToYaml handlers in the pool of community resources.
That said, if you'd be inclined to open source it I'd be happy to lend a hand if needed. It would be nice to see YamlToArray and ArrayToYaml handlers in the pool of community resources.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
-
- VIP Livecode Opensource Backer
- Posts: 92
- Joined: Wed May 29, 2013 1:54 am
- Location: Sydney, Australia
Re: YAML and LiveCode
I see that it's been a couple of years since anyone posted on this thread. I'm looking for a YAML library for LiveCode, and my big hope is that someone might have written one during this time... I've googled around, but cannot find anything. Does anyone know of one?
-
- VIP Livecode Opensource Backer
- Posts: 3581
- Joined: Mon Jan 22, 2007 7:36 am
- Location: Berkeley, CA, US
- Contact:
Re: YAML and LiveCode
I never bothered to make a library out of two functions, but here's what I use:
Code: Select all
/**
Array-to-Yaml and Yaml-to-Array library
Mark Wieder 2016
wtf licenced : have fun
Public functions here:
arrayToYaml
yamlToArray
yamlFileToArray
*/
-- allow 4 spaces per indentation in output yaml files
-- adjust as desired
constant kIndent = 4
/*
arrayToYaml
Convert a LiveCode array to yaml format
@pArray : the array to convert
@pIndentLevel : initially empty, recursion sets this
*/
function arrayToYaml pArray, pIndentLevel
local tYaml
local tIndentLevel
put pIndentLevel into tIndentLevel
if tIndentLevel is empty then
put kIndent into tIndentLevel
put "ArrayName :" & cr into tYaml
end if
if pArray is an array then
repeat for each key tKey in pArray
if pArray[tKey] is an array then
put indent(tIndentLevel) & tKey && ":" && pArray[tKey] & cr after tYaml
add kIndent to tIndentLevel
-- recurse to work through multidimensional arrays
put arrayToYaml(pArray[tKey], tIndentLevel) after tYaml
subtract kIndent from tIndentLevel
else
put indent(tIndentLevel) & tKey && ":" && pArray[tKey] & cr after tYaml
end if
end repeat
else
throw "not an array"
end if
return tYaml
end arrayToYaml
/*
indent
Used internally by arrayToYaml
*/
private function indent pIndentLevel
local tIndentLevel
-- return the proper number of spaces for indentation
repeat pIndentLevel times
put space after tIndentLevel
end repeat
return tIndentLevel
end indent
/*
indentationLevel
Return the indentation level of the supplied line
NOTE: changes the input line in situ to remove the indentation
Used internally by yamlToArray
*/
private function indentationLevel @pLine
local tIndentationLevel
local tKey, tValue
put 0 into tIndentationLevel
repeat while char 1 of pLine is space
add 1 to tIndentationLevel
delete char 1 of pLine
end repeat
return tIndentationLevel
end indentationLevel
/*
yamlToArray
Convert yaml format text to a LiveCode array
*/
function yamlToArray pYaml
local tArray
local tIndentation, tPrevIndent
local tWorkingLine
local tYamlHeading
local tKey, tValue
repeat for each line tLine in pYaml
put tLine into tWorkingLine
set the itemdelimiter to ":"
put item 1 of tWorkingLine into tKey
repeat while char -1 of tKey is in ": "
delete char -1 of tKey
end repeat
put word 1 to -1 of item 2 of tWorkingLine into tValue
put indentationLevel(tKey) into tIndentation
if tPrevIndent is empty then
-- first time through
put tIndentation into tPrevIndent
put tKey into tYamlHeading
put tValue into tArray[tYamlHeading]
else
switch
case tIndentation < tPrevIndent
-- remove the last array index
RemoveLastIndexFrom tYamlHeading
RemoveLastIndexFrom tYamlHeading
put tIndentation into tPrevIndent
if tYamlHeading is empty then
do "put tValue into tArray[" & tKey & "]"
else
do "put tValue into tArray" & yamlPathToArrayPath(tYamlHeading) & "[" & tKey & "]"
end if
break
case tIndentation is tPrevIndent
RemoveLastIndexFrom tYamlHeading
if tYamlHeading is empty then
do "put tValue into tArray" & "[" & tKey & "]"
else
do "put tValue into tArray" & yamlPathToArrayPath(tYamlHeading) & "[" & tKey & "]"
end if
put comma & tKey after tYamlHeading
break
case tIndentation > tPrevIndent
-- add an array index
if tYamlHeading is empty then
do "put tValue into tArray[" & tKey & "]"
else
do "put tValue into tArray" & yamlPathToArrayPath(tYamlHeading) & "[" & tKey & "]"
end if
put comma & tKey after tYamlHeading
put tIndentation into tPrevIndent
break
end switch
end if
end repeat
return tArray
end yamlToArray
private command RemoveLastIndexFrom @pIndexString
set the itemdelimiter to comma
delete item -1 of pIndexString
end RemoveLastIndexFrom
private function yamlPathToArrayPath pYamlPath
local tArrayPath
set the itemdelimiter to comma
repeat for each item tPath in pYamlPath
put "[" & tPath & "]" after tArrayPath
end repeat
return tArrayPath
end yamlPathToArrayPath
/*
yamlFileToArray
Point to a yaml file, return a LiveCode array
*/
function yamlFileToArray pFilePath
local tYaml
put url ("file:" & pFilePath) into tYaml
return yamlToArray(tYaml)
end yamlFileToArray
/*
*/
command testArrayToYaml
local tArray
put "hello" into tArray["hi"]
put "bucko" into tArray["greeting"]["name"]
put 1234 into tArray["greeting"]["mynumber"]
put "goodbye" into tArray["bye"]
put "510-555-1212" into tArray["greeting"]["phonenumber"]["landline"]
put "510-555-1212" into tArray["greeting"]["phonenumber"]["cell"]
put arrayToYaml(tArray)
end testArrayToYaml
command testYamlToArray
local tYaml
put "greeting :" & cr into tYaml
put " myNumber : 1234" & cr after tYaml
put " phonenumber :" & cr after tYaml
put " landline : 510-555-4567" & cr after tYaml
put " extension : 42" & cr after tYaml
put " cell : 510-555-1234" & cr after tYaml
put " name : bucko" & cr after tYaml
put "hi : hello" & cr after tYaml
put "bye : goodbye" & cr after tYaml
put arrayToYaml(yamlToArray(tYaml)) & cr after msg
end testYamlToArray
PowerDebug http://powerdebug.ahsoftware.net
PowerTools http://www.ahsoftware.net/PowerTools/PowerTools.irev
PowerTools http://www.ahsoftware.net/PowerTools/PowerTools.irev
-
- VIP Livecode Opensource Backer
- Posts: 92
- Joined: Wed May 29, 2013 1:54 am
- Location: Sydney, Australia
Re: YAML and LiveCode
Wow, Mark, thank you so much for sharing your code- it's truly helpful!
Your code seems almost complete, however it seems to expect that every line of the inputted YAML will always be in 'array' (key:value) format - like this:
YAML is actually a superset of JSON: all valid JSON documents are also valid YAML. For instance: like JSON, the YAML specs also allow for **lists**. The following is a valid YAML document:
YAML also allows for **comments**, which is any text - anywhere - preceded by a 'pound' sign:
The following are valid YAML documents, which combine arrays, lists and comments:
You can also use JSON's '[...]' notation for lists, and '{...}' for arrays - these are specially useful if placing short lists or arrays on a single line:
As YAML was primarily designed to be a data-serialisation language that is human-readable and easy to understand, there are ways for you to break large chunks of text that would span multiple lines:
Finally, there are some features of YAML that go *beyond* what you can do with JSON. This is where YAML starts to become really interesting, and where it gets a bit trickier to develop a parser for YAML than for JSON.
For instance, YAML has a few different ways to avoid duplication of data - e.g., by using '&' pointers to previously entered nodes:
YAML also has **document delimiters**, to allow you to send more than one 'document' in a single stream. Three dashes mark the beginning of a document, and three dots mark the end. Below we see 2 yaml documents in a single stream:
The full YAML spec is quite easy to understand, but it is unfortunately significantly more complex than JSON - you can read it in full, here:
http://www.yaml.org/spec/1.2/spec.html
The following is an example of a well-formed YAML document, with some of the language's basic features included:
Your code seems almost complete, however it seems to expect that every line of the inputted YAML will always be in 'array' (key:value) format - like this:
Code: Select all
name: Mark McGwire
hr: 65
avg: 0.278
Code: Select all
- Mark McGwire
- Sammy Sosa
- Ken Griffey
Code: Select all
hr: 65 # Home runs
avg: 0.278 # Batting average
rbi: 147 # Runs Batted In
Code: Select all
# Lists inside array
american:
- Boston Red Sox
- Detroit Tigers
- New York Yankees
national:
- New York Mets
- Chicago Cubs
- Atlanta Braves
Code: Select all
# Arrays inside list
-
name: Mark McGwire
hr: 65
avg: 0.278
-
name: Sammy Sosa
hr: 63
avg: 0.288
Code: Select all
- [name , hr, avg ]
- [Mark McGwire, 65, 0.278]
- [Sammy Sosa , 63, 0.288]
Code: Select all
name: Mark McGwire
accomplishment: >
Mark set a major league
home run record in 1998.
stats: |
65 Home Runs
0.278 Batting Average
For instance, YAML has a few different ways to avoid duplication of data - e.g., by using '&' pointers to previously entered nodes:
Code: Select all
---
hr:
- Mark McGwire
# labels this node as 'SS'
- &SS Sammy Sosa
rbi:
- *SS # previous node reference
- Ken Griffey
Code: Select all
---
time: 20:03:20
player: Sammy Sosa
action: strike (miss)
...
---
time: 20:03:47
player: Sammy Sosa
action: grand slam
...
http://www.yaml.org/spec/1.2/spec.html
The following is an example of a well-formed YAML document, with some of the language's basic features included:
Code: Select all
--- !<tag:clarkevans.com,2002:invoice>
invoice: 34843
date : 2001-01-23
bill-to: &id001
given : Chris
family : Dumars
address:
lines: |
458 Walkman Dr.
Suite #292
city : Royal Oak
state : MI
postal : 48046
ship-to: *id001
product:
- sku : BL394D
quantity : 4
description : Basketball
price : 450.00
- sku : BL4438H
quantity : 1
description : Super Hoop
price : 2392.00
tax : 251.42
total: 4443.52
comments: >
Late afternoon is best.
Backup contact is Nancy
Billsmer @ 338-4338.
-
- VIP Livecode Opensource Backer
- Posts: 3581
- Joined: Mon Jan 22, 2007 7:36 am
- Location: Berkeley, CA, US
- Contact:
Re: YAML and LiveCode
Not at all. It's the key/value hierarchy that's important, not the placement.I use these functions to deal with my ruby yaml files.it seems to expect that every line of the inputted YAML will always be in 'array' (key:value) format - like this:
Code: Select all
action:
accounts : 'Accounts'
launch_scan : 'Launch Scan'
view_scan_requests : 'View Scan Requests'
view_scan_results : 'View Scan Results'
findings:
day : 'Today'
week : 'Week'
month : 'Month'
policy_rules:
all : 'all'
email : 'email'
malware : 'malware'
network : 'network'
web : 'web'
Not exactly. It's a similar format though, especially with YAML 1.2.YAML is actually a superset of JSON
Anyway, glad you found some use in those functions.
PowerDebug http://powerdebug.ahsoftware.net
PowerTools http://www.ahsoftware.net/PowerTools/PowerTools.irev
PowerTools http://www.ahsoftware.net/PowerTools/PowerTools.irev
-
- VIP Livecode Opensource Backer
- Posts: 92
- Joined: Wed May 29, 2013 1:54 am
- Location: Sydney, Australia
Re: YAML and LiveCode
YAML is a superset of JSON, and a YAML parser should be able to parse JSON documents, too - as well as do quite a bit more.
The latest YAML specs can be found here. Section 1.3 of the specs, titled "Relation to JSON", states:
The latest YAML specs can be found here. Section 1.3 of the specs, titled "Relation to JSON", states:
It would be truly useful to have a fully-compliant YAML parser in LiveCode. There are many web frameworks that use .yaml files either for configuration or data storage, or both, and LiveCode would have been a great tool to be able to produce GUIs for these.(...)YAML can therefore be viewed as a natural superset of JSON, offering improved human readability and a more complete information model. This is also the case in practice; every JSON file is also a valid YAML file. This makes it easy to migrate from JSON to YAML if/when the additional features are required.
-
- VIP Livecode Opensource Backer
- Posts: 92
- Joined: Wed May 29, 2013 1:54 am
- Location: Sydney, Australia
Re: YAML and LiveCode
Hi all! It's been another couple of years, and I'm wondering whether there is now a YAML parser for LiveCode? I've downloaded the latest version (9.0), but haven't been able to see anything in the docs about YAML...
Re: YAML and LiveCode
Trevor has one in his Levure framework, since Levure used YML for configuration.
-
- VIP Livecode Opensource Backer
- Posts: 92
- Joined: Wed May 29, 2013 1:54 am
- Location: Sydney, Australia
Re: YAML and LiveCode
I was unable to (easily) find the code in Levure that deals with parsing YAML. Nevertheless, with a little research I did find a command-line tool that converts YAML to JSON, which LiveCode can then convert into a native array. The tool that I am using is Mike Fara's "yq", which so far has performed quite well for my purpose.
So, for future reference, using yq, the code that allows me to use YAML in LiveCode:
So, for future reference, using yq, the code that allows me to use YAML in LiveCode:
Code: Select all
local tYQCommand, tJSON, tArray
put "path/to/yq r -j" && "path/to/sample.yml" into tYQCommand
put shell(tYQCommand) into tJSON
put JSONToArray(tJSON) into tArray