📄 html.c
字号:
/* Structured stream to Rich hypertext converter** ============================================**** This generates a hypertext object. It converts from the** structured stream interface of HTML events into the style-** oriented interface of the HText.h interface. This module is** only used in clients and should not be linked into servers.**** Override this module if making a new GUI browser.**** Being Overidden***/#include "HTUtils.h"#include "tcp.h"#define Lynx_HTML_Handler#include "HTChunk.h"#include "HText.h"#include "HTStyle.h"#include "HTML.h"#include "HTCJK.h"#include "HTAtom.h"#include "HTAnchor.h"#include "HTMLGen.h"#include "HTParse.h"#include "HTList.h"#include "UCMap.h"#include "UCDefs.h"#include "UCAux.h"#include "LYGlobalDefs.h"#include "LYCharUtils.h"#include "LYCharSets.h"#include "HTAlert.h"#include "HTFont.h"#include "HTForms.h"#include "HTNestedList.h"#include "GridText.h"#include "LYSignal.h"#include "LYUtils.h"#include "LYMap.h"#include "LYList.h"#include "LYBookmark.h"#ifdef VMS#include "LYCurses.h"#include "HTVMSUtils.h"#endif /* VMS */#ifdef USE_COLOR_STYLE#include "AttrList.h"#include "LYHash.h"#include "LYStyle.h"#undef SELECTED_STYLES#define pHText_changeStyle(X,Y,Z) {}char Style_className[16384];#endif#include "LYexit.h"#include "LYLeaks.h"#define FREE(x) if (x) {free(x); x = NULL;}extern BOOL HTPassEightBitRaw;extern HTCJKlang HTCJK;extern BOOLEAN HT_Is_Gopher_URL;/* from Curses.h */extern int LYcols;struct _HTStream { CONST HTStreamClass * isa; /* .... */};PRIVATE HTStyleSheet * styleSheet; /* Application-wide *//* Module-wide style cache*/PUBLIC HTStyle *styles[HTML_ELEMENTS+31]; /* adding 24 nested list styles */ /* and 3 header alignment styles */ /* and 3 div alignment styles */PRIVATE HTStyle *default_style;PUBLIC char *LYToolbarName = "LynxPseudoToolbar";/* used to turn off a style if the HTML author forgot toPRIVATE int i_prior_style = -1; *//* * Private function.... */PRIVATE void HTML_end_element PARAMS((HTStructured *me, int element_number, char **include));/* Forward declarations of routines*/PRIVATE void get_styles NOPARAMS;PRIVATE void change_paragraph_style PARAMS((HTStructured * me, HTStyle * style));/* Set an internal flag that the next call to a stack-affecting method** is only internal and the stack manipulation should be skipped. - kw*/#define SET_SKIP_STACK(el_num) if (HTML_dtd.tags[el_num].contents != SGML_EMPTY) \ { me->skip_stack++; }extern int hash_code PARAMS((char* i));PUBLIC void strtolower ARGS1(char*, i){ if (!i) return; while (*i) { *i=tolower(*i); i++; }}/* Flattening the style structure** ------------------------------**On the NeXT, and on any read-only browser, it is simpler for the text to havea sequence of styles, rather than a nested tree of styles. In thiscase we have to flatten the structure as it arrives from SGML tags intoa sequence of styles.*//*** If style really needs to be set, call this.*/PUBLIC void actually_set_style ARGS1(HTStructured *, me){ if (!me->text) { /* First time through */ LYGetChartransInfo(me); UCSetTransParams(&me->T, me->UCLYhndl, me->UCI, HTAnchor_getUCLYhndl(me->node_anchor, UCT_STAGE_HTEXT), HTAnchor_getUCInfoStage(me->node_anchor, UCT_STAGE_HTEXT)); me->text = HText_new2(me->node_anchor, me->target); HText_beginAppend(me->text); HText_setStyle(me->text, me->new_style); me->in_word = NO; LYCheckForContentBase(me); } else { HText_setStyle(me->text, me->new_style); } me->old_style = me->new_style; me->style_change = NO;}/*** If you THINK you need to change style, call this.*/PRIVATE void change_paragraph_style ARGS2(HTStructured *, me, HTStyle *,style){ if (me->new_style != style) { me->style_change = YES; me->new_style = style; } me->in_word = NO;}/*_________________________________________________________________________**** A C T I O N R O U T I N E S*//* Character handling** ------------------*/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) return; /* * Do EOL conversion if needed. - FM * * Convert EOL styles: * macintosh: cr --> lf * ascii: cr-lf --> lf * unix: lf --> lf */ if ((me->lastraw == '\r') && c == '\n') { me->lastraw = -1; return; } me->lastraw = c; if (c == '\r') c = '\n'; /* * Handle SGML_LITTERAL tags that have HTChunk elements. - FM */ switch (me->sp[0].tag_number) { case HTML_COMMENT: return; /* Do Nothing */ case HTML_TITLE: if (c == LY_SOFT_HYPHEN) return; if (c != '\n' && c != '\t' && c != '\r') HTChunkPutc(&me->title, c); else HTChunkPutc(&me->title, ' '); return; case HTML_STYLE: HTChunkPutc(&me->style_block, c); return; case HTML_SCRIPT: HTChunkPutc(&me->script, c); return; case HTML_OBJECT: HTChunkPutc(&me->object, c); return; case HTML_TEXTAREA: HTChunkPutc(&me->textarea, c); return; case HTML_SELECT: case HTML_OPTION: HTChunkPutc(&me->option, c); return; case HTML_MATH: HTChunkPutc(&me->math, c); return; default: if (me->inSELECT) { /* * If we are within a SELECT not caught by the cases * above - HTML_SELECT or HTML_OPTION may not be the * last element pushed on the style stack if there were * invalid markup tags within a SELECT element. For error * recovery, treat text as part of the OPTION text, it is * probably meant to show up as user-visible text. * Having A as an open element while in SELECT is really sick, * don't make anchor text part of the option text in that case * since the option text will probably just be discarded. - kw */ if (me->sp[0].tag_number == HTML_A) break; HTChunkPutc(&me->option, c); return; } break; } /* end first switch */ /* * Handle all other tag content. - FM */ switch (me->sp[0].tag_number) { case HTML_PRE: /* Formatted text */ /* * We guarantee that the style is up-to-date in begin_litteral * But we still want to strip \r's */ if (c != '\r' && !(c == '\n' && me->inLABEL && !me->inP) && !(c == '\n' && !me->inPRE)) { me->inP = TRUE; me->inLABEL = FALSE; HText_appendCharacter(me->text, c); } me->inPRE = TRUE; break; case HTML_LISTING: /* Literal text */ case HTML_XMP: case HTML_PLAINTEXT: /* * We guarantee that the style is up-to-date in begin_litteral * But we still want to strip \r's */ if (c != '\r') { me->inP = TRUE; me->inLABEL = FALSE; HText_appendCharacter(me->text, c); } break; default: /* * Free format text. */ if (!strcmp(me->sp->style->name,"Preformatted")) { if (c != '\r' && !(c == '\n' && me->inLABEL && !me->inP) && !(c == '\n' && !me->inPRE)) { me->inP = TRUE; me->inLABEL = FALSE; HText_appendCharacter(me->text, c); } me->inPRE = TRUE; } else if (!strcmp(me->sp->style->name,"Listing") || !strcmp(me->sp->style->name,"Example")) { if (c != '\r') { me->inP = TRUE; me->inLABEL = FALSE; HText_appendCharacter(me->text, c); } } else { if (me->style_change) { if ((c == '\n') || (c == ' ')) return; /* Ignore it */ UPDATE_STYLE; } if (c == '\n') { if (me->in_word) { if (HText_getLastChar(me->text) != ' ') { me->inP = TRUE; me->inLABEL = FALSE; HText_appendCharacter(me->text, ' '); } me->in_word = NO; } } else if (c == ' ' || c == '\t') { if (HText_getLastChar(me->text) != ' ') { me->inP = TRUE; me->inLABEL = FALSE; HText_appendCharacter(me->text, ' '); } } else if (c == '\r') { /* ignore */ } else { me->inP = TRUE; me->inLABEL = FALSE; HText_appendCharacter(me->text, c); me->in_word = YES; } } } /* end second switch */ if (c == '\n' || c == '\t') { HText_setLastChar(me->text, ' '); /* set it to a generic seperater */ /* * \r's are ignored. In order to keep collapsing spaces * correctly we must default back to the previous * seperater if there was one */ } else if (c == '\r' && HText_getLastChar(me->text) == ' ') { HText_setLastChar(me->text, ' '); /* set it to a generic seperater */ } else { HText_setLastChar(me->text, c); }}/* String handling** ---------------**** This is written separately from put_character because the loop can** in some cases be promoted to a higher function call level for speed.*/PUBLIC void HTML_put_string ARGS2(HTStructured *, me, CONST char *, s){ if (LYMapsOnly || s == NULL) return; switch (me->sp[0].tag_number) { case HTML_COMMENT: break; /* Do Nothing */ case HTML_TITLE: HTChunkPuts(&me->title, s); break; case HTML_STYLE: HTChunkPuts(&me->style_block, s); break; case HTML_SCRIPT: HTChunkPuts(&me->script, s); break; case HTML_PRE: /* Formatted text */ case HTML_LISTING: /* Literal text */ case HTML_XMP: case HTML_PLAINTEXT: /* * We guarantee that the style is up-to-date in begin_litteral */ HText_appendText(me->text, s); break; case HTML_OBJECT: HTChunkPuts(&me->object, s); break; case HTML_TEXTAREA: HTChunkPuts(&me->textarea, s); break; case HTML_SELECT: case HTML_OPTION: HTChunkPuts(&me->option, s); break; case HTML_MATH: HTChunkPuts(&me->math, s); break; default: /* Free format text? */ if (!me->sp->style->freeFormat) { /* * If we are within a preformatted text style not caught * by the cases above (HTML_PRE or similar may not be the * last element pushed on the style stack). - kw */ HText_appendText(me->text, s); break; } else { CONST char *p = s; char c; if (me->style_change) { for (; *p && ((*p == '\n') || (*p == '\r') || (*p == ' ') || (*p == '\t')); p++) ; /* Ignore leaders */ if (!*p) return; UPDATE_STYLE; } for (; *p; p++) { if (*p == 13 && p[1] != 10) { /* * Treat any '\r' which is not followed by '\n' * as '\n', to account for macintosh lineend in * ALT attributes etc. - kw */ c = '\n'; } else { c = *p; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -