OnlyData is a simple, flexible, and human-readable data serialization language.
It includes:
- convenient formatting for simple data types
- line terminated data entry
- native import functionality
- file based object creation
########################################
## QUICK
str = simple strings
num = 105
bool = true
none = null
map = {
key: value
key: value
}
map = import ./other/data.onlydata
list = [ value, value, value ] # comment
########################################
## CLEAR
str = feel free to use apostrophe's denotation
str = and insert "quotations as you please"
str = 'or wrap strings if you want to'
str = "applying \"escapes\" when you 'need'"
str = " keep your space "
str = '# not a comment'
str = '[ not a list ]'
str = <<
<div>
<h1>A Formatted Multi-Line String</h1>
# all comments get trimmed
<p>as well as all whitespace and line breaks</p>
</div>
>>
str = <<<
<div>
<h2>A Raw Multi-Line String</h2>
<p>all characters remain as written</p>
</div>
>>>
num = +105
num = -15e3
num = 54,321.123_45
bool = yes
bool = True
bool = TRUE
none = nil
none = Null
none = NULL
map = { key: value, key: value }
map = {
key: value,
key: value,
}
map = {
key: value
key: value
}
map = import @base/custom/file.only
map = {
map: Import ../file/based/nesting.od
}
list = [ value, value, value, ]
list = [
value,
value,
value
]
list = [
value
value
value
]
- Each OnlyData file is equivalent to one map.
- UTF-8 encoding is mandatory.
- File extensions must be
.od
,.only
, or.onlydata
. - Line breaks are automatically converted to line feeds.
- Backslashes are taken literally (i.e. no escape sequences) except when escaping quotation marks within quoted strings.
- Initialized by a hash mark,
#
. - Terminated by a line break.
- Can begin at any point on a line.
- Keys must begin with a letter, a-z (not case-sensitive), or an underscore.
- Keys can contain letters, numbers, underscores, or dashes.
- Base keys use the equal sign,
=
, to attribute value. - Nested keys use the colon,
:
, to attribute value. - Whitespace is trimmed before and after each key.
- Keys must include a value.
- All values except for string blocks, maps, and lists are terminated by line breaks.
- Whitespace is trimmed before and after each value.
- Base values can be any data type.
- Nested values (i.e. values within nested maps or lists) can be any one line data type.
The standard true
or false
boolean values with optional yes
or no
aliases. Booleans are not case-sensitive.
key = false
key = True
key = YES
-
Basic String
All line-terminated values that do not match another data type are trimmed of whitespace and considered a string.str = I am a basic string. str = I am a basic string with "quotation marks" included.
-
Quoted String
One line strings can be enclosed by single,'
, or double,"
, quotation marks to improve clarity, keep whitespace, use a special character, or define an empty string. Quoted strings must begin and end with the chosen quotation mark. Quotation marks within quoted strings that match the opening mark must be escaped (i.e. backslashed). Multi-line strings must be blocked (i.e. cannot be quoted).str = '' str = 'I am a quoted string.' str = "I am a quoted string." str = 'I am a basic string with "quotation marks" included.' str = "I am a basic string with \"quotation marks\" included."
-
Blocked String
Multi-line strings must be enclosed by two or three angle brackets,<
and>
. Blocked string values must begin with only the opening angle brackets for the first line and end with only the closing angle brackets for the last line. For two bracket enclosed strings, all line breaks, comments, and leading/ending whitespace (per line) is trimmed. For three bracket enclosed strings (aka raw strings), only the leading and ending line breaks are trimmed.str = << # Trims comments, whitespace, and line breaks <div> <p>I am a blocked string.</p> </div> >> str = <<< # Keeps comments, whitespace, and line breaks <div> <p>I am a raw string.</p> </div> >>>
-
Integer
All positive or negative whole numbers within the signed 64-bit integer range. Integers may be preceded by a plus,+
, or minus,-
, sign and contain commas,,
, or underscores,_
, between groups of three digits for increased clarity.num = +5 num = -5 num = 1000 num = 1,000 num = 1_000
-
Float
All positive or negative fractions and exponentially-expressed numbers within the 64-bit double-precision float range. The decimal mark,.
, is used to indicate fractional portions, and the exponential mark,e
(not case-sensitive), to indicate exponents. Floats may be preceded by a plus,+
, or minus,-
, sign, contain commas,,
, or underscores,_
, between groups of three digits preceding the decimal and exponential mark, contain underscores,_
, between groups of three digits following the decimal mark and preceding the exponential mark, and precede an exponent with a plus,+
, or minus,-
, sign.num = +5.01 num = -5.09 num = 1.234 num = 3E+5 num = 3E-5 num = 3e10 num = 4.3e-10 num = 4.899E5 num = 54,321.123_45 num = 54_321.123_45 num = -54,321.123_45e6
Maps are simple key/value associative arrays.
Nested maps must be enclosed with curly braces, {
and }
, unless
importing a separate file. Note that deep nesting is strictly
limited to encourage simple data structures and when necessary the use of
separate pages (i.e. importing) to break down more complex
structures.
-
Inline Maps
- Key/value pairs must be separated by a comma,
,
. - A comma is optional for the last key/value pair.
- Strings must be quoted (i.e. basic and blocked strings are not allowed).
- Numbers must use underscores for any clarity marks (i.e. do not use commas).
- Maps, lists, and importing are not allowed
(i.e. use a multi-line map).
map = { key: value, key: value, key: value } map = { key: value, key: value, key: value, }
- Key/value pairs must be separated by a comma,
-
Multi-line Maps
- Key/value pairs are not allowed on the same line as the opening and closing curly braces.
- Key/value pairs must be separated by a line break.
- Key/value pairs may be separated by a comma and line break.
- If a comma is used to separate pairs, a comma is optional for the last key/value pair.
- Blocked strings are not allowed (i.e. keep strings to one-line when nesting).
- Maps and lists must be inline (i.e. deep nesting is only
allowed via importing).
map = { key: value key: value key: value } map = { key: value, key: value, key: value } map = { key: value, key: value, key: value, }
Lists are simple indexed arrays of values.
Lists must be enclosed with square brackets, [
and ]
.
-
Inline Lists
- Values must be separated by a comma,
,
. - A comma is optional for the last value.
- Strings must be quoted (i.e. basic and blocked strings are not allowed).
- Numbers must use underscores for any clarity marks (i.e. do not use commas).
- Maps, lists, and importing are not allowed
(i.e. use a multi-line list).
list = [ value, value, value ] list = [ value, value, value, ]
- Values must be separated by a comma,
-
Multi-line Lists
- Values are not allowed on the same line as the opening and closing square brackets.
- Values must be separated by a line break.
- Values may be separated by a comma and line break.
- If a comma is used to separate values, a comma is optional for the last value.
- Blocked strings are not allowed (i.e. keep strings to one-line).
- Maps and lists must be inline (i.e. deep nesting is only
allowed via importing).
list = [ value value value ] list = [ value, value, value ] list = [ value, value, value, ]
Null is used to represent all empty, missing, or undefined values. The
keywords null
or nil
(not case-sensitive) are used to represent a
null value.
key = null
key = NIL
Maps can be imported as values via the import
keyword (not
case-sensitive). An OnlyData filepath must follow the import
keyword.
Whitespace must be used to separate the keyword and filepath. An absolute or
relative filepath may be used. Additionally, a value from the
import-base
map (parser's must allow this option to be set) may used as
the base path by beginning the filepath with an at symbol, @
, followed
by the key name and a slash, @key/
. To import all files from a directory
into one map that uses each filename with the leading path and extension
trimmed as its keys and their parsed map as its values, an asterisk, *
,
may be used in place of the filename.
key = import /abs/path/to/file.od
key = import ../rel/path/to/file.od
key = Import rel/path/to/files/*.only
key = IMPORT @base/path/to/file.onlydata
contributing: see contributing guide
bugs/improvements: open an issue
questions: imagineadamsmith@gmail.com