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") {