From 8c1a9a36daa0ddeeab692bb1009b72ae35a71fbd Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Thu, 19 Nov 2020 03:09:28 +0500 Subject: [PATCH] Refactor rendering code This refactoring simplifies some originally quirky parts of rendering code while also adding support for rendering emphasized text (handled by the same routine the ordinary text already is). --- internal/gemini/renderer.go | 83 +++++++++---------------------------- 1 file changed, 19 insertions(+), 64 deletions(-) diff --git a/internal/gemini/renderer.go b/internal/gemini/renderer.go index be8ade3..9073d97 100644 --- a/internal/gemini/renderer.go +++ b/internal/gemini/renderer.go @@ -18,8 +18,6 @@ package gemini import ( - "bufio" - "bytes" "fmt" "io" "strings" @@ -65,30 +63,8 @@ func (r Renderer) link(w io.Writer, node *ast.Link, entering bool) { if entering { w.Write(linkPrefix) w.Write(node.Destination) - for _, child := range node.Children { - if l := child.AsLeaf(); l != nil { - w.Write(space) - w.Write(l.Literal) - } - } - } -} - -func (r Renderer) linkText(w io.Writer, node *ast.Link) { - for _, text := range node.Children { - // TODO: Renderer.linkText: link can contain subblocks - if l := text.AsLeaf(); l != nil { - w.Write(l.Literal) - } - } -} - -func (r Renderer) imageText(w io.Writer, node *ast.Image) { - for _, text := range node.Children { - // TODO: Renderer.imageText: link can contain subblocks - if l := text.AsLeaf(); l != nil { - w.Write(l.Literal) - } + w.Write(space) + r.text(w, node) } } @@ -96,15 +72,8 @@ func (r Renderer) image(w io.Writer, node *ast.Image, entering bool) { if entering { w.Write(linkPrefix) w.Write(node.Destination) - for _, sub := range node.Container.Children { - if l := sub.AsLeaf(); l != nil { - // TODO: Renderer.image: Markdown technically allows for - // links inside image titles, yet to think out how to - // render that :thinking: - w.Write(space) - w.Write(l.Literal) - } - } + w.Write(space) + r.text(w, node) } } @@ -113,16 +82,8 @@ func (r Renderer) blockquote(w io.Writer, node *ast.BlockQuote, entering bool) { // ideally to be merged with paragraph if entering { if para, ok := node.Children[0].(*ast.Paragraph); ok { - for _, subnode := range para.Children { - if l := subnode.AsLeaf(); l != nil { - reader := bufio.NewScanner(bytes.NewBuffer(l.Literal)) - for reader.Scan() { - w.Write(quotePrefix) - w.Write(reader.Bytes()) - w.Write(lineBreak) - } - } - } + w.Write(quotePrefix) + r.text(w, para) } } } @@ -178,23 +139,14 @@ func (r Renderer) paragraph(w io.Writer, node *ast.Paragraph, entering bool) (no for _, child := range children { // only render links text in the paragraph if they're // combined with some other text on page - if link, ok := child.(*ast.Link); ok { - if !onlyElement { - r.linkText(w, link) - } - linkStack = append(linkStack, link) - } - if image, ok := child.(*ast.Image); ok { + switch child := child.(type) { + case *ast.Link, *ast.Image: if !onlyElement { - r.imageText(w, image) + r.text(w, child) } - linkStack = append(linkStack, image) - } - if text, ok := child.(*ast.Text); ok { - r.text(w, text) - } - if inlineBlock, ok := child.(*ast.Code); ok { - r.text(w, inlineBlock) + linkStack = append(linkStack, child) + case *ast.Text, *ast.Code, *ast.Emph, *ast.Strong, *ast.Del: + r.text(w, child) } } if !onlyElementIsLink { @@ -250,10 +202,7 @@ func (r Renderer) list(w io.Writer, node *ast.List, level int) { } para, ok := item.Children[0].(*ast.Paragraph) if ok { - text, ok := para.Children[0].(*ast.Text) - if ok { - r.text(w, text) - } + r.text(w, para) } w.Write(lineBreak) if l >= 2 { @@ -270,6 +219,12 @@ func (r Renderer) text(w io.Writer, node ast.Node) { // replace all newlines in text with spaces, allowing for soft // wrapping; this is recommended as per Gemini spec p. 5.4.1 w.Write([]byte(strings.ReplaceAll(string(node.Literal), "\n", " "))) + return + } + if node := node.AsContainer(); node != nil { + for _, child := range node.Children { + r.text(w, child) + } } }