home readme diff tree note docs

0commit 1627c585128af263181053ab2cf1a4cdcd14ee21
1Author: Mason Wright <mason@lakefox.net>
2Date:   Tue Jun 24 20:37:01 2025 -0600
3
4    Added support for embedding tags in script/style/textarea tags
5
6diff --git a/src/parser.cc b/src/parser.cc
7index 32ca96f..dd54a62 100644
8--- a/src/parser.cc
9+++ b/src/parser.cc
10@@ -112,13 +112,13 @@ std::unique_ptr<Node> parseStream(std::istream& inputStream) {
11 	bool escaped = false;
12 	bool inQuote = false;
13 	bool inComment = false;
14+	bool waitToClose = false;
15 	char quoteType = '"';
16 
17 	std::string token;
18 
19 	char current;
20 	while (inputStream.get(current)) {
21-
22 		// Finds the --> and removes it then resets inComment
23 		if (inComment) {
24 			// added the peek to prevent hitting on every -
25@@ -126,7 +126,7 @@ std::unique_ptr<Node> parseStream(std::istream& inputStream) {
26 				char a,b;
27 				// load the next two
28 				if (inputStream.get(a) && inputStream.get(b)) {
29-					// We know b == -
30+					// We know a == -
31 					if (b == '>') {
32 						// Close the comment
33 						inComment = false;
34@@ -145,6 +145,42 @@ std::unique_ptr<Node> parseStream(std::istream& inputStream) {
35 			continue;
36 		}
37 
38+		std::string tagName = currentNode->getTagName();
39+		if (!waitToClose && (
40+					tagName == "style" || 
41+					tagName == "script" ||
42+					tagName == "textarea" 
43+					) && current == '<' && inputStream.peek() == '/' ) {
44+			// If its the starting of a closing tag and we are inside of a special tag
45+			// we need to see if the upcoming closing tag is the correct closing tag
46+			// if it is then we put the read ahead back and waitToClose. This will let normal parsing
47+			// continue
48+			const size_t readTo = tagName.length()+2;
49+			std::string buffer(readTo, '\0');
50+
51+			inputStream.read(&buffer[0], readTo);
52+
53+			if (buffer == "/"+tagName+">") {
54+				waitToClose = true;
55+			} else {
56+				token += current;
57+			}
58+
59+			for (int i = readTo-1; i>= 0; i--) {
60+				inputStream.putback(buffer[i]);
61+			}
62+			if (!waitToClose) {
63+				continue;
64+			}
65+		} else if (!waitToClose && (
66+					tagName == "style" || 
67+					tagName == "script" ||
68+					tagName == "textarea" 
69+					)) {
70+			token += current;
71+			continue;
72+		}
73+
74 		if (inTag) {
75 			 if ((current == '"' || current == '\'') && !escaped) {
76 				if (inQuote && current == quoteType) {
77@@ -157,6 +193,7 @@ std::unique_ptr<Node> parseStream(std::istream& inputStream) {
78 
79 			if (current == '>' && !inQuote && !escaped) {
80 				inTag = false;
81+				waitToClose = false;
82 				// Even if the next tag is next still add a text tag as we can just check if its empty and remove it
83 				// this check would still have to be done either way so we aren't wasting anything
84 				if (token.length() > 0) {