//! Helper function collection to provide ascii encodings for styling outputs. //! Stylings are implemented such that they can be nested in anyway to support //! multiple styles (i.e. bold and italic). //! //! Stylings however also include highlighting for specific terminal capabilities. //! For example url highlighting. // taken from https://github.com/rockorager/libvaxis/blob/main/src/Cell.zig (MIT-License) // with slight modifications fg: Color = .default, bg: Color = .default, ul: Color = .default, cursor: bool = false, ul_style: Underline = .off, emphasis: []const Emphasis, pub const Underline = enum { off, single, double, curly, dotted, dashed, }; pub const Emphasis = enum(u8) { reset = 0, bold = 1, dim, italic, underline, blink, invert = 7, hidden, strikethrough, }; pub fn eql(this: Style, other: Style) bool { return meta.eql(this, other); } pub fn value(this: Style, writer: *std.Io.Writer, cp: u21) !void { var buffer: [4]u8 = undefined; const bytes = try unicode.utf8Encode(cp, &buffer); assert(bytes > 0); // build ansi sequence for 256 colors ... // foreground try writer.printAscii("\x1b[", .{}); try this.fg.write(writer, .fg); // background try writer.printAsciiChar(';', .{}); try this.bg.write(writer, .bg); // underline // FIX assert that if the underline property is set that the ul style and the attribute for underlining is available try writer.printAsciiChar(';', .{}); try this.ul.write(writer, .ul); // append styles (aka attributes like bold, italic, strikethrough, etc.) for (this.emphasis) |attribute| try writer.print(";{d}", .{@intFromEnum(attribute)}); try writer.printAsciiChar('m', .{}); // content try writer.printAscii(buffer[0..bytes], .{}); try writer.printAscii("\x1b[0m", .{}); } // TODO implement helper functions for terminal capabilities: // - links / url display (osc 8) // - show / hide cursor? const std = @import("std"); const unicode = std.unicode; const meta = std.meta; const assert = std.debug.assert; const Color = @import("color.zig").Color; const Style = @This();