diff --git a/src/document/dom/renderer.c b/src/document/dom/renderer.c
index 08462ef57..d8e5d8de3 100644
--- a/src/document/dom/renderer.c
+++ b/src/document/dom/renderer.c
@@ -28,6 +28,7 @@
#include "util/box.h"
#include "util/error.h"
#include "util/memory.h"
+#include "util/scanner.h"
#include "util/snprintf.h"
#include "util/string.h"
@@ -387,7 +388,7 @@ add_dom_link(struct dom_renderer *renderer, unsigned char *string, int length)
static struct dom_node *
render_dom_tree(struct dom_stack *stack, struct dom_node *node, void *data)
{
- struct dom_renderer *renderer = stack->data;
+ struct dom_renderer *renderer = stack->renderer;
struct screen_char *template = &renderer->styles[node->type];
unsigned char *name, *value;
@@ -407,7 +408,7 @@ render_dom_tree(struct dom_stack *stack, struct dom_node *node, void *data)
static struct dom_node *
render_dom_tree_id_leaf(struct dom_stack *stack, struct dom_node *node, void *data)
{
- struct dom_renderer *renderer = stack->data;
+ struct dom_renderer *renderer = stack->renderer;
struct document *document = renderer->document;
struct screen_char *template = &renderer->styles[node->type];
unsigned char *name, *value, *id;
@@ -430,7 +431,7 @@ render_dom_tree_id_leaf(struct dom_stack *stack, struct dom_node *node, void *da
static struct dom_node *
render_dom_tree_leaf(struct dom_stack *stack, struct dom_node *node, void *data)
{
- struct dom_renderer *renderer = stack->data;
+ struct dom_renderer *renderer = stack->renderer;
struct document *document = renderer->document;
struct screen_char *template = &renderer->styles[node->type];
unsigned char *name, *value;
@@ -452,7 +453,7 @@ render_dom_tree_leaf(struct dom_stack *stack, struct dom_node *node, void *data)
static struct dom_node *
render_dom_tree_branch(struct dom_stack *stack, struct dom_node *node, void *data)
{
- struct dom_renderer *renderer = stack->data;
+ struct dom_renderer *renderer = stack->renderer;
struct document *document = renderer->document;
struct screen_char *template = &renderer->styles[node->type];
unsigned char *name, *id;
@@ -536,7 +537,7 @@ render_dom_node_text(struct dom_renderer *renderer, struct screen_char *template
static struct dom_node *
render_dom_node_source(struct dom_stack *stack, struct dom_node *node, void *data)
{
- struct dom_renderer *renderer = stack->data;
+ struct dom_renderer *renderer = stack->renderer;
assert(node && renderer && renderer->document);
@@ -550,7 +551,7 @@ render_dom_node_source(struct dom_stack *stack, struct dom_node *node, void *dat
static struct dom_node *
render_dom_proc_instr_source(struct dom_stack *stack, struct dom_node *node, void *data)
{
- struct dom_renderer *renderer = stack->data;
+ struct dom_renderer *renderer = stack->renderer;
unsigned char *value;
int valuelen;
@@ -577,7 +578,7 @@ render_dom_proc_instr_source(struct dom_stack *stack, struct dom_node *node, voi
static struct dom_node *
render_dom_element_source(struct dom_stack *stack, struct dom_node *node, void *data)
{
- struct dom_renderer *renderer = stack->data;
+ struct dom_renderer *renderer = stack->renderer;
assert(node && renderer && renderer->document);
@@ -587,27 +588,61 @@ render_dom_element_source(struct dom_stack *stack, struct dom_node *node, void *
}
static struct dom_node *
-render_dom_attribute_source(struct dom_stack *stack, struct dom_node *node, void *data)
+render_dom_element_end_source(struct dom_stack *stack, struct dom_node *node, void *data)
{
- struct dom_stack_state *state = get_dom_stack_parent(stack);
- struct dom_renderer *renderer = stack->data;
- struct screen_char *template = &renderer->styles[node->type];
- struct dom_node *attribute = NULL;
- int i;
+ struct dom_renderer *renderer = stack->renderer;
+ struct sgml_parser_state *pstate = data;
+ struct scanner_token *token = &pstate->end_token;
+ unsigned char *string = token->string;
+ int length = token->length;
- assert(node && renderer->document);
- assert(state && state->list);
+ assert(node && renderer && renderer->document);
- /* The attributes are sorted but we want them in the original order */
- foreach_dom_node(i, node, state->list) {
- if (node->string >= renderer->position
- && (!attribute || node->string < attribute->string))
- attribute = node;
+ if (!string || !length)
+ return node;
+
+ if (check_dom_node_source(renderer, string, length)) {
+ render_dom_flush(renderer, string);
+ renderer->position = string + length;
+ assert_source(renderer, renderer->position, 0);
}
- assert(attribute);
- node = attribute;
+ render_dom_text(renderer, &renderer->styles[node->type], string, length);
+ return node;
+}
+
+static struct dom_node *
+render_dom_attribute_source(struct dom_stack *stack, struct dom_node *node, void *data)
+{
+ struct dom_renderer *renderer = stack->renderer;
+ struct screen_char *template = &renderer->styles[node->type];
+
+ assert(node && renderer->document);
+
+#if 0
+ /* Disabled since the DOM source highlighter uses the stream parser and
+ * therefore the attributes is pushed to it in order. However, if/when
+ * we will support rendering (read saving) of loaded DOM trees this one
+ * small hack is needed to get the attributes in the original order. */
+ {
+ struct dom_stack_state *state = get_dom_stack_parent(stack);
+ struct dom_node *attribute = NULL;
+ int i;
+
+ assert(state && state->list);
+
+ /* The attributes are sorted but we want them in the original order */
+ foreach_dom_node(i, node, state->list) {
+ if (node->string >= renderer->position
+ && (!attribute || node->string < attribute->string))
+ attribute = node;
+ }
+
+ assert(attribute);
+ node = attribute;
+ }
+#endif
render_dom_node_text(renderer, template, node);
if (node->data.attribute.value) {
@@ -668,7 +703,7 @@ render_dom_attribute_source(struct dom_stack *stack, struct dom_node *node, void
return node;
}
-static dom_stack_callback_T dom_source_renderer_callbacks[DOM_NODES] = {
+static dom_stack_callback_T dom_source_renderer_push_callbacks[DOM_NODES] = {
/* */ NULL,
/* DOM_NODE_ELEMENT */ render_dom_element_source,
/* DOM_NODE_ATTRIBUTE */ render_dom_attribute_source,
@@ -684,6 +719,22 @@ static dom_stack_callback_T dom_source_renderer_callbacks[DOM_NODES] = {
/* DOM_NODE_NOTATION */ render_dom_node_source,
};
+static dom_stack_callback_T dom_source_renderer_pop_callbacks[DOM_NODES] = {
+ /* */ 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 */ NULL,
+ /* DOM_NODE_DOCUMENT_TYPE */ NULL,
+ /* DOM_NODE_DOCUMENT_FRAGMENT */ NULL,
+ /* DOM_NODE_NOTATION */ NULL,
+};
+
/* Shared multiplexor between renderers */
void
@@ -694,19 +745,10 @@ render_dom_document(struct cache_entry *cached, struct document *document,
struct dom_node *root;
struct dom_renderer renderer;
struct conv_table *convert_table;
- dom_stack_callback_T *callbacks = dom_source_renderer_callbacks;
struct sgml_parser *parser;
- struct dom_stack stack;
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;
-
convert_table = get_convert_table(head, document->options.cp,
document->options.assume_cp,
&document->cp,
@@ -714,11 +756,19 @@ render_dom_document(struct cache_entry *cached, struct document *document,
document->options.hard_assume);
init_dom_renderer(&renderer, document, buffer, convert_table);
- init_dom_stack(&stack, &renderer, callbacks, 0);
document->bgcolor = document->options.default_bg;
- walk_dom_nodes(&stack, root);
+ parser = init_sgml_parser(SGML_PARSER_STREAM, &renderer, cached,
+ document,
+ dom_source_renderer_push_callbacks,
+ dom_source_renderer_pop_callbacks);
+ if (!parser) return;
+
+ root = parse_sgml(parser, buffer);
+ done_sgml_parser(parser);
+ if (!root) return;
+
/* 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) */
@@ -727,5 +777,4 @@ render_dom_document(struct cache_entry *cached, struct document *document,
}
done_dom_node(root);
- done_dom_stack(&stack);
}
diff --git a/src/document/dom/stack.c b/src/document/dom/stack.c
index 560cb90d9..d1dc11a65 100644
--- a/src/document/dom/stack.c
+++ b/src/document/dom/stack.c
@@ -45,19 +45,23 @@ realloc_dom_stack_state_objects(struct dom_stack *stack)
}
void
-init_dom_stack(struct dom_stack *stack, void *data,
- dom_stack_callback_T callbacks[DOM_NODES],
+init_dom_stack(struct dom_stack *stack, void *parser, void *renderer,
+ dom_stack_callback_T push_callbacks[DOM_NODES],
+ dom_stack_callback_T pop_callbacks[DOM_NODES],
size_t object_size)
{
assert(stack);
memset(stack, 0, sizeof(*stack));
- stack->data = data;
+ stack->parser = parser;
+ stack->renderer = renderer;
stack->object_size = object_size;
- if (callbacks)
- memcpy(stack->callbacks, callbacks, DOM_STACK_CALLBACKS_SIZE);
+ if (push_callbacks)
+ memcpy(stack->push_callbacks, push_callbacks, DOM_STACK_CALLBACKS_SIZE);
+ if (pop_callbacks)
+ memcpy(stack->pop_callbacks, pop_callbacks, DOM_STACK_CALLBACKS_SIZE);
}
void
@@ -94,7 +98,6 @@ push_dom_node(struct dom_stack *stack, struct dom_node *node)
if (stack->object_size) {
unsigned char *state_objects;
- size_t offset = stack->depth * stack->object_size;
state_objects = realloc_dom_stack_state_objects(stack);
if (!state_objects) {
@@ -102,7 +105,7 @@ push_dom_node(struct dom_stack *stack, struct dom_node *node)
return NULL;
}
- state->data = (void *) &state_objects[offset];
+ state->depth = stack->depth;
}
state->node = node;
@@ -111,9 +114,11 @@ push_dom_node(struct dom_stack *stack, struct dom_node *node)
* in the callbacks */
stack->depth++;
- callback = stack->callbacks[node->type];
+ callback = stack->push_callbacks[node->type];
if (callback) {
- node = callback(stack, node, state->data);
+ void *state_data = get_dom_stack_state_data(stack, state);
+
+ node = callback(stack, node, state_data);
/* If the callback returned NULL pop the state immediately */
if (!node) {
@@ -130,26 +135,26 @@ static int
do_pop_dom_node(struct dom_stack *stack, struct dom_stack_state *parent)
{
struct dom_stack_state *state;
+ dom_stack_callback_T callback;
assert(stack);
if (!dom_stack_has_parents(stack)) return 0;
state = get_dom_stack_top(stack);
- if (state->callback) {
- /* Pass the node we are popping to and _not_ the state->node */
- state->callback(stack, parent->node, state->data);
+ callback = stack->pop_callbacks[state->node->type];
+ if (callback) {
+ void *state_data = get_dom_stack_state_data(stack, state);
+
+ callback(stack, state->node, state_data);
}
stack->depth--;
assert(stack->depth >= 0);
- if (stack->object_size && state->data) {
- size_t offset = stack->depth * stack->object_size;
+ if (stack->object_size) {
+ void *state_data = get_dom_stack_state_data(stack, state);
- /* I tried to use item->data here but it caused a memory
- * corruption bug on fm. This is also less trustworthy in that
- * the state->data pointer could have been mangled. --jonas */
- memset(&stack->state_objects[offset], 0, stack->object_size);
+ memset(state_data, 0, stack->object_size);
}
memset(state, 0, sizeof(*state));
@@ -170,16 +175,28 @@ void
pop_dom_nodes(struct dom_stack *stack, enum dom_node_type type,
unsigned char *string, uint16_t length)
{
- struct dom_stack_state *state, *parent;
- unsigned int pos;
+ struct dom_stack_state *state;
if (!dom_stack_has_parents(stack)) return;
- parent = search_dom_stack(stack, type, string, length);
- if (!parent) return;
+ state = search_dom_stack(stack, type, string, length);
+ if (state)
+ pop_dom_state(stack, type, state);
+}
+
+void
+pop_dom_state(struct dom_stack *stack, enum dom_node_type type,
+ struct dom_stack_state *target)
+{
+ struct dom_stack_state *state;
+ unsigned int pos;
+
+ if (!target) return;
+
+ if (!dom_stack_has_parents(stack)) return;
foreachback_dom_state (stack, state, pos) {
- if (do_pop_dom_node(stack, parent))
+ if (do_pop_dom_node(stack, target))
break;;
}
}
diff --git a/src/document/dom/stack.h b/src/document/dom/stack.h
index 1b6137eb8..b3d603ad5 100644
--- a/src/document/dom/stack.h
+++ b/src/document/dom/stack.h
@@ -24,14 +24,9 @@ struct dom_stack_state {
/* The index (in the list above) which are currently being handled. */
size_t index;
- /* A callback registered to be called when the node is popped. Used for
- * correctly highlighting ending elements (e.g. ). */
- dom_stack_callback_T callback;
-
- /* Parser specific data. For the SGML parser this holds DTD-oriented
- * info about the node (recorded in struct sgml_node_info). E.g.
- * whether an element node is optional. */
- void *data;
+ /* The depth of the state in the stack. This is amongst other things
+ * used to get the state object data. */
+ unsigned int depth;
};
/* The DOM stack is a convenient way to traverse DOM trees. Also it
@@ -42,14 +37,20 @@ struct dom_stack {
struct dom_stack_state *states;
size_t depth;
- /* This is one big array of parser specific objects which will be
- * assigned to the data member of the individual dom_stack_states. */
+ /* This is one big array of parser specific objects. */
+ /* The objects hold parser specific data. For the SGML parser this
+ * holds DTD-oriented info about the node (recorded in struct
+ * sgml_node_info). E.g. whether an element node is optional. */
unsigned char *state_objects;
size_t object_size;
- /* Parser and document specific stuff */
- dom_stack_callback_T callbacks[DOM_NODES];
- void *data;
+ /* Renderer specific callbacks for the streaming parser mode. */
+ dom_stack_callback_T push_callbacks[DOM_NODES];
+ dom_stack_callback_T pop_callbacks[DOM_NODES];
+
+ /* Data specific to the parser and renderer. */
+ void *renderer;
+ void *parser;
};
#define dom_stack_has_parents(nav) \
@@ -66,6 +67,9 @@ get_dom_stack_state(struct dom_stack *stack, int top_offset)
#define get_dom_stack_parent(nav) get_dom_stack_state(nav, 1)
#define get_dom_stack_top(nav) get_dom_stack_state(nav, 0)
+#define get_dom_stack_state_data(stack, state) \
+ ((void *) &(stack)->state_objects[(state)->depth * (stack)->object_size])
+
/* The state iterators do not include the bottom state */
#define foreach_dom_state(nav, item, pos) \
@@ -84,6 +88,7 @@ search_dom_stack(struct dom_stack *stack, enum dom_node_type type,
struct dom_stack_state *state;
int pos;
+ /* FIXME: Take node subtype and compare if non-zero or something. */
foreachback_dom_state (stack, state, pos) {
struct dom_node *parent = state->node;
@@ -102,8 +107,9 @@ search_dom_stack(struct dom_stack *stack, enum dom_node_type type,
/* The @object_size arg tells whether the stack should allocate objects for each
* state to be assigned to the state's @data member. Zero means no state data should
* be allocated. */
-void init_dom_stack(struct dom_stack *stack, void *data,
- dom_stack_callback_T callbacks[DOM_NODES],
+void init_dom_stack(struct dom_stack *stack, void *parser, void *renderer,
+ dom_stack_callback_T push_callbacks[DOM_NODES],
+ dom_stack_callback_T pop_callbacks[DOM_NODES],
size_t object_size);
void done_dom_stack(struct dom_stack *stack);
@@ -118,6 +124,11 @@ void pop_dom_node(struct dom_stack *stack);
void pop_dom_nodes(struct dom_stack *stack, enum dom_node_type type,
unsigned char *string, uint16_t length);
+/* Pop all stack states until a specific state is reached. */
+void
+pop_dom_state(struct dom_stack *stack, enum dom_node_type type,
+ struct dom_stack_state *target);
+
/* Visit each node in the tree rooted at @root pre-order */
void walk_dom_nodes(struct dom_stack *stack, struct dom_node *root);
diff --git a/src/document/sgml/html/html.c b/src/document/sgml/html/html.c
index b1df7d4df..63157fc56 100644
--- a/src/document/sgml/html/html.c
+++ b/src/document/sgml/html/html.c
@@ -37,66 +37,7 @@ static struct sgml_node_info html_elements[HTML_ELEMENTS] = {
};
-static struct dom_node *
-add_html_element_end_node(struct dom_stack *stack, struct dom_node *node, void *data)
-{
- struct sgml_parser *parser = stack->data;
- struct dom_node *parent;
- struct scanner_token *token;
-
- assert(stack && parser && node);
- assert(dom_stack_has_parents(stack));
-
- /* Are we the actual node being popped? */
- if (node != get_dom_stack_top(stack)->node)
- return NULL;
-
- parent = get_dom_stack_parent(stack)->node;
- token = get_scanner_token(&parser->scanner);
-
- assertm(token, "No token found in callback");
- assertm(token->type == SGML_TOKEN_ELEMENT_END, "Bad token found in callback");
-
- if (!token->length) return NULL;
-
- return add_dom_element(parent, token->string, token->length);
-}
-
-/* TODO: We need to handle ascending of
and "
text1
text2" using data - * from sgml_node_info. */ -static struct dom_node * -add_html_element_node(struct dom_stack *stack, struct dom_node *node, void *data) -{ - struct sgml_parser *parser = stack->data; - - assert(stack && node); - assert(dom_stack_has_parents(stack)); - - /* TODO: Move to SGML parser main loop and disguise these element ends - * in some internal processing instruction. */ - if (parser->flags & SGML_PARSER_ADD_ELEMENT_ENDS) - get_dom_stack_top(stack)->callback = add_html_element_end_node; - - return node; -} - - struct sgml_info sgml_html_info = { html_attributes, html_elements, - { - /* */ NULL, - /* DOM_NODE_ELEMENT */ add_html_element_node, - /* 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 */ NULL, - /* DOM_NODE_DOCUMENT_TYPE */ NULL, - /* DOM_NODE_DOCUMENT_FRAGMENT */ NULL, - /* DOM_NODE_NOTATION */ NULL, - } }; diff --git a/src/document/sgml/parser.c b/src/document/sgml/parser.c index a09af3e10..a2205ae8d 100644 --- a/src/document/sgml/parser.c +++ b/src/document/sgml/parser.c @@ -41,23 +41,27 @@ add_sgml_document(struct dom_stack *stack, struct uri *uri) static inline struct dom_node * add_sgml_element(struct dom_stack *stack, struct scanner_token *token) { - struct sgml_parser *parser = stack->data; + struct sgml_parser *parser = stack->parser; struct dom_node *parent = get_dom_stack_top(stack)->node; struct dom_stack_state *state; struct sgml_parser_state *pstate; struct dom_node *node; + struct sgml_node_info *node_info; node = add_dom_element(parent, token->string, token->length); + if (!node) return NULL; - if (!node || !push_dom_node(stack, node)) + node_info = get_sgml_node_info(parser->info->elements, node); + node->data.element.type = node_info->type; + + if (!push_dom_node(stack, node)) return NULL; state = get_dom_stack_top(stack); - assert(node == state->node && state->data); + assert(node == state->node); - pstate = state->data; - pstate->info = get_sgml_node_info(parser->info->elements, node); - node->data.element.type = pstate->info->type; + pstate = get_dom_stack_state_data(stack, state); + pstate->info = node_info; return node; } @@ -67,7 +71,7 @@ static inline void add_sgml_attribute(struct dom_stack *stack, struct scanner_token *token, struct scanner_token *valtoken) { - struct sgml_parser *parser = stack->data; + struct sgml_parser *parser = stack->parser; struct dom_node *parent = get_dom_stack_top(stack)->node; unsigned char *value = valtoken ? valtoken->string : NULL; uint16_t valuelen = valtoken ? valtoken->length : 0; @@ -77,9 +81,6 @@ add_sgml_attribute(struct dom_stack *stack, node = add_dom_attribute(parent, token->string, token->length, value, valuelen); - if (!node || !push_dom_node(stack, node)) - return; - info = get_sgml_node_info(parser->info->attributes, node); node->data.attribute.type = info->type; @@ -89,6 +90,9 @@ add_sgml_attribute(struct dom_stack *stack, if (valtoken && valtoken->type == SGML_TOKEN_STRING) node->data.attribute.quoted = 1; + if (!node || !push_dom_node(stack, node)) + return; + pop_dom_node(stack); } @@ -243,8 +247,18 @@ parse_sgml_document(struct dom_stack *stack, struct scanner *scanner) if (!token->length) { pop_dom_node(stack); } else { - pop_dom_nodes(stack, DOM_NODE_ELEMENT, - token->string, token->length); + struct dom_stack_state *state; + + state = search_dom_stack(stack, DOM_NODE_ELEMENT, + token->string, token->length); + if (state) { + struct sgml_parser_state *pstate; + + pstate = get_dom_stack_state_data(stack, state); + copy_struct(&pstate->end_token, token); + + pop_dom_state(stack, DOM_NODE_ELEMENT, state); + } } skip_scanner_token(scanner); break; @@ -293,7 +307,10 @@ parse_sgml_document(struct dom_stack *stack, struct scanner *scanner) struct sgml_parser * -init_sgml_parser(struct cache_entry *cached, struct document *document) +init_sgml_parser(enum sgml_parser_type type, void *renderer, + struct cache_entry *cached, struct document *document, + dom_stack_callback_T push_callbacks[DOM_NODES], + dom_stack_callback_T pop_callbacks[DOM_NODES]) { size_t obj_size = sizeof(struct sgml_parser_state); struct sgml_parser *parser; @@ -301,14 +318,13 @@ init_sgml_parser(struct cache_entry *cached, struct document *document) parser = mem_calloc(1, sizeof(*parser)); if (!parser) return NULL; + parser->type = type; 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; + init_dom_stack(&parser->stack, parser, renderer, + push_callbacks, pop_callbacks, obj_size); return parser; } diff --git a/src/document/sgml/parser.h b/src/document/sgml/parser.h index 21801787d..688ebc27a 100644 --- a/src/document/sgml/parser.h +++ b/src/document/sgml/parser.h @@ -11,13 +11,21 @@ struct cache_entry; struct document; struct string; -enum sgml_parser_flags { - SGML_PARSER_ADD_ELEMENT_ENDS = 1, +enum sgml_parser_type { + /* The first one is a DOM tree builder. */ + SGML_PARSER_TREE, + /* The second one will simply push nodes on the stack, not building a + * DOM tree. This interface is similar to that of SAX (Simple API for + * XML) where events are fired when nodes are entered and exited. It is + * useful when you are not actually interested in the DOM tree, but can + * do all processing in a stream-like manner, such as when highlighting + * HTML code. */ + SGML_PARSER_STREAM, }; struct sgml_parser { - /* The parser flags controls what gets added to the DOM tree */ - enum sgml_parser_flags flags; + enum sgml_parser_type type; + struct sgml_info *info; struct document *document; @@ -30,10 +38,16 @@ struct sgml_parser { struct sgml_parser_state { struct sgml_node_info *info; + /* This is used by the DOM source renderer for highlighting the + * end-tag of an element. */ + struct scanner_token end_token; }; struct sgml_parser * -init_sgml_parser(struct cache_entry *cached, struct document *document); +init_sgml_parser(enum sgml_parser_type type, void *renderer, + struct cache_entry *cached, struct document *document, + dom_stack_callback_T push_callbacks[DOM_NODES], + dom_stack_callback_T pop_callbacks[DOM_NODES]); void done_sgml_parser(struct sgml_parser *parser); diff --git a/src/document/sgml/sgml.h b/src/document/sgml/sgml.h index a33e54b68..a2b5ccba0 100644 --- a/src/document/sgml/sgml.h +++ b/src/document/sgml/sgml.h @@ -76,7 +76,6 @@ get_sgml_node_info(struct sgml_node_info list[], struct dom_node *node) struct sgml_info { struct sgml_node_info *attributes; struct sgml_node_info *elements; - dom_stack_callback_T callbacks[DOM_NODES]; }; #endif