All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 48s
73 lines
2.1 KiB
Zig
73 lines
2.1 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
|
|
const std = @import("std");
|
|
|
|
const Color = @import("color.zig").Color;
|
|
|
|
pub const Style = @This();
|
|
|
|
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,
|
|
};
|
|
|
|
fg: Color = .default,
|
|
bg: Color = .default,
|
|
ul: Color = .default,
|
|
ul_style: Underline = .off,
|
|
emphasis: []const Emphasis,
|
|
|
|
pub fn eql(this: Style, other: Style) bool {
|
|
return std.meta.eql(this, other);
|
|
}
|
|
|
|
pub fn value(this: Style, writer: anytype, cp: u21) !void {
|
|
var buffer: [4]u8 = undefined;
|
|
const bytes = try std.unicode.utf8Encode(cp, &buffer);
|
|
std.debug.assert(bytes > 0);
|
|
// build ansi sequence for 256 colors ...
|
|
// foreground
|
|
try std.fmt.format(writer, "\x1b[", .{});
|
|
try this.fg.write(writer, .fg);
|
|
// background
|
|
try std.fmt.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 std.fmt.format(writer, ";", .{});
|
|
try this.ul.write(writer, .ul);
|
|
// append styles (aka attributes like bold, italic, strikethrough, etc.)
|
|
for (this.emphasis) |attribute| try std.fmt.format(writer, ";{d}", .{@intFromEnum(attribute)});
|
|
try std.fmt.format(writer, "m", .{});
|
|
// content
|
|
try std.fmt.format(writer, "{s}", .{buffer[0..bytes]});
|
|
try std.fmt.format(writer, "\x1b[0m", .{});
|
|
}
|
|
|
|
// TODO implement helper functions for terminal capabilities:
|
|
// - links / url display (osc 8)
|
|
// - show / hide cursor?
|