aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/File.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/File.zig')
-rw-r--r--src/frontend/File.zig91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/frontend/File.zig b/src/frontend/File.zig
new file mode 100644
index 0000000..e7c3b6d
--- /dev/null
+++ b/src/frontend/File.zig
@@ -0,0 +1,91 @@
+const std = @import("std");
+
+pub fn File(comptime tag: ?[]const u8, Iterator: type) type {
+ const opening = if (tag) |t| "<" ++ t ++ ">" else "";
+ const closing = if (tag) |t| "</" ++ t ++ ">" else "";
+
+ return struct {
+ file: []const u8,
+ do_minify: bool,
+
+ pub fn path(comptime p: []const u8) @This() {
+ return .{
+ .file = p,
+ .do_minify = false,
+ };
+ }
+
+ pub fn minify(comptime p: []const u8) @This() {
+ return .{
+ .file = p,
+ .do_minify = true,
+ };
+ }
+
+ fn content(comptime self: @This()) []const u8 {
+ return opening ++ @embedFile(self.file) ++ closing;
+ }
+
+ fn content_minified(comptime self: @This()) []const u8 {
+ var minified: []const u8 = "";
+ var iterator: Iterator = .init(@embedFile(self.file));
+
+ while (iterator.next()) |segment| {
+ minified = minified ++ segment;
+ }
+
+ return opening ++ minified ++ closing;
+ }
+
+ pub fn to_html_string(comptime self: @This()) []const u8 {
+ return if (self.do_minify) self.content_minified() else self.content();
+ }
+ };
+}
+
+fn StringIterator(comptime quotes: []const u8) type {
+ return struct {
+ content: []const u8,
+
+ pub fn init(content: []const u8) @This() {
+ return .{ .content = content };
+ }
+
+ pub fn next(self: *@This()) ?[]const u8 {
+ @setEvalBranchQuota(self.content.len * 20);
+
+ self.content = std.mem.trimStart(u8, self.content, &std.ascii.whitespace);
+
+ if (self.content.len == 0) return null;
+
+ var index: usize = 0;
+
+ while (self.content.len > index) {
+ const char = self.content[index];
+
+ if (std.mem.indexOfScalar(u8, quotes, char) != null) {
+ index += 1;
+ while (self.content.len > index) {
+ if (self.content[index] == char) {
+ index += 1;
+ break;
+ }
+ index += 1;
+ }
+ } else if (std.ascii.isWhitespace(char)) {
+ break;
+ }
+ index += 1;
+ }
+
+ const block = self.content[0..index];
+ self.content = self.content[index..];
+
+ return block ++ " ";
+ }
+ };
+}
+
+pub const Style = File("style", StringIterator("\"'"));
+pub const Script = File("script", StringIterator("\"'`"));
+pub const Html = File(null, StringIterator("\"'"));