diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index e80d57a0..2365410d 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -83,39 +83,6 @@ GQueue *queue = NULL; ParseObject *current = NULL; static char * rofi_theme_parse_prepare_file ( const char *file, const char *parent_file ); -#define IN_RANGE(index,low,high) ( ( (index) > (low) )? ( ( (index) < (high) )? (index):(high) ) : ( low ) ) - -static double hue2rgb(double p, double q, double t){ - t += (t<0)?1:0; - t -= (t>1)?1:0; - if( t < (1/6.0) ) { - return p + (q - p) * 6 * t; - } - if( t < (1/2.0) ) { - return q; - } - if( t < (2/3.0) ) { - return p + (q - p) * (2/3.0 - t) * 6; - } - return p; -} -static ThemeColor hsl_to_rgb ( double h, double s, double l ) -{ - ThemeColor colour; - - if(s < 0.001 && s > -0.001){ - colour.red = colour.green = colour.blue = l; // achromatic - }else{ - - double q = l < 0.5 ? l * (1 + s) : l + s - l * s; - double p = 2 * l - q; - colour.red = hue2rgb(p, q, h + 1/3.0); - colour.green = hue2rgb(p, q, h); - colour.blue = hue2rgb(p, q, h - 1/3.0); - } - - return colour; -} %} %{ @@ -191,16 +158,30 @@ PERCENT (\%) ASTERIX \* + /* Position */ CENTER "center" NORTH "north" SOUTH "south" EAST "east" WEST "west" -NONE "none" -BOLD "bold" -UNDERLINE "underline" -ITALIC "italic" + /* Line Style */ +NONE "none" +BOLD "bold" +UNDERLINE "underline" +ITALIC "italic" + + /* Color schema */ +ARGB "argb" +RGBA "rgba" +RGB "rgb" +HWB "hwb" +CMYK "cmyk" +HSL "hsl" + +PARENT_LEFT \( +PARENT_RIGHT \) +COMMA , LS_DASH "dash" LS_SOLID "solid" @@ -375,71 +356,27 @@ if ( queue == NULL ){ {WHITESPACE}+ ; // ignore all whitespace {WHITESPACE}+ ; // ignore all whitespace -
":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return PSEP; } -";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return PCLOSE;} +
":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return PSEP; } +";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return PCLOSE;} (true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} -{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} {PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} +{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} \"{STRING}\" { yytext[yyleng-1] = '\0'; yylval->sval = g_strdup(&yytext[1]); return T_STRING;} @{WORD} { yylval->sval = g_strdup(yytext); return T_LINK; } -{REAL}{EM} { - yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL); - yylval->distance.type = PW_EM; - yylval->distance.style = SOLID; - return T_PIXEL; -} -{PNNUMBER}{PX} { - yylval->distance.distance = (double)g_ascii_strtoll(yytext, NULL, 10); - yylval->distance.type = PW_PX; - yylval->distance.style = SOLID; - return T_PIXEL; -} -{PNNUMBER}{PX}{WHITESPACE}{LS_DASH} { - yylval->distance.distance = (double)g_ascii_strtoll(yytext, NULL, 10); - yylval->distance.type = PW_PX; - yylval->distance.style = DASH; - return T_PIXEL; -} -{REAL}{EM}{WHITESPACE}{LS_DASH} { - yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL); - yylval->distance.type = PW_EM; - yylval->distance.style = DASH; - return T_PIXEL; -} -{PNNUMBER}{PX}{WHITESPACE}{LS_SOLID} { - yylval->distance.distance = (double)g_ascii_strtoll(yytext, NULL, 10); - yylval->distance.type = PW_PX; - yylval->distance.style = SOLID; - return T_PIXEL; -} -{REAL}{EM}{WHITESPACE}{LS_SOLID} { - yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL); - yylval->distance.type = PW_EM; - yylval->distance.style = SOLID; - return T_PIXEL; -} -{REAL}{PERCENT} { - yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL); - yylval->distance.type = PW_PERCENT; - yylval->distance.style = SOLID; - return T_PIXEL; -} -{REAL}{PERCENT}{WHITESPACE}{LS_SOLID} { - yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL); - yylval->distance.type = PW_PERCENT; - yylval->distance.style = SOLID; - return T_PIXEL; -} -{REAL}{PERCENT}{WHITESPACE}{LS_DASH} { - yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL); - yylval->distance.type = PW_PERCENT; - yylval->distance.style = DASH; - return T_PIXEL; -} +{EM} { return T_UNIT_EM; } +{PX} { return T_UNIT_PX; } +{PERCENT} { return PERCENT; } +{LS_SOLID} { return T_SOLID; } +{LS_DASH} { return T_DASH; } + + /** + * Color parsing. It is easier to do this at lexer level. + * Other schemes are done at yacc level. + */ #{HEX}{8} { union { unsigned int val; struct { unsigned char b,g,r,a;};} val; val.val = (unsigned int)strtoull ( &yytext[1], NULL, 16); @@ -467,68 +404,6 @@ if ( queue == NULL ){ yylval->colorval.blue = val.b/15.0; return T_COLOR; } -rgba\({WSO}{NUMBER}{1,3},{WSO}{NUMBER}{1,3},{WSO}{NUMBER}{1,3},{WSO}[01](\.{NUMBER}+)?\) { - char *endptr = &yytext[5]; - yylval->colorval.red = g_ascii_strtoull ( endptr, &endptr, 10)/255.0; - yylval->colorval.green= g_ascii_strtoull ( endptr+1, &endptr, 10)/255.0; - yylval->colorval.blue= g_ascii_strtoull ( endptr+1, &endptr, 10)/255.0; - yylval->colorval.alpha= g_ascii_strtod ( endptr+1, NULL); - return T_COLOR; -} -rgb\({WSO}{NUMBER}{1,3},{WSO}{NUMBER}{1,3},{WSO}{NUMBER}{1,3}\) { - char *endptr = &yytext[4]; - yylval->colorval.red = g_ascii_strtoull ( endptr, &endptr, 10)/255.0; - yylval->colorval.green = g_ascii_strtoull ( endptr+1, &endptr, 10)/255.0; - yylval->colorval.blue = g_ascii_strtoull ( endptr+1, &endptr, 10)/255.0; - yylval->colorval.alpha = 1.0; - return T_COLOR; -} -hsl\({WSO}{NUMBER}{1,3},{WSO}[1]?{NUMBER}{1,2}{PERCENT},{WSO}[1]?{NUMBER}{1,2}{PERCENT}\) { - char *endptr = &yytext[4]; - gint64 hi= g_ascii_strtoll ( endptr, &endptr, 10); - gint64 si= g_ascii_strtoll ( endptr+1, &endptr, 10); - gint64 li= g_ascii_strtoll ( endptr+2, &endptr, 10); - gdouble h = IN_RANGE(hi, 0, 359); - gdouble s = IN_RANGE(si, 0, 100); - gdouble l = IN_RANGE(li, 0, 100); - yylval->colorval = hsl_to_rgb ( h/360.0, s/100.0, l/100.0 ); - yylval->colorval.alpha = 1.0; - return T_COLOR; -} -cmyk\({WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT},{WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT},{WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT},{WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT}\) { - char *endptr = &yytext[5]; - gint64 ci = g_ascii_strtoll ( endptr, &endptr, 10); - gint64 mi = g_ascii_strtoll ( endptr+2, &endptr, 10); - gint64 my = g_ascii_strtoll ( endptr+2, &endptr, 10); - gint64 mk = g_ascii_strtoll ( endptr+2, &endptr, 10); - double c= IN_RANGE(ci, 0, 100)/100.0; - double m= IN_RANGE(mi, 0, 100)/100.0; - double y= IN_RANGE(my, 0, 100)/100.0; - double k= IN_RANGE(mk, 0, 100)/100.0; - yylval->colorval.red = (1.0-c)*(1.0-k); - yylval->colorval.green = (1.0-m)*(1.0-k); - yylval->colorval.blue = (1.0-y)*(1.0-k); - yylval->colorval.alpha = 1.0; - return T_COLOR; -} -hwb\({WHITESPACE}{NUMBER}{1,3},{WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT},{WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT}\) { - char *endptr = &yytext[4]; - gint64 hi = g_ascii_strtoll ( endptr, &endptr, 10); - gint64 hw = g_ascii_strtoll ( endptr+1, &endptr, 10); - gint64 hb = g_ascii_strtoll ( endptr+2, &endptr, 10); - double h= IN_RANGE(hi,0,360)/360.0; - double w= IN_RANGE(hw,0,100)/100.0; - double b= IN_RANGE(hb,0,100)/100.0; - yylval->colorval = hsl_to_rgb ( h, 1.0, 0.5); - yylval->colorval.red *= ( 1. - w - b ); - yylval->colorval.red += w; - yylval->colorval.green *= ( 1. - w - b ); - yylval->colorval.green += w; - yylval->colorval.blue *= ( 1. - w - b ); - yylval->colorval.blue += w; - yylval->colorval.alpha = 1.0; - return T_COLOR; -} argb:{HEX}{1,8} { union { unsigned int val; struct { unsigned char b,g,r,a;};} val; val.val = (unsigned int)strtoull ( &yytext[5], NULL, 16); @@ -538,16 +413,30 @@ if ( queue == NULL ){ yylval->colorval.blue = val.b/255.0; return T_COLOR; } + /* Color schemes */ +{ARGB} { return T_COL_ARGB; } +{RGBA} { return T_COL_RGBA; } +{RGB} { return T_COL_RGB; } +{HSL} { return T_COL_HSL; } +{HWB} { return T_COL_HWB; } +{CMYK} { return T_COL_CMYK; } + /* Fluff */ +{PARENT_LEFT} { return PARENT_LEFT; } +{PARENT_RIGHT} { return PARENT_RIGHT;} +{COMMA} { return COMMA; } + /* Position */ +{CENTER} { return T_POS_CENTER; } +{EAST} { return T_POS_EAST; } +{WEST} { return T_POS_WEST; } +{SOUTH} { return T_POS_SOUTH; } +{NORTH} { return T_POS_NORTH; } + /* Highlight style */ +{NONE} { return T_NONE; } +{BOLD} { return T_BOLD; } +{ITALIC} { return T_ITALIC; } +{UNDERLINE} { return T_UNDERLINE; } + -{CENTER} { return T_POS_CENTER; } -{EAST} { return T_POS_EAST; } -{WEST} { return T_POS_WEST; } -{SOUTH} { return T_POS_SOUTH; } -{NORTH} { return T_POS_NORTH; } -{NONE} { return T_NONE; } -{BOLD} { return T_BOLD; } -{ITALIC} { return T_ITALIC; } -{UNDERLINE} { return T_UNDERLINE; } <> { ParseObject *po = g_queue_pop_head ( file_queue ); if ( po ) { diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index d82dc4a5..63999258 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -74,6 +74,40 @@ typedef struct YYLTYPE { ThemeWidget *rofi_theme = NULL; void yyerror(YYLTYPE *yylloc, const char *what, const char* s); int yylex (YYSTYPE *, YYLTYPE *); + +#define IN_RANGE(index,low,high) ( ( (index) > (low) )? ( ( (index) < (high) )? (index):(high) ) : ( low ) ) + +static double hue2rgb(double p, double q, double t){ + t += (t<0)?1:0; + t -= (t>1)?1:0; + if( t < (1/6.0) ) { + return p + (q - p) * 6 * t; + } + if( t < (1/2.0) ) { + return q; + } + if( t < (2/3.0) ) { + return p + (q - p) * (2/3.0 - t) * 6; + } + return p; +} +static ThemeColor hsl_to_rgb ( double h, double s, double l ) +{ + ThemeColor colour; + + if(s < 0.001 && s > -0.001){ + colour.red = colour.green = colour.blue = l; // achromatic + }else{ + + double q = l < 0.5 ? l * (1 + s) : l + s - l * s; + double p = 2 * l - q; + colour.red = hue2rgb(p, q, h + 1/3.0); + colour.green = hue2rgb(p, q, h); + colour.blue = hue2rgb(p, q, h - 1/3.0); + } + + return colour; +} %} %union { @@ -104,7 +138,6 @@ int yylex (YYSTYPE *, YYLTYPE *); %token NAME_ELEMENT "Element name" %token T_BOOLEAN %token T_COLOR -%token T_PIXEL %token T_LINK %token FIRST_NAME %token T_POS_CENTER "Center" @@ -117,7 +150,24 @@ int yylex (YYSTYPE *, YYLTYPE *); %token T_BOLD "Bold" %token T_ITALIC "Italic" %token T_UNDERLINE "Underline" +%token T_DASH "Dash" +%token T_SOLID "Solid" +%token T_UNIT_PX "pixels" +%token T_UNIT_EM "em" +%token T_UNIT_PERCENT "%" + +%token T_COL_ARGB +%token T_COL_RGBA +%token T_COL_RGB +%token T_COL_HSL +%token T_COL_HWB +%token T_COL_CMYK + +%token PARENT_LEFT "Parent left '('" +%token PARENT_RIGHT "Parent right ')'" +%token COMMA "comma separator" +%token PERCENT "Percent sign" %token BOPEN "bracket open ('{')" %token BCLOSE "bracket close ('}')" @@ -131,6 +181,8 @@ int yylex (YYSTYPE *, YYLTYPE *); %type highlight_styles %type highlight_style +%type t_line_style +%type t_unit %type t_position %type t_position_ew %type t_position_sn @@ -141,6 +193,8 @@ int yylex (YYSTYPE *, YYLTYPE *); %type property %type property_list %type optional_properties +%type t_distance +%type t_color %start entries %% @@ -216,11 +270,6 @@ property $$->name = $1; $$->value.f = $3; } -| pvalue PSEP T_COLOR PCLOSE { - $$ = rofi_theme_property_create ( P_COLOR ); - $$->name = $1; - $$->value.color = $3; - } | pvalue PSEP T_STRING PCLOSE { $$ = rofi_theme_property_create ( P_STRING ); $$->name = $1; @@ -236,22 +285,22 @@ property $$->name = $1; $$->value.b = $3; } -| pvalue PSEP T_PIXEL PCLOSE { +| pvalue PSEP t_distance PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $3, $3, $3 }; } -| pvalue PSEP T_PIXEL T_PIXEL PCLOSE { +| pvalue PSEP t_distance t_distance PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $4, $3, $4 }; } -| pvalue PSEP T_PIXEL T_PIXEL T_PIXEL PCLOSE { +| pvalue PSEP t_distance t_distance t_distance PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $4, $5, $4 }; } -| pvalue PSEP T_PIXEL T_PIXEL T_PIXEL T_PIXEL PCLOSE { +| pvalue PSEP t_distance t_distance t_distance t_distance PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $4, $5, $6 }; @@ -261,7 +310,7 @@ property $$->name = $1; $$->value.i = $3; } -| pvalue PSEP highlight_styles T_COLOR PCLOSE { +| pvalue PSEP highlight_styles t_color PCLOSE { $$ = rofi_theme_property_create ( P_HIGHLIGHT ); $$->name = $1; $$->value.highlight.style = $3|HL_COLOR; @@ -272,6 +321,11 @@ property $$->name = $1; $$->value.highlight.style = $3; } +| pvalue PSEP t_color PCLOSE { + $$ = rofi_theme_property_create ( P_COLOR ); + $$->name = $1; + $$->value.color = $3; +} ; /** @@ -301,7 +355,7 @@ t_position_sn */ highlight_styles : highlight_style { $$ = $1;} -| highlight_styles highlight_style { $$ = $1|$2;} +| highlight_styles highlight_style { $$ = $1|$2;} ; /** Single style. */ highlight_style @@ -310,6 +364,87 @@ highlight_style | T_UNDERLINE { $$ = HL_UNDERLINE; } | T_ITALIC { $$ = HL_ITALIC; } ; + + +t_distance +: T_INT t_unit t_line_style { + $$.distance = (double)$1; + $$.type = $2; + $$.style = $3; +} +| T_DOUBLE t_unit t_line_style { + $$.distance = (double)$1; + $$.type = $2; + $$.style = $3; +}; + +t_unit +: T_UNIT_PX { $$ = PW_PX; } +| T_UNIT_EM { $$ = PW_EM; } +| PERCENT { $$ = PW_PERCENT; } +; +/****** + * Line style + * If not set, solid. + */ +t_line_style +: %empty { $$ = SOLID; } +| T_SOLID { $$ = SOLID; } +| T_DASH { $$ = DASH; } +; + +/** + * Color formats + */ +t_color +: T_COL_RGBA PARENT_LEFT T_INT COMMA T_INT COMMA T_INT COMMA T_DOUBLE PARENT_RIGHT { + $$.alpha = $9; + $$.red = $3/255.0; + $$.green = $5/255.0; + $$.blue = $7/255.0; +} +| T_COL_RGB PARENT_LEFT T_INT COMMA T_INT COMMA T_INT PARENT_RIGHT { + $$.alpha = 1.0; + $$.red = $3/255.0; + $$.green = $5/255.0; + $$.blue = $7/255.0; +} +| T_COL_HWB PARENT_LEFT T_INT COMMA T_DOUBLE PERCENT COMMA T_DOUBLE PERCENT PARENT_RIGHT { + $$.alpha = 1.0; + double h = IN_RANGE($3,0,360)/360.0; + double w = IN_RANGE($5,0,100)/100.0; + double b = IN_RANGE($8,0,100)/100.0; + $$ = hsl_to_rgb ( h, 1.0, 0.5); + $$.red *= ( 1. - w - b ); + $$.red += w; + $$.green *= ( 1. - w - b ); + $$.green += w; + $$.blue *= ( 1. - w - b ); + $$.blue += w; +} +| T_COL_CMYK PARENT_LEFT T_DOUBLE PERCENT COMMA T_DOUBLE PERCENT COMMA T_DOUBLE PERCENT COMMA T_DOUBLE PERCENT PARENT_RIGHT { + $$.alpha = 1.0; + double c= IN_RANGE($3, 0, 100)/100.0; + double m= IN_RANGE($6, 0, 100)/100.0; + double y= IN_RANGE($9, 0, 100)/100.0; + double k= IN_RANGE($12, 0, 100)/100.0; + $$.red = (1.0-c)*(1.0-k); + $$.green = (1.0-m)*(1.0-k); + $$.blue = (1.0-y)*(1.0-k); +} +| T_COL_HSL PARENT_LEFT T_INT COMMA T_DOUBLE PERCENT COMMA T_DOUBLE PERCENT PARENT_RIGHT { + gdouble h = IN_RANGE($3, 0, 359); + gdouble s = IN_RANGE($5, 0, 100); + gdouble l = IN_RANGE($8, 0, 100); + $$ = hsl_to_rgb ( h/360.0, s/100.0, l/100.0 ); + $$.alpha = 1.0; +} +| T_COLOR { + $$ = $1; +} +; + + pvalue: N_STRING { $$ = $1; } name_path: