diff options
Diffstat (limited to 'src')
54 files changed, 5088 insertions, 1105 deletions
diff --git a/src/GridText.c b/src/GridText.c index 069da98e..6b89dc21 100644 --- a/src/GridText.c +++ b/src/GridText.c @@ -1,4 +1,4 @@ -/* +/* Character grid hypertext object ** =============================== */ @@ -32,6 +32,7 @@ #include <LYEdit.h> #include <LYPrint.h> #include <LYPrettySrc.h> +#include <TRSTable.h> #ifdef EXP_CHARTRANS_AUTOSWITCH #include <UCAuto.h> #endif /* EXP_CHARTRANS_AUTOSWITCH */ @@ -91,6 +92,8 @@ struct _HTStream { /* only know it as object */ #define TITLE_LINES 1 #define IS_UTF_EXTRA(ch) (text->T.output_utf8 && \ ((unsigned char)(ch)&0xc0) == 0x80) +#define UTF8_XNEGLEN(c) (c&0xC0? 0 :c&32? 1 :c&16? 2 :c&8? 3 :c&4? 4 :c&2? 5:0) +#define UTF_XLEN(c) UTF8_XNEGLEN(((char)~(c))) extern BOOL HTPassHighCtrlRaw; extern HTCJKlang HTCJK; @@ -191,7 +194,7 @@ typedef struct _HTTabID { /* Notes on struct _Htext: -** next_line is valid if state is false. +** next_line is valid if stale is false. ** top_of_screen line means the line at the top of the screen ** or just under the title if there is one. */ @@ -219,6 +222,7 @@ struct _HText { int chars; /* Number of them */ TextAnchor * first_anchor; /* Singly linked list */ TextAnchor * last_anchor; + TextAnchor * last_anchor_before_stbl; HTList * forms; /* also linked internally */ int last_anchor_number; /* user number */ BOOL source; /* Is the text source? */ @@ -240,10 +244,12 @@ struct _HText { BOOL in_line_1; /* of paragraph */ BOOL stale; /* Must refresh */ BOOL page_has_target; /* has target on screen */ + BOOL has_utf8; /* has utf-8 on screen or line */ #ifdef DISP_PARTIAL int first_lineno_last_disp_partial; int last_lineno_last_disp_partial; #endif + STable_info * stbl; HTkcode kcode; /* Kanji code? */ enum grid_state { S_text, S_esc, S_dollar, S_paren, @@ -350,6 +356,8 @@ PRIVATE char underscore_string[MAX_LINE + 1]; PUBLIC char star_string[MAX_LINE + 1]; PRIVATE int ctrl_chars_on_this_line = 0; /* num of ctrl chars in current line */ +PRIVATE int utfxtra_on_this_line = 0; /* num of UTF-8 extra bytes in line, + they *also* count as ctrl chars. */ PRIVATE HTStyle default_style = { 0, "(Unstyled)", "", @@ -883,18 +891,36 @@ PUBLIC void HText_free ARGS1( /* Output a line ** ------------- */ -PRIVATE int display_line ARGS2( +PRIVATE int display_line ARGS4( HTLine *, line, - HText *, text) + HText *, text, + int, scrline GCC_UNUSED, + CONST char*, target) { register int i, j; char buffer[7]; char *data; size_t utf_extra = 0; + char LastDisplayChar = ' '; #ifdef USE_COLOR_STYLE int current_style = 0; +#define inunderline NO +#define inbold NO +#else + BOOL inbold=NO, inunderline=NO; +#endif +#if defined(SHOW_WHEREIS_TARGETS) && !defined(USE_COLOR_STYLE) + CONST char *cp_tgt; + int i_start_tgt=0, i_after_tgt; + int HitOffset, LenNeeded; + BOOL intarget=NO; +#else +#define intarget NO +#endif /* SHOW_WHEREIS_TARGETS && !USE_COLOR_STYLE */ + +#ifndef NCURSES_VERSION + text->has_utf8 = NO; /* use as per-line flag, except with ncurses */ #endif - char LastDisplayChar = ' '; /* * Set up the multibyte character buffer, @@ -930,7 +956,75 @@ PRIVATE int display_line ARGS2( */ data = line->data; i++; + +#ifndef USE_COLOR_STYLE +#if defined(SHOW_WHEREIS_TARGETS) + /* + * If the target is on this line, it will be emphasized. + */ + i_after_tgt = i; + if (target) { + if (case_sensitive) + cp_tgt = LYno_attr_mbcs_strstr(data, + target, + text->T.output_utf8, + &HitOffset, + &LenNeeded); + else + cp_tgt = LYno_attr_mbcs_case_strstr(data, + target, + text->T.output_utf8, + &HitOffset, + &LenNeeded); + if (cp_tgt) { + if (((int)line->offset + LenNeeded) >= LYcols) { + cp_tgt = NULL; + } else { + text->page_has_target = YES; + i_start_tgt = i + HitOffset; + i_after_tgt = i + LenNeeded; + } + } + } else { + cp_tgt = NULL; + } +#endif /* SHOW_WHEREIS_TARGETS */ +#endif /* USE_COLOR_STYLE */ + while ((i < LYcols) && ((buffer[0] = *data) != '\0')) { + +#ifndef USE_COLOR_STYLE +#if defined(SHOW_WHEREIS_TARGETS) + if (cp_tgt && i >= i_after_tgt) { + if (intarget) { + + if (case_sensitive) + cp_tgt = LYno_attr_mbcs_strstr(data, + target, + text->T.output_utf8, + &HitOffset, + &LenNeeded); + else + cp_tgt = LYno_attr_mbcs_case_strstr(data, + target, + text->T.output_utf8, + &HitOffset, + &LenNeeded); + if (cp_tgt) { + i_start_tgt = i + HitOffset; + i_after_tgt = i + LenNeeded; + } + if (!cp_tgt || i_start_tgt != i) { + LYstopTargetEmphasis(); + intarget = NO; + if (inbold) start_bold(); + if (inunderline) start_underline(); + } + } + } +#endif /* SHOW_WHEREIS_TARGETS */ +#endif /* USE_COLOR_STYLE */ + data++; #if defined(USE_COLOR_STYLE) || defined(SLSC) @@ -951,14 +1045,17 @@ PRIVATE int display_line ARGS2( addch('_'); i++; } else { + inunderline = YES; + if (!intarget) { #if (defined(DOSPATH) || defined(WIN_EX)) && !defined(USE_SLANG) - if (LYShowColor == SHOW_COLOR_NEVER) - start_bold(); - else - start_underline(); + if (LYShowColor == SHOW_COLOR_NEVER) + start_bold(); + else + start_underline(); #else - start_underline(); + start_underline(); #endif /* DOSPATH ... */ + } } break; @@ -967,6 +1064,8 @@ PRIVATE int display_line ARGS2( addch('_'); i++; } else { + inunderline = NO; + if (!intarget) { #if (defined(DOSPATH) || defined(WIN_EX)) && !defined(USE_SLANG) if (LYShowColor == SHOW_COLOR_NEVER) stop_bold(); @@ -975,15 +1074,20 @@ PRIVATE int display_line ARGS2( #else stop_underline(); #endif /* DOSPATH ... */ + } } break; case LY_BOLD_START_CHAR: - start_bold(); + inbold = YES; + if (!intarget) + start_bold(); break; case LY_BOLD_END_CHAR: - stop_bold (); + inbold = NO; + if (!intarget) + stop_bold(); break; #endif @@ -1014,12 +1118,25 @@ PRIVATE int display_line ARGS2( * Make it a hard hyphen and fall through. - FM */ buffer[0] = '-'; - i++; } default: +#ifndef USE_COLOR_STYLE +#if defined(SHOW_WHEREIS_TARGETS) + if (!intarget && cp_tgt && i >= i_start_tgt) { + /* + * Start the emphasis. + */ + if (data > cp_tgt) { + LYstartTargetEmphasis(); + intarget = YES; + } + } +#endif /* SHOW_WHEREIS_TARGETS */ +#endif /* USE_COLOR_STYLE */ i++; if (text->T.output_utf8 && !isascii(buffer[0])) { + text->has_utf8 = YES; if ((*buffer & 0xe0) == 0xc0) { utf_extra = 1; } else if ((*buffer & 0xf0) == 0xe0) { @@ -1057,6 +1174,7 @@ PRIVATE int display_line ARGS2( */ buffer[1] = *data; data++; + i++; addstr(buffer); buffer[1] = '\0'; /* @@ -1072,17 +1190,42 @@ PRIVATE int display_line ARGS2( */ LastDisplayChar = 'M'; } else { +#if 0 /* last-ditch attempt to prevent 0x9B to screen - disabled */ +#if defined(UNIX) || defined(VMS) + if (!dump_output_immediately && + (unsigned char)buffer[0] == 128+27) { + addstr("~^"); + buffer[0] ^= 0xc0; + } +#endif +#endif addstr(buffer); LastDisplayChar = buffer[0]; } } /* end of switch */ } /* end of while */ +#if !defined(NCURSES_VERSION) + if (text->has_utf8) { +#ifdef USE_SLANG + SLsmg_touch_lines(scrline, 1); +#else + touchline(stdscr, scrline, 1); +#endif + text->has_utf8 = NO; /* we had some, but have dealt with it. */ + } +#endif /* * Add the return. */ addch('\n'); +#if defined(SHOW_WHEREIS_TARGETS) && !defined(USE_COLOR_STYLE) + if (intarget) + LYstopTargetEmphasis(); +#else +#undef intarget +#endif /* SHOW_WHEREIS_TARGETS && !USE_COLOR_STYLE */ #ifndef USE_COLOR_STYLE stop_underline(); stop_bold(); @@ -1258,63 +1401,45 @@ PRIVATE void display_scrollbar ARGS1( int i; int h = display_lines - 2 * (LYsb_arrow!=0); /* Height of the scrollbar */ int off = (LYsb_arrow != 0); /* Start of the scrollbar */ - int top_skip, bot_skip, sh; + int top_skip, bot_skip, sh, shown; LYsb_begin = LYsb_end = -1; if (!LYsb || !text || h <= 2 || (text->Lines + 1) <= display_lines) return; + if (text->top_of_screen >= text->Lines + 1 - display_lines) { + /* Only part of the screen shows actual text */ + shown = text->Lines + 1 - text->top_of_screen; + + if (shown <= 0) + shown = 1; + } else + shown = display_lines; /* Each cell of scrollbar represents text->Lines/h lines of text. */ /* Always smaller than h */ - sh = (display_lines*h + text->Lines/2)/(text->Lines + 1); + sh = (shown*h + text->Lines/2)/(text->Lines + 1); if (sh <= 0) sh = 1; - if (sh >= h) - sh = h - 1; - - /* Always non-zero if not top, which is text->top_of_screen != 0 . */ - top_skip = (text->top_of_screen * h + text->Lines)/(text->Lines + 1); - if (top_skip >= h) - top_skip = h - 1; - - /* End happens when - (text->Lines + 1 - (text->top_of_screen + display_lines - 1)) - is either 0 or 1. */ - bot_skip = - (text->Lines + 1 - (text->top_of_screen + display_lines - 1) - 1); - if (bot_skip < 0) - bot_skip = 0; - bot_skip = (bot_skip * h + text->Lines)/(text->Lines + 1); - - /* Now make sure the height is always sh unless top_skip==bot_skip==1 */ - if (top_skip + bot_skip + sh != h && !(top_skip == 1 && bot_skip == 1)) { - /* One which is smaller takes precedence. */ - if (top_skip < bot_skip) { - int t = h - top_skip - sh; - - if (t < top_skip) - bot_skip = top_skip; - else - bot_skip = t; - } else { - int t = h - bot_skip - sh; + if (sh >= h - 1) + sh = h - 2; /* Position at ends indicates BEG and END */ - if (t < bot_skip) - top_skip = bot_skip; - else - top_skip = t; - } - } - /* Ensure the bar is visible if h >= 3 */ - if (top_skip + bot_skip >= h) - bot_skip = h - top_skip; - if (top_skip + bot_skip == h && h >= 3) { - if (bot_skip > 1) - bot_skip--; - else - top_skip--; + if (text->top_of_screen == 0) + top_skip = 0; + else if (text->Lines - (text->top_of_screen + display_lines - 1) <= 0) + top_skip = h - sh; + else { + /* text->top_of_screen between 1 and text->Lines - display_lines + corresponds to top_skip between 1 and h - sh - 1 */ + /* Use rounding to get as many positions into top_skip==h - sh - 1 + as into top_skip == 1: + 1--->1, text->Lines - display_lines + 1--->h - sh. */ + top_skip = 1 + + 1. * (h - sh - 1) * text->top_of_screen + /(text->Lines - display_lines + 1); } + bot_skip = h - sh - top_skip; + LYsb_begin = top_skip; LYsb_end = h - bot_skip; @@ -1391,12 +1516,13 @@ PRIVATE void display_page ARGS3( { HTLine * line = NULL; int i; -#if defined(FANCY_CURSES) || defined(USE_SLANG) +#if defined(USE_COLOR_STYLE) && defined(SHOW_WHEREIS_TARGETS) char *cp; #endif char tmp[7]; int last_screen; TextAnchor *Anchor_ptr = NULL; + int stop_before_for_anchors; FormInfo *FormInfo_ptr; BOOL display_flag = FALSE; HTAnchor *link_dest; @@ -1435,6 +1561,7 @@ PRIVATE void display_page ARGS3( #endif /* DISP_PARTIAL */ tmp[0] = tmp[1] = tmp[2] = '\0'; + if (target && *target == '\0') target = NULL; text->page_has_target = NO; if (display_lines <= 0) { /* No screen space to display anything! @@ -1522,6 +1649,7 @@ PRIVATE void display_page ARGS3( #endif text->top_of_screen = line_number; + text->top_of_screen_line = line; display_title(text); /* will move cursor to top of screen */ display_flag=TRUE; @@ -1534,11 +1662,20 @@ PRIVATE void display_page ARGS3( LynxResetScreenCache(); #endif /* USE_COLOR_STYLE */ +#ifdef DISP_PARTIAL + if (display_partial && text->stbl) { + stop_before_for_anchors = Stbl_getStartLine(text->stbl); + if (stop_before_for_anchors > line_number+(display_lines)) + stop_before_for_anchors = line_number+(display_lines); + } else +#endif + stop_before_for_anchors = line_number+(display_lines); + /* * Output the page. */ if (line) { -#if defined(FANCY_CURSES) || defined(USE_SLANG) +#if defined(USE_COLOR_STYLE) && defined(SHOW_WHEREIS_TARGETS) char *data; int offset, HitOffset, LenNeeded; #endif @@ -1571,9 +1708,10 @@ PRIVATE void display_page ARGS3( move((i + 2), 0); else #endif - display_line(line, text); + display_line(line, text, i+1, target); -#if defined(FANCY_CURSES) || defined(USE_SLANG) +#if defined(SHOW_WHEREIS_TARGETS) +#ifdef USE_COLOR_STYLE /* otherwise done in display_line - kw */ /* * If the target is on this line, recursively * seek and emphasize it. - FM @@ -1619,59 +1757,15 @@ PRIVATE void display_page ARGS3( */ x_pos--; - } else if (cp == &data[itmp]) { - /* - * First printable character of target. - */ - move((i + 1), x_pos); - if (text->T.output_utf8 && !isascii(tmp[0])) { - if ((*tmp & 0xe0) == 0xc0) { - utf_extra = 1; - } else if ((*tmp & 0xf0) == 0xe0) { - utf_extra = 2; - } else if ((*tmp & 0xf8) == 0xf0) { - utf_extra = 3; - } else if ((*tmp & 0xfc) == 0xf8) { - utf_extra = 4; - } else if ((*tmp & 0xfe) == 0xfc) { - utf_extra = 5; - } else { - /* - * Garbage. - */ - utf_extra = 0; - } - if (strlen(&line->data[itmp+1]) < utf_extra) { - /* - * Shouldn't happen. - */ - utf_extra = 0; - } - } - if (utf_extra) { - strncpy(&tmp[1], &line->data[itmp+1], utf_extra); - tmp[utf_extra+1] = '\0'; - itmp += utf_extra; - addstr(tmp); - tmp[1] = '\0'; - written += (utf_extra + 1); - utf_extra = 0; - } else if (HTCJK != NOCJK && !isascii(tmp[0])) { + } else if (&data[itmp] >= cp) { + if (cp == &data[itmp]) { /* - * For CJK strings, by Masanobu Kimura. + * First printable character of target. */ - tmp[1] = data[++itmp]; - addstr(tmp); - tmp[1] = '\0'; - written += 2; - } else { - addstr(tmp); - written++; + move((i + 1), x_pos); } - - } else if (&data[itmp] > cp) { /* - * Output all the other printable target chars. + * Output all the printable target chars. */ if (text->T.output_utf8 && !isascii(tmp[0])) { if ((*tmp & 0xe0) == 0xc0) { @@ -1714,6 +1808,15 @@ PRIVATE void display_page ARGS3( tmp[1] = '\0'; written += 2; } else { +#if 0 /* last-ditch attempt to prevent 0x9B to screen - disabled */ +#if defined(UNIX) || defined(VMS) + if (!dump_output_immediately && + (unsigned char)tmp[0] == 128+27) { + addstr("~^"); + tmp[0] ^= 0xc0; + } +#endif +#endif addstr(tmp); written++; } @@ -1736,7 +1839,8 @@ PRIVATE void display_page ARGS3( */ move((i + 2), 0); } /* end while */ -#endif /* FANCY CURSES || USE_SLANG */ +#endif /* USE_COLOR_STYLE */ +#endif /* SHOW_WHEREIS_TARGETS */ /* * Stop if this is the last line. Otherwise, make sure @@ -1774,11 +1878,11 @@ PRIVATE void display_page ARGS3( */ nlinks = 0; for (Anchor_ptr=text->first_anchor; Anchor_ptr != NULL && - Anchor_ptr->line_num <= line_number+(display_lines); + Anchor_ptr->line_num <= stop_before_for_anchors; Anchor_ptr = Anchor_ptr->next) { if (Anchor_ptr->line_num >= line_number && - Anchor_ptr->line_num < line_number+(display_lines)) { + Anchor_ptr->line_num < stop_before_for_anchors) { /* * Load normal hypertext anchors. */ @@ -1968,11 +2072,19 @@ PRIVATE void display_page ARGS3( } #endif /* DISP_PARTIAL */ - if (HTCJK != NOCJK) { + if (text->has_utf8) { + /* + * For other than ncurses, repainting is taken care of + * by touching lines in display_line and highlight. - kw 1999-10-07 + */ + clearok(curscr, TRUE); + } else if (HTCJK != NOCJK) { /* * For non-multibyte curses. + * + * Is this repainting necessary?? Let's try without. */ - lynx_force_repaint(); + /*clearok(curscr, TRUE);*/ } refresh(); @@ -1993,6 +2105,17 @@ PUBLIC void HText_beginAppend ARGS1( } +/* LYcols_cu is the notion that the display library has of the screen + width. Normally it is the same as LYcols, but there may be a + difference via SLANG_MBCS_HACK. LYcols_cu is used to try to prevent + that the display library wraps or truncates a line with UTF-8 chars + when it shouldn't. - kw */ +#ifdef USE_SLANG +#define LYcols_cu SLtt_Screen_Cols +#else +#define LYcols_cu LYcols +#endif + /* Add a new line of text ** ---------------------- ** @@ -2037,6 +2160,7 @@ PRIVATE void split_line ARGS2( */ HTLine * previous = text->last_line; int ctrl_chars_on_previous_line = 0; + int utfxtra_on_previous_line = utfxtra_on_this_line; char * cp; /* can't wrap in middle of multibyte sequences, so allocate 2 extra */ HTLine * line = (HTLine *)LY_CALLOC(1, LINE_SIZE(MAX_LINE)+2); @@ -2044,6 +2168,7 @@ PRIVATE void split_line ARGS2( outofmem(__FILE__, "split_line_1"); ctrl_chars_on_this_line = 0; /*reset since we are going to a new line*/ + utfxtra_on_this_line = 0; /*reset too, we'll count them*/ text->LastChar = ' '; #ifdef DEBUG_APPCH @@ -2218,14 +2343,16 @@ PRIVATE void split_line ARGS2( for (i = (plen - 1); i >= 0; i--) { if (p[i] == LY_BOLD_START_CHAR || p[i] == LY_BOLD_END_CHAR || - IS_UTF_EXTRA(p[i]) || p[i] == LY_SOFT_HYPHEN) { ctrl_chars_on_this_line++; + } else if (IS_UTF_EXTRA(p[i])) { + utfxtra_on_this_line++; } if (p[i] == LY_SOFT_HYPHEN && (int)text->permissible_split < i) { text->permissible_split = i + 1; } } + ctrl_chars_on_this_line += utfxtra_on_this_line; } /* @@ -2450,13 +2577,12 @@ PRIVATE void split_line ARGS2( * Align left, right or center. */ spare = 0; - ctrl_chars_on_previous_line = 0; /* - VH */ if ( #ifdef EXP_JUSTIFY_ELTS this_line_was_splitted || #endif (style->alignment == HT_CENTER || - style->alignment == HT_RIGHT) ) { + style->alignment == HT_RIGHT) || text->stbl) { /* Calculate spare character positions if needed */ for (cp = previous->data; *cp; cp++) { if (*cp == LY_UNDERLINE_START_CHAR || @@ -2466,17 +2592,56 @@ PRIVATE void split_line ARGS2( IS_UTF_EXTRA(*cp) || *cp == LY_SOFT_HYPHEN) ctrl_chars_on_previous_line++; + if ((previous->size > 0) && + (int)(previous->data[previous->size-1] == LY_SOFT_HYPHEN)) + ctrl_chars_on_previous_line--; } /* @@ first line indent */ spare = (LYcols-1) - (int)style->rightIndent - indent + - ctrl_chars_on_previous_line - previous->size - - ((previous->size > 0) && - (int)(previous->data[previous->size-1] == - LY_SOFT_HYPHEN ? - 1 : 0)); + ctrl_chars_on_previous_line - previous->size; + if (spare > 0 && text->T.output_utf8 && ctrl_chars_on_previous_line) { + utfxtra_on_previous_line -= utfxtra_on_this_line; + if (utfxtra_on_previous_line) { + int spare_cu = (LYcols_cu-1) - + utfxtra_on_previous_line - indent + + ctrl_chars_on_previous_line - previous->size; + /* + * Shift non-leftaligned UTF-8 lines that would be + * mishandled by the display library towards the left + * if this would make them fit. The resulting display + * will not be as intended, but this is better than + * having them split by curses. (But that may still + * happen anyway by curses space movement optimization). + * - kw + */ + if (spare_cu < spare) { + if (spare_cu >= 0) { + spare = spare_cu; + } else if (indent + (int)previous->offset + spare_cu >= 0) + { /* subtract overdraft from effective indentation */ + indent += (int)previous->offset + spare_cu; + previous->offset = 0; + spare = 0; + } + } + } + } } + if (text->stbl) + /* + * Notify simple table stuff of line split, so that it can + * set the last cell's length. The last cell should and + * its row should really end here, or on one of the following + * lines with no more characters added after the break. + * We don't know whether a cell has been started, so ignore + * errors here. - kw + */ + Stbl_lineBreak(text->stbl, + text->Lines - 1, + previous->size - ctrl_chars_on_previous_line); + switch (style->alignment) { case HT_CENTER : previous->offset = previous->offset + indent + spare/2; @@ -3014,7 +3179,7 @@ PUBLIC void HText_appendCharacter ARGS2( { HTLine * line; HTStyle * style; - int indent; + int indent, utfx; #ifdef DEBUG_APPCH #ifdef CJK_EX @@ -3141,6 +3306,7 @@ PUBLIC void HText_appendCharacter ARGS2( style = text->style; indent = text->in_line_1 ? (int)style->indent1st : (int)style->leftIndent; + utfx = utfxtra_on_this_line; if (HTCJK != NOCJK) { switch(text->state) { @@ -3293,7 +3459,8 @@ PUBLIC void HText_appendCharacter ARGS2( } #ifdef CJK_EX /* MOJI-BAKE Fix! 1997/10/12 -- 10/31 (Fri) 00:22:57 - JH7AYN */ - if (ch == LY_BOLD_START_CHAR || ch == LY_BOLD_END_CHAR) { + if (HTCJK != NOCJK && /* added condition - kw */ + (ch == LY_BOLD_START_CHAR || ch == LY_BOLD_END_CHAR)) { text->permissible_split = (int)line->size; /* Can split here */ if (HTCJK == JAPANESE) text->kcode = NOKANJI; @@ -3371,11 +3538,66 @@ PUBLIC void HText_appendCharacter ARGS2( return; } - if (IS_UTF_EXTRA(ch)) { - line->data[line->size++] = ch; - line->data[line->size] = '\0'; - ctrl_chars_on_this_line++; - return; + if (text->T.output_utf8) { + if (IS_UTF_EXTRA(ch)) { + if ((line->size > (MAX_LINE-1)) + || (indent + (int)(line->offset + line->size) + + utfx - ctrl_chars_on_this_line + + ((line->size > 0) && + (int)(line->data[line->size-1] == + LY_SOFT_HYPHEN ? + 1 : 0)) >= (LYcols_cu-1)) + ) { + if (!text->permissible_split || text->source) { + text->permissible_split = line->size; + while (text->permissible_split > 0 && + IS_UTF_EXTRA(line->data[text->permissible_split-1])) + text->permissible_split--; + if (text->permissible_split && + (line->data[text->permissible_split-1] & 0x80)) + text->permissible_split--; + if (text->permissible_split == line->size) + text->permissible_split = 0; + } + split_line(text, text->permissible_split); + line = text->last_line; + if (text->source && line->size - ctrl_chars_on_this_line + + utfxtra_on_this_line == 0) + HText_appendCharacter (text, LY_SOFT_NEWLINE); + } + line->data[line->size++] = ch; + line->data[line->size] = '\0'; + utfxtra_on_this_line++; + ctrl_chars_on_this_line++; + return; + } else if (ch & 0x80) { + if ((line->size > (MAX_LINE-7)) +#if 0 /* the equivalent should already happen below */ + || (indent + (int)(line->offset + line->size) + + utfx - ctrl_chars_on_this_line + + ((line->size > 0) && + (int)(line->data[line->size-1] == + LY_SOFT_HYPHEN ? + 1 : 0)) >= (LYcols_cu)) +#endif /* 0 */ + ) { + if (!text->permissible_split || text->source) { + text->permissible_split = line->size; + while (text->permissible_split > 0 && + (line->data[text->permissible_split-1] & 0x80) + == 0xC0) { + text->permissible_split--; + } + if (text->permissible_split == line->size) + text->permissible_split = 0; + } + split_line(text, text->permissible_split); + line = text->last_line; + if (text->source && line->size - ctrl_chars_on_this_line + + utfxtra_on_this_line == 0) + HText_appendCharacter (text, LY_SOFT_NEWLINE); + } + } } /* @@ -3432,8 +3654,8 @@ PUBLIC void HText_appendCharacter ARGS2( */ if (ch == '\t') { CONST HTTabStop * Tab; - int target; /* Where to tab to */ - int here; + int target, target_cu; /* Where to tab to */ + int here, here_cu; /* in _cu we try to guess what curses thinks */ if (line->size > 0 && line->data[line->size-1] == LY_SOFT_HYPHEN) { /* @@ -3445,6 +3667,7 @@ PUBLIC void HText_appendCharacter ARGS2( } here = ((int)(line->size + line->offset) + indent) - ctrl_chars_on_this_line; /* Consider special chars GAB */ + here_cu = here + utfxtra_on_this_line; if (style->tabs) { /* Use tab table */ for (Tab = style->tabs; Tab->position <= here; @@ -3472,6 +3695,11 @@ PUBLIC void HText_appendCharacter ARGS2( #endif } + if (target >= here) + target_cu = target; + else + target_cu = target + (here_cu - here); + if (target > (LYcols-1) - (int)style->rightIndent && HTOutputFormat != WWW_SOURCE) { new_line(text); @@ -3480,6 +3708,8 @@ PUBLIC void HText_appendCharacter ARGS2( * Can split here. - FM */ text->permissible_split = line->size; + if (target_cu > (LYcols-1)) + target -= target_cu - (LYcols-1); if (line->size == 0) { line->offset = line->offset + target - here; } else { @@ -3492,14 +3722,17 @@ PUBLIC void HText_appendCharacter ARGS2( } return; } /* if tab */ - else { + else if (text->source && text == HTMainText) { /* * If we're displaying document source, wrap long lines to keep all of * the source visible. */ int target = (int)(line->offset + line->size) - ctrl_chars_on_this_line; - if ((target >= (LYcols-1) - style->rightIndent) && - HTisDocumentSource()) { + int target_cu = target + utfxtra_on_this_line; + if (target >= (LYcols-1) - style->rightIndent || + (text->T.output_utf8 && + target_cu + UTF_XLEN(ch) >= (LYcols_cu-1)) + ) { new_line(text); line = text->last_line; HText_appendCharacter (text, LY_SOFT_NEWLINE); @@ -3524,8 +3757,10 @@ PUBLIC void HText_appendCharacter ARGS2( */ check_IgnoreExcess: if (text->IgnoreExcess && - ((indent + (int)line->offset + (int)line->size) + - (int)style->rightIndent - ctrl_chars_on_this_line) >= (LYcols-1)) + (((indent + (int)line->offset + (int)line->size) + + (int)style->rightIndent - ctrl_chars_on_this_line) >= (LYcols-1) || + ((indent + (int)line->offset + (int)line->size) + + utfxtra_on_this_line - ctrl_chars_on_this_line) >= (LYcols_cu-1))) return; /* @@ -3536,7 +3771,15 @@ check_IgnoreExcess: ((line->size > 0) && (int)(line->data[line->size-1] == LY_SOFT_HYPHEN ? - 1 : 0))) >= (LYcols - 1)) { + 1 : 0))) >= (LYcols - 1) || + (text->T.output_utf8 && + (((indent + (int)line->offset + (int)line->size) + + utfxtra_on_this_line - ctrl_chars_on_this_line + + UTF_XLEN(ch) + + ((line->size > 0) && + (int)(line->data[line->size-1] == + LY_SOFT_HYPHEN ? + 1 : 0))) >= (LYcols_cu - 1)))) { if (style->wordWrap && HTOutputFormat != WWW_SOURCE) { #ifdef EXP_JUSTIFY_ELTS @@ -3746,8 +3989,26 @@ PUBLIC void _internal_HTC ARGS3(HText *,text, int,style, int,dir) line = text->last_line; - if (line->numstyles < MAX_STYLES_ON_LINE) { + if (line->numstyles > 0 && dir == 0 && + line->styles[line->numstyles].direction && + line->styles[line->numstyles].style == style && + line->styles[line->numstyles].horizpos + == (int)line->size - ctrl_chars_on_this_line) { + /* + * If this is an OFF change directly preceded by an + * ON for the same style, just remove the previous one. - kw + */ + line->numstyles--; + } else if (line->numstyles < MAX_STYLES_ON_LINE) { line->styles[line->numstyles].horizpos = line->size; + /* + * Special chars for bold and underlining usually don't + * occur with color style, but soft hyphen can. + * And in UTF-8 display mode all non-initial bytes are + * counted as ctrl_chars. - kw + */ + if (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++; @@ -3796,6 +4057,475 @@ PUBLIC void HText_setIgnoreExcess ARGS2( text->IgnoreExcess = ignore; } +/* Simple table handling - private +** ------------------------------- +*/ + +/* + * Given a line and two int arrays of old/now position, this function + * does the actual work of creating a new line where spaces have been + * inserted in appropriate places - so that characters at/after the old + * position end up at/after the new position, for each pair, if possible. + * Some necessary changes for anchors starting on this line are also done + * here if needed. + * Returns a newly allocated HTLine* if changes were made + * (caller has to free the old one). + * Returns NULL if no changes needed. + * - kw + */ +PRIVATE HTLine * insert_blanks_in_line ARGS6( + HTLine *, line, + int, line_number, + HText *, text, + int, ninserts, + int *, oldpos, + int *, newpos) +{ + int i; + int ioldb, inewb; /* count bytes */ + int ioldc = 0, inewc = 0; /* count visible characters (positions) */ + int ip = 0; /* count oldpos,newpos insertion pairs */ + int acurshift, ashift = 0; /* for shifting of anchors in this line */ +#if defined(USE_COLOR_STYLE) + int stcurshift, stshift = 0; /* for shifting of styles in this line */ + int istyle; +#endif + int added_chars = 0; + HTLine * mod_line; + char * newdata; + TextAnchor * a; + if (!(line && line->size && ninserts)) + return NULL; + for (i = 0; i < ninserts; i++) + if (newpos[i] > oldpos[i] && + (newpos[i] - oldpos[i]) > added_chars) + added_chars = newpos[i] - oldpos[i]; + if (line->size + added_chars > MAX_LINE - 2) + return NULL; + if (line == text->last_line) + mod_line = (HTLine *) calloc(1, LINE_SIZE(MAX_LINE)); + else + mod_line = (HTLine *) calloc(1, LINE_SIZE(line->size + added_chars)); + if (!mod_line) + return NULL; + memcpy(mod_line, line, LINE_SIZE(1)); + newdata = mod_line->data; + for (ioldb = 0, inewb = 0; ioldb < (int)line->size; ioldb++) { + if ((line->data[ioldb] == LY_BOLD_START_CHAR || + line->data[ioldb] == LY_UNDERLINE_START_CHAR || + !IsSpecialAttrChar(line->data[ioldb])) && + (!(text && text->T.output_utf8) || + (unsigned char)line->data[ioldb] < 128 || + ((unsigned char)(line->data[ioldb] & 0xc0) == 0xc0))) { + /* + * A new displayable character starts here. Time to check + * whether this is a position to insert spaces. + */ + while (ip < ninserts && oldpos[ip] <= ioldc) { + if (inewc < newpos[ip]) { + /* + * Yup, spaces to insert. We also have to update + * anchor positions for anchors that start on the + * same line, this is a pain. Let's do it first. + * Note: we rely on a->line_pos counting bytes, not + * characters. That's one reason why HText_trimHightext + * has to be prevented from acting on these anchors in + * partial display mode before we get a chance to + * deal with them here. + */ + acurshift = 0; + for (a = text->last_anchor_before_stbl ? + text->last_anchor_before_stbl->next : + text->first_anchor; + a && a->line_num <= line_number; a = a->next) { + if (a->line_num == line_number) + if (a->line_pos - ashift >= ioldb) { + acurshift = newpos[ip] - inewc; + a->line_pos += acurshift; + a->start += acurshift; + } + } + ashift += acurshift; + + /* doing something for color styles here. + * we rely on horizpos counting characters + * (display positions), not bytes. */ +#if defined(USE_COLOR_STYLE) +#define NStyle mod_line->styles[istyle] + stcurshift = 0; + for (istyle = 0; istyle < line->numstyles; + istyle++) { + if (NStyle.horizpos - stshift >= ioldc) { + stcurshift = newpos[ip] - inewc; + NStyle.horizpos += stcurshift; + } + } + stshift += stcurshift; +#endif + /* + * Now insert the spaces. + */ + for (; inewc < newpos[ip]; inewc++) { + newdata[inewb++] = ' '; + } + } + ip++; /* done with this oldpos[ip],newpos[ip] pair. */ + } + /* + * Copy character data over, advance position pointers. + */ + newdata[inewb++] = line->data[ioldb]; + if (!(line->data[ioldb] == LY_BOLD_START_CHAR || + line->data[ioldb] == LY_UNDERLINE_START_CHAR)) { + ioldc++; + inewc++; + } + } else { + /* + * Just copy special attribute chars and utf-8 additional + * bytes over, don't advance position pointers. + */ + newdata[inewb++] = line->data[ioldb]; + } + } + newdata[inewb] = '\0'; + mod_line->size = inewb; + return mod_line; +} + +/* + * HText_insertBlanksInStblLines fixes up table lines when simple table + * processing is closed, by calling insert_blanks_in_line for lines + * that need fixup. Also recalculates alignment for those lines, + * does additional updating of anchor positions, and makes sure the + * display of the lines on screen will be updated after partial display + * upon return to mainloop. - kw + */ +PRIVATE int HText_insertBlanksInStblLines ARGS2( + HText *, me, + int, ncols) +{ + HTLine *line; + HTLine *mod_line, *first_line = NULL; + int * oldpos; + int * newpos; + int ninserts, lineno; + int first_lineno, last_lineno, first_lineno_pass2; + int added_chars_before = 0; + TextAnchor * a; + int lines_changed = 0; + int max_width = 0, indent, spare, table_offset; + HTStyle *style; + short alignment; + int i = 0; + + lineno = first_lineno = Stbl_getStartLine(me->stbl); + if (lineno < 0 || lineno > me->Lines) + return -1; + /* + * oldpos, newpos: allocate space for two int arrays. + */ + oldpos = (int *) calloc(2 * ncols, sizeof(int)); + if (!oldpos) + return -1; + else + newpos = oldpos + ncols; + for (line = me->last_line->next; i < lineno; line = line->next, i++) { + if (!line) { + free(oldpos); + return -1; + } + } + first_lineno_pass2 = last_lineno = me->Lines; + for (; line && lineno <= last_lineno; line = line->next, lineno++) { + if (added_chars_before) { + for (a = me->last_anchor_before_stbl ? + me->last_anchor_before_stbl->next : me->first_anchor; + a && a->line_num <= lineno; a = a->next) { + if (a->line_num == lineno) + a->start += added_chars_before; + } + } + ninserts = Stbl_getFixupPositions(me->stbl, lineno, oldpos, newpos); + if (ninserts < 0) + continue; + if (!first_line) { + first_line = line; + first_lineno_pass2 = lineno; + if (TRACE) { + int ip; + CTRACE((tfp, "line %d first to adjust -- newpos:", + lineno)); + for (ip = 0; ip < ncols; ip++) + fprintf(tfp, " %d", newpos[ip]); + fprintf(tfp, "\r\n"); + } + } + if (line == me->last_line) { + if (line->size == 0 || !HText_TrueLineSize(line, me, FALSE)) + continue; + /* + * Last ditch effort to end the table with a line break, + * if HTML_end_element didn't do it. - kw + */ + if (first_line == line) /* obscure: all table on last line... */ + first_line = NULL; + new_line(me); + line = me->last_line->prev; + if (first_line == NULL) + first_line = line; + } + if (ninserts == 0) { + /* Do it also for no positions (but not error) */ + int width = HText_TrueLineSize(line, me, FALSE); + if (width > max_width) + max_width = width; + CTRACE((tfp, "line %d true/max width:%d/%d oldpos: NONE\r\n", + lineno, width, max_width)); + continue; + } + mod_line = insert_blanks_in_line(line, lineno, me, + ninserts, oldpos, newpos); + if (mod_line) { + if (line == me->last_line) { + me->last_line = mod_line; + } else { + me->chars += (mod_line->size - line->size); + added_chars_before += (mod_line->size - line->size); + } + line->prev->next = mod_line; + line->next->prev = mod_line; + lines_changed++; + if (line == first_line) + first_line = mod_line; + free(line); + line = mod_line; +#ifdef DISP_PARTIAL + /* + * Make sure modified lines get fully re-displayed after + * loading with partial display is done. + */ + if (me->first_lineno_last_disp_partial >= 0) { + if (me->first_lineno_last_disp_partial >= lineno) { + me->first_lineno_last_disp_partial = + me->last_lineno_last_disp_partial = -1; + } else if (me->last_lineno_last_disp_partial >= lineno) { + me->last_lineno_last_disp_partial = lineno - 1; + } + } +#endif + } + { + int width = HText_TrueLineSize(line, me, FALSE); + if (width > max_width) + max_width = width; + if (TRACE) { + int ip; + CTRACE((tfp, "line %d true/max width:%d/%d oldpos:", + lineno, width, max_width)); + for (ip = 0; ip < ninserts; ip++) + fprintf(tfp, " %d", oldpos[ip]); + fprintf(tfp, "\r\n"); + } + } + } + /* + * Line offsets have been set based on the paragraph style, and + * have already been updated for centering or right-alignment + * for each line in split_line. Here we want to undo all that, and + * align the table as a whole (i.e. all lines for which + * Stbl_getFixupPositions returned >= 0). All those lines have to + * get the same offset, for the simple table formatting mechanism + * to make sense, and that may not actually be the case at this point. + * + * What indentation and alignment do we want for the table as + * a whole? Let's take most style properties from me->style. + * With some luck, it is the appropriate style for the element + * enclosing the TABLE. But let's take alignment from the attribute + * of the TABLE itself instead, if it was specified. + * + * Note that this logic assumes that all lines have been finished + * by split_line. The order of calls made by HTML_end_element for + * HTML_TABLE should take care of this. + */ + style = me->style; + alignment = Stbl_getAlignment(me->stbl); + if (alignment == HT_ALIGN_NONE) + alignment = style->alignment; + indent = style->leftIndent; + /* Calculate spare character positions */ + spare = (LYcols-1) - + (int)style->rightIndent - indent - max_width; + if (spare < 0 && (int)style->rightIndent + spare >= 0) { + /* + * Not enough room! But we can fit if we ignore right indentation, + * so let's do that. + */ + spare = 0; + } else if (spare < 0) { + spare += style->rightIndent; /* ignore right indent, but need more */ + } + if (spare < 0 && indent + spare >= 0) { + /* + * Still not enough room. But we can move to the left. + */ + indent += spare; + spare = 0; + } else if (spare < 0) { + /* + * Still not enough. Something went wrong. Try the best we + * can do. + */ + CTRACE((tfp, "insertBlanks: resulting table too wide by %d positions!", + -spare)); + indent = spare = 0; + } + /* + * Align left, right or center. + */ + switch (alignment) { + case HT_CENTER : + table_offset = indent + spare/2; + break; + case HT_RIGHT : + table_offset = indent + spare; + break; + case HT_LEFT : + case HT_JUSTIFY : + default: + table_offset = indent; + break; + } /* switch */ + + CTRACE((tfp, "changing offsets")); + for (line = first_line, lineno = first_lineno_pass2; + line && lineno <= last_lineno && line != me->last_line; + line = line->next, lineno++) { + ninserts = Stbl_getFixupPositions(me->stbl, lineno, oldpos, newpos); + if (ninserts >= 0 && (int) line->offset != table_offset) { +#ifdef DISP_PARTIAL + /* As above make sure modified lines get fully re-displayed */ + if (me->first_lineno_last_disp_partial >= 0) { + if (me->first_lineno_last_disp_partial >= lineno) { + me->first_lineno_last_disp_partial = + me->last_lineno_last_disp_partial = -1; + } else if (me->last_lineno_last_disp_partial >= lineno) { + me->last_lineno_last_disp_partial = lineno - 1; + } + } +#endif + CTRACE((tfp, " %d:%d", lineno, table_offset - line->offset)); + line->offset = table_offset; + } + } + CTRACE((tfp, " %d:done\r\n", lineno)); + free(oldpos); + return lines_changed; +} + +/* Simple table handling - public functions +** ---------------------------------------- +*/ + +/* Cancel simple table handling +*/ +PUBLIC void HText_cancelStbl ARGS1( + HText *, me) +{ + if (!me || !me->stbl) { + CTRACE((tfp, "cancelStbl: ignored.\n")); + return; + } + CTRACE((tfp, "cancelStbl: ok, will do.\n")); + Stbl_free(me->stbl); + me->stbl = NULL; +} +/* Start simple table handling +*/ +PUBLIC void HText_startStblTABLE ARGS2( + HText *, me, + short, alignment) +{ + if (!me) + return; + if (me->stbl) + HText_cancelStbl(me); /* auto cancel previously open table */ + me->stbl = Stbl_startTABLE(alignment); + if (me->stbl) { + CTRACE((tfp, "startStblTABLE: started.\n")); + me->last_anchor_before_stbl = me->last_anchor; + } else { + CTRACE((tfp, "startStblTABLE: failed.\n")); + } +} +/* Finish simple table handling +*/ +PUBLIC void HText_endStblTABLE ARGS1( + HText *, me) +{ + int ncols, lines_changed = 0; + if (!me || !me->stbl) { + CTRACE((tfp, "endStblTABLE: ignored.\n")); + return; + } + CTRACE((tfp, "endStblTABLE: ok, will try.\n")); + ncols = Stbl_finishTABLE(me->stbl); + CTRACE((tfp, "endStblTABLE: ncols = %d.\n", ncols)); + if (ncols > 0) { + lines_changed = HText_insertBlanksInStblLines(me, ncols); + CTRACE((tfp, "endStblTABLE: changed %d lines, done.\n", lines_changed)); + } + Stbl_free(me->stbl); + me->stbl = NULL; +} +/* Start simple table row +*/ +PUBLIC void HText_startStblTR ARGS2( + HText *, me, + short, alignment) +{ + if (!me || !me->stbl) + return; + if (Stbl_addRowToTable(me->stbl, alignment, me->Lines) < 0) + HText_cancelStbl(me); /* give up */ +} +/* Finish simple table row +*/ +PUBLIC void HText_endStblTR ARGS1( + HText *, me) +{ + if (!me || !me->stbl) + return; + /* should this do something?? */ +} +/* Finish simple table cell +*/ +PUBLIC void HText_startStblTD ARGS4( + HText *, me, + int, colspan, + short, alignment, + BOOL, isheader) +{ + if (!me || !me->stbl) + return; + if (colspan <= 0) + colspan = 1; + if (Stbl_addCellToTable(me->stbl, colspan, alignment, isheader, + me->Lines, HText_LastLineSize(me,FALSE)) < 0) + HText_cancelStbl(me); /* give up */ +} +/* Finish simple table cell +*/ +PUBLIC void HText_endStblTD ARGS1( + HText *, me) +{ + if (!me || !me->stbl) + return; + if (Stbl_finishCellInTable(me->stbl, YES, + me->Lines, HText_LastLineSize(me,FALSE)) < 0) + HText_cancelStbl(me); /* give up */ +} + /* Anchor handling ** --------------- */ @@ -4393,6 +5123,8 @@ PUBLIC void HText_endAppend ARGS1( new_line(text); if (text->halted) { + if (text->stbl) + HText_cancelStbl(text); /* * If output was stopped because memory was low, and we made * it to the end of the document, reset those flags and hope @@ -4400,6 +5132,12 @@ PUBLIC void HText_endAppend ARGS1( */ LYFakeZap(NO); text->halted = 0; + } else if (text->stbl) { + /* + * Could happen if TABLE end tag was missing. + * Alternatively we could cancel in this case. - kw + */ + HText_endStblTABLE(text); } /* @@ -4431,7 +5169,7 @@ PUBLIC void HText_endAppend ARGS1( * Fix up the anchor structure values and * create the hightext strings. - FM */ - HText_trimHightext(text, TRUE); + HText_trimHightext(text, TRUE, -1); } @@ -4454,14 +5192,15 @@ PUBLIC void HText_endAppend ARGS1( ** if applicable) fields indicate x positions in terms of displayed ** character cells, and the extent field apparently is unimportant; ** the anchor text has been copied to the hightext (and possibly -** hightext2) fields (which should be NULL up to this point), with -** special attribute chars removed. +** hightext2) fields (which should have been NULL up to that point), +** with special attribute chars removed. ** This needs to be done so that display_page finds the anchors in the ** form it expects when it sets the links[] elements. */ -PUBLIC void HText_trimHightext ARGS2( +PUBLIC void HText_trimHightext ARGS3( HText *, text, - BOOLEAN, final) + BOOLEAN, final, + int, stop_before) { int cur_line, cur_char, cur_shift; TextAnchor *anchor_ptr; @@ -4472,8 +5211,15 @@ PUBLIC void HText_trimHightext ARGS2( if (!text) return; - CTRACE((tfp, "Gridtext: Entering HText_trimHightext %s\n", - final ? "(final)" : "(partial)")); + if (final) { + CTRACE((tfp, "Gridtext: Entering HText_trimHightext (final)\n")); + } else { + if (stop_before < 0 || stop_before > text->Lines) + stop_before = text->Lines; + CTRACE((tfp, + "Gridtext: Entering HText_trimHightext (partial: 0..%d/%d)\n", + stop_before, text->Lines)); + } /* * Get the first line. @@ -4507,7 +5253,7 @@ re_parse: * the last line, or the very end of preceding line. * The last line is probably still not finished. - kw */ - if (cur_line >= text->Lines) + if (cur_line >= stop_before) break; if (anchor_ptr->start >= text->chars - 1) break; @@ -4607,7 +5353,7 @@ re_parse: HTLine *line_ptr2 = line_ptr->next; if (!final) { - if (cur_line + 1 >= text->Lines) { + if (cur_line + 1 >= stop_before) { FREE(anchor_ptr->hightext); /* bail out */ break; } @@ -5524,7 +6270,9 @@ PUBLIC void HTCheckFnameForCompression ARGS3( * file for us, but the anchor claims otherwise, * so tweak the suffix. - FM */ - *dot = '\0'; + if (cp == dot+1) + cp--; + *cp = '\0'; } else { /* * The anchor claims it's gzipped, and we @@ -5554,7 +6302,9 @@ PUBLIC void HTCheckFnameForCompression ARGS3( * file for us, but the anchor claims otherwise, * so tweak the suffix. - FM */ - *dot = '\0'; + if (cp == dot+1) + cp--; + *cp = '\0'; } else { /* * The anchor claims it's compressed, and @@ -5647,6 +6397,7 @@ PUBLIC void HText_pageDisplay ARGS2( } if (display_partial) { + int stop_before = -1; /* ** Garbage is reported from forms input fields in incremental mode. ** So we start HText_trimHightext() to forget this side effect. @@ -5656,7 +6407,9 @@ PUBLIC void HText_pageDisplay ARGS2( ** (FALSE = indicate that we are in partial mode) ** Multiple calls of HText_trimHightext works without problem now. */ - HText_trimHightext(HTMainText, FALSE); + if (HTMainText && HTMainText->stbl) + stop_before = Stbl_getStartLine(HTMainText->stbl); + HText_trimHightext(HTMainText, FALSE, stop_before); } #endif @@ -9360,8 +10113,9 @@ PUBLIC int HText_SubmitForm ARGS4( } fclose(fd); /* we need to modify the mime-type here */ + /* could use LYGetFileInfo for that and for other + headers that should be transmitted - kw */ - /* Argh. We need counted-length strings here */ HTSprintf(&query, "%s%s%s%s%s", escaped1, @@ -10662,7 +11416,7 @@ PRIVATE void insert_new_textarea_anchor ARGS2( f->maxlength = anchor->input_field->maxlength; f->no_cache = anchor->input_field->no_cache; f->disabled = anchor->input_field->disabled; - f->value_cs = current_char_set; + f->value_cs = current_char_set; /* use current setting - kw */ /* Init all the fields in the new HTLine (but see the #if). */ l->next = htline->next; @@ -10880,6 +11634,7 @@ PUBLIC int HText_ExtEditForm ARGS1( char *ed_temp; FILE *fp; + int rv; TextAnchor *anchor_ptr; TextAnchor *start_anchor = NULL; @@ -10981,12 +11736,28 @@ PUBLIC int HText_ExtEditForm ARGS1( HTSprintf0 (&tbuf, "%s %s %s", editor, ed_offset, ed_temp); #endif - if (LYSystem (tbuf)) { /* finally the editor is called */ +#ifdef UNIX + errno = 0; +#endif + rv = LYSystem (tbuf); /* finally the editor is called */ + if (rv) { /* * If something went wrong, we should probably return soon; * currently we don't, but at least put out a message. - kw */ - HTAlwaysAlert(NULL, ERROR_SPAWNING_EDITOR); +#ifdef UNIX + int rvhi = (rv >> 8); + CTRACE((tfp, "ExtEditForm: system() returned %d (0x%x), %s\n", + rv, rv, errno ? LYStrerror(errno) : "reason unknown")); + LYFixCursesOn("show error warning:"); + if (rv != -1 && (rv && 0xff) && !rvhi) { + HTAlwaysAlert(NULL, gettext("Editor killed by signal")); + } else if (!(rv == -1 || (rvhi == 127 && errno))) { + HTUserMsg2(gettext("Editor returned with error status, %s"), + errno ? LYStrerror(errno) : gettext("reason unknown.")); + } else +#endif + HTAlwaysAlert(NULL, ERROR_SPAWNING_EDITOR); } #ifdef UNIX @@ -11258,6 +12029,7 @@ PUBLIC int HText_InsertFile ARGS1( char *lp; char *cp; int entry_line = form_link->anchor_line_num; + int file_cs; int match_tag = 0; int newlines = 0; int len; @@ -11294,10 +12066,33 @@ PUBLIC int HText_InsertFile ARGS1( } else { - if ((fbuf = (char *) calloc (size + 1, (sizeof(char)))) == NULL) - outofmem(__FILE__, "HText_InsertFile"); + if ((fbuf = (char *) calloc (size + 1, (sizeof(char)))) == NULL) { + /* + * This could be huge - don't exit if we don't have enough + * memory for it. - kw + */ /*outofmem(__FILE__, "HText_InsertFile");*/ + free(fn); + HTAlert(MEMORY_EXHAUSTED_FILE); + return 0; + } + + /* Try to make the same assumption for the charset of the inserted + * file as we would for normal loading of that file, i.e. taking + * assume_local_charset and suffix mappings into account. + * If there is a mismatch with the display character set, characters + * may be displayed wrong, too bad; but the user has a chance to + * correct this by editing the lines, which will update f->value_cs + * again. - kw + */ + LYGetFileInfo(fn, 0, 0, 0, 0, 0, &file_cs); fp = fopen (fn, "r"); + if (!fp) { + free(fbuf); + free(fn); + HTAlert(FILE_CANNOT_OPEN_R); + return 0; + } size = fread (fbuf, 1, size, fp); fclose (fp); FREE(fn); @@ -11387,7 +12182,7 @@ PUBLIC int HText_InsertFile ARGS1( f->maxlength = anchor_ptr->input_field->maxlength; f->no_cache = anchor_ptr->input_field->no_cache; f->disabled = anchor_ptr->input_field->disabled; - f->value_cs = current_char_set; + f->value_cs = (file_cs >= 0) ? file_cs : current_char_set; /* Init all the fields in the new HTLine (but see the #if). */ l->offset = htline->offset; @@ -11474,6 +12269,13 @@ PUBLIC int HText_InsertFile ARGS1( StrAllocCopy(anchor_ptr->input_field->value, line); /* + * insert_new_textarea_anchor always uses current_char_set, + * we may want something else, so fix it up. - kw + */ + if (file_cs >= 0) + anchor_ptr->input_field->value_cs = file_cs; + + /* * And do the next line of insert text, for the next anchor ... */ lp += len; @@ -11673,6 +12475,15 @@ PRIVATE void redraw_part_of_line ARGS4( */ LastDisplayChar = 'M'; } else { +#if 0 /* last-ditch attempt to prevent 0x9B to screen - disabled */ +#if defined(UNIX) || defined(VMS) + if (!dump_output_immediately && + (unsigned char)buffer[0] == 128+27) { + addstr("~^"); + buffer[0] ^= 0xc0; + } +#endif +#endif addstr(buffer); LastDisplayChar = buffer[0]; } @@ -11696,6 +12507,588 @@ PRIVATE void redraw_part_of_line ARGS4( } #endif /* defined(USE_COLOR_STYLE) && !defined(NO_HILIT_FIX) */ +#ifndef USE_COLOR_STYLE +/* + * Function move_to_glyph is called from LYMoveToLink and does all + * the real work for it. + * The pair LYMoveToLink()/move_to_glyph() is similar to the pair + * redraw_lines_of_link()/redraw_part_of_line(), some key differences: + * LYMoveToLink/move_to_glyph redraw_* + * ----------------------------------------------------------------- + * - used without color style - used with color style + * - handles showing WHEREIS target - WHEREIS handled elsewhere + * - handles only one line - handles first two lines for + * hypertext anchors + * - right columns position for UTF-8 + * by redrawing as necessary + * - currently used for highlight - currently used for highlight + * ON and OFF OFF + * + * Eventually the two sets of function should be unified, and should handle + * UTF-8 positioning, both lines of hypertext anchors, and WHEREIS in all + * cases. If possible. The complex WHEREIS target logic in highlight() + * could then be completely removed. - kw + */ +PRIVATE void move_to_glyph ARGS10( + int, YP, + int, XP, + int, XP_draw_min, + char *, data, + int, datasize, + unsigned, offset, + CONST char *, target, + char *, hightext, + int, flags, + BOOL, utf_flag) +{ + register int i; + char buffer[7]; + CONST char *end_of_data; + size_t utf_extra = 0; +#if defined(SHOW_WHEREIS_TARGETS) + CONST char *cp_tgt; + int i_start_tgt=0, i_after_tgt; + int HitOffset, LenNeeded; +#endif /* SHOW_WHEREIS_TARGETS */ + BOOL intarget = NO, inunderline = NO, inbold = NO; + BOOL drawing = NO, inU = NO, hadutf8 = NO; + BOOL incurlink = NO, drawingtarget = NO, flag = NO; + char *sdata = data; + char LastDisplayChar = ' '; + int XP_link = XP; + int linkvlen; + + int len; + + if (flags & 1) + flag = YES; + if (flags & 2) + inU = YES; + /* Set up the multibyte character buffer */ + buffer[0] = buffer[1] = buffer[2] = '\0'; + /* + * Add offset, making sure that we do not + * go over the COLS limit on the display. + */ + i = (int)offset; + if (i > (int)LYcols - 1) + i = (int)LYcols - 1; + + linkvlen = hightext ? LYmbcsstrlen(hightext, utf_flag) : 0; + + /* + * Scan through the data, making sure that we do not + * go over the COLS limit on the display etc. + */ + len = datasize; + end_of_data = data + len; + +#if defined(SHOW_WHEREIS_TARGETS) + /* + * If the target overlaps with the part of this line that + * we are drawing, it will be emphasized. + */ + i_after_tgt = i; + if (target) { + if (case_sensitive) + cp_tgt = LYno_attr_mbcs_strstr(sdata, + target, + utf_flag, + &HitOffset, + &LenNeeded); + else + cp_tgt = LYno_attr_mbcs_case_strstr(sdata, + target, + utf_flag, + &HitOffset, + &LenNeeded); + if (cp_tgt) { + if ((int)offset + LenNeeded >= LYcols || + ((int)offset + HitOffset >= XP + linkvlen)) { + cp_tgt = NULL; + } else { + i_start_tgt = i + HitOffset; + i_after_tgt = i + LenNeeded; + } + } + } else { + cp_tgt = NULL; + } +#endif /* SHOW_WHEREIS_TARGETS */ + + + /* + * Iterate through the line data from the start, keeping track of + * the display ("glyph") position in i. Drawing will be turned + * on when either the first UTF-8 sequence (that occurs after + * XP_draw_min) is found, or when we reach the link itself (if + * highlight is non-NULL). - kw + */ + while ((i < LYcols - 1) && data < end_of_data && (*data != '\0')) { + + if (data && hightext && i >= XP && !incurlink) { + + /* + * We reached the position of link itself, and highlight is + * non-NULL. We switch data from being a pointer into the HTLine + * to be a pointer into hightext. Normally (as long as this + * routine is applied to normal hyperlink anchors) the text in + * hightext will be identical to that part of the HTLine that + * data was already pointing to, except that special attribute + * chars LY_BOLD_START_CHAR etc. have been stripped out (see + * HText_trimHightext). So the switching should not result in + * any different display, but it ensures that it doesn't go + * unnoticed if somehow hightext got messed up somewhere else. + * This is also useful in preparation for using this function + * for something else than normal hyperlink anchors, i.e. form + * fields. + * Turn on drawing here or make sure it gets turned on before the + * next actual normal character is handled. - kw + */ + data = hightext; + len = strlen(hightext); + end_of_data = hightext + len; + XP += linkvlen; + incurlink = YES; + if (cp_tgt) { + if (flag && i_after_tgt >= XP) + i_after_tgt = XP - 1; + } + /* + * The logic of where to set intarget drawingtarget etc. + * and when to react to it should be cleaned up (here and + * further below). For now this seems to work but isn't + * very clear. The complications arise from reproducing + * the behavior (previously done in highlight()) for target + * strings that fall into or overlap a link: use target + * emphasis for the target string, except for the first + * and last character of the anchor text if the anchor is + * highlighted as "current link". - kw + */ + if (!drawing) { +#ifdef SHOW_WHEREIS_TARGETS + if (intarget) { + if (i_after_tgt > i) { + move(YP, i); + if (flag) { + drawing = YES; + drawingtarget = NO; + if (inunderline) inU = YES; + lynx_start_link_color (flag, inU); + } else { + drawing = YES; + drawingtarget = YES; + LYstartTargetEmphasis(); + } + } +#if 0 + } else { + if (inunderline) inU = YES; + lynx_start_link_color (flag, inU); +#endif + } +#endif /* SHOW_WHEREIS_TARGETS */ + } else { +#ifdef SHOW_WHEREIS_TARGETS + if (intarget && i_after_tgt > i) { + if (flag && (data == hightext)) { + drawingtarget = NO; + LYstopTargetEmphasis(); + } + } else if (!intarget) +#endif /* SHOW_WHEREIS_TARGETS */ + { + if (inunderline) inU = YES; + if (inunderline) stop_underline(); + if (inbold) stop_bold(); + lynx_start_link_color (flag, inU); + } + + } + } + if (i >= XP || data >= end_of_data) + break; + if ((buffer[0] = *data) == '\0') + break; + + +#if defined(SHOW_WHEREIS_TARGETS) + /* + * Look for a subsequent occurrence of the target string, + * if we had a previous one and have now stepped past it. - kw + */ + if (cp_tgt && i >= i_after_tgt) { + if (intarget) { + + if (incurlink && flag && i == XP - 1) + cp_tgt = NULL; + else if (case_sensitive) + cp_tgt = LYno_attr_mbcs_strstr(sdata, + target, + utf_flag, + &HitOffset, + &LenNeeded); + else + cp_tgt = LYno_attr_mbcs_case_strstr(sdata, + target, + utf_flag, + &HitOffset, + &LenNeeded); + if (cp_tgt) { + i_start_tgt = i + HitOffset; + i_after_tgt = i + LenNeeded; + if (incurlink) { + if (flag && i_start_tgt == XP_link) + i_start_tgt++; + if (flag && i_start_tgt == XP - 1) + i_start_tgt++; + if (flag && i_after_tgt >= XP) + i_after_tgt = XP - 1; + if (flag && i_start_tgt >= XP) + cp_tgt = NULL; + } else if (i_start_tgt == XP) { + if (flag) + i_start_tgt++; + } + } + if (!cp_tgt || i_start_tgt != i) { + intarget = NO; + if (drawing) { + if (drawingtarget) { + drawingtarget = NO; + LYstopTargetEmphasis(); + if (incurlink) { + lynx_start_link_color (flag, inU); + } + } + if (!incurlink) { + if (inbold) start_bold(); + if (inunderline) start_underline(); + } + } + } + } + } +#endif /* SHOW_WHEREIS_TARGETS */ + + /* + * Advance data to point to the next input char (for the + * next round). Advance sdata, used for searching for a + * target string, so that they stays in synch. As long + * as we are not within the highlight text, data and sdata + * have identical values. After we have switched data to + * point into hightext, sdata remains a pointer into the + * HTLine (so that we don't miss a partial target match at + * the end of the anchor text). So sdata has to sometimes + * skip additional special attribute characters that are + * not present in highlight in order to stay in synch. - kw + */ + data++; + if (*sdata) { + do sdata++; + while (incurlink && *sdata && sdata != data && + IsSpecialAttrChar(*(sdata-1))); + } + + switch (buffer[0]) { + + case LY_UNDERLINE_START_CHAR: + if (!drawing || !incurlink) inunderline = YES; + if (drawing && !intarget && !incurlink) + start_underline(); + break; + + case LY_UNDERLINE_END_CHAR: + inunderline = NO; + if (drawing && !intarget && !incurlink) + stop_underline(); + break; + + case LY_BOLD_START_CHAR: + if (!drawing || !incurlink) inbold = YES; + if (drawing && !intarget && !incurlink) + start_bold(); + break; + + case LY_BOLD_END_CHAR: + inbold = NO; + if (drawing && !intarget && !incurlink) + stop_bold(); + break; + + case LY_SOFT_NEWLINE: + if (drawing) { + addch('+'); + } + i++; + break; + + case LY_SOFT_HYPHEN: + if (*data != '\0' || + isspace((unsigned char)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 + */ + break; + } else { + /* + * Make it a hard hyphen and fall through. - FM + */ + buffer[0] = '-'; + } + + default: + /* + * We have got an actual normal displayable character, or + * the start of one. Before proceeding check whether + * drawing needs to be turned on now. - kw + */ +#if defined(SHOW_WHEREIS_TARGETS) + if (incurlink) { + if (intarget && flag && i == XP - 1 && + i_after_tgt > i) + i_after_tgt = i; + } + if (cp_tgt && i >= i_start_tgt && sdata > cp_tgt) { + if (!intarget || + (intarget && incurlink && !drawingtarget)) { + + if (incurlink && drawing && + !(flag && + (i == XP_link || i == XP - 1))) { + lynx_stop_link_color (flag, inU); + } + if (incurlink && !drawing) { + move(YP, i); + if (inunderline) inU = YES; + if (flag && (i == XP_link || i == XP - 1)) { + lynx_start_link_color (flag, inU); + drawingtarget = NO; + } else { + LYstartTargetEmphasis(); + drawingtarget = YES; + } + drawing = YES; + } else if (incurlink && drawing && + intarget && !drawingtarget && + (flag && + (i == XP_link))) { + if (inunderline) inU = YES; + lynx_start_link_color (flag, inU); + } else if (drawing && + !(flag && + (i == XP_link || (incurlink && i == XP - 1)))) { + LYstartTargetEmphasis(); + drawingtarget = YES; + } + intarget = YES; + } + } else +#endif /* SHOW_WHEREIS_TARGETS */ + if (incurlink) { + if (!drawing) { + move(YP, i); + if (inunderline) inU = YES; + lynx_start_link_color (flag, inU); + drawing = YES; + } + } + + i++; + if (utf_flag && !isascii((unsigned char)buffer[0])) { + hadutf8 = YES; + if ((*buffer & 0xe0) == 0xc0) { + utf_extra = 1; + } else if ((*buffer & 0xf0) == 0xe0) { + utf_extra = 2; + } else if ((*buffer & 0xf8) == 0xf0) { + utf_extra = 3; + } else if ((*buffer & 0xfc) == 0xf8) { + utf_extra = 4; + } else if ((*buffer & 0xfe) == 0xfc) { + utf_extra = 5; + } else { + /* + * Garbage. + */ + utf_extra = 0; + } + if (strlen(data) < utf_extra) { + /* + * Shouldn't happen. + */ + utf_extra = 0; + } + LastDisplayChar = 'M'; + } + if (utf_extra) { + strncpy(&buffer[1], data, utf_extra); + buffer[utf_extra+1] = '\0'; + if (!drawing && i >= XP_draw_min) { + move(YP, i - 1); + drawing = YES; +#if defined(SHOW_WHEREIS_TARGETS) + if (intarget) { + drawingtarget = YES; + LYstartTargetEmphasis(); + } else +#endif /* SHOW_WHEREIS_TARGETS */ + { + if (inbold) + start_bold(); + if (inunderline) + start_underline(); + } + } + addstr(buffer); + buffer[1] = '\0'; + sdata += utf_extra; data += utf_extra; + utf_extra = 0; + } else if (HTCJK != NOCJK && !isascii(buffer[0])) { + /* + * For CJK strings, by Masanobu Kimura. + */ + if (drawing && (i < LYcols - 1)) { + buffer[1] = *data; + addstr(buffer); + buffer[1] = '\0'; + } + i++; + sdata++; data++; + /* + * 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 { + if (drawing) { +#if 0 /* last-ditch attempt to prevent 0x9B to screen - disabled */ +#if defined(UNIX) || defined(VMS) + if (!dump_output_immediately && + (unsigned char)buffer[0] == 128+27) { + addstr("~^"); + buffer[0] ^= 0xc0; + } +#endif +#endif + addstr(buffer); + } + LastDisplayChar = buffer[0]; + } + } /* end of switch */ + } /* end of while */ + + if (!drawing) { + move(YP, i); + lynx_start_link_color (flag, inU); + } else { +#if defined(SHOW_WHEREIS_TARGETS) + if (drawingtarget) { + LYstopTargetEmphasis(); + lynx_start_link_color (flag, inU); + } +#endif /* SHOW_WHEREIS_TARGETS */ + if (hadutf8) { +#ifdef USE_SLANG + SLsmg_touch_lines(YP, 1); +#elif defined(NCURSES_VERSION) + touchline(stdscr, YP, 1); +#else + touchwin(stdscr); +#endif + } + } + return; +} +#endif /* !USE_COLOR_STYLE */ + +#ifndef USE_COLOR_STYLE +/* + * Move cursor position to a link's place in the display. + * The "moving to" is done by scanning through the line's + * character data in the corresponding HTLine of HTMainText, + * and starting to draw when a UTF-8 encoded non-ASCII character + * is encountered before the link (with some protection against + * overwriting form fields). This refreshing of preceding data is + * necessary for preventing curses's or slang's display logic from + * getting too clever; their logic counts character positions wrong + * since they don't know about multi-byte characters that take up + * only one screen position. So we have to make them forget their + * idea of what's in a screen line drawn previously. + * If hightext is non-NULL, it should be the anchor text for a normal + * link as stored in a links[] element, and the anchor text will be + * drawn too, with appropriate attributes. - kw + */ +PUBLIC void LYMoveToLink ARGS6( + int, cur, + CONST char *, target, + char *, hightext, + int, flag, + BOOL, inU, + BOOL, utf_flag) +{ +#define pvtTITLE_HEIGHT 1 + HTLine* todr; + int i, n=0; + int XP_draw_min = 0; + int flags = ((flag == ON) ? 1 : 0) | (inU ? 2 : 0); + + /* + * We need to protect changed form text fields preceding this + * link on the same line against overwriting. - kw + */ + for (i = cur-1; i >= 0; i++) { + if (links[i].ly < links[cur].ly) + break; + if (links[i].type == WWW_FORM_LINK_TYPE) { + XP_draw_min = links[i].ly + links[i].form->size; + break; + } + } + + /* Find the right HTLine. */ + if (!HTMainText) { + todr = NULL; + } else if (HTMainText->stale) { + todr = HTMainText->last_line->next; + n = links[cur].ly - pvtTITLE_HEIGHT + HTMainText->top_of_screen; + } else { + todr = HTMainText->top_of_screen_line; + n = links[cur].ly - pvtTITLE_HEIGHT; + } + for (i = 0; i < n && todr; i++) { + todr = (todr == HTMainText->last_line) ? NULL : todr->next; + } + if (todr) { + if (target && *target == '\0') target = NULL; + move_to_glyph(links[cur].ly, links[cur].lx, XP_draw_min, + todr->data, todr->size, todr->offset, + target, hightext, flags, utf_flag); + } else { + /* This should not happen. */ + move_to_glyph(links[cur].ly, links[cur].lx, XP_draw_min, + "", 0, links[cur].lx, + target, hightext, flags, utf_flag); + /* move(links[cur].ly, links[cur].lx); */ + } +} +#endif /* !USE_COLOR_STYLE */ + /* This is used only if compiled with lss support. It's called to draw regular link (1st two lines of link) when it's being unhighlighted in @@ -11764,5 +13157,7 @@ PUBLIC void HText_updateKcode ARGS2( PUBLIC int HTMainText_Get_UCLYhndl NOARGS { - return (HTMainText ? HTMainText->node_anchor->UCStages->s[0].C.UChndl : 0); + return (HTMainText ? + HTAnchor_getUCLYhndl(HTMainText->node_anchor, UCT_STAGE_MIME) + : -1); } diff --git a/src/GridText.h b/src/GridText.h index 5fb73f07..190d97fa 100644 --- a/src/GridText.h +++ b/src/GridText.h @@ -32,7 +32,7 @@ #ifndef LY_SOFT_HYPHEN #define LY_SOFT_HYPHEN ((char)7) #endif /* !LY_SOFT_HYPHEN */ -#define LY_SOFT_NEWLINE ((char)8) +#define LY_SOFT_NEWLINE ((char)8) #ifdef EBCDIC #define IsSpecialAttrChar(a) (((a) > '\002') && ((a) <= '\011') && ((a)!='\t')) @@ -196,6 +196,15 @@ extern int HText_getTabIDColumn PARAMS((HText *text, CONST char *name)); extern int HText_HiddenLinkCount PARAMS((HText *text)); extern char * HText_HiddenLinkAt PARAMS((HText *text, int number)); +/* "simple table" stuff */ +extern void HText_cancelStbl PARAMS((HText *)); +extern void HText_startStblTABLE PARAMS((HText *, short)); +extern void HText_endStblTABLE PARAMS((HText *)); +extern void HText_startStblTR PARAMS((HText *, short)); +extern void HText_endStblTR PARAMS((HText *)); +extern void HText_startStblTD PARAMS((HText *, int, short, BOOL)); +extern void HText_endStblTD PARAMS((HText *)); + /* forms stuff */ extern void HText_beginForm PARAMS(( char * action, @@ -213,17 +222,18 @@ extern char * HText_setLastOptionValue PARAMS(( HText * text, char * value, char * submit_value, - int order, + int order, BOOLEAN checked, - int val_cs, - int submit_val_cs)); + int val_cs, + int submit_val_cs)); extern int HText_beginInput PARAMS(( HText * text, BOOL underline, InputFieldData *I)); extern void HText_trimHightext PARAMS(( HText * text, - BOOLEAN final)); + BOOLEAN final, + int stop_before)); extern int HText_SubmitForm PARAMS(( FormInfo * submit_item, document * doc, @@ -279,6 +289,14 @@ extern int HText_InsertFile PARAMS(( struct link * form_link)); extern void redraw_lines_of_link PARAMS((int cur)); +extern void LYMoveToLink PARAMS(( + int cur, + CONST char * target, + char * hightext, + int flag, + BOOL inU, + BOOL utf_flag)); + #ifdef USE_PSRC extern void HTMark_asSource NOPARAMS; diff --git a/src/HTFWriter.c b/src/HTFWriter.c index 8b1308c1..faae9477 100644 --- a/src/HTFWriter.c +++ b/src/HTFWriter.c @@ -171,24 +171,25 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me) * and remove any previous uncompressed copy. - FM */ StrAllocCopy(path, me->anchor->FileCache); - if ((len = strlen(path)) > 3) { - if (!strcasecomp(&path[len-3], "bz2")) { - path[len-4] = '\0'; - remove(path); - } else if (!strcasecomp(&path[len-2], "gz")) { + if ((len = strlen(path)) > 3 && + !strcasecomp(&path[len-2], "gz")) { #ifdef USE_ZLIB - if (!skip_loadfile) { - use_gzread = YES; - } else + if (!skip_loadfile) { + use_gzread = YES; + } else #endif /* USE_ZLIB */ - { - path[len-3] = '\0'; - remove(path); - } - } else if (!strcasecomp(&path[len-1], "Z")) { - path[len-2] = '\0'; + { + path[len-3] = '\0'; remove(path); } +#ifdef BZIP2_PATH + } else if (len > 4 && !strcasecomp(&path[len-3], "bz2")) { + path[len-4] = '\0'; + remove(path); +#endif /* BZIP2_PATH */ + } else if (len > 2 && !strcasecomp(&path[len-1], "Z")) { + path[len-2] = '\0'; + remove(path); } if (!use_gzread) { if (!dump_output_immediately) { @@ -216,7 +217,7 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me) refresh(); } HTAlert(ERROR_UNCOMPRESSING_TEMP); - remove(me->anchor->FileCache); + LYRemoveTemp(me->anchor->FileCache); FREE(me->anchor->FileCache); } else { /* @@ -437,7 +438,7 @@ PRIVATE void HTFWriter_abort ARGS2( LYCloseTempFP(me->fp); FREE(me->viewer_command); if (me->end_command) { /* Temp file */ - CTRACE((tfp, "HTFWriter: Aborting: file not executed.\n")); + CTRACE((tfp, "HTFWriter: Aborting: file not executed or saved.\n")); FREE(me->end_command); if (me->remove_command) { LYSystem(me->remove_command); @@ -913,7 +914,6 @@ PUBLIC HTStream* HTCompressed ARGS3( char *uncompress_mask = NULL; char *compress_suffix = ""; CONST char *middle; - FILE *fp = NULL; /* * Deal with any inappropriate invocations of this function, @@ -938,12 +938,7 @@ PUBLIC HTStream* HTCompressed ARGS3( * We have a presentation mapping for it. - FM */ can_present = TRUE; - if (!strcasecomp(anchor->content_encoding, "x-bzip2") || - !strcasecomp(anchor->content_encoding, "bzip")) { - StrAllocCopy(uncompress_mask, BZIP2_PATH); - StrAllocCat(uncompress_mask, " -d %s"); - compress_suffix = "bz2"; - } else if (!strcasecomp(anchor->content_encoding, "x-gzip") || + if (!strcasecomp(anchor->content_encoding, "x-gzip") || !strcasecomp(anchor->content_encoding, "gzip")) { /* * It's compressed with the modern gzip. - FM @@ -951,6 +946,13 @@ PUBLIC HTStream* HTCompressed ARGS3( StrAllocCopy(uncompress_mask, GZIP_PATH); StrAllocCat(uncompress_mask, " -d --no-name %s"); compress_suffix = "gz"; +#ifdef BZIP2_PATH + } else if (!strcasecomp(anchor->content_encoding, "x-bzip2") || + !strcasecomp(anchor->content_encoding, "bzip")) { + StrAllocCopy(uncompress_mask, BZIP2_PATH); + StrAllocCat(uncompress_mask, " -d %s"); + compress_suffix = "bz2"; +#endif /* BZIP2_PATH */ } else if (!strcasecomp(anchor->content_encoding, "x-compress") || !strcasecomp(anchor->content_encoding, "compress")) { /* @@ -976,7 +978,15 @@ PUBLIC HTStream* HTCompressed ARGS3( * and pass it back to be handled as that type. - FM */ if (strchr(anchor->content_encoding, '/') == NULL) { - StrAllocCopy(type, "application/"); + /* + * Use "x-" prefix, none of the types we are likely to + * construct here are official. That is we generate + * "application/x-gzip" and so on. - kw + */ + if (!strncasecomp(anchor->content_encoding, "x-", 2)) + StrAllocCopy(type, "application/"); + else + StrAllocCopy(type, "application/x-"); StrAllocCat(type, anchor->content_encoding); } else { StrAllocCopy(type, anchor->content_encoding); @@ -1008,10 +1018,7 @@ PUBLIC HTStream* HTCompressed ARGS3( * Remove any old versions of the file. - FM */ if (anchor->FileCache) { - while ((fp = fopen(anchor->FileCache, "r")) != NULL) { - fclose(fp); - remove(anchor->FileCache); - } + LYRemoveTemp(anchor->FileCache); FREE(anchor->FileCache); } diff --git a/src/HTInit.c b/src/HTInit.c index 811af8b5..f7ce2bcc 100644 --- a/src/HTInit.c +++ b/src/HTInit.c @@ -45,15 +45,17 @@ PUBLIC void HTFormatInit NOARGS if (LYgetXDisplay() != 0) { /* Must have X11 */ HTSetPresentation("application/postscript", "ghostview %s&", 1.0, 3.0, 0.0, 0); - HTSetPresentation("image/gif", XLoadImageCommand, 1.0, 3.0, 0.0, 0); - HTSetPresentation("image/x-xbm", XLoadImageCommand, 1.0, 3.0, 0.0, 0); - HTSetPresentation("image/x-xbitmap", XLoadImageCommand, 1.0, 3.0, 0.0, 0); - HTSetPresentation("image/x-png", XLoadImageCommand, 2.0, 3.0, 0.0, 0); - HTSetPresentation("image/png", XLoadImageCommand, 1.0, 3.0, 0.0, 0); - HTSetPresentation("image/x-rgb", XLoadImageCommand, 1.0, 3.0, 0.0, 0); - HTSetPresentation("image/x-tiff", XLoadImageCommand, 2.0, 3.0, 0.0, 0); - HTSetPresentation("image/tiff", XLoadImageCommand, 1.0, 3.0, 0.0, 0); - HTSetPresentation("image/jpeg", XLoadImageCommand, 1.0, 3.0, 0.0, 0); + if (XLoadImageCommand && *XLoadImageCommand) { + HTSetPresentation("image/gif", XLoadImageCommand, 1.0, 3.0, 0.0, 0); + HTSetPresentation("image/x-xbm", XLoadImageCommand, 1.0, 3.0, 0.0, 0); + HTSetPresentation("image/x-xbitmap",XLoadImageCommand,1.0, 3.0, 0.0, 0); + HTSetPresentation("image/x-png", XLoadImageCommand, 2.0, 3.0, 0.0, 0); + HTSetPresentation("image/png", XLoadImageCommand, 1.0, 3.0, 0.0, 0); + HTSetPresentation("image/x-rgb", XLoadImageCommand, 1.0, 3.0, 0.0, 0); + HTSetPresentation("image/x-tiff", XLoadImageCommand, 2.0, 3.0, 0.0, 0); + HTSetPresentation("image/tiff", XLoadImageCommand, 1.0, 3.0, 0.0, 0); + HTSetPresentation("image/jpeg", XLoadImageCommand, 1.0, 3.0, 0.0, 0); + } HTSetPresentation("video/mpeg", "mpeg_play %s &", 1.0, 3.0, 0.0, 0); } @@ -693,16 +695,45 @@ PRIVATE int HTLoadTypesConfigFile ARGS1( ** which are of the same format but are originals or regenerated, ** with different values. */ - +/* + * Additional notes: the encoding parameter may be taken into account when + * looking for a match; for that purpose "7bit", "8bit", and "binary" are + * equivalent. + * Use of mixed case and of pseudo MIME types with embedded spaces should + * be avoided. It was once necessary for getting the fancy strings into + * type labels in FTP directory listings, but that can now be done with + * the description field (using HTSetSuffix5). AFAIK the only effect of + * such "fancy" (and mostly invalid) types that cannot be reproduced by + * using a description fields is some statusline messages in SaveToFile + * (HTFWriter.c). And showing the user an invalid MIME type as the + * 'Content-type:' is not such a hot idea anyway, IMO. Still, if you + * want it, it is still possible (even in lynx.cfg now), but use of it + * in the defaults below has been reduced. + * Case variations rely on peculiar behavior of HTAtom.c for matching. + * They lead to surprising behavior, Lynx retains the case of a string + * in the form first encountered after starting up. So while later suffix + * rules generally override or modify earlier ones, the case used for a + * MIME time is determined by the first suffix rule (or other occurrence). + * Matching in HTAtom_for is effectively case insensitive, except for the + * first character of the string which is treated as case-sensitive by the + * hash function there; best not to rely on that, rather convert MIME types + * to lowercase on input as is already done in most places (And HTAtom could + * become consistently case-sensitive, as in newer W3C libwww). + * - kw 1999-10-12 + */ PUBLIC void HTFileInit NOARGS { FILE *fp; +#ifdef BUILTIN_SUFFIX_MAPS + if (LYUseBuiltinSuffixes) + { CTRACE((tfp, "HTFileInit: Loading default (HTInit) extension maps.\n")); /* default suffix interpretation */ - HTSetSuffix("*", "text/plain", "7bit", 1.0); - HTSetSuffix("*.*", "text/plain", "7bit", 1.0); + HTSetSuffix("*", "text/plain", "8bit", 1.0); + HTSetSuffix("*.*", "text/plain", "8bit", 1.0); + #ifdef EXEC_SCRIPTS /* @@ -718,7 +749,15 @@ PUBLIC void HTFileInit NOARGS #endif /* !VMS */ #endif /* EXEC_SCRIPTS */ - + /* + * Some of the old incarnation of the mappings is preserved + * and can be had by defining TRADITIONAL_SUFFIXES. This + * is for some cases where I felt the old rules might be preferred + * by someone, for some reason. It's not done consistently. + * A lot more of this stuff could probably be changed too or + * omitted, now that nearly the equivalent functionality is + * available in lynx.cfg. - kw 1999-10-12 + */ HTSetSuffix(".saveme", "application/x-Binary", "binary", 1.0); HTSetSuffix(".dump", "application/x-Binary", "binary", 1.0); HTSetSuffix(".bin", "application/x-Binary", "binary", 1.0); @@ -731,61 +770,104 @@ PUBLIC void HTFileInit NOARGS HTSetSuffix(".AXP_exe", "application/x-Executable", "binary", 1.0); HTSetSuffix(".VAX-exe", "application/x-Executable", "binary", 1.0); HTSetSuffix(".VAX_exe", "application/x-Executable", "binary", 1.0); - HTSetSuffix(".exe", "application/x-Executable", "binary", 1.0); + HTSetSuffix5(".exe", "application/octet-stream", "binary", "Executable", 1.0); +#ifdef TRADITIONAL_SUFFIXES HTSetSuffix(".exe.Z", "application/x-Comp. Executable", "binary", 1.0); - HTSetSuffix(".Z", "application/UNIX Compressed", "binary", 1.0); - HTSetSuffix(".tar_Z", "application/UNIX Compr. Tar", "binary", 1.0); HTSetSuffix(".tar.Z", "application/UNIX Compr. Tar", "binary", 1.0); +#else + HTSetSuffix5(".Z", "application/x-compress", "binary", "UNIX Compressed", 1.0); + HTSetSuffix5(".Z", NULL, "compress", "UNIX Compressed", 1.0); + HTSetSuffix5(".exe.Z", "application/octet-stream", "compress", + "Executable", 1.0); + HTSetSuffix5(".tar_Z", "application/x-tar", "compress", + "UNIX Compr. Tar", 1.0); + HTSetSuffix5(".tar.Z", "application/x-tar", "compress", + "UNIX Compr. Tar", 1.0); +#endif +#ifdef TRADITIONAL_SUFFIXES HTSetSuffix("-gz", "application/GNU Compressed", "binary", 1.0); HTSetSuffix("_gz", "application/GNU Compressed", "binary", 1.0); HTSetSuffix(".gz", "application/GNU Compressed", "binary", 1.0); HTSetSuffix5(".tar.gz", "application/x-tar", "binary", "GNU Compr. Tar", 1.0); HTSetSuffix5(".tgz", "application/x-tar", "gzip", "GNU Compr. Tar", 1.0); +#else + HTSetSuffix5("-gz", "application/x-gzip", "binary", "GNU Compressed", 1.0); + HTSetSuffix5("_gz", "application/x-gzip", "binary", "GNU Compressed", 1.0); + HTSetSuffix5(".gz", "application/x-gzip", "binary", "GNU Compressed", 1.0); + HTSetSuffix5("-gz", NULL, "gzip", "GNU Compressed", 1.0); + HTSetSuffix5("_gz", NULL, "gzip", "GNU Compressed", 1.0); + HTSetSuffix5(".gz", NULL, "gzip", "GNU Compressed", 1.0); + + HTSetSuffix5(".tar.gz", "application/x-tar", "gzip", "GNU Compr. Tar", 1.0); + HTSetSuffix5(".tgz", "application/x-tar", "gzip", "GNU Compr. Tar", 1.0); +#endif +#ifdef TRADITIONAL_SUFFIXES HTSetSuffix(".src", "application/x-WAIS-source", "8bit", 1.0); HTSetSuffix(".wsrc", "application/x-WAIS-source", "8bit", 1.0); +#else + HTSetSuffix5(".wsrc", "application/x-wais-source", "8bit", "WAIS-source", 1.0); +#endif - HTSetSuffix(".zip", "application/x-Zip File", "binary", 1.0); + HTSetSuffix5(".zip", "application/zip", "binary", "Zip File", 1.0); HTSetSuffix(".bz2", "application/x-bzip2", "binary", 1.0); HTSetSuffix(".bz2", "application/x-bzip2", "binary", 1.0); +#ifdef TRADITIONAL_SUFFIXES HTSetSuffix(".uu", "application/x-UUencoded", "8bit", 1.0); HTSetSuffix(".hqx", "application/x-Binhex", "8bit", 1.0); HTSetSuffix(".o", "application/x-Prog. Object", "binary", 1.0); HTSetSuffix(".a", "application/x-Prog. Library", "binary", 1.0); +#else + HTSetSuffix5(".uu", "application/x-uuencoded", "7bit", "UUencoded", 1.0); + + HTSetSuffix5(".hqx", "application/mac-binhex40", "8bit", "Mac BinHex", 1.0); + + HTSetSuffix5(".o", "application/octet-stream", "binary", "Prog. Object", 0.5); + HTSetSuffix5(".a", "application/octet-stream", "binary", "Prog. Library", 0.5); + HTSetSuffix5(".so", "application/octet-stream", "binary", "Shared Lib", 0.5); +#endif HTSetSuffix5(".oda", "application/oda", "binary", "ODA", 1.0); HTSetSuffix5(".pdf", "application/pdf", "binary", "PDF", 1.0); - HTSetSuffix(".eps", "application/Postscript", "8bit", 1.0); - HTSetSuffix(".ai", "application/Postscript", "8bit", 1.0); - HTSetSuffix(".ps", "application/Postscript", "8bit", 1.0); + HTSetSuffix5(".eps", "application/postscript", "8bit", "Postscript", 1.0); + HTSetSuffix5(".ai", "application/postscript", "8bit", "Postscript", 1.0); + HTSetSuffix5(".ps", "application/postscript", "8bit", "Postscript", 1.0); - HTSetSuffix(".rtf", "application/RTF", "8bit", 1.0); + HTSetSuffix5(".rtf", "application/rtf", "8bit", "RTF", 1.0); - HTSetSuffix(".dvi", "application/x-DVI", "8bit", 1.0); + HTSetSuffix5(".dvi", "application/x-dvi", "8bit", "DVI", 1.0); - HTSetSuffix(".hdf", "application/x-HDF", "8bit", 1.0); + HTSetSuffix5(".hdf", "application/x-hdf", "8bit", "HDF", 1.0); HTSetSuffix(".cdf", "application/x-netcdf", "8bit", 1.0); HTSetSuffix(".nc", "application/x-netcdf", "8bit", 1.0); +#ifdef TRADITIONAL_SUFFIXES HTSetSuffix(".latex", "application/x-Latex", "8bit", 1.0); HTSetSuffix(".tex", "application/x-Tex", "8bit", 1.0); HTSetSuffix(".texinfo", "application/x-Texinfo", "8bit", 1.0); HTSetSuffix(".texi", "application/x-Texinfo", "8bit", 1.0); +#else + HTSetSuffix5(".latex", "application/x-latex", "8bit", "LaTeX", 1.0); + HTSetSuffix5(".tex", "text/x-tex", "8bit", "TeX", 1.0); + HTSetSuffix5(".texinfo", "application/x-texinfo", "8bit", "Texinfo", 1.0); + HTSetSuffix5(".texi", "application/x-texinfo", "8bit", "Texinfo", 1.0); +#endif +#ifdef TRADITIONAL_SUFFIXES HTSetSuffix(".t", "application/x-Troff", "8bit", 1.0); HTSetSuffix(".tr", "application/x-Troff", "8bit", 1.0); HTSetSuffix(".roff", "application/x-Troff", "8bit", 1.0); @@ -793,51 +875,80 @@ PUBLIC void HTFileInit NOARGS HTSetSuffix(".man", "application/x-Troff-man", "8bit", 1.0); HTSetSuffix(".me", "application/x-Troff-me", "8bit", 1.0); HTSetSuffix(".ms", "application/x-Troff-ms", "8bit", 1.0); +#else + HTSetSuffix5(".t", "application/x-troff", "8bit", "Troff", 1.0); + HTSetSuffix5(".tr", "application/x-troff", "8bit", "Troff", 1.0); + HTSetSuffix5(".roff", "application/x-troff", "8bit", "Troff", 1.0); + + HTSetSuffix5(".man", "application/x-troff-man", "8bit", "Man Page", 1.0); + HTSetSuffix5(".me", "application/x-troff-me", "8bit", "Troff me", 1.0); + HTSetSuffix5(".ms", "application/x-troff-ms", "8bit", "Troff ms", 1.0); +#endif HTSetSuffix(".zoo", "application/x-Zoo File", "binary", 1.0); +#if defined(TRADITIONAL_SUFFIXES) || defined(VMS) HTSetSuffix(".bak", "application/x-VMS BAK File", "binary", 1.0); HTSetSuffix(".bkp", "application/x-VMS BAK File", "binary", 1.0); HTSetSuffix(".bck", "application/x-VMS BAK File", "binary", 1.0); - HTSetSuffix(".bkp_gz", "application/x-GNU BAK File", "binary", 1.0); - HTSetSuffix(".bkp-gz", "application/x-GNU BAK File", "binary", 1.0); - HTSetSuffix(".bck_gz", "application/x-GNU BAK File", "binary", 1.0); - HTSetSuffix(".bck-gz", "application/x-GNU BAK File", "binary", 1.0); + HTSetSuffix(".bkp_gz", "application/octet-stream", "gzip", "GNU BAK File", 1.0); + HTSetSuffix(".bkp-gz", "application/octet-stream", "gzip", "GNU BAK File", 1.0); + HTSetSuffix(".bck_gz", "application/octet-stream", "gzip", "GNU BAK File", 1.0); + HTSetSuffix(".bck-gz", "application/octet-stream", "gzip", "GNU BAK File", 1.0); - HTSetSuffix(".bkp-Z", "application/x-Comp. BAK File", "binary", 1.0); - HTSetSuffix(".bkp_Z", "application/x-Comp. BAK File", "binary", 1.0); - HTSetSuffix(".bck-Z", "application/x-Comp. BAK File", "binary", 1.0); - HTSetSuffix(".bck_Z", "application/x-Comp. BAK File", "binary", 1.0); + HTSetSuffix(".bkp-Z", "application/octet-stream", "compress", "Comp. BAK File", 1.0); + HTSetSuffix(".bkp_Z", "application/octet-stream", "compress", "Comp. BAK File", 1.0); + HTSetSuffix(".bck-Z", "application/octet-stream", "compress", "Comp. BAK File", 1.0); + HTSetSuffix(".bck_Z", "application/octet-stream", "compress", "Comp. BAK File", 1.0); +#else + HTSetSuffix5(".bak", NULL, "binary", "Backup", 0.5); + HTSetSuffix5(".bkp", "application/octet-stream", "binary", "VMS BAK File", 1.0); + HTSetSuffix5(".bck", "application/octet-stream", "binary", "VMS BAK File", 1.0); +#endif +#if defined(TRADITIONAL_SUFFIXES) || defined(VMS) HTSetSuffix(".hlb", "application/x-VMS Help Libr.", "binary", 1.0); HTSetSuffix(".olb", "application/x-VMS Obj. Libr.", "binary", 1.0); HTSetSuffix(".tlb", "application/x-VMS Text Libr.", "binary", 1.0); HTSetSuffix(".obj", "application/x-VMS Prog. Obj.", "binary", 1.0); HTSetSuffix(".decw$book", "application/x-DEC BookReader", "binary", 1.0); HTSetSuffix(".mem", "application/x-RUNOFF-MANUAL", "8bit", 1.0); +#else + HTSetSuffix5(".hlb", "application/octet-stream", "binary", "VMS Help Libr.", 1.0); + HTSetSuffix5(".olb", "application/octet-stream", "binary", "VMS Obj. Libr.", 1.0); + HTSetSuffix5(".tlb", "application/octet-stream", "binary", "VMS Text Libr.", 1.0); + HTSetSuffix5(".obj", "application/octet-stream", "binary", "Prog. Object", 1.0); + HTSetSuffix5(".decw$book", "application/octet-stream", "binary", "DEC BookReader", 1.0); + HTSetSuffix5(".mem", "text/x-runoff-manual", "8bit", "RUNOFF-MANUAL", 1.0); +#endif HTSetSuffix(".vsd", "application/visio", "binary", 1.0); - HTSetSuffix(".lha", "application/x-lha File", "binary", 1.0); - HTSetSuffix(".lzh", "application/x-lzh File", "binary", 1.0); - - HTSetSuffix(".sea", "application/x-sea File", "binary", 1.0); - HTSetSuffix(".sit", "application/x-sit File", "binary", 1.0); - - HTSetSuffix(".dms", "application/x-dms File", "binary", 1.0); - - HTSetSuffix(".iff", "application/x-iff File", "binary", 1.0); + HTSetSuffix5(".lha", "application/x-lha", "binary", "lha File", 1.0); + HTSetSuffix5(".lzh", "application/x-lzh", "binary", "lzh File", 1.0); + HTSetSuffix5(".sea", "application/x-sea", "binary", "sea File", 1.0); +#ifdef TRADITIONAL_SUFFIXES + HTSetSuffix5(".sit", "application/x-sit", "binary", "sit File", 1.0); +#else + HTSetSuffix5(".sit", "application/x-stuffit", "binary", "StuffIt", 1.0); +#endif + HTSetSuffix5(".dms", "application/x-dms", "binary", "dms File", 1.0); + HTSetSuffix5(".iff", "application/x-iff", "binary", "iff File", 1.0); HTSetSuffix(".bcpio", "application/x-bcpio", "binary", 1.0); HTSetSuffix(".cpio", "application/x-cpio", "binary", 1.0); +#ifdef TRADITIONAL_SUFFIXES HTSetSuffix(".gtar", "application/x-gtar", "binary", 1.0); +#endif HTSetSuffix(".shar", "application/x-shar", "8bit", 1.0); HTSetSuffix(".share", "application/x-share", "8bit", 1.0); +#ifdef TRADITIONAL_SUFFIXES HTSetSuffix(".sh", "application/x-sh", "8bit", 1.0); /* xtra */ +#endif HTSetSuffix(".sv4cpio", "application/x-sv4cpio", "binary", 1.0); HTSetSuffix(".sv4crc", "application/x-sv4crc", "binary", 1.0); @@ -908,6 +1019,31 @@ PUBLIC void HTFileInit NOARGS HTSetSuffix(".htm", "text/html", "8bit", 1.0); HTSetSuffix(".html", "text/html", "8bit", 1.0); + } else { /* LYSuffixRules */ + /* + * Note that even .html -> text/html, .htm -> text/html are omitted + * if default maps are compiled in but then skipped because of a + * configuration file directive. Whoever changes the config file + * in this way can easily also add the SUFFIX rules there. - kw + */ + CTRACE((tfp, "HTFileInit: Skipping all default (HTInit) extension maps!\n")); + } /* LYSuffixRules */ + +#else /* BUILTIN_SUFFIX_MAPS */ + + CTRACE((tfp, "HTFileInit: Default (HTInit) extension maps not compiled in.\n")); + /* + * The followin two are still used if BUILTIN_SUFFIX_MAPS was + * undefined. Without one of them, lynx would always need to + * have a mapping specified in a lynx.cfg or mime.types file + * to be usable for local HTML files at all. That includes + * many of the generated user interface pages. - kw + */ + HTSetSuffix(".htm", "text/html", "8bit", 1.0); + HTSetSuffix(".html", "text/html", "8bit", 1.0); +#endif /* BUILTIN_SUFFIX_MAPS */ + + /* These should override the default extensions as necessary. */ HTLoadExtensionsConfigFile(global_extension_map); diff --git a/src/HTML.c b/src/HTML.c index 01a6aabb..464a05b1 100644 --- a/src/HTML.c +++ b/src/HTML.c @@ -109,7 +109,8 @@ PRIVATE HTStyleSheet * styleSheet = NULL; /* Application-wide */ /* Module-wide style cache */ -PRIVATE HTStyle *styles[HTML_ELEMENTS+31]; /* adding 24 nested list styles */ +PRIVATE HTStyle *styles[HTML_ELEMENTS+HTML_EXTRA_ELEMENTS]; + /* adding 24 nested list styles */ /* and 3 header alignment styles */ /* and 3 div alignment styles */ PRIVATE HTStyle *default_style = NULL; @@ -123,11 +124,11 @@ PRIVATE int i_prior_style = -1; /* * Private function.... */ -PRIVATE void HTML_end_element PARAMS((HTStructured *me, +PRIVATE int HTML_end_element PARAMS((HTStructured *me, int element_number, char **include)); -PRIVATE void HTML_start_element PARAMS(( +PRIVATE int HTML_start_element PARAMS(( HTStructured * me, int element_number, CONST BOOL* present, @@ -236,7 +237,7 @@ PUBLIC void HTML_put_character ARGS2(HTStructured *, me, char, c) * Ignore all non-MAP content when just * scanning a document for MAPs. - FM */ - if (LYMapsOnly) + if (LYMapsOnly && me->sp[0].tag_number != HTML_OBJECT) return; /* @@ -465,7 +466,7 @@ PUBLIC void HTML_put_string ARGS2(HTStructured *, me, CONST char *, s) char* translated_string = NULL; #endif - if (LYMapsOnly || s == NULL) + if (s == NULL || (LYMapsOnly && me->sp[0].tag_number != HTML_OBJECT)) return; #ifdef USE_PSRC if (psrc_convert_string) { @@ -623,10 +624,10 @@ PUBLIC void HTML_write ARGS3(HTStructured *, me, CONST char*, s, int, l) CONST char* p; CONST char* e = s+l; - if (LYMapsOnly) + if (LYMapsOnly && me->sp[0].tag_number != HTML_OBJECT) return; - for (p = s; s < e; p++) + for (p = s; p < e; p++) HTML_put_character(me, *p); } @@ -759,10 +760,159 @@ PRIVATE void HTMLSRC_apply_markup ARGS4( #endif /* USE_PSRC*/ +PRIVATE void LYStartArea ARGS5( + HTStructured *, obj, + CONST char *, href, + CONST char *, alt, + CONST char *, title, + int, tag_charset) +{ + BOOL new_present[HTML_AREA_ATTRIBUTES]; + CONST char * new_value[HTML_AREA_ATTRIBUTES]; + int i; + + for (i = 0; i < HTML_AREA_ATTRIBUTES; i++) + new_present[i] = NO; + + if (alt) { + new_present[HTML_AREA_ALT] = YES; + new_value[HTML_AREA_ALT] = (CONST char *)alt; + } + if (title && *title) { + new_present[HTML_AREA_TITLE] = YES; + new_value[HTML_AREA_TITLE] = (CONST char *)title; + } + if (href) { + new_present[HTML_AREA_HREF] = YES; + new_value[HTML_AREA_HREF] = (CONST char *)href; + } + + (*obj->isa->start_element)(obj, HTML_AREA, new_present, new_value, + tag_charset, 0); +} + +PRIVATE void LYHandleFIG ARGS9( + HTStructured *, me, + CONST BOOL*, present, + CONST char **, value, + BOOL, isobject, + BOOL, imagemap, + CONST char *, id, + CONST char *, src, + BOOL, convert, + BOOL, start) +{ + if (start == TRUE) { + me->inFIG = TRUE; + if (me->inA) { + SET_SKIP_STACK(HTML_A); + HTML_end_element(me, HTML_A, NULL); + } + if (!isobject) { + LYEnsureDoubleSpace(me); + LYResetParagraphAlignment(me); + me->inFIGwithP = TRUE; + } else { + me->inFIGwithP = FALSE; + HTML_put_character(me, ' '); /* space char may be ignored */ + } + if (id && *id) { + if (present && convert) { + CHECK_ID(HTML_FIG_ID); + } else + LYHandleID(me, id); + } + me->in_word = NO; + me->inP = FALSE; + + if (clickable_images && src && src != '\0') { + char *href = NULL; + StrAllocCopy(href, src); + CHECK_FOR_INTERN(href); + LYLegitimizeHREF(me, &href, TRUE, TRUE); + if (*href) { + char *temp = NULL; + /* + * Check whether a base tag is in effect. - FM + */ + if ((me->inBASE && *href != '#') && + (temp = HTParse(href, me->base_href, PARSE_ALL)) && + *temp != '\0') + /* + * Use reference related to the base. + */ + StrAllocCopy(href, temp); + FREE(temp); + + /* + * Check whether to fill in localhost. - FM + */ + LYFillLocalFileURL(&href, + ((*href != '#' && + me->inBASE) ? + me->base_href : me->node_anchor->address)); + + me->CurrentA = HTAnchor_findChildAndLink( + me->node_anchor, /* Parent */ + NULL, /* Tag */ + href, /* Addresss */ + INTERN_LT); /* Type */ + HText_beginAnchor(me->text, me->inUnderline, me->CurrentA); + if (me->inBoldH == FALSE) + HText_appendCharacter(me->text, LY_BOLD_START_CHAR); + HTML_put_string(me, (isobject ? + (imagemap ? "(IMAGE)" : "(OBJECT)") : "[FIGURE]")); + if (me->inBoldH == FALSE) + HText_appendCharacter(me->text, LY_BOLD_END_CHAR); + HText_endAnchor(me->text, 0); + HTML_put_character(me, '-'); + HTML_put_character(me, ' '); /* space char may be ignored */ + me->in_word = NO; + } + FREE(href); + } + } else { /* handle end tag */ + if (me->inFIGwithP) { + LYEnsureDoubleSpace(me); + } else { + HTML_put_character(me, ' '); /* space char may be ignored */ + } + LYResetParagraphAlignment(me); + me->inFIGwithP = FALSE; + me->inFIG = FALSE; + change_paragraph_style(me, me->sp->style); /* Often won't really change */ + if (me->List_Nesting_Level >= 0) { + UPDATE_STYLE; + HText_NegateLineOne(me->text); + } + } +} + +PRIVATE void clear_objectdata ARGS1( + HTStructured *, me) +{ + if (me) { + HTChunkClear(&me->object); + me->object_started = FALSE; + me->object_declare = FALSE; + me->object_shapes = FALSE; + me->object_ismap = FALSE; + FREE(me->object_usemap); + FREE(me->object_id); + FREE(me->object_title); + FREE(me->object_data); + FREE(me->object_type); + FREE(me->object_classid); + FREE(me->object_codebase); + FREE(me->object_codetype); + FREE(me->object_name); + } +} + /* Start Element ** ------------- */ -PRIVATE void HTML_start_element ARGS6( +PRIVATE int HTML_start_element ARGS6( HTStructured *, me, int, element_number, CONST BOOL*, present, @@ -787,8 +937,10 @@ PRIVATE void HTML_start_element ARGS6( HTChildAnchor *ID_A = NULL; /* HTML_foo_ID anchor */ int url_type = 0, i = 0; char *cp = NULL; - int ElementNumber = element_number; + HTMLElement ElementNumber = element_number; BOOL intern_flag = FALSE; + short stbl_align = HT_ALIGN_NONE; + int status = HT_OK; #ifdef USE_COLOR_STYLE char* class_name; # if OPT_SCN @@ -883,7 +1035,7 @@ PRIVATE void HTML_start_element ARGS6( PSRCSTOP(tag); PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); psrc_nested_call=FALSE; - return; + return HT_OK; } /*if (!psrc_nested_call) */ /*fall through*/ } @@ -891,8 +1043,9 @@ PRIVATE void HTML_start_element ARGS6( if (LYMapsOnly) { if (!(ElementNumber == HTML_MAP || ElementNumber == HTML_AREA || - ElementNumber == HTML_BASE)) { - return; + ElementNumber == HTML_BASE || ElementNumber == HTML_OBJECT || + ElementNumber == HTML_A)) { + return HT_OK; } } else if (!me->text) { UPDATE_STYLE; @@ -1461,6 +1614,12 @@ PRIVATE void HTML_start_element ARGS6( HText_beginAnchor(me->text, me->inUnderline, ID_A); HText_endAnchor(me->text, 0); HText_setToolbar(me->text); + } else { + /* + * Add collapsible space to separate link from previous + * generated links. - kw + */ + HTML_put_character(me, ' '); } HText_beginAnchor(me->text, me->inUnderline, me->CurrentA); if (me->inBoldH == FALSE) @@ -1740,7 +1899,7 @@ PRIVATE void HTML_start_element ARGS6( case HTML_MARQUEE: change_paragraph_style(me, styles[HTML_BANNER]); UPDATE_STYLE; - if (me->sp->tag_number == ElementNumber) + if (me->sp->tag_number == (int) ElementNumber) LYEnsureDoubleSpace(me); /* * Treat this as a toolbar if we don't have one @@ -2062,6 +2221,13 @@ PRIVATE void HTML_start_element ARGS6( CTRACE((tfp, "HTML: TAB tag has no attributes. Ignored.\n")); break; } + /* + * If page author is using TAB within a TABLE, it's probably + * formatted specifically to work well for Lynx without simple + * table tracking code. Cancel tracking, it would only make + * things worse. - kw + */ + HText_cancelStbl(me->text); UPDATE_STYLE; CANT_JUSTIFY_THIS_LINE @@ -2215,13 +2381,23 @@ PRIVATE void HTML_start_element ARGS6( case HTML_KBD: case HTML_SAMP: case HTML_SMALL: - case HTML_SUB: - case HTML_SUP: case HTML_TT: case HTML_VAR: CHECK_ID(HTML_GEN_ID); break; /* ignore */ + case HTML_SUP: + if (isxdigit((unsigned char)HText_getLastChar(me->text))) { + HText_appendCharacter(me->text, '^'); + } + CHECK_ID(HTML_GEN_ID); + break; + + case HTML_SUB: + HText_appendCharacter(me->text, '['); + CHECK_ID(HTML_GEN_ID); + break; + case HTML_DEL: case HTML_S: case HTML_STRIKE: @@ -2285,7 +2461,7 @@ PRIVATE void HTML_start_element ARGS6( case HTML_BQ: change_paragraph_style(me, styles[ElementNumber]); UPDATE_STYLE; - if (me->sp->tag_number == ElementNumber) + if (me->sp->tag_number == (int) ElementNumber) LYEnsureDoubleSpace(me); CHECK_ID(HTML_BQ_ID); break; @@ -2293,7 +2469,7 @@ PRIVATE void HTML_start_element ARGS6( case HTML_NOTE: change_paragraph_style(me, styles[ElementNumber]); UPDATE_STYLE; - if (me->sp->tag_number == ElementNumber) + if (me->sp->tag_number == (int) ElementNumber) LYEnsureDoubleSpace(me); CHECK_ID(HTML_NOTE_ID); { @@ -2337,7 +2513,7 @@ PRIVATE void HTML_start_element ARGS6( case HTML_ADDRESS: change_paragraph_style(me, styles[ElementNumber]); UPDATE_STYLE; - if (me->sp->tag_number == ElementNumber) + if (me->sp->tag_number == (int) ElementNumber) LYEnsureDoubleSpace(me); CHECK_ID(HTML_ADDRESS_ID); break; @@ -2778,7 +2954,7 @@ PRIVATE void HTML_start_element ARGS6( case HTML_FN: change_paragraph_style(me, styles[ElementNumber]); UPDATE_STYLE; - if (me->sp->tag_number == ElementNumber) + if (me->sp->tag_number == (int) ElementNumber) LYEnsureDoubleSpace(me); CHECK_ID(HTML_FN_ID); if (me->inUnderline == FALSE) @@ -2794,6 +2970,25 @@ PRIVATE void HTML_start_element ARGS6( break; case HTML_A: + /* + * If we are looking for client-side image maps, + * then handle an A within a MAP that has a COORDS + * attribute as an AREA tag. Unfortunately we lose + * the anchor text this way for the LYNXIMGMAP, we + * would have to do much more parsing to collect it. + * After potentially handling the A as AREA, always return + * immediately if only looking for image maps, without + * pushing anything on the style stack. - kw + */ + if (me->map_address && present && present[HTML_A_COORDS]) + LYStartArea(me, + present[HTML_A_HREF] ? value[HTML_A_HREF] : NULL, + NULL, + present[HTML_A_TITLE] ? value[HTML_A_TITLE] : NULL, + tag_charset); + if (LYMapsOnly) { + return HT_OK; + } /* * A may have been declared SGML_EMPTY in HTMLDTD.c, and * SGML_character() in SGML.c may check for an A end @@ -3533,6 +3728,16 @@ PRIVATE void HTML_start_element ARGS6( } /* + * Generate a target anchor in this place in the containing + * document. MAP can now contain block markup, if it doesn't + * contain any AREAs (or A anchors with COORDS converted to AREAs) + * the current location can be used as a fallback for following + * a USEMAP link. - kw + */ + if (!LYMapsOnly) + LYHandleID(me, id_string); + + /* * Load map_address. - FM */ if (id_string) { @@ -3677,6 +3882,20 @@ PRIVATE void HTML_start_element ARGS6( break; case HTML_FIG: + if (present) + LYHandleFIG(me, present, value, + present[HTML_FIG_ISOBJECT], + present[HTML_FIG_IMAGEMAP], + present[HTML_FIG_ID] ? value[HTML_FIG_ID] : NULL, + present[HTML_FIG_SRC] ? value[HTML_FIG_SRC] : NULL, + YES, TRUE); + else + LYHandleFIG(me, NULL, NULL, + 0, + 0, + NULL, + NULL, YES, TRUE); +#if 0 me->inFIG = TRUE; if (me->inA) { SET_SKIP_STACK(HTML_A); @@ -3741,6 +3960,7 @@ PRIVATE void HTML_start_element ARGS6( } FREE(href); } +#endif break; case HTML_OBJECT: @@ -3847,9 +4067,81 @@ PRIVATE void HTML_start_element ARGS6( } } /* - * Set flag that we are accumulating OBJECT content. - FM + * If we can determine now that we are not going to do anything + * special to the OBJECT element's SGML contents, like skipping + * it completely or collecting it up in order to add something + * after it, then generate any output that should be emitted in the + * place of the OBJECT start tag NOW, then don't initialize special + * handling but return, letting our SGML parser know that further + * content is to be parsed normally not literally. We could defer + * this until we have collected the contents and then recycle the + * contents (as was previously always done), but that has a higher + * chance of completely losing content in case of nesting errors + * in the input, incomplete transmissions, etc. - kw */ - me->object_started = TRUE; + if ((!present || + (me->object_declare == FALSE && me->object_name == NULL && + me->object_shapes == FALSE && me->object_usemap == NULL))) { + if (!LYMapsOnly) { + if (!clickable_images || me->object_data == NULL || + !(me->object_data != NULL && + me->object_classid == NULL && + me->object_codebase == NULL && + me->object_codetype == NULL)) + FREE(me->object_data); + if (me->object_data) { + HTStartAnchor5(me, + me->object_id ? value[HTML_OBJECT_ID] + : NULL, + value[HTML_OBJECT_DATA], + value[HTML_OBJECT_TYPE], + tag_charset); + if ((me->object_type != NULL) && + !strncasecomp(me->object_type, "image/", 6)) + HTML_put_string(me, "(IMAGE)"); + else + HTML_put_string(me, "(OBJECT)"); + HTML_end_element(me,HTML_A,NULL); + } else if (me->object_id) + LYHandleID(me, me->object_id); + } + clear_objectdata(me); + /* + * We do NOT want the HTML_put_* functions that are going + * to be called for the OBJECT's character content to + * add to the chunk, so we don't push on the stack. + * Instead we keep a counter for open OBJECT tags that + * are treated this way, so HTML_end_element can skip + * handling the corresponding end tag that is going to + * arrive unexpectedly as far as our stack is concerned. + */ + status = HT_PARSER_OTHER_CONTENT; + if (me->sp[0].tag_number == HTML_FIG && + me->objects_figged_open > 0) { + ElementNumber = HTML_OBJECT_M; + } else { + me->objects_mixed_open++; + SET_SKIP_STACK(HTML_OBJECT); + } + } else if (me->object_declare == FALSE && me->object_name == NULL && + me->object_shapes == TRUE) { + LYHandleFIG(me, present, value, + 1, + 1 || me->object_ismap, + me->object_id, + (me->object_data && !me->object_classid) ? value[HTML_OBJECT_DATA] : NULL, + NO, TRUE); + clear_objectdata(me); + status = HT_PARSER_OTHER_CONTENT; + me->objects_figged_open++; + ElementNumber = HTML_FIG; + + } else { + /* + * Set flag that we are accumulating OBJECT content. - FM + */ + me->object_started = TRUE; + } } break; @@ -5477,11 +5769,22 @@ PRIVATE void HTML_start_element ARGS6( case HTML_TABLE: /* - * Not implemented. Just treat as a division + * Not fully implemented. Just treat as a division * with respect to any ALIGN attribute, with * a default of HT_LEFT, or leave as a PRE * block if we are presently in one. - FM + * + * Also notify simple table tracking code unless + * in a preformatted section, or (currently) non-left + * alignment. But first cancel tracking any already + * open (enclosing) table. + * + * If page author is using a TABLE within PRE, it's probably + * formatted specifically to work well for Lynx without simple + * table tracking code. Cancel tracking, it would only make + * things worse. - kw */ + HText_cancelStbl(me->text); if (me->inA) { SET_SKIP_STACK(HTML_A); HTML_end_element(me, HTML_A, include); @@ -5525,33 +5828,41 @@ PRIVATE void HTML_start_element ARGS6( change_paragraph_style(me, styles[HTML_DCENTER]); UPDATE_STYLE; me->current_default_alignment = styles[HTML_DCENTER]->alignment; - #endif + stbl_align = HT_CENTER; + } else if (!strcasecomp(value[HTML_TABLE_ALIGN], "right")) { me->DivisionAlignments[me->Division_Level] = HT_RIGHT; change_paragraph_style(me, styles[HTML_DRIGHT]); UPDATE_STYLE; me->current_default_alignment = styles[HTML_DRIGHT]->alignment; + stbl_align = HT_RIGHT; } else { me->DivisionAlignments[me->Division_Level] = HT_LEFT; change_paragraph_style(me, styles[HTML_DLEFT]); UPDATE_STYLE; me->current_default_alignment = styles[HTML_DLEFT]->alignment; + if (!strcasecomp(value[HTML_TABLE_ALIGN], "left") || + !strcasecomp(value[HTML_TABLE_ALIGN], "justify")) + stbl_align = HT_LEFT; } } else { me->DivisionAlignments[me->Division_Level] = HT_LEFT; change_paragraph_style(me, styles[HTML_DLEFT]); UPDATE_STYLE; me->current_default_alignment = styles[HTML_DLEFT]->alignment; + /* stbl_align remains HT_ALIGN_NONE */ } CHECK_ID(HTML_TABLE_ID); + HText_startStblTABLE(me->text, stbl_align); break; case HTML_TR: /* - * Not yet implemented. Just start a new row, + * Not fully implemented. Just start a new row, * if needed, act on an ALIGN attribute if present, * and check for an ID link. - FM + * Also notify simple table tracking code. - kw */ if (me->inA) { SET_SKIP_STACK(HTML_A); @@ -5571,6 +5882,7 @@ PRIVATE void HTML_start_element ARGS6( if (!strcmp(me->sp->style->name, "Preformatted")) { CHECK_ID(HTML_TR_ID); me->inP = FALSE; +/* HText_cancelStbl(me->text); seems unnecessary here - kw */ break; } if (LYoverride_default_alignment(me)) { @@ -5584,33 +5896,37 @@ PRIVATE void HTML_start_element ARGS6( me->sp->style->alignment = (short) me->current_default_alignment; } if (present && present[HTML_TR_ALIGN] && value[HTML_TR_ALIGN]) { -#ifdef SH_EX if (!strcasecomp(value[HTML_TR_ALIGN], "center") && - !(me->List_Nesting_Level >= 0 && !me->inP)) + !(me->List_Nesting_Level >= 0 && !me->inP)) { +#ifdef SH_EX if (no_table_center) me->sp->style->alignment = HT_LEFT; else me->sp->style->alignment = HT_CENTER; #else - if (!strcasecomp(value[HTML_TR_ALIGN], "center") && - !(me->List_Nesting_Level >= 0 && !me->inP)) me->sp->style->alignment = HT_CENTER; #endif - else if (!strcasecomp(value[HTML_TR_ALIGN], "right") && - !(me->List_Nesting_Level >= 0 && !me->inP)) + stbl_align = HT_CENTER; + } else if (!strcasecomp(value[HTML_TR_ALIGN], "right") && + !(me->List_Nesting_Level >= 0 && !me->inP)) { me->sp->style->alignment = HT_RIGHT; - else if (!strcasecomp(value[HTML_TR_ALIGN], "left") || - !strcasecomp(value[HTML_TR_ALIGN], "justify")) + stbl_align = HT_RIGHT; + } else if (!strcasecomp(value[HTML_TR_ALIGN], "left") || + !strcasecomp(value[HTML_TR_ALIGN], "justify")) { me->sp->style->alignment = HT_LEFT; + stbl_align = HT_LEFT; + } } CHECK_ID(HTML_TR_ID); me->inP = FALSE; + HText_startStblTR(me->text, stbl_align); break; case HTML_THEAD: case HTML_TFOOT: case HTML_TBODY: + HText_endStblTR(me->text); /* * Not yet implemented. Just check for an ID link. - FM */ @@ -5639,28 +5955,12 @@ PRIVATE void HTML_start_element ARGS6( SET_SKIP_STACK(HTML_U); HTML_end_element(me, HTML_U, include); } +/* HText_cancelStbl(me->text); we ingnore it instead - kw */ UPDATE_STYLE; CHECK_ID(HTML_COL_ID); break; case HTML_TH: - if (me->inA) { - SET_SKIP_STACK(HTML_A); - HTML_end_element(me, HTML_A, include); - } - if (me->Underline_Level > 0) { - SET_SKIP_STACK(HTML_U); - HTML_end_element(me, HTML_U, include); - } - UPDATE_STYLE; - CHECK_ID(HTML_TD_ID); - /* - * Not yet implemented. Just add a collapsible space and break. - FM - */ - HTML_put_character(me, ' '); - me->in_word = NO; - break; - case HTML_TD: if (me->inA) { SET_SKIP_STACK(HTML_A); @@ -5673,9 +5973,29 @@ PRIVATE void HTML_start_element ARGS6( UPDATE_STYLE; CHECK_ID(HTML_TD_ID); /* - * Not yet implemented. Just add a collapsible space and break. - FM + * Not fully implemented. Just add a collapsible space and break. - FM + * Also notify simple table tracking code. - kw */ HTML_put_character(me, ' '); + { + int colspan = 1; + if (present && present[HTML_TD_COLSPAN] && + value[HTML_TD_COLSPAN] && + isdigit((unsigned char)*value[HTML_TD_COLSPAN])) + colspan = atoi(value[HTML_TD_COLSPAN]); + if (present && present[HTML_TD_ALIGN] && value[HTML_TD_ALIGN]) { + if (!strcasecomp(value[HTML_TD_ALIGN], "center")) { + stbl_align = HT_CENTER; + } else if (!strcasecomp(value[HTML_TD_ALIGN], "right")) { + stbl_align = HT_RIGHT; + } else if (!strcasecomp(value[HTML_TD_ALIGN], "left") || + !strcasecomp(value[HTML_TD_ALIGN], "justify")) { + stbl_align = HT_LEFT; + } + } + HText_startStblTD(me->text, colspan, stbl_align, + (ElementNumber == HTML_TH)); + } me->in_word = NO; break; @@ -5693,13 +6013,14 @@ PRIVATE void HTML_start_element ARGS6( } /* end switch */ - if (HTML_dtd.tags[ElementNumber].contents != SGML_EMPTY) { + if (ElementNumber >= HTML_ELEMENTS || + HTML_dtd.tags[ElementNumber].contents != SGML_EMPTY) { if (me->skip_stack > 0) { CTRACE((tfp, "HTML:begin_element: internal call (level %d), leaving on stack - `%s'\n", me->skip_stack, me->sp->style->name)); me->skip_stack--; - return; + return status; } if (me->sp == me->stack) { if (me->stack_overrun == FALSE) { @@ -5713,7 +6034,7 @@ PRIVATE void HTML_start_element ARGS6( } me->stack_overrun = TRUE; } - return; + return HT_ERROR; } CTRACE((tfp,"HTML:begin_element[%d]: adding style to stack - %s\n", @@ -5738,10 +6059,8 @@ PRIVATE void HTML_start_element ARGS6( #if defined(USE_COLOR_STYLE) /* end really empty tags straight away */ -#define REALLY_EMPTY(e) ((HTML_dtd.tags[e].contents == SGML_EMPTY) && \ - !(HTML_dtd.tags[e].flags & Tgf_nreie)) - if (REALLY_EMPTY(element_number)) + if (ReallyEmptyTagNum(element_number)) { CTRACE((tfp, "STYLE:begin_element:ending EMPTY element style\n")); #if !defined(USE_HASH) @@ -5763,6 +6082,7 @@ PRIVATE void HTML_start_element ARGS6( #endif } #endif /* USE_COLOR_STYLE */ + return status; } /* End Element @@ -5779,12 +6099,13 @@ PRIVATE void HTML_start_element ARGS6( ** (internal code errors apart) good nesting. The parser checks ** incoming code errors, not this module. */ -PRIVATE void HTML_end_element ARGS3( +PRIVATE int HTML_end_element ARGS3( HTStructured *, me, int, element_number, char **, include) { int i = 0; + int status = HT_OK; char *temp = NULL, *cp = NULL; BOOL BreakFlag = FALSE; EMIT_IFDEF_EXP_JUSTIFY_ELTS(BOOL reached_awaited_stacked_elt=FALSE;) @@ -5809,30 +6130,35 @@ PRIVATE void HTML_end_element ARGS3( PSRCSTOP(tag); PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); psrc_nested_call=FALSE; - return; + return HT_OK; } /*fall through*/ } #endif -#ifdef CAREFUL /* parser assumed to produce good nesting */ - if (element_number != me->sp[0].tag_number && + if ((me->sp >= (me->stack + MAX_NESTING - 1) || + element_number != me->sp[0].tag_number) && HTML_dtd.tags[element_number].contents != SGML_EMPTY) { CTRACE((tfp, - "HTMLText: end of element %s when expecting end of %s\n", + "HTML: end of element %s when expecting end of %s\n", HTML_dtd.tags[element_number].name, + (me->sp == me->stack + MAX_NESTING - 1) ? "none" : + (me->sp->tag_number < 0) ? "*invalid tag*" : + (me->sp->tag_number >= HTML_ELEMENTS) ? "special tag" : HTML_dtd.tags[me->sp->tag_number].name)); +#ifdef CAREFUL /* parser assumed to produce good nesting */ /* panic */ - } #endif /* CAREFUL */ + } /* * If we're seeking MAPs, skip everything that's * not a MAP or AREA tag. - FM */ if (LYMapsOnly) { - if (!(element_number == HTML_MAP || element_number == HTML_AREA)) { - return; + if (!(element_number == HTML_MAP || element_number == HTML_AREA || + element_number == HTML_OBJECT)) { + return HT_OK; } } @@ -5862,10 +6188,32 @@ PRIVATE void HTML_end_element ARGS3( */ BreakFlag = TRUE; } + if (me->skip_stack == 0 && element_number == HTML_OBJECT && + me->sp[0].tag_number == HTML_OBJECT_M && + (me->sp < (me->stack + MAX_NESTING - 1))) + me->sp[0].tag_number = HTML_OBJECT; if (me->skip_stack > 0) { CTRACE((tfp, "HTML:end_element: Internal call (level %d), leaving on stack - %s\n", me->skip_stack, me->sp->style->name)); me->skip_stack--; + } else if (element_number == HTML_OBJECT && + me->sp[0].tag_number != HTML_OBJECT && + me->sp[0].tag_number != HTML_OBJECT_M && + me->objects_mixed_open > 0 && + !(me->objects_figged_open > 0 && + me->sp[0].tag_number == HTML_FIG)) { + /* + * Ignore non-corresponding OBJECT tags that we + * didn't push because the SGML parser was supposed + * to go on parsing the contents non-literally. - kw + */ + CTRACE((tfp, + "HTML:end_element[%d]: %s (level %d), %s - %s\n", + (int) STACKLEVEL(me), + "Special OBJECT handling", me->objects_mixed_open, + "leaving on stack", + me->sp->style->name)); + me->objects_mixed_open--; } else if (me->stack_overrun == TRUE && element_number != me->sp[0].tag_number) { /* @@ -5879,7 +6227,7 @@ PRIVATE void HTML_end_element ARGS3( * offer reasonable protection against crashes * if an overrun does occur. - FM */ - return; + return HT_OK; /* let's pretend... */ } else if (element_number == HTML_SELECT && me->sp[0].tag_number != HTML_SELECT) { /* @@ -5888,7 +6236,7 @@ PRIVATE void HTML_end_element ARGS3( * to deal with markup which amounts to a nested * SELECT, or an out of order FORM end tag. - FM */ - return; + return HT_OK; } else if ((element_number != me->sp[0].tag_number) && HTML_dtd.tags[HTML_LH].contents == SGML_EMPTY && (me->sp[0].tag_number == HTML_UL || @@ -5907,12 +6255,30 @@ PRIVATE void HTML_end_element ARGS3( * an HTML_LH, which we've declared as * SGML_EMPTY, so just return. - FM */ - return; + return HT_OK; } else if (me->sp < (me->stack + MAX_NESTING - 1)) { #ifdef EXP_JUSTIFY_ELTS if (wait_for_this_stacked_elt == me->stack - me->sp + MAX_NESTING) reached_awaited_stacked_elt = TRUE; #endif + if (element_number == HTML_OBJECT) { + if (me->sp[0].tag_number == HTML_FIG && + me->objects_figged_open > 0) { + /* + * It's an OBJECT for which we substituted a FIG, + * so pop the FIG and pretend that's what we are + * being called for. - kw + */ + CTRACE((tfp, + "HTML:end_element[%d]: %s (level %d), %s - %s\n", + (int) STACKLEVEL(me), + "Special OBJECT->FIG handling", me->objects_figged_open, + "treating as end FIG", + me->sp->style->name)); + me->objects_figged_open--; + element_number = HTML_FIG; + } + } (me->sp)++; CTRACE((tfp, "HTML:end_element[%d]: Popped style off stack - %s\n", (int) STACKLEVEL(me), @@ -5927,7 +6293,7 @@ PRIVATE void HTML_end_element ARGS3( if (reached_awaited_stacked_elt) wait_for_this_stacked_elt=-1; #endif - return; + return HT_OK; /* let's pretend... */ } /* @@ -6003,6 +6369,8 @@ PRIVATE void HTML_end_element ARGS3( if ((LYMultiBookmarks == TRUE) || ((bookmark_page && *bookmark_page) && strcmp(me->node_anchor->bookmark, bookmark_page))) { + if (!include) + include = &me->xinclude; for (i = 0; i <= MBM_V_MAXFILES; i++) { if (MBM_A_subbookmark[i] && !strcmp(MBM_A_subbookmark[i], @@ -6208,12 +6576,15 @@ PRIVATE void HTML_end_element ARGS3( case HTML_KBD: case HTML_SAMP: case HTML_SMALL: - case HTML_SUB: case HTML_SUP: case HTML_TT: case HTML_VAR: break; + case HTML_SUB: + HText_appendCharacter(me->text, ']'); + break; + case HTML_DEL: case HTML_S: case HTML_STRIKE: @@ -6362,19 +6733,11 @@ PRIVATE void HTML_end_element ARGS3( break; case HTML_FIG: - if (me->inFIGwithP) { - LYEnsureDoubleSpace(me); - } else { - HTML_put_character(me, ' '); /* space char may be ignored */ - } - LYResetParagraphAlignment(me); - me->inFIGwithP = FALSE; - me->inFIG = FALSE; - change_paragraph_style(me, me->sp->style); /* Often won't really change */ - if (me->List_Nesting_Level >= 0) { - UPDATE_STYLE; - HText_NegateLineOne(me->text); - } + LYHandleFIG(me, NULL, NULL, + 0, + 0, + NULL, + NULL, NO, FALSE); break; case HTML_OBJECT: @@ -6383,7 +6746,8 @@ PRIVATE void HTML_end_element ARGS3( */ { int s = 0, e = 0; - char *start = NULL, *first_end = NULL; + char *start = NULL, *first_end = NULL, *last_end = NULL; + char *first_map = NULL, *last_map = NULL; BOOL have_param = FALSE; char *data = NULL; @@ -6399,39 +6763,31 @@ PRIVATE void HTML_end_element ARGS3( if (!strncmp(cp, "<!--", 4)) { data = LYFindEndOfComment(cp); cp = data; - } else if (s == 0 && !strncasecomp(cp, "<PARAM", 6)) { + } else if (s == 0 && !strncasecomp(cp, "<PARAM", 6) && + !IsNmChar(cp[6])) { have_param = TRUE; - } else if (!strncasecomp(cp, "<OBJECT", 7)) { + } else if (!strncasecomp(cp, "<OBJECT", 7) && + !IsNmChar(cp[7])) { if (s == 0) start = cp; s++; - } else if (!strncasecomp(cp, "</OBJECT", 8)) { + } else if (!strncasecomp(cp, "</OBJECT", 8) && + !IsNmChar(cp[8])) { if (e == 0) first_end = cp; + last_end = cp; e++; + } else if (!strncasecomp(cp, "<MAP", 4) && + !IsNmChar(cp[4])) { + if (!first_map) + first_map = cp; + last_map = cp; + } else if (!strncasecomp(cp, "</MAP", 5) && + !IsNmChar(cp[5])) { + last_map = cp; } data = ++cp; } - if (s > e) { - /* - * We have nested OBJECT tags, and not yet all of the - * end tags, so restore an end tag to the content, and - * pass a dummy start tag to the SGML parser so that it - * will resume the accumulation of OBJECT content. - FM - */ - CTRACE((tfp, "HTML: Nested OBJECT tags. Recycling.\n")); - if (*include == NULL) { - StrAllocCopy(*include, "<OBJECT>"); - } else { - if (0 && strstr(*include, me->object.data) == NULL) { - StrAllocCat(*include, "<OBJECT>"); - } - } - me->object.size--; - HTChunkPuts(&me->object, "</OBJECT>"); - change_paragraph_style(me, me->sp->style); - break; - } if (s < e) { /* * We had more end tags than start tags, so @@ -6447,6 +6803,60 @@ PRIVATE void HTML_end_element ARGS3( } goto End_Object; } + if (s > e) { + if (!me->object_declare && !me->object_name && + !(me->object_shapes && !LYMapsOnly) && + !(me->object_usemap != NULL && !LYMapsOnly) && + !(clickable_images && !LYMapsOnly && + me->object_data != NULL && + !have_param && + me->object_classid == NULL && + me->object_codebase == NULL && + me->object_codetype == NULL)) { + /* + * We have nested OBJECT tags, and not yet all of the + * end tags, but have a case where the content needs + * to be parsed again (not dropped) and where we don't + * want to output anything special at the point when we + * *do* have accumulated all the end tags. So recycle + * the incomplete contents now, and signal the SGML + * parser that it should not regard the current OBJECT + * ended but should treat its contents as mixed. + * Normally these cases would have already handled + * in the real start_element call, so this block may + * not be necessary. - kw + */ + CTRACE((tfp, "%s:\n%s\n", + "HTML: Nested OBJECT tags. Recycling incomplete contents", + me->object.data)); + status = HT_PARSER_OTHER_CONTENT; + me->object.size--; + HTChunkPuts(&me->object, "</OBJECT>"); + if (!include) /* error, should not happen */ + include = &me->xinclude; + StrnAllocCat(*include, me->object.data, me->object.size); + clear_objectdata(me); + /* an internal fake call to keep our stack happy: */ + HTML_start_element(me, HTML_OBJECT, NULL,NULL, + me->tag_charset, include); + break; + } + /* + * We have nested OBJECT tags, and not yet all of the + * end tags, and we want the end tags. So restore an + * end tag to the content, and signal to the SGML parser + * that it should resume the accumulation of OBJECT content + * (after calling back to start_element) in a way that + * is equivalent to passing it a dummy start tag. - FM, kw + */ + CTRACE((tfp, "HTML: Nested OBJECT tags. Recycling.\n")); + status = HT_PARSER_REOPEN_ELT; + me->object.size--; + HTChunkPuts(&me->object, "</OBJECT>"); + if (!LYMapsOnly) + change_paragraph_style(me, me->sp->style); + break; + } /* * OBJECT start and end tags are fully matched, @@ -6464,7 +6874,7 @@ PRIVATE void HTML_end_element ARGS3( * the content (sigh 8-). - FM */ if (me->object_declare == TRUE) { - if (me->object_id && *me->object_id) + if (me->object_id && *me->object_id && !LYMapsOnly) LYHandleID(me, me->object_id); CTRACE((tfp, "HTML: DECLAREd OBJECT. Ignoring!\n")); goto End_Object; @@ -6476,7 +6886,7 @@ PRIVATE void HTML_end_element ARGS3( * present, and discard the content until we * have code to handle these. (sigh 8-). - FM */ - if (me->object_name != NULL) { + if (me->object_name != NULL && !LYMapsOnly) { if (me->object_id && *me->object_id) LYHandleID(me, me->object_id); CTRACE((tfp, "HTML: NAMEd OBJECT. Ignoring!\n")); @@ -6495,20 +6905,36 @@ PRIVATE void HTML_end_element ARGS3( * to have succeeded are met. We'll hope that * it did succeed. - FM */ - *first_end = '\0'; - data = NULL; - StrAllocCopy(data, start); - if (e > 1) { - for (i = e; i > 1; i--) { - StrAllocCat(data, "</OBJECT><OBJECT>"); + if (LYMapsOnly) { + /* + * Well we don't need to do this any more, + * nested objects should either not get here + * any more at all or can be handled fine by + * other code below. Leave in place for now + * as a special case for LYMapsOnly. - kw + */ + if (LYMapsOnly && (!last_map || last_map < first_end)) + *first_end = '\0'; + else + e = 0; + data = NULL; + if (LYMapsOnly && (!first_map || first_map > start)) + StrAllocCopy(data, start); + else + StrAllocCopy(data, me->object.data); + if (e > 0) { + for (i = e; i > 0; i--) { + StrAllocCat(data, "</OBJECT>"); + } } + if (!include) /* error, should not happen */ + include = &me->xinclude; + StrAllocCat(*include, data); + CTRACE((tfp, "HTML: Recycling nested OBJECT%s.\n", + (s > 1) ? "s" : "")); + FREE(data); + goto End_Object; } - StrAllocCat(data, "</OBJECT>"); - StrAllocCat(*include, data); - CTRACE((tfp, "HTML: Recycling nested OBJECT%s.\n", - (e > 1) ? "s" : "")); - FREE(data); - goto End_Object; } else { if (TRACE) { fprintf(tfp, @@ -6522,10 +6948,16 @@ PRIVATE void HTML_end_element ARGS3( } /* - * If it's content has SHAPES, convert it to FIG. - FM + * If its content has SHAPES, convert it to FIG. - FM + * + * This is now handled in our start_element without using + * include if the SGML parser cooperates, so this block + * may be unnecessary. - kw */ - if (me->object_shapes == TRUE) { + if (me->object_shapes == TRUE && !LYMapsOnly) { CTRACE((tfp, "HTML: OBJECT has SHAPES. Converting to FIG.\n")); + if (!include) /* error, should not happen */ + include = &me->xinclude; StrAllocCat(*include, "<FIG ISOBJECT IMAGEMAP"); if (me->object_ismap == TRUE) StrAllocCat(*include, " IMAGEMAP"); @@ -6552,9 +6984,11 @@ PRIVATE void HTML_end_element ARGS3( * If it has a USEMAP attribute and didn't have SHAPES, * convert it to IMG. - FM */ - if (me->object_usemap != NULL) { + if (me->object_usemap != NULL && !LYMapsOnly) { CTRACE((tfp, "HTML: OBJECT has USEMAP. Converting to IMG.\n")); + if (!include) /* error, should not happen */ + include = &me->xinclude; StrAllocCat(*include, "<IMG ISOBJECT"); if (me->object_id != NULL) { /* @@ -6598,20 +7032,70 @@ PRIVATE void HTML_end_element ARGS3( } else { StrAllocCat(*include, ">"); } + /* + * Add the content if it has <MAP, since that may + * be the MAP this usemap points to. But if we have + * nested objects, try to eliminate portions that + * cannot contribute to the quest for MAP. This is + * not perfect, we may get too much content; this seems + * preferable over losing too much. - kw + */ + if (first_map) { + if (s == 0) { + StrAllocCat(*include, me->object.data); + CTRACE((tfp, "HTML: MAP found, recycling object contents.\n")); + goto End_Object; + } + /* s > 0 and s == e */ + data = NULL; + if (last_map < start) { + *start = '\0'; + i = 0; + } else if (last_map < first_end) { + *first_end = '\0'; + i = e; + } else if (last_map < last_end) { + *last_end = '\0'; + i = 1; + } else { + i = 0; + } + if (first_map > last_end) { + /* fake empty object to keep stacks stack happy */ + StrAllocCopy(data, "<OBJECT><"); + StrAllocCat(data, last_end + 1); + i = 0; + } else if (first_map > start) { + StrAllocCopy(data, start); + } else { + StrAllocCopy(data, me->object.data); + } + for (; i > 0; i--) { + StrAllocCat(data, "</OBJECT>"); + } + CTRACE((tfp, "%s:\n%s\n", + "HTML: MAP and nested OBJECT tags. Recycling parts", + data)); + StrAllocCat(*include, data); + FREE(data); + } goto End_Object; } /* * Add an ID link if needed. - FM */ - if (me->object_id && *me->object_id) + if (me->object_id && *me->object_id && !LYMapsOnly) LYHandleID(me, me->object_id); /* * Add the OBJECTs content if not empty. - FM */ - if (me->object.size > 1) + if (me->object.size > 1) { + if (!include) /* error, should not happen */ + include = &me->xinclude; StrAllocCat(*include, me->object.data); + } /* * Create a link to the DATA, if desired, and @@ -6622,7 +7106,8 @@ PRIVATE void HTML_end_element ARGS3( * it a try. - FM */ if (clickable_images) { - if (me->object_data != NULL && + if (!LYMapsOnly && + me->object_data != NULL && !have_param && me->object_classid == NULL && me->object_codebase == NULL && @@ -6635,6 +7120,8 @@ PRIVATE void HTML_end_element ARGS3( * an image or not, and set the link name * accordingly. - FM */ + if (!include) /* error, should not happen */ + include = &me->xinclude; if (me->inA) StrAllocCat(*include, "</A>"); StrAllocCat(*include, " -<A HREF=\""); @@ -6655,22 +7142,10 @@ PRIVATE void HTML_end_element ARGS3( * Re-intialize all of the OBJECT elements. - FM */ End_Object: - HTChunkClear(&me->object); - me->object_started = FALSE; - me->object_declare = FALSE; - me->object_shapes = FALSE; - me->object_ismap = FALSE; - FREE(me->object_usemap); - FREE(me->object_id); - FREE(me->object_title); - FREE(me->object_data); - FREE(me->object_type); - FREE(me->object_classid); - FREE(me->object_codebase); - FREE(me->object_codetype); - FREE(me->object_name); + clear_objectdata(me); - change_paragraph_style(me, me->sp->style); /* Often won't really change */ + if (!LYMapsOnly) + change_paragraph_style(me, me->sp->style); /* Often won't really change */ break; case HTML_APPLET: @@ -6827,7 +7302,6 @@ End_Object: * Finish the data off. */ HTChunkTerminate(&me->textarea); - data = me->textarea.data; FREE(temp); I.type = "textarea"; @@ -6840,19 +7314,32 @@ End_Object: I.id = me->textarea_id; /* - * SGML unescape any character references in TEXTAREA - * content, then parse it into individual lines - * to be handled as a series of INPUT fields (ugh!). + * Transform the TEXTAREA content as needed, then parse + * it into individual lines to be handled as a series + * series of INPUT fields (ugh!). * Any raw 8-bit or multibyte characters already have been * handled in relation to the display character set * in SGML_character(). + * + * If TEXTAREA is handled as SGML_LITTERAL (the old way), + * we need to SGML-unescape any character references and NCRs + * here. Otherwise this will already have happened in the + * SGML.c parsing. - kw */ me->UsePlainSpace = TRUE; - TRANSLATE_AND_UNESCAPE_ENTITIES5(&me->textarea.data, + if (HTML_dtd.tags[element_number].contents == SGML_LITTERAL) { + TRANSLATE_AND_UNESCAPE_ENTITIES5(&me->textarea.data, me->UCLYhndl, current_char_set, me->UsePlainSpace, me->HiddenValue); + } else { + TRANSLATE_HTML5(&me->textarea.data, + me->UCLYhndl, + current_char_set, + me->UsePlainSpace, me->HiddenValue); + } + data = me->textarea.data; /* * Trim any trailing newlines and @@ -7091,6 +7578,7 @@ End_Object: me->DivisionAlignments[me->Division_Level]; change_paragraph_style(me, me->sp->style); UPDATE_STYLE; + HText_endStblTABLE(me->text); me->current_default_alignment = me->sp->style->alignment; if (me->List_Nesting_Level >= 0) HText_NegateLineOne(me->text); @@ -7098,6 +7586,7 @@ End_Object: /* These TABLE related elements may now not be SGML_EMPTY. - kw */ case HTML_TR: + HText_endStblTR(me->text); if (HText_LastLineSize(me->text, FALSE)) { HText_setLastChar(me->text, ' '); /* absorb next white space */ HText_appendCharacter(me->text, '\r'); @@ -7114,9 +7603,8 @@ End_Object: break; case HTML_TH: - break; - case HTML_TD: + HText_endStblTD(me->text); break; /* More stuff that may now not be SGML_EMPTY any more: */ @@ -7161,6 +7649,13 @@ End_Object: if (reached_awaited_stacked_elt) wait_for_this_stacked_elt=-1; #endif + + if (me->xinclude) { + HText_appendText(me->text, " *** LYNX ERROR ***\rUnparsed data:\r"); + HText_appendText(me->text, me->xinclude); + FREE(me->xinclude); + } + #ifdef USE_COLOR_STYLE #if !OPT_SCN TrimColorClass(HTML_dtd.tags[element_number].name, @@ -7174,7 +7669,7 @@ End_Object: # endif #endif - if (!REALLY_EMPTY(element_number)) + if (!ReallyEmptyTagNum(element_number)) { CTRACE((tfp, "STYLE:end_element: ending non-EMPTY style\n")); #if !defined(USE_HASH) @@ -7184,6 +7679,7 @@ End_Object: #endif /* USE_HASH */ } #endif /* USE_COLOR_STYLE */ + return status; } /* Expanding entities @@ -7226,6 +7722,8 @@ PRIVATE void HTML_free ARGS1(HTStructured *, me) */ FREE(me->base_href); FREE(me->map_address); + clear_objectdata(me); + FREE(me->xinclude); FREE(me); return; } @@ -7333,6 +7831,11 @@ PRIVATE void HTML_free ARGS1(HTStructured *, me) HTML_put_character(me, ']'); HTML_end_element(me, HTML_P, &include); } + if (me->xinclude) { + HText_appendText(me->text, " *** LYNX ERROR ***\rUnparsed data:\r"); + HText_appendText(me->text, me->xinclude); + FREE(me->xinclude); + } /* * Now call the cleanup function. - FM @@ -7404,6 +7907,7 @@ PRIVATE void HTML_free ARGS1(HTStructured *, me) FREE(me->base_href); FREE(me->map_address); FREE(me->LastOptionValue); + clear_objectdata(me); FREE(me); } @@ -7499,6 +8003,8 @@ PRIVATE void HTML_abort ARGS2(HTStructured *, me, HTError, e) FREE(me->textarea_cols); FREE(me->textarea_id); FREE(me->LastOptionValue); + FREE(me->xinclude); + clear_objectdata(me); FREE(me); } @@ -8107,7 +8613,7 @@ PUBLIC HTStream* HTMLParsedPresent ARGS3( ** is commented out. ** This will convert from HTML to presentation or plain text. ** -** It is registered in HTInit.c, but never actually used by lynx. +** It is registered in HTInit.c, but normally not used by lynx. ** - kw 1999-03-15 */ PUBLIC HTStream* HTMLToC ARGS3( @@ -8116,12 +8622,18 @@ PUBLIC HTStream* HTMLToC ARGS3( HTStream *, sink) { HTStructured * html; - - (*sink->isa->put_string)(sink, "/* "); /* Before even title */ +#if 0 + if (!sink) + sink = HTStreamStack(WWW_SOURCE, HTAtom_for("www/dump"), + HTOutputStream, anchor); +#endif + if (sink) + (*sink->isa->put_string)(sink, "/* "); /* Before even title */ html = HTML_new(anchor, WWW_PLAINTEXT, sink); html->comment_start = "/* "; html->comment_end = " */\n"; /* Must start in col 1 for cpp */ -/* HTML_put_string(html,html->comment_start); */ + if (!sink) + HTML_put_string(html,html->comment_start); #ifdef SOURCE_CACHE return CacheThru_new(anchor, SGML_new(&HTML_dtd, anchor, html)); diff --git a/src/HTML.h b/src/HTML.h index 69074324..04ea3f32 100644 --- a/src/HTML.h +++ b/src/HTML.h @@ -20,13 +20,19 @@ #define ATTR_CS_IN me->tag_charset #define TRANSLATE_AND_UNESCAPE_ENTITIES(s, p, h) \ - LYUCFullyTranslateString(s, ATTR_CS_IN, current_char_set, YES, p, h, st_HTML) + LYUCTranslateHTMLString(s, ATTR_CS_IN, current_char_set, YES, p, h, st_HTML) #define TRANSLATE_AND_UNESCAPE_ENTITIES5(s,cs_from,cs_to,p,h) \ - LYUCFullyTranslateString(s, cs_from, cs_to, YES, p, h, st_HTML) + LYUCTranslateHTMLString(s, cs_from, cs_to, YES, p, h, st_HTML) #define TRANSLATE_AND_UNESCAPE_ENTITIES6(s,cs_from,cs_to,spcls,p,h) \ - LYUCFullyTranslateString(s, cs_from, cs_to, spcls, p, h, st_HTML) + LYUCTranslateHTMLString(s, cs_from, cs_to, spcls, p, h, st_HTML) + +#define TRANSLATE_HTML(s,p,h) \ + LYUCFullyTranslateString(s, me->UCLYhndl, current_char_set, NO, YES, p, h, NO, st_HTML) + +#define TRANSLATE_HTML5(s,cs_from,cs_to,p,h) \ + LYUCFullyTranslateString(s, cs_from, cs_to, NO, YES, p, h, NO, st_HTML) /* * Strings from attributes which should be converted to some kind @@ -34,9 +40,9 @@ * esp. URLs (incl. #fragments) and HTML NAME and ID stuff. */ #define TRANSLATE_AND_UNESCAPE_TO_STD(s) \ - LYUCFullyTranslateString(s, ATTR_CS_IN, ATTR_CS_IN, NO, NO, YES, st_URL) + LYUCTranslateHTMLString(s, ATTR_CS_IN, ATTR_CS_IN, NO, NO, YES, st_URL) #define UNESCAPE_FIELDNAME_TO_STD(s) \ - LYUCFullyTranslateString(s, ATTR_CS_IN, ATTR_CS_IN, NO, NO, YES, st_HTML) + LYUCTranslateHTMLString(s, ATTR_CS_IN, ATTR_CS_IN, NO, NO, YES, st_HTML) extern CONST HTStructuredClass HTMLPresentation; @@ -84,6 +90,8 @@ struct _HTStructured { char * object_codebase; char * object_codetype; char * object_name; + int objects_mixed_open, + objects_figged_open; HTChunk option; /* Grow by 128 */ BOOL first_option; /* First OPTION in SELECT? */ char * LastOptionValue; @@ -161,6 +169,7 @@ struct _HTStructured { BOOL needBoldH; + char * xinclude; /* if no include strin address passed */ /* ** UCI and UCLYhndl give the UCInfo and charset registered for ** the HTML parser in the node_anchor's UCStages structure. It diff --git a/src/HTNestedList.h b/src/HTNestedList.h index 32a3049b..f7c0411d 100644 --- a/src/HTNestedList.h +++ b/src/HTNestedList.h @@ -37,4 +37,9 @@ #define HTML_DLEFT HTML_ELEMENTS+29 #define HTML_DRIGHT HTML_ELEMENTS+30 + +#define HTML_OBJECT_M HTML_ELEMENTS+31 + +#define HTML_EXTRA_ELEMENTS 31 + #endif /* HTNESTEDLIST_H */ diff --git a/src/LYCharSets.c b/src/LYCharSets.c index 6e775c27..62e1fdfc 100644 --- a/src/LYCharSets.c +++ b/src/LYCharSets.c @@ -621,7 +621,12 @@ PRIVATE void HTMLSetDisplayCharsetMatchLocale ARGS1(int,i) match = TRUE; /* guess, but see below */ #if !defined(LOCALE) - match = FALSE; + if (LYCharSet_UC[i].enc != UCT_ENC_UTF8) + /* + * Leave true for utf-8 display - the code doesn't deal + * very well with this case. - kw + */ + match = FALSE; #else if (UCForce8bitTOUPPER) { /* diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c index e0de8686..b4b54422 100644 --- a/src/LYCharUtils.c +++ b/src/LYCharUtils.c @@ -66,8 +66,8 @@ PUBLIC void LYEntify ARGS2( int amps = 0, lts = 0, gts = 0; #ifdef CJK_EX enum _state - { S_text, S_esc, S_dollar, S_paren, - S_nonascii_text, S_dollar_paren } state = S_text; + { S_text, S_esc, S_dollar, S_paren, + S_nonascii_text, S_dollar_paren } state = S_text; int in_sjis = 0; #endif @@ -126,8 +126,8 @@ PUBLIC void LYEntify ARGS2( state = S_esc; *q++ = *p; continue; - } - break; + } + break; case S_esc: if (*p == '$') { @@ -392,7 +392,7 @@ PUBLIC char *LYFindEndOfComment ARGS1( */ PUBLIC void LYFillLocalFileURL ARGS2( char **, href, - CONST char *, base) + CONST char *, base) { char * temp = NULL; @@ -510,7 +510,7 @@ PUBLIC void LYFillLocalFileURL ARGS2( ** - LP */ PUBLIC void LYAddMETAcharsetToFD ARGS2( - FILE *, fd, + FILE *, fd, int, disp_chndl) { if (disp_chndl == -1) @@ -883,7 +883,7 @@ PUBLIC char *LYLowercaseI_OL_String ARGS1( ** This function initializes the Ordered List counter. - FM */ PUBLIC void LYZero_OL_Counter ARGS1( - HTStructured *, me) + HTStructured *, me) { int i; @@ -905,7 +905,7 @@ PUBLIC void LYZero_OL_Counter ARGS1( ** This function is used by the HTML Structured object. - KW */ PUBLIC void LYGetChartransInfo ARGS1( - HTStructured *, me) + HTStructured *, me) { me->UCLYhndl = HTAnchor_getUCLYhndl(me->node_anchor, UCT_STAGE_STRUCTURED); @@ -944,7 +944,7 @@ PUBLIC void LYGetChartransInfo ARGS1( ** keep memory allocations at a minimum. - FM */ PUBLIC void LYExpandString ARGS2( - HTStructured *, me, + HTStructured *, me, char **, str) { char *p = *str; @@ -1485,68 +1485,6 @@ PUBLIC void LYExpandString ARGS2( #endif /* NOTUSED_FOTEMODS */ /* -** Get UCS character code for one character from UTF-8 encoded string. -** -** On entry: -** *ppuni should point to beginning of UTF-8 encoding character -** On exit: -** *ppuni is advanced to point to the last byte of UTF-8 sequence, -** if there was a valid one; otherwise unchanged. -** returns the UCS value -** returns negative value on error (invalid UTF-8 sequence) -*/ -PRIVATE UCode_t UCGetUniFromUtf8String ARGS1(char **, ppuni) -{ - UCode_t uc_out = 0; - char * p = *ppuni; - int utf_count, i; - if (!(**ppuni&0x80)) - return (UCode_t) **ppuni; /* ASCII range character */ - else if (!(**ppuni&0x40)) - return (-1); /* not a valid UTF-8 start */ - if ((*p & 0xe0) == 0xc0) { - utf_count = 1; - } else if ((*p & 0xf0) == 0xe0) { - utf_count = 2; - } else if ((*p & 0xf8) == 0xf0) { - utf_count = 3; - } else if ((*p & 0xfc) == 0xf8) { - utf_count = 4; - } else if ((*p & 0xfe) == 0xfc) { - utf_count = 5; - } else { /* garbage */ - return (-1); - } - for (p = *ppuni, i = 0; i < utf_count ; i++) { - if ((*(++p) & 0xc0) != 0x80) - return (-1); - } - p = *ppuni; - switch (utf_count) { - case 1: - uc_out = (((*p&0x1f) << 6) | (*(p+1)&0x3f)); - break; - case 2: - uc_out = (((((*p&0x0f) << 6) | (*(p+1)&0x3f)) << 6) | (*(p+2)&0x3f)); - break; - case 3: - uc_out = (((((((*p&0x07) << 6) | (*(p+1)&0x3f)) << 6) | (*(p+2)&0x3f)) << 6) - | (*(p+3)&0x3f)); - break; - case 4: - uc_out = (((((((((*p&0x03) << 6) | (*(p+1)&0x3f)) << 6) | (*(p+2)&0x3f)) << 6) - | (*(p+3)&0x3f)) << 6) | (*(p+4)&0x3f)); - break; - case 5: - uc_out = (((((((((((*p&0x01) << 6) | (*(p+1)&0x3f)) << 6) | (*(p+2)&0x3f)) << 6) - | (*(p+3)&0x3f)) << 6) | (*(p+4)&0x3f)) << 6) | (*(p+5)&0x3f)); - break; - } - *ppuni = p + utf_count; - return uc_out; -} - -/* * Given an UCS character code, will fill buffer passed in as q with * the code's UTF-8 encoding. * If terminate = YES, terminates string on success and returns pointer @@ -1682,7 +1620,7 @@ PRIVATE CONST char *hex = "0123456789ABCDEF"; ** BOOLEAN isURL)); */ -PRIVATE char ** LYUCFullyTranslateString_1 ARGS9( +PUBLIC char ** LYUCFullyTranslateString ARGS9( char **, str, int, cs_from, int, cs_to, @@ -1832,7 +1770,7 @@ PRIVATE char ** LYUCFullyTranslateString_1 ARGS9( sjis_1st = '\0'; } else { if (0xA1 <= code && code <= 0xDF) { - sjis_str[2] = '\0'; + sjis_str[2] = '\0'; JISx0201TO0208_SJIS((unsigned char)code, sjis_str, sjis_str + 1); REPLACE_STRING(sjis_str); @@ -2283,15 +2221,29 @@ PRIVATE char ** LYUCFullyTranslateString_1 ARGS9( ** otherwise use the Lynx special character. - FM */ if (code == 160) { - if (hidden) { - ; - } else if (plain_space) { + if (plain_space) { code = ' '; - } else { + state = S_got_outchar; + break; + } else if (use_lynx_specials) { code = HT_NON_BREAK_SPACE; + state = S_got_outchar; + break; + } else if ((hidden && !Back) || + (LYCharSet_UC[cs_to].codepoints & UCT_CP_SUPERSETOF_LAT1) || + LYCharSet_UC[cs_to].enc == UCT_ENC_8859 || + (LYCharSet_UC[cs_to].like8859 & + UCT_R_8859SPECL)) { + state = S_got_outchar; + break; + } else if ( + (LYCharSet_UC[cs_to].repertoire & UCT_REP_SUPERSETOF_LAT1)) { + ; /* nothing, may be translated later */ + } else { + code = ' '; + state = S_got_outchar; + break; } - state = S_got_outchar; - break; } /* ** For 173 (shy), use that value if it's @@ -2312,7 +2264,7 @@ PRIVATE char ** LYUCFullyTranslateString_1 ARGS9( } else if (hidden || Back) { state = S_got_outchar; break; - } else { + } else if (use_lynx_specials) { code = LY_SOFT_HYPHEN; state = S_got_outchar; break; @@ -2607,7 +2559,7 @@ PRIVATE char ** LYUCFullyTranslateString_1 ARGS9( #undef REPLACE_CHAR #undef REPLACE_STRING -PUBLIC BOOL LYUCFullyTranslateString ARGS7( +PUBLIC BOOL LYUCTranslateHTMLString ARGS7( char **, str, int, cs_from, int, cs_to, @@ -2618,7 +2570,7 @@ PUBLIC BOOL LYUCFullyTranslateString ARGS7( { BOOL ret = YES; /* May reallocate *str even if cs_to == 0 */ - if (!LYUCFullyTranslateString_1(str, cs_from, cs_to, TRUE, + if (!LYUCFullyTranslateString(str, cs_from, cs_to, TRUE, use_lynx_specials, plain_space, hidden, NO, stype)) { ret = NO; @@ -2634,7 +2586,7 @@ PUBLIC BOOL LYUCTranslateBackFormData ARGS4( { char ** ret; /* May reallocate *str */ - ret = (LYUCFullyTranslateString_1(str, cs_from, cs_to, FALSE, + ret = (LYUCFullyTranslateString(str, cs_from, cs_to, FALSE, NO, plain_space, YES, YES, st_HTML)); return (BOOL) (ret != NULL); @@ -2644,7 +2596,7 @@ PUBLIC BOOL LYUCTranslateBackFormData ARGS4( ** This function processes META tags in HTML streams. - FM */ PUBLIC void LYHandleMETA ARGS4( - HTStructured *, me, + HTStructured *, me, CONST BOOL*, present, CONST char **, value, char **, include GCC_UNUSED) @@ -2664,7 +2616,7 @@ PUBLIC void LYHandleMETA ARGS4( value[HTML_META_HTTP_EQUIV] && *value[HTML_META_HTTP_EQUIV]) { StrAllocCopy(http_equiv, value[HTML_META_HTTP_EQUIV]); convert_to_spaces(http_equiv, TRUE); - LYUCFullyTranslateString(&http_equiv, me->tag_charset, me->tag_charset, + LYUCTranslateHTMLString(&http_equiv, me->tag_charset, me->tag_charset, NO, NO, YES, st_other); LYTrimHead(http_equiv); LYTrimTail(http_equiv); @@ -2676,7 +2628,7 @@ PUBLIC void LYHandleMETA ARGS4( value[HTML_META_NAME] && *value[HTML_META_NAME]) { StrAllocCopy(name, value[HTML_META_NAME]); convert_to_spaces(name, TRUE); - LYUCFullyTranslateString(&name, me->tag_charset, me->tag_charset, + LYUCTranslateHTMLString(&name, me->tag_charset, me->tag_charset, NO, NO, YES, st_other); LYTrimHead(name); LYTrimTail(name); @@ -2722,7 +2674,7 @@ PUBLIC void LYHandleMETA ARGS4( */ if (!strcasecomp((http_equiv ? http_equiv : ""), "Pragma") || !strcasecomp((http_equiv ? http_equiv : ""), "Cache-Control")) { - LYUCFullyTranslateString(&content, me->tag_charset, me->tag_charset, + LYUCTranslateHTMLString(&content, me->tag_charset, me->tag_charset, NO, NO, YES, st_other); LYTrimHead(content); LYTrimTail(content); @@ -2796,7 +2748,7 @@ PUBLIC void LYHandleMETA ARGS4( * Date header from a server when making the * comparison. - FM */ - LYUCFullyTranslateString(&content, me->tag_charset, me->tag_charset, + LYUCTranslateHTMLString(&content, me->tag_charset, me->tag_charset, NO, NO, YES, st_other); LYTrimHead(content); LYTrimTail(content); @@ -2839,7 +2791,7 @@ PUBLIC void LYHandleMETA ARGS4( !strcasecomp((http_equiv ? http_equiv : ""), "Content-Type")) { LYUCcharset * p_in = NULL; LYUCcharset * p_out = NULL; - LYUCFullyTranslateString(&content, me->tag_charset, me->tag_charset, + LYUCTranslateHTMLString(&content, me->tag_charset, me->tag_charset, NO, NO, YES, st_other); LYTrimHead(content); LYTrimTail(content); @@ -3085,11 +3037,15 @@ PUBLIC void LYHandleMETA ARGS4( /* * Check for an anchor in http or https URLs. - FM */ +#ifndef DONT_TRACK_INTERNAL_LINKS + /* id_string seems to be used wrong below if given. + not that it matters much. avoid setting it here. - kw */ if ((strncmp(href, "http", 4) == 0) && (cp = strrchr(href, '#')) != NULL) { StrAllocCopy(id_string, cp); *cp = '\0'; } +#endif if (me->inA) { /* * Ugh! The META tag, which is a HEAD element, @@ -3213,7 +3169,7 @@ free_META_copies: ** end tag is present or not in the markup. - FM */ PUBLIC void LYHandlePlike ARGS6( - HTStructured *, me, + HTStructured *, me, CONST BOOL*, present, CONST char **, value, char **, include GCC_UNUSED, @@ -3322,7 +3278,7 @@ PUBLIC void LYHandlePlike ARGS6( ** an end tag. - FM */ PUBLIC void LYHandleSELECT ARGS5( - HTStructured *, me, + HTStructured *, me, CONST BOOL*, present, CONST char **, value, char **, include GCC_UNUSED, @@ -3553,7 +3509,7 @@ PUBLIC void LYHandleSELECT ARGS5( ** URLs. - FM */ PUBLIC int LYLegitimizeHREF ARGS4( - HTStructured *, me, + HTStructured *, me, char **, href, BOOL, force_slash, BOOL, strip_dots) @@ -3586,7 +3542,7 @@ PUBLIC int LYLegitimizeHREF ARGS4( } if (*(*href) == '\0') return(url_type); - LYUCFullyTranslateString(href, me->tag_charset, me->tag_charset, + LYUCTranslateHTMLString(href, me->tag_charset, me->tag_charset, NO, NO, YES, st_URL); url_type = is_url(*href); if (!url_type && force_slash && @@ -3679,7 +3635,7 @@ PUBLIC int LYLegitimizeHREF ARGS4( ** any BASE tag in the HTML stream, itself. - FM */ PUBLIC void LYCheckForContentBase ARGS1( - HTStructured *, me) + HTStructured *, me) { char *cp = NULL; BOOL present[HTML_BASE_ATTRIBUTES]; @@ -3747,7 +3703,7 @@ PUBLIC void LYCheckForContentBase ARGS1( ** or ID attribute was present in the tag. - FM */ PUBLIC void LYCheckForID ARGS4( - HTStructured *, me, + HTStructured *, me, CONST BOOL *, present, CONST char **, value, int, attribute) @@ -3764,7 +3720,7 @@ PUBLIC void LYCheckForID ARGS4( * Translate any named or numeric character references. - FM */ StrAllocCopy(temp, value[attribute]); - LYUCFullyTranslateString(&temp, me->tag_charset, me->tag_charset, + LYUCTranslateHTMLString(&temp, me->tag_charset, me->tag_charset, NO, NO, YES, st_URL); /* @@ -3789,8 +3745,8 @@ PUBLIC void LYCheckForID ARGS4( ** does not need checking for character references. - FM */ PUBLIC void LYHandleID ARGS2( - HTStructured *, me, - char *, id) + HTStructured *, me, + CONST char *, id) { HTChildAnchor *ID_A = NULL; @@ -3987,7 +3943,7 @@ PUBLIC BOOLEAN LYCommentHacks ARGS2( cp = comment + 17; StrAllocCopy(messageid, cp); /* This should be ok - message-id should only contain 7-bit ASCII */ - if (!LYUCFullyTranslateString(&messageid, 0, 0, NO, NO, YES, st_URL)) + if (!LYUCTranslateHTMLString(&messageid, 0, 0, NO, NO, YES, st_URL)) return FALSE; for (p = messageid; *p; p++) { if ((unsigned char)*p >= 127 || !isgraph((unsigned char)*p)) { @@ -4039,7 +3995,7 @@ PUBLIC BOOLEAN LYCommentHacks ARGS2( * header in raw form, but don't have MIME encoding implemented. * Someone may want to do more about this... - kw */ - if (!LYUCFullyTranslateString(&subject, 0, 0, NO, YES, NO, st_HTML)) + if (!LYUCTranslateHTMLString(&subject, 0, 0, NO, YES, NO, st_HTML)) return FALSE; for (p = subject; *p; p++) { if ((unsigned char)*p >= 127 || !isprint((unsigned char)*p)) { diff --git a/src/LYCharUtils.h b/src/LYCharUtils.h index d518d3ae..97cba343 100644 --- a/src/LYCharUtils.h +++ b/src/LYCharUtils.h @@ -14,22 +14,32 @@ typedef enum { st_other } CharUtil_st; -extern BOOL LYUCFullyTranslateString PARAMS(( - char ** str, +extern char** LYUCFullyTranslateString PARAMS(( + char ** str, int cs_from, int cs_to, + BOOLEAN do_ent, BOOL use_lynx_specials, - BOOLEAN plain_space, - BOOLEAN hidden, + BOOLEAN plain_space, + BOOLEAN hidden, + BOOL Back, + CharUtil_st stype)); +extern BOOL LYUCTranslateHTMLString PARAMS(( + char ** str, + int cs_from, + int cs_to, + BOOL use_lynx_specials, + BOOLEAN plain_space, + BOOLEAN hidden, CharUtil_st stype)); extern BOOL LYUCTranslateBackFormData PARAMS(( - char ** str, + char ** str, int cs_from, int cs_to, - BOOLEAN plain_space)); + BOOLEAN plain_space)); extern void LYEntify PARAMS(( - char ** str, - BOOLEAN isTITLE)); + char ** str, + BOOLEAN isTITLE)); extern void LYTrimHead PARAMS(( char * str)); extern void LYTrimTail PARAMS(( @@ -37,14 +47,14 @@ extern void LYTrimTail PARAMS(( extern char *LYFindEndOfComment PARAMS(( char * str)); extern void LYFillLocalFileURL PARAMS(( - char ** href, + char ** href, CONST char * base)); extern void LYAddMETAcharsetToFD PARAMS(( FILE * fd, int disp_chndl)); #ifdef Lynx_HTML_Handler -extern int OL_CONTINUE; /* flag for whether CONTINUE is set */ +extern int OL_CONTINUE; /* flag for whether CONTINUE is set */ extern int OL_VOID; /* flag for whether a count is set */ extern void LYZero_OL_Counter PARAMS(( HTStructured * me)); @@ -62,23 +72,23 @@ extern void LYHandleMETA PARAMS(( HTStructured * me, CONST BOOL* present, CONST char ** value, - char ** include)); + char ** include)); extern void LYHandlePlike PARAMS(( HTStructured * me, CONST BOOL* present, CONST char ** value, - char ** include, + char ** include, int align_idx, BOOL start)); extern void LYHandleSELECT PARAMS(( HTStructured * me, CONST BOOL* present, CONST char ** value, - char ** include, + char ** include, BOOL start)); extern int LYLegitimizeHREF PARAMS(( HTStructured * me, - char ** href, + char ** href, BOOL force_slash, BOOL strip_dots)); extern void LYCheckForContentBase PARAMS(( @@ -90,7 +100,7 @@ extern void LYCheckForID PARAMS(( int attribute)); extern void LYHandleID PARAMS(( HTStructured * me, - char * id)); + CONST char * id)); extern BOOLEAN LYoverride_default_alignment PARAMS(( HTStructured * me)); extern void LYEnsureDoubleSpace PARAMS(( @@ -101,7 +111,10 @@ extern void LYResetParagraphAlignment PARAMS(( HTStructured * me)); extern BOOLEAN LYCheckForCSI PARAMS(( HTParentAnchor * anchor, - char ** url)); + char ** url)); + #endif /* Lynx_HTML_Handler */ +#define LYUCTranslateBackHeaderText LYUCTranslateBackFormData + #endif /* LYCHARUTILS_H */ diff --git a/src/LYCurses.h b/src/LYCurses.h index 58725ff3..9ff9a597 100644 --- a/src/LYCurses.h +++ b/src/LYCurses.h @@ -202,6 +202,7 @@ extern unsigned int Lynx_Color_Flags; #endif #ifdef USE_SLANG +#define SHOW_WHEREIS_TARGETS 1 #if !defined(VMS) && !defined(DJGPP) #define USE_SLANG_MOUSE 1 @@ -282,6 +283,7 @@ extern void VTHome NOPARAMS; #else /* Define curses functions: */ #ifdef FANCY_CURSES +#define SHOW_WHEREIS_TARGETS 1 #ifdef VMS /* diff --git a/src/LYDownload.c b/src/LYDownload.c index eb74d163..2a985ad0 100644 --- a/src/LYDownload.c +++ b/src/LYDownload.c @@ -25,7 +25,7 @@ PUBLIC BOOLEAN LYDidRename = FALSE; PRIVATE char LYValidDownloadFile[LY_MAXPATH] = "\0"; PUBLIC void LYDownload ARGS1( - char *, line) + char *, line) { char *Line = NULL, *method, *file, *sug_file = NULL; int method_number; @@ -61,25 +61,25 @@ PUBLIC void LYDownload ARGS1( StrAllocCopy(Line, line); /* - * Parse out the sug_file, Method and the File. + * Parse out the File, sug_file, and the Method. */ - if ((sug_file = (char *)strstr(Line, "SugFile=")) != NULL) { - *(sug_file-1) = '\0'; + if ((file = (char *)strstr(Line, "/File=")) == NULL) + goto failed; + *file = '\0'; + /* + * Go past "File=". + */ + file += 6; + + if ((sug_file = (char *)strstr(file + 1, "/SugFile=")) != NULL) { + *sug_file = '\0'; /* * Go past "SugFile=". */ - sug_file += 8; + sug_file += 9; HTUnEscape(sug_file); } - if ((file = (char *)strstr(Line, "File=")) == NULL) - goto failed; - *(file-1) = '\0'; - /* - * Go past "File=". - */ - file += 5; - /* * Make sure that the file string is the one from * the last displayed download options menu. - FM @@ -486,7 +486,7 @@ cancelled: */ PUBLIC int LYdownload_options ARGS2( char **, newfile, - char *, data_file) + char *, data_file) { static char tempfile[LY_MAXPATH] = "\0"; char *downloaded_url = NULL; @@ -524,12 +524,12 @@ PUBLIC int LYdownload_options ARGS2( fprintf(fp0, "<pre>\n"); fprintf(fp0, "<em>%s</em> %s\n", - gettext("Downloaded link:"), + gettext("Downloaded link:"), downloaded_url); FREE(downloaded_url); fprintf(fp0, "<em>%s</em> %s\n", - gettext("Suggested file name:"), + gettext("Suggested file name:"), sug_filename); fprintf(fp0, "\n%s\n", diff --git a/src/LYEditmap.c b/src/LYEditmap.c index 7314e97b..4a23b319 100644 --- a/src/LYEditmap.c +++ b/src/LYEditmap.c @@ -284,7 +284,7 @@ LYE_NOP, LYE_BOL, LYE_BACK, LYE_ABORT, LYE_DELN, LYE_EOL, LYE_FORW, LYE_ABORT, /* ^D ^E ^F ^G */ -LYE_DELP, LYE_ENTER, LYE_ENTER, LYE_DELNW, /* LYE_DELEL,*/ +LYE_DELP, LYE_ENTER, LYE_ENTER, LYE_DELEL, /* bs tab nl ^K */ LYE_NOP, LYE_ENTER, LYE_FORWW, LYE_ABORT, diff --git a/src/LYForms.c b/src/LYForms.c index ac75a941..70f7486d 100644 --- a/src/LYForms.c +++ b/src/LYForms.c @@ -225,13 +225,29 @@ PUBLIC int change_form_link_ex ARGS8( * If c indicates that line editing ended with Enter, we still * defer to mainloop() for further checking if the submit * action URL could require more checks than we do here. - * call HText_SubmitForm() directly before returning. - * Only in the remaining cases do we proceed directly. - kw + * Only in the remaining cases do we proceed to call + * HText_SubmitForm() directly before returning. - kw */ if (immediate_submit || ((c == '\r' || c == '\n' || c == LAC_TO_LKC0(LYK_SUBMIT)) && peek_mouse_link() == -1)) { form_link->hightext = form->value; +#ifdef TEXT_SUBMIT_CONFIRM_WANTED + if (!immediate_submit && (c == '\r' || c == '\n') && + !HTConfirmDefault( + gettext("No submit button for this form, submit single text field?"), + YES)) { + /* User was prompted and declined; if canceled with ^G + * let mainloop stay on this field, otherwise move on to + * the next field or link. - kw + */ + if (HTLastConfirmCancelled()) + c = DO_NOTHING; + else + c = LAC_TO_LKC(LYK_NEXT_LINK); + break; + } +#endif if (!form->submit_action || *form->submit_action == '\0') { HTUserMsg(NO_FORM_ACTION); c = DO_NOTHING; @@ -965,6 +981,10 @@ PRIVATE int popup_options ARGS7( * if it all fits. Otherwise, set up the widest window possible. - FM */ #ifdef USE_SLANG + if (width + 4 > SLtt_Screen_Cols) { + lx = 1; + width = LYcols - 5; /* avoids a crash? - kw */ + } SLsmg_fill_region(top, lx - 1, bottom - top, width + 4, ' '); #else if (!(form_window = newwin(bottom - top, width + 4, top, lx - 1)) && @@ -979,7 +999,7 @@ PRIVATE int popup_options ARGS7( #if defined(NCURSES) LYsubwindow(form_window); #endif -#if defined(HAVE_GETBKGD) && !defined(PDCURSES)/* not defined in ncurses 1.8.7 */ +#if defined(HAVE_GETBKGD) /* not defined in ncurses 1.8.7 */ wbkgd(form_window, getbkgd(stdscr)); wbkgdset(form_window, getbkgd(stdscr)); #endif diff --git a/src/LYGetFile.c b/src/LYGetFile.c index f5713d68..9a80861c 100644 --- a/src/LYGetFile.c +++ b/src/LYGetFile.c @@ -14,7 +14,6 @@ #include <LYGetFile.h> #include <LYPrint.h> #include <LYOptions.h> -#include <LYHistory.h> #include <LYStrings.h> #include <LYClean.h> #include <LYDownload.h> @@ -28,12 +27,13 @@ #include <LYLocal.h> #endif /* DIRED_SUPPORT */ #include <LYReadCFG.h> +#include <LYHistory.h> #include <LYexit.h> #include <LYLeaks.h> PRIVATE int fix_httplike_urls PARAMS((document *doc, UrlTypes type)); -extern char * WWW_Download_File; + #ifdef VMS extern BOOLEAN LYDidRename; #endif /* VMS */ @@ -317,6 +317,11 @@ Try_Redirected_URL: /* show compile-time settings */ return(lynx_compile_opts(doc)); #endif + } else if (url_type == LYNXMESSAGES_URL_TYPE) { + /* Uh! */ + LYforce_no_cache = TRUE; + LYoverride_no_cache = FALSE; + /* continue */ #ifndef DISABLE_NEWS } else if (url_type == NEWSPOST_URL_TYPE || @@ -776,23 +781,9 @@ Try_Redirected_URL: } FREE(cp); } - if (url_type == LYNXMESSAGES_URL_TYPE) { - int rv; - /* show list of recent statusline messages */ - if ((rv = LYshow_statusline_messages(doc)) != NORMAL) { - return rv; - } - WWWDoc.address = doc->address; - WWWDoc.post_data = doc->post_data; - WWWDoc.post_content_type = doc->post_content_type; - WWWDoc.bookmark = doc->bookmark; - WWWDoc.isHEAD = doc->isHEAD; - WWWDoc.safe = doc->safe; - } else { + CTRACE_SLEEP(MessageSecs); + user_message(WWW_WAIT_MESSAGE, doc->address); - CTRACE_SLEEP(MessageSecs); - user_message(WWW_WAIT_MESSAGE, doc->address); - } if (TRACE) { #ifdef USE_SLANG if (LYCursesON) { @@ -851,6 +842,7 @@ Try_Redirected_URL: url_type == LYNXCOMPILE_OPTS_URL_TYPE || url_type == LYNXHIST_URL_TYPE || url_type == LYNXCOOKIE_URL_TYPE || + url_type == LYNXMESSAGES_URL_TYPE || (LYValidate && url_type != HTTP_URL_TYPE && url_type != HTTPS_URL_TYPE) || diff --git a/src/LYGetFile.h b/src/LYGetFile.h index 319efbb6..a9062318 100644 --- a/src/LYGetFile.h +++ b/src/LYGetFile.h @@ -16,6 +16,8 @@ extern int follow_link_number PARAMS(( extern void add_trusted PARAMS((char *str, int type)); extern BOOLEAN exec_ok PARAMS((CONST char *source, CONST char *linkpath, int type)); +extern char * WWW_Download_File; + /* values for follow_link_number() */ #define DO_LINK_STUFF 1 #define DO_GOTOLINK_STUFF 2 diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h index 586c5a7d..d0f8efbf 100644 --- a/src/LYGlobalDefs.h +++ b/src/LYGlobalDefs.h @@ -385,6 +385,7 @@ extern BOOLEAN LYPrependCharsetToSource; extern BOOLEAN LYQuitDefaultYes; extern BOOLEAN LYNonRestartingSIGWINCH; extern BOOLEAN LYReuseTempfiles; +extern BOOLEAN LYUseBuiltinSuffixes; extern BOOLEAN dont_wrap_pre; #ifdef EXP_JUSTIFY_ELTS @@ -412,6 +413,7 @@ extern BOOLEAN restore_sigpipe_for_children; #endif /* !VMS */ extern int HTNoDataOK; /* HT_NO_DATA-is-ok hack */ +extern BOOLEAN FileInitAlreadyDone; #ifdef WIN_EX /* LYMain.c */ diff --git a/src/LYHistory.c b/src/LYHistory.c index 93ff53fc..de190ef1 100644 --- a/src/LYHistory.c +++ b/src/LYHistory.c @@ -14,7 +14,7 @@ #include <LYShowInfo.h> #include <LYStrings.h> #include <LYCharUtils.h> -#include <LYGetFile.h> +#include <LYCharSets.h> #ifdef DIRED_SUPPORT #include <LYUpload.h> @@ -687,73 +687,6 @@ PRIVATE void to_stack ARGS1(char *, str) /* - * Status line messages list, LYNXMESSAGES:/ internal page, - * called from getfile(). - */ -PUBLIC int LYshow_statusline_messages ARGS1( - document *, newdoc) -{ - static char tempfile[LY_MAXPATH] = "\0"; - static char *info_url; - FILE *fp0; - int i; - char *temp = NULL; - - if (LYReuseTempfiles) { - fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "w"); - } else { - LYRemoveTemp(tempfile); - fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w"); - } - if (fp0 == NULL) { - HTAlert(CANNOT_OPEN_TEMP); - return(NOT_FOUND); - } - LYLocalFileToURL(&info_url, tempfile); - - LYforce_no_cache = TRUE; /* don't cache this doc */ - - BeginInternalPage (fp0, STATUSLINES_TITLE, NULL); - fprintf(fp0, "<pre>\n"); - fprintf(fp0, "<ol>\n"); - - /* print messages in reverse order: */ - i = topOfStack; - while (--i >= 0) { - if (buffstack[i] != NULL) { - StrAllocCopy(temp, buffstack[i]); - LYEntify(&temp, TRUE); - fprintf(fp0, "<li> <em>%s</em>\n", temp); - } - } - i = STATUSBUFSIZE; - while (--i >= topOfStack) { - if (buffstack[i] != NULL) { - StrAllocCopy(temp, buffstack[i]); - LYEntify(&temp, TRUE); - fprintf(fp0, "<li> <em>%s</em>\n", temp); - } - } - - fprintf(fp0, "</ol>\n"); - fprintf(fp0, "</pre>\n"); - EndInternalPage(fp0); - LYCloseTempFP(fp0); - - - /* exit to getfile() cycle */ - StrAllocCopy(newdoc->address, info_url); - FREE(newdoc->post_data); - FREE(newdoc->post_content_type); - FREE(newdoc->bookmark); - newdoc->isHEAD = FALSE; - - /* Leave loading it to getfile - that has the advantage to make - this kind of link 'd'ownloadable. - kw */ - return(NORMAL); -} - -/* * Dump statusline messages into the buffer. * Called from mainloop() when exit immediately with an error: * can not access startfile (first_file) so a couple of alert messages @@ -794,7 +727,6 @@ PUBLIC void LYstore_message2 ARGS2( if (message != NULL) { char *temp = NULL; HTSprintf(&temp, message, (argument == 0) ? "" : argument); - LYEntify(&temp, TRUE); to_stack(temp); } } @@ -805,7 +737,97 @@ PUBLIC void LYstore_message ARGS1( if (message != NULL) { char *temp = NULL; StrAllocCopy(temp, message); - LYEntify(&temp, TRUE); to_stack(temp); } } + +/* LYLoadMESSAGES +** -------------- +** Create a text/html stream with a list of recent statusline messages. +** LYNXMESSAGES:/ internal page. +** [implementation based on LYLoadKeymap()]. +*/ + +struct _HTStream +{ + HTStreamClass * isa; +}; + +PRIVATE int LYLoadMESSAGES ARGS4 ( + CONST char *, arg GCC_UNUSED, + HTParentAnchor *, anAnchor, + HTFormat, format_out, + HTStream*, sink) +{ + HTFormat format_in = WWW_HTML; + HTStream *target = NULL; + char *buf = NULL; + + int i; + char *temp = NULL; + + /* + * Set up the stream. - FM + */ + target = HTStreamStack(format_in, format_out, sink, anAnchor); + + if (!target || target == NULL) { + HTSprintf0(&buf, CANNOT_CONVERT_I_TO_O, + HTAtom_name(format_in), HTAtom_name(format_out)); + HTAlert(buf); + FREE(buf); + return(HT_NOT_LOADED); + } + anAnchor->no_cache = TRUE; + +#define PUTS(buf) (*target->isa->put_block)(target, buf, strlen(buf)) + + HTSprintf0(&buf, "<html>\n<head>\n"); + PUTS(buf); + /* + * This page is a list of messages in display character set. + */ + HTSprintf0(&buf, "<META %s content=\"text/html;charset=%s\">\n", + "http-equiv=\"content-type\"", + LYCharSet_UC[current_char_set].MIMEname); + PUTS(buf); + HTSprintf0(&buf, "<title>%s</title>\n", STATUSLINES_TITLE); + PUTS(buf); + HTSprintf0(&buf, "</head>\n<body>\n<pre>\n<ol>\n"); + PUTS(buf); + + /* print messages in reverse order: */ + i = topOfStack; + while (--i >= 0) { + if (buffstack[i] != NULL) { + StrAllocCopy(temp, buffstack[i]); + LYEntify(&temp, TRUE); + HTSprintf0(&buf, "<li> <em>%s</em>\n", temp); + PUTS(buf); + } + } + i = STATUSBUFSIZE; + while (--i >= topOfStack) { + if (buffstack[i] != NULL) { + StrAllocCopy(temp, buffstack[i]); + LYEntify(&temp, TRUE); + HTSprintf0(&buf, "<li> <em>%s</em>\n", temp); + PUTS(buf); + } + } + FREE(temp); + + HTSprintf0(&buf, "</ol>\n</pre>\n</body>\n</html>\n"); + PUTS(buf); + + (*target->isa->_free)(target); + FREE(buf); + return(HT_LOADED); +} + +#ifdef GLOBALDEF_IS_MACRO +#define _LYMESSAGES_C_GLOBALDEF_1_INIT { "LYNXMESSAGES", LYLoadMESSAGES, 0} +GLOBALDEF (HTProtocol,LYLynxStatusMessages,_LYMESSAGES_C_GLOBALDEF_1_INIT); +#else +GLOBALDEF PUBLIC HTProtocol LYLynxStatusMessages = {"LYNXMESSAGES", LYLoadMESSAGES, 0}; +#endif /* GLOBALDEF_IS_MACRO */ diff --git a/src/LYHistory.h b/src/LYHistory.h index ad25b250..f929e1d1 100644 --- a/src/LYHistory.h +++ b/src/LYHistory.h @@ -16,7 +16,6 @@ extern void LYpush PARAMS((document *doc, BOOLEAN force_push)); extern void LYstore_message2 PARAMS((CONST char *message, CONST char *argument)); extern void LYstore_message PARAMS((CONST char *message)); -extern int LYshow_statusline_messages PARAMS((document *newdoc)); extern void LYstatusline_messages_on_exit PARAMS((char **buf)); #endif /* LYHISTORY_H */ diff --git a/src/LYKeymap.c b/src/LYKeymap.c index c381c081..148479f7 100644 --- a/src/LYKeymap.c +++ b/src/LYKeymap.c @@ -928,16 +928,18 @@ PRIVATE int LYLoadKeymap ARGS4 ( } anAnchor->no_cache = TRUE; +#define PUTS(buf) (*target->isa->put_block)(target, buf, strlen(buf)) + HTSprintf0(&buf, "<head>\n<title>%s</title>\n</head>\n<body>\n", CURRENT_KEYMAP_TITLE); - (*target->isa->put_block)(target, buf, strlen(buf)); + PUTS(buf); HTSprintf0(&buf, "<h1>%s (%s)%s<a href=\"%s%s\">%s</a></h1>\n", LYNX_NAME, LYNX_VERSION, HELP_ON_SEGMENT, helpfilepath, CURRENT_KEYMAP_HELP, CURRENT_KEYMAP_TITLE); - (*target->isa->put_block)(target, buf, strlen(buf)); + PUTS(buf); HTSprintf0(&buf, "<pre>\n"); - (*target->isa->put_block)(target, buf, strlen(buf)); + PUTS(buf); for (i = 'a'+1; i <= 'z'+1; i++) { print_binding(target, i); @@ -959,7 +961,7 @@ PRIVATE int LYLoadKeymap ARGS4 ( } HTSprintf0(&buf,"</pre>\n</body>\n"); - (*target->isa->put_block)(target, buf, strlen(buf)); + PUTS(buf); (*target->isa->_free)(target); FREE(buf); diff --git a/src/LYLocal.c b/src/LYLocal.c index cbb7f62f..735fccdc 100644 --- a/src/LYLocal.c +++ b/src/LYLocal.c @@ -2324,7 +2324,7 @@ PRIVATE int LYExecv ARGS3( char **, argv, char *, msg) { -#if defined(VMS) || defined(SH_EX) || defined(_WINDOWS) +#if defined(VMS) || defined(_WINDOWS) CTRACE((tfp, "LYExecv: Called inappropriately!\n")); return(0); #else diff --git a/src/LYMain.c b/src/LYMain.c index 3960ade5..baeb89b8 100644 --- a/src/LYMain.c +++ b/src/LYMain.c @@ -87,7 +87,8 @@ PUBLIC char *LYCSwingPath = NULL; #endif /* VMS */ #if HAVE_CUSERID && !defined(_XOPEN_SOURCE) -extern char *cuserid(); /* workaround for Redhat 6.0 */ +/*extern char *cuserid();*/ /* workaround for Redhat 6.0 */ + /* for the price of screwing up legitimate systems? Nah. */ #endif #ifdef DIRED_SUPPORT @@ -461,6 +462,7 @@ PUBLIC int partial_threshold = -1; /* # of lines to be d/l'ed until we repaint PUBLIC BOOLEAN LYNonRestartingSIGWINCH = FALSE; PUBLIC BOOLEAN LYReuseTempfiles = FALSE; +PUBLIC BOOLEAN LYUseBuiltinSuffixes = TRUE; /* These are declared in cutil.h for current freeWAIS libraries. - FM */ #ifdef DECLARE_WAIS_LOGFILES @@ -473,6 +475,8 @@ extern int HTNewsChunkSize; /* Number of news articles per chunk (HTNews.c) */ extern int HTNewsMaxChunk; /* Max news articles before chunking (HTNews.c) */ #endif +PUBLIC BOOLEAN FileInitAlreadyDone = FALSE; + PRIVATE BOOLEAN stack_dump = FALSE; PRIVATE char *terminal = NULL; PRIVATE char *pgm; @@ -545,9 +549,9 @@ PUBLIC int is_windows_nt(void) version = GetVersion(); if ((version & 0x80000000) == 0) - return 1; + return 1; else - return 0; + return 0; } #endif @@ -1664,8 +1668,16 @@ PUBLIC int main ARGS2( * file, if they overlap. */ HTFormatInit(); - HTFileInit(); + if (!FileInitAlreadyDone) + HTFileInit(); + if (LYUserAgent && *LYUserAgent && + !strstr(LYUserAgent, "Lynx") && + !strstr(LYUserAgent, "lynx") && + !strstr(LYUserAgent, "L_y_n_x") && + !strstr(LYUserAgent, "l_y_n_x")) { + HTAlwaysAlert(gettext("Warning:"), UA_NO_LYNX_WARNING); + } #ifdef SH_EX if (show_cfg) { cleanup(); @@ -1811,7 +1823,7 @@ PUBLIC int main ARGS2( */ #ifndef DOSPATH if (signal(SIGPIPE, SIG_IGN) != SIG_IGN) - restore_sigpipe_for_children = TRUE; + restore_sigpipe_for_children = TRUE; #endif /* DOSPATH */ } #endif /* !VMS */ @@ -2039,18 +2051,20 @@ PUBLIC int main ARGS2( /* * Called by HTAccessInit to register any protocols supported by lynx. * Protocols added by lynx: - * LYNXKEYMAP, lynxcgi, LYNXIMGMAP, LYNXCOOKIE + * LYNXKEYMAP, lynxcgi, LYNXIMGMAP, LYNXCOOKIE, LYNXMESSAGES */ #ifdef GLOBALREF_IS_MACRO extern GLOBALREF (HTProtocol, LYLynxKeymap); extern GLOBALREF (HTProtocol, LYLynxCGI); extern GLOBALREF (HTProtocol, LYLynxIMGmap); extern GLOBALREF (HTProtocol, LYLynxCookies); +extern GLOBALREF (HTProtocol, LYLynxStatusMessages); #else GLOBALREF HTProtocol LYLynxKeymap; GLOBALREF HTProtocol LYLynxCGI; GLOBALREF HTProtocol LYLynxIMGmap; GLOBALREF HTProtocol LYLynxCookies; +GLOBALREF HTProtocol LYLynxStatusMessages; #endif /* GLOBALREF_IS_MACRO */ PUBLIC void LYRegisterLynxProtocols NOARGS @@ -2059,13 +2073,14 @@ PUBLIC void LYRegisterLynxProtocols NOARGS HTRegisterProtocol(&LYLynxCGI); HTRegisterProtocol(&LYLynxIMGmap); HTRegisterProtocol(&LYLynxCookies); + HTRegisterProtocol(&LYLynxStatusMessages); } #ifndef NO_CONFIG_INFO /* * Some stuff to reload lynx.cfg without restarting new lynx session, * also load options menu items and command-line options - * to make things consistent. Not implemented yet. + * to make things consistent. * Warning: experimental, more main() reorganization required. * * Called by user of interactive session by LYNXCFG://reload/ link. @@ -2112,7 +2127,7 @@ PUBLIC void reload_read_cfg NOARGS custom_display_charset = FALSE; memset((char*)charset_subsets, 0, sizeof(charset_subset_t)*MAXCHARSETS); #endif - free_lynx_cfg(); /* free downloaders, printers, not always environments */ + free_lynx_cfg(); /* free downloaders, printers, environments */ /* * Process the configuration file. */ @@ -2396,6 +2411,49 @@ static int color_fun ARGS1( } #endif +#ifdef MISC_EXP +/* -convert_to */ +static int convert_to_fun ARGS1( + char *, next_arg) +{ + if (next_arg != 0) { + char *outformat = NULL; + char *cp1, *cp2, *cp4; + int chndl; + StrAllocCopy(outformat, next_arg); + /* not lowercased, to allow for experimentation - kw */ + /*LYLowerCase(outformat);*/ + if ((cp1 = strchr(outformat, ';')) != NULL) { + if ((cp2 = LYstrstr(cp1, "charset")) != NULL) { + cp2 += 7; + while (*cp2 == ' ' || *cp2 == '=' || *cp2 == '\"') + cp2++; + for (cp4 = cp2; (*cp4 != '\0' && *cp4 != '\"' && + *cp4 != ';' && + !WHITE(*cp4)); cp4++) + ; /* do nothing */ + *cp4 = '\0'; + /* This is intentionally not the "safe" version, + to allow for experimentation. */ + chndl = UCGetLYhndl_byMIME(cp2); + if (chndl < 0) chndl = UCLYhndl_for_unrec; + if (chndl < 0) { + fprintf(stderr, + gettext("Lynx: ignoring unrecognized charset=%s\n"), cp2); + } else { + current_char_set = chndl; + } + *cp1 = '\0'; /* truncate outformat */ + } + } + HTOutputFormat = HTAtom_for(outformat); + } else { + HTOutputFormat = NULL; + } + return 0; +} +#endif + /* -crawl */ static int crawl_fun ARGS1( char *, next_arg GCC_UNUSED) @@ -2987,6 +3045,12 @@ static Parse_Args_Type Arg_Table [] = "force color mode on with standard bg colors" ), #endif +#ifdef MISC_EXP + PARSE_SET( + "convert_to", FUNCTION_ARG, convert_to_fun, + "=FORMAT\nconvert input, FORMAT is in MIME type notation (experimental)" + ), +#endif PARSE_SET( "cookies", TOGGLE_ARG, &LYSetCookies, "toggles handling of Set-Cookie headers" diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c index 78225419..1c8f18d8 100644 --- a/src/LYMainLoop.c +++ b/src/LYMainLoop.c @@ -241,6 +241,7 @@ PRIVATE void free_mainloop_variables NOARGS #ifdef DIRED_SUPPORT clear_tags(); #endif /* DIRED_SUPPORT */ + FREE(WWW_Download_File); /* LYGetFile.c/HTFWriter.c */ return; } @@ -500,7 +501,7 @@ PRIVATE void do_check_goto_URL ARGS3( !strncmp(user_input_buffer, "LYNXPRINT:", 10)) { HTUserMsg(GOTO_SPECIAL_DISALLOWED); - } else { + } else { StrAllocCopy(newdoc.address, user_input_buffer); newdoc.isHEAD = FALSE; /* @@ -1314,9 +1315,8 @@ gettext("Enctype multipart/form-data not yet supported! Cannot submit.")); } #ifdef EXP_ADDRLIST_PAGE -PRIVATE BOOLEAN handle_LYK_ADDRLIST ARGS2( - int *, cmd, - BOOLEAN *, refresh_screen) +PRIVATE BOOLEAN handle_LYK_ADDRLIST ARGS1( + int *, cmd) { /* * Don't do if already viewing list addresses page. @@ -1343,7 +1343,6 @@ PRIVATE BOOLEAN handle_LYK_ADDRLIST ARGS2( * a POST response. - kw */ - refresh_screen = TRUE; /* redisplay */ if (LYValidate || check_realm) { LYPermitURL = TRUE; StrAllocCopy(lynxlistfile, newdoc.address); @@ -2189,7 +2188,7 @@ PRIVATE int handle_LYK_DWIMEDIT ARGS3( HTUserMsg(ANYEDIT_DISABLED); } return 1; - } + } #endif /* AUTOEXTEDIT */ return 0; } @@ -2991,8 +2990,7 @@ PRIVATE void handle_LYK_HISTORICAL NOARGS return; } -PRIVATE BOOLEAN handle_LYK_HISTORY ARGS2( - BOOLEAN *, refresh_screen, +PRIVATE BOOLEAN handle_LYK_HISTORY ARGS1( BOOLEAN, ForcePush) { if (curdoc.title && strcmp(curdoc.title, HISTORY_PAGE_TITLE)) { @@ -3029,7 +3027,6 @@ PRIVATE BOOLEAN handle_LYK_HISTORY ARGS2( newdoc.link = 1; /*@@@ bypass "recent statusline messages" link */ FREE(curdoc.address); /* so it doesn't get pushed */ - *refresh_screen = TRUE; if (LYValidate || check_realm) { LYPermitURL = TRUE; } @@ -3090,10 +3087,9 @@ PRIVATE void handle_LYK_INDEX ARGS2( } /* end if */ } -PRIVATE void handle_LYK_INDEX_SEARCH ARGS5( +PRIVATE void handle_LYK_INDEX_SEARCH ARGS4( BOOLEAN *, force_load, BOOLEAN, ForcePush, - BOOLEAN *, refresh_screen, int *, old_c, int, real_c) { @@ -3132,7 +3128,6 @@ PRIVATE void handle_LYK_INDEX_SEARCH ARGS5( newdoc.internal_link = FALSE; curdoc.line = -1; Newline = 0; - *refresh_screen = TRUE; /* redisplay it */ } else if (use_this_url_instead != NULL) { /* * Got back a redirecting URL. Check it out. @@ -3411,9 +3406,8 @@ PRIVATE void handle_LYK_LEFT_LINK ARGS1( } } -PRIVATE BOOLEAN handle_LYK_LIST ARGS2( - int *, cmd, - BOOLEAN *, refresh_screen) +PRIVATE BOOLEAN handle_LYK_LIST ARGS1( + int *, cmd) { /* * Don't do if already viewing list page. @@ -3440,7 +3434,6 @@ PRIVATE BOOLEAN handle_LYK_LIST ARGS2( * a POST response. - kw */ - *refresh_screen = TRUE; /* redisplay */ if (LYValidate || check_realm) { LYPermitURL = TRUE; StrAllocCopy(lynxlistfile, newdoc.address); @@ -3776,7 +3769,7 @@ PRIVATE void handle_LYK_NEXT_PAGE ARGS3( highlight(OFF, curdoc.link, prev_target); curdoc.link = nlinks-1; /* put on last link */ } else if (*old_c != real_c) { - *old_c = real_c; + *old_c = real_c; HTInfoMsg(ALREADY_AT_END); } } @@ -3799,7 +3792,7 @@ PRIVATE BOOLEAN handle_LYK_NOCACHE ARGS2( LYforce_no_cache = TRUE; reloading = TRUE; } - } + } return TRUE; } @@ -3976,8 +3969,7 @@ PRIVATE void handle_LYK_PREV_PAGE ARGS3( } } -PRIVATE void handle_LYK_PRINT ARGS4( - BOOLEAN *, refresh_screen, +PRIVATE void handle_LYK_PRINT ARGS3( BOOLEAN *, ForcePush, int *, old_c, int, real_c) @@ -4005,7 +3997,6 @@ PRIVATE void handle_LYK_PRINT ARGS4( *ForcePush = TRUE; /* see LYpush() and print_options() */ if (check_realm) LYPermitURL = TRUE; - *refresh_screen = TRUE; /* redisplay */ } } @@ -4071,8 +4062,8 @@ PRIVATE void handle_LYK_RELOAD ARGS1( */ if (HTisDocumentSource()) { - force_old_UCLYhndl_on_reload = TRUE; - forced_UCLYhdnl = HTMainText_Get_UCLYhndl(); + if ((forced_UCLYhdnl = HTMainText_Get_UCLYhndl()) >= 0) + force_old_UCLYhndl_on_reload = TRUE; #ifndef USE_PSRC HTOutputFormat = WWW_SOURCE; #else @@ -4628,7 +4619,7 @@ PRIVATE void handle_LYK_VIEW_BOOKMARK ARGS3( } #if defined(CJK_EX) /* 1997/12/13 (Sat) 15:20:18 */ if (HTCJK == JAPANESE) { - *last_kcode = NOKANJI; /* AUTO */ + last_kcode = NOKANJI; /* AUTO */ } #endif LYforce_no_cache = TRUE; /*force the document to be reloaded*/ @@ -4651,9 +4642,8 @@ PRIVATE void handle_LYK_VIEW_BOOKMARK ARGS3( } } -PRIVATE BOOLEAN handle_LYK_VLINKS ARGS2( - int *, cmd, - BOOLEAN *, refresh_screen) +PRIVATE BOOLEAN handle_LYK_VLINKS ARGS1( + int *, cmd) { if (!strcmp((curdoc.title ? curdoc.title : ""), VISITED_LINKS_TITLE)) { @@ -4678,7 +4668,6 @@ PRIVATE BOOLEAN handle_LYK_VLINKS ARGS2( newdoc.isHEAD = FALSE; newdoc.safe = FALSE; newdoc.internal_link = FALSE; - *refresh_screen = TRUE; if (LYValidate || check_realm) { LYPermitURL = TRUE; StrAllocCopy(lynxlinksfile, newdoc.address); @@ -6004,7 +5993,7 @@ try_again: */ if (HTdocument_settings_changed()) { if (HTcan_reparse_document()) { - HTUserMsg(gettext("Reparsing document under current settings...")); + HTInfoMsg(gettext("Reparsing document under current settings...")); if (HTreparse_document()) {} } else { /* @@ -6734,7 +6723,7 @@ new_cmd: /* break; case LYK_HISTORY: /* show the history page */ - if (handle_LYK_HISTORY(&refresh_screen, ForcePush)) + if (handle_LYK_HISTORY(ForcePush)) break; /* FALLTHRU */ @@ -6790,7 +6779,7 @@ new_cmd: /* handle_LYK_HELP(&cshelpfile); break; - case LYK_INDEX: /* index file */ + case LYK_INDEX: /* index file */ handle_LYK_INDEX(&old_c, real_c); break; @@ -6804,7 +6793,7 @@ new_cmd: /* break; case LYK_INDEX_SEARCH: /* search for a user string */ - handle_LYK_INDEX_SEARCH(&force_load, ForcePush, &refresh_screen, &old_c, real_c); + handle_LYK_INDEX_SEARCH(&force_load, ForcePush, &old_c, real_c); break; case LYK_WHEREIS: /* search within the document */ @@ -6812,7 +6801,7 @@ new_cmd: /* handle_LYK_WHEREIS(cmd, prev_target, &refresh_screen); break; - case LYK_COMMENT: /* reply by mail */ + case LYK_COMMENT: /* reply by mail */ handle_LYK_COMMENT(&refresh_screen, owner_address, &old_c, real_c); break; @@ -6821,11 +6810,11 @@ new_cmd: /* handle_LYK_TAG_LINK(prev_target); break; - case LYK_MODIFY: /* rename a file or directory */ + case LYK_MODIFY: /* rename a file or directory */ handle_LYK_MODIFY(&refresh_screen); break; - case LYK_CREATE: /* create a new file or directory */ + case LYK_CREATE: /* create a new file or directory */ handle_LYK_CREATE(); break; #endif /* DIRED_SUPPORT */ @@ -6877,23 +6866,23 @@ new_cmd: /* break; case LYK_PRINT: /* print the file */ - handle_LYK_PRINT(&refresh_screen, &ForcePush, &old_c, real_c); + handle_LYK_PRINT(&ForcePush, &old_c, real_c); break; case LYK_LIST: /* list links in the current document */ - if (handle_LYK_LIST(&cmd, &refresh_screen)) + if (handle_LYK_LIST(&cmd)) goto new_cmd; break; #ifdef EXP_ADDRLIST_PAGE case LYK_ADDRLIST: /* always list URL's (only) */ - if (handle_LYK_ADDRLIST(&cmd, &refresh_screen)) + if (handle_LYK_ADDRLIST(&cmd)) goto new_cmd; break; #endif /* EXP_ADDRLIST_PAGE */ case LYK_VLINKS: /* list links visited during the current session */ - if (handle_LYK_VLINKS(&cmd, &refresh_screen)) + if (handle_LYK_VLINKS(&cmd)) goto new_cmd; break; @@ -7109,14 +7098,13 @@ PRIVATE int are_different ARGS2( /* * Are the base addresses different? */ - if (strcmp(doc1->address, doc2->address)) - { + if (strcmp(doc1->address, doc2->address)) { if (cp1) *cp1 = '#'; if (cp2) *cp2 = '#'; return(TRUE); - } + } if (cp1) *cp1 = '#'; if (cp2) @@ -7125,19 +7113,14 @@ PRIVATE int are_different ARGS2( /* * Do the docs have different contents? */ - if (doc1->post_data) - { - if (doc2->post_data) - { + if (doc1->post_data) { + if (doc2->post_data) { if (strcmp(doc1->post_data, doc2->post_data)) return(TRUE); - } - else - return(TRUE); - } - else - if (doc2->post_data) + } else return(TRUE); + } else if (doc2->post_data) + return(TRUE); /* * We'll assume the two documents in fact are the same. @@ -7194,14 +7177,13 @@ PRIVATE int are_phys_different ARGS2( /* * Are the base addresses different? */ - if (strcmp(ap1, ap2)) - { + if (strcmp(ap1, ap2)) { if (cp1) *cp1 = '#'; if (cp2) *cp2 = '#'; return(TRUE); - } + } if (cp1) *cp1 = '#'; if (cp2) @@ -7210,19 +7192,14 @@ PRIVATE int are_phys_different ARGS2( /* * Do the docs have different contents? */ - if (doc1->post_data) - { - if (doc2->post_data) - { + if (doc1->post_data) { + if (doc2->post_data) { if (strcmp(doc1->post_data, doc2->post_data)) return(TRUE); - } - else - return(TRUE); - } - else - if (doc2->post_data) + } else return(TRUE); + } else if (doc2->post_data) + return(TRUE); /* * We'll assume the two documents in fact are the same. diff --git a/src/LYMap.c b/src/LYMap.c index 05593910..b74c743d 100644 --- a/src/LYMap.c +++ b/src/LYMap.c @@ -124,8 +124,8 @@ PRIVATE void LYLynxMaps_free NOARGS * MAP element content. - FM */ PUBLIC BOOL LYAddImageMap ARGS3( - char *, address, - char *, title, + char *, address, + char *, title, HTParentAnchor *, node_anchor) { LYImageMap *new = NULL; @@ -173,7 +173,7 @@ PUBLIC BOOL LYAddImageMap ARGS3( cur = theList; while (NULL != (old = (LYImageMap *)HTList_nextObject(cur))) { if (old->address == 0) /* shouldn't happen */ - continue; + continue; if (!strcmp(old->address, address)) { FREE(old->address); FREE(old->title); @@ -212,9 +212,9 @@ PUBLIC BOOL LYAddImageMap ARGS3( * in the appropriate list. - FM */ PUBLIC BOOL LYAddMapElement ARGS5( - char *, map, - char *, address, - char *, title, + char *, map, + char *, address, + char *, title, HTParentAnchor *, node_anchor, BOOL, intern_flag) { @@ -299,7 +299,7 @@ PUBLIC BOOL LYAddMapElement ARGS5( * structure. - FM */ PUBLIC BOOL LYHaveImageMap ARGS1( - char *, address) + char *, address) { LYImageMap *Map; HTList *cur = LynxMaps; @@ -470,6 +470,25 @@ PRIVATE int LYLoadIMGmap ARGS4 ( break; } } + if (theMap && HTList_count(theMap->elements) == 0) { + /* + * We found a MAP without any usable AREA. + * Fake a redirection to the address with fragment. + * We do this even for post data (internal link within + * a document with post data) if it will not result in + * an unwanted network request. - kw + */ + if (!anAnchor->post_data) { + StrAllocCopy(redirecting_url, address); + return(HT_REDIRECTING); + } else if (WWWDoc.safe || + (underlying->document && !anAnchor->document && + (LYinternal_flag || LYoverride_no_cache))) { + StrAllocCopy(redirecting_url, address); + redirect_post_content = TRUE; + return(HT_REDIRECTING); + } + } if (!(theMap && theMap->elements)) { if (anAnchor->post_data && !WWWDoc.safe && ((underlying && underlying->document && !LYforce_no_cache) || diff --git a/src/LYNews.c b/src/LYNews.c index 2425c365..85c5759e 100644 --- a/src/LYNews.c +++ b/src/LYNews.c @@ -118,6 +118,13 @@ PUBLIC char *LYNewsPost ARGS2( return(postfile); /* + * Return immediately if we do get called, maybe by some quirk + * of HTNews.c, when we shouldn't. - kw + */ + if (no_newspost) + return(postfile); + + /* * Open a temporary file for the headers * and message body. - FM */ diff --git a/src/LYOptions.c b/src/LYOptions.c index 60fe6e4c..ba1e2973 100644 --- a/src/LYOptions.c +++ b/src/LYOptions.c @@ -1615,13 +1615,15 @@ draw_options: HTInfoMsg(""); } else if (LYUserAgent && *LYUserAgent && !strstr(LYUserAgent, "Lynx") && - !strstr(LYUserAgent, "lynx")) { - _statusline(UA_COPYRIGHT_WARNING); + !strstr(LYUserAgent, "lynx") && + !strstr(LYUserAgent, "L_y_n_x") && + !strstr(LYUserAgent, "l_y_n_x")) { + _statusline(UA_PLEASE_USE_LYNX); } else { _statusline(VALUE_ACCEPTED); } } else { /* disallowed */ - _statusline(UA_COPYRIGHT_WARNING); + _statusline(UA_CHANGE_DISABLED); } response = ' '; break; @@ -2425,7 +2427,7 @@ PUBLIC int popup_choice ARGS7( #ifdef NCURSES LYsubwindow(form_window); #endif -#if defined(HAVE_GETBKGD) && !defined(PDCURSES)/* not defined in ncurses 1.8.7 */ +#if defined(HAVE_GETBKGD)/* not defined in ncurses 1.8.7 */ wbkgd(form_window, getbkgd(stdscr)); wbkgdset(form_window, getbkgd(stdscr)); #endif @@ -3405,19 +3407,26 @@ static char * user_agent_string = "user_agent"; #define PutLabel(fp, text) \ fprintf(fp," %-33s: ", text) +#define PutLabelNotSaved(fp, text) \ + if (!no_option_save) { \ + int l=strlen(text); \ + fprintf(fp," %s", text); \ + fprintf(fp,"%s%-*s: ", (l<30)?" ":"", (l<30)?32-l:3, "(!)"); \ + } else PutLabel(fp, text) + #define PutTextInput(fp, Name, Value, Size, disable) \ fprintf(fp,\ "<input size=%d type=\"text\" name=\"%s\" value=\"%s\" %s>\n",\ - (int) Size, Name, Value, disable) + (int) Size, Name, Value, disable_all?disabled_string:disable) #define PutOption(fp, flag, html, name) \ fprintf(fp,"<option value=\"%s\" %s>%s\n", html, SELECTED(flag), name) #define BeginSelect(fp, text) \ - fprintf(fp,"<select name=\"%s\">\n", text) + fprintf(fp,"<select name=\"%s\" %s>\n", text, disable_all?disabled_string:"") #define MaybeSelect(fp, flag, text) \ - fprintf(fp,"<select name=\"%s\" %s>\n", text, DISABLED(flag)) + fprintf(fp,"<select name=\"%s\" %s>\n", text, disable_all?disabled_string:DISABLED(flag)) #define EndSelect(fp)\ fprintf(fp,"</select>\n") @@ -3928,8 +3937,10 @@ PUBLIC int postoptions ARGS1( : LYUserAgentDefault); if (LYUserAgent && *LYUserAgent && !strstr(LYUserAgent, "Lynx") && - !strstr(LYUserAgent, "lynx")) { - HTAlert(UA_COPYRIGHT_WARNING); + !strstr(LYUserAgent, "lynx") && + !strstr(LYUserAgent, "L_y_n_x") && + !strstr(LYUserAgent, "l_y_n_x")) { + HTAlert(UA_PLEASE_USE_LYNX); } } } @@ -4137,6 +4148,7 @@ PRIVATE int gen_options ARGS1( BOOLEAN can_do_colors; #endif static char tempfile[LY_MAXPATH] = "\0"; + BOOLEAN disable_all = FALSE; FILE *fp0; size_t cset_len = 0; size_t text_len = COLS - 38; /* cf: PutLabel */ @@ -4163,6 +4175,13 @@ PRIVATE int gen_options ARGS1( the flag. - kw 1999-05-24 */ LYforce_no_cache = TRUE; + /* + * Without LYUseFormsOptions set we should maybe not even get here. + * However, it's possible we do; disable the form in that case. - kw + */ + if (!LYUseFormsOptions) + disable_all = TRUE; + BeginInternalPage(fp0, OPTIONS_TITLE, NULL); /* help link below */ /* @@ -4183,17 +4202,22 @@ PRIVATE int gen_options ARGS1( /* Submit/Reset/Help */ fprintf(fp0,"<p align=center>\n"); - fprintf(fp0,"<input type=\"submit\" value=\"%s\"> - \n", ACCEPT_CHANGES); - fprintf(fp0,"<input type=\"reset\" value=\"%s\">\n", RESET_CHANGES); - fprintf(fp0,"%s\n", CANCEL_CHANGES); + if (!disable_all) { + fprintf(fp0,"<input type=\"submit\" value=\"%s\"> - \n", ACCEPT_CHANGES); + fprintf(fp0,"<input type=\"reset\" value=\"%s\">\n", RESET_CHANGES); + fprintf(fp0,"%s\n", CANCEL_CHANGES); + } fprintf(fp0, "<a href=\"%s%s\">%s</a>\n", helpfilepath, OPTIONS_HELP, TO_HELP); /* Save options */ if (!no_option_save) { - fprintf(fp0, "<p align=center>%s: ", SAVE_OPTIONS); - fprintf(fp0, "<input type=\"checkbox\" name=\"%s\">\n", - save_options_string); + if (!disable_all) { + fprintf(fp0, "<p align=center>%s: ", SAVE_OPTIONS); + fprintf(fp0, "<input type=\"checkbox\" name=\"%s\">\n", + save_options_string); + } + fprintf(fp0, "<br>(options marked with (!) will not be saved)\n"); } /* @@ -4203,7 +4227,9 @@ PRIVATE int gen_options ARGS1( fprintf(fp0,"\n <em>%s</em>\n", gettext("Personal Preferences")); /* Cookies: SELECT */ - PutLabel(fp0, gettext("Cookies")); + /* @@@ This is inconsistent - LYAcceptAllCookies gets saved to RC file + but LYSetCookies doesn't! */ + PutLabelNotSaved(fp0, gettext("Cookies")); BeginSelect(fp0, cookies_string); PutOption(fp0, !LYSetCookies, cookies_ignore_all_string, @@ -4348,7 +4374,7 @@ PRIVATE int gen_options ARGS1( EndSelect(fp0); /* X Display: INPUT */ - PutLabel(fp0, gettext("X Display")); + PutLabelNotSaved(fp0, gettext("X Display")); PutTextInput(fp0, x_display_string, NOTEMPTY(x_display), text_len, ""); /* @@ -4371,7 +4397,7 @@ PRIVATE int gen_options ARGS1( /* ok, LYRawMode, so use UCAssume_MIMEcharset */ curval = safeUCGetLYhndl_byMIME(UCAssume_MIMEcharset); } - PutLabel(fp0, gettext("Assumed document character set")); + PutLabelNotSaved(fp0, gettext("Assumed document character set")); BeginSelect(fp0, assume_char_set_string); for (i = 0; i < LYNumCharsets; i++) { #ifdef EXP_CHARSET_CHOICE @@ -4385,15 +4411,16 @@ PRIVATE int gen_options ARGS1( } /* Raw Mode: ON/OFF */ - if (LYHaveCJKCharacterSet) + if (LYHaveCJKCharacterSet) { /* * Since CJK people hardly mixed with other world * we split the header to make it more readable: * "CJK mode" for CJK display charsets, and "Raw 8-bit" for others. */ - PutLabel(fp0, gettext("CJK mode")); - else - PutLabel(fp0, gettext("Raw 8-bit")); + PutLabelNotSaved(fp0, gettext("CJK mode")); + } else { + PutLabelNotSaved(fp0, gettext("Raw 8-bit")); + } BeginSelect(fp0, raw_mode_string); PutOptValues(fp0, LYRawMode, bool_values); @@ -4401,7 +4428,7 @@ PRIVATE int gen_options ARGS1( #ifndef SH_EX /* 1999/01/19 (Tue) */ /* HTML error recovery: SELECT */ - PutLabel(fp0, gettext("HTML error recovery")); + PutLabelNotSaved(fp0, gettext("HTML error recovery")); BeginSelect(fp0, DTD_recovery_string); PutOptValues(fp0, Old_DTD, DTD_type_values); EndSelect(fp0); @@ -4414,7 +4441,7 @@ PRIVATE int gen_options ARGS1( EndSelect(fp0); /* Show Images: SELECT */ - PutLabel(fp0, gettext("Show images")); + PutLabelNotSaved(fp0, gettext("Show images")); BeginSelect(fp0, images_string); PutOption(fp0, !pseudo_inline_alts && !clickable_images, images_ignore_all_string, @@ -4531,7 +4558,7 @@ PRIVATE int gen_options ARGS1( /* User Agent: INPUT */ if (!no_useragent) { - PutLabel(fp0, gettext("User-Agent header")); + PutLabelNotSaved(fp0, gettext("User-Agent header")); PutTextInput(fp0, user_agent_string, NOTEMPTY(LYUserAgent), text_len, ""); } @@ -4544,10 +4571,12 @@ PRIVATE int gen_options ARGS1( fprintf(fp0,"\n</pre>\n"); /* Submit/Reset */ - fprintf(fp0,"<p align=center>\n"); - fprintf(fp0,"<input type=\"submit\" value=\"%s\">\n - ", ACCEPT_CHANGES); - fprintf(fp0,"<input type=\"reset\" value=\"%s\">\n", RESET_CHANGES); - fprintf(fp0,"%s\n", CANCEL_CHANGES); + if (!disable_all) { + fprintf(fp0,"<p align=center>\n"); + fprintf(fp0,"<input type=\"submit\" value=\"%s\">\n - ", ACCEPT_CHANGES); + fprintf(fp0,"<input type=\"reset\" value=\"%s\">\n", RESET_CHANGES); + fprintf(fp0,"%s\n", CANCEL_CHANGES); + } /* * close HTML diff --git a/src/LYPrint.c b/src/LYPrint.c index 817f5d04..03ea1b04 100644 --- a/src/LYPrint.c +++ b/src/LYPrint.c @@ -1232,38 +1232,27 @@ PRIVATE int remove_quotes ARGS1( * * Always returns a new allocated string which has to be freed. */ +#include <LYCharUtils.h> PRIVATE char* subject_translate8bit ARGS1(char *, source) { - CONST char *p = source; - char temp[2]; char *target = NULL; int charset_in, charset_out; - char replace_buf [10]; int i = outgoing_mail_charset; /* from lynx.cfg, -1 by default */ + StrAllocCopy(target, source); if (i < 0 || i == current_char_set || LYCharSet_UC[current_char_set].enc == UCT_ENC_CJK || LYCharSet_UC[i].enc == UCT_ENC_CJK) { - StrAllocCopy(target, source); return(target); /* OK */ } else { charset_out = i; charset_in = current_char_set; } - for ( ; *p; p++) { - LYstrncpy(temp, p, sizeof(temp)-1); - if ((unsigned char)*temp <= 127) { - StrAllocCat(target, temp); - } else { - if (UCTransCharStr(replace_buf, sizeof(replace_buf), *temp, - charset_in, charset_out, YES) > 0) - StrAllocCat(target, replace_buf); - } - } + LYUCTranslateBackHeaderText(&target, charset_in, charset_out, YES); return(target); } diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c index b2bfd81e..2d47628e 100644 --- a/src/LYReadCFG.c +++ b/src/LYReadCFG.c @@ -4,6 +4,7 @@ #include <HTUtils.h> #endif #include <HTFile.h> +#include <HTInit.h> #include <UCMap.h> #include <LYUtils.h> @@ -822,29 +823,109 @@ static int source_cache_fun ARGS1( static int suffix_fun ARGS1( char *, value) { - char *mime_type; + char *mime_type, *p; + char *encoding = NULL, *sq = NULL, *description = NULL; + float q = 1.0; if ((strlen (value) < 3) - || (NULL == (mime_type = strchr (value, ':')))) + || (NULL == (mime_type = strchr (value, ':')))) { + CTRACE((tfp, "Invalid SUFFIX:%s ignored.\n", value)); return 0; + } *mime_type++ = '\0'; + if (*mime_type) { + if ((encoding = strchr(mime_type, ':')) != NULL) { + *encoding++ = '\0'; + if ((sq = strchr(encoding, ':')) != NULL) { + *sq++ = '\0'; + if ((description = strchr(sq, ':')) != NULL) { + *description++ = '\0'; + if ((p = strchr(sq, ':')) != NULL) + *p = '\0'; + LYTrimTail(description); + } + LYRemoveBlanks(sq); + if (!*sq) + sq = NULL; + } + LYRemoveBlanks(encoding); + LYLowerCase(encoding); + if (!*encoding) + encoding = NULL; + } + } LYRemoveBlanks(mime_type); - LYLowerCase(mime_type); + /* + * Not converted to lowercase on input, to make it possible to + * reproduce the equivalent of some of the HTInit.c defaults + * that use mixed case, although that is not recomended. - kw + */ /*LYLowerCase(mime_type);*/ + + if (!*mime_type) { /* that's ok now, with an encoding! */ + CTRACE((tfp, "SUFFIX:%s without MIME type for %s\n", value, + encoding ? encoding : "what?")); + mime_type = NULL; /* that's ok now, with an encoding! */ + if (!encoding) + return 0; + } - if (strstr(mime_type, "tex") != NULL || - strstr(mime_type, "postscript") != NULL || - strstr(mime_type, "sh") != NULL || - strstr(mime_type, "troff") != NULL || - strstr(mime_type, "rtf") != NULL) - HTSetSuffix(value, mime_type, "8bit", 1.0); - else - HTSetSuffix(value, mime_type, "binary", 1.0); + if (!encoding) { + if (strstr(mime_type, "tex") != NULL || + strstr(mime_type, "postscript") != NULL || + strstr(mime_type, "sh") != NULL || + strstr(mime_type, "troff") != NULL || + strstr(mime_type, "rtf") != NULL) + encoding = "8bit"; + else + encoding = "binary"; + } + if (!sq) { + q = 1.0; + } else { + double df = strtod(sq, &p); + if (p == sq && df == 0.0) { + CTRACE((tfp, "Invalid q=%s for SUFFIX:%s, using -1.0\n", + sq, value)); + q = -1.0; + } else { + q = df; + } + } + HTSetSuffix5(value, mime_type, encoding, description, q); return 0; } +static int suffix_order_fun ARGS1( + char *, value) +{ + char *p = value; + char *optn; + BOOLEAN want_file_init_now = FALSE; + + LYUseBuiltinSuffixes = TRUE; + while ((optn = HTNextTok(&p, ", ", "", NULL)) != NULL) { + if (!strcasecomp(optn, "NO_BUILTIN")) { + LYUseBuiltinSuffixes = FALSE; + } else if (!strcasecomp(optn, "PRECEDENCE_HERE")) { + want_file_init_now = TRUE; + } else if (!strcasecomp(optn, "PRECEDENCE_OTHER")) { + want_file_init_now = FALSE; + } else { + CTRACE((tfp, "Invalid SUFFIX_ORDER:%s\n", optn)); + break; + } + } + + if (want_file_init_now && !FileInitAlreadyDone) { + HTFileInit(); + FileInitAlreadyDone = TRUE; + } + return 0; +} + static int system_editor_fun ARGS1( char *, value) { @@ -1329,6 +1410,7 @@ static Config_Type Config_Table [] = PARSE_SET("strip_dotdot_urls", CONF_BOOL, &LYStripDotDotURLs), PARSE_SET("substitute_underscores", CONF_BOOL, &use_underscore), PARSE_FUN("suffix", CONF_FUN, suffix_fun), + PARSE_FUN("suffix_order", CONF_FUN, suffix_order_fun), PARSE_FUN("system_editor", CONF_FUN, system_editor_fun), PARSE_STR("system_mail", CONF_STR, &system_mail), PARSE_STR("system_mail_flags", CONF_STR, &system_mail_flags), diff --git a/src/LYStrings.c b/src/LYStrings.c index 1806d0cc..a4a7fe29 100644 --- a/src/LYStrings.c +++ b/src/LYStrings.c @@ -315,6 +315,17 @@ PRIVATE int set_clicked_link ARGS4( return INSERT_KEY; if (y >= h) return REMOVE_KEY; +#ifdef DISP_PARTIAL /* Newline is not defined otherwise */ + if (clicks >= 2) { + double frac = (1. * y)/(h - 1); + int l = HText_getNumOfLines() + 1; /* NOL() off by one? */ + + l -= display_lines; + if (l > 0) + Newline = frac * l + 1 + 0.5; + return LYReverseKeymap(LYK_DO_NOTHING); + } +#endif if (y < LYsb_begin) return PGUP; if (y >= LYsb_end) @@ -418,7 +429,7 @@ PRIVATE int set_clicked_link ARGS4( * Writes a null byte into the n+1 byte of dst. */ PUBLIC char *LYstrncpy ARGS3( - char *, dst, + char *, dst, CONST char *, src, int, n) { @@ -451,7 +462,7 @@ PUBLIC char *LYstrncpy ARGS3( * argument should be TRUE for UTF8. - KW & FM */ PUBLIC char * LYmbcsstrncpy ARGS5( - char *, dst, + char *, dst, CONST char *, src, int, n_bytes, int, n_glyphs, @@ -485,7 +496,7 @@ PUBLIC char * LYmbcsstrncpy ARGS5( * of UTF-8 encoded characters. - KW */ PUBLIC char * LYmbcs_skip_glyphs ARGS3( - char *, data, + char *, data, int, n_glyphs, BOOL, utf_flag) { @@ -516,7 +527,7 @@ PUBLIC char * LYmbcs_skip_glyphs ARGS3( * characters. - FM */ PUBLIC int LYmbcsstrlen ARGS2( - char *, str, + char *, str, BOOL, utf_flag) { int i, j, len = 0; @@ -740,7 +751,7 @@ static Keysym_String_List Keysym_Strings [] = INTERN_KEY( "INSERT_KEY", INSERT_KEY, KEY_IC ), INTERN_KEY( "REMOVE_KEY", REMOVE_KEY, KEY_DC ), INTERN_KEY( "DO_NOTHING", DO_NOTHING, DO_NOTHING|LKC_ISLKC ), - INTERN_KEY( NULL, -1, ERR ) + INTERN_KEY( NULL, -1, ERR ) }; #ifdef NCURSES_VERSION @@ -1141,7 +1152,7 @@ PRIVATE void setup_vtXXX_keymap NOARGS }; size_t n; for (n = 0; n < TABLESIZE(table); n++) - define_key(table[n].string, table[n].value); + define_key(table[n].string, table[n].value); } PUBLIC int lynx_initialize_keymaps NOARGS @@ -1204,7 +1215,7 @@ PRIVATE int LYmouse_menu ARGS4(int, x, int, y, int, atlink, int, code) "Page down", "End of document", "Bookmarks", - "Cookie jar", + "Cookie jar", "Search index", "Set Options", NULL @@ -1238,7 +1249,7 @@ PRIVATE int LYmouse_menu ARGS4(int, x, int, y, int, atlink, int, code) LYK_NEXT_PAGE, LYK_END, LYK_VIEW_BOOKMARK, - LYK_COOKIE_JAR, + LYK_COOKIE_JAR, LYK_INDEX_SEARCH, LYK_OPTIONS }; @@ -1297,7 +1308,7 @@ PRIVATE int LYmouse_menu ARGS4(int, x, int, y, int, atlink, int, code) case LYK_NEXT_PAGE: case LYK_END: case LYK_VIEW_BOOKMARK: - case LYK_COOKIE_JAR: + case LYK_COOKIE_JAR: case LYK_INDEX_SEARCH: case LYK_OPTIONS: mouse_link = -3; /* so LYgetch_for() passes it on - kw */ @@ -1328,7 +1339,7 @@ PRIVATE int myGetChar NOARGS } PUBLIC int LYgetch_for ARGS1( - int, code) + int, code) { SLang_Key_Type *key; int keysym; @@ -1371,7 +1382,7 @@ PUBLIC int LYgetch_for ARGS1( #define found_CSI(first,second) ((second) == '[' || (first) == 155) PUBLIC int LYgetch_for ARGS1( - int, code) + int, code) { int a, b, c, d = -1; int current_modifier = 0; @@ -1644,7 +1655,7 @@ re_read: case KEY_LEFT: c = LTARROW; break; - case KEY_RIGHT: /* ... */ + case KEY_RIGHT: /* ... */ c = RTARROW; break; #if defined(SH_EX) && defined(DOSPATH) /* for NEC PC-9800 1998/08/30 (Sun) 21:50:35 */ @@ -1660,23 +1671,23 @@ re_read: case KEY_B3: c = RTARROW; break; - case PAD0: /* PC-9800 Ins */ + case PAD0: /* PC-9800 Ins */ c = INSERT_KEY; break; - case PADSTOP: /* PC-9800 DEL */ + case PADSTOP: /* PC-9800 DEL */ c = REMOVE_KEY; break; #endif /* SH_EX */ case KEY_HOME: /* Home key (upward+left arrow) */ c = HOME; break; - case KEY_CLEAR: /* Clear screen */ + case KEY_CLEAR: /* Clear screen */ c = 18; /* CTRL-R */ break; - case KEY_NPAGE: /* Next page */ + case KEY_NPAGE: /* Next page */ c = PGDOWN; break; - case KEY_PPAGE: /* Previous page */ + case KEY_PPAGE: /* Previous page */ c = PGUP; break; case KEY_LL: /* home down or bottom (lower left) */ @@ -2028,7 +2039,7 @@ re_read: case K_ELeft: c = LTARROW; break; - case K_Right: /* ... */ + case K_Right: /* ... */ case K_ERight: c = RTARROW; break; @@ -2036,11 +2047,11 @@ re_read: case K_EHome: c = HOME; break; - case K_PageDown: /* Next page */ + case K_PageDown: /* Next page */ case K_EPageDown: c = PGDOWN; break; - case K_PageUp: /* Previous page */ + case K_PageUp: /* Previous page */ case K_EPageUp: c = PGUP; break; @@ -2086,18 +2097,18 @@ re_read: case SL_KEY_LEFT: c = LTARROW; break; - case SL_KEY_RIGHT: /* ... */ + case SL_KEY_RIGHT: /* ... */ c = RTARROW; break; case SL_KEY_HOME: /* Home key (upward+left arrow) */ case SL_KEY_A1: /* upper left of keypad */ c = HOME; break; - case SL_KEY_NPAGE: /* Next page */ + case SL_KEY_NPAGE: /* Next page */ case SL_KEY_C3: /* lower right of keypad */ c = PGDOWN; break; - case SL_KEY_PPAGE: /* Previous page */ + case SL_KEY_PPAGE: /* Previous page */ case SL_KEY_A3: /* upper right of keypad */ c = PGUP; break; @@ -2193,7 +2204,7 @@ PUBLIC void LYUpperCase ARGS1( * Remove ALL whitespace from a string (including embedded blanks). */ PUBLIC void LYRemoveBlanks ARGS1( - char *, buffer) + char *, buffer) { if (buffer != 0) { size_t i, j; @@ -2208,7 +2219,7 @@ PUBLIC void LYRemoveBlanks ARGS1( * Skip whitespace */ PUBLIC char * LYSkipBlanks ARGS1( - char *, buffer) + char *, buffer) { while (isspace((unsigned char)(*buffer))) buffer++; @@ -2219,7 +2230,7 @@ PUBLIC char * LYSkipBlanks ARGS1( * Skip non-whitespace */ PUBLIC char * LYSkipNonBlanks ARGS1( - char *, buffer) + char *, buffer) { while (*buffer != 0 && !isspace((unsigned char)(*buffer))) buffer++; @@ -2252,7 +2263,7 @@ PUBLIC CONST char * LYSkipCNonBlanks ARGS1( * Trim leading blanks from a string */ PUBLIC void LYTrimLeading ARGS1( - char *, buffer) + char *, buffer) { char *skipped = LYSkipBlanks(buffer); while ((*buffer++ = *skipped++) != 0) @@ -2263,7 +2274,7 @@ PUBLIC void LYTrimLeading ARGS1( * Trim trailing blanks from a string */ PUBLIC void LYTrimTrailing ARGS1( - char *, buffer) + char *, buffer) { size_t i = strlen(buffer); while (i != 0 && isspace((unsigned char)buffer[i-1])) @@ -2320,7 +2331,7 @@ PRIVATE char killbuffer[1024] = "\0"; PUBLIC void LYSetupEdit ARGS4( EDREC *, edit, - char *, old, + char *, old, int, maxstr, int, maxdsp) { @@ -3015,9 +3026,9 @@ PUBLIC void LYRefreshEdit ARGS1( #define CurModif MyEdit.current_modifiers PUBLIC int LYgetstr ARGS4( - char *, inputline, + char *, inputline, int, hidden, - size_t, bufsize, + size_t, bufsize, int, recall) { int x, y, MaxStringSize; @@ -3280,8 +3291,8 @@ PUBLIC char *LYstrsep ARGS2( * It is a case insensitive search. */ PUBLIC char * LYstrstr ARGS2( - char *, chptr, - CONST char *, tarptr) + char *, chptr, + CONST char *, tarptr) { int len = strlen(tarptr); @@ -3307,8 +3318,8 @@ PUBLIC char * LYstrstr ARGS2( * It is a case insensitive search. */ PUBLIC char * LYno_attr_char_case_strstr ARGS2( - char *, chptr, - char *, tarptr) + char *, chptr, + char *, tarptr) { register char *tmpchptr, *tmptarptr; @@ -3418,8 +3429,8 @@ PRIVATE int LYAddToCloset ARGS1(char*, str) * It is a case sensitive search. */ PUBLIC char * LYno_attr_char_strstr ARGS2( - char *, chptr, - char *, tarptr) + char *, chptr, + char *, tarptr) { register char *tmpchptr, *tmptarptr; @@ -3476,13 +3487,14 @@ PUBLIC char * LYno_attr_char_strstr ARGS2( * It is a case insensitive search. - KW & FM */ PUBLIC char * LYno_attr_mbcs_case_strstr ARGS5( - char *, chptr, - char *, tarptr, + char *, chptr, + CONST char *, tarptr, BOOL, utf_flag, int *, nstartp, int *, nendp) { - register char *tmpchptr, *tmptarptr; + char *tmpchptr; + CONST char *tmptarptr; int len = 0; int offset; @@ -3518,9 +3530,9 @@ PUBLIC char * LYno_attr_mbcs_case_strstr ARGS5( /* * One char target. */ - *nstartp = offset; - *nendp = len; - return(chptr); + if (nstartp) *nstartp = offset; + if (nendp) *nendp = len; + return(chptr); } if (!utf_flag && HTCJK != NOCJK && !isascii(*chptr) && *chptr == *tarptr && @@ -3539,8 +3551,8 @@ PUBLIC char * LYno_attr_mbcs_case_strstr ARGS5( /* * One character match. - FM */ - *nstartp = offset; - *nendp = len + tarlen; + if (nstartp) *nstartp = offset; + if (nendp) *nendp = len + tarlen; return(chptr); } tarlen++; @@ -3557,7 +3569,7 @@ PUBLIC char * LYno_attr_mbcs_case_strstr ARGS5( * See if the rest of the target matches. - FM */ while (1) { - if (!IsSpecialAttrChar(*tmpchptr)) { + if (!IsSpecialAttrChar(*tmpchptr)) { if (!utf_flag && HTCJK != NOCJK && !isascii(*tmpchptr)) { if (*tmpchptr == *tmptarptr && *(tmpchptr + 1) == *(tmptarptr + 1) && @@ -3565,7 +3577,7 @@ PUBLIC char * LYno_attr_mbcs_case_strstr ARGS5( tmpchptr++; tmptarptr++; } else { - break; + break; } } else if (0 != UPPER8(*tmpchptr, *tmptarptr)) { break; @@ -3577,18 +3589,17 @@ PUBLIC char * LYno_attr_mbcs_case_strstr ARGS5( tmpchptr++; tmptarptr++; - } else { + } else { tmpchptr++; - } + } - if (*tmptarptr == '\0') { - *nstartp = offset; - *nendp = len + tarlen; - return(chptr); - } - if (*tmpchptr == '\0') { - break; - } + if (*tmptarptr == '\0') { + if (nstartp) *nstartp = offset; + if (nendp) *nendp = len + tarlen; + return(chptr); + } + if (*tmpchptr == '\0') + break; } } else if (!(IS_UTF_EXTRA(*chptr) || IsSpecialAttrChar(*chptr))) { @@ -3615,19 +3626,20 @@ PUBLIC char * LYno_attr_mbcs_case_strstr ARGS5( * LY_UNDERLINE_END_CHAR * LY_BOLD_START_CHAR * LY_BOLD_END_CHAR - * LY_SOFT_HYPHEN + * LY_SOFT_HYPHEN * if present in chptr. * It assumes UTF8 if utf_flag is set. * It is a case sensitive search. - KW & FM */ PUBLIC char * LYno_attr_mbcs_strstr ARGS5( - char *, chptr, - char *, tarptr, + char *, chptr, + CONST char *, tarptr, BOOL, utf_flag, int *, nstartp, int *, nendp) { - register char *tmpchptr, *tmptarptr; + char *tmpchptr; + CONST char *tmptarptr; int len = 0; int offset; @@ -3659,9 +3671,9 @@ PUBLIC char * LYno_attr_mbcs_strstr ARGS5( /* * One char target. */ - *nstartp = offset; - *nendp = len + 1; - return(chptr); + if (nstartp) *nstartp = offset; + if (nendp) *nendp = len + 1; + return(chptr); } if (!utf_flag && HTCJK != NOCJK && !isascii(*chptr) && *tmpchptr != '\0' && @@ -3679,8 +3691,8 @@ PUBLIC char * LYno_attr_mbcs_strstr ARGS5( /* * One character match. - FM */ - *nstartp = offset; - *nendp = len + tarlen; + if (nstartp) *nstartp = offset; + if (nendp) *nendp = len + tarlen; return(chptr); } tarlen++; @@ -3721,14 +3733,13 @@ PUBLIC char * LYno_attr_mbcs_strstr ARGS5( } if (*tmptarptr == '\0') { - *nstartp = offset; - *nendp = len + tarlen; + if (nstartp) *nstartp = offset; + if (nendp) *nendp = len + tarlen; return(chptr); } - if (*tmpchptr == '\0') { + if (*tmpchptr == '\0') break; } - } } else if (!(IS_UTF_EXTRA(*chptr) || IsSpecialAttrChar(*chptr))) { if (!utf_flag && HTCJK != NOCJK && !isascii(*chptr) && @@ -3781,11 +3792,11 @@ PUBLIC char * SNACat ARGS3( strncpy(*dest + length, src, n); *(*dest + length + n) = '\0'; /* terminate */ } else { - *dest = (char *)calloc(1, strlen(src) + 1); + *dest = (char *)calloc(1, n + 1); if (*dest == NULL) outofmem(__FILE__, "SNACat"); - strncpy(*dest, src, n); - *dest[n] = '\0'; /* terminate */ + memcpy(*dest, src, n); + (*dest)[n] = '\0'; /* terminate */ } } return *dest; @@ -3845,6 +3856,13 @@ PRIVATE long UniToLowerCase ARGS1(long, upper) */ PUBLIC int UPPER8 ARGS2(int,ch1, int,ch2) { + /* if they are the same or one is a null characters return immediately. */ + if (ch1 == ch2) + return 0; + if (!ch2) + return (unsigned char)ch1; + else if (!ch1) + return -(unsigned char)ch2; /* case-insensitive match for us-ascii */ if ((unsigned char)TOASCII(ch1) < 128 && (unsigned char)TOASCII(ch2) < 128) @@ -3858,9 +3876,12 @@ PUBLIC int UPPER8 ARGS2(int,ch1, int,ch2) return(TOUPPER(ch1) - TOUPPER(ch2)); /* old-style */ else { - long uni_ch1 = UCTransToUni(ch1, current_char_set); - long uni_ch2 = UCTransToUni(ch2, current_char_set); - return(UniToLowerCase(uni_ch1) - UniToLowerCase(uni_ch2)); + long uni_ch2 = UCTransToUni(ch2, current_char_set); + long uni_ch1; + if (uni_ch2 < 0) + return (unsigned char)ch1; + uni_ch1 = UCTransToUni(ch1, current_char_set); + return(UniToLowerCase(uni_ch1) - UniToLowerCase(uni_ch2)); } } diff --git a/src/LYStrings.h b/src/LYStrings.h index 550c4096..e836c6a4 100644 --- a/src/LYStrings.h +++ b/src/LYStrings.h @@ -47,13 +47,13 @@ extern int LYmbcsstrlen PARAMS(( BOOL utf_flag)); extern char * LYno_attr_mbcs_strstr PARAMS(( char * chptr, - char * tarptr, + CONST char * tarptr, BOOL utf_flag, int * nstartp, int * nendp)); extern char * LYno_attr_mbcs_case_strstr PARAMS(( char * chptr, - char * tarptr, + CONST char * tarptr, BOOL utf_flag, int * nstartp, int * nendp)); diff --git a/src/LYUtils.c b/src/LYUtils.c index a48994fa..4d30777d 100644 --- a/src/LYUtils.c +++ b/src/LYUtils.c @@ -127,15 +127,17 @@ PUBLIC void highlight ARGS3( char buffer[200]; int i; char tmp[7]; -#if defined(FANCY_CURSES) || defined(USE_SLANG) +#ifdef SHOW_WHEREIS_TARGETS char *cp; char *theData = NULL; char *Data = NULL; int Offset, HitOffset, tLen; int LenNeeded; BOOL TargetEmphasisON = FALSE; + BOOL target1_drawn = NO; #endif BOOL utf_flag = (BOOL)(LYCharSet_UC[current_char_set].enc == UCT_ENC_UTF8); + BOOL hl1_drawn = NO; #if defined(USE_COLOR_STYLE) && !defined(NO_HILIT_FIX) BOOL hl2_drawn=FALSE; /* whether links[cur].hightext2 is already drawn properly */ @@ -165,10 +167,22 @@ PUBLIC void highlight ARGS3( #define LXP (links[cur].lx) #define LYP (links[cur].ly) #endif - move(links[cur].ly, links[cur].lx); #ifndef USE_COLOR_STYLE - lynx_start_link_color (flag == ON, links[cur].inUnderline); + if (links[cur].type == WWW_FORM_LINK_TYPE || + !links[cur].hightext) { + LYMoveToLink(cur, target, NULL, + flag, links[cur].inUnderline, utf_flag); + lynx_start_link_color (flag == ON, links[cur].inUnderline); + } else { + LYMoveToLink(cur, target, links[cur].hightext, + flag, links[cur].inUnderline, utf_flag); + hl1_drawn = YES; +#ifdef SHOW_WHEREIS_TARGETS + target1_drawn = YES; +#endif + } #else + move(links[cur].ly, links[cur].lx); if (flag == ON) { LynxChangeStyle(s_alink, STACK_ON, 0); } else { @@ -227,18 +241,18 @@ PUBLIC void highlight ARGS3( redraw_lines_of_link(cur); } else #endif - { + if (!hl1_drawn) { /* * Copy into the buffer only what will fit * within the width of the screen. */ - LYmbcsstrncpy(buffer, - (links[cur].hightext ? - links[cur].hightext : ""), - (sizeof(buffer) - 1), - ((LYcols - 1) - links[cur].lx), - utf_flag); - addstr(buffer); + LYmbcsstrncpy(buffer, + (links[cur].hightext ? + links[cur].hightext : ""), + (sizeof(buffer) - 1), + ((LYcols - 1) - links[cur].lx), + utf_flag); + addstr(buffer); } } @@ -279,7 +293,8 @@ PUBLIC void highlight ARGS3( #endif lynx_stop_link_color (flag == ON, links[cur].inUnderline); -#if defined(FANCY_CURSES) || defined(USE_SLANG) +#ifdef SHOW_WHEREIS_TARGETS + if (!target1_drawn) /* * If we have an emphasized WHEREIS hit in the highlighted * text, restore the emphasis. Note that we never emphasize @@ -1759,7 +1774,7 @@ highlight_search_done: */ LYHideCursor(); else -#endif /* FANCY CURSES || USE_SLANG */ +#endif /* SHOW_WHEREIS_TARGETS */ /* * Never hide the cursor if there's no FANCY CURSES or SLANG. */ @@ -1893,12 +1908,21 @@ PUBLIC void statusline ARGS1( if (p) p= '\0'; } +#if 0 + /* This is broken. It shows a truncated name if the complete URL is + so long that it has already been shortened by the caller to fit. + Moreover it doesn't belong here. This function should just display + what it's asked to and not second-guess its caller. If you want + a different message displayed, pass it a different message. + Finally, I dislike the intended change anyway. It shows less + information, it is a dumbed down interface. - kw */ if (strncmp(text, "LYNXDOWNLOAD:", 13) == 0) { p = strstr(text + 13, "SugFile="); if (p != NULL) { strcpy(text_buff, p + 3); } } +#endif /* * Deal with any CJK escape sequences and Kanji if we have a CJK @@ -3240,7 +3264,13 @@ PUBLIC void size_change ARGS1( LYcols = SLtt_Screen_Cols; #ifdef SLANG_MBCS_HACK PHYSICAL_SLtt_Screen_Cols = LYcols; - SLtt_Screen_Cols = (LYcols * 6); +#ifdef SLANG_NO_LIMIT /* define this if slang has been fixed */ + SLtt_Screen_Cols = (LYcols-1) * 6; +#else + /* Needs to be limited: fixed buffer bugs in slang can cause crash, + see slang's SLtt_smart_puts - kw */ + SLtt_Screen_Cols = HTMIN((LYcols-1) * 6, 255); +#endif #endif /* SLANG_MBCS_HACK */ if (sig == 0) /* @@ -7617,9 +7647,9 @@ PUBLIC void LYSyslog ARGS1( CTRACE((tfp, "...alter %s\n", buf)); FREE(buf); return; - } + } } - syslog (LOG_INFO|LOG_LOCAL5, arg); + syslog (LOG_INFO|LOG_LOCAL5, "%s", arg ? arg : "(null-URL)"); } PUBLIC void LYCloselog NOARGS diff --git a/src/TRSTable.c b/src/TRSTable.c new file mode 100644 index 00000000..3545fdb8 --- /dev/null +++ b/src/TRSTable.c @@ -0,0 +1,1335 @@ +/* Simple table object +** =================== +** Authors +** KW Klaus Weide <kweide@enteract.com> +** History: +** 2 Jul 1999 KW Created. +*/ + +#include <HTUtils.h> +#include <HTStyle.h> /* for HT_LEFT, HT_CENTER, HT_RIGHT */ +#include <LYCurses.h> +#include <TRSTable.h> + +#include <LYLeaks.h> + +#define CELLS_GROWBY 2 +#define ROWS_GROWBY 2 +#define MAX_STBL_POS (LYcols-1) + +typedef enum { + CS_invalid = -1, + CS_new = 0, + CS__0, /* new, at BOL */ + CS__0eb, /* starts at BOL, empty, break */ + CS__eb, /* empty, break */ + CS__0cb, /* starts at BOL, content, break */ + CS__cb, /* content, break */ + CS__0f, /* starts at BOL, finished */ + CS__ef, /* empty, finished */ + CS__0cf, /* starts at BOL, content, finished */ + CS__cf, /* content, finished */ + CS__ebc, /* empty, break, more content */ + CS__cbc /* content, break, more content */ +} cellstate_t; + +typedef struct _STable_states { + cellstate_t prev_state; + cellstate_t state; + int lineno; /* last line no. looked at */ + int icell_core; /* first/best 'core' cell in row so far */ + int x_td; /* x pos of currently open cell or -1 */ + int pending_len; /* if state is CS__0?[ec]b (??) */ +} STable_states; + + +typedef struct _STable_cellinfo { + int Line; /* lineno in doc (zero-based) */ + int pos; /* column where cell starts */ + int len; /* number of character positions */ + int colspan; /* number of columns to span */ + short alignment; /* one of HT_LEFT, HT_CENTER, HT_RIGHT */ +} STable_cellinfo; + +typedef struct _STable_rowinfo { + int Line; /* lineno in doc (zero-based) */ + int ncells; /* number of table cells */ +/* int pending_skip;*/ /* skip this many after finishing open cell */ + BOOL fixed_line; /* if we have a 'core' line of cells */ + int allocated; /* number of table cells allocated */ + STable_cellinfo * cells; + short alignment; /* global align attribute for this row */ +} STable_rowinfo; + +struct _STable_info { + int startline; /* lineno where table starts (zero-based) */ + int nrows; /* number of rows */ + int ncols; /* number of rows */ + int maxlen; /* sum of max. cell lengths of any row */ + int maxpos; /* max. of max. cell pos's of any row */ + int allocated_rows; /* number of rows allocated */ + int allocated_sumcols; /* number of sumcols allocated */ + STable_cellinfo * sumcols; /* for summary (max len/pos) col info */ + STable_rowinfo * rows; + short alignment; /* global align attribute for this table */ + STable_states s; +}; + +/* +** Functions and structures in this source file keep track of positions. +** They don't know about the character data in those lines, or about +** the HText and HTLine structures. GridText.c doesn't know about our +** structures. It should stay that way. +** +** The basic idea: we let the code in HTML.c/GridText.c produce and format +** output "as usual", i.e. as without Simple Table support. We keep track +** of the positions in the generated output where cells and rows start (or +** end). If all goes well, that preliminary output (stored in HText/HTLine +** structures) can be fixed up when the TABLE end tag is processed, by just +** inserting spaces in the right places (and possibly changing alignment). +** If all goes not well, we already have a safe fallback. +** +** Note that positions passed to and from these functions should be +** in terms of screen positions, not just byte counts in a HTLine.data +** (cf. line->data vs. HText_TrueLineSize). +** +** Memory is allocated dynamically, so we can have tables of arbitrary +** length. On allocation error we just return and error indication +** instead of outofmem(), so caller can give up table tracking and maybe +** recover memory. +** +** Implemented: +** - ALIGN={left,right,center,justify} applied to individual table cells +** ("justify" is treated as "left") +** - Inheritance of horizontal alignment according to HTML 4.0 (with the +** exception of COLGROUP/COL) +** - COLSPAN >1 (nearly untested) +** - Line breaks at start of first cell or at end of last cell are treated +** as if they were not part of the cell and row. This allows us to +** cooperate with one way in which tables have been made friendly to +** browsers without any table support. +** Missing, but can be added: +** - Support for COLGROUP/COL +** - ROWSPAN >1 (reserving cells in following rows) +** - Tables wider than display. The limitation is not here but in GridText.c +** etc. If horizontal scrolling were implemented there, the mechanisms +** here coudl deal with wide tables (just change MAX_STBL_POS code). +** Missing, unlikely to add: +** - Support for non-LTR directionality. A general problem, support is +** lacking throughout the lynx code. +** - Support for most other table-related attributes. Most of them are +** for decorative purposes. +** Impossible or very unlikely (because it doesn't fit the model): +** - Any cell contents of more than one line, line breaks within cells. +** Anything that requires handling cell contents as paragraphs (block +** elements), like reflowing. Vertical alignment. +*/ +PRIVATE int Stbl_finishCellInRow PARAMS(( + STable_rowinfo * me, + STable_states * s, + BOOL certain, + int lineno, + int pos)); +PRIVATE int Stbl_finishRowInTable PARAMS(( + STable_info * me)); + + +PUBLIC struct _STable_info * Stbl_startTABLE ARGS1( + short, alignment) +{ + STable_info *me = (STable_info *) calloc(1, sizeof(STable_info)); + if (me) { + me->alignment = alignment; + me->s.x_td = -1; + me->s.icell_core = -1; + } + return me; +} + +PRIVATE void free_rowinfo ARGS1( + STable_rowinfo *, me) +{ + if (me && me->allocated) { + FREE(me->cells); + } +} + +PUBLIC void Stbl_free ARGS1( + STable_info *, me) +{ + if (me && me->allocated_rows && me->rows) { + int i; + for (i = 0; i <= me->nrows; i++) + free_rowinfo(me->rows + i); + free(me->rows); + } + if (me) + FREE(me->sumcols); + FREE(me); +} + +/* + * Returns -1 on error, otherwise index of just-added table cell. + */ +PRIVATE int Stbl_addCellToRow ARGS7( + STable_rowinfo *, me, + STable_states *, s, + int, colspan, + short, alignment, + BOOL, isheader, + int, lineno, + int *, ppos) +{ + STable_cellinfo *cells; + int i; + int last_colspan = me->ncells ? + me->cells[me->ncells - 1].colspan : 1; + cellstate_t newstate; + + if (me->ncells == 0) + s->prev_state = CS_invalid; + else if (s->prev_state == CS_invalid || + (/*s->state != CS_new && */ s->state != CS__0 && + s->state != CS__ef && s->state != CS__0f)) + s->prev_state = s->state; + + if (me->ncells == 0 || *ppos == 0) + newstate = CS__0; + else + newstate = CS_new; + + if (me->ncells > 0 && s->pending_len > 0) { + if (s->prev_state != CS__cbc) + me->cells[me->ncells - 1].len = s->pending_len; + s->pending_len = 0; + } + s->x_td = *ppos; + + if (lineno != s->lineno) { + if (!me->fixed_line) { + if (me->ncells == 0 || *ppos == 0) { + switch (s->prev_state) { + case CS_invalid: + case CS__0: + case CS__0eb: + case CS__0cb: + case CS__0f: + case CS__0cf: + if (me->ncells > 0) + for (i = me->ncells + last_colspan - 2; + i >= me->ncells - 1; i--) { + me->cells[i].pos = *ppos; + me->cells[i].Line = lineno; + } + me->Line = lineno; + /* s->lineno = lineno; */ + break; + case CS_new: + case CS__eb: + case CS__ef: + case CS__cf: + default: + break; + case CS__cb: + *ppos = me->cells[me->ncells - 1].pos + + me->cells[me->ncells - 1].len; + } + } else { + switch (s->prev_state) { + case CS__0: + case CS__0eb: + case CS__0f: + break; + case CS__cb: + return -1; + case CS__cf: +/* HTAlert("foo woo!!"); */ + return -1; + case CS__0cb: + case CS__0cf: + if (*ppos > me->cells[0].pos) + me->Line = lineno; + me->fixed_line = YES; + break; + case CS_new: + case CS__eb: + case CS__ef: + default: + me->fixed_line = YES; + break; + case CS__cbc: + return -1; + } + } + } + if (me->fixed_line && lineno != me->Line) { + switch (s->prev_state) { + case CS__cb: + case CS__cf: + if (*ppos > 0) + return -1; + else + *ppos = me->cells[me->ncells - 1].pos /* == 0 */ + + me->cells[me->ncells - 1].len; + break; + case CS__0cf: + case CS__0cb: + if (*ppos == 0 || *ppos <= me->cells[0].pos) + *ppos = me->cells[me->ncells - 1].pos /* == 0 */ + + me->cells[me->ncells - 1].len; + break; + case CS__0: + case CS__0f: + case CS__0eb: +/* me->Line = lineno; */ + break; + case CS_new: + case CS__eb: + case CS__ef: + default: + *ppos = me->cells[me->ncells - 1].pos; break; + case CS__cbc: +/* *ppos = me->cells[me->ncells - 1].pos + + me->cells[me->ncells - 1].len; + if (*ppos > 0) + return -1; */ + break; + case CS_invalid: + break; + } + } + s->lineno = lineno; + } else { /* lineno == s->lineno: */ + switch (s->prev_state) { + case CS_invalid: + case CS__0: + case CS__0eb: /* cannot happen */ + case CS__0cb: /* cannot happen */ + case CS__0f: + case CS__0cf: /* ##302?? set icell_core? or only in finish? */ + break; + case CS__eb: /* cannot happen */ + case CS__cb: /* cannot happen */ + case CS__ef: + break; + case CS__ebc: /* should have done smth in finish */ + case CS__cbc: /* should have done smth in finish */ + break; + case CS_new: + case CS__cf: + if (me->fixed_line && me->Line != lineno) { + return -1; + } else { + me->fixed_line = YES; + me->Line = lineno; + } + } + } + +#if 0 /* MEGA_COMMENTOUT */ + if (lineno != me->Line) { + if (!me->fixed_line) { + if (me->ncells == 0 || + (*ppos == 0 && me->cells[me->ncells - 1].pos == 0)) { + if (me->ncells > 0) + for (i = me->ncells + last_colspan - 2; + i >= 0; i--) { + me->cells[i].pos = *ppos; + me->cells[i].Line = lineno; + } + me->Line = lineno; + s->state = CS__0; + } + if (*ppos > 0 && me->ncells > 0 && + (me->cells[me->ncells - 1].pos > 0 || + me->cells[me->ncells - 1].len > 0)) { + me->fixed_line = YES; + + } + } + if (me->fixed_line && lineno != me->Line) { + if (me->cells[me->ncells - 1].pos > 0 && + me->cells[me->ncells - 1].len > 0) { + return -1; + } else if (me->cells[me->ncells - 1].pos == 0 && + me->cells[me->ncells - 1].len > 0) { + if (*ppos > 0 && *ppos > me->cells[0].pos) + me->Line = lineno; + else + *ppos = me->cells[me->ncells - 1].pos; /* == 0 */ + } else /* if (me->cells[me->ncells - 1].pos == 0 && + me->cells[me->ncells - 1].len <= 0) { + me->Line = lineno; + } else */ { + *ppos = me->cells[me->ncells - 1].pos; + } + } +#if 0 + for (i = 0; i < me->ncells; i++) { + if (me->cells[i].Line == lineno) { + break; + } else if (me->cells[i].len <= 0) { + me->cells[i].Line = lineno; + /* @@@ reset its pos too ?? */ + } else { + break; + } + } + if (i < me->ncells && me->cells[i].Line != lineno) + return -1; + me->Line = lineno; +#endif + } +#endif /* MEGA_COMMENTOUT */ + s->state = newstate; + + if (me->ncells > 0 && me->cells[me->ncells - 1].colspan > 1) { + me->ncells += me->cells[me->ncells-1].colspan - 1; + } + { + int growby = 0; + while (me->ncells + colspan + 1 > me->allocated + growby) + growby += CELLS_GROWBY; + if (growby) { + if (me->allocated == 0 && !me->cells) { + cells = calloc(growby, sizeof(STable_cellinfo)); + } else { + cells = realloc(me->cells, + (me->allocated + growby) + * sizeof(STable_cellinfo)); + } + if (cells) { + me->allocated += growby; + me->cells = cells; + } else { + return -1; + } + } + } + + me->cells[me->ncells].Line = lineno; + me->cells[me->ncells].pos = *ppos; + me->cells[me->ncells].len = -1; + me->cells[me->ncells].colspan = colspan; + me->cells[me->ncells].alignment = + (alignment==HT_ALIGN_NONE) ? me->alignment : alignment; + if (me->cells[me->ncells].alignment==HT_ALIGN_NONE) + me->cells[me->ncells].alignment = isheader ? HT_CENTER : HT_LEFT; + for (i = me->ncells + 1; i < me->ncells + colspan; i++) { + me->cells[i].Line = lineno; + me->cells[i].pos = *ppos; + me->cells[i].len = -1; + me->cells[i].colspan = 0; + me->cells[i].alignment = HT_LEFT; + } + me->cells[me->ncells + colspan].pos = -1; /* not yet used */ + me->ncells++; + return (me->ncells - 1); +} + +PRIVATE int Stbl_finishCellInRow ARGS5( + STable_rowinfo *, me, + STable_states *, s, + BOOL, certain, + int, lineno, + int, pos) +{ + STable_cellinfo *lastcell; + cellstate_t newstate = CS_invalid; + BOOL broken = NO, empty; + + if (me->ncells <= 0) + return -1; + lastcell = me->cells + (me->ncells - 1); + broken = (lineno != lastcell->Line || lineno != s->lineno); + empty = broken ? (pos == 0) : (pos <= s->x_td); + if (broken) { + if (!certain) { + switch (s->state) { + case CS_invalid: + newstate = empty ? CS_invalid : CS__cbc; + break; + case CS__0: + newstate = empty ? CS__0eb : CS__0cb; + break; + case CS__0eb: + newstate = empty ? CS__0eb : CS__ebc; + s->state = newstate; + if (me->fixed_line) { + if (empty) + return lastcell->len <= 0 ? 0 : lastcell->len; + else + return lastcell->len <= 0 ? 0 : -1; + } else { + if (empty) + return lastcell->len <= 0 ? 0 : lastcell->len; + else + return lastcell->len <= 0 ? 0 : 0; + } + newstate = empty ? CS__0eb : CS__ebc; + break; + case CS__0cb: + if (!me->fixed_line) { + if (empty) { /* ##462_return_0 */ +/* if (s->icell_core == -1) + s->icell_core = lastcell->Line; */ /* we don't know yet */ + /* lastcell->Line = lineno; */ + } else { /* !empty */ + if (s->icell_core == -1) + me->Line = -1; + } + } + if (s->pending_len && empty) { /* ##470_why_that?? */ + if ((me->fixed_line && me->Line == lastcell->Line) || + s->icell_core == me->ncells - 1) + lastcell->len = s->pending_len; + s->pending_len = 0; + } /* @@@ for empty do smth. about ->Line / ->icell_core !! */ + newstate = empty ? CS__0cb : CS__cbc; /* ##474_needs_len!=-1? */ + break; + case CS__0f: + case CS__0cf: + break; + case CS_new: + newstate = empty ? CS__eb : CS__cb; + break; + case CS__eb: /* ##484_set_pending_ret_0_if_empty? */ + newstate = empty ? CS__eb : CS__ebc; + s->state = newstate; + if (me->fixed_line) { + if (empty) + return lastcell->len <= 0 ? 0 : lastcell->len; + else + return lastcell->len <= 0 ? 0 : -1; + } else { + if (empty) + return lastcell->len <= 0 ? 0 : lastcell->len; + else + return lastcell->len <= 0 ? 0 : -1; + } + newstate = empty ? CS__eb : CS__ebc; + break; + case CS__cb: + if (s->pending_len && empty) { /* ##496: */ + lastcell->len = s->pending_len; + s->pending_len = 0; + } /* @@@ for empty do smth. about ->Line / ->icell_core !! */ + if (empty) { + if (!me->fixed_line) { + me->fixed_line = YES; + me->Line = lastcell->Line; /* should've happened in break */ + } else { + if (me->Line != lastcell->Line) + return -1; + } + } else { + if (!me->fixed_line) { + me->fixed_line = YES; + me->Line = lastcell->Line; /* should've happened in break */ + } + s->state = CS__cbc; + return -1; + } + newstate = empty ? CS__cb : CS__cbc; + break; + case CS__ef: + return 0; + case CS__cf: + return lastcell->len; /* ##523_change_state? */ + case CS__cbc: + if (!me->fixed_line) { + if (empty) { + if (s->icell_core == -1) /* ##528??: */ + me->Line = lineno; + /* lastcell->Line = lineno; */ + } else { /* !empty */ + if (s->icell_core == -1) + me->Line = -1; + } + } + s->pending_len = 0; + newstate = empty ? CS_invalid : CS__cbc; + break; + default: + break; + } + } else { /* broken, certain: */ + s->x_td = -1; + switch (s->state) { + case CS_invalid: + /* ##540_return_-1_for_invalid_if_len!: */ + if (!empty && lastcell->len > 0) { + newstate = CS__0cf; + s->state = newstate; + return -1; + } + /* ##541_set_len_0_Line_-1_sometimes: */ + lastcell->len = 0; + lastcell->Line = -1; + /* fall thru ##546 really fall thru??: */ + newstate = empty ? CS_invalid : CS__cbc; break; + case CS__0: + newstate = empty ? CS__0f : CS__0cf; break; + case CS__0eb: + newstate = empty ? CS__0f : CS__0cf; /* ebc?? */ + s->state = newstate; + if (me->fixed_line) { + if (empty) + return lastcell->len <= 0 ? 0 : lastcell->len; + else + return lastcell->len <= 0 ? 0 : -1; + } else { + if (empty) + return lastcell->len <= 0 ? 0 : lastcell->len; + else + return lastcell->len <= 0 ? 0 : 0; + } + newstate = empty ? CS__0f : CS__0cf; break; /* ebc?? */ + case CS__0cb: + if (s->pending_len) { + if (empty) + lastcell->len = s->pending_len; + else + lastcell->len = 0; + s->pending_len = 0; + } + if (!me->fixed_line) { + if (empty) { + if (s->icell_core == -1) + s->icell_core = me->ncells - 1; + /* lastcell->Line = lineno; */ + } else { /* !empty */ + if (s->icell_core == -1) + me->Line = -1; + } + } + if (s->pending_len && empty) { + lastcell->len = s->pending_len; + s->pending_len = 0; + } /* @@@ for empty do smth. about ->Line / ->icell_core !! */ + newstate = empty ? CS__0cf : CS__cbc; break; + case CS__0f: + newstate = CS__0f; + case CS__0cf: + break; + case CS_new: + newstate = empty ? CS__ef : CS__cf; break; + case CS__eb: + newstate = empty ? CS__ef : CS__ef; /* ##579??? !!!!! */ + s->state = newstate; + if (me->fixed_line) { + if (empty) + return lastcell->len <= 0 ? 0 : lastcell->len; + else + return lastcell->len <= 0 ? 0 : -1; + } else { + if (empty) + return lastcell->len <= 0 ? 0 : lastcell->len; + else + return lastcell->len <= 0 ? 0 : -1; + } + newstate = empty ? CS__ef : CS__ef; break; + case CS__cb: + if (s->pending_len && empty) { + lastcell->len = s->pending_len; + s->pending_len = 0; + } + if (empty) { + if (!me->fixed_line) { + me->fixed_line = YES; + me->Line = lastcell->Line; /* should've happened in break */ + } else { + if (me->Line != lastcell->Line) + return -1; + } + } else { + return -1; + } + newstate = empty ? CS__cf : CS__cbc; break; + case CS__ef: /* ignored error */ + case CS__cf: /* ignored error */ + break; + case CS__ebc: /* ##540_handle_ebc: */ + lastcell->len = 0; + if (!me->fixed_line) { + if (!empty) { + if (s->icell_core == -1) + lastcell->Line = -1; + } + } + s->pending_len = 0; + newstate = empty ? CS_invalid : CS__cbc; break; + case CS__cbc: /* ##586 */ + lastcell->len = 0; /* ##613 */ + if (me->fixed_line && me->Line == lastcell->Line) + return -1; + if (!me->fixed_line) { + if (empty) { + if (s->icell_core == -1) + me->Line = lineno; + /* lastcell->Line = lineno; */ +#if 0 /* ?? */ + } else { /* !empty */ + if (s->icell_core == -1) + me->Line = -1; +#endif + } + } + s->pending_len = 0; /* ##629 v */ + newstate = empty ? CS_invalid : CS__cbc; break; + } + } + } else { /* (!broken) */ + if (!certain) { + switch (s->state) { + case CS_invalid: + case CS__0: + s->pending_len = empty ? 0 : pos - lastcell->pos; + newstate = empty ? CS__0eb : CS__0cb; + s->state = newstate; + return 0; /* or 0 for xlen to s->pending_len?? */ + case CS__0eb: /* cannot happen */ + newstate = CS__eb; + case CS__0cb: /* cannot happen */ + newstate = CS__cb; break; + case CS__0f: + case CS__0cf: + break; + case CS_new: + if (!empty && s->prev_state == CS__cbc) /* ##609: */ + return -1; + if (!empty) { + if (!me->fixed_line) { + me->fixed_line = YES; + me->Line = lineno; + } else { + if (me->Line != lineno) + return -1; + } + } + newstate = empty ? CS__eb : CS__cb; + s->state = newstate; + if (!me->fixed_line) { + s->pending_len = empty ? 0 : pos - lastcell->pos; + return 0; + } else { + s->pending_len = 0; + lastcell->len = empty ? 0 : pos - lastcell->pos; + return lastcell->len; + } + case CS__eb: /* cannot happen */ + newstate = empty ? CS__eb : CS__ebc; break; + case CS__cb: /* cannot happen */ + newstate = empty ? CS__cb : CS__cbc; break; + case CS__ef: + return 0; + case CS__cf: + return lastcell->len; + case CS__cbc: /* ??? */ + break; + default: + break; + } + } else { /* !broken, certain: */ + s->x_td = -1; + switch (s->state) { + case CS_invalid: /* ##691_no_lastcell_len_for_invalid: */ + if (!(me->fixed_line && me->Line == lastcell->Line)) + lastcell->len = 0; + case CS__0: + newstate = empty ? CS__0f : CS__0cf; break; /* ##630 */ + case CS__0eb: + newstate = empty ? CS__0f : CS__0f; break; /* ??? */ + case CS__0cb: + newstate = empty ? CS__0cf : CS__cbc; break; /* ??? */ + case CS__0f: + newstate = CS__0f; break; /* ??? */ + case CS__0cf: + break; /* ??? */ + case CS_new: + if (!empty && s->prev_state == CS__cbc) + return -1; + if (!empty) { /* ##642_set_fixed!: */ + if (!me->fixed_line) { + me->fixed_line = YES; + me->Line = lineno; + } else { + if (me->Line != lineno) + return -1; + } + } + if (lastcell->len < 0) + lastcell->len = empty ? 0 : pos - lastcell->pos; + newstate = empty ? CS__ef : CS__cf; + s->state = newstate; + return (me->fixed_line && lineno != me->Line) ? -1 : lastcell->len; + case CS__eb: + newstate = empty ? CS__ef : CS__cf; break; /* ??? */ + case CS__cb: + newstate = empty ? CS__cf : CS__cf; break; /* ??? */ + case CS__ef: /* ignored error */ + case CS__cf: /* ignored error */ + default: + break; + } + lastcell->len = pos - lastcell->pos; + } /* if (!certain) ... else */ + } /* if (broken) ... else */ + +#if 0 /* MEGA_COMMENTOUT */ + if (lineno != me->cells[0].Line) { +#if 0 + int i; + for (i = ncells - 1; i >= 0; i--) { + if (!(me->cells[i].len == 0 || me->cells[i].colspan == 0)) + break; + } +#endif + if (lineno >= lastcell->Line) { + if (me->fixed_line) { + if (pos == 0) { + if (lastcell->len <= 0) { + return 0; + } else { + return lastcell->len; + } + } else { /* pos != 0 */ + if (lastcell->len <= 0 && lineno > lastcell->Line && lastcell->Line <= me->Line) { + return 0; + } else { + return -1; + } + } + } else { /* not me->fixed_line */ + if (pos == 0) { + if (lastcell->len <= 0) { + return 0; + } else { + return lastcell->len; + } + } else { /* pos != 0 */ + if (lastcell->len <= 0) { + return 0; + } else { + if (me->ncells == 1 || lastcell->pos == 0) { + return 0; + } else + return -1; + } + } + } + } + } +#endif /* MEGA_COMMENTOUT */ + s->state = newstate; +/* lastcell->len = pos - lastcell->pos; */ + return (lastcell->len); +} + +/* + * Returns -1 on error, otherwise index of just-added table row. + */ +PUBLIC int Stbl_addRowToTable ARGS3( + STable_info *, me, + short, alignment, + int, lineno) +{ + STable_rowinfo *rows, *row; + STable_states * s = &me->s; + if (me->nrows > 0 && me->rows[me->nrows-1].ncells > 0) { + if (s->pending_len > 0) + me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len = s->pending_len; + s->pending_len = 0; +/* if (me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len >= 0 && + me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].Line == lineno) + Stbl_finishCellInTable(me, YES, + lineno, + me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].pos + + me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len); */ + } +#if 0 + s->prev_state = s->state = CS_invalid; + s->lineno = -1; + s->icell_core = -1; +#endif + Stbl_finishRowInTable(me); + if (me->nrows > 0 && me->rows[me->nrows-1].Line == lineno) + me->rows[me->nrows-1].Line = -1; + s->pending_len = 0; + s->x_td = -1; + + { + int i; + int growby = 0; + while (me->nrows + 2 > me->allocated_rows + growby) + growby += ROWS_GROWBY; + if (growby) { + if (me->allocated_rows == 0 && !me->rows) { + rows = calloc(growby, sizeof(STable_rowinfo)); + } else { + rows = realloc(me->rows, + (me->allocated_rows + growby) + * sizeof(STable_rowinfo)); + for (i = 0; rows && i < growby; i++) { + row = rows + me->allocated_rows + i; + row->allocated = 0; + row->ncells = 0; + row->fixed_line = NO; + row->cells = NULL; + row->alignment = HT_ALIGN_NONE; + } + } + if (rows) { + me->allocated_rows += growby; + me->rows = rows; + } else { + return -1; + } + } + } + + me->rows[me->nrows].Line = lineno; + if (me->nrows == 0) + me->startline = lineno; + me->rows[me->nrows].alignment = + (alignment==HT_ALIGN_NONE) ? me->alignment : alignment; + me->nrows++; + me->rows[me->nrows].Line = -1; /* not yet used */ + return (me->nrows - 1); +} + +/* + * Returns -1 on error, otherwise current number of rows. + */ +PRIVATE int Stbl_finishRowInTable ARGS1( + STable_info *, me) +{ + STable_rowinfo *lastrow; + STable_states * s = &me->s; + int ncells; + if (!me->rows || !me->nrows) + return -1; /* no row started! */ + lastrow = me->rows + (me->nrows - 1); + ncells = lastrow->ncells; + if (lastrow->ncells > 0) { + if (s->pending_len > 0) + lastrow->cells[lastrow->ncells - 1].len = s->pending_len; + s->pending_len = 0; + } + s->prev_state = s->state = CS_invalid; + s->lineno = -1; + +#if 0 + if (lastrow->Line == -1 && s->icell_core >= 0) +#endif + if (s->icell_core >= 0 && !lastrow->fixed_line && + lastrow->cells[s->icell_core].Line >= 0) + lastrow->Line = lastrow->cells[s->icell_core].Line; + s->icell_core = -1; + return (me->nrows); +} + +PRIVATE void update_sumcols0 ARGS7( + STable_cellinfo *, sumcols, + STable_rowinfo *, lastrow, + int, pos, + int, len, + int, icell, + int, ispan, + int, allocated_sumcols) +{ + int i; + if (len > 0) { + int sumpos = pos; + int prevsumpos = sumcols[icell + ispan].pos; + int advance; + if (ispan > 0) { + if (lastrow->cells[icell].pos + len > sumpos) + sumpos = lastrow->cells[icell].pos + len; + if (sumcols[icell+ispan-1].pos + sumcols[icell+ispan-1].len > sumpos) + sumpos = sumcols[icell+ispan-1].pos + sumcols[icell+ispan-1].len; + } + advance = sumpos - prevsumpos; + if (advance > 0) { + for (i = icell + ispan; i < allocated_sumcols; i++) { + if (ispan > 0 && sumcols[i].colspan < -1) { + if (i + sumcols[i].colspan < icell + ispan) { + advance = sumpos - sumcols[i].pos; + if (i > 0) + advance = HTMAX(advance, + sumcols[i-1].pos + sumcols[i-1].len + - (sumcols[i].pos)); + if (advance <= 0) + break; + } + } + if (sumcols[i].pos >= 0) + sumcols[i].pos += advance; + else { + sumcols[i].pos = sumpos; + break; + } + } + } + } +} + +/* + * Returns -1 on error, otherwise 0. + */ +PUBLIC int Stbl_addCellToTable ARGS6( + STable_info *, me, + int, colspan, + short, alignment, + BOOL, isheader, + int, lineno, + int, pos) +{ + STable_states * s = &me->s; + STable_rowinfo *lastrow; + STable_cellinfo *sumcols, *sumcol; + int i, icell, ncells, sumpos; +#if 0 + int prevsumpos, advance; +#endif + + if (!me->rows || !me->nrows) + return -1; /* no row started! */ + /* ##850_fail_if_fail?? */ + Stbl_finishCellInTable(me, YES, + lineno, pos); + lastrow = me->rows + (me->nrows - 1); + ncells = lastrow->ncells; /* remember what it was before adding cell. */ + icell = Stbl_addCellToRow(lastrow, s, + colspan, alignment, isheader, + lineno, &pos); + if (icell < 0) + return icell; + if (me->nrows == 1 && me->startline < lastrow->Line) + me->startline = lastrow->Line; + + { + int growby = 0; + while (icell + colspan + 1 > me->allocated_sumcols + growby) + growby += CELLS_GROWBY; + if (growby) { + if (me->allocated_sumcols == 0 && !me->sumcols) { + sumcols = calloc(growby, sizeof(STable_cellinfo)); + } else { + sumcols = realloc(me->sumcols, + (me->allocated_sumcols + growby) + * sizeof(STable_cellinfo)); + for (i = 0; sumcols && i < growby; i++) { + sumcol = sumcols + me->allocated_sumcols + i; + sumcol->pos = sumcols[me->allocated_sumcols-1].pos; + sumcol->len = 0; + sumcol->colspan = 0; + } + } + if (sumcols) { + me->allocated_sumcols += growby; + me->sumcols = sumcols; + } else { + return -1; + } + } + } +#if 0 + if (icell + colspan > me->ncols) { + me->sumcols[icell + colspan].pos = -1; /* not yet used @@@ ??? */ + } +#endif + if (icell + 1 > me->ncols) { + me->ncols = icell + 1; + } + if (colspan > 1 && colspan + me->sumcols[icell + colspan].colspan > 0) + me->sumcols[icell + colspan].colspan = -colspan; + sumpos = pos; + if (ncells > 0) + sumpos += me->sumcols[ncells-1].pos - lastrow->cells[ncells-1].pos; + update_sumcols0(me->sumcols, lastrow, sumpos, + sumpos - (ncells > 0 ? me->sumcols[icell].pos : me->sumcols[icell].pos), + icell, 0, me->allocated_sumcols); +#if 0 + prevsumpos = me->sumcols[icell].pos; + advance = sumpos - prevsumpos; + if (advance > 0) { + for (i = icell; i < me->allocated_sumcols; i++) { + if (me->sumcols[i].pos >= 0) + me->sumcols[i].pos += advance; + else { + me->sumcols[i].pos = sumpos; + break; + } + } + } +#endif + + +#if 0 + int prevopos = (ncells > 0 ? lastrow->cells[ncells-1].pos : 0); + int prevnpos = (ncells > 0 ? me->sumcols[ncells-1].pos : 0); +#endif +#if 0 + if (pos > me->maxpos) { + me->maxpos = pos; + if (me->maxpos > /* @@@ max. line length we can accept */ MAX_STBL_POS) + return -1; + } +#endif + me->maxpos = me->sumcols[me->allocated_sumcols-1].pos; + if (me->maxpos > /* @@@ max. line length we can accept */ MAX_STBL_POS) + return -1; + return 0; +} + +/* + * Returns -1 on error, otherwise 0. + */ +PUBLIC int Stbl_finishCellInTable ARGS4( + STable_info *, me, + BOOL, certain, + int, lineno, + int, pos) +{ + STable_states * s = &me->s; + STable_rowinfo *lastrow; + int len, xlen, icell; + int i; + if (me->nrows == 0) + return -1; + lastrow = me->rows + (me->nrows - 1); + icell = lastrow->ncells - 1; + if (icell < 0) + return icell; + if (s->x_td == -1) + return certain ? -1 : 0; + len = Stbl_finishCellInRow(lastrow, s, certain, lineno, pos); + if (len == -1) + return len; + xlen = (len > 0) ? len : s->pending_len; /* ##890 use xlen if fixed_line?: */ + if (lastrow->fixed_line && lastrow->Line == lineno) + len = xlen; + if (lastrow->cells[icell].colspan > 1) { + /* + * @@@ This is all a too-complicated mess; do we need + * sumcols len at all, or is pos enough?? + * Answer: sumcols len is at least used for center/right + * alignment, and should probably continue to be used there; + * all other uses are probably not necessary. + */ + int spanlen = 0, spanlend = 0; + for (i = icell; i < icell + lastrow->cells[icell].colspan; i++) { + if (me->sumcols[i].len > 0) { + spanlen += me->sumcols[i].len; + if (i > icell) + spanlen++; + } + spanlend = HTMAX(spanlend, + me->sumcols[i+1].pos - me->sumcols[icell].pos); + } + if (spanlend) + spanlend--; + if (spanlend > spanlen) + spanlen = spanlend; + /* @@@ could overcount? */ + if (len > spanlen) + me->maxlen += (len - spanlen); +#if 0 /* this is all quite bogus! */ + if (me->sumcols[icell].colspan > 1) + me->sumcols[icell+me->sumcols[icell].colspan].pos = + HTMAX(me->sumcols[icell].pos + len, + me->sumcols[icell+me->sumcols[icell].colspan].pos); + if (lastrow->cells[icell].colspan > me->sumcols[icell].colspan) { + me->sumcols[icell].colspan = lastrow->cells[icell].colspan; + if (me->sumcols[icell].colspan > 1) + me->sumcols[icell+me->sumcols[icell].colspan].pos = + HTMAX(me->sumcols[icell].pos + len, + me->sumcols[icell+me->sumcols[icell].colspan].pos); + } +#endif + } else if (len > me->sumcols[icell].len) { + if (me->sumcols[icell + 1].colspan >= -1) + me->maxlen += (len - me->sumcols[icell].len); + me->sumcols[icell].len = len; + } + + if (len > 0) { + update_sumcols0(me->sumcols, lastrow, pos, len, + icell, lastrow->cells[icell].colspan, + me->allocated_sumcols); + me->maxpos = me->sumcols[me->allocated_sumcols-1].pos; + } +#if 0 + if (len > 0) { + int sumpos = pos; + int ispan = lastrow->cells[icell].colspan; + int prevsumpos = me->sumcols[icell + ispan].pos; + int advance; + if (lastrow->cells[icell].pos + len > sumpos) + sumpos = lastrow->cells[icell].pos + len; + if (me->sumcols[icell+ispan-1].pos + me->sumcols[icell+ispan-1].len > sumpos) + sumpos = me->sumcols[icell+ispan-1].pos + me->sumcols[icell+ispan-1].len; + advance = sumpos - prevsumpos; + if (advance > 0) { + for (i = icell + ispan; i < me->allocated_sumcols; i++) { + if (me->sumcols[i].colspan < -1) { + if (i + me->sumcols[i].colspan < icell + ispan) { + advance = sumpos - me->sumcols[i].pos; + if (i > 0) + advance = HTMAX(advance, + me->sumcols[i-1].pos + me->sumcols[i-1].len + - (me->sumcols[i].pos)); + if (advance <= 0) + break; + } + } + if (me->sumcols[i].pos >= 0) + me->sumcols[i].pos += advance; + else { + me->sumcols[i].pos = sumpos; + break; + } + } + } + me->maxpos = me->sumcols[me->allocated_sumcols-1].pos; + } +#endif + + if (me->maxlen + (xlen - len) > MAX_STBL_POS) + return -1; + if (me->maxpos > /* @@@ max. line length we can accept */ MAX_STBL_POS) + return -1; + + if (lineno != lastrow->Line) { + /* @@@ Do something here? Or is it taken care of in + Stbl_finishCellInRow ? */ + } + + return 0; +} + +PUBLIC int Stbl_finishTABLE ARGS1( + STable_info *, me) +{ + STable_states * s = &me->s; + int i; + int curpos = 0; + + if (!me || me->nrows <= 0 || me->ncols <= 0) { + return -1; + } + if (me->nrows > 0 && me->rows[me->nrows-1].ncells > 0) { + if (s->pending_len > 0) + me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len = s->pending_len; + s->pending_len = 0; +/* if (me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len >= 0) + Stbl_finishCellInTable(me, YES, + me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].Line, + me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].pos + + me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len); */ + } + Stbl_finishRowInTable(me); + for (i = 0; i < me->ncols; i++) { + if (me->sumcols[i].pos < curpos) { + me->sumcols[i].pos = curpos; + } else { + curpos = me->sumcols[i].pos; + } + if (me->sumcols[i].len > 0) { + curpos += me->sumcols[i].len; + } + } +#if 0 /* ??? */ + for (j = 0; j < me->nrows; j++) { + STable_rowinfo *row = me->rows + i; + for (i = 0; i < row->ncells; i++) { + } + } +#endif + return me->ncols; +} + +PUBLIC short Stbl_getAlignment ARGS1( + STable_info *, me) +{ + return me ? me->alignment : HT_ALIGN_NONE; +} + +PRIVATE int get_fixup_positions ARGS4( + STable_rowinfo *, me, + int *, oldpos, + int *, newpos, + STable_cellinfo *, sumcols) +{ + int i = 0, ip = 0; + int next_i, newlen; + int ninserts; + + if (!me) + return -1; + while (i < me->ncells) { + next_i = i + me->cells[i].colspan; + if (me->cells[i].Line != me->Line) { + if (me->cells[i].Line > me->Line) + break; + i = next_i; + continue; + } + oldpos[ip] = me->cells[i].pos; + newpos[ip] = sumcols[i].pos; + if ((me->cells[i].alignment == HT_CENTER || + me->cells[i].alignment == HT_RIGHT) && + me->cells[i].len > 0) { + newlen = sumcols[next_i].pos - newpos[ip] - 1; + newlen = HTMAX(newlen, sumcols[i].len); + if (me->cells[i].len < newlen) { + if (me->cells[i].alignment == HT_RIGHT) { + newpos[i] += newlen - me->cells[i].len; + } else { + newpos[i] += (newlen - me->cells[i].len) / 2; + } + } + } + ip++; + i = next_i; + } + ninserts = ip; + return ninserts; +} + +/* + * Returns -1 if we have no row for this lineno, or for other error, + * 0 or greater (number of oldpos/newpos pairs) if we have + * a table row. + */ +PUBLIC int Stbl_getFixupPositions ARGS4( + STable_info *, me, + int, lineno, + int *, oldpos, + int *, newpos) +{ + STable_rowinfo * row; + int j; + int ninserts = -1; + if (!me || !me->nrows) + return -1; + for (j = 0; j < me->nrows; j++) { + row = me->rows + j; + if (row->Line == lineno) { + ninserts = get_fixup_positions(row, oldpos, newpos, + me->sumcols); + break; + } + } + return ninserts; +} + +PUBLIC int Stbl_getStartLine ARGS1( + STable_info *, me) +{ + if (!me) + return -1; + else + return me->startline; +} diff --git a/src/TRSTable.h b/src/TRSTable.h new file mode 100644 index 00000000..7ef88b45 --- /dev/null +++ b/src/TRSTable.h @@ -0,0 +1,15 @@ +typedef struct _STable_info STable_info; +extern STable_info * Stbl_startTABLE PARAMS((short)); +extern int Stbl_finishTABLE PARAMS((STable_info *)); +extern void Stbl_free PARAMS((STable_info *)); +extern int Stbl_addRowToTable PARAMS((STable_info *, short, int)); +extern int Stbl_addCellToTable PARAMS((STable_info *, int, short, BOOL, int, int)); +extern int Stbl_finishCellInTable PARAMS((STable_info *, BOOL, int, int)); +#define Stbl_lineBreak(stbl,l,pos) Stbl_finishCellInTable(stbl, NO, l, pos) +extern int Stbl_getStartLine PARAMS((STable_info *)); +extern int Stbl_getFixupPositions PARAMS(( + STable_info * me, + int lineno, + int * oldpos, + int * newpos)); +extern short Stbl_getAlignment PARAMS((STable_info *)); diff --git a/src/UCAuto.c b/src/UCAuto.c index 70c8972a..87bbd3c7 100644 --- a/src/UCAuto.c +++ b/src/UCAuto.c @@ -1,7 +1,7 @@ /* ** This file contains code for changing the Linux console mode. ** Currently some names for font files are hardwired in here. -** You have to change this code if it needs accomodation for your +** You have to change this code if it needs accommodation for your ** system (or get the required files...). ** ** Depending on the Display Character Set switched to, and the previous @@ -168,7 +168,7 @@ PUBLIC void UCChangeTerminalCodepage ARGS2( SETFONT, old_font, NOOUTPUT); } CTRACE((tfp, "Executing setfont to restore: '%s'\n", tmpbuf1)); - LYSystem(tmpbuf1); + status = LYSystem(tmpbuf1); FREE(tmpbuf1); } } @@ -181,6 +181,10 @@ PUBLIC void UCChangeTerminalCodepage ARGS2( LYRemoveTemp(old_umap); FREE(old_umap); } + if (status == 0) { + FREE(T_font_fn); + FREE(T_umap_fn); + } } return; } else if (lastcs < 0 && old_umap == 0 && old_font == 0) { @@ -370,6 +374,14 @@ PUBLIC void UCChangeTerminalCodepage ARGS2( name = "unknown-8bit"; } + if (status == 1) + HasUmap = Is_Unset; + else if (status < 0) { + if (HasUmap == Is_Set) + HasUmap = Dunno; + name = "unknown-8bit"; + } + if (TransT != lastTransT) { if (TransT == GN_Blat1) { /* diff --git a/src/UCAux.c b/src/UCAux.c index eaab7522..d4701484 100644 --- a/src/UCAux.c +++ b/src/UCAux.c @@ -151,7 +151,7 @@ PUBLIC BOOL UCNeedNotTranslate ARGS2( ** up to the caller to do something about them. - KW */ PUBLIC void UCSetTransParams ARGS5( - UCTransParams *, pT, + UCTransParams *, pT, int, cs_in, CONST LYUCcharset*, p_in, int, cs_out, @@ -452,3 +452,65 @@ PUBLIC BOOL UCConvertUniToUtf8 ARGS2( } return YES; } + +/* +** Get UCS character code for one character from UTF-8 encoded string. +** +** On entry: +** *ppuni should point to beginning of UTF-8 encoding character +** On exit: +** *ppuni is advanced to point to the last byte of UTF-8 sequence, +** if there was a valid one; otherwise unchanged. +** returns the UCS value +** returns negative value on error (invalid UTF-8 sequence) +*/ +PUBLIC UCode_t UCGetUniFromUtf8String ARGS1(char **, ppuni) +{ + UCode_t uc_out = 0; + char * p = *ppuni; + int utf_count, i; + if (!(**ppuni&0x80)) + return (UCode_t) **ppuni; /* ASCII range character */ + else if (!(**ppuni&0x40)) + return (-1); /* not a valid UTF-8 start */ + if ((*p & 0xe0) == 0xc0) { + utf_count = 1; + } else if ((*p & 0xf0) == 0xe0) { + utf_count = 2; + } else if ((*p & 0xf8) == 0xf0) { + utf_count = 3; + } else if ((*p & 0xfc) == 0xf8) { + utf_count = 4; + } else if ((*p & 0xfe) == 0xfc) { + utf_count = 5; + } else { /* garbage */ + return (-1); + } + for (p = *ppuni, i = 0; i < utf_count ; i++) { + if ((*(++p) & 0xc0) != 0x80) + return (-1); + } + p = *ppuni; + switch (utf_count) { + case 1: + uc_out = (((*p&0x1f) << 6) | (*(p+1)&0x3f)); + break; + case 2: + uc_out = (((((*p&0x0f) << 6) | (*(p+1)&0x3f)) << 6) | (*(p+2)&0x3f)); + break; + case 3: + uc_out = (((((((*p&0x07) << 6) | (*(p+1)&0x3f)) << 6) | (*(p+2)&0x3f)) << 6) + | (*(p+3)&0x3f)); + break; + case 4: + uc_out = (((((((((*p&0x03) << 6) | (*(p+1)&0x3f)) << 6) | (*(p+2)&0x3f)) << 6) + | (*(p+3)&0x3f)) << 6) | (*(p+4)&0x3f)); + break; + case 5: + uc_out = (((((((((((*p&0x01) << 6) | (*(p+1)&0x3f)) << 6) | (*(p+2)&0x3f)) << 6) + | (*(p+3)&0x3f)) << 6) | (*(p+4)&0x3f)) << 6) | (*(p+5)&0x3f)); + break; + } + *ppuni = p + utf_count; + return uc_out; +} diff --git a/src/chrtrans/cp1250_uni.tbl b/src/chrtrans/cp1250_uni.tbl index 207add88..64ad83c4 100644 --- a/src/chrtrans/cp1250_uni.tbl +++ b/src/chrtrans/cp1250_uni.tbl @@ -26,6 +26,8 @@ C1250 # The entries are in cp1250 order # ################## +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw 0x20-0x7e idem # @@ -39,11 +41,11 @@ C1250 0x87 U+2021 #DOUBLE DAGGER 0x88 #UNDEFINED 0x89 U+2030 #PER MILLE SIGN -0x8A U+0160 #LATIN CAPITAL LETTER S WITH CARON +0x8A U+0160 U+0428 #LATIN CAPITAL LETTER S WITH CARON 0x8B U+2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK 0x8C U+015A #LATIN CAPITAL LETTER S WITH ACUTE 0x8D U+0164 #LATIN CAPITAL LETTER T WITH CARON -0x8E U+017D #LATIN CAPITAL LETTER Z WITH CARON +0x8E U+017D U+0416 #LATIN CAPITAL LETTER Z WITH CARON 0x8F U+0179 #LATIN CAPITAL LETTER Z WITH ACUTE 0x90 #UNDEFINED 0x91 U+2018 #LEFT SINGLE QUOTATION MARK @@ -55,21 +57,21 @@ C1250 0x97 U+2014 #EM DASH 0x98 #UNDEFINED 0x99 U+2122 #TRADE MARK SIGN -0x9A U+0161 #LATIN SMALL LETTER S WITH CARON +0x9A U+0161 U+0448 #LATIN SMALL LETTER S WITH CARON 0x9B U+203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK 0x9C U+015B #LATIN SMALL LETTER S WITH ACUTE 0x9D U+0165 #LATIN SMALL LETTER T WITH CARON -0x9E U+017E #LATIN SMALL LETTER Z WITH CARON +0x9E U+017E U+0436 #LATIN SMALL LETTER Z WITH CARON 0x9F U+017A #LATIN SMALL LETTER Z WITH ACUTE 0xA0 U+00A0 #NO-BREAK SPACE -0xA1 U+02C7 #CARON -0xA2 U+02D8 #BREVE +0xA1 U+02C7 U+030c #CARON +0xA2 U+02D8 U+0306 #BREVE 0xA3 U+0141 #LATIN CAPITAL LETTER L WITH STROKE 0xA4 U+00A4 #CURRENCY SIGN 0xA5 U+0104 #LATIN CAPITAL LETTER A WITH OGONEK 0xA6 U+00A6 #BROKEN BAR 0xA7 U+00A7 #SECTION SIGN -0xA8 U+00A8 #DIAERESIS +0xA8 U+00A8 U+0308 #DIAERESIS 0xA9 U+00A9 #COPYRIGHT SIGN 0xAA U+015E #LATIN CAPITAL LETTER S WITH CEDILLA 0xAB U+00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK @@ -77,20 +79,20 @@ C1250 0xAD U+00AD #SOFT HYPHEN 0xAE U+00AE #REGISTERED SIGN 0xAF U+017B #LATIN CAPITAL LETTER Z WITH DOT ABOVE -0xB0 U+00B0 #DEGREE SIGN +0xB0 U+00B0 U+030a #DEGREE SIGN 0xB1 U+00B1 #PLUS-MINUS SIGN -0xB2 U+02DB #OGONEK +0xB2 U+02DB U+0328 #OGONEK 0xB3 U+0142 #LATIN SMALL LETTER L WITH STROKE 0xB4 U+00B4 #ACUTE ACCENT -0xB5 U+00B5 #MICRO SIGN +0xB5 U+00B5 U+03bc #MICRO SIGN 0xB6 U+00B6 #PILCROW SIGN 0xB7 U+00B7 #MIDDLE DOT -0xB8 U+00B8 #CEDILLA +0xB8 U+00B8 U+0327 #CEDILLA 0xB9 U+0105 #LATIN SMALL LETTER A WITH OGONEK 0xBA U+015F #LATIN SMALL LETTER S WITH CEDILLA 0xBB U+00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 0xBC U+013D #LATIN CAPITAL LETTER L WITH CARON -0xBD U+02DD #DOUBLE ACUTE ACCENT +0xBD U+02DD U+030b #DOUBLE ACUTE ACCENT 0xBE U+013E #LATIN SMALL LETTER L WITH CARON 0xBF U+017C #LATIN SMALL LETTER Z WITH DOT ABOVE 0xC0 U+0154 #LATIN CAPITAL LETTER R WITH ACUTE @@ -101,7 +103,7 @@ C1250 0xC5 U+0139 #LATIN CAPITAL LETTER L WITH ACUTE 0xC6 U+0106 #LATIN CAPITAL LETTER C WITH ACUTE 0xC7 U+00C7 #LATIN CAPITAL LETTER C WITH CEDILLA -0xC8 U+010C #LATIN CAPITAL LETTER C WITH CARON +0xC8 U+010C U+0427 # LATIN CAPITAL LETTER C WITH CARON 0xC9 U+00C9 #LATIN CAPITAL LETTER E WITH ACUTE 0xCA U+0118 #LATIN CAPITAL LETTER E WITH OGONEK 0xCB U+00CB #LATIN CAPITAL LETTER E WITH DIAERESIS @@ -133,7 +135,7 @@ C1250 0xE5 U+013A #LATIN SMALL LETTER L WITH ACUTE 0xE6 U+0107 #LATIN SMALL LETTER C WITH ACUTE 0xE7 U+00E7 #LATIN SMALL LETTER C WITH CEDILLA -0xE8 U+010D #LATIN SMALL LETTER C WITH CARON +0xE8 U+010D U+02a7 U+0447 # LATIN SMALL LETTER C WITH CARON 0xE9 U+00E9 #LATIN SMALL LETTER E WITH ACUTE 0xEA U+0119 #LATIN SMALL LETTER E WITH OGONEK 0xEB U+00EB #LATIN SMALL LETTER E WITH DIAERESIS @@ -156,4 +158,13 @@ C1250 0xFC U+00FC #LATIN SMALL LETTER U WITH DIAERESIS 0xFD U+00FD #LATIN SMALL LETTER Y WITH ACUTE 0xFE U+0163 #LATIN SMALL LETTER T WITH CEDILLA -0xFF U+02D9 #DOT ABOVE +0xFF U+02D9 U+0307 U+0387 #DOT ABOVE + +U+2218 " \260 " # RING OPERATOR +U+2219 " \225 " # BULLET OPERATOR +U+2297 "(\327)" # CIRCLED TIMES +U+2299 "(\267)" # CIRCLED DOT OPERATOR +U+229A "(\260)" # CIRCLED RING OPERATOR +U+22A0 "[\327]" # SQUARED TIMES +U+22A1 "[\267]" # SQUARED DOT OPERATOR +U+22C5 " \267 " # DOT OPERATOR diff --git a/src/chrtrans/cp1252_uni.tbl b/src/chrtrans/cp1252_uni.tbl index 7a9e149f..2365c9c5 100644 --- a/src/chrtrans/cp1252_uni.tbl +++ b/src/chrtrans/cp1252_uni.tbl @@ -30,6 +30,8 @@ C1252 # The entries are in cp1252 order # ################## +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw 0x20-0x7e idem # @@ -41,7 +43,7 @@ C1252 0x85 U+2026 #HORIZONTAL ELLIPSIS 0x86 U+2020 #DAGGER 0x87 U+2021 #DOUBLE DAGGER -0x88 U+02C6 #MODIFIER LETTER CIRCUMFLEX ACCENT +0x88 U+02C6 U+0302 #MODIFIER LETTER CIRCUMFLEX ACCENT 0x89 U+2030 #PER MILLE SIGN 0x8A U+0160 #LATIN CAPITAL LETTER S WITH CARON 0x8B U+2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK @@ -53,7 +55,7 @@ C1252 0x91 U+2018 #LEFT SINGLE QUOTATION MARK 0x92 U+2019 #RIGHT SINGLE QUOTATION MARK 0x93 U+201C #LEFT DOUBLE QUOTATION MARK -0x94 U+201D #RIGHT DOUBLE QUOTATION MARK +0x94 U+201D U+02dd U+030b #RIGHT DOUBLE QUOTATION MARK 0x95 U+2022 #BULLET 0x96 U+2013 #EN DASH 0x97 U+2014 #EM DASH @@ -73,23 +75,23 @@ C1252 0xA5 U+00A5 #YEN SIGN 0xA6 U+00A6 #BROKEN BAR 0xA7 U+00A7 #SECTION SIGN -0xA8 U+00A8 #DIAERESIS +0xA8 U+00A8 U+0308 #DIAERESIS 0xA9 U+00A9 #COPYRIGHT SIGN 0xAA U+00AA #FEMININE ORDINAL INDICATOR 0xAB U+00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 0xAC U+00AC #NOT SIGN 0xAD U+00AD #SOFT HYPHEN 0xAE U+00AE #REGISTERED SIGN -0xAF U+00AF #MACRON -0xB0 U+00B0 #DEGREE SIGN +0xAF U+00AF U+0304 #MACRON +0xB0 U+00B0 U+030a #DEGREE SIGN 0xB1 U+00B1 #PLUS-MINUS SIGN 0xB2 U+00B2 #SUPERSCRIPT TWO 0xB3 U+00B3 #SUPERSCRIPT THREE 0xB4 U+00B4 #ACUTE ACCENT -0xB5 U+00B5 #MICRO SIGN +0xB5 U+00B5 U+03bc #MICRO SIGN 0xB6 U+00B6 #PILCROW SIGN -0xB7 U+00B7 #MIDDLE DOT -0xB8 U+00B8 #CEDILLA +0xB7 U+00B7 U+0307 U+0387 U+2027 #MIDDLE DOT +0xB8 U+00B8 U+0327 #CEDILLA 0xB9 U+00B9 #SUPERSCRIPT ONE 0xBA U+00BA #MASCULINE ORDINAL INDICATOR 0xBB U+00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK @@ -161,3 +163,13 @@ C1252 0xFD U+00FD #LATIN SMALL LETTER Y WITH ACUTE 0xFE U+00FE #LATIN SMALL LETTER THORN 0xFF U+00FF #LATIN SMALL LETTER Y WITH DIAERESIS + +U+2218 " \260 " # RING OPERATOR +U+2219 " \225 " # BULLET OPERATOR +U+221b " ROOT\263 " +U+2297 "(\327)" # CIRCLED TIMES +U+2299 "(\267)" # CIRCLED DOT OPERATOR +U+229A "(\260)" # CIRCLED RING OPERATOR +U+22A0 "[\327]" # SQUARED TIMES +U+22A1 "[\267]" # SQUARED DOT OPERATOR +U+22C5 " \267 " # DOT OPERATOR diff --git a/src/chrtrans/cp437_uni.tbl b/src/chrtrans/cp437_uni.tbl index 818cbab3..95755693 100644 --- a/src/chrtrans/cp437_uni.tbl +++ b/src/chrtrans/cp437_uni.tbl @@ -28,8 +28,8 @@ C437 # # The entries are in cp437_DosLatinUS order # -# some mapppings of greek letters to latin letters added, -# just for fun.. - KW +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw # ####################################### @@ -51,7 +51,7 @@ C437 0x8d U+00ec #LATIN SMALL LETTER I WITH GRAVE 0x8e U+00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS 0x8f U+00c5 #LATIN CAPITAL LETTER A WITH RING ABOVE -0x90 U+00c9 #LATIN CAPITAL LETTER E WITH ACUTE +0x90 U+00c9 U+0388 #LATIN CAPITAL LETTER E WITH ACUTE 0x91 U+00e6 #LATIN SMALL LIGATURE AE 0x92 U+00c6 #LATIN CAPITAL LIGATURE AE 0x93 U+00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX @@ -61,7 +61,7 @@ C437 0x97 U+00f9 #LATIN SMALL LETTER U WITH GRAVE 0x98 U+00ff #LATIN SMALL LETTER Y WITH DIAERESIS 0x99 U+00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS -0x9a U+00dc #LATIN CAPITAL LETTER U WITH DIAERESIS +0x9a U+00dc U+03ab #LATIN CAPITAL LETTER U WITH DIAERESIS 0x9b U+00a2 #CENT SIGN 0x9c U+00a3 #POUND SIGN 0x9d U+00a5 #YEN SIGN @@ -135,40 +135,45 @@ C437 0xe1 U+00df U+03b2 #LATIN SMALL LETTER SHARP S 0xe2 U+0393 #GREEK CAPITAL LETTER GAMMA 0xe3 U+03c0 #GREEK SMALL LETTER PI -0xe4 U+03a3 #GREEK CAPITAL LETTER SIGMA +0xe4 U+03a3 U+2211 #GREEK CAPITAL LETTER SIGMA 0xe5 U+03c3 #GREEK SMALL LETTER SIGMA 0xe6 U+00b5 U+03bc #MICRO SIGN 0xe7 U+03c4 #GREEK SMALL LETTER TAU 0xe8 U+03a6 #GREEK CAPITAL LETTER PHI 0xe9 U+0398 U+03b8 #GREEK CAPITAL LETTER THETA -0xea U+03a9 #GREEK CAPITAL LETTER OMEGA +0xea U+03a9 U+2126 #GREEK CAPITAL LETTER OMEGA 0xeb U+03b4 #GREEK SMALL LETTER DELTA 0xec U+221e #INFINITY -0xed U+03c6 #GREEK SMALL LETTER PHI -0xee U+03b5 #GREEK SMALL LETTER EPSILON +0xed U+03c6 U+00f8 #GREEK SMALL LETTER PHI +0xee U+03b5 U+2208 U+220a #GREEK SMALL LETTER EPSILON 0xef U+2229 #INTERSECTION 0xf0 U+2261 #IDENTICAL TO 0xf1 U+00b1 #PLUS-MINUS SIGN -0xf2 U+2265 #GREATER-THAN OR EQUAL TO -0xf3 U+2264 #LESS-THAN OR EQUAL TO -0xf4 U+2320 #TOP HALF INTEGRAL +0xf2 U+2265 U+2267 #GREATER-THAN OR EQUAL TO +0xf3 U+2264 U+2266 #LESS-THAN OR EQUAL TO +0xf4 U+2320 U+0283 #TOP HALF INTEGRAL 0xf5 U+2321 #BOTTOM HALF INTEGRAL 0xf6 U+00f7 #DIVISION SIGN 0xf7 U+2248 #ALMOST EQUAL TO -0xf8 U+00b0 #DEGREE SIGN -0xf9 U+2219 #BULLET OPERATOR -0xfa U+00b7 #MIDDLE DOT +0xf8 U+00b0 U+030a #DEGREE SIGN +0xf9 U+2219 U+0307 U+0387 #BULLET OPERATOR +0xfa U+00b7 U+2027 #MIDDLE DOT 0xfb U+221a #SQUARE ROOT 0xfc U+207f #SUPERSCRIPT LATIN SMALL LETTER N 0xfd U+00b2 #SUPERSCRIPT TWO 0xfe U+25a0 #BLACK SQUARE 0xff U+00a0 #NO-BREAK SPACE -U+03ac:a' U+03ad "\356'" #:î' U+03ae:h' -U+03af:i' -U+03cc:o' U+03cd:u' U+03ce:w' +U+2209 " !\356 " +U+221b " 3\373" +U+221c " 4\373" +U+2262 " !\360" +U+2299 "(\372)" +U+229a "(\370)" +U+22a1 "[\372]" +U+02a7 "t\364" diff --git a/src/chrtrans/cp737_uni.tbl b/src/chrtrans/cp737_uni.tbl index 6beee2c4..710bd288 100644 --- a/src/chrtrans/cp737_uni.tbl +++ b/src/chrtrans/cp737_uni.tbl @@ -25,6 +25,8 @@ C737 # The entries are in cp737_DOSGreek order # ################## +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw 0x20-0x7f idem # @@ -54,16 +56,16 @@ C737 0x97 U+03a9 #GREEK CAPITAL LETTER OMEGA 0x98 U+03b1 #GREEK SMALL LETTER ALPHA 0x99 U+03b2 #GREEK SMALL LETTER BETA -0x9a U+03b3 #GREEK SMALL LETTER GAMMA +0x9a U+03b3 U+0263 #GREEK SMALL LETTER GAMMA 0x9b U+03b4 #GREEK SMALL LETTER DELTA 0x9c U+03b5 #GREEK SMALL LETTER EPSILON 0x9d U+03b6 #GREEK SMALL LETTER ZETA 0x9e U+03b7 #GREEK SMALL LETTER ETA 0x9f U+03b8 #GREEK SMALL LETTER THETA -0xa0 U+03b9 #GREEK SMALL LETTER IOTA +0xa0 U+03b9 U+0131 #GREEK SMALL LETTER IOTA 0xa1 U+03ba #GREEK SMALL LETTER KAPPA 0xa2 U+03bb #GREEK SMALL LETTER LAMDA -0xa3 U+03bc #GREEK SMALL LETTER MU +0xa3 U+03bc U+00b5 #GREEK SMALL LETTER MU 0xa4 U+03bd #GREEK SMALL LETTER NU 0xa5 U+03be #GREEK SMALL LETTER XI 0xa6 U+03bf #GREEK SMALL LETTER OMICRON @@ -72,7 +74,7 @@ C737 0xa9 U+03c3 #GREEK SMALL LETTER SIGMA 0xaa U+03c2 #GREEK SMALL LETTER FINAL SIGMA 0xab U+03c4 #GREEK SMALL LETTER TAU -0xac U+03c5 #GREEK SMALL LETTER UPSILON +0xac U+03c5 U+028a #GREEK SMALL LETTER UPSILON 0xad U+03c6 #GREEK SMALL LETTER PHI 0xae U+03c7 #GREEK SMALL LETTER CHI 0xaf U+03c8 #GREEK SMALL LETTER PSI @@ -132,7 +134,7 @@ C737 0xe5 U+03af #GREEK SMALL LETTER IOTA WITH TONOS 0xe6 U+03cc #GREEK SMALL LETTER OMICRON WITH TONOS 0xe7 U+03cd #GREEK SMALL LETTER UPSILON WITH TONOS -0xe8 U+03cb #GREEK SMALL LETTER UPSILON WITH DIALYTIKA +0xe8 U+03cb U+00fc #GREEK SMALL LETTER UPSILON WITH DIALYTIKA 0xe9 U+03ce #GREEK SMALL LETTER OMEGA WITH TONOS 0xea U+0386 #GREEK CAPITAL LETTER ALPHA WITH TONOS 0xeb U+0388 #GREEK CAPITAL LETTER EPSILON WITH TONOS @@ -149,10 +151,20 @@ C737 0xf6 U+00f7 #DIVISION SIGN 0xf7 U+2248 #ALMOST EQUAL TO 0xf8 U+00b0 #DEGREE SIGN -0xf9 U+2219 #BULLET OPERATOR +0xf9 U+2219 U+0307 U+0387 #BULLET OPERATOR 0xfa U+00b7 #MIDDLE DOT 0xfb U+221a #SQUARE ROOT 0xfc U+207f #SUPERSCRIPT LATIN SMALL LETTER N 0xfd U+00b2 #SUPERSCRIPT TWO 0xfe U+25a0 #BLACK SQUARE 0xff U+00a0 #NO-BREAK SPACE + +U+2209 " !\234 " +U+2218 " \370 " # RING OPERATOR +U+221b " 3\373" +U+221c " 4\373" +U+2299 "(\372)" +U+229a "(\370)" +U+22a1 "[\372]" +U+02a4 "d\235" +U+2249 "!\367" diff --git a/src/chrtrans/cp850_uni.tbl b/src/chrtrans/cp850_uni.tbl index bc44cde8..91fe44ee 100644 --- a/src/chrtrans/cp850_uni.tbl +++ b/src/chrtrans/cp850_uni.tbl @@ -31,12 +31,14 @@ C850 # The entries are in cp850_DOSLatin1 order # ################## +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw 0x20-0x7e idem # 0x80 U+00c7 #LATIN CAPITAL LETTER C WITH CEDILLA -0x81 U+00fc #LATIN SMALL LETTER U WITH DIAERESIS -0x82 U+00e9 #LATIN SMALL LETTER E WITH ACUTE +0x81 U+00fc U+03cb #LATIN SMALL LETTER U WITH DIAERESIS +0x82 U+00e9 U+03ad #LATIN SMALL LETTER E WITH ACUTE 0x83 U+00e2 #LATIN SMALL LETTER A WITH CIRCUMFLEX 0x84 U+00e4 #LATIN SMALL LETTER A WITH DIAERESIS 0x85 U+00e0 #LATIN SMALL LETTER A WITH GRAVE @@ -45,12 +47,12 @@ C850 0x88 U+00ea #LATIN SMALL LETTER E WITH CIRCUMFLEX 0x89 U+00eb #LATIN SMALL LETTER E WITH DIAERESIS 0x8a U+00e8 #LATIN SMALL LETTER E WITH GRAVE -0x8b U+00ef #LATIN SMALL LETTER I WITH DIAERESIS +0x8b U+00ef U+03ca #LATIN SMALL LETTER I WITH DIAERESIS 0x8c U+00ee #LATIN SMALL LETTER I WITH CIRCUMFLEX 0x8d U+00ec #LATIN SMALL LETTER I WITH GRAVE 0x8e U+00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS 0x8f U+00c5 #LATIN CAPITAL LETTER A WITH RING ABOVE -0x90 U+00c9 #LATIN CAPITAL LETTER E WITH ACUTE +0x90 U+00c9 U+0388 #LATIN CAPITAL LETTER E WITH ACUTE 0x91 U+00e6 #LATIN SMALL LIGATURE AE 0x92 U+00c6 #LATIN CAPITAL LIGATURE AE 0x93 U+00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX @@ -60,16 +62,16 @@ C850 0x97 U+00f9 #LATIN SMALL LETTER U WITH GRAVE 0x98 U+00ff #LATIN SMALL LETTER Y WITH DIAERESIS 0x99 U+00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS -0x9a U+00dc #LATIN CAPITAL LETTER U WITH DIAERESIS +0x9a U+00dc U+03ab #LATIN CAPITAL LETTER U WITH DIAERESIS 0x9b U+00f8 #LATIN SMALL LETTER O WITH STROKE 0x9c U+00a3 #POUND SIGN 0x9d U+00d8 #LATIN CAPITAL LETTER O WITH STROKE 0x9e U+00d7 #MULTIPLICATION SIGN 0x9f U+0192 #LATIN SMALL LETTER F WITH HOOK -0xa0 U+00e1 #LATIN SMALL LETTER A WITH ACUTE -0xa1 U+00ed #LATIN SMALL LETTER I WITH ACUTE -0xa2 U+00f3 #LATIN SMALL LETTER O WITH ACUTE -0xa3 U+00fa #LATIN SMALL LETTER U WITH ACUTE +0xa0 U+00e1 U+03ac #LATIN SMALL LETTER A WITH ACUTE +0xa1 U+00ed U+03af #LATIN SMALL LETTER I WITH ACUTE +0xa2 U+00f3 U+03cc #LATIN SMALL LETTER O WITH ACUTE +0xa3 U+00fa U+03cd #LATIN SMALL LETTER U WITH ACUTE 0xa4 U+00f1 #LATIN SMALL LETTER N WITH TILDE 0xa5 U+00d1 #LATIN CAPITAL LETTER N WITH TILDE 0xa6 U+00aa #FEMININE ORDINAL INDICATOR @@ -87,7 +89,7 @@ C850 0xb2 U+2593 #DARK SHADE 0xb3 U+2502 #BOX DRAWINGS LIGHT VERTICAL 0xb4 U+2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT -0xb5 U+00c1 #LATIN CAPITAL LETTER A WITH ACUTE +0xb5 U+00c1 U+0386 #LATIN CAPITAL LETTER A WITH ACUTE 0xb6 U+00c2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX 0xb7 U+00c0 #LATIN CAPITAL LETTER A WITH GRAVE 0xb8 U+00a9 #COPYRIGHT SIGN @@ -119,10 +121,10 @@ C850 0xd2 U+00ca #LATIN CAPITAL LETTER E WITH CIRCUMFLEX 0xd3 U+00cb #LATIN CAPITAL LETTER E WITH DIAERESIS 0xd4 U+00c8 #LATIN CAPITAL LETTER E WITH GRAVE -0xd5 U+0131 #LATIN SMALL LETTER DOTLESS I -0xd6 U+00cd #LATIN CAPITAL LETTER I WITH ACUTE +0xd5 U+0131 U+03b9 #LATIN SMALL LETTER DOTLESS I +0xd6 U+00cd U+038a #LATIN CAPITAL LETTER I WITH ACUTE 0xd7 U+00ce #LATIN CAPITAL LETTER I WITH CIRCUMFLEX -0xd8 U+00cf #LATIN CAPITAL LETTER I WITH DIAERESIS +0xd8 U+00cf U+03aa #LATIN CAPITAL LETTER I WITH DIAERESIS 0xd9 U+2518 #BOX DRAWINGS LIGHT UP AND LEFT 0xda U+250c #BOX DRAWINGS LIGHT DOWN AND RIGHT 0xdb U+2588 #FULL BLOCK @@ -130,13 +132,13 @@ C850 0xdd U+00a6 #BROKEN BAR 0xde U+00cc #LATIN CAPITAL LETTER I WITH GRAVE 0xdf U+2580 #UPPER HALF BLOCK -0xe0 U+00d3 #LATIN CAPITAL LETTER O WITH ACUTE +0xe0 U+00d3 U+038c #LATIN CAPITAL LETTER O WITH ACUTE 0xe1 U+00df #LATIN SMALL LETTER SHARP S 0xe2 U+00d4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX 0xe3 U+00d2 #LATIN CAPITAL LETTER O WITH GRAVE 0xe4 U+00f5 #LATIN SMALL LETTER O WITH TILDE 0xe5 U+00d5 #LATIN CAPITAL LETTER O WITH TILDE -0xe6 U+00b5 #MICRO SIGN +0xe6 U+00b5 U+03bc #MICRO SIGN 0xe7 U+00fe #LATIN SMALL LETTER THORN 0xe8 U+00de #LATIN CAPITAL LETTER THORN 0xe9 U+00da #LATIN CAPITAL LETTER U WITH ACUTE @@ -144,22 +146,30 @@ C850 0xeb U+00d9 #LATIN CAPITAL LETTER U WITH GRAVE 0xec U+00fd #LATIN SMALL LETTER Y WITH ACUTE 0xed U+00dd #LATIN CAPITAL LETTER Y WITH ACUTE -0xee U+00af #MACRON -0xef U+00b4 #ACUTE ACCENT +0xee U+00af U+0304 #MACRON +0xef U+00b4 U+0301 #ACUTE ACCENT 0xf0 U+00ad #SOFT HYPHEN 0xf1 U+00b1 #PLUS-MINUS SIGN -0xf2 U+2017 #DOUBLE LOW LINE +0xf2 U+2017 U+0333 #DOUBLE LOW LINE 0xf3 U+00be #VULGAR FRACTION THREE QUARTERS 0xf4 U+00b6 #PILCROW SIGN 0xf5 U+00a7 #SECTION SIGN 0xf6 U+00f7 #DIVISION SIGN -0xf7 U+00b8 #CEDILLA -0xf8 U+00b0 #DEGREE SIGN -0xf9 U+00a8 #DIAERESIS -0xfa U+00b7 #MIDDLE DOT +0xf7 U+00b8 U+0327 #CEDILLA +0xf8 U+00b0 U+030a #DEGREE SIGN +0xf9 U+00a8 U+0308 #DIAERESIS +0xfa U+00b7 U+0307 U+0387 U+2027 #MIDDLE DOT 0xfb U+00b9 #SUPERSCRIPT ONE 0xfc U+00b3 #SUPERSCRIPT THREE 0xfd U+00b2 #SUPERSCRIPT TWO 0xfe U+25a0 #BLACK SQUARE 0xff U+00a0 #NO-BREAK SPACE +U+2218 " \370 " # RING OPERATOR +U+221b " ROOT\374 " +U+2297 "(\236)" # CIRCLED TIMES +U+2299 "(\372)" # CIRCLED DOT OPERATOR +U+229A "(\370)" # CIRCLED RING OPERATOR +U+22A0 "[\236]" # SQUARED TIMES +U+22A1 "[\372]" # SQUARED DOT OPERATOR +U+22C5 " \372 " # DOT OPERATOR diff --git a/src/chrtrans/cp852_uni.tbl b/src/chrtrans/cp852_uni.tbl index fec2ecf4..c4ac349b 100644 --- a/src/chrtrans/cp852_uni.tbl +++ b/src/chrtrans/cp852_uni.tbl @@ -25,12 +25,14 @@ C852 # The entries are in cp852_DOSLatin2 order # ################## +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw 0x20-0x7e idem # 0x80 U+00c7 #LATIN CAPITAL LETTER C WITH CEDILLA -0x81 U+00fc #LATIN SMALL LETTER U WITH DIAERESIS -0x82 U+00e9 #LATIN SMALL LETTER E WITH ACUTE +0x81 U+00fc U+03cb #LATIN SMALL LETTER U WITH DIAERESIS +0x82 U+00e9 U+03ad #LATIN SMALL LETTER E WITH ACUTE 0x83 U+00e2 #LATIN SMALL LETTER A WITH CIRCUMFLEX 0x84 U+00e4 #LATIN SMALL LETTER A WITH DIAERESIS 0x85 U+016f #LATIN SMALL LETTER U WITH RING ABOVE @@ -44,7 +46,7 @@ C852 0x8d U+0179 #LATIN CAPITAL LETTER Z WITH ACUTE 0x8e U+00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS 0x8f U+0106 #LATIN CAPITAL LETTER C WITH ACUTE -0x90 U+00c9 #LATIN CAPITAL LETTER E WITH ACUTE +0x90 U+00c9 U+0388 #LATIN CAPITAL LETTER E WITH ACUTE 0x91 U+0139 #LATIN CAPITAL LETTER L WITH ACUTE 0x92 U+013a #LATIN SMALL LETTER L WITH ACUTE 0x93 U+00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX @@ -54,25 +56,25 @@ C852 0x97 U+015a #LATIN CAPITAL LETTER S WITH ACUTE 0x98 U+015b #LATIN SMALL LETTER S WITH ACUTE 0x99 U+00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS -0x9a U+00dc #LATIN CAPITAL LETTER U WITH DIAERESIS +0x9a U+00dc U+03ab #LATIN CAPITAL LETTER U WITH DIAERESIS 0x9b U+0164 #LATIN CAPITAL LETTER T WITH CARON 0x9c U+0165 #LATIN SMALL LETTER T WITH CARON 0x9d U+0141 #LATIN CAPITAL LETTER L WITH STROKE 0x9e U+00d7 #MULTIPLICATION SIGN -0x9f U+010d #LATIN SMALL LETTER C WITH CARON -0xa0 U+00e1 #LATIN SMALL LETTER A WITH ACUTE -0xa1 U+00ed #LATIN SMALL LETTER I WITH ACUTE -0xa2 U+00f3 #LATIN SMALL LETTER O WITH ACUTE -0xa3 U+00fa #LATIN SMALL LETTER U WITH ACUTE +0x9f U+010d U+02a7 U+0447 #LATIN SMALL LETTER C WITH CARON +0xa0 U+00e1 U+03ac #LATIN SMALL LETTER A WITH ACUTE +0xa1 U+00ed U+03af #LATIN SMALL LETTER I WITH ACUTE +0xa2 U+00f3 U+03cc #LATIN SMALL LETTER O WITH ACUTE +0xa3 U+00fa U+03cd #LATIN SMALL LETTER U WITH ACUTE 0xa4 U+0104 #LATIN CAPITAL LETTER A WITH OGONEK 0xa5 U+0105 #LATIN SMALL LETTER A WITH OGONEK -0xa6 U+017d #LATIN CAPITAL LETTER Z WITH CARON -0xa7 U+017e #LATIN SMALL LETTER Z WITH CARON +0xa6 U+017d U+0416 #LATIN CAPITAL LETTER Z WITH CARON +0xa7 U+017e U+0436 #LATIN SMALL LETTER Z WITH CARON 0xa8 U+0118 #LATIN CAPITAL LETTER E WITH OGONEK 0xa9 U+0119 #LATIN SMALL LETTER E WITH OGONEK 0xaa U+00ac #NOT SIGN 0xab U+017a #LATIN SMALL LETTER Z WITH ACUTE -0xac U+010c #LATIN CAPITAL LETTER C WITH CARON +0xac U+010c U+0427 #LATIN CAPITAL LETTER C WITH CARON 0xad U+015f #LATIN SMALL LETTER S WITH CEDILLA 0xae U+00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 0xaf U+00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK @@ -81,7 +83,7 @@ C852 0xb2 U+2593 #DARK SHADE 0xb3 U+2502 #BOX DRAWINGS LIGHT VERTICAL 0xb4 U+2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT -0xb5 U+00c1 #LATIN CAPITAL LETTER A WITH ACUTE +0xb5 U+00c1 U+0386 #LATIN CAPITAL LETTER A WITH ACUTE 0xb6 U+00c2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX 0xb7 U+011a #LATIN CAPITAL LETTER E WITH CARON 0xb8 U+015e #LATIN CAPITAL LETTER S WITH CEDILLA @@ -114,7 +116,7 @@ C852 0xd3 U+00cb #LATIN CAPITAL LETTER E WITH DIAERESIS 0xd4 U+010f #LATIN SMALL LETTER D WITH CARON 0xd5 U+0147 #LATIN CAPITAL LETTER N WITH CARON -0xd6 U+00cd #LATIN CAPITAL LETTER I WITH ACUTE +0xd6 U+00cd U+038a #LATIN CAPITAL LETTER I WITH ACUTE 0xd7 U+00ce #LATIN CAPITAL LETTER I WITH CIRCUMFLEX 0xd8 U+011b #LATIN SMALL LETTER E WITH CARON 0xd9 U+2518 #BOX DRAWINGS LIGHT UP AND LEFT @@ -124,14 +126,14 @@ C852 0xdd U+0162 #LATIN CAPITAL LETTER T WITH CEDILLA 0xde U+016e #LATIN CAPITAL LETTER U WITH RING ABOVE 0xdf U+2580 #UPPER HALF BLOCK -0xe0 U+00d3 #LATIN CAPITAL LETTER O WITH ACUTE +0xe0 U+00d3 U+038c #LATIN CAPITAL LETTER O WITH ACUTE 0xe1 U+00df #LATIN SMALL LETTER SHARP S 0xe2 U+00d4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX 0xe3 U+0143 #LATIN CAPITAL LETTER N WITH ACUTE 0xe4 U+0144 #LATIN SMALL LETTER N WITH ACUTE 0xe5 U+0148 #LATIN SMALL LETTER N WITH CARON -0xe6 U+0160 #LATIN CAPITAL LETTER S WITH CARON -0xe7 U+0161 #LATIN SMALL LETTER S WITH CARON +0xe6 U+0160 U+0428 #LATIN CAPITAL LETTER S WITH CARON +0xe7 U+0161 U+0448 #LATIN SMALL LETTER S WITH CARON 0xe8 U+0154 #LATIN CAPITAL LETTER R WITH ACUTE 0xe9 U+00da #LATIN CAPITAL LETTER U WITH ACUTE 0xea U+0155 #LATIN SMALL LETTER R WITH ACUTE @@ -139,21 +141,28 @@ C852 0xec U+00fd #LATIN SMALL LETTER Y WITH ACUTE 0xed U+00dd #LATIN CAPITAL LETTER Y WITH ACUTE 0xee U+0163 #LATIN SMALL LETTER T WITH CEDILLA -0xef U+00b4 #ACUTE ACCENT +0xef U+00b4 U+0301 #ACUTE ACCENT 0xf0 U+00ad #SOFT HYPHEN -0xf1 U+02dd #DOUBLE ACUTE ACCENT -0xf2 U+02db #OGONEK -0xf3 U+02c7 #CARON -0xf4 U+02d8 #BREVE +0xf1 U+02dd U+030b #DOUBLE ACUTE ACCENT +0xf2 U+02db U+0328 #OGONEK +0xf3 U+02c7 U+030c #CARON +0xf4 U+02d8 U+0306 #BREVE 0xf5 U+00a7 #SECTION SIGN 0xf6 U+00f7 #DIVISION SIGN -0xf7 U+00b8 #CEDILLA -0xf8 U+00b0 #DEGREE SIGN -0xf9 U+00a8 #DIAERESIS -0xfa U+02d9 #DOT ABOVE +0xf7 U+00b8 U+0327 #CEDILLA +0xf8 U+00b0 U+030a #DEGREE SIGN +0xf9 U+00a8 U+0308 #DIAERESIS +0xfa U+02d9 U+0307 U+0387 #DOT ABOVE 0xfb U+0171 #LATIN SMALL LETTER U WITH DOUBLE ACUTE 0xfc U+0158 #LATIN CAPITAL LETTER R WITH CARON 0xfd U+0159 #LATIN SMALL LETTER R WITH CARON 0xfe U+25a0 #BLACK SQUARE 0xff U+00a0 #NO-BREAK SPACE +U+2218 " \370 " # RING OPERATOR +U+2297 "(\236)" # CIRCLED TIMES +U+2299 "(\372)" # CIRCLED DOT OPERATOR +U+229A "(\370)" # CIRCLED RING OPERATOR +U+22A0 "[\236]" # SQUARED TIMES +U+22A1 "[\372]" # SQUARED DOT OPERATOR +U+22C5 " \372 " # DOT OPERATOR diff --git a/src/chrtrans/def7_uni.tbl b/src/chrtrans/def7_uni.tbl index 39dc165d..ffc217fe 100644 --- a/src/chrtrans/def7_uni.tbl +++ b/src/chrtrans/def7_uni.tbl @@ -67,7 +67,7 @@ U+00bd: 1/2 U+00be: 3/4 U+00bf:? 0x41 U+00c0-U+00c3 -U+00c4:A: +U+00c4 "Ae" # Ä, not the best choice for some languages. U+00c5:AA U+00c6:AE U+00c7:C, @@ -76,17 +76,17 @@ U+00c7:C, U+00d0:D- 0x4e U+00d1 0x4f U+00d2-U+00d5 -U+00d6:O: +U+00d6 "Oe" # Ö, not the best choice for some languages. U+00d7: * U+00d8:O/ 0x55 U+00d9-U+00db -U+00dc:U: +U+00dc "Ue" # Ü, not the best choice for some languages. 0x59 U+00dd U+00de:TH U+00df:ss U+00e0:`a 0x61 U+00e1-U+00e3 -U+00e4:a: +U+00e4 "ae" # ä, not the best choice for some languages. U+00e5:aa U+00e6:ae U+00e7:c, @@ -96,11 +96,11 @@ U+00ec:`i U+00f0:d- 0x6e U+00f1 0x6f U+00f2-U+00f5 -U+00f6:o: +U+00f6 "oe" # ö, not the best choice for some languages. U+00f7:-: U+00f8:o/ 0x75 U+00f9-U+00fb -U+00fc:u: +U+00fc "ue" # ü, not the best choice for some languages. 0x79 U+00fd U+00fe:th 0x79 U+00ff @@ -165,7 +165,7 @@ U+0171:u" 0x77 U+0175 0x59 U+0176 U+0178 0x79 U+0177 -0x5a U+0179 U+017b U+017d +0x5a U+0179 U+017b U+017d U+021d 0x7a U+017a U+017c U+017e U+017f:s1 U+0187:C2 @@ -314,7 +314,7 @@ U+028d:w<vls> U+028e:l^ U+028f:I. U+0290:z. -U+0292:ed +U+0292:Z 0x3f U+0294 # LATIN SMALL LETTER GLOTTAL STOP -> ? U+0295:H<vcd> U+0296:l! @@ -326,6 +326,9 @@ U+029b:G` U+029e:k! 0x4c U+029F # LATIN LETTER SMALL CAPITAL L U+02a0:q` +U+02a4:d3 +U+02a6:ts +U+02a7:tS U+02b0:<h> U+02b1:<?> 0x3b U+02b2 U+0321 @@ -335,23 +338,50 @@ U+02bb:;S 0x60 U+02bc U+02c6:^ U+02c7:'< +U+02c8:| U+02c9:1- U+02cb:1! 0x3a U+02d0 +U+02d1 ":\\" +0x2b U+02d6 +0x2d U+02d7 U+02d8:'( U+02d9:'. U+02da:'0 U+02db:'; U+02dc:~ U+02dd:'" +U+02e5:_T +U+02e6:_H +U+02e7:_M +U+02e8:_L +U+02e9:_B +U+02ec:_v +U+02ee:'' +0x60 U+0300 +0x27 U+0301 +0x5e U+0302 0x7e U+0303 U+0334 +U+030b:'' +0x7c U+030d +U+030e:|| +U+030f:`` 0x2e U+0322 U+0323 U+0324:<?> U+0325:<o> +0x2c U+0326 U+0327 0x2d U+0329 0x5b U+032a U+032b:<w> U+0334:<H> +0x2f U+0337 U+0338 +U+0340:` +U+0341:' +U+0342:~ +U+0344:'% +U+0345:j3 +U+0347:= +U+0360:~~ U+0374:' U+0375:, U+037a:j3 @@ -359,12 +389,12 @@ U+037e:?% U+0384:'* U+0385:'% # Greek letters -U+0386:A% +U+0386:A' U+0387:.* -U+0388:E% +U+0388:E' U+0389:Y% -U+038a:I% -U+038c:O% +U+038a:I' +U+038c:O' U+038e:U% U+038f:W% U+0390:i3 @@ -391,13 +421,13 @@ U+03a5:U U+03a6:F U+03a7:X U+03a8:Q -U+03a9:W +U+03a9:W* U+03aa:J U+03ab:V* -U+03ac:a% -U+03ad:e% +U+03ac:a' +U+03ad:e' U+03ae:y% -U+03af:i% +U+03af:i' U+03b0:u3 U+03b1:a U+03b2:b @@ -426,7 +456,7 @@ U+03c8:q U+03c9:w U+03ca:j U+03cb:v* -U+03cc:o% +U+03cc:o' U+03cd:u% U+03ce:w% # Greek symbols @@ -435,6 +465,7 @@ U+03d1 "theta " U+03d2 "upsi " U+03d5 "phi " U+03d6 "pi " +U+03d7:k. U+03da:T3 U+03db:t3 U+03dc:M3 @@ -445,6 +476,7 @@ U+03e0:P3 U+03e1:p3 U+03f0 "kappa " U+03f1 "rho " +U+03f3:J U+03f4:'% U+03f5:j3 # Cyrillic capital letters @@ -555,7 +587,8 @@ U+0480:C3 U+0481:c3 U+0490:G3 U+0491:g3 - +U+04d4:AE +U+04d5:ae # These may make Yiddish slightly more readable, until we have # something better. @@ -1272,14 +1305,30 @@ U+1ef6:Y2 U+1ef7:y2 U+1ef8:Y? U+1ef9:y? -U+1f00:;' -U+1f01:,' -U+1f02:;! -U+1f03:,! -U+1f04:?; -U+1f05:?, -U+1f06:!: -U+1f07:?: +0x61 U+1f00 +U+1f01:ha +U+1f02:`a +U+1f03:h`a +U+1f04:a' +U+1f05:ha' +U+1f06:a~ +U+1f07:ha~ +0x41 U+1f08 +U+1f09:hA +U+1f0a:`A +U+1f0b:h`A +U+1f0c:A' +U+1f0d:hA' +U+1f0e:A~ +U+1f0f:hA~ +U+1f11:he +U+1f19:hE +U+1f31:hi +U+1f39:hI +U+1f41:ho +U+1f49:hO +U+1f51:hu +U+1f59:hU U+1fbf:,, U+1fc0:?* U+1fc1:?: @@ -1289,6 +1338,8 @@ U+1fcf:?, U+1fdd:;! U+1fde:;' U+1fdf:?; +U+1fe5:rh +U+1fec:Rh U+1fed:!: U+1fef:!* U+1ffe:;; @@ -1299,7 +1350,7 @@ U+2003 " " U+200e:(->) U+200f:(<-) U+200a: -0x2d U+2010 U+2013 U+2015 # hyphen-like +0x2d U+2010 U+2011 U+2013 U+2015 # hyphen-like U+2014 "--" U+2016:|| U+2017:=2 @@ -1309,8 +1360,12 @@ U+2017:=2 U+2020:/- U+2021:/= U+2022 " o " +0x2e U+2024 U+2025:.. U+2026:... +U+2027:. +U+2028 "\015" +U+2029 "\015\012" # Dont wanna see these: # POP DIRECTIONAL FORMATTING 202C @@ -1318,6 +1373,7 @@ U+202c: # LEFT-TO-RIGHT OVERRIDE 202D U+202d: +U+202f "" U+2030: 0/00 U+2032:' U+2033:'' @@ -1333,6 +1389,8 @@ U+203c:!! U+203e:'- 0x2d U+2043 # HYPHEN BULLET ? U+2044:/ +U+2048:?! +U+2049:!? # end of General punctuation. U+2070:^0 U+2074:^4 @@ -1370,22 +1428,31 @@ U+20a7:Pt U+20a9:W= # New euro currency sign glyph: U+20AC:EUR +U+2100:a/c +U+2101:a/s U+2103:oC U+2105:c/o +U+2106:c/u U+2109:oF +0x67 U+210a +0x68 U+210e +U+210f "\134hbar " U+2111:Im +U+2113:l U+2116:No. U+2117:PO U+2118:P U+211C:Re U+211e:Rx U+2120:(SM) +U+2121:TEL # TRADE MARK SIGN: U+2122:(TM) U+2126:Ohm 0x4b U+212A # Kelvin sign - K U+212b:Ang. U+212E:est. +0x6f U+2134 U+2135 "Aleph " U+2136 "Bet " U+2137 "Gimel " @@ -1402,6 +1469,7 @@ U+215b: 1/8 U+215c: 3/8 U+215d: 5/8 U+215e: 7/8 +U+215f: 1/ U+2160:I U+2161:II U+2162:III @@ -1459,25 +1527,34 @@ U+2200:FA U+2202:\partial U+2203:TE U+2205:{} -U+2206:decr. +U+2206:Delta U+2207:Nabla U+2208:(- U+2209:!(- +U+220a:(- U+220b:-) +U+220c:!-) +U+220d:-) +U+220e " qed" U+220f:\prod U+2211:\sum U+2212: - U+2213:-/+ U+2214:.+ +0x2f U+2215 +U+2216 " - " U+2217:* U+2218:Ob U+2219:sb U+221a " SQRT " +U+221b " ROOT3 " +U+221c " ROOT4 " U+221d:0( U+221e:infty U+221f:-L U+2220:-V U+2225:PP +U+2226 " !PP " U+2227:AND U+2228:OR U+2229:(U @@ -1495,30 +1572,69 @@ U+2243:?- U+2245:?= # ALMOST EQUAL TO: U+2248:~= +U+2249 " !~= " U+224c:=? U+2253:HI +U+2254::= +U+2255:=: U+2260:!= U+2261:=3 +U+2262 " !=3 " U+2264:=< U+2265:>= +U+2266:.LE. +U+2267:.GE. +U+2268:.LT.NOT.EQ. +U+2269:.GT.NOT.EQ. U+226a:<< U+226b:>> U+226e:!< U+226f:!> +U+2276 " <> " +U+2277 " >< " U+2282:(C U+2283:)C -U+2282:!(C +U+2284 " !(C " +U+2285 " !)C " U+2286:(_ U+2287:)_ -U+2295:(+) -U+2297:(x) -U+2299:0. -U+229a:02 +U+2295 "(+)" # CIRCLED PLUS +U+2296 "(-)" # CIRCLED MINUS +U+2297 "(x)" # CIRCLED TIMES +U+2298 "(/)" # CIRCLED DIVISION SLASH +U+2299 "(.)" # CIRCLED DOT OPERATOR +U+229A "(o)" # CIRCLED RING OPERATOR +U+229B "(*)" # CIRCLED ASTERISK OPERATOR +U+229C "(=)" # CIRCLED EQUALS +U+229D "(-)" # CIRCLED DASH +U+229E "[+]" # SQUARED PLUS +U+229F "[-]" # SQUARED MINUS +U+22A0 "[x]" # SQUARED TIMES +U+22A1 "[.]" # SQUARED DOT OPERATOR U+22a5:-T -U+22c5:.P +U+22A7 " MODELS " # MODELS +U+22A8 " TRUE " # TRUE +U+22A9 " FORCES " # FORCES +U+22AC " !PROVES " # DOES NOT PROVE +U+22AD " NOT TRUE " # NOT TRUE +U+22AE " !FORCES " # DOES NOT FORCE +U+22B2 " NORMAL SUBGROUP OF " +U+22B3 " CONTAINS AS NORMAL SUBGROUP " +U+22B4 " NORMAL SUBGROUP OF OR EQUAL TO " +U+22B5 " CONTAINS AS NORMAL SUBGROUP OR EQUAL TO " +U+22B8 " MULTIMAP " # MULTIMAP +U+22BA " INTERCALATE " # INTERCALATE +U+22BB " XOR " # XOR +U+22BC " NAND " # NAND +U+22C5 " DOT " # DOT OPERATOR +U+22d6:<. +U+22d7:>. +U+22d8:<<< +U+22d9:>>> U+22ee::3 U+22ef:.3 U+2302:Eh +U+2307:~~ U+2308:<7 U+2309:>7 U+230a:7< @@ -1529,7 +1645,10 @@ U+2315:TR U+2318:88 U+2320:Iu U+2321:Il +U+2322::( U+2323::) +U+2324:|^| +U+2327:[X] U+2329:</ U+232a:/> U+2423:Vs @@ -1716,16 +1835,16 @@ U+25a9:RX U+25aa:sB U+25ac:SR U+25ad:Or -U+25b2:UT +U+25b2:^ U+25b3:uT -U+25b6:PR +U+25b6:|> U+25b7:Tr -U+25ba:PR -U+25bc:Dt +U+25ba:|> +U+25bc:v U+25bd:dT -U+25c0:PL +U+25c0:<| U+25c1:Tl -U+25c4:PL +U+25c4:<| U+25c6:Db U+25c7:Dw U+25ca:LZ @@ -1745,6 +1864,9 @@ U+260e:TEL U+260f:tel U+261c:<-- U+261e:--> +U+2621 "CAUTION " +U+2627:XP +U+2639::-( U+263a::-) U+263b:(-: U+263c:SU @@ -1792,6 +1914,7 @@ U+3016:(I U+3017:)I U+301c:-? U+3020:=T:) +0x20 U+303f U+3041:A5 U+3042:a5 U+3043:I5 @@ -2163,6 +2286,11 @@ U+fefa:lh. U+fefb:la- U+fefc:la. +0x21-0x7e U+ff01-U+ff5e +0x2e U+ff61 +0x22 U+ff62 U+ff63 +0x2c U+ff64 + # Symbols for C0 and C1 control characters, in case they get through... U+0000:NUL U+0001:SH @@ -2207,6 +2335,7 @@ U+007f:DT #U+0083:NH #U+0084:IN #U+0085:NL +U+0085 "\012" #U+0086:SA #U+0087:ES #U+0088:HS @@ -2236,5 +2365,5 @@ U+007f:DT # Let's try to show a question mark for character that cannot # be shown. U+fffd is used for invalid characters. -# It works, but let's stick with UHHH representatiion. - FM -#U+fffd:? +# It works, but let's stick with UHHH representation. - FM +#U+fffd "?" diff --git a/src/chrtrans/iso01_uni.tbl b/src/chrtrans/iso01_uni.tbl index 2d138ec2..5a47e2f8 100644 --- a/src/chrtrans/iso01_uni.tbl +++ b/src/chrtrans/iso01_uni.tbl @@ -52,6 +52,9 @@ C819 # # Any comments or problems, contact <John_Jenkins@taligent.com> # +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw +# 0x20-0x7e idem 0xa0-0xff idem # iso 8859-1 special: trivial mapping to Unicode # @@ -150,7 +153,7 @@ C819 #0x7C U+007C # VERTICAL LINE #0x7D U+007D # RIGHT CURLY BRACKET #0x7E U+007E # TILDE -#0xA0 U+00A0 # NO-BREAK SPACE +0xA0 U+00A0 U+2007 # NO-BREAK SPACE #0xA1 U+00A1 # INVERTED EXCLAMATION MARK #0xA2 U+00A2 # CENT SIGN #0xA3 U+00A3 # POUND SIGN @@ -158,23 +161,23 @@ C819 #0xA5 U+00A5 # YEN SIGN #0xA6 U+00A6 # BROKEN BAR #0xA7 U+00A7 # SECTION SIGN -#0xA8 U+00A8 # DIAERESIS +0xA8 U+00A8 U+0308 # DIAERESIS #0xA9 U+00A9 # COPYRIGHT SIGN #0xAA U+00AA # FEMININE ORDINAL INDICATOR #0xAB U+00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK #0xAC U+00AC # NOT SIGN #0xAD U+00AD # SOFT HYPHEN #0xAE U+00AE # REGISTERED SIGN -#0xAF U+00AF # MACRON -#0xB0 U+00B0 # DEGREE SIGN +0xAF U+00AF U+0304 # MACRON +0xB0 U+00B0 U+030a # DEGREE SIGN #0xB1 U+00B1 # PLUS-MINUS SIGN #0xB2 U+00B2 # SUPERSCRIPT TWO #0xB3 U+00B3 # SUPERSCRIPT THREE #0xB4 U+00B4 # ACUTE ACCENT -#0xB5 U+00B5 # MICRO SIGN +0xB5 U+00B5 U+03bc # MICRO SIGN #0xB6 U+00B6 # PILCROW SIGN -#0xB7 U+00B7 # MIDDLE DOT -#0xB8 U+00B8 # CEDILLA +0xB7 U+00B7 U+0307 U+0387 U+2027 # MIDDLE DOT +0xB8 U+00B8 U+0327 # CEDILLA #0xB9 U+00B9 # SUPERSCRIPT ONE #0xBA U+00BA # MASCULINE ORDINAL INDICATOR #0xBB U+00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK @@ -250,4 +253,11 @@ C819 0xd0 U+0110 # Dstrok and ETH are nearly the same... -U+2297 "(\327)" +U+2218 " \260 " # RING OPERATOR +U+221b " ROOT\263 " +U+2297 "(\327)" # CIRCLED TIMES +U+2299 "(\267)" # CIRCLED DOT OPERATOR +U+229A "(\260)" # CIRCLED RING OPERATOR +U+22A0 "[\327]" # SQUARED TIMES +U+22A1 "[\267]" # SQUARED DOT OPERATOR +U+22C5 " \267 " # DOT OPERATOR diff --git a/src/chrtrans/iso02_uni.tbl b/src/chrtrans/iso02_uni.tbl index 383b4674..b245be55 100644 --- a/src/chrtrans/iso02_uni.tbl +++ b/src/chrtrans/iso02_uni.tbl @@ -46,6 +46,9 @@ C912 # # Any comments or problems, contact <John_Jenkins@taligent.com> # +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw +# 0x20-0x7e idem # #0x20 U+0020 # SPACE @@ -145,35 +148,35 @@ C912 #0x7E U+007E # TILDE 0xA0 U+00A0 # NO-BREAK SPACE 0xA1 U+0104 # LATIN CAPITAL LETTER A WITH OGONEK -0xA2 U+02D8 # BREVE +0xA2 U+02D8 U+0306 # BREVE 0xA3 U+0141 # LATIN CAPITAL LETTER L WITH STROKE 0xA4 U+00A4 # CURRENCY SIGN 0xA5 U+013D # LATIN CAPITAL LETTER L WITH CARON 0xA6 U+015A # LATIN CAPITAL LETTER S WITH ACUTE 0xA7 U+00A7 # SECTION SIGN -0xA8 U+00A8 # DIAERESIS -0xA9 U+0160 # LATIN CAPITAL LETTER S WITH CARON +0xA8 U+00A8 U+0308 # DIAERESIS +0xA9 U+0160 U+0428 # LATIN CAPITAL LETTER S WITH CARON 0xAA U+015E # LATIN CAPITAL LETTER S WITH CEDILLA 0xAB U+0164 # LATIN CAPITAL LETTER T WITH CARON 0xAC U+0179 # LATIN CAPITAL LETTER Z WITH ACUTE 0xAD U+00AD # SOFT HYPHEN -0xAE U+017D # LATIN CAPITAL LETTER Z WITH CARON +0xAE U+017D U+0416 # LATIN CAPITAL LETTER Z WITH CARON 0xAF U+017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE -0xB0 U+00B0 # DEGREE SIGN +0xB0 U+00B0 U+030a # DEGREE SIGN 0xB1 U+0105 # LATIN SMALL LETTER A WITH OGONEK -0xB2 U+02DB # OGONEK +0xB2 U+02DB U+0328 # OGONEK 0xB3 U+0142 # LATIN SMALL LETTER L WITH STROKE 0xB4 U+00B4 # ACUTE ACCENT 0xB5 U+013E # LATIN SMALL LETTER L WITH CARON 0xB6 U+015B # LATIN SMALL LETTER S WITH ACUTE -0xB7 U+02C7 # CARON -0xB8 U+00B8 # CEDILLA -0xB9 U+0161 # LATIN SMALL LETTER S WITH CARON +0xB7 U+02C7 U+030c # CARON +0xB8 U+00B8 U+0327 # CEDILLA +0xB9 U+0161 U+0448 # LATIN SMALL LETTER S WITH CARON 0xBA U+015F # LATIN SMALL LETTER S WITH CEDILLA 0xBB U+0165 # LATIN SMALL LETTER T WITH CARON 0xBC U+017A # LATIN SMALL LETTER Z WITH ACUTE -0xBD U+02DD # DOUBLE ACUTE ACCENT -0xBE U+017E # LATIN SMALL LETTER Z WITH CARON +0xBD U+02DD U+030b # DOUBLE ACUTE ACCENT +0xBE U+017E U+0436 # LATIN SMALL LETTER Z WITH CARON 0xBF U+017C # LATIN SMALL LETTER Z WITH DOT ABOVE 0xC0 U+0154 # LATIN CAPITAL LETTER R WITH ACUTE 0xC1 U+00C1 # LATIN CAPITAL LETTER A WITH ACUTE @@ -183,7 +186,7 @@ C912 0xC5 U+0139 # LATIN CAPITAL LETTER L WITH ACUTE 0xC6 U+0106 # LATIN CAPITAL LETTER C WITH ACUTE 0xC7 U+00C7 # LATIN CAPITAL LETTER C WITH CEDILLA -0xC8 U+010C # LATIN CAPITAL LETTER C WITH CARON +0xC8 U+010C U+0427 # LATIN CAPITAL LETTER C WITH CARON 0xC9 U+00C9 # LATIN CAPITAL LETTER E WITH ACUTE 0xCA U+0118 # LATIN CAPITAL LETTER E WITH OGONEK 0xCB U+00CB # LATIN CAPITAL LETTER E WITH DIAERESIS @@ -198,7 +201,7 @@ C912 0xD4 U+00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX 0xD5 U+0150 # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE 0xD6 U+00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS -0xD7 U+00D7 # MULTIPLICATION SIGN +0xD7 U+00D7 U+00b7 # MULTIPLICATION SIGN 0xD8 U+0158 # LATIN CAPITAL LETTER R WITH CARON 0xD9 U+016E # LATIN CAPITAL LETTER U WITH RING ABOVE 0xDA U+00DA # LATIN CAPITAL LETTER U WITH ACUTE @@ -215,7 +218,7 @@ C912 0xE5 U+013A # LATIN SMALL LETTER L WITH ACUTE 0xE6 U+0107 # LATIN SMALL LETTER C WITH ACUTE 0xE7 U+00E7 # LATIN SMALL LETTER C WITH CEDILLA -0xE8 U+010D # LATIN SMALL LETTER C WITH CARON +0xE8 U+010D U+02a7 U+0447 # LATIN SMALL LETTER C WITH CARON 0xE9 U+00E9 # LATIN SMALL LETTER E WITH ACUTE 0xEA U+0119 # LATIN SMALL LETTER E WITH OGONEK 0xEB U+00EB # LATIN SMALL LETTER E WITH DIAERESIS @@ -238,8 +241,15 @@ C912 0xFC U+00FC # LATIN SMALL LETTER U WITH DIAERESIS 0xFD U+00FD # LATIN SMALL LETTER Y WITH ACUTE 0xFE U+0163 # LATIN SMALL LETTER T WITH CEDILLA -0xFF U+02D9 # DOT ABOVE +0xFF U+02D9 U+0307 U+0387 # DOT ABOVE 0xd0 U+00d0 # Dstrok and ETH are nearly the same... +U+2218 " \260 " # RING OPERATOR +U+2297 "(\327)" # CIRCLED TIMES +U+2299 "(\377)" # CIRCLED DOT OPERATOR +U+229A "(\260)" # CIRCLED RING OPERATOR +U+22A0 "[\327]" # SQUARED TIMES +U+22A1 "[\377]" # SQUARED DOT OPERATOR +U+22C5 " \377 " # DOT OPERATOR diff --git a/src/chrtrans/iso05_uni.tbl b/src/chrtrans/iso05_uni.tbl index 1436a687..7eeba113 100644 --- a/src/chrtrans/iso05_uni.tbl +++ b/src/chrtrans/iso05_uni.tbl @@ -46,6 +46,9 @@ C915 # # Any comments or problems, contact <John_Jenkins@taligent.com> # +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw +# 0x20-0x7e idem # #0x20 U+0020 # SPACE @@ -149,8 +152,8 @@ C915 0xA3 U+0403 # CYRILLIC CAPITAL LETTER GJE 0xA4 U+0404 # CYRILLIC CAPITAL LETTER UKRAINIAN IE 0xA5 U+0405 # CYRILLIC CAPITAL LETTER DZE -0xA6 U+0406 # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -0xA7 U+0407 # CYRILLIC CAPITAL LETTER YI +0xA6 U+0406 U+0130 # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0xA7 U+0407 U+03AA # CYRILLIC CAPITAL LETTER YI 0xA8 U+0408 # CYRILLIC CAPITAL LETTER JE 0xA9 U+0409 # CYRILLIC CAPITAL LETTER LJE 0xAA U+040A # CYRILLIC CAPITAL LETTER NJE @@ -162,28 +165,28 @@ C915 0xB0 U+0410 # CYRILLIC CAPITAL LETTER A 0xB1 U+0411 # CYRILLIC CAPITAL LETTER BE 0xB2 U+0412 # CYRILLIC CAPITAL LETTER VE -0xB3 U+0413 # CYRILLIC CAPITAL LETTER GHE +0xB3 U+0413 U+0393 # CYRILLIC CAPITAL LETTER GHE 0xB4 U+0414 # CYRILLIC CAPITAL LETTER DE 0xB5 U+0415 # CYRILLIC CAPITAL LETTER IE -0xB6 U+0416 # CYRILLIC CAPITAL LETTER ZHE +0xB6 U+0416 U+017d # CYRILLIC CAPITAL LETTER ZHE 0xB7 U+0417 # CYRILLIC CAPITAL LETTER ZE 0xB8 U+0418 # CYRILLIC CAPITAL LETTER I 0xB9 U+0419 # CYRILLIC CAPITAL LETTER SHORT I 0xBA U+041A # CYRILLIC CAPITAL LETTER KA -0xBB U+041B # CYRILLIC CAPITAL LETTER EL +0xBB U+041B U+039b # CYRILLIC CAPITAL LETTER EL 0xBC U+041C # CYRILLIC CAPITAL LETTER EM 0xBD U+041D # CYRILLIC CAPITAL LETTER EN 0xBE U+041E # CYRILLIC CAPITAL LETTER O -0xBF U+041F # CYRILLIC CAPITAL LETTER PE +0xBF U+041F U+03a0 # CYRILLIC CAPITAL LETTER PE 0xC0 U+0420 # CYRILLIC CAPITAL LETTER ER 0xC1 U+0421 # CYRILLIC CAPITAL LETTER ES 0xC2 U+0422 # CYRILLIC CAPITAL LETTER TE 0xC3 U+0423 # CYRILLIC CAPITAL LETTER U -0xC4 U+0424 # CYRILLIC CAPITAL LETTER EF +0xC4 U+0424 U+03a6 # CYRILLIC CAPITAL LETTER EF 0xC5 U+0425 # CYRILLIC CAPITAL LETTER HA 0xC6 U+0426 # CYRILLIC CAPITAL LETTER TSE -0xC7 U+0427 # CYRILLIC CAPITAL LETTER CHE -0xC8 U+0428 # CYRILLIC CAPITAL LETTER SHA +0xC7 U+0427 U+010c # CYRILLIC CAPITAL LETTER CHE +0xC8 U+0428 U+0160 # CYRILLIC CAPITAL LETTER SHA 0xC9 U+0429 # CYRILLIC CAPITAL LETTER SHCHA 0xCA U+042A # CYRILLIC CAPITAL LETTER HARD SIGN 0xCB U+042B # CYRILLIC CAPITAL LETTER YERU @@ -197,28 +200,28 @@ C915 0xD3 U+0433 # CYRILLIC SMALL LETTER GHE 0xD4 U+0434 # CYRILLIC SMALL LETTER DE 0xD5 U+0435 # CYRILLIC SMALL LETTER IE -0xD6 U+0436 # CYRILLIC SMALL LETTER ZHE +0xD6 U+0436 U+017e # CYRILLIC SMALL LETTER ZHE 0xD7 U+0437 # CYRILLIC SMALL LETTER ZE 0xD8 U+0438 # CYRILLIC SMALL LETTER I 0xD9 U+0439 # CYRILLIC SMALL LETTER SHORT I 0xDA U+043A # CYRILLIC SMALL LETTER KA -0xDB U+043B # CYRILLIC SMALL LETTER EL +0xDB U+043B U+03bb # CYRILLIC SMALL LETTER EL 0xDC U+043C # CYRILLIC SMALL LETTER EM 0xDD U+043D # CYRILLIC SMALL LETTER EN 0xDE U+043E # CYRILLIC SMALL LETTER O -0xDF U+043F # CYRILLIC SMALL LETTER PE +0xDF U+043F U+03c0 # CYRILLIC SMALL LETTER PE 0xE0 U+0440 # CYRILLIC SMALL LETTER ER 0xE1 U+0441 # CYRILLIC SMALL LETTER ES 0xE2 U+0442 # CYRILLIC SMALL LETTER TE 0xE3 U+0443 # CYRILLIC SMALL LETTER U -0xE4 U+0444 # CYRILLIC SMALL LETTER EF +0xE4 U+0444 U+03c6 # CYRILLIC SMALL LETTER EF 0xE5 U+0445 # CYRILLIC SMALL LETTER HA 0xE6 U+0446 # CYRILLIC SMALL LETTER TSE -0xE7 U+0447 # CYRILLIC SMALL LETTER CHE -0xE8 U+0448 # CYRILLIC SMALL LETTER SHA +0xE7 U+0447 U+010d # CYRILLIC SMALL LETTER CHE +0xE8 U+0448 U+0161 # CYRILLIC SMALL LETTER SHA 0xE9 U+0449 # CYRILLIC SMALL LETTER SHCHA 0xEA U+044A # CYRILLIC SMALL LETTER HARD SIGN -0xEB U+044B # CYRILLIC SMALL LETTER YERU +0xEB U+044B U+0131 # CYRILLIC SMALL LETTER YERU 0xEC U+044C # CYRILLIC SMALL LETTER SOFT SIGN 0xED U+044D # CYRILLIC SMALL LETTER E 0xEE U+044E # CYRILLIC SMALL LETTER YU @@ -230,7 +233,7 @@ C915 0xF4 U+0454 # CYRILLIC SMALL LETTER UKRAINIAN IE 0xF5 U+0455 # CYRILLIC SMALL LETTER DZE 0xF6 U+0456 # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I -0xF7 U+0457 # CYRILLIC SMALL LETTER YI +0xF7 U+0457 U+03CA # CYRILLIC SMALL LETTER YI 0xF8 U+0458 # CYRILLIC SMALL LETTER JE 0xF9 U+0459 # CYRILLIC SMALL LETTER LJE 0xFA U+045A # CYRILLIC SMALL LETTER NJE @@ -240,3 +243,7 @@ C915 0xFE U+045E # CYRILLIC SMALL LETTER SHORT U 0xFF U+045F # CYRILLIC SMALL LETTER DZHE +U+0400 "`\265" +U+040d "`\270" +U+0450 "`\325" +U+045d "`\330" diff --git a/src/chrtrans/iso07_uni.tbl b/src/chrtrans/iso07_uni.tbl index 7e9063ec..458c2389 100644 --- a/src/chrtrans/iso07_uni.tbl +++ b/src/chrtrans/iso07_uni.tbl @@ -46,6 +46,9 @@ C813 # # Any comments or problems, contact <John_Jenkins@taligent.com> # +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw +# 0x20-0x7e idem # #0x20 U+0020 # SPACE @@ -161,20 +164,20 @@ C813 0xB3 U+00B3 # SUPERSCRIPT THREE 0xB4 U+0384 # GREEK TONOS 0xB5 U+0385 # GREEK DIALYTIKA TONOS -0xB6 U+0386 # GREEK CAPITAL LETTER ALPHA WITH TONOS -0xB7 U+00B7 # MIDDLE DOT -0xB8 U+0388 # GREEK CAPITAL LETTER EPSILON WITH TONOS -0xB9 U+0389 # GREEK CAPITAL LETTER ETA WITH TONOS -0xBA U+038A # GREEK CAPITAL LETTER IOTA WITH TONOS +0xB6 U+0386 U+1fbb # GREEK CAPITAL LETTER ALPHA WITH TONOS +0xB7 U+00B7 U+0307 U+0387 U+2027 # MIDDLE DOT +0xB8 U+0388 U+1fc9 # GREEK CAPITAL LETTER EPSILON WITH TONOS +0xB9 U+0389 U+1fcb # GREEK CAPITAL LETTER ETA WITH TONOS +0xBA U+038A U+1fdb # GREEK CAPITAL LETTER IOTA WITH TONOS 0xBB U+00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -0xBC U+038C # GREEK CAPITAL LETTER OMICRON WITH TONOS +0xBC U+038C U+1ff9 # GREEK CAPITAL LETTER OMICRON WITH TONOS 0xBD U+00BD # VULGAR FRACTION ONE HALF -0xBE U+038E # GREEK CAPITAL LETTER UPSILON WITH TONOS -0xBF U+038F # GREEK CAPITAL LETTER OMEGA WITH TONOS +0xBE U+038E U+1feb # GREEK CAPITAL LETTER UPSILON WITH TONOS +0xBF U+038F U+1ffb # GREEK CAPITAL LETTER OMEGA WITH TONOS 0xC0 U+0390 # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS 0xC1 U+0391 # GREEK CAPITAL LETTER ALPHA 0xC2 U+0392 # GREEK CAPITAL LETTER BETA -0xC3 U+0393 # GREEK CAPITAL LETTER GAMMA +0xC3 U+0393 U+0413 # GREEK CAPITAL LETTER GAMMA 0xC4 U+0394 # GREEK CAPITAL LETTER DELTA 0xC5 U+0395 # GREEK CAPITAL LETTER EPSILON 0xC6 U+0396 # GREEK CAPITAL LETTER ZETA @@ -182,39 +185,39 @@ C813 0xC8 U+0398 # GREEK CAPITAL LETTER THETA 0xC9 U+0399 # GREEK CAPITAL LETTER IOTA 0xCA U+039A # GREEK CAPITAL LETTER KAPPA -0xCB U+039B # GREEK CAPITAL LETTER LAMDA +0xCB U+039B U+041b # GREEK CAPITAL LETTER LAMDA 0xCC U+039C # GREEK CAPITAL LETTER MU 0xCD U+039D # GREEK CAPITAL LETTER NU 0xCE U+039E # GREEK CAPITAL LETTER XI 0xCF U+039F # GREEK CAPITAL LETTER OMICRON -0xD0 U+03A0 # GREEK CAPITAL LETTER PI +0xD0 U+03A0 U+041f # GREEK CAPITAL LETTER PI 0xD1 U+03A1 # GREEK CAPITAL LETTER RHO 0xD3 U+03A3 # GREEK CAPITAL LETTER SIGMA 0xD4 U+03A4 # GREEK CAPITAL LETTER TAU 0xD5 U+03A5 # GREEK CAPITAL LETTER UPSILON -0xD6 U+03A6 # GREEK CAPITAL LETTER PHI -0xD7 U+03A7 # GREEK CAPITAL LETTER CHI +0xD6 U+03A6 U+0424 # GREEK CAPITAL LETTER PHI +0xD7 U+03A7 U+0425 # GREEK CAPITAL LETTER CHI 0xD8 U+03A8 # GREEK CAPITAL LETTER PSI 0xD9 U+03A9 # GREEK CAPITAL LETTER OMEGA 0xDA U+03AA # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA 0xDB U+03AB # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -0xDC U+03AC # GREEK SMALL LETTER ALPHA WITH TONOS -0xDD U+03AD # GREEK SMALL LETTER EPSILON WITH TONOS -0xDE U+03AE # GREEK SMALL LETTER ETA WITH TONOS -0xDF U+03AF # GREEK SMALL LETTER IOTA WITH TONOS +0xDC U+03AC U+1f71 # GREEK SMALL LETTER ALPHA WITH TONOS +0xDD U+03AD U+1f73 # GREEK SMALL LETTER EPSILON WITH TONOS +0xDE U+03AE U+1f75 # GREEK SMALL LETTER ETA WITH TONOS +0xDF U+03AF U+1f77 # GREEK SMALL LETTER IOTA WITH TONOS 0xE0 U+03B0 # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS 0xE1 U+03B1 # GREEK SMALL LETTER ALPHA 0xE2 U+03B2 # GREEK SMALL LETTER BETA -0xE3 U+03B3 # GREEK SMALL LETTER GAMMA -0xE4 U+03B4 # GREEK SMALL LETTER DELTA +0xE3 U+03B3 U+0263 # GREEK SMALL LETTER GAMMA +0xE4 U+03B4 U+00f0 # GREEK SMALL LETTER DELTA 0xE5 U+03B5 # GREEK SMALL LETTER EPSILON 0xE6 U+03B6 # GREEK SMALL LETTER ZETA 0xE7 U+03B7 # GREEK SMALL LETTER ETA 0xE8 U+03B8 # GREEK SMALL LETTER THETA -0xE9 U+03B9 # GREEK SMALL LETTER IOTA +0xE9 U+03B9 U+0131 # GREEK SMALL LETTER IOTA 0xEA U+03BA # GREEK SMALL LETTER KAPPA 0xEB U+03BB # GREEK SMALL LETTER LAMDA -0xEC U+03BC # GREEK SMALL LETTER MU +0xEC U+03BC U+00b5 # GREEK SMALL LETTER MU 0xED U+03BD # GREEK SMALL LETTER NU 0xEE U+03BE # GREEK SMALL LETTER XI 0xEF U+03BF # GREEK SMALL LETTER OMICRON @@ -223,14 +226,20 @@ C813 0xF2 U+03C2 # GREEK SMALL LETTER FINAL SIGMA 0xF3 U+03C3 # GREEK SMALL LETTER SIGMA 0xF4 U+03C4 # GREEK SMALL LETTER TAU -0xF5 U+03C5 # GREEK SMALL LETTER UPSILON +0xF5 U+03C5 U+028a # GREEK SMALL LETTER UPSILON 0xF6 U+03C6 # GREEK SMALL LETTER PHI 0xF7 U+03C7 # GREEK SMALL LETTER CHI 0xF8 U+03C8 # GREEK SMALL LETTER PSI 0xF9 U+03C9 # GREEK SMALL LETTER OMEGA 0xFA U+03CA # GREEK SMALL LETTER IOTA WITH DIALYTIKA -0xFB U+03CB # GREEK SMALL LETTER UPSILON WITH DIALYTIKA -0xFC U+03CC # GREEK SMALL LETTER OMICRON WITH TONOS -0xFD U+03CD # GREEK SMALL LETTER UPSILON WITH TONOS -0xFE U+03CE # GREEK SMALL LETTER OMEGA WITH TONOS +0xFB U+03CB U+00fc # GREEK SMALL LETTER UPSILON WITH DIALYTIKA +0xFC U+03CC U+1f79 # GREEK SMALL LETTER OMICRON WITH TONOS +0xFD U+03CD U+1f7b # GREEK SMALL LETTER UPSILON WITH TONOS +0xFE U+03CE U+1f7d # GREEK SMALL LETTER OMEGA WITH TONOS +U+2218 " \260 " # RING OPERATOR +U+2209 " !\345 " +U+221b " ROOT\263 " +U+229A "(\260)" # CIRCLED RING OPERATOR +U+02a4 "d\346" +U+20af "\304\361\367" diff --git a/src/chrtrans/iso09_uni.tbl b/src/chrtrans/iso09_uni.tbl index 0b93209c..5dc9660c 100644 --- a/src/chrtrans/iso09_uni.tbl +++ b/src/chrtrans/iso09_uni.tbl @@ -46,7 +46,11 @@ C920 # # Any comments or problems, contact <John_Jenkins@taligent.com> # +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw +# 0x20-0x7e idem +0x49 U+042b # #0x20 U+0020 # SPACE #0x21 U+0021 # EXCLAMATION MARK @@ -151,23 +155,23 @@ C920 0xA5 U+00A5 # YEN SIGN 0xA6 U+00A6 # BROKEN BAR 0xA7 U+00A7 # SECTION SIGN -0xA8 U+00A8 # DIAERESIS +0xA8 U+00A8 U+0308 # DIAERESIS 0xA9 U+00A9 # COPYRIGHT SIGN 0xAA U+00AA # FEMININE ORDINAL INDICATOR 0xAB U+00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 0xAC U+00AC # NOT SIGN 0xAD U+00AD # SOFT HYPHEN 0xAE U+00AE # REGISTERED SIGN -0xAF U+00AF # MACRON -0xB0 U+00B0 # DEGREE SIGN +0xAF U+00AF U+0304 # MACRON +0xB0 U+00B0 U+030a # DEGREE SIGN 0xB1 U+00B1 # PLUS-MINUS SIGN 0xB2 U+00B2 # SUPERSCRIPT TWO 0xB3 U+00B3 # SUPERSCRIPT THREE 0xB4 U+00B4 # ACUTE ACCENT -0xB5 U+00B5 # MICRO SIGN +0xB5 U+00B5 U+03bc # MICRO SIGN 0xB6 U+00B6 # PILCROW SIGN -0xB7 U+00B7 # MIDDLE DOT -0xB8 U+00B8 # CEDILLA +0xB7 U+00B7 U+0307 U+0387 # MIDDLE DOT +0xB8 U+00B8 U+0327 # CEDILLA 0xB9 U+00B9 # SUPERSCRIPT ONE 0xBA U+00BA # MASCULINE ORDINAL INDICATOR 0xBB U+00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK @@ -204,8 +208,8 @@ C920 0xDA U+00DA # LATIN CAPITAL LETTER U WITH ACUTE 0xDB U+00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX 0xDC U+00DC # LATIN CAPITAL LETTER U WITH DIAERESIS -0xDD U+0130 # LATIN CAPITAL LETTER I WITH DOT ABOVE -0xDE U+015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xDD U+0130 U+0418 U+0406 # LATIN CAPITAL LETTER I WITH DOT ABOVE +0xDE U+015E U+0428 # LATIN CAPITAL LETTER S WITH CEDILLA 0xDF U+00DF # LATIN SMALL LETTER SHARP S 0xE0 U+00E0 # LATIN SMALL LETTER A WITH GRAVE 0xE1 U+00E1 # LATIN SMALL LETTER A WITH ACUTE @@ -236,7 +240,15 @@ C920 0xFA U+00FA # LATIN SMALL LETTER U WITH ACUTE 0xFB U+00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX 0xFC U+00FC # LATIN SMALL LETTER U WITH DIAERESIS -0xFD U+0131 # LATIN SMALL LETTER DOTLESS I -0xFE U+015F # LATIN SMALL LETTER S WITH CEDILLA +0xFD U+0131 U+03b9 U+044b # LATIN SMALL LETTER DOTLESS I +0xFE U+015F U+0448 # LATIN SMALL LETTER S WITH CEDILLA 0xFF U+00FF # LATIN SMALL LETTER Y WITH DIAERESIS +U+2218 " \260 " # RING OPERATOR +U+221b " ROOT\263 " +U+2297 "(\327)" # CIRCLED TIMES +U+2299 "(\267)" # CIRCLED DOT OPERATOR +U+229A "(\260)" # CIRCLED RING OPERATOR +U+22A0 "[\327]" # SQUARED TIMES +U+22A1 "[\267]" # SQUARED DOT OPERATOR +U+22C5 " \267 " # DOT OPERATOR diff --git a/src/chrtrans/koi8r_uni.tbl b/src/chrtrans/koi8r_uni.tbl index 1378eed9..8bf4001a 100644 --- a/src/chrtrans/koi8r_uni.tbl +++ b/src/chrtrans/koi8r_uni.tbl @@ -11,6 +11,9 @@ C878 # Based on a table received from "Glenn E. Thobe" <thobe@lafn.org> # (verified against RFC1489). # +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw +# #hex unicode # description #--- U+---- # --------------- 0x80 U+2500 # FORMS LIGHT HORIZONTAL @@ -43,7 +46,7 @@ C878 0x9B U+2321 # BOTTOM HALF INTEGRAL 0x9C U+00B0 # DEGREE SIGN 0x9D U+00B2 # SUPERSCRIPT DIGIT TWO -0x9E U+00B7 # MIDDLE DOT +0x9E U+00B7 U+2027 # MIDDLE DOT 0x9F U+00F7 # DIVISION SIGN 0xA0 U+2550 # FORMS DOUBLE HORIZONTAL 0xA1 U+2551 # FORMS DOUBLE VERTICAL @@ -83,31 +86,31 @@ C878 0xC3 U+0446 # SMA TSE 0xC4 U+0434 # SMA DE 0xC5 U+0435 # SMA IE -0xC6 U+0444 # SMA EF +0xC6 U+0444 U+03c6 # SMA EF 0xC7 U+0433 # SMA GE 0xC8 U+0445 # SMA KHA 0xC9 U+0438 # SMA II 0xCA U+0439 # SMA SHORT II 0xCB U+043A # SMA KA -0xCC U+043B # SMA EL +0xCC U+043B U+03bb # SMA EL 0xCD U+043C # SMA EM 0xCE U+043D # SMA EN 0xCF U+043E # SMA O -0xD0 U+043F # SMA PE +0xD0 U+043F U+03c0 # SMA PE 0xD1 U+044F # SMA IA 0xD2 U+0440 # SMA ER 0xD3 U+0441 # SMA ES 0xD4 U+0442 # SMA TE 0xD5 U+0443 # SMA U -0xD6 U+0436 # SMA ZHE +0xD6 U+0436 U+017e # SMA ZHE 0xD7 U+0432 # SMA VE 0xD8 U+044C # SMA SOFT SIGN -0xD9 U+044B # SMA YERI +0xD9 U+044B U+0131 # SMA YERI 0xDA U+0437 # SMA ZE -0xDB U+0448 # SMA SHA +0xDB U+0448 U+0161 # SMA SHA 0xDC U+044D # SMA REVERSED E 0xDD U+0449 # SMA SHCHA -0xDE U+0447 # SMA CHE +0xDE U+0447 U+010d # SMA CHE 0xDF U+044A # SMA HARD SIGN 0xE0 U+042E # CAP IU 0xE1 U+0410 # CAP A @@ -115,30 +118,30 @@ C878 0xE3 U+0426 # CAP TSE 0xE4 U+0414 # CAP DE 0xE5 U+0415 # CAP IE -0xE6 U+0424 # CAP EF -0xE7 U+0413 # CAP GE +0xE6 U+0424 U+03a6 # CAP EF +0xE7 U+0413 U+0393 # CAP GE 0xE8 U+0425 # CAP KHA 0xE9 U+0418 # CAP II 0xEA U+0419 # CAP SHORT II 0xEB U+041A # CAP KA -0xEC U+041B # CAP EL +0xEC U+041B U+039b # CAP EL 0xED U+041C # CAP EM 0xEE U+041D # CAP EN 0xEF U+041E # CAP O -0xF0 U+041F # CAP PE +0xF0 U+041F U+03a0 # CAP PE 0xF1 U+042F # CAP IA 0xF2 U+0420 # CAP ER 0xF3 U+0421 # CAP ES 0xF4 U+0422 # CAP TE 0xF5 U+0423 # CAP U -0xF6 U+0416 # CAP ZHE +0xF6 U+0416 U+017d # CAP ZHE 0xF7 U+0412 # CAP VE 0xF8 U+042C # CAP SOFT SIGN 0xF9 U+042B # CAP YERI 0xFA U+0417 # CAP ZE -0xFB U+0428 # CAP SHA +0xFB U+0428 U+0160 # CAP SHA 0xFC U+042D # CAP REVERSED E 0xFD U+0429 # CAP SHCHA -0xFE U+0427 # CAP CHE +0xFE U+0427 U+010c # CAP CHE 0xFF U+042A # CAP HARD SIGN diff --git a/src/chrtrans/mac_uni.tbl b/src/chrtrans/mac_uni.tbl index ea76d078..c2457e7b 100644 --- a/src/chrtrans/mac_uni.tbl +++ b/src/chrtrans/mac_uni.tbl @@ -80,6 +80,8 @@ OMacintosh (8 bit) # interpreted (if at all) as the control codes DC1-DC4. # ################## +# Lines with more than one Unicode (U+XXXX) value contain additional +# replacement mappings added for lynx. - kw #0x20 U+0020 # SPACE #0x21 U+0021 # EXCLAMATION MARK @@ -276,7 +278,7 @@ OMacintosh (8 bit) 0xDE U+FB01 # LATIN SMALL LIGATURE FI 0xDF U+FB02 # LATIN SMALL LIGATURE FL 0xE0 U+2021 # DOUBLE DAGGER -0xE1 U+00B7 # MIDDLE DOT +0xE1 U+00B7 U+0307 U+0387 U+2027 # MIDDLE DOT 0xE2 U+201A # SINGLE LOW-9 QUOTATION MARK 0xE3 U+201E # DOUBLE LOW-9 QUOTATION MARK 0xE4 U+2030 # PER MILLE SIGN diff --git a/src/chrtrans/makeuctb.c b/src/chrtrans/makeuctb.c index 8c333d90..9ad80ecb 100644 --- a/src/chrtrans/makeuctb.c +++ b/src/chrtrans/makeuctb.c @@ -89,7 +89,7 @@ PUBLIC int strncasecomp ARGS3( CONST char *q = b; for (p = a, q = b; ; p++, q++) { - int diff; + int diff; if (p == (a+n)) return 0; /* Match up to n characters */ if (!(*p && *q)) @@ -136,6 +136,8 @@ PRIVATE int Raw_found = 0; /* whether explicit R directive found */ PRIVATE int CodePage = 0; PRIVATE int CodePage_found = 0; /* whether explicit C directive found */ +#define MAX_UNIPAIRS 2500 + PRIVATE void addpair_str ARGS2( char *, str, int, un) @@ -147,8 +149,8 @@ PRIVATE void addpair_str ARGS2( /* * Initialize the map for replacement strings. */ - themap_str.entries = - (struct unipair_str *) malloc (2000 * sizeof (struct unipair_str)); + themap_str.entries = (struct unipair_str *) malloc (MAX_UNIPAIRS + * sizeof (struct unipair_str)); if (!themap_str.entries) { fprintf(stderr, "%s: Out of memory\n", tblname); @@ -169,9 +171,10 @@ PRIVATE void addpair_str ARGS2( /* * Add to list. */ - if (themap_str.entry_ct > 1999) { + if (themap_str.entry_ct > MAX_UNIPAIRS-1) { fprintf(stderr, - "ERROR: Only 2000 unicode replacement strings permitted!\n"); + "ERROR: Only %d unicode replacement strings permitted!\n", + MAX_UNIPAIRS); done(EX_DATAERR); } themap_str.entries[themap_str.entry_ct].unicode = un; @@ -187,7 +190,7 @@ PRIVATE void addpair ARGS2( { int i; - if (!Raw_found) { /* enc not (yet) explicitly given with 'R' */ + if (!Raw_found) { /* enc not (yet) explicitly given with 'R' */ if (fp >= 128) { if (RawOrEnc != UCT_ENC_8BIT && RawOrEnc <= UCT_ENC_8859) { if (fp < 160) { /* cannot be 8859 */ @@ -391,7 +394,7 @@ PUBLIC int main ARGS2( } p++; while (*p == ' ' || *p == '\t') { - p++; + p++; } RawOrEnc = strtol(p,0,10); Raw_found = 1; @@ -400,7 +403,7 @@ PUBLIC int main ARGS2( /* * Is this the default table? */ - case 'D': + case 'D': if (p[1] == 'e' || p[1] == 'E') { buffer[sizeof(buffer) - 1] = '\0'; if (!strncasecomp(p, "Default", 7)) { @@ -417,7 +420,7 @@ PUBLIC int main ARGS2( /* * Is this the default table? */ - case 'F': + case 'F': if (p[1] == 'a' || p[1] == 'A') { buffer[sizeof(buffer) - 1] = '\0'; if (!strncasecomp(p, "FallBack", 8)) { @@ -477,7 +480,7 @@ PUBLIC int main ARGS2( } p++; while (*p == ' ' || *p == '\t') { - p++; + p++; } CodePage = strtol(p,0,10); CodePage_found = 1; @@ -587,7 +590,7 @@ PUBLIC int main ARGS2( if (p1 == p) { fprintf(stderr, "Bad input line: %s\n", buffer); done(EX_DATAERR); - } + } p = p1; while (*p == ' ' || *p == '\t') { @@ -601,7 +604,7 @@ PUBLIC int main ARGS2( done(EX_DATAERR); } p = p1; - } else { + } else { fp1 = 0; } @@ -643,7 +646,7 @@ PUBLIC int main ARGS2( fprintf(stderr, " there should be a Unicode range.\n"); done(EX_DATAERR); - } + } p++; un1 = getunicode(&p); if (un0 < 0 || un1 < 0) { @@ -651,7 +654,7 @@ PUBLIC int main ARGS2( "%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n", tblname, fp0, fp1); done(EX_DATAERR); - } + } if (un1 - un0 != fp1 - fp0) { fprintf(stderr, "%s: Unicode range U+%x-U+%x not of the same length", @@ -660,7 +663,7 @@ PUBLIC int main ARGS2( " as font position range 0x%x-0x%x\n", fp0, fp1); done(EX_DATAERR); - } + } for (i = fp0; i <= fp1; i++) { addpair(i,un0-fp0+i); } @@ -752,8 +755,8 @@ PUBLIC int main ARGS2( this_isDefaultMap = !strncmp(this_MIMEcharset,"iso-8859-1", 10); } fprintf(stderr, - "makeuctb: %s: %stranslation map", - this_MIMEcharset, (this_isDefaultMap ? "default " : "")); + "makeuctb: %s: %stranslation map", + this_MIMEcharset, (this_isDefaultMap ? "default " : "")); if (this_isDefaultMap == 1) { *id_append = '\0'; } else { @@ -808,7 +811,7 @@ static CONST u8 dfont_unicount%s[%d] = \n\ if (nuni) { fprintf(chdr, "\nstatic CONST u16 dfont_unitable%s[%d] = \n{\n\t", - id_append, nuni); + id_append, nuni); } else { fprintf(chdr, "\nstatic CONST u16 dfont_unitable%s[1]; /* dummy */\n", id_append); } @@ -841,8 +844,8 @@ static struct unipair_str repl_map%s[%d] = \n\ for (i = 0; i < themap_str.entry_ct; i++) { fprintf(chdr, "{0x%x,\"%s\"}", - themap_str.entries[i].unicode, - themap_str.entries[i].replace_str); + themap_str.entries[i].unicode, + themap_str.entries[i].replace_str); if (i == (themap_str.entry_ct - 1)) { fprintf(chdr, "\n};\n"); } else if ((i % 4) == 3) { diff --git a/src/makefile.dos b/src/makefile.dos index a10c0b2d..98b57662 100644 --- a/src/makefile.dos +++ b/src/makefile.dos @@ -7,7 +7,7 @@ LYForms.o LYPrint.o LYrcFile.o LYDownload.o LYNews.o LYKeymap.o \ HTML.o HTFWriter.o HTInit.o DefaultStyle.o LYLocal.o LYUpload.o \ LYLeaks.o LYexit.o LYJump.o LYList.o LYCgi.o LYTraversal.o \ LYEditmap.o LYCharSets.o LYCharUtils.o LYMap.o LYCookie.o LYExtern.o \ -LYStyle.o LYHash.o LYPrettySrc.o +LYStyle.o LYHash.o LYPrettySrc.o TRSTable.o CFLAGS= $(MCFLAGS) -I. -I.. $(SLANGINC) diff --git a/src/makefile.dsl b/src/makefile.dsl index 9eb56338..093bcb0c 100644 --- a/src/makefile.dsl +++ b/src/makefile.dsl @@ -7,7 +7,7 @@ LYForms.o LYPrint.o LYrcFile.o LYDownload.o LYNews.o LYKeymap.o \ HTML.o HTFWriter.o HTInit.o DefaultStyle.o LYLocal.o LYUpload.o \ LYLeaks.o LYexit.o LYJump.o LYList.o LYCgi.o LYTraversal.o \ LYEditmap.o LYCharSets.o LYCharUtils.o LYMap.o LYCookie.o LYExtern.o \ -LYStyle.o LYHash.o LYPrettySrc.o +LYStyle.o LYHash.o LYPrettySrc.o TRSTable.o CFLAGS= $(MCFLAGS) $(INTLFLAGS) -I. -I.. $(SLANGINC) diff --git a/src/makefile.in b/src/makefile.in index 67dc920b..89e8ef71 100644 --- a/src/makefile.in +++ b/src/makefile.in @@ -67,7 +67,7 @@ LYForms.o LYPrint.o LYrcFile.o LYDownload.o LYNews.o LYKeymap.o \ HTML.o HTFWriter.o HTInit.o DefaultStyle.o LYLocal.o LYUpload.o \ LYLeaks.o LYexit.o LYJump.o LYList.o LYCgi.o LYTraversal.o \ LYEditmap.o LYCharSets.o LYCharUtils.o LYMap.o LYCookie.o LYExtern.o \ -LYStyle.o LYHash.o LYPrettySrc.o $(CHARTRANS_OBJS) @LIBOBJS@ +LYStyle.o LYHash.o LYPrettySrc.o TRSTable.o $(CHARTRANS_OBJS) @LIBOBJS@ C_SRC = $(OBJS:.o=.c) diff --git a/src/makefile.wsl b/src/makefile.wsl index a97b51bf..97f488d9 100644 --- a/src/makefile.wsl +++ b/src/makefile.wsl @@ -7,7 +7,7 @@ LYForms.o LYPrint.o LYrcFile.o LYDownload.o LYNews.o LYKeymap.o \ HTML.o HTFWriter.o HTInit.o DefaultStyle.o LYLocal.o LYUpload.o \ LYLeaks.o LYexit.o LYJump.o LYList.o LYCgi.o LYTraversal.o \ LYEditmap.o LYCharSets.o LYCharUtils.o LYMap.o LYCookie.o LYExtern.o \ -LYStyle.o LYHash.o LYPrettySrc.o +LYStyle.o LYHash.o LYPrettySrc.o TRSTable.o CFLAGS= $(MCFLAGS) -I. -I.. $(SLANGINC) |