source: gaycko/trunk/src/dom/dom.c @ 4759

Last change on this file since 4759 was 4759, checked in by Jean-Yves Lamoureux, 11 years ago
  • Added fix_table and fix_tr
File size: 5.2 KB
Line 
1/*
2 *  Gaycko        Text mode web browser
3 *  Copyright (c) 2011 Jean-Yves Lamoureux <jylam@lnxscene.org>
4 *                All Rights Reserved
5 *
6 *  This library is free software. It comes without any warranty, to
7 *  the extent permitted by applicable law. You can redistribute it
8 *  and/or modify it under the terms of the Do What The Fuck You Want
9 *  To Public License, Version 2, as published by Sam Hocevar. See
10 *  http://sam.zoy.org/wtfpl/COPYING for more details.
11 */
12#include <config.h>
13#include <stdio.h>
14#include <string.h>
15#include "dom.h"
16#include "helpers/str.h"
17
18gDOM *gaycko_convert_dom(htmlDocPtr doc) {
19
20        gDOM *dom = malloc(sizeof(gDOM));
21        dom->root = NULL; 
22        htmlNodePtr root = xmlDocGetRootElement(doc);
23        gNode **r = NULL;
24        gNode *ret = NULL;
25
26        if(root != NULL)
27        {
28                ret = explore(r, root, 0, NULL);
29        }
30
31        dom->root = ret;
32
33        return dom;
34}
35
36
37gNode *add_node(htmlNodePtr node) {
38
39        gNode *e;
40        e = malloc(sizeof(gNode));
41        e->children_count  = 0;
42        e->children        = NULL;
43        e->attribute_count = 0;
44        e->attributes      = NULL;
45        e->text            = NULL;
46
47        e->properties = malloc(sizeof(gProperty));
48    e->properties->x = 0;
49    e->properties->y = 0;
50    e->properties->width = 0;
51    e->properties->height = 0;
52   
53        if(!node->name) {
54                e->name = strdup("UNKNOW");
55                e->type = ELEM_UNKNOW;
56                return e;       
57        }
58       
59        e->name = (char*)strdup((const char*)node->name);
60        if(!strncmp(e->name, "html", 4)) {
61                e->type = ELEM_HTML;
62        }else if(!strncmp(e->name, "head", 4)) {
63                e->type = ELEM_HEAD;
64        }else if(!strncmp(e->name, "title", 5)) {
65                e->type = ELEM_TITLE;
66        }else if(!strncmp(e->name, "meta", 4)) {
67                e->type = ELEM_META;
68        }else if(!strncmp(e->name, "body", 4)) {
69                e->type = ELEM_BODY;
70        }else if(!strncmp(e->name, "h1", 2)) {
71                e->type = ELEM_H1;
72        }else if(!strncmp(e->name, "h2", 2)) {
73                e->type = ELEM_H2;
74        }else if(!strncmp(e->name, "h3", 2)) {
75                e->type = ELEM_H3;
76        }else if(!strncmp(e->name, "hr", 2)) {
77                e->type = ELEM_HR;
78        }else if(!strncmp(e->name, "br", 2) || !strncmp(e->name, "br ", 3)) {
79                e->type = ELEM_BR;
80        }else if(!strncmp(e->name, "p", 1)) {
81                e->type = ELEM_P;
82        }else if(!strncmp(e->name, "img", 3)) {
83                e->type = ELEM_IMG;
84        }else if(!strncmp(e->name, "table", 3)) {
85                e->type = ELEM_TABLE;
86        e->specific.table = malloc(sizeof(gTable));
87        e->specific.table->border   = 0;
88        e->specific.table->tr_count = 0;
89        }else if(!strncmp(e->name, "tr", 3)) {
90                e->type = ELEM_TR;
91        e->specific.tr    = malloc(sizeof(gTr));
92        e->specific.tr->border   = 0;
93        e->specific.tr->td_count = 0;
94        }else if(!strncmp(e->name, "td", 3)) {
95                e->type = ELEM_TD;
96        }else if(!strncmp(e->name, "text", 4)) {
97                e->type = ELEM_TEXT;
98                e->text = (char*)strdup((const char*)xmlNodeGetContent(node));
99                strip_eol(e->text);
100                strip_spaces(&e->text);
101        }else {
102                e->type = ELEM_UNKNOW;
103                printf("Unknow tag '%s'\n", e->name);   
104        }
105
106        if(node->properties) {
107                for(xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
108                        e->attributes = realloc(e->attributes, sizeof(gAttribute)*(e->attribute_count+1));
109                        e->attributes[e->attribute_count].name = strdup((const char*)attr->name);
110                        e->attributes[e->attribute_count].value = strdup((char*)attr->children->content);
111                        e->attribute_count++;
112                }
113        }
114
115        return e;
116}
117
118
119gNode* explore(gNode **elem, htmlNodePtr hnode, unsigned int level, gNode *parent)
120{
121        unsigned int c = 0;
122        for(htmlNodePtr node = hnode; node != NULL; node = node->next)
123        {
124                gNode *child = add_node(node);
125                child->level = level;
126
127                if(elem) elem  = realloc(elem, sizeof(gNode*)*(c+1));
128                else elem = malloc(sizeof(gNode*));
129
130
131                elem[c] = child;
132
133                c++;
134
135                if(node->type == XML_ELEMENT_NODE)
136                {
137                        if(node->children != NULL) {
138                                explore(child->children,
139                                                node->children,
140                                                level+1,
141                                                child);
142                        } else {
143                                free(child->children);
144                                child->children = NULL;
145                        }
146                }         
147                if(parent) {
148                        parent->children = realloc(parent->children, sizeof(gNode*)*(parent->children_count+1));
149                        parent->children[parent->children_count] = child;
150            child->parent = parent;
151                        parent->children_count++;
152                }
153        }
154        return *elem;
155}
156
157
158void destroy_node(gNode *elem) {
159        if(!elem) return;
160
161        unsigned int a;
162        for(a = 0; a < elem->attribute_count; a++) {
163                if(elem->attributes[a].name) free(elem->attributes[a].name);
164                if(elem->attributes[a].value) free(elem->attributes[a].value);
165        }
166        if(elem->attributes) free(elem->attributes);
167        if(elem->text)       free(elem->text);
168        if(elem->name)       free(elem->name);
169
170        unsigned int i;
171        for(i=0; i < elem->children_count; i++) {
172                destroy_node(elem->children[i]);
173                elem->children[i] = NULL;
174        }
175        free(elem->children);
176        free(elem);
177}
178
179#define LEVEL {unsigned int foo=0; for(foo=0; foo<elem->level; foo++) printf("    ");}
180
181void pretty_print(gNode *elem) {
182        if(!elem) {
183                printf("elem is %p\n", elem);
184                return;
185        }
186
187        if(elem->type == ELEM_TEXT) {
188                LEVEL printf("%s\n", elem->text);
189        } else {
190                LEVEL printf("<%s", elem->name);
191        unsigned int a;
192        for(a = 0; a < elem->attribute_count; a++) {
193                printf(" %s=\"%s\"", elem->attributes[a].name, elem->attributes[a].value); 
194        }
195        printf(">\n");
196        }
197
198        unsigned int i;
199        for(i=0; i < elem->children_count; i++) {
200                pretty_print(elem->children[i]);
201        }
202
203        if(elem->type == ELEM_TEXT) {
204
205        } else {
206                LEVEL printf("</%s>\n", elem->name);
207        }
208}
209
Note: See TracBrowser for help on using the repository browser.