commit 17839623927e816114d4f6858520958748d0ede2
parent dc7d92ffbab9cda6929046f9b5fbea1a625d807f
Author: tongong <tongong@gmx.net>
Date:   Wed, 29 Jun 2022 18:20:48 +0200
added html->binary bundling
Diffstat:
5 files changed, 58 insertions(+), 29 deletions(-)
diff --git a/bundle_binary.ha b/bundle_binary.ha
@@ -5,7 +5,7 @@ use os;
 fn tacker_binary(inputpath: str, ofile: io::handle) void = {
 	const ifile = os::open(inputpath)!;
 	defer io::close(ifile)!;
-	const enc = base64::newencoder(&base64::url_encoding, ofile);
+	const enc = base64::newencoder(&base64::std_encoding, ofile);
 	io::copy(&enc, ifile)!;
 	io::close(&enc)!;
 };
diff --git a/bundle_html.ha b/bundle_html.ha
@@ -25,16 +25,23 @@ fn tacker_html(inputpath: str, ofile: io::handle) void = {
 		const m = searchio::search(ifile, ofile, p_main);
 		if (m is size) {
 			const m = m: size;
-			if (m == 0) { // html comments
+
+			let tagbuf = bufio::dynamic(io::mode::RDWR);
+			defer io::close(&tagbuf)!;
+			if (m != 0) {
+				fmt::fprint(&tagbuf, p_main.original[m])!;
+				searchio::search(ifile, &tagbuf, p_tagclose);
+				fmt::fprint(&tagbuf, ">")!;
+			};
+
+			if (m == 0) {
+				// html comments
 				fmt::fprint(ofile, "<!--")!;
 				searchio::search(ifile, ofile, p_comment);
 				fmt::fprint(ofile, "-->")!;
-			} else if (m == 1) { // <script>
-				let tagbuf = bufio::dynamic(io::mode::RDWR);
-				defer io::close(&tagbuf)!;
-				fmt::fprint(&tagbuf, "<script")!;
-				searchio::search(ifile, &tagbuf, p_tagclose);
-				fmt::fprint(&tagbuf, ">")!;
+			} else if (m == 1) {
+				// <script> -> look at src and replace the whole
+				// tag
 				const src = tag_get_attr(tagbuf.buf,
 					strings::toutf8("src"));
 				if (src is not_found) {
@@ -51,12 +58,9 @@ fn tacker_html(inputpath: str, ofile: io::handle) void = {
 					tacker_js(src, ofile);
 					fmt::fprint(ofile, "</script>")!;
 				};
-			} else if (m == 2) { // stylesheets
-				let tagbuf = bufio::dynamic(io::mode::RDWR);
-				defer io::close(&tagbuf)!;
-				fmt::fprint(&tagbuf, "<link")!;
-				searchio::search(ifile, &tagbuf, p_tagclose);
-				fmt::fprint(&tagbuf, ">")!;
+			} else if (m == 2) {
+				// stylesheets -> look at rel and href and
+				// replace the whole tag
 				const rel = tag_get_attr(tagbuf.buf,
 					strings::toutf8("rel"));
 				let is_style = rel is tag_split;
@@ -73,7 +77,9 @@ fn tacker_html(inputpath: str, ofile: io::handle) void = {
 					const href = tag_get_attr(tagbuf.buf,
 						strings::toutf8("href"));
 					if (href is not_found)
-						fixed_fatalf("broken style tag \"{}\".", strings::fromutf8(tagbuf.buf));
+						fixed_fatalf("broken style tag \"{}\".",
+							strings::fromutf8(
+							tagbuf.buf));
 					const href = href: tag_split;
 					const href = strings::fromutf8(href.1);
 					fmt::fprint(ofile, "<style>\n")!;
@@ -84,8 +90,24 @@ fn tacker_html(inputpath: str, ofile: io::handle) void = {
 					fmt::fprint(ofile, "</style>")!;
 				};
 			} else {
-				// TODO other embeds
-				fmt::fatal("[TODO] unimplemented html tag transform");
+				// media tags -> look at src and replace only
+				// src, not the whole tag
+				const src = tag_get_attr(tagbuf.buf,
+					strings::toutf8("src"));
+				if (src is not_found) {
+					io::write(ofile, tagbuf.buf)!;
+				} else {
+					const src = src: tag_split;
+					const srctext = strings::fromutf8(
+						src.1);
+					const srctext = resolve_path(srctext,
+						inputpath);
+					defer free(srctext);
+					io::write(ofile, src.0)!;
+					fmt::fprint(ofile, "data:;base64,")!;
+					tacker_binary(srctext, ofile);
+					io::write(ofile, src.2)!;
+				};
 			};
 		} else break;
 	};
diff --git a/searchio/searchio.ha b/searchio/searchio.ha
@@ -4,8 +4,11 @@ use os;
 use sort;
 use strings;
 
-// sorted
-export type pattern = []patternelem;
+export type pattern = struct {
+	elems: []patternelem, // sorted
+	// reference to the string list before compile
+	original: []str,
+};
 export type patternelem = struct {
 	// if the first n bytes are identical to the first n bytes in the string
 	// before they are set to 0
@@ -29,7 +32,7 @@ fn patternelem_cmp(a: *void, b: *void) int = {
 
 // pattern has to be finished
 export fn compile(s: []str) pattern = {
-	let p: pattern = [];
+	let p: []patternelem = [];
 	for (let i = 0z; i < len(s); i += 1) {
 		append(p, patternelem {
 			data = strings::toutf8(strings::dup(s[i])),
@@ -46,12 +49,12 @@ export fn compile(s: []str) pattern = {
 			} else break;
 		};
 	};
-	return p;
+	return pattern { elems = p, original = s };
 };
 
 export fn finish(p: pattern) void = {
-	for (let i = 0z; i < len(p); i += 1) {
-		free(p[i].data);
+	for (let i = 0z; i < len(p.elems); i += 1) {
+		free(p.elems[i].data);
 	};
 };
 
@@ -78,8 +81,8 @@ export fn search(ifile: io::handle, ofile: io::handle, end: pattern)
 		const buf = buf[0];
 
 		let nomatches = true;
-		for (let i = curr_elem; i < len(end); i += 1) {
-			const e = end[i].data;
+		for (let i = curr_elem; i < len(end.elems); i += 1) {
+			const e = end.elems[i].data;
 			if (curr_index != 0 && i != curr_elem &&
 				e[curr_index - 1] != 0) break;
 			if (e[curr_index] != 0 && e[curr_index] > buf) break;
@@ -87,8 +90,9 @@ export fn search(ifile: io::handle, ofile: io::handle, end: pattern)
 				curr_elem = i;
 				curr_index += 1;
 				nomatches = false;
-				if (curr_index == len(end[curr_elem].data))
-					return end[curr_elem].index;
+				if (curr_index == len(end.elems[curr_elem]
+						.data))
+					return end.elems[curr_elem].index;
 				break;
 			};
 		};
@@ -96,10 +100,11 @@ export fn search(ifile: io::handle, ofile: io::handle, end: pattern)
 			if (curr_index != 0) {
 				for (let i = 0z; i < curr_index; i += 1) {
 					let elem = curr_elem;
-					for (end[elem].data[i] == 0) {
+					for (end.elems[elem].data[i] == 0) {
 						elem -= 1;
 					};
-					io::write(ofile, [end[elem].data[i]])!;
+					io::write(ofile, [end.elems[elem]
+						.data[i]])!;
 				};
 				curr_elem = 0;
 				curr_index = 0;
diff --git a/test-page/example.png b/test-page/example.png
Binary files differ.
diff --git a/test-page/index.html b/test-page/index.html
@@ -11,5 +11,7 @@
     </head>
     <body>
         <h1>test page</h1>
+        a nice image:
+        <img src=./example.png alt="example image"/>
     </body>
 </html>