home readme diff tree note docs

0commit 16a07a463325bba0631eff4c54345502c4430c39
1Author: Mason Wright <mason@lakefox.net>
2Date:   Sun Jul 27 13:41:22 2025 -0600
3
4    save
5
6diff --git a/src/parser.cc b/src/parser.cc
7index 3b5671c..73abe5f 100644
8--- a/src/parser.cc
9+++ b/src/parser.cc
10@@ -372,75 +372,67 @@ std::unique_ptr<StyleHandler> parseCSS(std::istream& inputStream) {
11 			// need to parse the selector and add it to the stack
12 			current.selector = buffer;
13 
14-			stack.push_back(current);
15-			current = SelectorAndProps();
16-			
17-			buffer.clear();
18-		} else if (ch == '}') {
19-			// compile the selector and add to the handler
20-			// This handles the nested selectors
21-			// if the first non whitespace charactor is a &
22-			// then join them without a space else join them with
23-			std::string selector;
24-			for (size_t i = 0; i < stack.size(); i++) {
25-				bool firstChar = false;
26-
27-				// Here split the stack[i] by commas and run each one
28-
29-				std::string selectorBuffer;
30-				int depth = 0;
31-				for (size_t h = 0; h < stack[i].selector.length(); h++) {
32-					char ss = stack[i].selector[h];
33-
34-					// Handle comma's in () they need to be added to the selectorBuffer
35-					// but don't split the selector by them
36-					if (ss == '(') {
37-						depth++;
38-					} else if (ss == ')') {
39-						depth--;
40-					}
41-
42-					// Split the selector by comma's or at the end
43-					if ((ss == ',' || h == stack[i].selector.length()-1) && depth == 0) {
44-						for (size_t j = 0; j < selectorBuffer.length(); j++) {
45-						char c = selectorBuffer[j];
46-						if (!std::isspace(c) && !firstChar) {
47-							if (c != '&') {
48-								selector.push_back(' ');
49-								selector.push_back(c);
50-							}
51-
52-							firstChar = true;
53-						} else if (firstChar) {
54-							if (std::isspace(c)) { 
55-								if (j < selectorBuffer.length()-1 && !std::isspace(selectorBuffer[j+1])) {
56-									selector.push_back(c);
57-								}
58-							} else {
59-								selector.push_back(c);
60-							}
61-						}
62-					}
63-						selectorBuffer.clear();
64-					} else {
65-						selectorBuffer.push_back(ss);
66-					}
67 
68-					
69-				}
70 
71+// Probally split the selector by commas here
72+// but the stack isn't setup to handle multiple selectors on the same level
73 
74-			}
75 
76-			handler->add(selector, current.props);
77 
78-			if (!stack.empty()) {
79-				current = stack.back();
80-				stack.pop_back();
81-			} else {
82-				current = SelectorAndProps();
83-			}
84+			stack.push_back(current);
85+			current = SelectorAndProps();
86+			
87 			buffer.clear();
88+		} else if (ch == '}') {
89+			// compile the selector and add to the handler
90+                        // This handles the nested selectors
91+                        // if the first non whitespace charactor is a &
92+                        // then join them without a space else join them with
93+                        std::string selector;
94+                        for (size_t i = 0; i < stack.size(); i++) {
95+                                bool firstChar = false;
96+
97+// A better way to simplify this is to think about 
98+// generating all possible combinations
99+// if .selector == vector<string> then selectorStore = vector<string>
100+// build stack of selectors increamentally 
101+// when new branch is found >>duplicate stack<<
102+//
103+// also this only handles one branch so div > span etc not multi level
104+
105+				std::cout << ">" << stack[i].selector << std::endl;
106+                                for (size_t j = 0; j < stack[i].selector.length(); j++) {
107+                                        char c = stack[i].selector[j];
108+                                        if (!std::isspace(c) && !firstChar) {
109+                                                if (c != '&') {
110+                                                        selector.push_back(' ');
111+                                                        selector.push_back(c);
112+                                                }
113+                                                
114+                                                firstChar = true;
115+                                        } else if (firstChar) {
116+                                                if (std::isspace(c)) { 
117+                                                        if (j < stack[i].selector.length()-1 && !std::isspace(stack[i].selector[j+1])) {
118+                                                                selector.push_back(c);
119+                                                        }
120+                                                } else {
121+                                                        selector.push_back(c);
122+                                                }
123+                                        }
124+                                }
125+                        }
126+
127+
128+			std::cout << "-" << selector << std::endl;
129+                        handler->add(selector, current.props);
130+
131+                        if (!stack.empty()) {
132+                                current = stack.back();
133+                                stack.pop_back();
134+                        } else {
135+                                current = SelectorAndProps();
136+                        }
137+                        buffer.clear();
138 		} else if (ch == ';') {
139 			// end of a style property
140 			std::string key;
141@@ -480,7 +472,9 @@ std::unordered_map<std::string, std::string> parseCSSInline(std::string inlineSt
142 	for (size_t i = 0; i < inlineStyles.length(); i++) {
143 		char ch = inlineStyles[i];
144 
145-		if (ch == ';') {
146+		if (ch == ';' || i >= inlineStyles.length()-1) {
147+			// If this is a ';' then it will be removed in the last else if statement
148+			buffer.push_back(ch);
149 			std::string key;
150 			std::string value;
151 			bool keyFound = false;
152@@ -491,7 +485,8 @@ std::unordered_map<std::string, std::string> parseCSSInline(std::string inlineSt
153 				} else if (!std::isspace(c) && !keyFound) {
154 					key += c;
155 				} else if (keyFound &&
156-						!(std::isspace(c) && i < buffer.length()-1 && std::isspace(buffer[i+1]))
157+						!(std::isspace(c) && i < buffer.length()-1 && std::isspace(buffer[i+1])) &&
158+						c != ';'
159 					  ) {
160 					// if the key is found and the charactor isn't a ':'
161 					// 	also (if c is a space and the next c will be a space)
162@@ -509,27 +504,5 @@ std::unordered_map<std::string, std::string> parseCSSInline(std::string inlineSt
163 		}
164 	}
165 
166-	if (buffer.length() > 0) {
167-		std::string key;
168-		std::string value;
169-		bool keyFound = false;
170-		for (size_t i = 0; i < buffer.length(); i++) {
171-			char c = buffer[i];
172-			if (!keyFound && c == ':') {
173-				keyFound = true;
174-			} else if (!std::isspace(c) && !keyFound) {
175-				key += c;
176-			} else if (keyFound  &&
177-					!(std::isspace(c) && i < buffer.length()-1 && std::isspace(buffer[i+1]))) {
178-				// if the key is found and the charactor isn't a ':'
179-				// 	also (if c is a space and the next c will be a space)
180-				// 	this is to auto trim duplicate spaces from the value
181-				value += c;
182-
183-			}
184-		}
185-		props[key] = value;
186-	}
187-
188 	return props;
189 }
190diff --git a/tests/css_parser.cc b/tests/css_parser.cc
191index 0a27e38..ea8473d 100644
192--- a/tests/css_parser.cc
193+++ b/tests/css_parser.cc
194@@ -231,10 +231,12 @@ html#nested {
195 				{"font-size", "10px"}
196 				  }, 9, handler->item(9));
197 	}
198+/*
199 	printSelector(handler->item(10).selector);
200 	printSelector(handler->item(11).selector);
201 	printSelector(handler->item(12).selector);
202 	printSelector(handler->item(13).selector);
203+*/
204 }
205 
206 TEST_CASE("parseCSS can parse multiple selectors nested") {