diff --git a/pax-compiler/src/parsing.rs b/pax-compiler/src/parsing.rs index 5913f6273..8f7748a0d 100644 --- a/pax-compiler/src/parsing.rs +++ b/pax-compiler/src/parsing.rs @@ -85,7 +85,6 @@ fn recurse_pratt_parse_to_string<'a>( Rule::expression_grouped => { /* expression_grouped = { "(" ~ expression_body ~ ")" ~ literal_number_unit? } */ let mut inner = primary.into_inner(); - let exp_bod = recurse_pratt_parse_to_string(inner.next().unwrap().into_inner(), pratt_parser, Rc::clone(&symbolic_ids)); if let Some(literal_number_unit) = inner.next() { let unit = literal_number_unit.as_str(); @@ -110,10 +109,18 @@ fn recurse_pratt_parse_to_string<'a>( xo_function_args_list = {expression_body ~ ("," ~ expression_body)*} */ //prepend identifiers; recurse-pratt-parse `xo_function_args`' `expression_body`s - let mut pairs = primary.into_inner(); - + let mut pairs = primary.clone().into_inner(); let mut output = "".to_string(); let mut next_pair = pairs.next().unwrap(); + match next_pair.as_rule() { + Rule::literal_color => { + return recurse_pratt_parse_to_string(primary.into_inner(), pratt_parser, Rc::clone(&symbolic_ids)); + } + Rule::literal_hex_color => { + return recurse_pratt_parse_to_string(pairs, pratt_parser, Rc::clone(&symbolic_ids)); + } + _=>() + } while let Rule::identifier = next_pair.as_rule() { output = output + next_pair.as_str(); next_pair = pairs.next().unwrap(); @@ -172,8 +179,7 @@ fn recurse_pratt_parse_to_string<'a>( format!("{}", op0_out + &op1_out + &op2_out) }, Rule::xo_literal => { - let literal_kind = primary.into_inner().next().unwrap(); - + let literal_kind = primary.clone().into_inner().next().unwrap(); match literal_kind.as_rule() { Rule::literal_number_with_unit => { let mut inner = literal_kind.into_inner(); @@ -201,12 +207,34 @@ fn recurse_pratt_parse_to_string<'a>( Rule::string => { format!("StringBox::from({})",literal_kind.as_str().to_string()) }, + Rule::literal_color => { + return recurse_pratt_parse_to_string(literal_kind.into_inner(), pratt_parser, Rc::clone(&symbolic_ids)); + }, + Rule::literal_hex_color => { + return recurse_pratt_parse_to_string(primary.into_inner(), pratt_parser, Rc::clone(&symbolic_ids)); + } _ => { /* {literal_enum_value | literal_tuple_access | literal_tuple | string } */ literal_kind.as_str().to_string() } } }, + Rule::literal_color => { + let color_format = primary.as_str(); + return parse_rgb_color(primary,color_format); + }, + Rule::literal_hex_color => { + let hex = primary.as_str(); + let hex = hex.trim().trim_start_matches('#'); + let r = u8::from_str_radix(&hex[0..2], 16).expect("Invalid hex value for red") as f64; + let g = u8::from_str_radix(&hex[2..4], 16).expect("Invalid hex value for green") as f64; + let b = u8::from_str_radix(&hex[4..6], 16).expect("Invalid hex value for blue") as f64; + + let r = format!("Size::Percent({}.into())",(r/255.0)*100.0); + let g = format!("Size::Percent({}.into())",(g/255.0)*100.0); + let b = format!("Size::Percent({}.into())",(b/255.0)*100.0); + format!("Color::rgb({r},{g},{b}).into()") + } Rule::xo_object => { let mut output : String = "".to_string(); @@ -269,7 +297,8 @@ fn recurse_pratt_parse_to_string<'a>( Rule::expression_body => { recurse_pratt_parse_to_string(primary.into_inner(), pratt_parser, Rc::clone(&symbolic_ids)) }, - _ => unreachable!("{}",primary.as_str()), + + _ => unreachable!("{:#?}",primary.as_str()), }) .map_prefix(|op, rhs| match op.as_rule() { Rule::xo_neg => format!("(-{})", rhs), @@ -302,6 +331,37 @@ fn recurse_pratt_parse_to_string<'a>( .parse(expression) } +fn parse_rgb_color(color: Pair<'_, Rule>, color_format: &str) -> String { + let mut inner = color.into_inner(); + + let r = inner.next().unwrap().as_str().replace("%", ""); + let g = inner.next().unwrap().as_str().replace("%", ""); + let b = inner.next().unwrap().as_str().replace("%", ""); + let a = inner + .next() + .map(|x| x.as_str().replace("%", "")) + .unwrap_or("1".to_string()); + + let r = format!("Size::Percent({}.into())", r); + let g = format!("Size::Percent({}.into())", g); + let b = format!("Size::Percent({}.into())", b); + let a = format!("Size::Percent({}.into())", a); + + let comma_count = color_format.chars().filter(|&c| c == ',').count(); + + if color_format.starts_with("rgb(") && comma_count == 2 { + format!("Color::rgb({r},{g},{b}).into()") + } else if color_format.starts_with("rgba(") && comma_count == 3 { + format!("Color::rgba({r},{g},{b},{a}).into()") + } else if color_format.starts_with("hlc(") && comma_count == 2 { + format!("Color::hlc({r},{g},{b}).into()") + } else if color_format.starts_with("hlca(") && comma_count == 3 { + format!("Color::hlca({r},{g},{b},{a}).into()") + } else { + panic!("Invalid color format: {}", color_format) + } +} + fn parse_template_from_component_definition_string(ctx: &mut TemplateNodeParseContext, pax: &str) { let pax_component_definition = PaxParser::parse(Rule::pax_component_definition, pax) .expect(&format!("unsuccessful parse from {}", &pax)) // unwrap the parse result diff --git a/pax-compiler/src/pax.pest b/pax-compiler/src/pax.pest index 65ff8a3a2..9f29fd12a 100644 --- a/pax-compiler/src/pax.pest +++ b/pax-compiler/src/pax.pest @@ -107,7 +107,7 @@ handlers_value = { literal_function | function_list } literal_function = { "self."? ~ identifier ~ ","? } function_list = {"[" ~ literal_function* ~ "]"} -literal_value = { literal_number_with_unit | literal_number | literal_tuple | literal_enum_value | literal_boolean | string } +literal_value = { literal_number_with_unit | literal_number | literal_color | literal_hex_color | literal_enum_value | literal_boolean | string | literal_tuple} literal_number_with_unit = { literal_number ~ literal_number_unit } literal_number = {"-"? ~ (literal_number_float | literal_number_integer)} literal_number_integer = {(!(".") ~ ASCII_DIGIT)+ } @@ -115,6 +115,10 @@ literal_number_float = {ASCII_DIGIT* ~ "." ~ ASCII_DIGIT+} literal_number_unit = {("%" | "px" | "deg" | "rad")} literal_tuple = {("(") ~ literal_value ~ ("," ~ literal_value)* ~ (")")} literal_boolean = {("true" | "false")} +//some_color = {("rgb(")) | ("rgba(")) | ("hlc(")) | ("hlca(")) } +literal_color = {(("rgb(") | ("rgba(")| ("hlc(")| ("hlca(")) ~ literal_number_with_unit ~ ("," ~ literal_number_with_unit)* ~ ("," ~ literal_number_with_unit)* ~ (")")} +literal_mixed_hex = { '0'..'9' | (('a'..'f') | ('A'..'F'))} +literal_hex_color = {"#" ~ literal_mixed_hex{6}} //Enums like Orientation::Vertical or Color::Rgba(100%, 100%, 0, 0) @@ -215,7 +219,7 @@ xo_range = { (xo_literal | xo_symbol) ~ (xo_range_exclusive) ~ (xo_literal | xo_ xo_range_exclusive = @{".."} // xo_range_inclusive = @{"..="} -xo_literal = {literal_enum_value | literal_tuple_access | literal_number_with_unit | literal_number | string | literal_tuple } +xo_literal = {literal_enum_value | literal_tuple_access | literal_number_with_unit | literal_number | string | literal_tuple | literal_color | literal_hex_color } //objects may recurse into arbitrary expressions for any value -- consider the `key_2` in: // `some_prop={ TypedReturn {key_0: 0, key_1: "one", key_2: 1.0 + 1.0} }` @@ -226,7 +230,7 @@ xo_symbol = { "$"? ~ identifier ~ (("." ~ identifier) | ("[" ~ expression_body ~ xo_tuple = { "(" ~ expression_body ~ ("," ~ expression_body)* ~ ")"} xo_list = { "[" ~ (expression_body ~ ("," ~ expression_body)*)? ~ "]" } -xo_function_call = {identifier ~ (("::") ~ identifier)* ~ ("("~xo_function_args_list~")")} +xo_function_call = { literal_color | identifier ~ (("::") ~ identifier)* ~ ("("~xo_function_args_list~")")} xo_function_args_list = {(expression_body ~ ("," ~ expression_body)*)?} ////// ////// ////// diff --git a/pax-example/src/website_desktop.pax b/pax-example/src/website_desktop.pax index 35501d708..15f4eeb50 100644 --- a/pax-example/src/website_desktop.pax +++ b/pax-example/src/website_desktop.pax @@ -12,7 +12,7 @@ fill={Fill::linearGradient( (0%, 50%), (100%, 50%), - [GradientStop::get(Color::rgba(0.0%,0.0%,0.0%,100.0%), 0%), GradientStop::get(Color::rgba(0.0%,0.0%,0.0%,50.0%), 100%)])} + [GradientStop::get(Color::rgba(0.0,0.0,0.0,1.0), 0%), GradientStop::get(Color::rgba(0.0,0.0,0.0,0.5), 100%)])} corner_radii={ RectangleCornerRadii::radii(50.0,50.0,50.0,50.0) @@ -34,7 +34,7 @@ fill={Fill::linearGradient( (0%, 0%), (100%, 100%), - [GradientStop::get(Color::rgb(100.0%,100.0%,0.0%), 0%), GradientStop::get(Color::rgb(100.0%,0.0%,100.0%), 100%)])} + [GradientStop::get(Color::rgb(1.0,1.0,0.0), 0%), GradientStop::get(Color::rgb(1.0,0.0,1.0), 100%)])} /> @@ -49,7 +49,7 @@ fill={Fill::linearGradient( (0%, 0%), (100%, 100%), - [GradientStop::get(Color::rgb(0.0%,100.0%,100.0%), 0%), GradientStop::get(Color::rgb(0.0%,100.0%,0.0%), 100%)])} + [GradientStop::get(Color::rgb(0.0,1.0,1.0), 0%), GradientStop::get(Color::rgb(0.0,1.0,0.0), 100%)])} /> @@ -64,7 +64,7 @@ fill={Fill::linearGradient( (0%, 0%), (100%, 100%), - [GradientStop::get(Color::rgb(100.0%,0.0%,0.0%), 0%), GradientStop::get(Color::rgb(0.0%,100.0%,100.0%), 100%)])} + [GradientStop::get(Color::rgb(1.0,0.0,0.0), 0%), GradientStop::get(Color::rgb(0.0,1.0,1.0), 100%)])} /> @@ -79,7 +79,7 @@ fill={Fill::linearGradient( (0%, 0%), (100%, 100%), - [GradientStop::get(Color::rgb(100.0%,0.0%,100.0%), 0%), GradientStop::get(Color::rgb(0.0%,100.0%,0.0%), 100%)])} + [GradientStop::get(Color::rgb(1.0,0.0,1.0), 0%), GradientStop::get(Color::rgb(0.0,1.0,0.0), 100%)])} /> @@ -96,7 +96,7 @@ fill={Fill::linearGradient( (0%, 0%), (100%, 100%), - [GradientStop::get(Color::rgb(0.0%,0.0%,100.0%), 0%), GradientStop::get(Color::rgb(100.0%,100.0%,0.0%), 100%)])} + [GradientStop::get(Color::rgb(0.0,0.0,1.0), 0%), GradientStop::get(Color::rgb(1.0,1.0,0.0), 100%)])} /> @@ -108,7 +108,7 @@ style_link: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Bold)}, font_size: 22px, - fill: {Color::rgba(100.0%,100.0%,100.0%,100.0%)} + fill: {Color::rgba(1.0,1.0,1.0,1.0)} align_vertical: TextAlignVertical::Center, align_horizontal: TextAlignHorizontal::Center, underline: true @@ -147,7 +147,7 @@ style: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Bold)}, font_size: 72px, - fill: {Color::rgba(100.0%,100.0%,100.0%,100.0%)} + fill: {Color::rgba(1.0,1.0,1.0,1.0)} align_vertical: TextAlignVertical::Center, align_horizontal: TextAlignHorizontal::Center, align_multiline: TextAlignHorizontal::Center, @@ -158,7 +158,7 @@ style: { font: {Font::system("Helvetica", FontStyle::Italic, FontWeight::Bold)}, font_size: 72px, - fill: {Color::rgba(100.0%,100.0%,1.0%,100.0%)} + fill: {Color::rgba(1.0,1.0,1.0,1.0)} align_vertical: TextAlignVertical::Center, align_horizontal: TextAlignHorizontal::Center, align_multiline: TextAlignHorizontal::Center, @@ -169,7 +169,7 @@ style: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Bold)}, font_size: 54px, - fill: {Color::rgba(100.0%,100.0%,100.0%,100.0%)} + fill: {Color::rgba(1.0,1.0,1.0,1.0)} align_vertical: TextAlignVertical::Center, align_horizontal: TextAlignHorizontal::Center, align_multiline: TextAlignHorizontal::Center, @@ -180,7 +180,7 @@ style_link: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Bold)}, font_size: 36px, - fill: {Color::rgba(0.0%,0.0%,0.0%,100.0%)} + fill: {Color::rgba(0.0,0.0,0.0,1.0)} align_vertical: TextAlignVertical::Top, align_horizontal: TextAlignHorizontal::Center, align_multiline: TextAlignHorizontal::Center, @@ -192,7 +192,7 @@ style_link: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Bold)}, font_size: 36px, - fill: {Color::rgba(0.0%,0.0%,0.0%,100.0%)} + fill: {Color::rgba(0.0,0.0,0.0,1.0)} align_vertical: TextAlignVertical::Center, align_horizontal: TextAlignHorizontal::Center, align_multiline: TextAlignHorizontal::Center, @@ -204,7 +204,7 @@ style: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Normal)}, font_size: 28px, - fill: {Color::rgba(0.0%,0.0%,0.0%,100.0%)} + fill: {Color::rgba(0.0,0.0,0.0,1.0)} align_vertical: TextAlignVertical::Top, align_horizontal: TextAlignHorizontal::Left, align_multiline: TextAlignHorizontal::Left, @@ -215,7 +215,7 @@ style: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Normal)}, font_size: 20px, - fill: {Color::rgba(0.0%,0.0%,0.0%,100.0%)} + fill: {Color::rgba(0.0,0.0,0.0,1.0)} align_vertical: TextAlignVertical::Top, align_horizontal: TextAlignHorizontal::Left, align_multiline: TextAlignHorizontal::Left, diff --git a/pax-example/src/website_mobile.pax b/pax-example/src/website_mobile.pax index 379c76255..25868ca95 100644 --- a/pax-example/src/website_mobile.pax +++ b/pax-example/src/website_mobile.pax @@ -10,7 +10,7 @@ fill={Fill::linearGradient( (0%, 50%), (100%, 50%), - [GradientStop::get(Color::rgba(0.0%,0.0%,0.0%,100.0%), 0%), GradientStop::get(Color::rgba(0.0%,0.0%,0.0%,50.0%), 100%)])} + [GradientStop::get(Color::rgba(0.0,0.0,0.0,1.0), 0%), GradientStop::get(Color::rgba(0.0,0.0,0.0,0.5), 100%)])} corner_radii={ RectangleCornerRadii::radii(50.0,50.0,50.0,50.0) @@ -32,7 +32,7 @@ fill={Fill::linearGradient( (0%, 0%), (100%, 100%), - [GradientStop::get(Color::rgb(100.0%,100.0%,0.0%), 0%), GradientStop::get(Color::rgb(100.0%,0.0%,100.0%), 100%)])} + [GradientStop::get(Color::rgb(1.0,1.0,0.0), 0%), GradientStop::get(Color::rgb(1.0,0.0,1.0), 100%)])} /> @@ -47,7 +47,7 @@ fill={Fill::linearGradient( (0%, 0%), (100%, 100%), - [GradientStop::get(Color::rgb(0.0%,100.0%,100.0%), 0%), GradientStop::get(Color::rgb(0.0%,100.0%,0.0%), 100%)])} + [GradientStop::get(Color::rgb(0.0,1.0,1.0), 0%), GradientStop::get(Color::rgb(0.0,1.0,0.0), 100%)])} /> @@ -62,7 +62,7 @@ fill={Fill::linearGradient( (0%, 0%), (100%, 100%), - [GradientStop::get(Color::rgb(100.0%,0.0%,0.0%), 0%), GradientStop::get(Color::rgb(0.0%,100.0%,100.0%), 100%)])} + [GradientStop::get(Color::rgb(1.0,0.0,0.0), 0%), GradientStop::get(Color::rgb(0.0,1.0,1.0), 100%)])} /> @@ -77,7 +77,7 @@ fill={Fill::linearGradient( (0%, 0%), (100%, 100%), - [GradientStop::get(Color::rgb(100.0%,0.0%,100.0%), 0%), GradientStop::get(Color::rgb(0.0%,100.0%,0.0%), 100%)])} + [GradientStop::get(Color::rgb(1.0,0.0,1.0), 0%), GradientStop::get(Color::rgb(0.0,1.0,0.0), 100%)])} /> @@ -94,7 +94,7 @@ fill={Fill::linearGradient( (0%, 0%), (100%, 100%), - [GradientStop::get(Color::rgb(0.0%,0.0%,100.0%), 0%), GradientStop::get(Color::rgb(100.0%,100.0%,0.0%), 100%)])} + [GradientStop::get(Color::rgb(0.0,0.0,1.0), 0%), GradientStop::get(Color::rgb(1.0,1.0,0.0), 100%)])} /> @@ -108,7 +108,7 @@ style_link: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Bold)}, font_size: 22px, - fill: {Color::rgba(100.0%,100.0%,100.0%,100.0%)} + fill: {Color::rgba(1.0,1.0,1.0,1.0)} align_vertical: TextAlignVertical::Center, align_horizontal: TextAlignHorizontal::Center, underline: true @@ -151,7 +151,7 @@ style: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Bold)}, font_size: 52px, - fill: {Color::rgba(100.0%,100.0%,100.0%,100.0%)} + fill: {Color::rgba(1.0,1.0,1.0,1.0)} align_vertical: TextAlignVertical::Center, align_horizontal: TextAlignHorizontal::Center, align_multiline: TextAlignHorizontal::Center, @@ -162,7 +162,7 @@ style: { font: {Font::system("Helvetica", FontStyle::Italic, FontWeight::Bold)}, font_size: 34px, - fill: {Color::rgba(100.0%,100.0%,100.0%,100.0%)} + fill: {Color::rgba(1.0,1.0,1.0,1.0)} align_vertical: TextAlignVertical::Center, align_horizontal: TextAlignHorizontal::Center, align_multiline: TextAlignHorizontal::Center, @@ -173,7 +173,7 @@ style: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Bold)}, font_size: 54px, - fill: {Color::rgba(100.0%,100.0%,100.0%,100.0%)} + fill: {Color::rgba(1.0,1.0,1.0,1.0)} align_vertical: TextAlignVertical::Center, align_horizontal: TextAlignHorizontal::Center, align_multiline: TextAlignHorizontal::Center, @@ -184,7 +184,7 @@ style_link: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Bold)}, font_size: 36px, - fill: {Color::rgba(0.0%,0.0%,0.0%,100.0%)} + fill: {Color::rgba(0.0,0.0,0.0,1.0)} align_vertical: TextAlignVertical::Top, align_horizontal: TextAlignHorizontal::Center, align_multiline: TextAlignHorizontal::Center, @@ -196,7 +196,7 @@ style_link: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Bold)}, font_size: 40px, - fill: {Color::rgba(0.0%,0.0%,0.0%,100.0%)} + fill: {Color::rgba(0.0,0.0,0.0,1.0)} align_vertical: TextAlignVertical::Center, align_horizontal: TextAlignHorizontal::Center, align_multiline: TextAlignHorizontal::Center, @@ -208,7 +208,7 @@ style: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Normal)}, font_size: 20px, - fill: {Color::rgba(0.0%,0.0%,0.0%,100.0%)} + fill: {Color::rgba(0.0,0.0,0.0,1.0)} align_vertical: TextAlignVertical::Top, align_horizontal: TextAlignHorizontal::Left, align_multiline: TextAlignHorizontal::Left, @@ -219,7 +219,7 @@ style: { font: {Font::system("Helvetica", FontStyle::Normal, FontWeight::Normal)}, font_size: 20px, - fill: {Color::rgba(0.0%,0.0%,0.0%,100.0%)} + fill: {Color::rgba(0.0,0.0,0.0,1.0)} align_vertical: TextAlignVertical::Top, align_horizontal: TextAlignHorizontal::Left, align_multiline: TextAlignHorizontal::Left,