From a3d0b7af9adbdd9290dba1f25941be5db70dc20c Mon Sep 17 00:00:00 2001 From: Yves Biener Date: Sun, 13 Oct 2024 16:39:51 +0200 Subject: [PATCH] mod(node2buffer): add styling to parsed contents --- src/widget/PopupMenu.zig | 7 ++- src/widget/ViewPort.zig | 15 ++++++- src/widget/node2buffer.zig | 90 +++++++++++++++++++++++++++++--------- 3 files changed, 88 insertions(+), 24 deletions(-) diff --git a/src/widget/PopupMenu.zig b/src/widget/PopupMenu.zig index 90d00c7..27d4bac 100644 --- a/src/widget/PopupMenu.zig +++ b/src/widget/PopupMenu.zig @@ -37,6 +37,10 @@ pub fn update(this: *@This(), event: Event) ?Event { // Home return .{ .path = "./doc/home.md" }; } + if (key.matches('t', .{})) { + // test + return .{ .path = "./doc/test.md" }; + } }, else => {}, } @@ -55,6 +59,7 @@ pub fn draw(this: *@This(), win: vaxis.Window) void { \\ \\**a** about \\**h** home + \\**t** test ; var zmd = Zmd.init(this.allocator); defer zmd.deinit(); @@ -63,7 +68,7 @@ pub fn draw(this: *@This(), win: vaxis.Window) void { defer cells.deinit(); zmd.parse(msg) catch @panic("failed to parse markdown file"); - node2buffer.toBuffer(zmd.nodes.items[0], this.allocator, msg, &cells, .{}) catch @panic("failed to transform to cell array"); + node2buffer.toBuffer(zmd.nodes.items[0], this.allocator, msg, &cells, .{}, null) catch @panic("failed to transform to cell array"); var col: usize = 0; var row: usize = 0; diff --git a/src/widget/ViewPort.zig b/src/widget/ViewPort.zig index d1e11ae..2f4c79e 100644 --- a/src/widget/ViewPort.zig +++ b/src/widget/ViewPort.zig @@ -77,7 +77,14 @@ pub fn update(this: *@This(), event: Event) void { this.buffer.clearRetainingCapacity(); zmd.parse(this.contents.?) catch @panic("failed to parse markdown contents"); - node2buffer.toBuffer(zmd.nodes.items[0], this.allocator, this.contents.?, &this.buffer, .{}) catch @panic("failed to transform to cell array"); + node2buffer.toBuffer( + zmd.nodes.items[0], + this.allocator, + this.contents.?, + &this.buffer, + .{}, + null, + ) catch @panic("failed to transform to cell array"); }, else => {}, } @@ -95,7 +102,11 @@ pub fn draw(this: *@This(), win: vaxis.Window) void { for (this.buffer.items) |cell| { if (bounds.above(pos.y)) break; - // if (!bounds.colInside(pos.x)) continue; // FIX: how can I prevent writes out of bounce of the viewport? + + if (!bounds.colInside(pos.x)) { + pos.x = 0; + pos.y += 1; + } this.view.writeCell(win, pos.x, pos.y, cell); if (std.mem.eql(u8, cell.char.grapheme, "\n")) { diff --git a/src/widget/node2buffer.zig b/src/widget/node2buffer.zig index 19ee4e7..02ee290 100644 --- a/src/widget/node2buffer.zig +++ b/src/widget/node2buffer.zig @@ -3,45 +3,69 @@ 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), s: vaxis.Cell.Style) !void { - const content = switch (node.token.element.type) { - .text => input[node.token.start..node.token.end], - .code, .block => node.content, - else => "", - }; - var style = s; +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 seperator, etc.) // determine general styling changes switch (node.token.element.type) { .bold => { style.bold = true; - }, - .bold_close => { - style.bold = false; + next_start = node.token.start; + style.fg = .{ .index = 5 }; }, .italic => { style.italic = true; - }, - .italic_close => { - style.italic = false; + next_start = node.token.start; + style.fg = .{ .index = 2 }; }, .block => { // TODO: what should I do with blocks? - }, - .block_close => { - // TODO: what should I do with blocks? + style.fg = .{ .index = 7 }; + next_start = node.token.start; }, .code => { - style.dim = true; + next_start = node.token.start; + style.fg = .{ .index = 6 }; }, - .code_close => { - style.dim = false; + .href => { + next_start = node.token.start; + style.fg = .{ .index = 8 }; }, 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], + .bold_close, .italic_close, .block_close, .code_close, .title_close, .href_close => { + if (next_start) |s| { + next_start = null; + const e = node.token.end; + std.log.debug("start - end: {d}..{d}", .{ s, e }); + std.log.debug("content: {s}", .{input[s..e]}); + break :value input[s..e]; + } + break :value ""; + }, + else => { + break :value ""; + }, + } + }; + + // display content switch (node.token.element.type) { - .root, .none, .eof => {}, .linebreak, .paragraph => { try array.append(.{ .char = .{ .grapheme = "\n" }, @@ -111,7 +135,31 @@ pub fn toBuffer(node: *zmd.Node, allocator: std.mem.Allocator, input: []const u8 }, } + // 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); + try toBuffer(child_node, allocator, input, array, style, next_start); } }