mod(structure): update project structure
Remove examples, add description for design goals in README.md and apply re-names and naming changes accordingly for the project structure. Implement a flat hierachry, as the library shall remain pretty simple.
This commit is contained in:
232
src/style.zig
Normal file
232
src/style.zig
Normal file
@@ -0,0 +1,232 @@
|
||||
//! 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 ctlseqs = @import("ctlseqs.zig");
|
||||
|
||||
const Color = @import("color.zig").Color;
|
||||
|
||||
pub const Style = @This();
|
||||
|
||||
pub const Underline = enum {
|
||||
off,
|
||||
single,
|
||||
double,
|
||||
curly,
|
||||
dotted,
|
||||
dashed,
|
||||
};
|
||||
|
||||
fg: Color = .default,
|
||||
bg: Color = .default,
|
||||
ul: Color = .default,
|
||||
ul_style: Underline = .off,
|
||||
|
||||
bold: bool = false,
|
||||
dim: bool = false,
|
||||
italic: bool = false,
|
||||
blink: bool = false,
|
||||
reverse: bool = false,
|
||||
invisible: bool = false,
|
||||
strikethrough: bool = false,
|
||||
|
||||
pub fn eql(this: Style, other: Style) bool {
|
||||
return this.fg.eql(other.fg) and
|
||||
this.bg.eql(other.bg) and
|
||||
this.ul.eql(other.ul) and
|
||||
other.ul_style == this.ul_style and
|
||||
other.bold == this.bold and
|
||||
other.dim == this.dim and
|
||||
other.italic == this.italic and
|
||||
other.blink == this.blink and
|
||||
other.reverse == this.reverse and
|
||||
other.invisible == this.invisible and
|
||||
other.strikethrough == this.strikethrough;
|
||||
}
|
||||
|
||||
/// Merge _other_ `Style` to _this_ style and overwrite _this_ `Style`'s value
|
||||
/// if the _other_ value differs from the default value.
|
||||
pub fn merge(this: *Style, other: Style) void {
|
||||
if (other.fg != .default) this.fg = other.fg;
|
||||
if (other.bg != .default) this.bg = other.bg;
|
||||
if (other.ul != .default) this.ul = other.ul;
|
||||
if (other.ul_style != .off) this.ul_style = other.ul_style;
|
||||
if (other.bold != false) this.bold = other.bold;
|
||||
if (other.dim != false) this.dim = other.dim;
|
||||
if (other.italic != false) this.italic = other.italic;
|
||||
if (other.blink != false) this.blink = other.blink;
|
||||
if (other.reverse != false) this.reverse = other.reverse;
|
||||
if (other.invisible != false) this.invisible = other.invisible;
|
||||
if (other.strikethrough != false) this.strikethrough = other.strikethrough;
|
||||
}
|
||||
|
||||
fn start(this: Style, writer: anytype) !void {
|
||||
// foreground
|
||||
switch (this.fg) {
|
||||
.default => try std.fmt.format(writer, ctlseqs.fg_reset, .{}),
|
||||
.index => |idx| {
|
||||
switch (idx) {
|
||||
0...7 => {
|
||||
try std.fmt.format(writer, ctlseqs.fg_base, .{idx});
|
||||
},
|
||||
8...15 => {
|
||||
try std.fmt.format(writer, ctlseqs.fg_bright, .{idx - 8});
|
||||
},
|
||||
else => {
|
||||
try std.fmt.format(writer, ctlseqs.fg_indexed, .{idx});
|
||||
},
|
||||
}
|
||||
},
|
||||
.rgb => |rgb| {
|
||||
try std.fmt.format(writer, ctlseqs.fg_rgb, .{ rgb[0], rgb[1], rgb[2] });
|
||||
},
|
||||
}
|
||||
// background
|
||||
switch (this.bg) {
|
||||
.default => try std.fmt.format(writer, ctlseqs.bg_reset, .{}),
|
||||
.index => |idx| {
|
||||
switch (idx) {
|
||||
0...7 => {
|
||||
try std.fmt.format(writer, ctlseqs.bg_base, .{idx});
|
||||
},
|
||||
8...15 => {
|
||||
try std.fmt.format(writer, ctlseqs.bg_bright, .{idx});
|
||||
},
|
||||
else => {
|
||||
try std.fmt.format(writer, ctlseqs.bg_indexed, .{idx});
|
||||
},
|
||||
}
|
||||
},
|
||||
.rgb => |rgb| {
|
||||
try std.fmt.format(writer, ctlseqs.bg_rgb, .{ rgb[0], rgb[1], rgb[2] });
|
||||
},
|
||||
}
|
||||
// underline color
|
||||
switch (this.ul) {
|
||||
.default => try std.fmt.format(writer, ctlseqs.ul_reset, .{}),
|
||||
.index => |idx| {
|
||||
try std.fmt.format(writer, ctlseqs.ul_indexed, .{idx});
|
||||
},
|
||||
.rgb => |rgb| {
|
||||
try std.fmt.format(writer, ctlseqs.ul_rgb, .{ rgb[0], rgb[1], rgb[2] });
|
||||
},
|
||||
}
|
||||
// underline style
|
||||
switch (this.ul_style) {
|
||||
.off => try std.fmt.format(writer, ctlseqs.ul_off, .{}),
|
||||
.single => try std.fmt.format(writer, ctlseqs.ul_single, .{}),
|
||||
.double => try std.fmt.format(writer, ctlseqs.ul_double, .{}),
|
||||
.curly => try std.fmt.format(writer, ctlseqs.ul_curly, .{}),
|
||||
.dotted => try std.fmt.format(writer, ctlseqs.ul_dotted, .{}),
|
||||
.dashed => try std.fmt.format(writer, ctlseqs.ul_dashed, .{}),
|
||||
}
|
||||
// bold
|
||||
switch (this.bold) {
|
||||
true => try std.fmt.format(writer, ctlseqs.bold_set, .{}),
|
||||
false => try std.fmt.format(writer, ctlseqs.bold_dim_reset, .{}),
|
||||
}
|
||||
// dim
|
||||
switch (this.dim) {
|
||||
true => try std.fmt.format(writer, ctlseqs.dim_set, .{}),
|
||||
false => try std.fmt.format(writer, ctlseqs.bold_dim_reset, .{}),
|
||||
}
|
||||
// italic
|
||||
switch (this.italic) {
|
||||
true => try std.fmt.format(writer, ctlseqs.italic_set, .{}),
|
||||
false => try std.fmt.format(writer, ctlseqs.italic_reset, .{}),
|
||||
}
|
||||
// blink
|
||||
switch (this.blink) {
|
||||
true => try std.fmt.format(writer, ctlseqs.blink_set, .{}),
|
||||
false => try std.fmt.format(writer, ctlseqs.blink_reset, .{}),
|
||||
}
|
||||
// reverse
|
||||
switch (this.reverse) {
|
||||
true => try std.fmt.format(writer, ctlseqs.reverse_set, .{}),
|
||||
false => try std.fmt.format(writer, ctlseqs.reverse_reset, .{}),
|
||||
}
|
||||
// invisible
|
||||
switch (this.invisible) {
|
||||
true => try std.fmt.format(writer, ctlseqs.invisible_set, .{}),
|
||||
false => try std.fmt.format(writer, ctlseqs.invisible_reset, .{}),
|
||||
}
|
||||
// strikethrough
|
||||
switch (this.strikethrough) {
|
||||
true => try std.fmt.format(writer, ctlseqs.strikethrough_set, .{}),
|
||||
false => try std.fmt.format(writer, ctlseqs.strikethrough_reset, .{}),
|
||||
}
|
||||
}
|
||||
|
||||
fn end(this: Style, writer: anytype) !void {
|
||||
// foreground
|
||||
switch (this.fg) {
|
||||
.default => {},
|
||||
else => try std.fmt.format(writer, ctlseqs.fg_reset, .{}),
|
||||
}
|
||||
// background
|
||||
switch (this.bg) {
|
||||
.default => {},
|
||||
else => try std.fmt.format(writer, ctlseqs.bg_reset, .{}),
|
||||
}
|
||||
// underline color
|
||||
switch (this.ul) {
|
||||
.default => {},
|
||||
else => try std.fmt.format(writer, ctlseqs.ul_reset, .{}),
|
||||
}
|
||||
// underline style
|
||||
switch (this.ul_style) {
|
||||
.off => {},
|
||||
else => try std.fmt.format(writer, ctlseqs.ul_off, .{}),
|
||||
}
|
||||
// bold
|
||||
switch (this.bold) {
|
||||
true => try std.fmt.format(writer, ctlseqs.bold_dim_reset, .{}),
|
||||
false => {},
|
||||
}
|
||||
// dim
|
||||
switch (this.dim) {
|
||||
true => try std.fmt.format(writer, ctlseqs.bold_dim_reset, .{}),
|
||||
false => {},
|
||||
}
|
||||
// italic
|
||||
switch (this.italic) {
|
||||
true => try std.fmt.format(writer, ctlseqs.italic_reset, .{}),
|
||||
false => {},
|
||||
}
|
||||
// blink
|
||||
switch (this.blink) {
|
||||
true => try std.fmt.format(writer, ctlseqs.blink_reset, .{}),
|
||||
false => {},
|
||||
}
|
||||
// reverse
|
||||
switch (this.reverse) {
|
||||
true => try std.fmt.format(writer, ctlseqs.reverse_reset, .{}),
|
||||
false => {},
|
||||
}
|
||||
// invisible
|
||||
switch (this.invisible) {
|
||||
true => try std.fmt.format(writer, ctlseqs.invisible_reset, .{}),
|
||||
false => {},
|
||||
}
|
||||
// strikethrough
|
||||
switch (this.strikethrough) {
|
||||
true => try std.fmt.format(writer, ctlseqs.strikethrough_reset, .{}),
|
||||
false => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value(this: Style, writer: anytype, content: u8) !void {
|
||||
try this.start(writer);
|
||||
_ = try writer.write(&[_]u8{content});
|
||||
try this.end(writer);
|
||||
}
|
||||
|
||||
// TODO: implement helper functions for terminal capabilities:
|
||||
// - links / url display (osc 8)
|
||||
// - show / hide cursor?
|
||||
Reference in New Issue
Block a user