项目作者: muon-data

项目描述 :
MuON data interchange specification
高级语言:
项目地址: git://github.com/muon-data/muon.git
创建时间: 2019-06-08T01:47:51Z
项目社区:https://github.com/muon-data/muon

开源协议:Creative Commons Attribution Share Alike 4.0 International

下载


MuON v1.1

Micro Object Notation

by Douglas Lau

MuON is a text format for data serialization. It is suitable for
configuration files and data interchange — as expressive as other formats, but
much simpler.

  1. # MuON example
  2. movie: Alien
  3. director: Ridley Scott
  4. cast:=Sigourney Weaver
  5. :=Tom Skerritt
  6. :=John Hurt
  7. release: 1979-06-22
  8. region: USA
  9. release: 1979-09-06
  10. region: UK
  11. gross: 203_630_630
  12. emoji: 👽 👾

Specification

MuON is Unicode text encoded in
UTF-8, with no
byte-order mark.
MuON is case sensitive and line based.

A line is a definition, comment or blank, and must end with a single line
feed
character (U+000A). Comments begin with a number sign #, which may
be preceded by spaces. Blank lines contain no characters.

  1. # Example comment

A definition maps a key to a value, with a colon and space between.

  1. key: value

If the value is empty, the space is not required.

Some definitions create branches. Starting from a root record, all
branches form a tree. With no indents, definitions are contained in the root.
After a branch, subsequent definitions with one more indent are contained in
it.

  1. key_in_root: value in root
  2. branch:
  3. key_in_branch: value in branch

Definition indents are exactly 2, 3 or 4 spaces (U+0020). Nested branches
use multiple indents. The number of spaces must be the same for all indents
in a file.

  1. family: Ursidae
  2. # One indent; 3 spaces
  3. genus: Ailuropoda
  4. # Two indents; 6 spaces
  5. species: A. melanoleuca 🐼

