diff options
Diffstat (limited to 'src/frontend/File.zig')
| -rw-r--r-- | src/frontend/File.zig | 91 |
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("\"'")); |