Files
zterm/src/style.zig

79 lines
2.2 KiB
Zig

//! 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);
}
// TODO might be useful to use the std.ascii stuff!
pub fn value(this: Style, writer: anytype, 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 format(writer, "\x1b[", .{});
try this.fg.write(writer, .fg);
// background
try format(writer, ";", .{});
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 format(writer, ";", .{});
try this.ul.write(writer, .ul);
// append styles (aka attributes like bold, italic, strikethrough, etc.)
for (this.emphasis) |attribute| try format(writer, ";{d}", .{@intFromEnum(attribute)});
try format(writer, "m", .{});
// content
try format(writer, "{s}", .{buffer[0..bytes]});
try format(writer, "\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 format = std.fmt.format;
const Color = @import("color.zig").Color;
const Style = @This();