Files
gastown/internal/ui/markdown.go
Ryan Snodgrass e1f2bb8b4b feat(ui): import comprehensive UX system from beads
Import beads' UX design system into gastown:

- Add internal/ui/ package with Ayu theme colors and semantic styling
  - styles.go: AdaptiveColor definitions for light/dark mode
  - terminal.go: TTY detection, NO_COLOR/CLICOLOR support
  - markdown.go: Glamour rendering with agent mode bypass
  - pager.go: Smart paging with GT_PAGER support

- Add colorized help output (internal/cmd/help.go)
  - Group headers in accent color
  - Command names styled for scannability
  - Flag types and defaults muted

- Add gt thanks command (internal/cmd/thanks.go)
  - Contributor display with same logic as bd thanks
  - Styled with Ayu theme colors

- Update gt doctor to match bd doctor UX
  - Category grouping (Core, Infrastructure, Rig, Patrol, etc.)
  - Semantic icons (✓ ⚠ ✖) with Ayu colors
  - Tree connectors for detail lines
  - Summary line with pass/warn/fail counts
  - Warnings section at end with numbered issues

- Migrate existing styles to use ui package
  - internal/style/style.go uses ui.ColorPass etc.
  - internal/tui/feed/styles.go uses ui package colors

Co-Authored-By: SageOx <ox@sageox.ai>
2026-01-09 22:46:06 -08:00

66 lines
1.2 KiB
Go

package ui
import (
"os"
"github.com/charmbracelet/glamour"
"golang.org/x/term"
)
// RenderMarkdown renders markdown text with glamour styling.
// Returns raw markdown on failure for graceful degradation.
func RenderMarkdown(markdown string) string {
// agent mode outputs plain text for machine parsing
if IsAgentMode() {
return markdown
}
// no styling when colors are disabled
if !ShouldUseColor() {
return markdown
}
wrapWidth := getTerminalWidth()
renderer, err := glamour.NewTermRenderer(
glamour.WithAutoStyle(),
glamour.WithWordWrap(wrapWidth),
)
if err != nil {
return markdown
}
rendered, err := renderer.Render(markdown)
if err != nil {
return markdown
}
return rendered
}
// getTerminalWidth returns the terminal width for word wrapping.
// Caps at 100 chars for readability (research suggests 50-75 optimal, 80-100 comfortable).
// Falls back to 80 if detection fails.
func getTerminalWidth() int {
const (
defaultWidth = 80
maxWidth = 100
)
fd := int(os.Stdout.Fd())
if !term.IsTerminal(fd) {
return defaultWidth
}
width, _, err := term.GetSize(fd)
if err != nil || width <= 0 {
return defaultWidth
}
if width > maxWidth {
return maxWidth
}
return width
}