Skip to content

Commit

Permalink
Handle fence vs regular code block transparently
Browse files Browse the repository at this point in the history
  • Loading branch information
sourishkrout committed Sep 30, 2024
1 parent b7215c8 commit 646f57f
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 33 deletions.
40 changes: 29 additions & 11 deletions pkg/document/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package document
import (
"bytes"
"encoding/json"
"errors"
"math"
"regexp"
"strconv"
Expand Down Expand Up @@ -47,7 +48,8 @@ type CodeBlockEncoding int
const (
Fenced CodeBlockEncoding = iota + 1
UnfencedWithSpaces
UnfencedWithTab
// todo(sebastian): goldmark converts all tabs to spaces
// UnfencedWithTab
)

type CodeBlock struct {
Expand All @@ -69,23 +71,37 @@ var _ Block = (*CodeBlock)(nil)

func newCodeBlock(
document *Document,
node *ast.FencedCodeBlock,
node ast.Node,
identityResolver identityResolver,
nameResolver *nameResolver,
source []byte,
encoding CodeBlockEncoding,
render renderer,
) (*CodeBlock, error) {
attributes, err := getAttributes(node, source, DefaultAttributeParser)
var fenced *ast.FencedCodeBlock
encoding := Fenced

switch node.Kind() {
case ast.KindCodeBlock:
// todo(sebastian): should we attempt to preserve tab vs spaces?
encoding = UnfencedWithSpaces
fenced = ast.NewFencedCodeBlock(ast.NewText())
fenced.BaseBlock = node.(*ast.CodeBlock).BaseBlock
case ast.KindFencedCodeBlock:
fenced = node.(*ast.FencedCodeBlock)
default:
return nil, errors.New("invalid node kind neither CodeBlock nor FencedCodeBlock")
}

attributes, err := getAttributes(fenced, source, DefaultAttributeParser)
if err != nil {
return nil, err
}

id, hasID := identityResolver.GetCellID(node, attributes)
id, hasID := identityResolver.GetCellID(fenced, attributes)

name, hasName := getName(node, source, nameResolver, attributes)
name, hasName := getName(fenced, source, nameResolver, attributes)

value, err := render(node, source)
value, err := render(fenced, source)
if err != nil {
return nil, err
}
Expand All @@ -96,16 +112,18 @@ func newCodeBlock(
encoding: encoding,
id: id,
idGenerated: !hasID,
inner: node,
intro: getIntro(node, source),
language: getLanguage(node, source),
lines: getLines(node, source),
inner: fenced,
intro: getIntro(fenced, source),
language: getLanguage(fenced, source),
lines: getLines(fenced, source),
name: name,
nameGenerated: !hasName,
value: value,
}, nil
}

func (b *CodeBlock) FencedEncoding() bool { return b.encoding == Fenced }

func (b *CodeBlock) Attributes() map[string]string { return b.attributes }

func (b *CodeBlock) Background() bool {
Expand Down
15 changes: 2 additions & 13 deletions pkg/document/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package document
import (
"bytes"
"fmt"
"strconv"
"sync"

"github.com/pkg/errors"
Expand Down Expand Up @@ -171,26 +170,16 @@ func (d *Document) parse() {

func (d *Document) buildBlocksTree(parent ast.Node, node *Node) error {
for astNode := parent.FirstChild(); astNode != nil; astNode = astNode.NextSibling() {
codeBlockEncoding := Fenced
switch astNode.Kind() {
case ast.KindCodeBlock:
b := ast.NewFencedCodeBlock(ast.NewText())
b.BaseBlock = astNode.(*ast.CodeBlock).BaseBlock
astNode = b

codeBlockEncoding = UnfencedWithSpaces
fallthrough
case ast.KindFencedCodeBlock:
case ast.KindCodeBlock, ast.KindFencedCodeBlock:
block, err := newCodeBlock(
d,
astNode.(*ast.FencedCodeBlock),
astNode,
d.identityResolver,
d.nameResolver,
d.content,
codeBlockEncoding,
d.renderer,
)
block.attributes["runme.dev/fenced"] = strconv.FormatBool(codeBlockEncoding == Fenced)
if err != nil {
return errors.WithStack(err)
}
Expand Down
22 changes: 13 additions & 9 deletions pkg/document/editor/cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ func toCellsRec(
}
metadata[PrefixAttributeName(InternalAttributePrefix, "nameGenerated")] = nameGeneratedStr

if !block.FencedEncoding() {
metadata[PrefixAttributeName(InternalAttributePrefix, "fenced")] = "false"
}

*cells = append(*cells, &Cell{
Kind: CodeKind,
Value: string(block.Content()),
Expand Down Expand Up @@ -322,7 +326,15 @@ func serializeCellCodeBlock(w io.Writer, cell *Cell) {
var buf bytes.Buffer
value := cell.Value

if b, _ := strconv.ParseBool(cell.Metadata[PrefixAttributeName(InternalAttributePrefix, "fenced")]); b {
if b, err := strconv.ParseBool(cell.Metadata[PrefixAttributeName(InternalAttributePrefix, "fenced")]); err == nil && !b {
for _, v := range strings.Split(value, "\n") {
_, _ = buf.Write(bytes.Repeat([]byte{' '}, 4))
_, _ = buf.WriteString(v)
_ = buf.WriteByte('\n')
}

serializeCellOutputsText(&buf, cell)
} else {
ticksCount := longestBacktickSeq(value)
if ticksCount < 3 {
ticksCount = 3
Expand All @@ -340,14 +352,6 @@ func serializeCellCodeBlock(w io.Writer, cell *Cell) {
serializeCellOutputsText(&buf, cell)

_, _ = buf.Write(bytes.Repeat([]byte{'`'}, ticksCount))
} else {
for _, v := range strings.Split(value, "\n") {
_, _ = buf.Write(bytes.Repeat([]byte{' '}, 4))
_, _ = buf.WriteString(v)
_ = buf.WriteByte('\n')
}

serializeCellOutputsText(&buf, cell)
}

serializeCellOutputsImage(&buf, cell)
Expand Down

0 comments on commit 646f57f

Please sign in to comment.