A key is a sequence of one or more characters. It must be "quoted"
if it contains a colon or begins with a space, quote mark or number sign. In
this case, all quote marks in the key must be doubled.

  1. # "skeleton" key begins with a quote mark
  2. """skeleton"" key": value

Also, a key should be quoted if it begins with
whitespace, contains
control characters
or homoglyphs
of colon.

A value is a sequence of characters. With the exception of line feed, any
Unicode character is allowed.


A schema is a template with types as values. It can be separate or
prepended to a MuON file. In either case, it begins and ends with a line of
three colons.

  1. :::
  2. # Example MuON schema
  3. movie: list record
  4. title: text
  5. director: text Alan Smithee
  6. cast: list text
  7. release: list record
  8. release_date: date >=1878-01-01
  9. region: text
  10. gross: int
  11. emoji: optional text
  12. :::

There are eleven available types: text, bool, int, number,
datetime, date, time, record, choice, dictionary and any. They
are used to parse objects from values.

An optional or list modifier may precede the type, followed by a space.

One or two constraints may follow the type, with a space between. This is
one of four specifiers >, >=, < or <=, followed by a value. For int,
number, datetime, date and time types, it defines a subrange of valid
values. For text, it restricts the count of characters.

A default value may be included after the type and any constraints, also
separated with a space. It is a value for the type, used when a definition is
not present. Allowed types are text, bool, int, number, datetime,
date and time. Defaults are not allowed with optional or list
modifiers.


Text is a sequence of characters.

  1. :::
  2. greeting: text Hello!
  3. farewell: text Goodbye!
  4. :::
  5. # greeting is Hello!
  6. farewell: Be seeing you.

Because values cannot contain line feeds, they can only be represented using
multiple definitions. The text must be split into values between each line
feed. For each definition after the first, use a text append separator,
which is :> instead of the usual : before the value.

When appending, use a blank key — a sequence of spaces with the same number
of characters as the key.

  1. lyric: Out in the garden
  2. :>There's half of a heaven

Bool is a boolean: either true or false.

  1. earth_is_flat: false

Int is an integer (whole number) in one of three forms:

  • Decimal: sequence of digits 0-9. May have a + or - sign prefix
  • Binary: b followed by sequence of digits 0 or 1
  • Hexadecimal: x followed by sequence of digits 0-9, A-F or
    a-f

An underscore may be inserted between digits to improve readability.

  1. locke: 4
  2. reyes: b1000
  3. ford: x0F
  4. jarrah: +16
  5. shephard: b01_0111
  6. kwon: x2a

If no constraints are given, an integer has no bounds (BigInt).

  1. :::
  2. uint8: int >=0 <=255
  3. rank: int >0 <6
  4. :::
  5. uint8: 49
  6. rank: 3

A number is a 64-bit
floating point number, made up of
these parts:

  1. Whole number part (same as decimal int)
  2. Fractional part (decimal point followed by sequence of digits 0-9)
  3. Exponent part (e followed by decimal int)

One or both of the whole or fractional parts must be present, but the exponent
part is not required. As with ints, underscores may be included.

The values inf and NaN stand for infinity and not a number,
respectively. Either can be prefixed with a + or - sign.

  1. prime: 37
  2. log_e_2: .6931471805599453
  3. mercury: -38.83440
  4. planck: 6.626_070_15e-34
  5. buzz: +inf
  6. avogadro: 6.022_140_76e23

Datetime is date, time and offset, as specified by date-time
from RFC 3339. The date and
time are separated by an uppercase T only. If the offset is represented by
Z, it must also be uppercase.

  1. moonwalk: 1969-07-21T02:56:00Z

Date is year, month and day, as specified by full-date from
RFC 3339.

  1. birthday: 2019-08-01

Time is hour, minute and second, as specified by partial-time from
RFC 3339.

  1. start: 08:00:00
  2. end: 15:58:14.593849001

A record is a branch containing fields as subsequent definitions. A
record represents all of its fields.

  1. :::
  2. book: record
  3. title: text
  4. author: text
  5. year: int
  6. :::
  7. book:
  8. title: If on a winter's night a traveler
  9. author: Italo Calvino
  10. year: 1979

Field keys are often used in programming languages as
identifiers.
For compatibility, they should contain only ASCII alphanumeric or underscore
characters.

Since records do not use their values, they can substitute for the first
field, which must then be left out. Like defaults, substitution is only
allowed for text, bool, int, number, datetime, date and time types
without optional or list modifiers.

  1. book: The Left Hand of Darkness
  2. author: Ursula K. Le Guin
  3. year: 1969

In the schema, a record id can follow record after a space. It is used
if a record exists in more than one place. After the first definition, the
fields do not need to be included.

  1. :::
  2. player: record Character
  3. name: text
  4. health: int
  5. nemesis: record Character
  6. :::
  7. player: Arthur
  8. health: 50
  9. nemesis: Mordred
  10. health: 60

A choice is a branch containing variants as subsequent definitions. A
choice represents exactly one of the variants.

A variant containing no data is declared as a definition with no type.
These variants can substitute for the choice value.

  1. :::
  2. pill: choice
  3. red
  4. blue
  5. :::
  6. pill: red

Variants can also contain arbitrary data. These must be declared with a
subsequent definition.

  1. :::
  2. strategy: choice
  3. attack: int
  4. retreat
  5. surrender: text
  6. :::
  7. strategy:
  8. attack: 50

In the schema, a variant id can follow choice after a space. This works
in the same way as a record id.

  1. :::
  2. face_a: choice direction
  3. North
  4. South
  5. East
  6. West
  7. face_b: choice direction
  8. :::
  9. face_a: North
  10. face_b: East

A dictionary is a branch for associative arrays — useful if keys are not
known in advance. The schema must contain a single definition with types for
both key and value. The key type is restricted to text, bool, int,
number, datetime, date or time.

  1. :::
  2. num_word: dictionary
  3. text: int
  4. :::
  5. num_word:
  6. fifty: 50
  7. one: 1
  8. thirteen: 13

Any is a branch containing data of any type. It should be used for data
which does not fit into a rigid schema.

  1. :::
  2. product: list record
  3. name: text
  4. price: number
  5. details: any
  6. :::
  7. product: duct tape
  8. price: 4.99
  9. details:
  10. color: silver
  11. width: 8 cm
  12. product: machete
  13. price: 29.99
  14. details:
  15. length: 50 cm
  16. weight: 0.5 kg

Optional types are not required — the absence of a definition represents
a None or null value.

  1. :::
  2. name: text
  3. occupation: optional text
  4. :::
  5. name: Surfer Joe
  6. # no occupation

A list is parsed as a sequence of objects, separated by spaces. If a
list is empty, omit its definition.

  1. :::
  2. show_times: list time
  3. healthy_snacks: list text
  4. :::
  5. show_times: 15:40:00 18:00:00 20:20:00
  6. # no healthy_snacks

Like text, lists can be appended. All objects are added to the end.

  1. fibonacci: 0 1 1 2 3
  2. : 5 8 13 21 34
  3. # same as fibonacci: 0 1 1 2 3 5 8 13 21 34

When appending to list record or list dictionary, the key cannot be
blank, since the definitions are not consecutive.

  1. person: George Washington
  2. birthday: 1732-02-22
  3. person: Abraham Lincoln
  4. birthday: 1809-02-12

For list text, objects are separated by spaces, just like other lists. If
a text object contains spaces, use the text value separator := to treat
an entire value as a single object. The text append separator :> will
also append an entire value to the previous text object.

  1. shopping: avocado banana
  2. :=cream cheese
  3. : cucumber
  4. :=ice cream
  5. : raw
  6. :>burger! (mmmm)

Contributing

Any feedback, bug reports, spelling fixes, or text clarity improvements are
welcome! Please create an issue.