OLD | NEW |
1 /* | 1 /* |
2 * HTMLtree.c : implementation of access function for an HTML tree. | 2 * HTMLtree.c : implementation of access function for an HTML tree. |
3 * | 3 * |
4 * See Copyright for the status of this software. | 4 * See Copyright for the status of this software. |
5 * | 5 * |
6 * daniel@veillard.com | 6 * daniel@veillard.com |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #define IN_LIBXML | 10 #define IN_LIBXML |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 * @encoding: the encoding string | 153 * @encoding: the encoding string |
154 * | 154 * |
155 * Sets the current encoding in the Meta tags | 155 * Sets the current encoding in the Meta tags |
156 * NOTE: this will not change the document content encoding, just | 156 * NOTE: this will not change the document content encoding, just |
157 * the META flag associated. | 157 * the META flag associated. |
158 * | 158 * |
159 * Returns 0 in case of success and -1 in case of error | 159 * Returns 0 in case of success and -1 in case of error |
160 */ | 160 */ |
161 int | 161 int |
162 htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) { | 162 htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) { |
163 htmlNodePtr cur, meta; | 163 htmlNodePtr cur, meta = NULL, head = NULL; |
164 const xmlChar *content; | 164 const xmlChar *content = NULL; |
165 char newcontent[100]; | 165 char newcontent[100]; |
166 | 166 |
167 | 167 |
168 if (doc == NULL) | 168 if (doc == NULL) |
169 return(-1); | 169 return(-1); |
170 | 170 |
| 171 /* html isn't a real encoding it's just libxml2 way to get entities */ |
| 172 if (!xmlStrcasecmp(encoding, BAD_CAST "html")) |
| 173 return(-1); |
| 174 |
171 if (encoding != NULL) { | 175 if (encoding != NULL) { |
172 snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s", | 176 snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s", |
173 (char *)encoding); | 177 (char *)encoding); |
174 newcontent[sizeof(newcontent) - 1] = 0; | 178 newcontent[sizeof(newcontent) - 1] = 0; |
175 } | 179 } |
176 | 180 |
177 cur = doc->children; | 181 cur = doc->children; |
178 | 182 |
179 /* | 183 /* |
180 * Search the html | 184 * Search the html |
(...skipping 13 matching lines...) Expand all Loading... |
194 return(-1); | 198 return(-1); |
195 cur = cur->children; | 199 cur = cur->children; |
196 | 200 |
197 /* | 201 /* |
198 * Search the head | 202 * Search the head |
199 */ | 203 */ |
200 while (cur != NULL) { | 204 while (cur != NULL) { |
201 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) { | 205 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) { |
202 if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0) | 206 if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0) |
203 break; | 207 break; |
204 » if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) | 208 » if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) { |
| 209 head = cur->parent; |
205 goto found_meta; | 210 goto found_meta; |
| 211 } |
206 } | 212 } |
207 cur = cur->next; | 213 cur = cur->next; |
208 } | 214 } |
209 if (cur == NULL) | 215 if (cur == NULL) |
210 return(-1); | 216 return(-1); |
211 found_head: | 217 found_head: |
212 if (cur->children == NULL) { | 218 head = cur; |
213 » if (encoding == NULL) | 219 if (cur->children == NULL) |
214 » return(0); | 220 goto create; |
215 » meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL); | |
216 » xmlAddChild(cur, meta); | |
217 » xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type"); | |
218 » xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent); | |
219 » return(0); | |
220 } | |
221 cur = cur->children; | 221 cur = cur->children; |
222 | 222 |
223 found_meta: | 223 found_meta: |
224 if (encoding != NULL) { | |
225 /* | |
226 * Create a new Meta element with the right attributes | |
227 */ | |
228 | |
229 meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL); | |
230 xmlAddPrevSibling(cur, meta); | |
231 xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type"); | |
232 xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent); | |
233 } | |
234 | |
235 /* | 224 /* |
236 * Search and destroy all the remaining the meta elements carrying | 225 * Search and update all the remaining the meta elements carrying |
237 * encoding informations | 226 * encoding informations |
238 */ | 227 */ |
239 while (cur != NULL) { | 228 while (cur != NULL) { |
240 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) { | 229 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) { |
241 if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) { | 230 if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) { |
242 xmlAttrPtr attr = cur->properties; | 231 xmlAttrPtr attr = cur->properties; |
243 int http; | 232 int http; |
244 const xmlChar *value; | 233 const xmlChar *value; |
245 | 234 |
246 content = NULL; | 235 content = NULL; |
247 http = 0; | 236 http = 0; |
248 while (attr != NULL) { | 237 while (attr != NULL) { |
249 if ((attr->children != NULL) && | 238 if ((attr->children != NULL) && |
250 (attr->children->type == XML_TEXT_NODE) && | 239 (attr->children->type == XML_TEXT_NODE) && |
251 (attr->children->next == NULL)) { | 240 (attr->children->next == NULL)) { |
252 value = attr->children->content; | 241 value = attr->children->content; |
253 if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv")) | 242 if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv")) |
254 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type"))) | 243 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type"))) |
255 http = 1; | 244 http = 1; |
256 » » » else | 245 » » » else |
257 { | 246 { |
258 if ((value != NULL) && | 247 if ((value != NULL) && |
259 » » » » (!xmlStrcasecmp(attr->name, BAD_CAST"content"))) | 248 (!xmlStrcasecmp(attr->name, BAD_CAST"content"))) |
260 » » » content = value; | 249 » » » content = value; |
261 } | 250 } |
262 if ((http != 0) && (content != NULL)) | 251 if ((http != 0) && (content != NULL)) |
263 break; | 252 break; |
264 } | 253 } |
265 attr = attr->next; | 254 attr = attr->next; |
266 } | 255 } |
267 if ((http != 0) && (content != NULL)) { | 256 if ((http != 0) && (content != NULL)) { |
268 meta = cur; | 257 meta = cur; |
269 » » cur = cur->next; | 258 » » break; |
270 » » xmlUnlinkNode(meta); | |
271 xmlFreeNode(meta); | |
272 » » continue; | |
273 } | 259 } |
274 | 260 |
275 } | 261 } |
276 } | 262 } |
277 cur = cur->next; | 263 cur = cur->next; |
278 } | 264 } |
| 265 create: |
| 266 if (meta == NULL) { |
| 267 if ((encoding != NULL) && (head != NULL)) { |
| 268 /* |
| 269 * Create a new Meta element with the right attributes |
| 270 */ |
| 271 |
| 272 meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL); |
| 273 if (head->children == NULL) |
| 274 xmlAddChild(head, meta); |
| 275 else |
| 276 xmlAddPrevSibling(head->children, meta); |
| 277 xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type"); |
| 278 xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent); |
| 279 } |
| 280 } else { |
| 281 /* change the document only if there is a real encoding change */ |
| 282 if (xmlStrcasestr(content, encoding) == NULL) { |
| 283 xmlSetProp(meta, BAD_CAST"content", BAD_CAST newcontent); |
| 284 } |
| 285 } |
| 286 |
| 287 |
279 return(0); | 288 return(0); |
280 } | 289 } |
281 | 290 |
282 /** | 291 /** |
283 * booleanHTMLAttrs: | 292 * booleanHTMLAttrs: |
284 * | 293 * |
285 * These are the HTML attributes which will be output | 294 * These are the HTML attributes which will be output |
286 * in minimized form, i.e. <option selected="selected"> will be | 295 * in minimized form, i.e. <option selected="selected"> will be |
287 * output as <option selected>, as per XSLT 1.0 16.2 "HTML Output Method" | 296 * output as <option selected>, as per XSLT 1.0 16.2 "HTML Output Method" |
288 * | 297 * |
(...skipping 20 matching lines...) Expand all Loading... |
309 | 318 |
310 while (htmlBooleanAttrs[i] != NULL) { | 319 while (htmlBooleanAttrs[i] != NULL) { |
311 if (xmlStrcasecmp((const xmlChar *)htmlBooleanAttrs[i], name) == 0) | 320 if (xmlStrcasecmp((const xmlChar *)htmlBooleanAttrs[i], name) == 0) |
312 return 1; | 321 return 1; |
313 i++; | 322 i++; |
314 } | 323 } |
315 return 0; | 324 return 0; |
316 } | 325 } |
317 | 326 |
318 #ifdef LIBXML_OUTPUT_ENABLED | 327 #ifdef LIBXML_OUTPUT_ENABLED |
| 328 /* |
| 329 * private routine exported from xmlIO.c |
| 330 */ |
| 331 xmlOutputBufferPtr |
| 332 xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder); |
319 /************************************************************************ | 333 /************************************************************************ |
320 * * | 334 * * |
321 * Output error handlers * | 335 * Output error handlers * |
322 * * | 336 * * |
323 ************************************************************************/ | 337 ************************************************************************/ |
324 /** | 338 /** |
325 * htmlSaveErrMemory: | 339 * htmlSaveErrMemory: |
326 * @extra: extra informations | 340 * @extra: extra informations |
327 * | 341 * |
328 * Handle an out of memory condition | 342 * Handle an out of memory condition |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 } | 573 } |
560 | 574 |
561 /* | 575 /* |
562 * Fallback to HTML or ASCII when the encoding is unspecified | 576 * Fallback to HTML or ASCII when the encoding is unspecified |
563 */ | 577 */ |
564 if (handler == NULL) | 578 if (handler == NULL) |
565 handler = xmlFindCharEncodingHandler("HTML"); | 579 handler = xmlFindCharEncodingHandler("HTML"); |
566 if (handler == NULL) | 580 if (handler == NULL) |
567 handler = xmlFindCharEncodingHandler("ascii"); | 581 handler = xmlFindCharEncodingHandler("ascii"); |
568 | 582 |
569 buf = xmlAllocOutputBuffer(handler); | 583 buf = xmlAllocOutputBufferInternal(handler); |
570 if (buf == NULL) { | 584 if (buf == NULL) { |
571 *mem = NULL; | 585 *mem = NULL; |
572 *size = 0; | 586 *size = 0; |
573 return; | 587 return; |
574 } | 588 } |
575 | 589 |
576 htmlDocContentDumpFormatOutput(buf, cur, NULL, format); | 590 htmlDocContentDumpFormatOutput(buf, cur, NULL, format); |
577 | 591 |
578 xmlOutputBufferFlush(buf); | 592 xmlOutputBufferFlush(buf); |
579 if (buf->conv != NULL) { | 593 if (buf->conv != NULL) { |
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 */ | 1157 */ |
1144 int | 1158 int |
1145 htmlSaveFileFormat(const char *filename, xmlDocPtr cur, | 1159 htmlSaveFileFormat(const char *filename, xmlDocPtr cur, |
1146 const char *encoding, int format) { | 1160 const char *encoding, int format) { |
1147 xmlOutputBufferPtr buf; | 1161 xmlOutputBufferPtr buf; |
1148 xmlCharEncodingHandlerPtr handler = NULL; | 1162 xmlCharEncodingHandlerPtr handler = NULL; |
1149 int ret; | 1163 int ret; |
1150 | 1164 |
1151 if ((cur == NULL) || (filename == NULL)) | 1165 if ((cur == NULL) || (filename == NULL)) |
1152 return(-1); | 1166 return(-1); |
1153 | 1167 |
1154 xmlInitParser(); | 1168 xmlInitParser(); |
1155 | 1169 |
1156 if (encoding != NULL) { | 1170 if (encoding != NULL) { |
1157 xmlCharEncoding enc; | 1171 xmlCharEncoding enc; |
1158 | 1172 |
1159 enc = xmlParseCharEncoding(encoding); | 1173 enc = xmlParseCharEncoding(encoding); |
1160 if (enc != cur->charset) { | 1174 if (enc != cur->charset) { |
1161 if (cur->charset != XML_CHAR_ENCODING_UTF8) { | 1175 if (cur->charset != XML_CHAR_ENCODING_UTF8) { |
1162 /* | 1176 /* |
1163 * Not supported yet | 1177 * Not supported yet |
1164 */ | 1178 */ |
1165 return(-1); | 1179 return(-1); |
1166 } | 1180 } |
1167 | 1181 |
1168 handler = xmlFindCharEncodingHandler(encoding); | 1182 handler = xmlFindCharEncodingHandler(encoding); |
1169 if (handler == NULL) | 1183 if (handler == NULL) |
1170 return(-1); | 1184 return(-1); |
1171 htmlSetMetaEncoding(cur, (const xmlChar *) encoding); | |
1172 } | 1185 } |
| 1186 htmlSetMetaEncoding(cur, (const xmlChar *) encoding); |
1173 } else { | 1187 } else { |
1174 htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8"); | 1188 htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8"); |
1175 } | 1189 } |
1176 | 1190 |
1177 /* | 1191 /* |
1178 * Fallback to HTML or ASCII when the encoding is unspecified | 1192 * Fallback to HTML or ASCII when the encoding is unspecified |
1179 */ | 1193 */ |
1180 if (handler == NULL) | 1194 if (handler == NULL) |
1181 handler = xmlFindCharEncodingHandler("HTML"); | 1195 handler = xmlFindCharEncodingHandler("HTML"); |
1182 if (handler == NULL) | 1196 if (handler == NULL) |
(...skipping 25 matching lines...) Expand all Loading... |
1208 int | 1222 int |
1209 htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) { | 1223 htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) { |
1210 return(htmlSaveFileFormat(filename, cur, encoding, 1)); | 1224 return(htmlSaveFileFormat(filename, cur, encoding, 1)); |
1211 } | 1225 } |
1212 | 1226 |
1213 #endif /* LIBXML_OUTPUT_ENABLED */ | 1227 #endif /* LIBXML_OUTPUT_ENABLED */ |
1214 | 1228 |
1215 #define bottom_HTMLtree | 1229 #define bottom_HTMLtree |
1216 #include "elfgcchack.h" | 1230 #include "elfgcchack.h" |
1217 #endif /* LIBXML_HTML_ENABLED */ | 1231 #endif /* LIBXML_HTML_ENABLED */ |
OLD | NEW |