about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GridText.c242
-rw-r--r--src/HTAlert.c7
-rw-r--r--src/HTFWriter.c30
-rw-r--r--src/LYCurses.c195
-rw-r--r--src/LYCurses.h24
-rw-r--r--src/LYGlobalDefs.h1
-rw-r--r--src/LYMain.c86
-rw-r--r--src/LYMainLoop.c73
-rw-r--r--src/LYMainLoop.h1
-rw-r--r--src/LYMap.c9
-rw-r--r--src/LYOptions.c68
-rw-r--r--src/LYPrettySrc.c222
-rw-r--r--src/LYReadCFG.c7
-rw-r--r--src/LYStrings.c36
-rw-r--r--src/LYStyle.c118
-rw-r--r--src/LYUtils.c15
-rw-r--r--src/LYrcFile.h1
-rw-r--r--src/chrtrans/makeuctb.c1
-rw-r--r--src/makefile.in2
19 files changed, 772 insertions, 366 deletions
diff --git a/src/GridText.c b/src/GridText.c
index bf3e690d..bbf1b8a2 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -54,6 +54,12 @@ unsigned int cached_styles[CACHEH][CACHEW];
 
 #include <LYJustify.h>
 
+#ifdef CONV_JISX0201KANA_JISX0208KANA
+#define is_CJK2(b) (HTCJK != NOCJK && is8bits(UCH(b)))
+#else
+#define is_CJK2(b) (HTCJK != NOCJK && is8bits(UCH(b)) && kanji_code != SJIS)
+#endif
+
 #ifdef USE_CURSES_PADS
 #  define DISPLAY_COLS    (LYwideLines ? MAX_COLS : LYcols)
 #  define WRAP_COLS(text) ((text)->stbl ?				\
@@ -722,6 +728,48 @@ static void *LY_check_calloc(size_t nmemb, size_t size)
 
 #endif /* CHECK_FREE_MEM */
 
+#ifdef USE_COLOR_STYLE
+/*
+ * Color style information is stored with the multibyte-character offset into
+ * the string at which the style would apply.  Compute the corresponding column
+ * so we can compare it with the updated column value after writing strings
+ * with curses.
+ *
+ * The offsets count multibyte characters.  Other parts of the code assume each
+ * character uses one cell, but some CJK (or UTF-8) codes use two cells.  We
+ * need to know the number of cells.
+ */
+static int StyleToCols(HText *text, HTLine *line, int nstyle)
+{
+    int result = line->offset;	/* this much is spaces one byte/cell */
+    int nchars = line->styles[nstyle].horizpos;
+    char *data = line->data;
+    char *last = line->size + data;
+    int utf_extra;
+
+    while (nchars > 0 && data < last) {
+	if (IsSpecialAttrChar(*data) && *data != LY_SOFT_NEWLINE) {
+	    ++data;
+	} else {
+	    utf_extra = utf8_length(text->T.output_utf8, data);
+	    if (utf_extra++) {
+		result += LYstrExtent(data, utf_extra, 2);
+		data += utf_extra;
+	    } else if (is_CJK2(*data)) {
+		data += 2;
+		result += 2;
+	    } else {
+		++data;
+		++result;
+	    }
+	    --nchars;
+	}
+    }
+
+    return result;
+}
+#endif
+
 /*
  * Clear highlight information for a given anchor
  * (text was allocated in the pool).
@@ -1324,6 +1372,15 @@ static int display_line(HTLine *line,
     text->has_utf8 = NO;	/* use as per-line flag, except with ncurses */
 #endif
 
+#if defined(WIDEC_CURSES)
+    /*
+     * FIXME: this should not be necessary, but in some wide-character pages
+     * the output line wraps, foiling our attempt to just use newlines to
+     * advance to the next page.
+     */
+    wmove(LYwin, scrline + TITLE_LINES - 1, 0);
+#endif
+
     /*
      * Set up the multibyte character buffer,
      * and clear the line to which we will be
@@ -1416,7 +1473,7 @@ static int display_line(HTLine *line,
 
 	data++;
 
-#if defined(USE_COLOR_STYLE) || defined(SLSC)
+#if defined(USE_COLOR_STYLE)
 #define CStyle line->styles[current_style]
 
 	while (current_style < line->numstyles &&
@@ -1494,14 +1551,13 @@ static int display_line(HTLine *line,
 		isspace(UCH(LastDisplayChar)) ||
 		LastDisplayChar == '-') {
 		/*
-		 * Ignore the soft hyphen if it is not the last
-		 * character in the line.  Also ignore it if it
-		 * first character following the margin, or if it
-		 * is preceded by a white character (we loaded 'M'
-		 * into LastDisplayChar if it was a multibyte
-		 * character) or hyphen, though it should have
-		 * been excluded by HText_appendCharacter() or by
-		 * split_line() in those cases.  -FM
+		 * Ignore the soft hyphen if it is not the last character in
+		 * the line.  Also ignore it if it first character following
+		 * the margin, or if it is preceded by a white character (we
+		 * loaded 'M' into LastDisplayChar if it was a multibyte
+		 * character) or hyphen, though it should have been excluded by
+		 * HText_appendCharacter() or by split_line() in those cases. 
+		 * -FM
 		 */
 		break;
 	    } else {
@@ -1526,7 +1582,6 @@ static int display_line(HTLine *line,
 	    }
 #endif /* SHOW_WHEREIS_TARGETS */
 #endif /* USE_COLOR_STYLE */
-	    i++;
 	    if (text->T.output_utf8 && is8bits(buffer[0])) {
 		text->has_utf8 = YES;
 		utf_extra = utf8_length(text->T.output_utf8, data - 1);
@@ -1539,15 +1594,11 @@ static int display_line(HTLine *line,
 		buffer[1] = '\0';
 		data += utf_extra;
 		utf_extra = 0;
-	    } else if (HTCJK != NOCJK && is8bits(buffer[0])
-#ifndef CONV_JISX0201KANA_JISX0208KANA
-		       && kanji_code != SJIS
-#endif
-		) {
+	    } else if (is_CJK2(buffer[0])) {
 		/*
 		 * For CJK strings, by Masanobu Kimura.
 		 */
-		if (i < DISPLAY_COLS) {
+		if (i <= DISPLAY_COLS) {
 		    buffer[1] = *data;
 		    buffer[2] = '\0';
 		    data++;
@@ -1564,11 +1615,21 @@ static int display_line(HTLine *line,
 		     * used.  -FM
 		     */
 		    LastDisplayChar = 'M';
+#ifndef USE_SLANG
+		    {
+			int y, x;
+
+			getyx(LYwin, y, x);
+			if (x >= DISPLAY_COLS || x == 0)
+			    break;
+		    }
+#endif
 		}
 	    } else {
 		LYaddstr(buffer);
 		LastDisplayChar = buffer[0];
 	    }
+	    i++;
 	}			/* end of switch */
     }				/* end of while */
 
@@ -2725,8 +2786,9 @@ static HTStyleChange *skip_matched_and_correct_offsets(HTStyleChange *end,
 	    } else
 		return 0;
 	}
-	if (tmp->horizpos > split_pos)
+	if (tmp->horizpos > split_pos) {
 	    tmp->horizpos = split_pos;
+	}
     }
     return 0;
 }
@@ -2739,6 +2801,7 @@ static void split_line(HText *text, unsigned split)
     int indent = (text->in_line_1
 		  ? text->style->indent1st
 		  : text->style->leftIndent);
+    int new_offset;
     short alignment;
     TextAnchor *a;
     int CurLine = text->Lines;
@@ -2778,6 +2841,7 @@ static void split_line(HText *text, unsigned split)
 #endif
 
     cp = previous->data;
+
     /* Float LY_SOFT_NEWLINE to the start */
     if (cp[0] == LY_BOLD_START_CHAR
 	|| cp[0] == LY_UNDERLINE_START_CHAR) {
@@ -2974,14 +3038,15 @@ static void split_line(HText *text, unsigned split)
 	 * The second loop below may then handle remaining changes.  - kw */
 	while (from >= previous->styles && to >= line->styles) {
 	    *to = *from;
-	    if ((int) to->horizpos > s_post)
+	    if ((int) to->horizpos > s_post) {
 		to->horizpos += -s_post + SpecialAttrChars;
-	    else if ((int) to->horizpos > s_pre &&
-		     (to->direction == STACK_ON ||
-		      to->direction == ABS_ON))
+	    } else if ((int) to->horizpos > s_pre &&
+		       (to->direction == STACK_ON ||
+			to->direction == ABS_ON)) {
 		to->horizpos = ((int) to->horizpos < s) ? 0 : SpecialAttrChars;
-	    else
+	    } else {
 		break;
+	    }
 	    to--;
 	    from--;
 	}
@@ -3037,8 +3102,9 @@ static void split_line(HText *text, unsigned split)
 		    break;
 		}
 	    }
-	    if ((int) scan->horizpos > s_pre)
+	    if ((int) scan->horizpos > s_pre) {
 		scan->horizpos = s_pre;
+	    }
 	    scan--;
 	}
 	line->numstyles = line->styles + MAX_STYLES_ON_LINE - 1 - to;
@@ -3047,11 +3113,13 @@ static void split_line(HText *text, unsigned split)
 
 	    for (n = 0; n < line->numstyles; n++)
 		line->styles[n] = to[n + 1];
-	} else if (line->numstyles == 0)
+	} else if (line->numstyles == 0) {
 	    line->styles[0].horizpos = ~0;	/* ?!!! */
+	}
 	previous->numstyles = at_end - previous->styles + 1;
-	if (previous->numstyles == 0)
+	if (previous->numstyles == 0) {
 	    previous->styles[0].horizpos = ~0;	/* ?!!! */
+	}
     }
 #endif /*USE_COLOR_STYLE */
 
@@ -3169,19 +3237,21 @@ static void split_line(HText *text, unsigned split)
 #endif
     }
 
+    new_offset = previous->offset;
     switch (style->alignment) {
     case HT_CENTER:
-	previous->offset = previous->offset + indent + spare / 2;
+	new_offset += indent + spare / 2;
 	break;
     case HT_RIGHT:
-	previous->offset = previous->offset + indent + spare;
+	new_offset += indent + spare;
 	break;
     case HT_LEFT:
     case HT_JUSTIFY:		/* Not implemented */
     default:
-	previous->offset = previous->offset + indent;
+	new_offset += indent;
 	break;
     }				/* switch */
