/* character level styles for Lynx * (c) 1996 Rob Partington -- donated to the Lyncei (if they want it :-) * @Id: LYStyle.c 1.13 Wed, 22 Oct 1997 08:29:34 -0600 dickey @ */ #include "HTUtils.h" #include "HTML.h" #include "tcp.h" #include "LYSignal.h" #include "LYGlobalDefs.h" #include "LYStructs.h" #include "LYCurses.h" #include "LYCharUtils.h" #include "AttrList.h" #include "SGML.h" #include "HTMLDTD.h" /* Hash table definitions */ #include "LYHash.h" #include "LYStyle.h" #include "LYexit.h" #include "LYLeaks.h" #ifdef USE_COLOR_STYLE PUBLIC bucket hashStyles[CSHASHSIZE]; /* definitions for the mono attributes we can use */ static int ncursesMono[7] = { A_NORMAL, A_BOLD, A_REVERSE, A_UNDERLINE, A_STANDOUT, A_BLINK, A_DIM }; /* * If these strings don't match the meanings of the above attributes, * you'll confuse the hell out of people, so make them the same. - RP */ static char *Mono_Strings[7] = { "normal", "bold", "reverse", "underline", "standout", "blink", "dim" }; /* definitions for the colour attributes we can use */ static int ncursesColors[8] = { COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; /* * Ditto for these strings - RP */ static char *Color_Strings[16] = { "black", "red", "green", "brown", "blue", "magenta", "cyan", "lightgray", "gray", "brightred", "brightgreen", "yellow", "brightblue", "brightmagenta", "brightcyan", "white" }; /* Remember the hash codes for common elements */ PUBLIC int s_alink=NOSTYLE, s_a=NOSTYLE, s_status=NOSTYLE, s_label=NOSTYLE, s_value=NOSTYLE, s_high=NOSTYLE, s_normal=NOSTYLE, s_alert=NOSTYLE, s_title=NOSTYLE; /* start somewhere safe */ PRIVATE int colorPairs=0; PRIVATE int last_fA=COLOR_WHITE, last_bA=COLOR_BLACK; #define FREE(x) if (x) {free(x); x = NULL;} /* icky parsing of the style options */ PRIVATE void parse_attributes ARGS5(char*,mono,char*,fg,char*,bg,int,style,char*,element) { int i; int mA=0, fA=COLOR_WHITE, bA=COLOR_BLACK, cA=0; int newstyle=hash_code(element); if (TRACE) fprintf(stderr, "CSS(PA):style d=%d / h=%d, e=%s\n", style, newstyle,element); for (i=0; i<7; i++) { if (!strcasecmp(Mono_Strings[i], mono)) { mA = ncursesMono[i]; } } if (TRACE) fprintf(stderr, "CSS(CP):%d\n", colorPairs); /* * `nocolor' means don't even try to do colour for this - RP */ if (!strcasecmp("nocolor", fg)) { fA=-1; bA=-1; cA=-1; } else { for (i=0; i<16; i++) { if (!strcasecmp(Color_Strings[i], fg)) { fA = ncursesColors[i%8]; /* * if the string was in the upper 8, then it's * a bright version, so set the BOLD attribute */ cA = (i>=8 ? A_BOLD : 0); } } /* * Backgrounds are horribly broken under ncurses - RP */ for (i=0; i<16; i++) { if (!strcasecmp(Color_Strings[i], bg)) { bA = ncursesColors[i%8]; cA |=(i>=8 ? A_BOLD : 0); } } } /* * If we have colour, and space to create a new colour attribute, * and we have a valid colour description, then add this style */ if (lynx_has_color && colorPairs < COLOR_PAIRS-1 && fA!=-1) { if (colorPairs <= 0 || fA != last_fA || bA != last_bA) { colorPairs++; init_pair(colorPairs, fA, bA); last_fA = fA; last_bA = bA; } if (style < DSTYLE_ELEMENTS) setStyle(style, COLOR_PAIR(colorPairs)|cA, cA, mA); setHashStyle(newstyle, COLOR_PAIR(colorPairs)|cA, cA, mA, element); } else { /* only mono is set */ if (style < DSTYLE_ELEMENTS) setStyle(style, -1, -1, mA); setHashStyle(newstyle, -1, -1, mA, element); } } /* parse a style option of the format * STYLE::FG:BG */ PRIVATE void parse_style ARGS1(char*,buffer) { char *tmp = strchr(buffer, ':'); char *element, *mono, *fg, *bg; if(!tmp) { fprintf (stderr, "\ Syntax Error parsing style in lss file:\n\ [%s]\n\ The line must be of the form:\n\ OBJECT:MONO:COLOR (ie em:bold:brightblue:white)\n\ where OBJECT is one of EM,STRONG,B,I,U,BLINK etc.\n\n", buffer); if (!dump_output_immediately) { #ifndef NOSIGHUP (void) signal(SIGHUP, SIG_DFL); #endif /* NOSIGHUP */ (void) signal(SIGTERM, SIG_DFL); #ifndef VMS (void) signal(SIGINT, SIG_DFL); #endif /* !VMS */ #ifdef SIGTSTP if (no_suspend) (void) signal(SIGTSTP,SIG_DFL); #endif /* SIGTSTP */ exit(-1); } exit(1); } { char *i; for (i=buffer; *i; *i++=tolower(*i)); } *tmp='\0'; element=buffer; mono=tmp+1; tmp=strchr(mono, ':'); if (!tmp) { fg="nocolor"; bg="nocolor"; } else { *tmp='\0'; fg=tmp+1; tmp=strchr(fg, ':'); if (!tmp) bg="black"; else {*tmp='\0'; bg=tmp+1;} } if (TRACE) { int bucket = hash_code(element); fprintf(stderr, "CSSPARSE:%s => %d %s\n", element, bucket, (hashStyles[bucket].name ? "used" : "")); } strtolower(element); /* * We use some pseudo-elements, so catch these first */ if (!strncasecmp(element, "alink", 5)) /* active link */ { parse_attributes(mono,fg,bg,DSTYLE_ALINK,"alink"); } else if (!strcasecmp(element, "a")) /* normal link */ { parse_attributes(mono,fg,bg, DSTYLE_LINK,"a"); parse_attributes(mono,fg,bg, HTML_A,"a"); } else if (!strncasecmp(element, "status", 4)) /* status bar */ { parse_attributes(mono,fg,bg, DSTYLE_STATUS,"status"); } else if (!strncasecmp(element, "label", 6)) /* [INLINE]'s */ { parse_attributes(mono,fg,bg,DSTYLE_OPTION,"label"); } else if (!strncasecmp(element, "value", 5)) /* [INLINE]'s */ { parse_attributes(mono,fg,bg,DSTYLE_VALUE,"value"); } else if (!strncasecmp(element, "high", 4)) /* [INLINE]'s */ { parse_attributes(mono,fg,bg,DSTYLE_HIGH,"high"); } else if (!strcmp(element, "normal")) /* added - kw */ { parse_attributes(mono,fg,bg,DSTYLE_NORMAL,"html"); } /* this may vanish */ else if (!strncasecmp(element, "candy", 5)) /* [INLINE]'s */ { parse_attributes(mono,fg,bg,DSTYLE_CANDY,"candy"); } /* Ok, it must be a HTML element, so look through the list until we * find it */ else { #if !defined(USE_HASH) int i; for (i=0; i for HTML_%s\n",mono,fg,bg,HTML_dtd.tags[i].name); parse_attributes(mono,fg,bg,i+STARTAT,element); break; } } #else int element_number = -1; HTTag * t = SGMLFindTag(&HTML_dtd, element); if (t && t->name) { element_number = t - HTML_dtd.tags; } if (element_number >= HTML_A && element_number < HTML_ELEMENTS) parse_attributes(mono,fg,bg, element_number+STARTAT,element); else parse_attributes(mono,fg,bg, DSTYLE_ELEMENTS,element); #endif } } PRIVATE void free_colorstylestuff NOARGS { style_initialiseHashTable(); style_deleteStyleList(); } /* * initialise the default style sheet * This should be able to be read from a file in CSS format :-) */ PRIVATE void initialise_default_stylesheet NOARGS { } /* Set all the buckets in the hash table to be empty */ PUBLIC void style_initialiseHashTable NOARGS { int i; static int firsttime = 1; for (i=0; i 0) { if (buffer[len-1] == '\n' || buffer[len-1] == '\r') buffer[len-1]='\0'; /* hack */ else buffer[1023]='\0'; /* hack */ } LYTrimTail(buffer); LYTrimHead(buffer); if (buffer[0] != '#' && (len = strlen(buffer)) > 0) HStyle_addStyle(buffer); } /* the default styles are added after the user styles in order ** that they come before them RP */ /* style_defaultStyleSheet(); */ fclose (fh); if (LYCursesON) parse_userstyles(); return 0; } #endif /* USE_COLOR_STYLE */