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

📄 renderer.c

📁 elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, elinks也是gentoo安装过程中默认使用的浏览器, 这是elinks源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* DOM Source Renderer */#define check_dom_node_source(renderer, str, len)	\	((renderer)->source <= (str) && (str) + (len) <= (renderer)->end)#define assert_source(renderer, str, len) \	assertm(check_dom_node_source(renderer, str, len), "renderer[%p : %p] str[%p : %p]", \		(renderer)->source, (renderer)->end, (str), (str) + (len))static inline voidrender_dom_flush(struct dom_renderer *renderer, unsigned char *string){	struct screen_char *template = &renderer->styles[DOM_NODE_TEXT];	int length = string - renderer->position;	assert_source(renderer, renderer->position, 0);	assert_source(renderer, string, 0);	if (length <= 0) return;	render_dom_text(renderer, template, renderer->position, length);	renderer->position = string;	assert_source(renderer, renderer->position, 0);}static inline voidrender_dom_node_text(struct dom_renderer *renderer, struct screen_char *template,		     struct dom_node *node){	unsigned char *string = node->string.string;	int length = node->string.length;	if (node->type == DOM_NODE_ENTITY_REFERENCE) {		string -= 1;		length += 2;	}	if (check_dom_node_source(renderer, string, length)) {		render_dom_flush(renderer, string);		renderer->position = string + length;		assert_source(renderer, renderer->position, 0);	}	render_dom_text(renderer, template, string, length);}#ifdef HAVE_REGEX_Hstatic inline voidrender_dom_node_enhanced_text(struct dom_renderer *renderer, struct dom_node *node){	regex_t *regex = &renderer->url_regex;	regmatch_t regmatch;	unsigned char *string = node->string.string;	int length = node->string.length;	struct screen_char *template = &renderer->styles[node->type];	unsigned char *alloc_string;	if (check_dom_node_source(renderer, string, length)) {		render_dom_flush(renderer, string);		renderer->position = string + length;		assert_source(renderer, renderer->position, 0);	}	alloc_string = memacpy(string, length);	if (alloc_string)		string = alloc_string;	while (length > 0 && !regexec(regex, string, 1, &regmatch, 0)) {		int matchlen = regmatch.rm_eo - regmatch.rm_so;		int offset = regmatch.rm_so;		if (!matchlen || offset < 0 || regmatch.rm_eo > length)			break;		if (offset > 0)			render_dom_text(renderer, template, string, offset);		string += offset;		length -= offset;		add_dom_link(renderer, string, matchlen);		length -= matchlen;		string += matchlen;	}	if (length > 0)		render_dom_text(renderer, template, string, length);	mem_free_if(alloc_string);}#endifstatic voidrender_dom_node_source(struct dom_stack *stack, struct dom_node *node, void *data){	struct dom_renderer *renderer = stack->current->data;	assert(node && renderer && renderer->document);#ifdef HAVE_REGEX_H	if (renderer->find_url	    && (node->type == DOM_NODE_TEXT		|| node->type == DOM_NODE_CDATA_SECTION		|| node->type == DOM_NODE_COMMENT)) {		render_dom_node_enhanced_text(renderer, node);		return;	}#endif	render_dom_node_text(renderer, &renderer->styles[node->type], node);}/* This callback is also used for rendering processing instruction nodes.  */static voidrender_dom_element_source(struct dom_stack *stack, struct dom_node *node, void *data){	struct dom_renderer *renderer = stack->current->data;	assert(node && renderer && renderer->document);	render_dom_node_text(renderer, &renderer->styles[node->type], node);}static voidrender_dom_element_end_source(struct dom_stack *stack, struct dom_node *node, void *data){	struct dom_renderer *renderer = stack->current->data;	struct dom_stack_state *state = get_dom_stack_top(stack);	struct sgml_parser_state *pstate = get_dom_stack_state_data(stack->contexts[0], state);	struct dom_scanner_token *token = &pstate->end_token;	unsigned char *string = token->string.string;	int length = token->string.length;	assert(node && renderer && renderer->document);	if (!string || !length)		return;	if (check_dom_node_source(renderer, string, length)) {		render_dom_flush(renderer, string);		renderer->position = string + length;		assert_source(renderer, renderer->position, 0);	}	render_dom_text(renderer, &renderer->styles[node->type], string, length);}static voidset_base_uri(struct dom_renderer *renderer, unsigned char *value, size_t valuelen){	unsigned char *href = memacpy(value, valuelen);	unsigned char *uristring;	struct uri *uri;	if (!href) return;	uristring = join_urls(renderer->base_uri, href);	mem_free(href);	if (!uristring) return;	uri = get_uri(uristring, 0);	mem_free(uristring);	if (!uri) return;	done_uri(renderer->base_uri);	renderer->base_uri = uri;}static voidrender_dom_attribute_source(struct dom_stack *stack, struct dom_node *node, void *data){	struct dom_renderer *renderer = stack->current->data;	struct screen_char *template = &renderer->styles[node->type];	assert(node && renderer->document);	render_dom_node_text(renderer, template, node);	if (is_dom_string_set(&node->data.attribute.value)) {		int quoted = node->data.attribute.quoted == 1;		unsigned char *value = node->data.attribute.value.string - quoted;		int valuelen = node->data.attribute.value.length + quoted * 2;		if (check_dom_node_source(renderer, value, 0)) {			render_dom_flush(renderer, value);			renderer->position = value + valuelen;			assert_source(renderer, renderer->position, 0);		}		if (node->data.attribute.reference		    && valuelen - quoted * 2 > 0) {			int skips;			/* Need to flush the first quoting delimiter and any			 * leading whitespace so that the renderers x position			 * is at the start of the value string. */			for (skips = 0; skips < valuelen; skips++) {				if ((quoted && skips == 0)				    || isspace(value[skips])				    || value[skips] < ' ')					continue;				break;			}			if (skips > 0) {				render_dom_text(renderer, template, value, skips);				value    += skips;				valuelen -= skips;			}			/* Figure out what should be skipped after the actual			 * link text. */			for (skips = 0; skips < valuelen; skips++) {				if ((quoted && skips == 0)				    || isspace(value[valuelen - skips - 1])				    || value[valuelen - skips - 1] < ' ')					continue;				break;			}			if (renderer->doctype == SGML_DOCTYPE_HTML			    && node->data.attribute.type == HTML_ATTRIBUTE_HREF			    && node->parent->data.element.type == HTML_ELEMENT_BASE) {				set_base_uri(renderer, value, valuelen - skips);			}			add_dom_link(renderer, value, valuelen - skips);			if (skips > 0) {				value += valuelen - skips;				render_dom_text(renderer, template, value, skips);			}		} else {			render_dom_text(renderer, template, value, valuelen);		}	}}static voidrender_dom_cdata_source(struct dom_stack *stack, struct dom_node *node, void *data){	struct dom_renderer *renderer = stack->current->data;	unsigned char *string = node->string.string;	assert(node && renderer && renderer->document);	/* Highlight the 'CDATA' part of <![CDATA[ if it is there. */	if (check_dom_node_source(renderer, string - 6, 6)) {		render_dom_flush(renderer, string - 6);		render_dom_text(renderer, &renderer->styles[DOM_NODE_ATTRIBUTE], string - 6, 5);		renderer->position = string - 1;		assert_source(renderer, renderer->position, 0);	}	render_dom_node_text(renderer, &renderer->styles[node->type], node);}static voidrender_dom_document_end(struct dom_stack *stack, struct dom_node *node, void *data){	struct dom_renderer *renderer = stack->current->data;	/* If there are no non-element nodes after the last element node make	 * sure that we flush to the end of the cache entry source including	 * the '>' of the last element tag if it has one. (bug 519) */	if (check_dom_node_source(renderer, renderer->position, 0)) {		render_dom_flush(renderer, renderer->end);	}}static struct dom_stack_context_info dom_source_renderer_context_info = {	/* Object size: */			0,	/* Push: */	{		/*				*/ NULL,		/* DOM_NODE_ELEMENT		*/ render_dom_element_source,		/* DOM_NODE_ATTRIBUTE		*/ render_dom_attribute_source,		/* DOM_NODE_TEXT		*/ render_dom_node_source,		/* DOM_NODE_CDATA_SECTION	*/ render_dom_cdata_source,		/* DOM_NODE_ENTITY_REFERENCE	*/ render_dom_node_source,		/* DOM_NODE_ENTITY		*/ render_dom_node_source,		/* DOM_NODE_PROC_INSTRUCTION	*/ render_dom_element_source,		/* DOM_NODE_COMMENT		*/ render_dom_node_source,		/* DOM_NODE_DOCUMENT		*/ NULL,		/* DOM_NODE_DOCUMENT_TYPE	*/ render_dom_node_source,		/* DOM_NODE_DOCUMENT_FRAGMENT	*/ render_dom_node_source,		/* DOM_NODE_NOTATION		*/ render_dom_node_source,	},	/* Pop: */	{		/*				*/ NULL,		/* DOM_NODE_ELEMENT		*/ render_dom_element_end_source,		/* DOM_NODE_ATTRIBUTE		*/ NULL,		/* DOM_NODE_TEXT		*/ NULL,		/* DOM_NODE_CDATA_SECTION	*/ NULL,		/* DOM_NODE_ENTITY_REFERENCE	*/ NULL,		/* DOM_NODE_ENTITY		*/ NULL,		/* DOM_NODE_PROC_INSTRUCTION	*/ NULL,		/* DOM_NODE_COMMENT		*/ NULL,		/* DOM_NODE_DOCUMENT		*/ render_dom_document_end,		/* DOM_NODE_DOCUMENT_TYPE	*/ NULL,		/* DOM_NODE_DOCUMENT_FRAGMENT	*/ NULL,		/* DOM_NODE_NOTATION		*/ NULL,	}};/* Shared multiplexor between renderers */voidrender_dom_document(struct cache_entry *cached, struct document *document,		    struct string *buffer){	unsigned char *head = empty_string_or_(cached->head);	struct dom_node *root;	struct dom_renderer renderer;	struct conv_table *convert_table;	struct sgml_parser *parser;	unsigned char *string = struri(cached->uri);	size_t length = strlen(string);	struct dom_string uri = INIT_DOM_STRING(string, length);	struct dom_string source = INIT_DOM_STRING(buffer->source, buffer->length);	assert(document->options.plain);	convert_table = get_convert_table(head, document->options.cp,					  document->options.assume_cp,					  &document->cp,					  &document->cp_status,					  document->options.hard_assume);	init_dom_renderer(&renderer, document, buffer, convert_table);	document->bgcolor = document->options.default_bg;	if (!strcasecmp("application/rss+xml", cached->content_type)) {		renderer.doctype = SGML_DOCTYPE_RSS;	} else if (!strcasecmp("application/xbel+xml", cached->content_type)		   || !strcasecmp("application/x-xbel", cached->content_type)		   || !strcasecmp("application/xbel", cached->content_type)) {		renderer.doctype = SGML_DOCTYPE_XBEL;	} else {		assertm(!strcasecmp("text/html", cached->content_type)			|| !strcasecmp("application/xhtml+xml", cached->content_type),			"Couldn't resolve doctype '%s'", cached->content_type);		renderer.doctype = SGML_DOCTYPE_HTML;	}	parser = init_sgml_parser(SGML_PARSER_STREAM, renderer.doctype, &uri);	if (!parser) return;	add_dom_stack_context(&parser->stack, &renderer,			      &dom_source_renderer_context_info);	root = parse_sgml(parser, &source);	if (root) {		assert(parser->stack.depth == 1);		get_dom_stack_top(&parser->stack)->immutable = 0;		/* For SGML_PARSER_STREAM this will free the DOM		 * root node. */		pop_dom_node(&parser->stack);	}#ifdef HAVE_REGEX_H	if (renderer.find_url)		regfree(&renderer.url_regex);#endif	done_uri(renderer.base_uri);	done_sgml_parser(parser);}

⌨️ 快捷键说明

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