From 2e8d29bb96b1d3f5c92409269606a3cf6f4b1065 Mon Sep 17 00:00:00 2001 From: JaviLib Date: Sun, 22 Feb 2026 04:53:47 +0100 Subject: [PATCH] feat: server-side Markdown rendering with goldmark v1.6.0 - Implement renderMarkdown() in http.go using goldmark - Add goldmark extension: GFM, TaskList, Typographer - Remove frontend regex-based markdown processing - Update go.mod/go.sum with goldmark dependency --- go.mod | 1 + go.sum | 2 ++ pkg/channels/http.go | 25 ++++++++++++++++++++++++- pkg/channels/http_templates/index.html | 7 ------- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 1f88639c8..5d8528ecb 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/slack-go/slack v0.17.3 github.com/stretchr/testify v1.11.1 github.com/tencent-connect/botgo v0.2.1 + github.com/yuin/goldmark v1.6.0 golang.org/x/oauth2 v0.35.0 ) diff --git a/go.sum b/go.sum index 0e95bf5cd..22743d3e4 100644 --- a/go.sum +++ b/go.sum @@ -149,6 +149,8 @@ github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3i github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68= +github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y= diff --git a/pkg/channels/http.go b/pkg/channels/http.go index 044d1dc25..31313ff9d 100644 --- a/pkg/channels/http.go +++ b/pkg/channels/http.go @@ -7,10 +7,13 @@ import ( "fmt" "html/template" "net/http" + "strings" "sync" "time" "github.com/gorilla/websocket" + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" "github.com/sipeed/picoclaw/pkg/bus" "github.com/sipeed/picoclaw/pkg/config" @@ -128,9 +131,12 @@ func (c *HTTPChannel) Send(ctx context.Context, msg bus.OutboundMessage) error { return nil } + // Render Markdown to HTML before sending + renderedContent := renderMarkdown(msg.Content) + wsMsg := WSMessage{ Type: "response", - Content: msg.Content, + Content: renderedContent, ChatID: msg.ChatID, } @@ -272,4 +278,21 @@ func (c *HTTPChannel) removeSession(chatID string) { func generateChatID(r *http.Request) string { return fmt.Sprintf("web_%d", time.Now().UnixNano()) +} + +// renderMarkdown converts Markdown to HTML using goldmark +func renderMarkdown(input string) string { + md := goldmark.New( + goldmark.WithExtensions( + extension.GFM, + extension.TaskList, + extension.Typographer, + ), + ) + + var buf strings.Builder + if err := md.Convert([]byte(input), &buf); err != nil { + return input // fallback to plain text on error + } + return buf.String() } \ No newline at end of file diff --git a/pkg/channels/http_templates/index.html b/pkg/channels/http_templates/index.html index 224485d1d..62c425a67 100644 --- a/pkg/channels/http_templates/index.html +++ b/pkg/channels/http_templates/index.html @@ -247,13 +247,6 @@ function addMessage(content, type) { const div = document.createElement('div'); div.className = `message ${type}`; - - // Simple markdown-like formatting for code blocks - content = content.replace(/```(\w*)\n?([\s\S]*?)```/g, '
$2
'); - content = content.replace(/`([^`]+)`/g, '$1'); - content = content.replace(/\*\*([^*]+)\*\*/g, '$1'); - content = content.replace(/\n/g, '
'); - div.innerHTML = content; chatContainer.appendChild(div); chatContainer.scrollTop = chatContainer.scrollHeight;