//! Markdown Viewer Demo //! //! Run with: zig build markdown-demo const std = @import("std"); const zcatui = @import("zcatui"); const Terminal = zcatui.Terminal; const Rect = zcatui.Rect; const Buffer = zcatui.Buffer; const Style = zcatui.Style; const Color = zcatui.Color; const Block = zcatui.widgets.Block; const Borders = zcatui.widgets.Borders; const Markdown = zcatui.widgets.Markdown; const sample_markdown = \\# Welcome to zcatui \\ \\A **TUI library** for Zig, inspired by _ratatui_. \\ \\## Features \\ \\- 35+ widgets \\- Event handling (keyboard, mouse) \\- Animations with easing \\- Clipboard support (OSC 52) \\- Syntax highlighting \\ \\## Code Example \\ \\```zig \\const zcatui = @import("zcatui"); \\ \\pub fn main() !void { \\ var term = try zcatui.Terminal.init(allocator); \\ defer term.deinit(); \\ // ... \\} \\``` \\ \\## Installation \\ \\Add to your `build.zig.zon`: \\ \\```zon \\.dependencies = .{ \\ .zcatui = .{ .url = "..." }, \\}, \\``` \\ \\> **Note**: This is a blockquote with important information \\> that spans multiple lines. \\ \\### Links \\ \\Check out the [documentation](https://git.reugenio.com/reugenio/zcatui). \\ \\--- \\ \\*Thank you for using zcatui!* ; /// State for the demo const State = struct { scroll_offset: u16 = 0, running: bool = true, }; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); var term = try Terminal.init(allocator); defer term.deinit(); var state = State{}; while (state.running) { try term.drawWithContext(&state, render); if (try term.pollEvent(100)) |event| { switch (event) { .key => |key| { switch (key.code) { .char => |c| { if (c == 'q') state.running = false; if (c == 'j') state.scroll_offset +|= 1; if (c == 'k' and state.scroll_offset > 0) state.scroll_offset -= 1; }, .up => { if (state.scroll_offset > 0) state.scroll_offset -= 1; }, .down => { state.scroll_offset +|= 1; }, .page_up => { state.scroll_offset -|= 10; }, .page_down => { state.scroll_offset +|= 10; }, .home => state.scroll_offset = 0, .esc => state.running = false, else => {}, } }, else => {}, } } } } fn render(state: *State, area: Rect, buf: *Buffer) void { // Border const block = Block.init() .title(" Markdown Viewer ") .setBorders(Borders.all) .borderStyle((Style{}).fg(Color.cyan)); block.render(area, buf); // Markdown content const inner = Rect.init(2, 2, area.width -| 4, area.height -| 5); const md = Markdown.init(sample_markdown) .setScroll(state.scroll_offset); md.render(inner, buf); // Footer with scroll info var footer_buf: [64]u8 = undefined; const footer = std.fmt.bufPrint(&footer_buf, "Line {d} | j/k or up/down to scroll, PgUp/PgDn, q to quit", .{state.scroll_offset}) catch "..."; _ = buf.setString( 2, area.height -| 2, footer, (Style{}).fg(Color.rgb(100, 100, 100)), ); }