mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Split the parser interface up into init, parser and done steps
The parser will eventually have to live across parses for incremental renderering. Also the renderer and parser need to share the DOM stack.
This commit is contained in:
parent
83dca03a27
commit
3a9cba5695
@ -691,13 +691,20 @@ render_dom_document(struct cache_entry *cached, struct document *document,
|
|||||||
struct string *buffer)
|
struct string *buffer)
|
||||||
{
|
{
|
||||||
unsigned char *head = empty_string_or_(cached->head);
|
unsigned char *head = empty_string_or_(cached->head);
|
||||||
struct dom_node *root = parse_sgml(cached, document, buffer);
|
struct dom_node *root;
|
||||||
struct dom_renderer renderer;
|
struct dom_renderer renderer;
|
||||||
struct conv_table *convert_table;
|
struct conv_table *convert_table;
|
||||||
dom_stack_callback_T *callbacks = dom_source_renderer_callbacks;
|
dom_stack_callback_T *callbacks = dom_source_renderer_callbacks;
|
||||||
|
struct sgml_parser *parser;
|
||||||
struct dom_stack stack;
|
struct dom_stack stack;
|
||||||
|
|
||||||
assert(document->options.plain);
|
assert(document->options.plain);
|
||||||
|
|
||||||
|
parser = init_sgml_parser(cached, document);
|
||||||
|
if (!parser) return;
|
||||||
|
|
||||||
|
root = parse_sgml(parser, buffer);
|
||||||
|
done_sgml_parser(parser);
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
|
|
||||||
convert_table = get_convert_table(head, document->options.cp,
|
convert_table = get_convert_table(head, document->options.cp,
|
||||||
|
@ -292,43 +292,49 @@ parse_sgml_document(struct dom_stack *stack, struct scanner *scanner)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
struct sgml_parser *
|
||||||
init_sgml_parser(struct sgml_parser *parser, struct document *document,
|
init_sgml_parser(struct cache_entry *cached, struct document *document)
|
||||||
struct cache_entry *cache_entry, struct sgml_info *info,
|
{
|
||||||
struct string *buffer)
|
size_t obj_size = sizeof(struct sgml_parser_state);
|
||||||
|
struct sgml_parser *parser;
|
||||||
|
|
||||||
|
parser = mem_calloc(1, sizeof(*parser));
|
||||||
|
if (!parser) return NULL;
|
||||||
|
|
||||||
|
parser->document = document;
|
||||||
|
parser->cache_entry = cached;
|
||||||
|
parser->info = &sgml_html_info;
|
||||||
|
|
||||||
|
init_dom_stack(&parser->stack, parser, parser->info->callbacks, obj_size);
|
||||||
|
|
||||||
|
if (document->options.plain)
|
||||||
|
parser->flags |= SGML_PARSER_ADD_ELEMENT_ENDS;
|
||||||
|
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
done_sgml_parser(struct sgml_parser *parser)
|
||||||
|
{
|
||||||
|
done_dom_stack(&parser->stack);
|
||||||
|
mem_free(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Make it possible to push variable number of strings (even nested
|
||||||
|
* while parsing another string) so that we can feed back output of stuff
|
||||||
|
* like ECMAScripts document.write(). */
|
||||||
|
struct dom_node *
|
||||||
|
parse_sgml(struct sgml_parser *parser, struct string *buffer)
|
||||||
{
|
{
|
||||||
unsigned char *source = buffer->source;
|
unsigned char *source = buffer->source;
|
||||||
unsigned char *end = source + buffer->length;
|
unsigned char *end = source + buffer->length;
|
||||||
|
|
||||||
memset(parser, 0, sizeof(*parser));
|
|
||||||
|
|
||||||
init_scanner(&parser->scanner, &sgml_scanner_info, source, end);
|
init_scanner(&parser->scanner, &sgml_scanner_info, source, end);
|
||||||
|
|
||||||
parser->document = document;
|
parser->root = add_sgml_document(&parser->stack, parser->document->uri);
|
||||||
parser->cache_entry = cache_entry;
|
if (parser->root) {
|
||||||
parser->info = info;
|
parse_sgml_document(&parser->stack, &parser->scanner);
|
||||||
|
|
||||||
if (document->options.plain)
|
|
||||||
parser->flags |= SGML_PARSER_ADD_ELEMENT_ENDS;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dom_node *
|
|
||||||
parse_sgml(struct cache_entry *cached, struct document *document,
|
|
||||||
struct string *buffer)
|
|
||||||
{
|
|
||||||
struct dom_stack stack;
|
|
||||||
struct sgml_parser parser;
|
|
||||||
size_t obj_size = sizeof(struct sgml_parser_state);
|
|
||||||
|
|
||||||
init_sgml_parser(&parser, document, cached, &sgml_html_info, buffer);
|
|
||||||
init_dom_stack(&stack, &parser, parser.info->callbacks, obj_size);
|
|
||||||
|
|
||||||
parser.root = add_sgml_document(&stack, document->uri);
|
|
||||||
if (parser.root) {
|
|
||||||
parse_sgml_document(&stack, &parser.scanner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
done_dom_stack(&stack);
|
return parser->root;
|
||||||
|
|
||||||
return parser.root;
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#define EL__DOCUMENT_SGML_PARSER_H
|
#define EL__DOCUMENT_SGML_PARSER_H
|
||||||
|
|
||||||
#include "document/dom/node.h"
|
#include "document/dom/node.h"
|
||||||
|
#include "document/dom/stack.h"
|
||||||
#include "document/sgml/sgml.h"
|
#include "document/sgml/sgml.h"
|
||||||
#include "util/scanner.h"
|
#include "util/scanner.h"
|
||||||
|
|
||||||
@ -24,13 +25,18 @@ struct sgml_parser {
|
|||||||
struct dom_node *root;
|
struct dom_node *root;
|
||||||
|
|
||||||
struct scanner scanner;
|
struct scanner scanner;
|
||||||
|
struct dom_stack stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sgml_parser_state {
|
struct sgml_parser_state {
|
||||||
struct sgml_node_info *info;
|
struct sgml_node_info *info;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dom_node *
|
struct sgml_parser *
|
||||||
parse_sgml(struct cache_entry *cached, struct document *document, struct string *buffer);
|
init_sgml_parser(struct cache_entry *cached, struct document *document);
|
||||||
|
|
||||||
|
void done_sgml_parser(struct sgml_parser *parser);
|
||||||
|
|
||||||
|
struct dom_node *parse_sgml(struct sgml_parser *parser, struct string *buffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user