home
readme
diff
tree
note
docs
0commit 58fce8a90c6b63146ed15c66a0d96c17cc2065d0
1Author: lakefox <mason@lakefox.net>
2Date: Sat Feb 7 19:09:39 2026 -0700
3
4 Added classes
5
6diff --git a/include/grim.h b/include/grim.h
7index 78b577b..24481f4 100755
8--- a/include/grim.h
9+++ b/include/grim.h
10@@ -313,9 +313,10 @@ void FREE_SYMBOL_TABLE(SymbolTable* st);
11
12 void FREE_NODE(Node* n);
13
14-
15 char* INNER_HTML(SymbolTable* sym, Node* node, char** buffer, size_t* size, int depth);
16
17+void ADD_CLASS(SymbolTable* sym, Node* n, char* value);
18+
19 /*
20 bool testSelector(Node*, std::vector<std::vector<std::string>>);
21
22diff --git a/src/grim.c b/src/grim.c
23index bc22ce7..56ec0db 100755
24--- a/src/grim.c
25+++ b/src/grim.c
26@@ -82,7 +82,7 @@ Node* CREATE_ELEMENT(SymbolTable* sym, const char* value) {
27 Node* el = malloc(sizeof(Node));
28 memset(el, 0, sizeof(Node));
29 el->tag_name = intern_string(sym, value);
30- el->innertext = '\0';
31+ el->innertext = NULL;
32 el->id = -1;
33 return el;
34 }
35@@ -175,6 +175,14 @@ char* INNER_HTML(SymbolTable* sym, Node* node, char** buffer, size_t* size, int
36 }
37 }
38
39+ if (node->classes_count > 0) {
40+ append_to_buffer(buffer, size, " class=\"");
41+ for (int i = 0; i < node->classes_count; i++) {
42+ append_to_buffer(buffer, size, symbol_lookup_string(sym, node->class_list[i]));
43+ }
44+ append_to_buffer(buffer, size, "\"");
45+ }
46+
47 append_to_buffer(buffer, size, ">\n");
48
49 if (node->innertext && strlen(node->innertext)) {
50@@ -250,6 +258,30 @@ char* GET_INNERTEXT(Node* n) {
51 return n->innertext;
52 }
53
54+void ADD_CLASS(SymbolTable* sym, Node* n, char* value) {
55+ int class = intern_string(sym, value);
56+
57+ for (int i = 0; i < n->classes_count; i++) {
58+ if (n->class_list[i] == class) {
59+ return;
60+ }
61+ }
62+
63+ n->class_list[n->classes_count++] = class;
64+}
65+
66+void REMOVE_CLASS(SymbolTable* sym, Node* n, char* value) {
67+ int class = intern_string(sym, value);
68+
69+ for (int i = 0; i < n->classes_count; i++) {
70+ if (n->class_list[i] == class) {
71+ n->classes_count -= 1;
72+ memmove(&n->class_list[i], &n->class_list[i+1], (n->classes_count-i)*sizeof(Symbol));
73+ return;
74+ }
75+ }
76+}
77+
78 // +---------------------------------------------------+
79 // | (mnjki) CSS Style Handling |
80 // +---------------------------------------------------+
81diff --git a/src/parser.c b/src/parser.c
82index 8c85c43..c006745 100755
83--- a/src/parser.c
84+++ b/src/parser.c
85@@ -1157,7 +1157,8 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
86 return units;
87 }
88 */
89-Style parseCSS(std::istream& inputStream) {
90+/*
91+void css_parser(std::istream& inputStream) {
92 // nowhitespace: value(can have whitespace); = property
93 // a selector name is anything before a { up to a ; or a }
94 std::vector<Style*> stack;
95@@ -1330,7 +1331,7 @@ Style parseCSS(std::istream& inputStream) {
96 }
97
98 return root;
99-}
100+}*/
101
102 /*
103 std::string get_working_path() {
104@@ -1476,7 +1477,18 @@ void html_parser(SymbolTable* sym, Node* root, const char* input, int size) {
105 if (strcmp(attr_name, "id") == 0) {
106 SET_ID(sym, currentNode, token);
107 } else if (strcmp(attr_name, "class") == 0) {
108-
109+ char* buffer;
110+ int buffer_length = 0;
111+ for (int j = 0; j < token_length; j++) {
112+ if (isspace(token[j])) {
113+ buffer[buffer_length++] = '\0';
114+ ADD_CLASS(sym, currentNode, buffer);
115+ buffer[0] = '\0';
116+ buffer_length = 0;
117+ } else {
118+ buffer[buffer_length++] = token[j];
119+ }
120+ }
121 } else {
122 SET_ATTRIBUTE(currentNode, attr_name, token);
123 }
124diff --git a/tests/index.html b/tests/index.html
125index 28a9c20..4881b2b 100755
126--- a/tests/index.html
127+++ b/tests/index.html
128@@ -17,7 +17,7 @@
129 <p id="test2">
130 this is a test
131 </p>
132- <textarea><script>console.log(\"</pre>\");</script></textarea>
133+ <textarea class="red blue green"><script>console.log(\"</pre>\");</script></textarea>
134 <pre>
135 <script> console.log("</pre>");</script>
136 </pre>