1 /* DOM document renderer */
11 #include "cache/cache.h"
12 #include "document/document.h"
13 #include "document/dom/renderer.h"
14 #include "document/dom/rss.h"
15 #include "document/dom/source.h"
16 #include "document/dom/util.h"
17 #include "document/renderer.h"
18 #include "dom/configuration.h"
19 #include "dom/scanner.h"
20 #include "dom/sgml/parser.h"
21 #include "dom/sgml/html/html.h"
22 #include "dom/sgml/rss/rss.h"
24 #include "dom/stack.h"
25 #include "intl/charsets.h"
26 #include "protocol/uri.h"
27 #include "util/error.h"
28 #include "util/memory.h"
29 #include "util/string.h"
33 init_dom_renderer(struct dom_renderer
*renderer
, struct document
*document
,
34 struct string
*buffer
, struct conv_table
*convert_table
)
36 memset(renderer
, 0, sizeof(*renderer
));
38 renderer
->document
= document
;
39 renderer
->convert_table
= convert_table
;
40 renderer
->convert_mode
= document
->options
.plain
? CSM_NONE
: CSM_DEFAULT
;
41 renderer
->source
= buffer
->source
;
42 renderer
->end
= buffer
->source
+ buffer
->length
;
43 renderer
->position
= renderer
->source
;
44 renderer
->base_uri
= get_uri_reference(document
->uri
);
48 done_dom_renderer(struct dom_renderer
*renderer
)
50 done_uri(renderer
->base_uri
);
55 get_doctype(struct dom_renderer
*renderer
, struct cache_entry
*cached
)
57 if (!c_strcasecmp("application/rss+xml", cached
->content_type
)) {
58 renderer
->doctype
= SGML_DOCTYPE_RSS
;
60 } else if (!c_strcasecmp("application/docbook+xml",
61 cached
->content_type
)) {
62 renderer
->doctype
= SGML_DOCTYPE_DOCBOOK
;
64 } else if (!c_strcasecmp("application/xbel+xml", cached
->content_type
)
65 || !c_strcasecmp("application/x-xbel", cached
->content_type
)
66 || !c_strcasecmp("application/xbel", cached
->content_type
)) {
67 renderer
->doctype
= SGML_DOCTYPE_XBEL
;
70 assertm(!c_strcasecmp("text/html", cached
->content_type
)
71 || !c_strcasecmp("application/xhtml+xml",
72 cached
->content_type
),
73 "Couldn't resolve doctype '%s'", cached
->content_type
);
75 renderer
->doctype
= SGML_DOCTYPE_HTML
;
79 /* Shared multiplexor between renderers */
81 render_dom_document(struct cache_entry
*cached
, struct document
*document
,
82 struct string
*buffer
)
84 unsigned char *head
= empty_string_or_(cached
->head
);
85 struct dom_renderer renderer
;
86 struct dom_config config
;
87 struct conv_table
*convert_table
;
88 struct sgml_parser
*parser
;
89 enum sgml_parser_type parser_type
;
90 unsigned char *string
= struri(cached
->uri
);
91 size_t length
= strlen(string
);
92 struct dom_string uri
= INIT_DOM_STRING(string
, length
);
94 convert_table
= get_convert_table(head
, document
->options
.cp
,
95 document
->options
.assume_cp
,
98 document
->options
.hard_assume
);
100 init_dom_renderer(&renderer
, document
, buffer
, convert_table
);
102 document
->color
.background
= document
->options
.default_style
.color
.background
;
104 document
->options
.utf8
= is_cp_utf8(document
->options
.cp
);
105 #endif /* CONFIG_UTF8 */
107 if (document
->options
.plain
)
108 parser_type
= SGML_PARSER_STREAM
;
110 parser_type
= SGML_PARSER_TREE
;
112 get_doctype(&renderer
, cached
);
114 parser
= init_sgml_parser(parser_type
, renderer
.doctype
, &uri
, 0);
117 if (document
->options
.plain
) {
118 add_dom_stack_context(&parser
->stack
, &renderer
,
119 &dom_source_renderer_context_info
);
121 } else if (renderer
.doctype
== SGML_DOCTYPE_RSS
) {
122 add_dom_stack_context(&parser
->stack
, &renderer
,
123 &dom_rss_renderer_context_info
);
124 add_dom_config_normalizer(&parser
->stack
, &config
, RSS_CONFIG_FLAGS
);
127 /* FIXME: When rendering this way we don't really care about the code.
128 * However, it will be useful when we will be able to also
129 * incrementally parse new data. This will require the parser to live
130 * during the fetching of data. */
131 parse_sgml(parser
, buffer
->source
, buffer
->length
, 1);
133 assert(parser
->stack
.depth
== 1);
135 get_dom_stack_top(&parser
->stack
)->immutable
= 0;
136 /* For SGML_PARSER_STREAM this will free the DOM
138 pop_dom_node(&parser
->stack
);
141 done_dom_renderer(&renderer
);
142 done_sgml_parser(parser
);