Fig
Fig is a human-readable configuration / data interchange format.
Fig must be UTF-8. All valid UTF-8 is valid Fig.
I am pretty sure Fig was an acronym, but I forgot what it stood for.
I invented Fig in a hostel in Copenhagen during KotlinConf 2019. I was jetlagged and consuming a bunch of coffee and Carlsberg, which may explain why I forgot what it stands for and why it is so weird.
The format
Comments
Comments are in angle brackets.
<this is a comment>
You cannot have a > in a comment. Sorry.
Data types
Fig has 6 data types:
- null
- boolean
- number
- string
- list
- map
Nulls
null is null.
Booleans
true and false
Numbers
Numbers are made of an optional + or -,
followed by one or more digits (0 - 9),
optionally followed by . and one or more digits,
optionally followed by E then optionally a + or - then one or more digits.
There should probably be a way to indicate inifinity, negative infinity, and NaN.
Strings
A sequence of non-whitespace characters or
a sequence of any characters quoted with ".
\ escapes characters.
"this has a double quote in it -> \" <- right there. and a backslash here:\\"
a"b" < <-- that is 2 strings because the " starts a new one>
The value here is "a, not a because there is no trailing ".
"a
Lists
A list is a sequence of values in square brackets.
[
"this is a list"
"of two strings and an integer" 9
]
The closing ] may be omitted at the end of the file.
[ this is a list
Maps
A map is a sequence of keys and values.
Maps are enclosed in { and }.
Key/value pairs are separated by whitespace.
Keys and values are separated by :, with optionaly whitespace before and after the :.
A key with no : after it has a null value.
Keys are nullable strings.
{
a:5
b:"hello world"
:"this value has a null key"
c:[a list value in a map]
d:{a:map in:"a map"}
e:null <null value>
f <implicit null value>
}
The closing } may be omitted at the end of the file.
This is valid:
{ this:is a:map with:[a list
Map names
Maps can have names. This is very useful to identify a type for deserializing.
A named map has a % immediately after the {, followed by the name,
which is a sequence of non-whitespace characters.
[
{%star
name:Sun
mass:1.9885E30
location:"in the middle"
}
{%planet
name:Pluto
mass:1.303E22
location:"way out there"
}
{%comet
name:"Halley's Comet"
mass:2.2E14
location:"the central part of town"
}
]
Whitespace
The following UTF-8 codepoints are considered whitespace:
- 0009 - CHARACTER TABULATION (\t)
- 000A - LINE FEED (\n)
- 000B - LINE TABULATION
- 000C - FORM FEED
- 000D - CARRIAGE RETURN (\r)
- 001C - INFORMATION SEPARATOR FOUR
- 001D - INFORMATION SEPARATOR THREE
- 001E - INFORMATION SEPARATOR TWO
- 001F - INFORMATION SEPARATOR ONE
- 0020 - SPACE
- 00A0 - NO-BREAK SPACE
- 1680 - OGHAM SPACE MARK
- 2000 - EN QUAD
- 2001 - EM QUAD
- 2002 - EN SPACE
- 2003 - EM SPACE
- 2004 - THREE-PER-EM SPACE
- 2005 - FOUR-PER-EM SPACE
- 2006 - SIX-PER-EM SPACE
- 2007 - FIGURE SPACE
- 2008 - PUNCTUATION SPACE
- 2009 - THIN SPACE
- 200A - HAIR SPACE
- 2028 - LINE SEPARATOR
- 2029 - PARAGRAPH SEPARATOR
- 202F - NARROW NO-BREAK SPACE
- 205F - MEDIUM MATHEMATICAL SPACE
- 3000 - IDEOGRAPHIC SPACE
Fig File
A Fig file is a list or a map. If the content is not explicitly a list
(by starting with optional whitespace/comments and then a [)
or explicitly a map
(by starting with optional whitespace/comments and then a {)
then it is a list
(without a trailing ])
this is a list of 7 values <and a comment at the end>
Everything is valid?
Yup. This is where it gets weird. And where the parser probably gets slow on large files.
One advantage of making everything valid is that nobody can take advantage of undefined or illegal syntax to make an extension of Fig.
This can almost certainly be used as evidence to either my genius or my insanity.