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

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