From 00920ddd36a8ebb851b52c3c048c0017753176bd Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Thu, 30 Jul 2026 10:24:19 +0200 Subject: complete js parser + minifier --- src/z/parser/js/formatter.zig | 67 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/z/parser/js/formatter.zig (limited to 'src/z/parser/js/formatter.zig') diff --git a/src/z/parser/js/formatter.zig b/src/z/parser/js/formatter.zig new file mode 100644 index 0000000..fbea7bc --- /dev/null +++ b/src/z/parser/js/formatter.zig @@ -0,0 +1,67 @@ +const std = @import("std"); + +pub const FormatOptions = struct { + indent_size: usize = 4, + minify: bool = false, +}; + +pub const Formatter = struct { + buf: []u8, + pos: usize, + indent_level: usize, + options: FormatOptions, + last_char: u8 = 0, + + pub fn write(self: *@This(), s: []const u8) void { + if (self.options.minify) { + if (s.len == 0) return; + var start: usize = 0; + while (start < s.len and s[start] == ' ') start += 1; + var end = s.len; + while (end > start and s[end - 1] == ' ') end -= 1; + if (start >= end) return; + const trimmed = s[start..end]; + if (self.last_char != 0 and isWordChar(self.last_char) and isWordChar(trimmed[0])) { + self.buf[self.pos] = ' '; + self.pos += 1; + } + @memcpy(self.buf[self.pos..][0..trimmed.len], trimmed); + self.pos += trimmed.len; + self.last_char = trimmed[trimmed.len - 1]; + } else { + @memcpy(self.buf[self.pos..][0..s.len], s); + self.pos += s.len; + } + } + + pub fn writeChar(self: *@This(), c: u8) void { + self.buf[self.pos] = c; + self.pos += 1; + self.last_char = c; + } + + pub fn writeIndent(self: *@This()) void { + if (self.options.minify) return; + const spaces = self.indent_level * self.options.indent_size; + var i: usize = 0; + while (i < spaces) : (i += 1) { + self.writeChar(' '); + } + } + + pub fn newline(self: *@This()) void { + if (self.options.minify) return; + self.writeChar('\n'); + } + + pub fn writeSpace(self: *@This()) void { + if (!self.options.minify) self.writeChar(' '); + } + + fn isWordChar(c: u8) bool { + return switch (c) { + 'a'...'z', 'A'...'Z', '0'...'9', '_', '$' => true, + else => false, + }; + } +}; -- cgit v1.2.3-70-g09d2