+    previous->offset = ((new_offset < 0) ? 0 : new_offset);
 
     if (text->stbl)
 	/*
@@ -3286,7 +3356,7 @@ static void split_line(HText *text, unsigned split)
     /* now perform justification - by VH */
 
     if (this_line_was_split
-	&& spare
+	&& spare > 0
 	&& !text->stbl		/* We don't inform TRST on the cell width change yet */
 	&& justify_max_void_percent > 0
 	&& justify_max_void_percent <= 100
@@ -4147,7 +4217,7 @@ void HText_appendCharacter(HText *text, int ch)
 	    if (target_cu > WRAP_COLS(text))
 		target -= target_cu - WRAP_COLS(text);
 	    if (line->size == 0) {
-		line->offset = line->offset + target - here;
+		line->offset += (target - here);
 	    } else {
 		for (; here < target; here++) {
 		    /* Put character into line */
@@ -4472,8 +4542,9 @@ void _internal_HTC(HText *text, int style, int dir)
 	     * And in UTF-8 display mode all non-initial bytes are
 	     * counted as ctrl_chars.  - kw
 	     */
-	    if ((int) line->styles[line->numstyles].horizpos >= ctrl_chars_on_this_line)
+	    if ((int) line->styles[line->numstyles].horizpos >= ctrl_chars_on_this_line) {
 		line->styles[line->numstyles].horizpos -= ctrl_chars_on_this_line;
+	    }
 	    line->styles[line->numstyles].style = style;
 	    line->styles[line->numstyles].direction = dir;
 	    line->numstyles++;
@@ -4747,7 +4818,9 @@ static int HText_insertBlanksInStblLines(HText *me, int ncols)
 	    }
 #endif
 	    CTRACE((tfp, " %d:%d", lineno, table_offset - line->offset));
-	    line->offset = table_offset;
+	    line->offset = (table_offset > 0
+			    ? table_offset
+			    : 0);
 	}
     }
 #ifdef EXP_NESTED_TABLES
