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

Last change on this file since 4755 was 4755, checked in by Jean-Yves Lamoureux, 9 years ago
  • Display rendering in caca window
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        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, "br", 2) || !strncmp(e->name, "br ", 3)) {
73                e->type = ELEM_BR;
74        }else if(!strncmp(e->name, "p", 1)) {
75                e->type = ELEM_P;
76        }else if(!strncmp(e->name, "img", 3)) {
77                e->type = ELEM_IMG;
78        }else if(!strncmp(e->name, "table", 3)) {
79                e->type = ELEM_TABLE;
80        }else if(!strncmp(e->name, "tr", 3)) {
81                e->type = ELEM_TR;
82        }else if(!strncmp(e->name, "td", 3)) {
83                e->type = ELEM_TD;
84        }else if(!strncmp(e->name, "text", 4)) {
85                e->type = ELEM_TEXT;
86                e->text = (char*)strdup((const char*)xmlNodeGetContent(node));
87                strip_eol(e->text);
88                strip_spaces(&e->text);
89        }else {
90                e->type = ELEM_UNKNOW;
91                printf("Unknow tag '%s'\n", e->name);   
92        }
93
94        if(node->properties) {
95                for(xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
96                        e->attributes = realloc(e->attributes, sizeof(gAttribute)*(e->attribute_count+1));
97                        e->attributes[e->attribute_count].name = strdup((const char*)attr->name);
98                        e->attributes[e->attribute_count].value = strdup((char*)attr->children->content);
99                        e->attribute_count++;
100                }
101        }
102
103        return e;
104}
105
106
107gNode* explore(gNode **elem, htmlNodePtr hnode, unsigned int level, gNode *parent)
108{
109        unsigned int c = 0;
110        for(htmlNodePtr node = hnode; node != NULL; node = node->next)
111        {
112                gNode *child = add_node(node);
113                child->level = level;
114
115                if(elem) elem  = realloc(elem, sizeof(gNode*)*(c+1));
116                else elem = malloc(sizeof(gNode*));
117
118
119                elem[c] = child;
120
121                c++;
122
123                if(node->type == XML_ELEMENT_NODE)
124                {
125                        if(node->children != NULL) {
126                                explore(child->children,
127                                                node->children,
128                                                level+1,
129                                                child);
130                        } else {
131                                free(child->children);
132                                child->children = NULL;
133                        }
134                }         
135                if(parent) {
136                        parent->children = realloc(parent->children, sizeof(gNode*)*(parent->children_count+1));
137                        parent->children[parent->children_count] = child;
138                        parent->children_count++;
139                }
140        }
141        return *elem;
142}
143
144
145void destroy_node(gNode *elem) {
146        if(!elem) return;
147
148        unsigned int a;
149        for(a = 0; a < elem->attribute_count; a++) {
150                if(elem->attributes[a].name) free(elem->attributes[a].name);
151                if(elem->attributes[a].value) free(elem->attributes[a].value);
152        }
153        if(elem->attributes) free(elem->attributes);
154        if(elem->text)       free(elem->text);
155        if(elem->name)       free(elem->name);
156
157        unsigned int i;
158        for(i=0; i < elem->children_count; i++) {
159                destroy_node(elem->children[i]);
160                elem->children[i] = NULL;
161        }
162        free(elem->children);
163        free(elem);
164}
165
166#define LEVEL {unsigned int foo=0; for(foo=0; foo<elem->level; foo++) printf("    ");}
167
168void pretty_print(gNode *elem) {
169        if(!elem) {
170                printf("elem is %p\n", elem);
171                return;
172        }
173
174        if(elem->type == ELEM_TEXT) {
175                LEVEL printf("%s\n", elem->text);
176        } else {
177                LEVEL printf("<%s", elem->name);
178        unsigned int a;
179        for(a = 0; a < elem->attribute_count; a++) {
180                printf(" %s=\"%s\"", elem->attributes[a].name, elem->attributes[a].value); 
181        }
182        printf(">\n");
183        }
184
185        unsigned int i;
186        for(i=0; i < elem->children_count; i++) {
187                pretty_print(elem->children[i]);
188        }
189
190        if(elem->type == ELEM_TEXT) {
191
192        } else {
193                LEVEL printf("</%s>\n", elem->name);
194        }
195}
196
Note: See TracBrowser for help on using the repository browser.