201 lines
4.0 KiB
Markdown
201 lines
4.0 KiB
Markdown
# Fig
|
|
|
|
Fig is a human-readable 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 X 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 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"
|
|
}
|
|
{%coment
|
|
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. |