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

Last change on this file since 4750 was 4750, checked in by Jean-Yves Lamoureux, 10 years ago
  • Initial general node and table width computation
File size: 4.8 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    //pretty_print(ret);
34
35        return dom;
36}
37
38
39gNode *add_node(htmlNodePtr node) {
40
41        gNode *e;
42        e = malloc(sizeof(gNode));
43        e->children_count  = 0;
44        e->children        = NULL;
45        e->attribute_count = 0;
46        e->attributes      = NULL;
47        e->text            = NULL;
48
49        e->properties = malloc(sizeof(gProperty));
50    e->properties->x = 0;
51    e->properties->y = 0;
52    e->properties->width = 0;
53    e->properties->height = 0;
54   
55        if(!node->name) {
56                e->name = strdup("UNKNOW");
57                e->type = ELEM_UNKNOW;
58                return e;       
59        }
60       
61        e->name = (char*)strdup((const char*)node->name);
62        if(!strncmp(e->name, "html", 4)) {
63                e->type = ELEM_HTML;
64        }else if(!strncmp(e->name, "head", 4)) {
65                e->type = ELEM_HEAD;
66        }else if(!strncmp(e->name, "title", 5)) {
67                e->type = ELEM_TITLE;
68        }else if(!strncmp(e->name, "meta", 4)) {
69                e->type = ELEM_META;
70        }else if(!strncmp(e->name, "body", 4)) {
71                e->type = ELEM_BODY;
72        }else if(!strncmp(e->name, "h1", 2)) {
73                e->type = ELEM_H1;
74        }else if(!strncmp(e->name, "br", 2) || !strncmp(e->name, "br ", 3)) {
75                e->type = ELEM_BR;
76        }else if(!strncmp(e->name, "p", 1)) {
77                e->type = ELEM_P;
78        }else if(!strncmp(e->name, "img", 3)) {
79                e->type = ELEM_IMG;
80        }else if(!strncmp(e->name, "table", 3)) {
81                e->type = ELEM_TABLE;
82        }else if(!strncmp(e->name, "tr", 3)) {
83                e->type = ELEM_TR;
84        }else if(!strncmp(e->name, "td", 3)) {
85                e->type = ELEM_TD;
86        }else if(!strncmp(e->name, "text", 4)) {
87                e->type = ELEM_TEXT;
88                e->text = (char*)strdup((const char*)xmlNodeGetContent(node));
89                strip_eol(e->text);
90                strip_spaces(e->text);
91        }else {
92                e->type = ELEM_UNKNOW;
93                printf("Unknow tag '%s'\n", e->name);   
94        }
95
96        if(node->properties) {
97                for(xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
98                        e->attributes = realloc(e->attributes, sizeof(gAttribute)*(e->attribute_count+1));
99                        e->attributes[e->attribute_count].name = strdup((const char*)attr->name);
100                        e->attributes[e->attribute_count].value = strdup((char*)attr->children->content);
101                        e->attribute_count++;
102                }
103        }
104
105        return e;
106}
107
108
109gNode* explore(gNode **elem, htmlNodePtr hnode, unsigned int level, gNode *parent)
110{
111        unsigned int c = 0;
112        for(htmlNodePtr node = hnode; node != NULL; node = node->next)
113        {
114                gNode *child = add_node(node);
115                child->level = level;
116
117                if(elem) elem  = realloc(elem, sizeof(gNode*)*(c+1));
118                else elem = malloc(sizeof(gNode*));
119
120
121                elem[c] = child;
122
123                c++;
124
125                if(node->type == XML_ELEMENT_NODE)
126                {
127                        if(node->children != NULL) {
128                                explore(child->children,
129                                                node->children,
130                                                level+1,
131                                                child);
132                        } else {
133                                free(child->children);
134                                child->children = NULL;
135                        }
136                }         
137                if(parent) {
138                        parent->children = realloc(parent->children, sizeof(gNode*)*(parent->children_count+1));
139                        parent->children[parent->children_count] = child;
140                        parent->children_count++;
141                }
142        }
143        return *elem;
144}
145
146
147void destroy_node(gNode *elem) {
148        if(!elem) return;
149
150        unsigned int a;
151        for(a = 0; a < elem->attribute_count; a++) {
152                if(elem->attributes[a].name) free(elem->attributes[a].name);
153                if(elem->attributes[a].value) free(elem->attributes[a].value);
154        }
155        if(elem->attributes) free(elem->attributes);
156        if(elem->text)       free(elem->text);
157        if(elem->name)       free(elem->name);
158
159        unsigned int i;
160        for(i=0; i < elem->children_count; i++) {
161                destroy_node(elem->children[i]);
162                elem->children[i] = NULL;
163        }
164        free(elem->children);
165        free(elem);
166}
167
168#define LEVEL {unsigned int foo=0; for(foo=0; foo<elem->level; foo++) printf("    ");}
169
170void pretty_print(gNode *elem) {
171        if(!elem) {
172                printf("elem is %p\n", elem);
173                return;
174        }
175
176        if(elem->type == ELEM_TEXT) {
177                LEVEL printf("%s\n", elem->text);
178        } else {
179                LEVEL printf("<%s", elem->name);
180        unsigned int a;
181        for(a = 0; a < elem->attribute_count; a++) {
182                printf(" %s=\"%s\"", elem->attributes[a].name, elem->attributes[a].value); 
183        }
184        printf(">\n");
185        }
186
187        unsigned int i;
188        for(i=0; i < elem->children_count; i++) {
189                pretty_print(elem->children[i]);
190        }
191
192        if(elem->type == ELEM_TEXT) {
193
194        } else {
195                LEVEL printf("</%s>\n", elem->name);
196        }
197}
198
Note: See TracBrowser for help on using the repository browser.