Skip to content

Commit

Permalink
[Lexer] Add support for @media.
Browse files Browse the repository at this point in the history
Issue: #893
  • Loading branch information
DaveDavenport committed Aug 19, 2019
1 parent ad74da4 commit 9049eaf
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 7 deletions.
22 changes: 22 additions & 0 deletions include/theme.h
Expand Up @@ -32,6 +32,20 @@
#include <widgets/widget.h>
#include "rofi-types.h"


typedef enum {
THEME_MEDIA_TYPE_MIN_WIDTH,
THEME_MEDIA_TYPE_MAX_WIDTH,
THEME_MEDIA_TYPE_MIN_HEIGHT,
THEME_MEDIA_TYPE_MAX_HEIGHT,
} ThemeMediaType;


typedef struct ThemeMedia {
ThemeMediaType type;
RofiDistance value;
} ThemeMedia;

/**
* ThemeWidget.
*/
Expand All @@ -43,6 +57,8 @@ typedef struct ThemeWidget
unsigned int num_widgets;
struct ThemeWidget **widgets;

ThemeMedia *media;

GHashTable *properties;

struct ThemeWidget *parent;
Expand Down Expand Up @@ -323,4 +339,10 @@ char *helper_get_theme_path ( const char *file );
* @returns full path to file.
*/
char * rofi_theme_parse_prepare_file ( const char *file, const char *parent_file );

/**
* Process conditionals.
*/
void rofi_theme_parse_process_conditionals ( void );
void rofi_theme_parse_merge_widgets ( ThemeWidget *parent, ThemeWidget *child );
#endif
88 changes: 82 additions & 6 deletions lexer/theme-lexer.l
Expand Up @@ -190,6 +190,13 @@ SOUTH (?i:south)
EAST (?i:east)
WEST (?i:west)
WIDTH (?i:width)
HEIGHT (?i:height)
MIN (?:min)
MAX (?:max)
/* Line Style */
NONE (?i:none)
BOLD (?i:bold)
Expand Down Expand Up @@ -239,6 +246,8 @@ C_COMMENT_OPEN "/*"
INCLUDE "@import"
THEME "@theme"

MEDIA "@media"

CONFIGURATION (?i:configuration)

%x INCLUDE
Expand All @@ -250,6 +259,8 @@ CONFIGURATION (?i:configuration)
%x NAMESTR
%x SECTION
%x DEFAULTS
%x MEDIA
%x MEDIA_CONTENT
%%

