From e44645afbb6814bb93536587a5d4af43ad3ab2ef Mon Sep 17 00:00:00 2001 From: Chris Bednarski Date: Thu, 25 Jul 2024 22:37:54 -0700 Subject: [PATCH 1/2] Implement Text interface for BaseBlock This implementation was missing, making it impossible to retrieve Text from block types, such as CodeBlock and FencedCodeBlock, via the ast interface. --- ast/block.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ast/block.go b/ast/block.go index c5d4738..e781a45 100644 --- a/ast/block.go +++ b/ast/block.go @@ -1,6 +1,7 @@ package ast import ( + "bytes" "fmt" "strings" @@ -47,6 +48,14 @@ func (b *BaseBlock) SetLines(v *textm.Segments) { b.lines = v } +func (b *BaseBlock) Text(source []byte) []byte { + var buf bytes.Buffer + for _, line := range b.Lines().Sliced(0, b.Lines().Len()) { + buf.Write(line.Value(source)) + } + return buf.Bytes() +} + // A Document struct is a root node of Markdown text. type Document struct { BaseBlock From e36775542115aac9f8e3be2a2b154152eefd7f48 Mon Sep 17 00:00:00 2001 From: Chris Bednarski Date: Thu, 25 Jul 2024 23:40:45 -0700 Subject: [PATCH 2/2] Added test for BaseBlock.Text retrieval --- ast/ast_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/ast/ast_test.go b/ast/ast_test.go index 684fbc3..7cee141 100644 --- a/ast/ast_test.go +++ b/ast/ast_test.go @@ -1,8 +1,11 @@ package ast import ( + "bytes" "reflect" "testing" + + "github.com/yuin/goldmark/text" ) func TestRemoveChildren(t *testing.T) { @@ -73,3 +76,48 @@ func node(n Node, children ...Node) Node { } return n } + +func TestBaseBlock_Text(t *testing.T) { + source := []byte(`# Heading + + code block here + and also here + +A paragraph + +` + "```" + `somelang +fenced code block +` + "```" + ` + +The end`) + + t.Run("fetch text from code block", func(t *testing.T) { + block := NewCodeBlock() + block.lines = text.NewSegments() + block.lines.Append(text.Segment{Start: 15, Stop: 31}) + block.lines.Append(text.Segment{Start: 32, Stop: 46}) + + expected := []byte("code block here\nand also here\n") + if !bytes.Equal(expected, block.Text(source)) { + t.Errorf("Expected: %q, got: %q", string(expected), string(block.Text(source))) + } + }) + + t.Run("fetch text from fenced code block", func(t *testing.T) { + block := NewFencedCodeBlock(&Text{ + Segment: text.Segment{Start: 63, Stop: 71}, + }) + block.lines = text.NewSegments() + block.lines.Append(text.Segment{Start: 72, Stop: 90}) + + expectedLang := []byte("somelang") + if !bytes.Equal(expectedLang, block.Language(source)) { + t.Errorf("Expected: %q, got: %q", string(expectedLang), string(block.Language(source))) + } + + expected := []byte("fenced code block\n") + if !bytes.Equal(expected, block.Text(source)) { + t.Errorf("Expected: %q, got: %q", string(expected), string(block.Text(source))) + } + }) +}