zcatui/examples/markdown_demo.zig
reugenio 7abc87a4f5 feat: zcatui v2.2 - Complete feature set with 13 new modules
New modules (13):
- src/resize.zig: SIGWINCH terminal resize detection
- src/drag.zig: Mouse drag state and Splitter panels
- src/diagnostic.zig: Elm-style error messages with code snippets
- src/debug.zig: Debug overlay (FPS, timing, widget count)
- src/profile.zig: Performance profiling with scoped timers
- src/sixel.zig: Sixel graphics encoding for terminal images
- src/async_loop.zig: epoll-based async event loop with timers
- src/compose.zig: Widget composition utilities
- src/shortcuts.zig: Keyboard shortcut registry
- src/widgets/logo.zig: ASCII art logo widget

Enhanced modules:
- src/layout.zig: Added Constraint.ratio(num, denom)
- src/terminal.zig: Integrated resize handling
- src/root.zig: Re-exports all new modules

New examples (9):
- resize_demo, splitter_demo, dirtree_demo
- help_demo, markdown_demo, progress_demo
- spinner_demo, syntax_demo, viewport_demo

Package manager:
- build.zig.zon: Zig package manager support

Stats: 60+ source files, 186+ tests, 20 executables

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 22:46:06 +01:00

140 lines
3.7 KiB
Zig

//! 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)),
);
}