Skip to content

Commit

Permalink
美化首页复杂评论内容的展示
Browse files Browse the repository at this point in the history
去图片、链接、表格、代码块。
  • Loading branch information
movsb committed Apr 22, 2024
1 parent a99f41d commit 08e3718
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 1 deletion.
79 changes: 79 additions & 0 deletions service/modules/renderers/prettifier.go
@@ -0,0 +1,79 @@
package renderers

import (
"bytes"
"fmt"
"strings"

"golang.org/x/net/html"
)

// 简化并美化 Markdown 的展示。
// 比如:
// - 不显示复杂的链接、图片、表格、代码块等元素。
// - 不显示脚注。
type Prettifier struct {
}

func (p *Prettifier) Prettify(htmlContent string) (string, error) {
doc, err := html.Parse(strings.NewReader(htmlContent))
if err != nil {
return "", err
}

buf := bytes.NewBuffer(nil)

var walk func(buf *bytes.Buffer, node *html.Node)
walk = func(buf *bytes.Buffer, node *html.Node) {
switch node.Type {
case html.DocumentNode:
case html.TextNode:
buf.WriteString(node.Data)
case html.ElementNode:
switch node.Data {
case `a`:
sub := bytes.NewBuffer(nil)
for c := node.FirstChild; c != nil; c = c.NextSibling {
walk(sub, c)
}
buf.WriteString(fmt.Sprintf(`[链接:%s]`, sub.String()))
return
case `img`:
var alt string
for _, a := range node.Attr {
if strings.ToLower(a.Key) == `alt` {
alt = a.Val
}
}
if alt == "" {
alt = "图片"
}
buf.WriteString(fmt.Sprintf(`[图片:%s]`, alt))
case `div`:
for _, a := range node.Attr {
if strings.ToLower(a.Key) == `class` {
if strings.Contains(a.Val, `footnotes`) {
return
}
}
}
case `pre`:
if node.FirstChild != nil && node.FirstChild.NextSibling == nil && node.FirstChild.Data == `code` {
buf.WriteString(`[代码]`)
return
}
case `table`:
buf.WriteString(`[表格]`)
return
}
default:
return
}
for c := node.FirstChild; c != nil; c = c.NextSibling {
walk(buf, c)
}
}

walk(buf, doc)
return buf.String(), nil
}
60 changes: 60 additions & 0 deletions service/modules/renderers/prettifier_test.go
@@ -0,0 +1,60 @@
package renderers_test

import (
"log"
"strings"
"testing"

"github.com/movsb/taoblog/service/modules/renderers"
)

func TestPrettifier(t *testing.T) {
cases := []struct {
ID float32
Options []renderers.Option
Description string
Markdown string
Text string
}{
{
ID: 1,
Markdown: `![文本](/URL)`,
Text: `[图片:文本]`,
},
{
ID: 2,
Markdown: `[文本](链接)`,
Text: `[链接:文本]`,
},
{
ID: 3,
Markdown: "代码:\n\n```go\npackage main\n```",
Text: "代码:\n[代码]",
},
{
ID: 4,
Markdown: `|h1|h2|
|-|-|
|1|2|
`,
Text: `[表格]`,
},
}
for _, tc := range cases {
md := renderers.NewMarkdown(tc.Options...)
if tc.ID == 6.0 {
log.Println(`debug`)
}
_, html, err := md.Render(tc.Markdown)
if err != nil {
t.Fatal(err)
}
text, err := (&renderers.Prettifier{}).Prettify(html)
if err != nil {
t.Fatal(err)
}
if strings.TrimSpace(text) != strings.TrimSpace(tc.Text) {
t.Fatalf("not equal:\nMarkdown:%s\nExpected:%s\nGot:%s\n\n", tc.Markdown, tc.Text, text)
}
}
}
2 changes: 1 addition & 1 deletion theme/blog/templates/home.html
Expand Up @@ -26,7 +26,7 @@ <h2>近期评论</h2>
<a href="/{{.PostID}}/">{{.PostTitle}}</a>
<ul class=post-comment-list>
{{- range .Comments}}
<li><p><b>{{.Author}}</b>:{{.Text}}</p></li>
<li><p><b>{{.Author}}</b>:{{.PrettyText}}</p></li>
{{- end }}
</ul>
</li>
Expand Down
10 changes: 10 additions & 0 deletions theme/data/comment.go
Expand Up @@ -4,6 +4,7 @@ import (
"context"

"github.com/movsb/taoblog/protocols"
"github.com/movsb/taoblog/service/modules/renderers"
)

// Comment ...
Expand All @@ -19,6 +20,15 @@ func (c *Comment) Text() string {
return c.Content
}

func (c *Comment) PrettyText() string {
prettifier := renderers.Prettifier{}
text, err := prettifier.Prettify(c.Content)
if err != nil {
return c.Text()
}
return text
}

// LatestCommentsByPost ...
type LatestCommentsByPost struct {
PostTitle string
Expand Down

0 comments on commit 08e3718

Please sign in to comment.