%{
Expand Down Expand Up @@ -424,23 +435,23 @@ if ( queue == NULL ){

/* After Namestr/Classstr we want to go to state str, then to { */
<INITIAL,SECTION>{WHITESPACE}+ ; // ignore all whitespace
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST,PROPERTIES_VAR>{WHITESPACE}+ ; // ignore all whitespace
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST,PROPERTIES_VAR,MEDIA_CONTENT>{WHITESPACE}+ ; // ignore all whitespace

<SECTION>":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return T_PSEP; }
<PROPERTIES>";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return T_PCLOSE;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;}

<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>@{WORD} {
yylval->sval = g_strdup(yytext+1);
return T_LINK;
}

<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{EM} { return T_UNIT_EM; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CH} { return T_UNIT_CH; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{PX} { return T_UNIT_PX; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{EM} { return T_UNIT_EM; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{CH} { return T_UNIT_CH; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PX} { return T_UNIT_PX; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{PERCENT} { return T_PERCENT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LS_SOLID} { return T_SOLID; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LS_DASH} { return T_DASH; }
Expand Down Expand Up @@ -619,6 +630,63 @@ if ( queue == NULL ){
yylloc->last_line ++;
};


<INITIAL>{MEDIA} {
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
BEGIN(MEDIA);
return T_MEDIA;
}

<MEDIA>{S_T_PARENT_LEFT} {
printf("push parent: %d %d\n", YY_START, MEDIA_CONTENT);
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
BEGIN(MEDIA_CONTENT);
return T_PARENT_LEFT;
}
<MEDIA_CONTENT>{WIDTH} {
return T_MEDIA_WIDTH;
}
<MEDIA_CONTENT>{HEIGHT} {
return T_MEDIA_HEIGHT;
}
<MEDIA_CONTENT>{MIN} {
return T_MEDIA_MIN;
}
<MEDIA_CONTENT>{MAX} {
return T_MEDIA_MAX;
}
<MEDIA_CONTENT>"-" {
return T_MEDIA_SEP;
}
<MEDIA_CONTENT>":" {
return T_PSEP;
}
<MEDIA_CONTENT>{S_T_PARENT_RIGHT} {
int id = GPOINTER_TO_INT(g_queue_pop_head ( queue ));
BEGIN(id);
printf("closing parent: %d %d\n",id, MEDIA);
return T_PARENT_RIGHT;
}
<MEDIA>"\{" {
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
BEGIN(INITIAL);
return T_BOPEN;
}

<INITIAL>"\}" {
g_queue_pop_head ( queue );
BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue )));
return T_BCLOSE;
}
<MEDIA>{WHITESPACE}+ ; // ignore all whitespace


<MEDIA,MEDIA_CONTENT>. {
yytext[yyleng-1] = '\0';
fprintf(stderr,"found: |%s|\n", yytext);
return T_ERROR;
}

/**
* If we just encounter a word, we assume it is a Widget name.
* This makes include,theme, configuration a reserved keyword.
Expand All @@ -630,9 +698,13 @@ if ( queue == NULL ){
return T_NAME_ELEMENT;
}
<INITIAL>. {
yytext[yyleng-1] = '\0';
fprintf(stderr,"initial found: |%s|\n", yytext);
return T_ERROR;
}
<SECTION>. {
yytext[yyleng-1] = '\0';
fprintf(stderr,"section found: |%s|\n", yytext);
return T_ERROR_SECTION;
}
<PROPERTIES_LIST,PROPERTIES_VAR>{WORD} {
Expand All @@ -646,9 +718,13 @@ if ( queue == NULL ){
}

<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST>. {
yytext[yyleng-1] = '\0';
fprintf(stderr,"prop found: |%s|\n", yytext);
return T_ERROR_PROPERTY;
}
<NAMESTR>. {
yytext[yyleng-1] = '\0';
fprintf(stderr,"namestr found: |%s|\n", yytext);
return T_ERROR_NAMESTRING;
}
%%
Expand Down
89 changes: 88 additions & 1 deletion lexer/theme-parser.y
Expand Up @@ -172,6 +172,8 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b)
%token T_POS_NORTH "North"
%token T_POS_SOUTH "South"

%token T_MEDIA "@media"

%token T_NONE "None"
%token T_BOLD "Bold"
%token T_ITALIC "Italic"
Expand Down Expand Up @@ -223,8 +225,17 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b)

%token T_INHERIT "Inherit"

%token T_MEDIA_WIDTH "Width"
%token T_MEDIA_HEIGHT "Height"

%token T_MEDIA_MIN "Min"
%token T_MEDIA_MAX "Max"
%token T_MEDIA_SEP "-"

%type <sval> t_entry
%type <sval> t_entry_my
%type <theme> t_entry_list
%type <theme> t_media_entry_list
%type <list> t_entry_name_path
%type <list> t_entry_name_path_selectors
%type <property> t_property
Expand Down Expand Up @@ -280,6 +291,38 @@ t_entry_list:
}
;

t_media_entry_list:
t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optional T_BCLOSE {
ThemeWidget *widget = $$ = g_slice_new0 ( ThemeWidget );
for ( GList *liter = g_list_first ( $2); liter; liter = g_list_next ( liter ) ) {
for ( GList *iter = g_list_first ( (GList*)liter->data ); widget && iter ; iter = g_list_next ( iter ) ) {
widget = rofi_theme_find_or_create_name ( widget, iter->data );
}
g_list_free_full ( (GList*)liter->data, g_free );
widget->set = TRUE;
rofi_theme_widget_add_properties ( widget, $4);
}
if ( $4 ) {
g_hash_table_destroy ( $4 );
}
g_list_free ( $2 );
}
| t_media_entry_list t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optional T_BCLOSE {
ThemeWidget *widget = $$ = $1 ;
for ( GList *liter = g_list_first ( $3); liter; liter = g_list_next ( liter ) ) {
for ( GList *iter = g_list_first ( (GList*)liter->data ); widget && iter ; iter = g_list_next ( iter ) ) {
widget = rofi_theme_find_or_create_name ( widget, iter->data );
}
g_list_free_full ( (GList*)liter->data, g_free );
widget->set = TRUE;
rofi_theme_widget_add_properties ( widget, $5);
}
if ( $5 ) {
g_hash_table_destroy ( $5 );
}
g_list_free ( $3 );
};

/**
* Small dummy object to make the prefix optional.
*/
Expand All @@ -293,7 +336,7 @@ t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optio
{
for ( GList *liter = g_list_first ( $2); liter; liter = g_list_next ( liter ) ) {
ThemeWidget *widget = rofi_theme;
for ( GList *iter = g_list_first ( (GList*)liter->data ); iter ; iter = g_list_next ( iter ) ) {
for ( GList *iter = g_list_first ( (GList*)liter->data ); widget && iter ; iter = g_list_next ( iter ) ) {
widget = rofi_theme_find_or_create_name ( widget, iter->data );
}
g_list_free_full ( (GList*)liter->data, g_free );
Expand All @@ -312,6 +355,50 @@ t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optio
g_hash_table_destroy ( $3 );
}
}
| T_MEDIA T_PARENT_LEFT T_MEDIA_MIN T_MEDIA_SEP T_MEDIA_WIDTH T_PSEP t_property_distance T_PARENT_RIGHT T_BOPEN t_media_entry_list T_BCLOSE {
ThemeWidget *widget = rofi_theme_find_or_create_name ( rofi_theme, "min-width" );
widget->set = TRUE;
widget->media = g_malloc0(sizeof(ThemeMedia));
widget->media->type = THEME_MEDIA_TYPE_MIN_WIDTH;
widget->media->value = $7;
for ( unsigned int i = 0; i < $10->num_widgets;i++) {
ThemeWidget *d = $10->widgets[i];
rofi_theme_parse_merge_widgets(widget, d);
}
}
| T_MEDIA T_PARENT_LEFT T_MEDIA_MIN T_MEDIA_SEP T_MEDIA_HEIGHT T_PSEP t_property_distance T_PARENT_RIGHT T_BOPEN t_media_entry_list T_BCLOSE {
ThemeWidget *widget = rofi_theme_find_or_create_name ( rofi_theme, "min-height" );
widget->set = TRUE;
widget->media = g_malloc0(sizeof(ThemeMedia));
widget->media->type = THEME_MEDIA_TYPE_MIN_HEIGHT;
widget->media->value = $7;
for ( unsigned int i = 0; i < $10->num_widgets;i++) {
ThemeWidget *d = $10->widgets[i];
rofi_theme_parse_merge_widgets(widget, d);
}
}
| T_MEDIA T_PARENT_LEFT T_MEDIA_MAX T_MEDIA_SEP T_MEDIA_WIDTH T_PSEP t_property_distance T_PARENT_RIGHT T_BOPEN t_media_entry_list T_BCLOSE {
ThemeWidget *widget = rofi_theme_find_or_create_name ( rofi_theme, "max-width" );
widget->set = TRUE;
widget->media = g_malloc0(sizeof(ThemeMedia));
widget->media->type = THEME_MEDIA_TYPE_MAX_WIDTH;
widget->media->value = $7;
for ( unsigned int i = 0; i < $10->num_widgets;i++) {
ThemeWidget *d = $10->widgets[i];
rofi_theme_parse_merge_widgets(widget, d);
}
}
| T_MEDIA T_PARENT_LEFT T_MEDIA_MAX T_MEDIA_SEP T_MEDIA_HEIGHT T_PSEP t_property_distance T_PARENT_RIGHT T_BOPEN t_media_entry_list T_BCLOSE {
ThemeWidget *widget = rofi_theme_find_or_create_name ( rofi_theme, "max-height");
widget->set = TRUE;
widget->media = g_malloc0(sizeof(ThemeMedia));
widget->media->type = THEME_MEDIA_TYPE_MAX_HEIGHT;
widget->media->value = $7;
for ( unsigned int i = 0; i < $10->num_widgets;i++) {
ThemeWidget *d = $10->widgets[i];
rofi_theme_parse_merge_widgets(widget, d);
}
}
;

t_config_property_list_optional
Expand Down
3 changes: 3 additions & 0 deletions source/rofi.c
Expand Up @@ -999,6 +999,9 @@ int main ( int argc, char *argv[] )
}
TICK_N ( "Setup late Display" );

rofi_theme_parse_process_conditionals ();
TICK_N ( "Theme setup" );

// Setup signal handling sources.
// SIGINT
g_unix_signal_add ( SIGINT, main_loop_signal_handler_int, NULL );
Expand Down

0 comments on commit 9049eaf

Please sign in to comment.