mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
The theme, colour profile, Markdown/math renderer, tool cards, diff view, assistant block and clipboard writes move out of internal/frontend/cli into internal/frontend/termrender, so a terminal frontend other than cli can draw the same bytes without importing cli. cli now calls termrender for every style, width, box and Markdown helper; view_helpers.go stays in cli. termrender exports the surface a frontend draws with: Bold/Dim/Green/Red/ Yellow/Accent/Reverse, VisibleWidth/PadRight/Boxed, ConfigureTheme, ConfigureThemeFromConfig(ForTTYOutput), ActiveTheme/ThemeName and the ThemeStyle/ThemeFg/ThemeLipColor/ApplyTextareaTheme helpers over an exported Palette/Color, RenderMarkdown and MarkdownRenderer, AssistantBlock, ToolCard/ ToolDot/ToolHead/ToolArg/ToolDisplayName, DiffBlock/DiffStat, CopyToClipboard with ClipboardCopyMsg, ANSIConsoleReady and SetColorProfile. Transcript helpers nothing calls (edgeScrollDir, selSpan, scrollbarThumb) are dropped with their tests, and the clipboard message loses the seq and status-hint fields no caller set. The metadata-command test now asserts that version/help never reach the TTY theme setup, through a cli-side seam, since the terminal probe it used to swap is termrender's. The repolint baseline diff is the moved files' prior essay debt carried to their new paths (mathnode.go, md.go, width_test.go; transcript.go's is paid off), plus orphan budget for the eight exports whose consumer, the new terminal UI, is not in the tree yet (ToolCard, DiffBlock, AssistantBlock, RenderMarkdown, CopyToClipboard, ApplyTextareaTheme, ThemeName) or which only a cli test drives (SetColorProfile). Wiring the UI reclaims that budget.
69 lines
1.7 KiB
Go
69 lines
1.7 KiB
Go
package termrender
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/yuin/goldmark/ast"
|
|
"github.com/yuin/goldmark/parser"
|
|
"github.com/yuin/goldmark/text"
|
|
)
|
|
|
|
var kindMath = ast.NewNodeKind("Math")
|
|
|
|
type mathNode struct {
|
|
ast.BaseInline
|
|
value string // Unicode rendering for terminal display
|
|
source string // original LaTeX source (e.g. "\alpha", "\frac{1}{2}")
|
|
display bool
|
|
}
|
|
|
|
func (n *mathNode) Kind() ast.NodeKind { return kindMath }
|
|
func (n *mathNode) Dump(src []byte, level int) { ast.DumpHelper(n, src, level, nil, nil) }
|
|
|
|
type mathParser struct{}
|
|
|
|
func (p *mathParser) Trigger() []byte { return []byte{'$'} }
|
|
|
|
func (p *mathParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node {
|
|
line, _ := block.PeekLine()
|
|
if len(line) == 0 || line[0] != '$' {
|
|
return nil
|
|
}
|
|
display := len(line) >= 2 && line[1] == '$'
|
|
delim := 1
|
|
if display {
|
|
delim = 2
|
|
}
|
|
|
|
rest := line[delim:]
|
|
var closeAt int
|
|
if display {
|
|
closeAt = bytes.Index(rest, []byte("$$"))
|
|
} else {
|
|
closeAt = bytes.IndexByte(rest, '$')
|
|
}
|
|
if closeAt < 0 {
|
|
return nil
|
|
}
|
|
inner := rest[:closeAt]
|
|
if len(bytes.TrimSpace(inner)) == 0 {
|
|
return nil
|
|
}
|
|
|
|
// Currency guard (markdown-it-texmath rule): a single-$ span only counts as
|
|
// math when the open isn't followed by space, the close isn't preceded by
|
|
// space, and the char after the close isn't a digit — so "$5 and $10" stays
|
|
// prose. Display $$ is unambiguous and skips the check.
|
|
if !display {
|
|
after := closeAt + 1
|
|
if inner[0] == ' ' || inner[len(inner)-1] == ' ' ||
|
|
(after < len(rest) && rest[after] >= '0' && rest[after] <= '9') {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
block.Advance(delim + closeAt + delim)
|
|
src := string(bytes.TrimSpace(inner))
|
|
return &mathNode{value: latexToUnicode(src), source: src, display: display}
|
|
}
|