⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.c

📁 elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, elinks也是gentoo安装过程中默认使用的浏览器, 这是elinks源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		}element:		endingtag = *name == '/'; name += endingtag; namelen -= endingtag;		if (!endingtag && html_context->putsp == HTML_SPACE_ADD && !html_top.invisible)			put_chrs(html_context, " ", 1);		put_chrs(html_context, base_pos, html - base_pos);		if (!html_is_preformatted() && !endingtag && html_context->putsp == HTML_SPACE_NORMAL) {			unsigned char *ee = end;			unsigned char *nm;			while (!parse_element(ee, eof, &nm, NULL, NULL, &ee))				if (*nm == '/')					goto ng;			if (ee < eof && isspace(*ee)) {				put_chrs(html_context, " ", 1);			}ng:;		}		html = process_element(name, namelen, endingtag, end, html, eof, attr, html_context);	}	if (noupdate) put_chrs(html_context, base_pos, html - base_pos);	ln_break(html_context, 1);	/* Restore the part in case the html_context was trashed in the last	 * iteration so that when destroying the stack in the caller we still	 * get the right part pointer. */	html_context->part = part;	html_context->putsp = HTML_SPACE_SUPPRESS;	html_context->position = 0;	html_context->was_br = 0;}static unsigned char *start_element(struct element_info *ei,              unsigned char *name, int namelen,              unsigned char *html,              unsigned char *eof, unsigned char *attr,              struct html_context *html_context){#define ELEMENT_RENDER_PROLOGUE \	ln_break(html_context, ei->linebreak); \	a = get_attr_val(attr, "id", html_context->options); \	if (a) { \		html_context->special_f(html_context, SP_TAG, a); \		mem_free(a); \	}	unsigned char *a;	struct par_attrib old_format;	int restore_format;#ifdef CONFIG_CSS	struct css_selector *selector = NULL;#endif	if (html_top.type == ELEMENT_WEAK) {		kill_html_stack_item(html_context, &html_top);	}	/* We try to process nested <script> if we didn't process the parent	 * one. */	if (html_top.invisible	    && (ei->func != html_script || html_top.invisible < 2)) {		ELEMENT_RENDER_PROLOGUE		return html;	}	restore_format = html_is_preformatted();	old_format = par_format;	/* Support for <meta refresh="..."> inside <body>. (bug 700) */	if (ei->func == html_meta && html_context->was_body) {		html_handle_body_meta(html_context, name - 1, eof);		html_context->was_body = 0;	}#ifdef CONFIG_CSS	if (ei->func == html_style && html_context->options->css_enable) {		css_parse_stylesheet(&html_context->css_styles,				     html_context->base_href, html, eof);	}#endif	if (ei->type == ELEMENT_TYPE_NON_NESTABLE	    || ei->type == ELEMENT_TYPE_LI) {		struct html_element *e;		if (ei->type == ELEMENT_TYPE_NON_NESTABLE) {			foreach (e, html_context->stack) {				if (e->type < ELEMENT_KILLABLE) break;				if (is_block_element(e) || is_inline_element(ei)) break;			}		} else foreach (e, html_context->stack) {			if (is_block_element(e) && is_inline_element(ei)) break;			if (e->type < ELEMENT_KILLABLE) break;			if (!strlcasecmp(e->name, e->namelen, name, namelen)) break;		}		if (!strlcasecmp(e->name, e->namelen, name, namelen)) {			while (e->prev != (void *) &html_context->stack)				kill_html_stack_item(html_context, e->prev);			if (e->type > ELEMENT_IMMORTAL)				kill_html_stack_item(html_context, e);		}	}	if (ei->type != ELEMENT_TYPE_NON_PAIRABLE) {		html_stack_dup(html_context, ELEMENT_KILLABLE);		html_top.name = name;		html_top.namelen = namelen;		html_top.options = attr;		html_top.linebreak = ei->linebreak;#ifdef CONFIG_ECMASCRIPT		if (has_attr(attr, "onClick", html_context->options)) {			/* XXX: Put something better to format.link. --pasky */			mem_free_set(&format.link, stracpy("javascript:void(0);"));			mem_free_set(&format.target, stracpy(html_context->base_target));			format.style.fg = format.clink;			html_top.pseudo_class = ELEMENT_LINK;			mem_free_set(&format.title, stracpy("onClick placeholder"));			/* Er. I know. Well, double html_focusable()s shouldn't			 * really hurt. */			html_focusable(html_context, attr);		}#endif	}#ifdef CONFIG_CSS	if (html_top.options && html_context->options->css_enable) {		/* XXX: We should apply CSS otherwise as well, but that'll need		 * some deeper changes in order to have options filled etc.		 * Probably just applying CSS from more places, since we		 * usually have type != ELEMENT_TYPE_NESTABLE when we either (1)		 * rescan on your own from somewhere else (2) html_stack_dup()		 * in our own way.  --pasky */		/* Call it now to gain some of the stuff which might affect		 * formatting of some elements. */		/* FIXME: The caching of the CSS selector is broken, since t can		 * lead to wrong styles being applied to following elements, so		 * disabled for now. */		selector = get_css_selector_for_element(html_context, &html_top,							&html_context->css_styles,							&html_context->stack);		if (selector) {			apply_css_selector_style(html_context, &html_top, selector);			done_css_selector(selector);		}	}	/* Now this was the reason for this whole funny ELEMENT_RENDER_PROLOGUE	 * bussiness. Only now we have the definitive linebreak value, since	 * that's what the display: property plays with. */#endif	ELEMENT_RENDER_PROLOGUE	if (ei->func) ei->func(html_context, attr, html, eof, &html);#ifdef CONFIG_CSS	if (selector && html_top.options) {		/* Call it now to override default colors of the elements. */		selector = get_css_selector_for_element(html_context, &html_top,							&html_context->css_styles,							&html_context->stack);		if (selector) {			apply_css_selector_style(html_context, &html_top, selector);			done_css_selector(selector);		}	}#endif	if (ei->func != html_br) html_context->was_br = 0;	if (restore_format) par_format = old_format;	return html;#undef ELEMENT_RENDER_PROLOGUE}static unsigned char *end_element(struct element_info *ei,            unsigned char *name, int namelen,            unsigned char *html,            unsigned char *eof, unsigned char *attr,            struct html_context *html_context){	struct html_element *e, *elt;	int lnb = 0;	int kill = 0;	if (ei->func == html_xmp) html_context->was_xmp = 0;	html_context->was_br = 0;	if (ei->type == ELEMENT_TYPE_NON_PAIRABLE	    || ei->type == ELEMENT_TYPE_LI)		return html;	/* Apply background color from the <HTML> element. (bug 696) */	if (ei->func == html_html	    && html_top.type >= ELEMENT_KILLABLE	    && !html_context->was_body_background)		html_apply_canvas_bgcolor(html_context);	/* dump_html_stack(html_context); */	foreach (e, html_context->stack) {		if (is_block_element(e) && is_inline_element(ei)) kill = 1;		if (strlcasecmp(e->name, e->namelen, name, namelen)) {			if (e->type < ELEMENT_KILLABLE)				break;			else				continue;		}		if (kill) {			kill_html_stack_item(html_context, e);			break;		}		for (elt = e;		     elt != (void *) &html_context->stack;		     elt = elt->prev)			if (elt->linebreak > lnb)				lnb = elt->linebreak;		/* This hack forces a line break after a list end. It is needed		 * when ending a list with the last <li> having no text the		 * line_breax is 2 so the ending list's linebreak will be		 * ignored when calling ln_break(). */		if (html_context->was_li)			html_context->line_breax = 0;		ln_break(html_context, lnb);		while (e->prev != (void *) &html_context->stack)			kill_html_stack_item(html_context, e->prev);		kill_html_stack_item(html_context, e);		break;	}	/* dump_html_stack(html_context); */	return html;}static unsigned char *process_element(unsigned char *name, int namelen, int endingtag,                unsigned char *html, unsigned char *prev_html,                unsigned char *eof, unsigned char *attr,                struct html_context *html_context){	struct element_info *ei;#ifndef USE_FASTFIND	{		struct element_info elem;		unsigned char tmp;		tmp = name[namelen];		name[namelen] = '\0';		elem.name = name;		ei = bsearch(&elem, elements, NUMBER_OF_TAGS, sizeof(elem), compar);		name[namelen] = tmp;	}#else	ei = (struct element_info *) fastfind_search(&ff_tags_index, name, namelen);#endif	if (html_context->was_xmp) {		if (!ei || ei->func != html_xmp || !endingtag) {			put_chrs(html_context, "<", 1);			return prev_html + 1;		}	}	if (!ei) return html;	if (!endingtag) {		return start_element(ei, name, namelen, html, eof, attr, html_context);	} else {		return end_element(ei, name, namelen, html, eof, attr, html_context);	}}voidscan_http_equiv(unsigned char *s, unsigned char *eof, struct string *head,		struct string *title, struct document_options *options){	unsigned char *name, *attr, *he, *c;	int namelen;	if (title && !init_string(title)) return;	add_char_to_string(head, '\n');se:	while (s < eof && *s != '<') {sp:		s++;	}	if (s >= eof) return;	if (s + 2 <= eof && (s[1] == '!' || s[1] == '?')) {		s = skip_comment(s, eof);		goto se;	}	if (parse_element(s, eof, &name, &namelen, &attr, &s)) goto sp;ps:	if (!strlcasecmp(name, namelen, "HEAD", 4)) goto se;	if (!strlcasecmp(name, namelen, "/HEAD", 5)) return;	if (!strlcasecmp(name, namelen, "BODY", 4)) return;	if (title && !title->length && !strlcasecmp(name, namelen, "TITLE", 5)) {		unsigned char *s1;xse:		s1 = s;		while (s < eof && *s != '<') {xsp:			s++;		}		if (s - s1)			add_bytes_to_string(title, s1, s - s1);		if (s >= eof) goto se;		if (s + 2 <= eof && (s[1] == '!' || s[1] == '?')) {			s = skip_comment(s, eof);			goto xse;		}		if (parse_element(s, eof, &name, &namelen, &attr, &s)) {			s1 = s;			goto xsp;		}		clr_spaces(title->source);		goto ps;	}	if (strlcasecmp(name, namelen, "META", 4)) goto se;	he = get_attr_val(attr, "charset", options);	if (he) {		add_to_string(head, "Charset: ");		add_to_string(head, he);		mem_free(he);	}	he = get_attr_val(attr, "http-equiv", options);	if (!he) goto se;	add_to_string(head, he);	mem_free(he);	c = get_attr_val(attr, "content", options);	if (c) {		add_to_string(head, ": ");		add_to_string(head, c);	        mem_free(c);	}	add_crlf_to_string(head);	goto se;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -