chore: update memo metadata description

pull/2629/head
Steven 1 year ago
parent bdc867d153
commit 7b0ceee57b

@ -15,7 +15,7 @@ import (
"github.com/usememos/memos/internal/util"
"github.com/usememos/memos/plugin/gomark/parser"
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
"github.com/usememos/memos/plugin/gomark/render/html"
"github.com/usememos/memos/plugin/gomark/render"
"github.com/usememos/memos/store"
)
@ -198,7 +198,7 @@ func getRSSItemDescription(content string) (string, error) {
if err != nil {
return "", err
}
result := html.NewHTMLRender().Render(nodes)
result := render.NewHTMLRender().Render(nodes)
return result, nil
}

@ -1 +1,14 @@
package render
import (
htmlrender "github.com/usememos/memos/plugin/gomark/render/html"
stringrender "github.com/usememos/memos/plugin/gomark/render/string"
)
func NewHTMLRender() *htmlrender.HTMLRender {
return htmlrender.NewHTMLRender()
}
func NewStringRender() *stringrender.StringRender {
return stringrender.NewStringRender()
}

@ -0,0 +1,169 @@
package string
import (
"bytes"
"github.com/usememos/memos/plugin/gomark/ast"
)
// StringRender renders AST to raw string.
type StringRender struct {
output *bytes.Buffer
context *RendererContext
}
type RendererContext struct {
}
// NewStringRender creates a new StringRender.
func NewStringRender() *StringRender {
return &StringRender{
output: new(bytes.Buffer),
context: &RendererContext{},
}
}
// RenderNode renders a single AST node to raw string.
func (r *StringRender) RenderNode(node ast.Node) {
switch n := node.(type) {
case *ast.LineBreak:
r.renderLineBreak(n)
case *ast.Paragraph:
r.renderParagraph(n)
case *ast.CodeBlock:
r.renderCodeBlock(n)
case *ast.Heading:
r.renderHeading(n)
case *ast.HorizontalRule:
r.renderHorizontalRule(n)
case *ast.Blockquote:
r.renderBlockquote(n)
case *ast.UnorderedList:
r.renderUnorderedList(n)
case *ast.OrderedList:
r.renderOrderedList(n)
case *ast.Bold:
r.renderBold(n)
case *ast.Italic:
r.renderItalic(n)
case *ast.BoldItalic:
r.renderBoldItalic(n)
case *ast.Code:
r.renderCode(n)
case *ast.Image:
r.renderImage(n)
case *ast.Link:
r.renderLink(n)
case *ast.Tag:
r.renderTag(n)
case *ast.Strikethrough:
r.renderStrikethrough(n)
case *ast.Text:
r.renderText(n)
default:
// Handle other block types if needed.
}
}
// RenderNodes renders a slice of AST nodes to raw string.
func (r *StringRender) RenderNodes(nodes []ast.Node) {
for _, node := range nodes {
r.RenderNode(node)
}
}
// Render renders the AST to raw string.
func (r *StringRender) Render(astRoot []ast.Node) string {
r.RenderNodes(astRoot)
return r.output.String()
}
func (r *StringRender) renderLineBreak(_ *ast.LineBreak) {
r.output.WriteString("\n")
}
func (r *StringRender) renderParagraph(node *ast.Paragraph) {
r.RenderNodes(node.Children)
}
func (r *StringRender) renderCodeBlock(node *ast.CodeBlock) {
r.output.WriteString(node.Content)
}
func (r *StringRender) renderHeading(node *ast.Heading) {
r.RenderNodes(node.Children)
r.output.WriteString("\n")
}
func (r *StringRender) renderHorizontalRule(_ *ast.HorizontalRule) {
r.output.WriteString("\n---\n")
}
func (r *StringRender) renderBlockquote(node *ast.Blockquote) {
r.output.WriteString("\n")
r.RenderNodes(node.Children)
r.output.WriteString("\n")
}
func (r *StringRender) renderUnorderedList(node *ast.UnorderedList) {
prevSibling, nextSibling := node.PrevSibling(), node.NextSibling()
if prevSibling == nil || prevSibling.Type() != ast.UnorderedListNode {
r.output.WriteString("\n")
}
r.output.WriteString("* ")
r.RenderNodes(node.Children)
if nextSibling == nil || nextSibling.Type() != ast.UnorderedListNode {
r.output.WriteString("\n")
}
}
func (r *StringRender) renderOrderedList(node *ast.OrderedList) {
prevSibling, nextSibling := node.PrevSibling(), node.NextSibling()
if prevSibling == nil || prevSibling.Type() != ast.OrderedListNode {
r.output.WriteString("\n")
}
r.output.WriteString("1. ")
r.RenderNodes(node.Children)
if nextSibling == nil || nextSibling.Type() != ast.OrderedListNode {
r.output.WriteString("\n")
}
}
func (r *StringRender) renderText(node *ast.Text) {
r.output.WriteString(node.Content)
}
func (r *StringRender) renderBold(node *ast.Bold) {
r.output.WriteString(node.Content)
}
func (r *StringRender) renderItalic(node *ast.Italic) {
r.output.WriteString(node.Content)
}
func (r *StringRender) renderBoldItalic(node *ast.BoldItalic) {
r.output.WriteString(node.Content)
}
func (r *StringRender) renderCode(node *ast.Code) {
r.output.WriteString("`")
r.output.WriteString(node.Content)
r.output.WriteString("`")
}
func (*StringRender) renderImage(*ast.Image) {
// Do nothing.
}
func (*StringRender) renderLink(*ast.Link) {
// Do nothing.
}
func (r *StringRender) renderTag(node *ast.Tag) {
r.output.WriteString(`#`)
r.output.WriteString(node.Content)
}
func (r *StringRender) renderStrikethrough(node *ast.Strikethrough) {
r.output.WriteString(node.Content)
}

@ -0,0 +1,34 @@
package string
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/usememos/memos/plugin/gomark/parser"
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
)
func TestStringRender(t *testing.T) {
tests := []struct {
text string
expected string
}{
{
text: "Hello world!",
expected: `Hello world!`,
},
{
text: "**Hello** world!",
expected: `Hello world!`,
},
}
for _, test := range tests {
tokens := tokenizer.Tokenize(test.text)
nodes, err := parser.Parse(tokens)
require.NoError(t, err)
actual := NewStringRender().Render(nodes)
require.Equal(t, test.expected, actual)
}
}

@ -12,6 +12,9 @@ import (
v1 "github.com/usememos/memos/api/v1"
"github.com/usememos/memos/internal/util"
"github.com/usememos/memos/plugin/gomark/parser"
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
"github.com/usememos/memos/plugin/gomark/render"
"github.com/usememos/memos/server/profile"
"github.com/usememos/memos/store"
)
@ -151,12 +154,23 @@ Sitemap: %s/sitemap.xml`, instanceURL, instanceURL)
}
func generateMemoMetadata(memo *store.Memo, creator *store.User) string {
description := memo.Content
description := ""
if memo.Visibility == store.Private {
description = "This memo is private."
} else if memo.Visibility == store.Protected {
description = "This memo is protected."
} else {
tokens := tokenizer.Tokenize(memo.Content)
nodes, _ := parser.Parse(tokens)
description = render.NewStringRender().Render(nodes)
if len(description) == 0 {
description = memo.Content
}
if len(description) > 100 {
description = description[:100] + "..."
}
}
metadataList := []string{
fmt.Sprintf(`<meta name="description" content="%s" />`, description),
fmt.Sprintf(`<meta property="og:title" content="%s" />`, fmt.Sprintf("%s(@%s) on Memos", creator.Nickname, creator.Username)),

Loading…
Cancel
Save