@@ -7343,6 +7416,7 @@ BOOL HTFindPoundSelector(const char *selector)
 {
     TextAnchor *a;
 
+    CTRACE((tfp, "FindPound: searching for \"%s\"\n", selector));
     for (a = HTMainText->first_anchor; a != 0; a = a->next) {
 
 	if (a->anchor && a->anchor->tag) {
@@ -13316,6 +13390,39 @@ int HText_InsertFile(LinkInfo * form_link)
     return (newlines);
 }
 
+#ifdef USE_COLOR_STYLE
+static int GetColumn(void)
+{
+    int result;
+
+#ifdef USE_SLANG
+    result = SLsmg_get_column();
+#else
+    int y, x;
+
+    LYGetYX(y, x);
+    result = x;
+    (void) y;
+#endif
+    return result;
+}
+
+static BOOL DidWrap(int y0, int x0)
+{
+    BOOL result = NO;
+
+#ifndef USE_SLANG
+    int y, x;
+
+    LYGetYX(y, x);
+    (void) x0;
+    if (x >= DISPLAY_COLS || ((x == 0) && (y != y0)))
+	result = YES;
+#endif
+    return result;
+}
+#endif /* USE_COLOR_STYLE */
+
 /*
  * This function draws the part of line 'line', pointed by 'str' (which can be
  * non terminated with null - i.e., is line->data+N) drawing 'len' bytes (not
@@ -13339,6 +13446,7 @@ static void redraw_part_of_line(HTLine *line, const char *str,
 
 #ifdef USE_COLOR_STYLE
     int current_style = 0;
+    int tcols, scols;
 #endif
     char LastDisplayChar = ' ';
     int YP, XP;
@@ -13359,13 +13467,17 @@ static void redraw_part_of_line(HTLine *line, const char *str,
 	buffer[0] = *data;
 	data++;
 
-#if defined(USE_COLOR_STYLE) || defined(SLSC)
+#if defined(USE_COLOR_STYLE)
 #define CStyle line->styles[current_style]
 
+	tcols = GetColumn();
+	scols = StyleToCols(text, line, current_style);
+
 	while (current_style < line->numstyles &&
-	       i >= (int) (CStyle.horizpos + line->offset + 1)) {
+	       tcols >= scols) {
 	    LynxChangeStyle(CStyle.style, CStyle.direction);
 	    current_style++;
+	    scols = StyleToCols(text, line, current_style);
 	}
 #endif
 	switch (buffer[0]) {
@@ -13399,8 +13511,10 @@ static void redraw_part_of_line(HTLine *line, const char *str,
 
 #endif
 	case LY_SOFT_NEWLINE:
-	    if (!dump_output_immediately)
+	    if (!dump_output_immediately) {
 		LYaddch('+');
+		i++;
+	    }
 	    break;
 
 	case LY_SOFT_HYPHEN:
@@ -13408,14 +13522,13 @@ static void redraw_part_of_line(HTLine *line, const char *str,
 		isspace(UCH(LastDisplayChar)) ||
 		LastDisplayChar == '-') {
 		/*
-		 * Ignore the soft hyphen if it is not the last
-		 * character in the line.  Also ignore it if it
-		 * first character following the margin, or if it
-		 * is preceded by a white character (we loaded 'M'
-		 * into LastDisplayChar if it was a multibyte
-		 * character) or hyphen, though it should have
-		 * been excluded by HText_appendCharacter() or by
-		 * split_line() in those cases.  -FM
+		 * Ignore the soft hyphen if it is not the last character in
+		 * the line.  Also ignore it if it first character following
+		 * the margin, or if it is preceded by a white character (we
+		 * loaded 'M' into LastDisplayChar if it was a multibyte
+		 * character) or hyphen, though it should have been excluded by
+		 * HText_appendCharacter() or by split_line() in those cases. 
+		 * -FM
 		 */
 		break;
 	    } else {
@@ -13423,12 +13536,10 @@ static void redraw_part_of_line(HTLine *line, const char *str,
 		 * Make it a hard hyphen and fall through.  -FM
 		 */
 		buffer[0] = '-';
-		i++;
 	    }
 	    /* FALLTHRU */
 
 	default:
-	    i++;
 	    if (text->T.output_utf8 && is8bits(buffer[0])) {
 		utf_extra = utf8_length(text->T.output_utf8, data - 1);
 		LastDisplayChar = 'M';
@@ -13440,30 +13551,35 @@ static void redraw_part_of_line(HTLine *line, const char *str,
 		buffer[1] = '\0';
 		data += utf_extra;
 		utf_extra = 0;
-	    } else if (HTCJK != NOCJK && is8bits(buffer[0])) {
+	    } else if (is_CJK2(buffer[0])) {
 		/*
 		 * For CJK strings, by Masanobu Kimura.
 		 */
-		buffer[1] = *data;
-		data++;
-		LYaddstr(buffer);
-		buffer[1] = '\0';
-		/*
-		 * For now, load 'M' into LastDisplayChar,
-		 * but we should check whether it's white
-		 * and if so, use ' '.  I don't know if
-		 * there actually are white CJK characters,
-		 * and we're loading ' ' for multibyte
-		 * spacing characters in this code set,
-		 * but this will become an issue when
-		 * the development code set's multibyte
-		 * character handling is used.  -FM
-		 */
-		LastDisplayChar = 'M';
+		if (i <= DISPLAY_COLS) {
+		    buffer[1] = *data;
+		    buffer[2] = '\0';
+		    data++;
+		    i++;
+		    LYaddstr(buffer);
+		    buffer[1] = '\0';
+		    /*
+		     * For now, load 'M' into LastDisplayChar, but we should
+		     * check whether it's white and if so, use ' '.  I don't
+		     * know if there actually are white CJK characters, and
+		     * we're loading ' ' for multibyte spacing characters in
+		     * this code set, but this will become an issue when the
+		     * development code set's multibyte character handling is
+		     * used.  -FM
+		     */
+		    LastDisplayChar = 'M';
+		}
 	    } else {
 		LYaddstr(buffer);
 		LastDisplayChar = buffer[0];
 	    }
+	    if (DidWrap(YP, XP))
+		break;
+	    i++;
 	}			/* end of switch */
     }				/* end of while */
 
@@ -14058,7 +14174,7 @@ void LYMoveToLink(int cur,
  * regular link when it's being unhighlighted in LYhighlight().
  */
 #ifdef USE_COLOR_STYLE
-void redraw_lines_of_link(int cur GCC_UNUSED)
+void redraw_lines_of_link(int cur)
 {
 #define pvtTITLE_HEIGHT 1
     HTLine *todr1;
diff --git a/src/HTAlert.c b/src/HTAlert.c
index 21dfd04c..2c59b206 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -50,6 +50,13 @@ void HTAlert(const char *Msg)
     _user_message(ALERT_FORMAT, Msg);
     LYstore_message2(ALERT_FORMAT, Msg);
 
+    if (dump_output_immediately && dump_to_stderr) {
+	fflush(stdout);
+	fprintf(stderr, ALERT_FORMAT, Msg);
+	fputc('\n', stderr);
+	fflush(stderr);
+    }
+
     LYSleepAlert();
 }
 
diff --git a/src/HTFWriter.c b/src/HTFWriter.c
index 3fe384af..21c3374e 100644
--- a/src/HTFWriter.c
+++ b/src/HTFWriter.c
@@ -81,9 +81,27 @@ struct _HTStream {
  *
  *			A C T I O N	R O U T I N E S
  *  Bug:
- *	All errors are ignored.
+ *	Most errors are ignored.
  */
 
+/*	Error handling
+ *	------------------
+ */
+static void HTFWriter_error(HTStream *me, char *id)
+{
+    char buf[200];
+
+    sprintf(buf, "%.60s: %.60s: %.60s",
+	    id,
+	    me->isa->name,
+	    LYStrerror(errno));
+    HTAlert(buf);
+/*
+ * Only disaster results from:
+ *	me->isa->_abort(me, NULL);
+ */
+}
+
 /*	Character handling
  *	------------------
  */
@@ -109,8 +127,13 @@ static void HTFWriter_put_string(HTStream *me, const char *s)
  */
 static void HTFWriter_write(HTStream *me, const char *s, int l)
 {
+    size_t result;
+
     if (me->fp) {
-	fwrite(s, 1, l, me->fp);
+	result = fwrite(s, 1, l, me->fp);
+	if (result != (size_t) l) {
+	    HTFWriter_error(me, "HTFWriter_write");
+	}
     }
 }
 
@@ -487,7 +510,8 @@ static const HTStreamClass HTFWriter =	/* As opposed to print etc */
     "FileWriter",
     HTFWriter_free,
     HTFWriter_abort,
-    HTFWriter_put_character, HTFWriter_put_string,
+    HTFWriter_put_character,
+    HTFWriter_put_string,
     HTFWriter_write
 };
 
diff --git a/src/LYCurses.c b/src/LYCurses.c
index 8677433a..9a7532fc 100644
--- a/src/LYCurses.c
+++ b/src/LYCurses.c
@@ -80,11 +80,11 @@ static void make_blink_boldbg(void);
 #endif
 
 #if defined(USE_COLOR_TABLE) || defined(USE_SLANG)
-int Current_Attr, Masked_Attr;
+static int Current_Attr, Masked_Attr;
 #endif
 
 #ifdef USE_SLANG
-unsigned int Lynx_Color_Flags = 0;
+unsigned Lynx_Color_Flags = 0;
 BOOLEAN FullRefresh = FALSE;
 int curscr = 0;
 
@@ -442,9 +442,9 @@ void curses_w_style(WINDOW * win, int style,
 #endif
     }
 
-    CTRACE2(TRACE_STYLE, (tfp, "CSS.CS:<%s%s> code %#x, color %#x\n",
+    CTRACE2(TRACE_STYLE, (tfp, "CSS.CS:<%s%s> style %d code %#x, color %#x\n",
 			  (dir ? "" : "/"),
-			  ds->name, ds->code, ds->color));
+			  ds->name, style, ds->code, ds->color));
 
     getyx(win, YP, XP);
 
@@ -615,7 +615,8 @@ static struct {
 static int get_color_pair(int n)
 {
 #ifdef USE_CURSES_PAIR_0
-    if (lynx_color_pairs[n].fg == default_fg
+    if ((n < (int) TABLESIZE(lynx_color_pairs))
+	&& lynx_color_pairs[n].fg == default_fg
 	&& lynx_color_pairs[n].bg == default_bg)
 	return 0;
 #endif
@@ -649,40 +650,106 @@ static int lynx_color_cfg_attr(int code)
     return result;
 }
 
+static int encode_color_attr(int color_attr)
+{
+    int result;
+    int code = 0;
+    int offs = 1;
+
+    if (color_attr & A_BOLD)
+	code |= 1;
+    if (color_attr & (A_REVERSE | A_DIM))
+	code |= 2;
+    if (color_attr & A_UNDERLINE)
+	code |= 4;
+    result = lynx_color_cfg_attr(code);
+
+    if (code + offs < COLOR_PAIRS) {
+	result |= get_color_pair(code + offs);
+    }
+    return result;
+}
+
+static int decode_mono_code(int mono_code)
+{
+    int result = 0;
+
+    if (mono_code & 1)
+	result |= A_BOLD;
+    if (mono_code & 2)
+	result |= A_REVERSE;
+    if (mono_code & 4)
+	result |= A_UNDERLINE;
+
+    return result;
+}
+
 /*
  * Map the SGR attributes (0-7) into ANSI colors, modified with the actual BOLD
- * attribute we'll get 16 colors.
+ * attribute to get 16 colors.
  */
-static void LYsetWAttr(WINDOW * win)
+int LYgetTableAttr(void)
 {
-    if (lynx_has_color && LYShowColor >= SHOW_COLOR_ON) {
-	int code = 0;
-	int attr = A_NORMAL;
-	int offs = 1;
-
-	if (Current_Attr & A_BOLD)
-	    code |= 1;
-	if (Current_Attr & A_REVERSE)
-	    code |= 2;
-	if (Current_Attr & A_UNDERLINE)
-	    code |= 4;
-	attr = lynx_color_cfg_attr(code);
-
-	if (code + offs < COLOR_PAIRS) {
-	    attr |= get_color_pair(code + offs);
-	}
+    int result;
 
-	wattrset(win, attr & ~Masked_Attr);
+    if (lynx_has_color && LYShowColor >= SHOW_COLOR_ON) {
+	result = encode_color_attr(Current_Attr);
     } else {
-	wattrset(win, Current_Attr & ~Masked_Attr);
+	result = Current_Attr;
     }
+    return result & ~Masked_Attr;
 }
 
+#ifdef USE_COLOR_STYLE
+/*
+ * Return a string that corresponds to the attributes that would be returned by
+ * LYgetTableAttr().
+ */
+char *LYgetTableString(int code)
+{
+    int mask = decode_mono_code(code);
+    int second = encode_color_attr(mask);
+    int pair = PAIR_NUMBER(second);
+    int mono = second & A_ATTRIBUTES;
+    int fg = lynx_color_pairs[pair].fg;
+    int bg = lynx_color_pairs[pair].bg;
+    unsigned n;
+    char *result = 0;
+
+    CTRACE((tfp, "LYgetTableString(%d)\n", code));
+
+    if (fg == 0 && bg == 0) {
+	fg = COLOR_WHITE;
+    }
+    CTRACE((tfp, "%#x -> %#x (%d) fg=%d, bg=%d\n", mask, second, pair, fg, bg));
+    for (n = 0; n < TABLESIZE(Mono_Attrs); ++n) {
+	if ((Mono_Attrs[n].code & mono) != 0) {
+	    if (result != 0)
+		StrAllocCat(result, "+");
+	    StrAllocCat(result, Mono_Attrs[n].name);
+	}
+    }
+    if (result == 0)
+	StrAllocCopy(result, "normal");
+    StrAllocCat(result, ":");
+    StrAllocCat(result, lookup_color(fg));
+    if (bg >= 0) {
+	StrAllocCat(result, ":");
+	StrAllocCat(result, lookup_color(bg));
+    }
+    CTRACE((tfp, "->%s\n", result));
+    return result;
+}
+#endif
+
 /*
  * Initialize a curses color-pair based on our configured color values.
  */
 static void lynx_init_color_pair(int n)
 {
+#ifdef USE_COLOR_STYLE
+    (void) n;			/* we only use lynx_color_pairs[] data */
+#else
     int m;
 
     if (lynx_called_initscr) {
@@ -694,23 +761,27 @@ static void lynx_init_color_pair(int n)
 			  (short) map2bold(lynx_color_pairs[pair].fg),
 			  (short) map2bold(lynx_color_pairs[pair].bg));
 	}
-	if (n == 0 && LYShowColor >= SHOW_COLOR_ON)
+	if (n == 0 && LYShowColor >= SHOW_COLOR_ON) {
 	    wbkgd(LYwin, COLOR_BKGD | ' ');
+	}
     }
+#endif
 }
 
 static void lynx_map_color(int n)
 {
     CTRACE((tfp, "lynx_map_color(%d)\n", n));
 
-    lynx_color_pairs[n + 1].fg = lynx_color_cfg[n].fg;
-    lynx_color_pairs[n + 1].bg = lynx_color_cfg[n].bg;
+    if (n + 1 < (int) TABLESIZE(lynx_color_pairs)) {
+	lynx_color_pairs[n + 1].fg = lynx_color_cfg[n].fg;
+	lynx_color_pairs[n + 1].bg = lynx_color_cfg[n].bg;
 
-    lynx_color_pairs[n + 9].fg = lynx_color_cfg[n].fg;
-    lynx_color_pairs[n + 9].bg = lynx_color_cfg[0].bg;
+	lynx_color_pairs[n + 9].fg = lynx_color_cfg[n].fg;
+	lynx_color_pairs[n + 9].bg = lynx_color_cfg[0].bg;
 
-    lynx_color_pairs[n + 17].fg = lynx_color_cfg[n].bg;
-    lynx_color_pairs[n + 17].bg = lynx_color_cfg[n].bg;
+	lynx_color_pairs[n + 17].fg = lynx_color_cfg[n].bg;
+	lynx_color_pairs[n + 17].bg = lynx_color_cfg[n].bg;
+    }
 
     lynx_init_color_pair(n);
 }
@@ -723,6 +794,8 @@ int lynx_chg_color(int color,
 		   int fg,
 		   int bg)
 {
+    CTRACE((tfp, "lynx_chg_color(color=%d, fg=%d, bg=%d)\n", color, fg, bg));
+
     if (fg == ERR_COLOR || bg == ERR_COLOR)
 	return -1;
     if (color >= 0 && color < 8) {
@@ -795,12 +868,7 @@ void LYnoVideo(int a)
     lynx_setup_attrs();
 #else
 #ifdef USE_COLOR_TABLE
-    if (a & 1)
-	Masked_Attr |= A_BOLD;
-    if (a & 2)
-	Masked_Attr |= A_REVERSE;
-    if (a & 4)
-	Masked_Attr |= A_UNDERLINE;
+    Masked_Attr = decode_mono_code(a);
 #endif
 #endif
 }
@@ -1141,7 +1209,7 @@ void start_curses(void)
 #endif
 #ifdef USE_COLOR_TABLE
 	lynx_init_colors();
-#endif /* USE_COLOR_TABLE */
+#endif
     }
 #ifdef __DJGPP__
     _eth_init();
@@ -1220,6 +1288,8 @@ void lynx_enable_mouse(int state)
     }
 #endif
 
+    (void) state;
+
     if (LYUseMouse == 0)
 	return;
 
@@ -1382,9 +1452,11 @@ void stop_curses(void)
 	int i;
 
 	for (i = 0; i <= 3; i++) {
-	    fprintf(stdout, "\r\n");
+	    printf("\r\n");
 	}
     }
+#else
+    printf("\r");		/* PDCurses may leave the cursor randomly */
 #endif
 
     fflush(stdout);
@@ -1567,6 +1639,11 @@ static int dumbterm(char *terminal)
 #ifdef FANCY_CURSES
 #ifndef USE_COLOR_STYLE
 #ifdef USE_COLOR_TABLE
+static void LYsetWAttr(WINDOW * win)
+{
+    wattrset(win, LYgetTableAttr());
+}
+
 void LYaddWAttr(WINDOW * win, int a)
 {
     Current_Attr |= a;
@@ -1775,36 +1852,30 @@ void LYwaddnstr(WINDOW * w GCC_UNUSED,
      * Link-highlighting uses wrapping.  You can see this by viewing the
      * options screen in a terminal which is narrower than 80 columns.
      *
-     * Check for that case, and split up the call into segments for each line.
+     * Check for that case, and use curses's wrapping in a derived window to
+     * simplify things, e.g., in case the string contains multibyte or
+     * multicolumn characters.
      */
     int y0, x0;
 
     getyx(LYwin, y0, x0);
 
     if (LYuseCursesPads
-	&& LYshiftWin == 0
+	&& (LYwin == w)		/* popups do not wrap */
+	&&LYshiftWin == 0
 	&& LYwideLines == FALSE
-	&& ((int) len > (LYcolLimit - x0))) {
-	int start = 0;
-	int piece = (LYcolLimit - x0);
-
-	CTRACE((tfp, "LYwaddnstr wrapping src:%s, len:%u:%d\n", src, len, LYcolLimit));
-	LYwideLines = TRUE;	/* prevent recursion */
-	while (piece > 0) {
-	    int y, x;
-
-	    getyx(LYwin, y, x);
-	    CTRACE((tfp, "piece src:%.*s, len:%d\n", piece, src + start, piece));
-	    LYwaddnstr(w, src + start, piece);
-	    start += piece;
-	    if (start >= (int) len)
-		break;
-	    LYmove(y + 1, 0);
-	    piece = LYcolLimit;
-	    if ((start + piece) > (int) len)
-		piece = len - start;
+	&& ((int) len > (LYcolLimit - x0))
+	&& (x0 < LYcolLimit)) {
+	WINDOW *sub = derwin(LYwin, LYlines, LYcolLimit, 0, 0);
+
+	if (sub != 0) {
+	    wmove(sub, y0, x0);
+	    LYwideLines = TRUE;
+	    LYwaddnstr(sub, src, len);
+	    delwin(sub);
 	}
 	LYwideLines = FALSE;
+
 	return;
     }
 #endif
@@ -2418,7 +2489,7 @@ int LYscreenWidth(void)
  */
 void LYnormalColor(void)
 {
-#if defined(USE_COLOR_STYLE) && USE_CURSES_PADS
+#if defined(USE_COLOR_STYLE) && defined(USE_CURSES_PADS)
     if (LYwin != stdscr) {
 	int color = displayStyles[DSTYLE_NORMAL].color;
 
diff --git a/src/LYCurses.h b/src/LYCurses.h
index abe30e7e..b84ba4ba 100644
--- a/src/LYCurses.h
+++ b/src/LYCurses.h
@@ -32,7 +32,9 @@
  */
 #undef USE_COLOR_TABLE
 
-#ifndef USE_COLOR_STYLE
+#ifdef USE_COLOR_STYLE
+#define USE_COLOR_TABLE 1	/* default color logic is used */
+#else
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
 #define USE_COLOR_TABLE 1
 #endif
@@ -410,11 +412,6 @@ extern "C" {
 #define LYtableCols	0
 #endif
 
-#if defined(USE_COLOR_TABLE) || defined(USE_SLANG)
-    extern int Current_Attr;
-    extern int Masked_Attr;
-#endif
-
     extern BOOLEAN setup(char *terminal);
     extern int LYscreenHeight(void);
     extern int LYscreenWidth(void);
@@ -465,7 +462,7 @@ extern "C" {
     extern void LYaddAttr(int a);
     extern void LYsubAttr(int a);
     extern void lynx_setup_colors(void);
-    extern unsigned int Lynx_Color_Flags;
+    extern unsigned Lynx_Color_Flags;
 #endif
 
 #ifdef USE_SLANG
@@ -594,14 +591,11 @@ extern "C" {
  *  our own functions to add or subtract the
  *  A_foo attributes. - FM
  */
-#ifdef USE_COLOR_TABLE
+#if defined(USE_COLOR_TABLE) && !defined(USE_COLOR_STYLE)
     extern void LYaddWAttr(WINDOW * win, int a);
     extern void LYsubWAttr(WINDOW * win, int a);
     extern void LYaddWAttr(WINDOW * win, int a);
     extern void LYsubWAttr(WINDOW * win, int a);
-    extern void lynx_set_color(int a);
-    extern void lynx_standout(int a);
-    extern int lynx_chg_color(int, int, int);
 
 #undef  standout
 #define standout() 		lynx_standout(TRUE)
@@ -614,6 +608,14 @@ extern "C" {
 #define LYsubWAttr(win,attr)	wattroff(win,attr)
 #endif
 
+#if defined(USE_COLOR_TABLE)
+    extern void lynx_set_color(int a);
+    extern void lynx_standout(int a);
+    extern char *LYgetTableString(int code);
+    extern int LYgetTableAttr(void);
+    extern int lynx_chg_color(int, int, int);
+#endif
+
 #define start_bold()		LYaddAttr(LYUnderlineLinks ? A_UNDERLINE : A_BOLD)
 #define stop_bold()		LYsubAttr(LYUnderlineLinks ? A_UNDERLINE : A_BOLD)
 #define start_underline()	LYaddAttr(LYUnderlineLinks ? A_BOLD : A_UNDERLINE)
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index 82a828ff..b1e19f66 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -211,6 +211,7 @@ extern "C" {
     extern BOOLEAN child_lynx;	/* TRUE to exit with an arrow */
     extern BOOLEAN dump_links_only;
     extern BOOLEAN dump_output_immediately;
+    extern BOOLEAN dump_to_stderr;
     extern BOOLEAN emacs_keys;	/* TRUE to turn on emacs-like key movement */
     extern BOOLEAN error_logging;	/* TRUE to mail error messages */
     extern BOOLEAN ftp_local_passive;
diff --git a/src/LYMain.c b/src/LYMain.c
index e9753f7c..00498122 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -201,6 +201,7 @@ BOOLEAN check_mail = CHECKMAIL;
 BOOLEAN child_lynx = FALSE;
 BOOLEAN dump_links_only = FALSE;
 BOOLEAN dump_output_immediately = FALSE;
+BOOLEAN dump_to_stderr = FALSE;
 BOOLEAN emacs_keys = EMACS_KEYS_ALWAYS_ON;
 BOOLEAN error_logging = MAIL_SYSTEM_ERROR_LOGGING;
 BOOLEAN ftp_passive = FTP_PASSIVE;	/* TRUE if doing ftp in passive mode */
@@ -628,7 +629,8 @@ static void FatalProblem(int sig);
 #endif /* !VMS */
 
 #if defined(USE_COLOR_STYLE)
-char *lynx_lss_file = NULL;
+char *lynx_lss_file2 = NULL;	/* from command-line options */
+char *lynx_lss_file = NULL;	/* from config-file, etc. */
 #endif
 
 #ifdef __DJGPP__
@@ -759,6 +761,7 @@ static void free_lynx_globals(void)
     FREE(LYTraceLogPath);
     FREE(lynx_cfg_file);
 #if defined(USE_COLOR_STYLE)
+    FREE(lynx_lss_file2);
     FREE(lynx_lss_file);
 #endif
     FREE(UCAssume_MIMEcharset);
@@ -1094,11 +1097,9 @@ int main(int argc,
 #endif /* LOCALE */
     /* Set the text message domain.  */
 #if defined(HAVE_LIBINTL_H) || defined(HAVE_LIBGETTEXT_H)
-#ifndef __DJGPP__
     if ((cp = LYGetEnv("LYNX_LOCALEDIR")) == 0)
 	cp = LOCALEDIR;
     bindtextdomain("lynx", cp);
-#endif /* !__DJGPP__ */
     textdomain("lynx");
 #endif /* HAVE_LIBINTL_H */
 
@@ -1452,7 +1453,7 @@ int main(int argc,
      */
     if (!LYCanReadFile(lynx_cfg_file)) {
 	fprintf(stderr,
-		gettext("\nConfiguration file %s is not available.\n\n"),
+		gettext("\nConfiguration file \"%s\" is not available.\n\n"),
 		lynx_cfg_file);
 	exit_immediately(EXIT_FAILURE);
     }
@@ -1494,36 +1495,6 @@ int main(int argc,
 	fprintf(stderr, gettext("\nLynx edit map not declared.\n\n"));
 	exit_immediately(EXIT_FAILURE);
     }
-#if defined(USE_COLOR_STYLE)
-    /*
-     * If no alternate lynx-style file was specified on the command line, see
-     * if it's in the environment.
-     */
-    if (!lynx_lss_file) {
-	if (((cp = LYGetEnv("LYNX_LSS")) != NULL) ||
-	    (cp = LYGetEnv("lynx_lss")) != NULL)
-	    StrAllocCopy(lynx_lss_file, cp);
-    }
-
-    /*
-     * If we still don't have a lynx-style file, use the userdefs.h definition.
-     */
-    if (!lynx_lss_file)
-	StrAllocCopy(lynx_lss_file, LYNX_LSS_FILE);
-
-    tildeExpand(&lynx_lss_file, TRUE);
-
-    /*
-     * If the lynx-style file is not available, inform the user and exit.
-     */
-    if (!LYCanReadFile(lynx_lss_file)) {
-	fprintf(stderr, gettext("\nLynx file %s is not available.\n\n"),
-		lynx_lss_file);
-    } else {
-	style_readFromFile(lynx_lss_file);
-    }
-#endif /* USE_COLOR_STYLE */
-
 #ifdef USE_COLOR_TABLE
     /*
      * Set up default foreground and background colors.
@@ -1564,6 +1535,47 @@ int main(int argc,
      */
     read_cfg(lynx_cfg_file, "main program", 1, (FILE *) 0);
 
+#if defined(USE_COLOR_STYLE)
+    /*
+     * A command-line "-lss" always overrides the config-file, even if it is
+     * an empty string such as -lss="".
+     */
+    if (lynx_lss_file2 != 0) {
+	FREE(lynx_lss_file);
+	lynx_lss_file = lynx_lss_file2;
+	lynx_lss_file2 = 0;
+    }
+
+    /*
+     * If no alternate lynx-style file was specified on the command line, see
+     * if it's in the environment.
+     */
+    if (!lynx_lss_file) {
+	if (((cp = LYGetEnv("LYNX_LSS")) != NULL) ||
+	    (cp = LYGetEnv("lynx_lss")) != NULL)
+	    StrAllocCopy(lynx_lss_file, cp);
+    }
+
+    /*
+     * If we still don't have a lynx-style file, use the userdefs.h definition.
+     */
+    if (!lynx_lss_file)
+	StrAllocCopy(lynx_lss_file, LYNX_LSS_FILE);
+
+    tildeExpand(&lynx_lss_file, TRUE);
+
+    /*
+     * If the lynx-style file is not available, inform the user and exit.
+     */
+    if (!isEmpty(lynx_lss_file) && !LYCanReadFile(lynx_lss_file)) {
+	fprintf(stderr, gettext("\nLynx file \"%s\" is not available.\n\n"),
+		lynx_lss_file);
+	exit_immediately(EXIT_FAILURE);
+    } else {
+	style_readFromFile(lynx_lss_file);
+    }
+#endif /* USE_COLOR_STYLE */
+
     /*
      * Process the RC file.
      */
@@ -3501,7 +3513,7 @@ keys (may be incompatible with some curses packages)"
 #endif /* EXEC_LINKS || EXEC_SCRIPTS */
 #if defined(USE_COLOR_STYLE)
    PARSE_STR(
-      "lss",		2|NEED_LYSTRING_ARG,	lynx_lss_file,
+      "lss",		2|NEED_LYSTRING_ARG,	lynx_lss_file2,
       "=FILENAME\nspecifies a lynx.lss file other than the default"
    ),
 #endif
@@ -3762,6 +3774,10 @@ treated '>' as a co-terminator for double-quotes and tags"
       "allow non-http startfile and homepage with -validate"
    ),
    PARSE_SET(
+      "stderr",		4|SET_ARG,		dump_to_stderr,
+      "write warning messages to standard error when -dump -or -source is used"
+   ),
+   PARSE_SET(
       "stdin",		4|SET_ARG,		startfile_stdin,
       "read startfile from standard input"
    ),
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index b8172cc6..e20ebf53 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -395,8 +395,16 @@ int LYGetNewline(void)
 {
     return Newline;
 }
+
 #define LYGetNewline()		Newline
 
+void LYChgNewline(int adjust)
+{
+    LYSetNewline(Newline + adjust);
+}
+
+#define LYChgNewline(adjust)	Newline += (adjust)
+
 #ifdef USE_SOURCE_CACHE
 static BOOLEAN from_source_cache = FALSE;
 
@@ -2204,7 +2212,7 @@ static void handle_LYK_DOWN_xxx(int *old_c,
     int i;
 
     if (more_text) {
-	Newline += scroll_by;
+	LYChgNewline(scroll_by);
 	if (nlinks > 0 && curdoc.link > -1 &&
 	    links[curdoc.link].ly > scroll_by) {
 	    newdoc.link = curdoc.link;
@@ -2243,15 +2251,14 @@ static void handle_LYK_DOWN_LINK(int *follow_col,
 	if (newlink > -1) {
 	    set_curdoc_link(newlink);
 	} else if (more_text) {	/* next page */
-	    Newline += display_lines;
+	    LYChgNewline(display_lines);
 	} else if (*old_c != real_c) {
 	    *old_c = real_c;
 	    HTUserMsg(NO_LINKS_BELOW);
 	    return;
 	}
     } else if (more_text) {	/* next page */
-	Newline += display_lines;
-
+	LYChgNewline(display_lines);
     } else if (*old_c != real_c) {
 	*old_c = real_c;
 	HTInfoMsg(ALREADY_AT_END);
@@ -2741,7 +2748,7 @@ static BOOLEAN handle_LYK_FASTBACKW_LINK(int *cmd,
 	    *cmd = LYK_PREV_LINK;
 	    code = TRUE;
 	} else {
-	    Newline++;		/* our line counting starts with 1 not 0 */
+	    LYChgNewline(1);	/* our line counting starts with 1 not 0 */
 	}
     } else if (*old_c != real_c) {
 	*old_c = real_c;
@@ -2805,7 +2812,7 @@ static void handle_LYK_FASTFORW_LINK(int *old_c,
 	       HTGetLinkOrFieldStart(curdoc.link,
 				     &Newline, &newdoc.link,
 				     1, TRUE) != NO) {
-	Newline++;		/* our line counting starts with 1 not 0 */
+	LYChgNewline(1);	/* our line counting starts with 1 not 0 */
 	/* nothing more to do here */
 
     } else if (*old_c != real_c) {
@@ -3720,13 +3727,8 @@ static BOOLEAN handle_LYK_OPTIONS(int *cmd,
 
 		HEAD_request = HTLoadedDocumentIsHEAD();
 		HText_setNoCache(HTMainText);
-#ifdef NO_ASSUME_SAME_DOC
-		newdoc.line = 1;
-		newdoc.link = 0;
-#else
 		newdoc.line = curdoc.line;
 		newdoc.link = curdoc.link;
-#endif /* NO_ASSUME_SAME_DOC */
 		LYforce_no_cache = TRUE;
 		free_address(&curdoc);	/* So it doesn't get pushed. */
 	    }
@@ -3826,8 +3828,7 @@ static void handle_LYK_NEXT_LINK(int c,
 	set_curdoc_link(0);
 
     } else if (more_text) {	/* next page */
-	Newline += display_lines;
-
+	LYChgNewline(display_lines);
     } else if (*old_c != real_c) {
 	*old_c = real_c;
 	HTInfoMsg(ALREADY_AT_END);
@@ -3838,7 +3839,7 @@ static void handle_LYK_NEXT_PAGE(int *old_c,
 				 int real_c)
 {
     if (more_text) {
-	Newline += display_lines;
+	LYChgNewline(display_lines);
     } else if (curdoc.link < nlinks - 1) {
 	set_curdoc_link(nlinks - 1);
     } else if (*old_c != real_c) {
@@ -3891,7 +3892,7 @@ static void handle_LYK_PREV_LINK(int *arrowup,
 			    ? display_lines
 			    : LYGetNewline() - 1);
 
-	Newline -= scrollamount;
+	LYChgNewline(-scrollamount);
 	if (scrollamount < display_lines &&
 	    nlinks > 0 && curdoc.link == 0 &&
 	    links[0].ly - 1 + scrollamount <= display_lines) {
@@ -4020,7 +4021,7 @@ static void handle_LYK_PREV_PAGE(int *old_c,
 				 int real_c)
 {
     if (LYGetNewline() > 1) {
-	Newline -= display_lines;
+	LYChgNewline(-display_lines);
     } else if (curdoc.link > 0) {
 	set_curdoc_link(0);
     } else if (*old_c != real_c) {
@@ -4120,13 +4121,6 @@ static void handle_LYK_RELOAD(int real_cmd)
 
     HEAD_request = HTLoadedDocumentIsHEAD();
     HText_setNoCache(HTMainText);
-#ifdef NO_ASSUME_SAME_DOC
-    /*
-     * Don't assume the reloaded document will be the same.  - FM
-     */
-    newdoc.line = 1;
-    newdoc.link = 0;
-#else
     /*
      * Do assume the reloaded document will be the same.  - FM
      *
@@ -4135,7 +4129,6 @@ static void handle_LYK_RELOAD(int real_cmd)
      */
     newdoc.line = curdoc.line;
     newdoc.link = curdoc.link;
-#endif /* NO_ASSUME_SAME_DOC */
     free_address(&curdoc);	/* so it doesn't get pushed */
 #ifdef VMS
     lynx_force_repaint();
@@ -4401,13 +4394,8 @@ static void handle_LYK_SWITCH_DTD(void)
 	    }
 	    HText_setNoCache(HTMainText);
 	    move_address(&newdoc, &curdoc);
-#ifdef NO_ASSUME_SAME_DOC
-	    newdoc.line = 1;
-	    newdoc.link = 0;
-#else
 	    newdoc.line = curdoc.line;
 	    newdoc.link = curdoc.link;
-#endif /* NO_ASSUME_SAME_DOC */
 	}
 #ifdef USE_SOURCE_CACHE
     }				/* end if no bypass */
@@ -4471,7 +4459,7 @@ static void handle_LYK_TAG_LINK(void)
 		   - 1) {
 	    set_curdoc_link(0);
 	} else if (more_text) {	/* next page */
-	    Newline += (display_lines);
+	    LYChgNewline(display_lines);
 	}
     }
 }
@@ -4590,7 +4578,7 @@ static void handle_LYK_UP_xxx(int *arrowup,
     if (LYGetNewline() > 1) {
 	if (LYGetNewline() - scroll_by < 1)
 	    scroll_by = LYGetNewline() - 1;
-	Newline -= scroll_by;
+	LYChgNewline(-scroll_by);
 	if (nlinks > 0 && curdoc.link > -1) {
 	    if (links[curdoc.link].ly + scroll_by <= display_lines) {
 		newdoc.link = curdoc.link +
@@ -4648,7 +4636,7 @@ static void handle_LYK_UP_LINK(int *follow_col,
 			    ? display_lines
 			    : LYGetNewline() - 1);
 
-	Newline -= scrollamount;
+	LYChgNewline(-scrollamount);
 	if (scrollamount < display_lines &&
 	    nlinks > 0 && curdoc.link > -1 &&
 	    links[0].ly - 1 + scrollamount <= display_lines) {
@@ -5235,6 +5223,7 @@ int mainloop(void)
     unsigned int len;
     int i;
     int follow_col = -1, key_count = 0, last_key = 0;
+    int tmpNewline;
 
     /* "internal" means "within the same document, with certainty".  It includes a
      * space so it cannot conflict with any (valid) "TYPE" attributes on A
@@ -5558,10 +5547,18 @@ int mainloop(void)
 		    newdoc.address = temp;
 		    temp = NULL;
 		}
-		getresult = getfile(&newdoc, &Newline);
+		tmpNewline = -1;
+		getresult = getfile(&newdoc, &tmpNewline);
+		if (!reloading && !popped_doc && (tmpNewline >= 0)) {
+		    LYSetNewline(tmpNewline);
+		}
 	    }
 #else /* TRACK_INTERNAL_LINKS */
-	    getresult = getfile(&newdoc, &Newline);
+	    tmpNewline = -1;
+	    getresult = getfile(&newdoc, &tmpNewline);
+	    if (!reloading && !popped_doc && (tmpNewline >= 0)) {
+		LYSetNewline(tmpNewline);
+	    }
 #endif /* TRACK_INTERNAL_LINKS */
 
 #ifdef INACTIVE_INPUT_STYLE_VH
@@ -6225,8 +6222,8 @@ int mainloop(void)
 
 	/*
 	 * If the curdoc.line is different than Newline then there must have
-	 * been a change since last update.  Run HText_pageDisplay() create a
-	 * fresh screen of text out.
+	 * been a change since last update.  Run HText_pageDisplay() to create
+	 * a fresh screen of text output.
 	 *
 	 * If we got new HTMainText go this way.  All display_partial calls
 	 * ends here for final redraw.
@@ -6625,10 +6622,8 @@ int mainloop(void)
 
 			    if (links[curdoc.link].ly < display_lines) {
 				refresh_screen = TRUE;
-
 			    } else {
-
-				Newline += (display_lines / 2);
+				LYChgNewline(display_lines / 2);
 				if (nlinks > 0 && curdoc.link > -1 &&
 				    links[curdoc.link].ly > display_lines / 2) {
 				    newdoc.link = curdoc.link;
diff --git a/src/LYMainLoop.h b/src/LYMainLoop.h
index 3c220ddf..bd2926a3 100644
--- a/src/LYMainLoop.h
+++ b/src/LYMainLoop.h
@@ -17,6 +17,7 @@ extern "C" {
     extern int LYGetNewline(void);
     extern int mainloop(void);
     extern void HTAddGotoURL(char *url);
+    extern void LYChgNewline(int adjust);
     extern void LYCloseTracelog(void);
     extern void LYSetNewline(int value);
     extern void handle_LYK_TRACE_TOGGLE(void);
diff --git a/src/LYMap.c b/src/LYMap.c
index 53384d9b..41a4b752 100644
--- a/src/LYMap.c
+++ b/src/LYMap.c
@@ -610,6 +610,8 @@ static int LYLoadIMGmap(const char *arg,
 
 void LYPrintImgMaps(FILE *fp)
 {
+    const char *only = HTLoadedDocumentURL();
+    int only_len = strlen(only);
     HTList *outer = LynxMaps;
     HTList *inner;
     LYImageMap *map;
@@ -618,6 +620,13 @@ void LYPrintImgMaps(FILE *fp)
 
     if (HTList_count(outer) > 0) {
 	while (NULL != (map = (LYImageMap *) HTList_nextObject(outer))) {
+	    if (only_len != 0) {
+		if (strncmp(only, map->address, only_len)
+		    || (map->address[only_len] != '\0'
+			&& map->address[only_len] != '#')) {
+		    continue;
+		}
+	    }
 	    fprintf(fp, "\n%s\n", isEmpty(map->title) ? NO_MAP_TITLE : map->title);
 	    fprintf(fp, "%s\n", map->address);
 	    inner = map->elements;
diff --git a/src/LYOptions.c b/src/LYOptions.c
index 85ec2390..bbbd49ee 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -37,16 +37,12 @@ static void terminate_options(int sig);
 
 #define COL_OPTION_VALUES 36	/* display column where option values start */
 
-#ifndef NO_OPTION_MENU
-
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
 static BOOLEAN can_do_colors = FALSE;
 #endif
 
 static int LYChosenShowColor = SHOW_COLOR_UNKNOWN;	/* whether to show and save */
 
-#endif /* NO_OPTION_MENU */
-
 BOOLEAN LYCheckUserAgent(void)
 {
     if (non_empty(LYUserAgent)) {
@@ -60,7 +56,37 @@ BOOLEAN LYCheckUserAgent(void)
     return TRUE;
 }
 
-#ifndef NO_OPTION_MENU
+static void validate_x_display(void)
+{
+    char *cp;
+
+    if ((cp = LYgetXDisplay()) != NULL) {
+	StrAllocCopy(x_display, cp);
+    } else {
+	FREE(x_display);
+    }
+}
+
+static void summarize_x_display(char *display_option)
+{
+    if ((x_display == NULL && *display_option == '\0') ||
+	(x_display != NULL && !strcmp(x_display, display_option))) {
+	if (x_display == NULL && LYisConfiguredForX == TRUE) {
+	    _statusline(VALUE_ACCEPTED_WARNING_X);
+	} else if (x_display != NULL && LYisConfiguredForX == FALSE) {
+	    _statusline(VALUE_ACCEPTED_WARNING_NONX);
+	} else {
+	    _statusline(VALUE_ACCEPTED);
+	}
+    } else {
+	if (*display_option) {
+	    _statusline(FAILED_TO_SET_DISPLAY);
+	} else {
+	    _statusline(FAILED_CLEAR_SET_DISPLAY);
+	}
+    }
+}
+
 static void SetupChosenShowColor(void)
 {
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
@@ -97,37 +123,7 @@ static void SetupChosenShowColor(void)
 #endif /* USE_SLANG || COLOR_CURSES */
 }
 
-static void validate_x_display(void)
-{
-    char *cp;
-
-    if ((cp = LYgetXDisplay()) != NULL) {
-	StrAllocCopy(x_display, cp);
-    } else {
-	FREE(x_display);
-    }
-}
-
-static void summarize_x_display(char *display_option)
-{
-    if ((x_display == NULL && *display_option == '\0') ||
-	(x_display != NULL && !strcmp(x_display, display_option))) {
-	if (x_display == NULL && LYisConfiguredForX == TRUE) {
-	    _statusline(VALUE_ACCEPTED_WARNING_X);
-	} else if (x_display != NULL && LYisConfiguredForX == FALSE) {
-	    _statusline(VALUE_ACCEPTED_WARNING_NONX);
-	} else {
-	    _statusline(VALUE_ACCEPTED);
-	}
-    } else {
-	if (*display_option) {
-	    _statusline(FAILED_TO_SET_DISPLAY);
-	} else {
-	    _statusline(FAILED_CLEAR_SET_DISPLAY);
-	}
-    }
-}
-
+#ifndef NO_OPTION_MENU
 static int boolean_choice(int status,
 			  int line,
 			  int column,
diff --git a/src/LYPrettySrc.c b/src/LYPrettySrc.c
index 988a1ab6..fa6edfac 100644
--- a/src/LYPrettySrc.c
+++ b/src/LYPrettySrc.c
@@ -150,9 +150,9 @@ static void append_open_tag(char *tagname,
 
 #  if 0
 	/*
-	 * we don't provide a classname as attribute of that tag, since for plain
-	 * formatting tags they are not used directly for anything except style -
-	 * and we provide style value directly.
+	 * we don't provide a classname as attribute of that tag, since for
+	 * plain formatting tags they are not used directly for anything except
+	 * style - and we provide style value directly.
 	 */
 	int class_attr_idx = 0;
 	int n = tag->number_of_attributes;
@@ -171,20 +171,30 @@ static void append_open_tag(char *tagname,
 #endif
 }
 
-/* returns 1 if incorrect */
+#define isLeadP(p) ((isalpha(UCH(*p)) || *p == '_'))
+#define isNextP(p) ((isalnum(UCH(*p)) || *p == '_'))
+
+#define FMT_AT " at column %d:\n\t%s\n"
+#define TXT_AT (1 + p - ts), ts
+
+/* returns FALSE if incorrect */
 int html_src_parse_tagspec(char *ts,
 			   HTlexeme lexeme,
 			   BOOL checkonly,
 			   BOOL isstart)
 {
+    BOOL stop = FALSE;
+    BOOL code = FALSE;
     char *p = ts;
     char *tagstart = 0;
     char *tagend = 0;
     char *classstart;
     char *classend;
-    char stop = FALSE, after_excl = FALSE;
+    char save, save1;
+    char after_excl = FALSE;
     html_src_check_state state = HTSRC_CK_normal;
-    HT_tagspec *head = NULL, *tail = NULL;
+    HT_tagspec *head = NULL;
+    HT_tagspec *tail = NULL;
     HT_tagspec **slot = (isstart ? lexeme_start : lexeme_end) + lexeme;
 
     while (!stop) {
@@ -194,111 +204,139 @@ int html_src_parse_tagspec(char *ts,
 	    switch (*p) {
 	    case '\0':
 		stop = TRUE;
+		code = TRUE;
 		break;
 	    case ' ':
 	    case '\t':
 		break;
 	    case '!':
-		if (state == HTSRC_CK_seen_excl)
-		    return 1;	/*second '!' */
+		if (state == HTSRC_CK_seen_excl) {
+		    CTRACE2(TRACE_CFG,
+			    (tfp, "second '!'" FMT_AT,
+			     TXT_AT));
+		    stop = TRUE;
+		    break;
+		}
 		state = HTSRC_CK_seen_excl;
 		after_excl = TRUE;
 		break;
 	    default:
-		if (isalpha(UCH(*p)) || *p == '_') {
-		    tagstart = p;
-		    while (*p && (isalnum(UCH(*p)) || *p == '_'))
-			++p;
-		    tagend = p;
-		    state = HTSRC_CK_after_tagname;
-		} else
-		    return 1;
-		continue;
+		if (!isLeadP(p)) {
+		    CTRACE2(TRACE_CFG,
+			    (tfp, "no name starting" FMT_AT,
+			     TXT_AT));
+		    stop = TRUE;
+		    break;
+		}
+		tagstart = p;
+		while (*p && isNextP(p))
+		    ++p;
+		tagend = p--;
+		state = HTSRC_CK_after_tagname;
 	    }
 	    break;
 	case HTSRC_CK_after_tagname:
 	    switch (*p) {
 	    case '\0':
 		stop = TRUE;
+		code = TRUE;
 		/* FALLTHRU */
 	    case ' ':
 		/* FALLTHRU */
 	    case '\t':
-		{
-		    char save = *tagend;
-
-		    *tagend = '\0';
-		    classstart = 0;
-		    if (checkonly) {
-			int idx = html_src_tag_index(tagstart);
-
-			*tagend = save;
-			if (idx == -1)
-			    return 1;
-		    } else {
-			if (after_excl)
-			    append_close_tag(tagstart, &head, &tail);
-			else
-			    append_open_tag(tagstart, NULL, &head, &tail);
+		save = *tagend;
+
+		*tagend = '\0';
+		classstart = 0;
+		if (checkonly) {
+		    int idx = html_src_tag_index(tagstart);
+
+		    CTRACE2(TRACE_CFG,
+			    (tfp, "tag index(%s) = %d\n",
+			     tagstart, idx));
+
+		    *tagend = save;
+		    if (idx == -1) {
+			stop = TRUE;
+			break;
 		    }
-		    state = HTSRC_CK_normal;
-		    after_excl = FALSE;
+		} else {
+		    if (after_excl)
+			append_close_tag(tagstart, &head, &tail);
+		    else
+			append_open_tag(tagstart, NULL, &head, &tail);
 		}
+		state = HTSRC_CK_normal;
+		after_excl = FALSE;
 		break;
 	    case '.':
-		if (after_excl)
-		    return 1;
+		if (after_excl) {
+		    CTRACE2(TRACE_CFG,
+			    (tfp, "dot after '!'" FMT_AT,
+			     TXT_AT));
+		    stop = TRUE;
+		    break;
+		}
 		state = HTSRC_CK_seen_dot;
 		break;
 	    default:
-		return 1;
+		CTRACE2(TRACE_CFG,
+			(tfp, "unexpected char '%c' after tagname" FMT_AT,
+			 *p, TXT_AT));
+		stop = TRUE;
+		break;
 	    }
 	    break;
-	case HTSRC_CK_seen_dot:{
-		switch (*p) {
-		case ' ':
-		case '\t':
+	case HTSRC_CK_seen_dot:
+	    switch (*p) {
+	    case ' ':
+	    case '\t':
+		break;
+	    case '\0':
+		CTRACE2(TRACE_CFG,
+			(tfp, "expected text after dot" FMT_AT,
+			 TXT_AT));
+		stop = TRUE;
+		break;
+	    default:
+		if (!isLeadP(p)) {
+		    CTRACE2(TRACE_CFG,
+			    (tfp, "no name starting" FMT_AT,
+			     TXT_AT));
+		    stop = TRUE;
 		    break;
-		case '\0':
-		    return 1;
-		default:{
-			char save, save1;
-
-			if (isalpha(UCH(*p)) || *p == '_') {
-			    classstart = p;
-			    while (*p && (isalnum(UCH(*p)) || *p == '_'))
-				++p;
-			    classend = p;
-			    save = *classend;
-			    *classend = '\0';
-			    save1 = *tagend;
-			    *tagend = '\0';
-			    if (checkonly) {
-				int idx = html_src_tag_index(tagstart);
-
-				*tagend = save1;
-				*classend = save;
-				if (idx == -1)
-				    return 1;
-			    } else {
-				append_open_tag(tagstart, classstart, &head, &tail);
-			    }
-			    state = HTSRC_CK_normal;
-			    after_excl = FALSE;
-			    continue;
-			} else
-			    return 1;
-		    }
-		}		/*of switch(*p) */
+		}
+		classstart = p;
+		while (*p && isNextP(p))
+		    ++p;
+		classend = p--;
+		save = *classend;
+		*classend = '\0';
+		save1 = *tagend;
+		*tagend = '\0';
+		if (checkonly) {
+		    int idx = html_src_tag_index(tagstart);
+
+		    *tagend = save1;
+		    *classend = save;
+		    if (idx == -1)
+			return FALSE;
+		} else {
+		    append_open_tag(tagstart, classstart, &head, &tail);
+		}
+		state = HTSRC_CK_normal;
+		after_excl = FALSE;
 		break;
-	    }			/* of case HTSRC_CK_seen_dot: */
+	    }			/* of switch(*p) */
+	    break;
 	}			/* of switch */
 	++p;
     }
 
-    if (!checkonly)
+    if (code && !checkonly)
 	*slot = head;
-    return 0;
+
+    return code;
 }
 
 /*this will clean the data associated with lexeme 'l' */
@@ -344,12 +382,23 @@ void html_src_on_lynxcfg_reload(void)
     HTMLSRC_init_caches(TRUE);
 }
 
+static void failed_init(const char *tag, int lexeme)
+{
+    fprintf(stderr,
+	    gettext("parse-error while caching %s tagspec of lexeme %d\n"),
+	    tag, lexeme);
+    fprintf(stderr,
+	    gettext("Use -trace -trace-mask=8 to see details in log.\n"));
+    exit_immediately(EXIT_FAILURE);
+}
+
 void HTMLSRC_init_caches(BOOL dont_exit)
 {
     int i;
     char *p;
     char buf[1000];
 
+    CTRACE2(TRACE_CFG, (tfp, "HTMLSRC_init_caches(%d tagspecs)\n", HTL_num_lexemes));
     for (i = 0; i < HTL_num_lexemes; ++i) {
 	/*we assume that HT_tagspecs was NULLs at when program started */
 	LYstrncpy(buf,
@@ -359,18 +408,21 @@ void HTMLSRC_init_caches(BOOL dont_exit)
 		  sizeof(buf) - 1);
 	StrAllocCopy(HTL_tagspecs[i], buf);
 
+	CTRACE2(TRACE_CFG, (tfp, "parsing lexeme %d: %s\n", i + 1, buf));
+
 	if ((p = strchr(buf, ':')) != 0)
 	    *p = '\0';
-	if (html_src_parse_tagspec(buf, (HTlexeme) i, FALSE, TRUE) && !dont_exit) {
-	    fprintf(stderr,
-		    "internal error while caching 1st tagspec of %d lexeme", i);
-	    exit_immediately(EXIT_FAILURE);
+	if (!html_src_parse_tagspec(buf,
+				    (HTlexeme) i,
+				    FALSE,
+				    TRUE) && !dont_exit) {
+	    failed_init("1st", i);
 	}
-	if (html_src_parse_tagspec(p ? p + 1 : NULL, (HTlexeme) i, FALSE,
-				   FALSE) && !dont_exit) {
-	    fprintf(stderr,
-		    "internal error while caching 2nd tagspec of %d lexeme", i);
-	    exit_immediately(EXIT_FAILURE);
+	if (!html_src_parse_tagspec(p ? p + 1 : NULL,
+				    (HTlexeme) i,
+				    FALSE,
+				    FALSE) && !dont_exit) {
+	    failed_init("2nd", i);
 	}
     }
 }
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index e8e21d55..ce7a758c 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -1100,8 +1100,8 @@ static int parse_html_src_spec(HTlexeme lexeme_code, char *value,
     CTRACE((tfp, "ReadCFG - parsing tagspec '%s:%s' for option '%s'\n",
 	    value, ts2, option_name));
     html_src_clean_item(lexeme_code);
-    if (html_src_parse_tagspec(value, lexeme_code, TRUE, TRUE)
-	|| html_src_parse_tagspec(ts2, lexeme_code, TRUE, TRUE)) {
+    if (!html_src_parse_tagspec(value, lexeme_code, TRUE, TRUE)
+	|| !html_src_parse_tagspec(ts2, lexeme_code, TRUE, TRUE)) {
 	*ts2 = ':';
 	BS();
     }
@@ -1258,6 +1258,9 @@ static Config_Type Config_Table [] =
 #ifdef USE_COLOR_TABLE
      PARSE_FUN(RC_COLOR,                color_fun),
 #endif
+#ifdef USE_COLOR_STYLE
+     PARSE_STR(RC_COLOR_STYLE,          lynx_lss_file),
+#endif
      PARSE_PRG(RC_COMPRESS_PATH,        ppCOMPRESS),
      PARSE_PRG(RC_COPY_PATH,            ppCOPY),
      PARSE_INT(RC_CONNECT_TIMEOUT,      connect_timeout),
diff --git a/src/LYStrings.c b/src/LYStrings.c
index 92eaf1bd..2b1e29bb 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -111,6 +111,10 @@ int fancy_mouse(WINDOW * win, int row,
 {
     int cmd = LYK_DO_NOTHING;
 
+    (void) win;
+    (void) row;
+    (void) position;
+
 #ifdef USE_MOUSE
 /*********************************************************************/
 
@@ -733,6 +737,17 @@ static int myGetChar(void)
 	    break;
 	}
     } while (!done);
+
+    /* PDCurses - until version 2.7 in 2005 - defined ERR as 0, unlike other
+     * versions of curses.  Generally both EOF and ERR are defined as -1's,
+     * making lynx's code work nicely when mixing curses and stdio functions.
+     * Accommodate PDCurses by making it follow that convention.
+     */
+#if defined(ERR) && ((ERR) != -1)
+    if (c == ERR)
+	c = -1;
+#endif
+
     return c;
 }
 #define GetChar() myGetChar()
@@ -1070,8 +1085,10 @@ static BOOLEAN unescape_string(char *src, char *dst, char *final)
 	    dst[1] = '\0';
 	    ok = TRUE;
 	}
-    } else if (*src == DQUOTE)
+    } else if (*src == DQUOTE) {
 	ok = expand_substring(dst, src + 1, src + strlen(src) - 1, final);
+	(void) final;
+    }
     return ok;
 }
 
@@ -1110,15 +1127,16 @@ int map_string_to_keysym(const char *str, int *keysym)
 	if (*str) {
 	    size_t len = strlen(str);
 
-	    if (len == 1)
+	    if (len == 1) {
 		return (*keysym = (UCH(str[0])) | modifier);
-	    else if (len == 2 && str[0] == '^' &&
-		     (isalpha(UCH(str[1])) ||
-		      (TOASCII(str[1]) >= '@' && TOASCII(str[1]) <= '_')))
+	    } else if (len == 2 && str[0] == '^' &&
+		       (isalpha(UCH(str[1])) ||
+			(TOASCII(str[1]) >= '@' && TOASCII(str[1]) <= '_'))) {
 		return (*keysym = FROMASCII(UCH(str[1] & 0x1f)) | modifier);
-	    else if (len == 2 && str[0] == '^' &&
-		     str[1] == '?')
+	    } else if (len == 2 && str[0] == '^' &&
+		       str[1] == '?') {
 		return (*keysym = CH_DEL | modifier);
+	    }
 	    if (*str == '^' || *str == '\\') {
 		char buf[BUFSIZ];
 
@@ -1637,6 +1655,8 @@ static int LYgetch_for(int code)
     int current_modifier = 0;
     BOOLEAN done_esc = FALSE;
 
+    (void) code;
+
     have_levent = 0;
 
   re_read:
@@ -3800,6 +3820,8 @@ static void draw_option(WINDOW * win, int entry,
 {
     char Cnum[MAX_LINE];
 
+    (void) width;
+
     FormatChoiceNum(Cnum, num_choices, number, "");
 #ifdef USE_SLANG
     SLsmg_gotorc(win->top_y + entry, (win->left_x + 2));
diff --git a/src/LYStyle.c b/src/LYStyle.c
index 3249f12f..a8ac9379 100644
--- a/src/LYStyle.c
+++ b/src/LYStyle.c
@@ -1,6 +1,6 @@
 /* character level styles for Lynx
  * (c) 1996 Rob Partington -- donated to the Lyncei (if they want it :-)
- * @Id: LYStyle.c 1.60 Thu, 02 Jun 2005 15:36:59 -0700 dickey @
+ * @Id: LYStyle.c 1.61 Thu, 31 Aug 2006 16:37:53 -0700 dickey @
  */
 #include <HTUtils.h>
 #include <HTML.h>
@@ -372,28 +372,113 @@ static void free_colorstylestuff(void)
 #endif
 
 /*
- * initialise the default style sheet
- * This should be able to be read from a file in CSS format :-)
+ * Initialise the default style sheet to match the vanilla-curses lynx.
  */
 static void initialise_default_stylesheet(void)
 {
-    static const char *table[] =
-    {
-	"a:bold:green",
-	"alert:bold:yellow:red",
-	"alink:reverse:yellow:black",
-	"label:normal:magenta",
-	"status:reverse:yellow:blue",
-	"title:normal:magenta",
-	"whereis:reverse+underline:magenta:cyan"
+    /* Use the data setup in USE_COLOR_TABLE */
+    /* *INDENT-OFF* */
+    static const struct {
+	int		color;	/* index into lynx_color_pairs[] */
+	const char	*type;
+    } table2[] = {
+	/*
+	 * non-color-style colors encode bold/reverse/underline as a 0-7
+	 * index like this:
+	 *  b,r,u 0
+	 *  b,r,U 1
+	 *  b,R,u 2
+	 *  b,R,U 3
+	 *  B,r,u 4
+	 *  B,r,U 5
+	 *  B,R,u 6
+	 *  B,R,U 7
+	 */
+	{ 0,	"normal" },
+	{ 1,	"a" },
+	{ 2,	"status" },
+	{ 4,	"b" },
+	{ 4,	"blink" },
+	{ 4,	"cite" },
+	{ 4,	"del" },
+	{ 4,	"em" },
+	{ 4,	"i" },
+	{ 4,	"ins" },
+	{ 4,	"strike" },
+	{ 4,	"strong" },
+	{ 4,	"u" },
+#if 0
+	{ 5,	"a.b" },
+	{ 5,	"b.a" },
+	{ 5,	"var.a" },
+#endif
+	{ 6,	"alink" },
+	{ 7,	"whereis" },
+#if 0
+	{ 0,	"h2.link" },
+	{ 0,	"link.h2" },
+#endif
+#ifdef USE_PRETTYSRC
+	/* FIXME: HTL_tagspecs_defaults[] has similar info */
+	{ 4,	"span.htmlsrc_comment" },
+	{ 4,	"span.htmlsrc_tag" },
+	{ 4,	"span.htmlsrc_attrib" },
+	{ 4,	"span.htmlsrc_attrval" },
+	{ 4,	"span.htmlsrc_abracket" },
+	{ 4,	"span.htmlsrc_entity" },
+	{ 4,	"span.htmlsrc_href" },
+	{ 4,	"span.htmlsrc_entire" },
+	{ 4,	"span.htmlsrc_badseq" },
+	{ 4,	"span.htmlsrc_badtag" },
+	{ 4,	"span.htmlsrc_badattr" },
+	{ 4,	"span.htmlsrc_sgmlspecial" },
+#endif
     };
+    /* *INDENT-ON* */
+
     unsigned n;
-    char temp[80];
+    char *normal = LYgetTableString(0);
+    char *strong = LYgetTableString(4);
 
-    CTRACE((tfp, "initialize_default_stylesheet\n"));
-    for (n = 0; n < TABLESIZE(table); n++) {
-	parse_style(strcpy(temp, table[n]));
+    CTRACE((tfp, "initialise_default_stylesheet\n"));
+
+    /*
+     * For debugging this function, create hash codes for all of the tags.
+     * That makes it simpler to find the cases that are overlooked in the
+     * table.
+     */
+    for (n = 0; n < (unsigned) HTML_dtd.number_of_tags; ++n) {
+	char *name = 0;
+
+	HTSprintf0(&name, "%s:%s", HTML_dtd.tags[n].name, normal);
+	parse_style(name);
+	FREE(name);
+    }
+
+    for (n = 0; n < TABLESIZE(table2); ++n) {
+	int code = table2[n].color;
+	char *name = 0;
+	char *value = 0;
+
+	switch (code) {
+	case 0:
+	    value = normal;
+	    break;
+	case 4:
+	    value = strong;
+	    break;
+	default:
+	    value = LYgetTableString(code);
+	    break;
+	}
+	HTSprintf0(&name, "%s:%s", table2[n].type, value);
+	parse_style(name);
+	FREE(name);
+	if (value != normal && value != strong && value != 0)
+	    free(value);
     }
+    FREE(normal);
+    FREE(strong);
 }
 
 /* Set all the buckets in the hash table to be empty */
@@ -444,7 +529,6 @@ void parse_userstyles(void)
     colorPairs = 0;
     style_initialiseHashTable();
 
-    /* set our styles to be the same as vanilla-curses-lynx */
     if (HTList_isEmpty(cur)) {
 	initialise_default_stylesheet();
     } else {
diff --git a/src/LYUtils.c b/src/LYUtils.c
index 10d6442c..61a2a45f 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -1023,6 +1023,9 @@ void LYhighlight(int flag,
 #endif
     tmp[0] = tmp[1] = tmp[2] = '\0';
 
+    CTRACE((tfp, "LYhighlight %s %d:%s\n",
+	    flag ? "on" : "off", cur, NONNULL(target)));
+
     /*
      * Bugs in the history code might cause -1 to be sent for cur, which yields
      * a crash when LYstrncpy() is called with a nonsense pointer.  As far as I
@@ -1442,7 +1445,7 @@ void statusline(const char *text)
 	    LYaddstr(buffer);
 	    wbkgdset(LYwin,
 		     ((lynx_has_color && LYShowColor >= SHOW_COLOR_ON)
-		      ? hashStyles[a].color
+		      ? (chtype) hashStyles[a].color
 		      : A_NORMAL) | ' ');
 	    LYclrtoeol();
 	    if (!(lynx_has_color && LYShowColor >= SHOW_COLOR_ON))
@@ -2706,8 +2709,10 @@ BOOLEAN LYCanReadFile(const char *filename)
 {
     FILE *fp;
 
-    if ((fp = fopen(filename, "r")) != 0) {
-	return LYCloseInput(fp);
+    if (!isEmpty(filename)) {
+	if ((fp = fopen(filename, "r")) != 0) {
+	    return LYCloseInput(fp);
+	}
     }
     return FALSE;
 }
@@ -7505,7 +7510,7 @@ static int clip_grab(void)
     if (!cmd)
 	return 0;
 
-    paste_handle = popen(cmd, "rt");
+    paste_handle = popen(cmd, TXT_R);
     if (!paste_handle)
 	return 0;
     return 1;
@@ -7551,7 +7556,7 @@ int put_clip(const char *s)
     if (!cmd)
 	return -1;
 
-    fh = popen(cmd, "wt");
+    fh = popen(cmd, TXT_W);
     if (!fh)
 	return -1;
     res = fwrite(s, 1, l, fh);
diff --git a/src/LYrcFile.h b/src/LYrcFile.h
index 16db1647..c39d8a37 100644
--- a/src/LYrcFile.h
+++ b/src/LYrcFile.h
@@ -34,6 +34,7 @@
 #define RC_CHMOD_PATH                   "chmod_path"
 #define RC_COLLAPSE_BR_TAGS             "collapse_br_tags"
 #define RC_COLOR                        "color"
+#define RC_COLOR_STYLE                  "color_style"
 #define RC_COMPRESS_PATH                "compress_path"
 #define RC_CONNECT_TIMEOUT              "connect_timeout"
 #define RC_COOKIE_ACCEPT_DOMAINS        "cookie_accept_domains"
diff --git a/src/chrtrans/makeuctb.c b/src/chrtrans/makeuctb.c
index e11cd1fe..9d3d9280 100644
--- a/src/chrtrans/makeuctb.c
+++ b/src/chrtrans/makeuctb.c
@@ -22,6 +22,7 @@
 #define NO_FILIO_H
 #endif
 
+#define DONT_USE_GETTEXT
 #define DONT_USE_SOCKS5
 #include <UCDefs.h>
 #include <UCkd.h>
diff --git a/src/makefile.in b/src/makefile.in
index 36a18ae3..adbd2a04 100644
--- a/src/makefile.in
+++ b/src/makefile.in
@@ -77,7 +77,7 @@ OBJS	= \
 	LYLeaks$o LYexit$o LYJump$o LYList$o LYCgi$o \
 	LYTraversal$o LYEditmap$o LYCharSets$o LYCharUtils$o \
 	LYMap$o LYCookie$o LYStyle$o LYHash$o LYPrettySrc$o \
-	TRSTable$o $(CHARTRANS_OBJS) @LIBOBJS@
+	TRSTable$o $(CHARTRANS_OBJS) @EXTRA_OBJS@ @LIBOBJS@
 
 C_SRC	= $(OBJS:$o=.c)