timeblok 0.5.0

A language for event scheduling in plain text
Documentation
SP = _{" "*}
WHITESPACE = _{ " " }
COMMENT = _{"//"~(!NEWLINE~ANY)*}
NUM_FIELD = @{ASCII_DIGIT+}
IDENT = @{ ASCII_ALPHA ~ ASCII_ALPHANUMERIC* }
AND = {"&" | "and"}
OR = {","|"|" | "or"}
NOT = {"!" | "not"}

UNSURE = {""} // Inherits values or constraints possessed from upstream
ALL={"*"} // Overrides upstream constraints, assumes all possible values
AM = {"AM" | "am"}
PM = {"PM" | "pm"}
TOD = {AM | PM }
FIELD = {NUM_FIELD | UNSURE}
NUM_RANGE = {FIELD~SP~"~"~SP~FIELD}

UNIT_FILTER = _{NUM_RANGE | RANGE | NUM_FIELD }

OP = _{OR|AND}

FILTER = {
    "{"~
    (
       NEWLINE*~
	   (FILTER|UNIT_FILTER)
       ~
       (NEWLINE*~OP~NEWLINE*~(FILTER|UNIT_FILTER))*~NEWLINE*
    )
    ~"}"
}

FLEX_FIELD = _{FILTER | FIELD} // FLEX for "flexible"

TIME = {
    FIELD ~
    (( ":" ~ FIELD? ~ SP ~ TOD?) |
    (":"~FIELD)? ~TOD)
}

DATE = {FIELD ~ "-" ~ FIELD~ "-" ~ FIELD}
DATETIME = {DATE ~ SP ~ TIME}
OCCASION = {DATETIME | DATE | TIME}

UNIT_DATE_FILTER = {NOT? ~ (
    RANGE|
    FLEX_DATE|
    DATE_FILTER|
    IDENT
)}

DATE_FILTER = {
    "{"~NEWLINE*~UNIT_DATE_FILTER~(NEWLINE*~OP~NEWLINE*~UNIT_DATE_FILTER)*~NEWLINE*~"}"
}

FLEX_DATE = {FLEX_FIELD~"-"~FLEX_FIELD~"-"~FLEX_FIELD}
FLEX_DATETIME = {FLEX_DATE ~ SP ~ TIME}
FLEX_OCCASION = {FLEX_DATETIME | FLEX_DATE | TIME | DATE_FILTER} // Don't see much value in bringing flex to time in day.
STRING = {(!"\"" ~ ASCII)*}
STRING_WRAP = _{"\"" ~ STRING ~ "\""}
CARG = {(!(NEWLINE|WHITESPACE)~ANY)+}

ARGW = _{ (DATE_FILTER | FILTER | NUM_FIELD| IDENT | STRING_WRAP | CARG) ~ WHITESPACE*}
ARGE = _{ (DATE_FILTER | FILTER | NUM_FIELD| IDENT | STRING_WRAP | CARG) ~ WHITESPACE* ~ (NEWLINE|EOI)}
ARGS = {(!ARGE~ARGW)*~ARGE}
COMMAND = ${"/" ~ (IDENT~WHITESPACE) ~ ARGS}
PROPERTY = ${"@" ~ (IDENT~WHITESPACE) ~ ARGE}

RANGE = {OCCASION ~ SP ~ "~" ~ SP ~ OCCASION}
EVENT_HEADER = {(RANGE | OCCASION) ~ SP ~ NOTE_LINE}
NOTE = {(!NEWLINE~ANY)+}
NOTE_LINE = _{NOTE ~ NEWLINE?}
EVENT = {
    EVENT_HEADER ~ NEWLINE* ~
    (!(EVENT_HEADER | OCCASION | FLEX_OCCASION | COMMAND) ~ (PROPERTY |NOTE_LINE))*
}
FLEX_EVENTS = {
	FLEX_OCCASION ~ NEWLINE* ~ EVENT*
}
RECORD = {EVENT | OCCASION | COMMAND | FLEX_EVENTS | NOTE_LINE}
FILE = {
    SOI ~
    (RECORD ~ NEWLINE*)*
}