All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 31s
179 lines
5.3 KiB
Zig
179 lines
5.3 KiB
Zig
///! Transform a given `zmd.Note` into a buffer which can be used by any `vaxis.widgets.View`
|
|
const std = @import("std");
|
|
const vaxis = @import("vaxis");
|
|
const zmd = @import("zmd");
|
|
|
|
pub fn toBuffer(
|
|
node: *zmd.Node,
|
|
allocator: std.mem.Allocator,
|
|
input: []const u8,
|
|
array: *std.ArrayList(vaxis.Cell),
|
|
sty: vaxis.Cell.Style,
|
|
start: ?usize,
|
|
) !void {
|
|
var next_start: ?usize = start;
|
|
var style = sty;
|
|
// FIXME: support list display
|
|
// TODO: improve code block listings (i.e. add line numbers with corresponding separator, etc.)
|
|
|
|
// determine general styling changes
|
|
switch (node.token.element.type) {
|
|
.bold => {
|
|
style.bold = true;
|
|
next_start = node.token.start;
|
|
style.fg = .{ .index = 5 };
|
|
},
|
|
.italic => {
|
|
style.italic = true;
|
|
next_start = node.token.start;
|
|
style.fg = .{ .index = 2 };
|
|
},
|
|
.block => {
|
|
// TODO: what should I do with blocks?
|
|
style.fg = .{ .index = 7 };
|
|
next_start = node.token.start;
|
|
},
|
|
.code => {
|
|
next_start = node.token.start;
|
|
style.fg = .{ .index = 6 };
|
|
},
|
|
.href => {
|
|
next_start = node.token.start;
|
|
style.fg = .{ .index = 8 };
|
|
},
|
|
.link => {
|
|
style.fg = .{ .index = 3 };
|
|
},
|
|
else => {},
|
|
}
|
|
|
|
// determine content that needs to be displayed
|
|
const content = value: {
|
|
switch (node.token.element.type) {
|
|
.text => break :value input[node.token.start..node.token.end],
|
|
.link => break :value input[node.token.start + 1 .. node.token.start + 1 + node.title.?.len],
|
|
// TODO: use corresponding link contents to create 'real' links using escape sequences
|
|
.bold_close, .italic_close, .block_close, .code_close, .title_close, .href_close => {
|
|
if (next_start) |s| {
|
|
next_start = null;
|
|
break :value input[s..node.token.end];
|
|
}
|
|
break :value "";
|
|
},
|
|
else => {
|
|
break :value "";
|
|
},
|
|
}
|
|
};
|
|
|
|
// display content
|
|
switch (node.token.element.type) {
|
|
.linebreak, .paragraph => {
|
|
try array.append(.{
|
|
.char = .{ .grapheme = "\n" },
|
|
.style = style,
|
|
});
|
|
style.ul_style = .off;
|
|
},
|
|
.h1 => {
|
|
style.ul_style = .single;
|
|
try array.append(.{
|
|
.char = .{ .grapheme = "#" },
|
|
.style = style,
|
|
});
|
|
},
|
|
.h2 => {
|
|
style.ul_style = .single;
|
|
for (0..2) |_| {
|
|
try array.append(.{
|
|
.char = .{ .grapheme = "#" },
|
|
.style = style,
|
|
});
|
|
}
|
|
},
|
|
.h3 => {
|
|
style.ul_style = .single;
|
|
for (0..3) |_| {
|
|
try array.append(.{
|
|
.char = .{ .grapheme = "#" },
|
|
.style = style,
|
|
});
|
|
}
|
|
},
|
|
.h4 => {
|
|
style.ul_style = .single;
|
|
for (0..4) |_| {
|
|
try array.append(.{
|
|
.char = .{ .grapheme = "#" },
|
|
.style = style,
|
|
});
|
|
}
|
|
},
|
|
.h5 => {
|
|
style.ul_style = .single;
|
|
for (0..5) |_| {
|
|
try array.append(.{
|
|
.char = .{ .grapheme = "#" },
|
|
.style = style,
|
|
});
|
|
}
|
|
},
|
|
.h6 => {
|
|
style.ul_style = .single;
|
|
for (0..6) |_| {
|
|
try array.append(.{
|
|
.char = .{ .grapheme = "#" },
|
|
.style = style,
|
|
});
|
|
}
|
|
},
|
|
.link => {
|
|
style.ul_style = .single;
|
|
const uri = input[node.token.start + 1 + node.title.?.len + 2 .. node.token.start + 1 + node.title.?.len + 2 + node.href.?.len];
|
|
for (content, 0..) |_, i| {
|
|
try array.append(.{
|
|
.link = .{ .uri = uri },
|
|
.char = .{ .grapheme = content[i .. i + 1] },
|
|
.style = style,
|
|
});
|
|
}
|
|
},
|
|
else => {
|
|
for (content, 0..) |_, i| {
|
|
try array.append(.{
|
|
.char = .{ .grapheme = content[i .. i + 1] },
|
|
.style = style,
|
|
});
|
|
}
|
|
},
|
|
}
|
|
|
|
// close styling after creating the corresponding cells
|
|
switch (node.token.element.type) {
|
|
.bold_close => {
|
|
style.bold = false;
|
|
style.fg = .default;
|
|
},
|
|
.italic_close => {
|
|
style.italic = false;
|
|
style.fg = .default;
|
|
},
|
|
.block_close => {
|
|
// TODO: what should I do with blocks?
|
|
style.fg = .default;
|
|
},
|
|
.code_close => {
|
|
style.fg = .default;
|
|
},
|
|
.href_close => {
|
|
style.fg = .default;
|
|
},
|
|
else => {},
|
|
}
|
|
|
|
// run conversion for all childrens
|
|
for (node.children.items) |child_node| {
|
|
try toBuffer(child_node, allocator, input, array, style, next_start);
|
|
}
|
|
}
|