WHITESPACE = _{ " "+ }
WS_OPT = _{ " "* }
sep = _{ ";" }
ident = @{ ASCII_ALPHANUMERIC+ }
bool = @{ "true" | "false" }
fp = @{ int ~ ("." ~ ASCII_DIGIT+)? }
uint = @{ ASCII_DIGIT+ }
int = @{ "-"? ~ ASCII_DIGIT+ }
// string_unicode is based on https://pest.rs/book/examples/json.html
string_unicode = ${ (quot_double ~ string_inner ~ quot_double) | (quot_single ~ string_inner ~ quot_single) }
string_inner = @{ char* }
quotation = _{ quot_single | quot_double }
quot_single = _{ "'" }
quot_double = _{ "\"" }
char = {
!quotation ~ ANY
| "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
| "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}
named_value = ${ ident ~ "(" ~ arguments ~ ")" }
// note that all numbers (floating point, unsigned integers, integers etc.) are represented
// as "fp" (floating point representation) in the grammar
arg = _{ bool | fp | string_unicode }
arguments = _{ arg ~ (WS_OPT ~ "," ~ WS_OPT ~ arg)* }
triplet_sep = _{ WHITESPACE ~ "|" ~ WHITESPACE }
triplet_fp3 = _{ fp ~ WHITESPACE ~ fp ~ WHITESPACE ~ fp }
f3x3_args_sep = _{ triplet_fp3 ~ triplet_sep ~ triplet_fp3 ~ triplet_sep ~ triplet_fp3 }
f3x3_args_no_sep = _{ triplet_fp3 ~ WHITESPACE ~ triplet_fp3 ~ WHITESPACE ~ triplet_fp3 }
blur = ${ ^"blur" ~ WHITESPACE ~ fp }
brighten = ${ ^"brighten" ~ WHITESPACE ~ int }
contrast = ${ ^"contrast" ~ WHITESPACE ~ fp }
crop = ${ ^"crop" ~ WHITESPACE ~ uint ~ WHITESPACE ~ uint ~ WHITESPACE ~ uint ~ WHITESPACE ~ uint }
diff = ${ ^"diff" ~ WHITESPACE ~ string_unicode }
filter3x3 = ${ ^"filter3x3" ~ WHITESPACE ~ (f3x3_args_sep | f3x3_args_no_sep) }
flip_horizontal = { ^"flip-horizontal" }
flip_vertical = { ^"flip-vertical" }
grayscale = { ^"grayscale" }
huerotate = ${ ^"hue-rotate" ~ WHITESPACE ~ int }
horizontal_gradient = ${ ^"horizontal-gradient" ~ WHITESPACE ~ named_value ~ WHITESPACE ~ named_value }
invert = { ^"invert" }
overlay = ${ ^"overlay" ~ WHITESPACE ~ string_unicode ~ WHITESPACE ~ uint ~ WHITESPACE ~ uint }
resize = ${ ^"resize" ~ WHITESPACE ~ uint ~ WHITESPACE ~ uint }
rotate90 = { ^"rotate90" }
rotate180 = { ^"rotate180" }
rotate270 = { ^"rotate270" }
threshold = { ^"threshold" }
unsharpen = ${ ^"unsharpen" ~ WHITESPACE ~ fp ~ WHITESPACE ~ int }
vertical_gradient = ${ ^"vertical-gradient" ~ WHITESPACE ~ named_value ~ WHITESPACE ~ named_value }
// example usage: draw-text "my text" rgba(10, 10, 255, 255) size(16)
draw_text = ${^"draw-text" ~ WHITESPACE ~ string_unicode ~ (WHITESPACE ~ named_value)*}
env_resize_sampling_filter_name = {^"sampling-filter"}
env_resize_preserve_aspect_ratio_name = {^"preserve-aspect-ratio"}
env_available = _{
env_resize_sampling_filter_name
| env_resize_preserve_aspect_ratio_name
}
set_resize_sampling_filter = ${env_resize_sampling_filter_name ~ WHITESPACE ~ ident }
set_resize_preserve_aspect_ratio = ${ env_resize_preserve_aspect_ratio_name ~ WHITESPACE ~ bool}
setenv_available = _{
set_resize_sampling_filter
| set_resize_preserve_aspect_ratio
}
setopt = ${^"set" ~ WHITESPACE ~ setenv_available}
unsetopt = ${^"del" ~ WHITESPACE ~ env_available}
operation = _{
blur
| brighten
| contrast
| crop
| diff
| draw_text
| filter3x3
| flip_horizontal
| flip_vertical
| grayscale
| huerotate
| horizontal_gradient
| invert
| overlay
| resize
| rotate90
| rotate180
| rotate270
| threshold
| unsharpen
| vertical_gradient
}
sequence = _{
(operation | setopt | unsetopt ) ~ ( (NEWLINE* ~ EOI) | (sep ~ NEWLINE+) | sep)
}
main = _{ SOI ~ sequence* ~ EOI }