Skip to content

Commit

Permalink
updates metadata for markdown cells using a nested data structure
Browse files Browse the repository at this point in the history
  • Loading branch information
pastuxso committed Oct 18, 2023
1 parent a22c65e commit 7b35af6
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 44 deletions.
52 changes: 31 additions & 21 deletions internal/document/editor/cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package editor

import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"strconv"
"strings"

Expand Down Expand Up @@ -148,7 +150,14 @@ func toCellsRec(
astNode := block.Unwrap()

metadata := make(map[string]string)
DumpToMap(astNode, source, astNode.Kind().String(), 0, &metadata)
astMetadata := DumpToMap(astNode, source, astNode.Kind().String())
jsonAstMetaData, err := json.Marshal(astMetadata)

if err != nil {
log.Fatalf("Error converting to JSON: %s", err)
}

metadata["runme.dev/ast"] = string(jsonAstMetaData)

isListItem := node.Item() != nil && node.Item().Unwrap().Kind() == ast.KindListItem
if childIdx == 0 && isListItem {
Expand Down Expand Up @@ -299,15 +308,10 @@ func trimRightNewLine(s []byte) []byte {
return bytes.TrimRight(s, "\n")
}

func DumpToMap(node ast.Node, source []byte, root string, level int, metadata *map[string]string) {
rootKey := "runme.dev/"
(*metadata)[rootKey+"Size"] = strconv.Itoa(level)

if level > 0 {
rootKey = fmt.Sprintf("%s%d/", rootKey, level)
}
func DumpToMap(node ast.Node, source []byte, root string) *map[string]interface{} {
metadata := make(map[string]interface{})

(*metadata)[rootKey+"Kind"] = node.Kind().String()
metadata["Kind"] = node.Kind().String()

if node.Type() == ast.TypeBlock {
buf := []string{}
Expand All @@ -317,27 +321,34 @@ func DumpToMap(node ast.Node, source []byte, root string, level int, metadata *m
buf = append(buf, string(line.Value(source)))
}

(*metadata)[rootKey+"RawText"] = strings.Join(buf, "")
metadata["RawText"] = strings.Join(buf, "")
}

for name, value := range DumpAttributes(node, source) {
(*metadata)[rootKey+name] = value
metadata[name] = value
}

i := level
children := []interface{}{}

for c := node.FirstChild(); c != nil; c = c.NextSibling() {
DumpToMap(c, source, root, level+i+1, metadata)
i++
childrenMetadata := DumpToMap(c, source, node.Kind().String())
children = append(children, childrenMetadata)
}

if len(children) > 0 {
metadata["Children"] = children
}

return &metadata
}

func DumpAttributes(n ast.Node, source []byte) map[string]string {
attributes := map[string]string{}
func DumpAttributes(n ast.Node, source []byte) map[string]interface{} {
attributes := make(map[string]interface{})

switch n.Kind() {
case ast.KindHeading:
t := n.(*ast.Heading)
attributes["Level"] = fmt.Sprintf("%d", t.Level)
attributes["Level"] = t.Level

case ast.KindText:
t := n.(*ast.Text)
Expand Down Expand Up @@ -372,18 +383,17 @@ func DumpAttributes(n ast.Node, source []byte) map[string]string {

case ast.KindList:
t := n.(*ast.List)
attributes["Ordered"] = fmt.Sprintf("%v", t.IsOrdered())
attributes["Ordered"] = t.IsOrdered()
attributes["Marker"] = fmt.Sprintf("%c", t.Marker)
attributes["Tight"] = fmt.Sprintf("%v", t.IsTight)
attributes["Tight"] = t.IsTight

if t.IsOrdered() {
attributes["Start"] = fmt.Sprintf("%d", t.Start)
}

case ast.KindListItem:
t := n.(*ast.ListItem)
attributes["Offset"] = fmt.Sprintf("%d", t.Offset)

attributes["Offset"] = t.Offset
}

return attributes
Expand Down
44 changes: 44 additions & 0 deletions internal/document/editor/editor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package editor

import (
"bytes"
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -96,6 +97,49 @@ func TestEditor_CodeBlock(t *testing.T) {
})
}

func TestEditor_Metadata(t *testing.T) {
data := []byte(`# Heading Level 1
Paragraph 1 with a link [Link1](https://example.com 'Link Title 1') and a second link [Link2](https://example2.com 'Link Title 2')..
## Heading Level 2
### Heading Level 3
#### Heading Level 4
##### Heading Level 5
`)
notebook, err := Deserialize(data)
require.NoError(t, err)
require.NotEmpty(t, notebook.Metadata)

astStr := notebook.Cells[0].Metadata["runme.dev/ast"]
var metadata map[string]interface{}
err = json.Unmarshal([]byte(astStr), &metadata)
require.NoError(t, err)

assert.Equal(t, "Heading", metadata["Kind"])
assert.Equal(t, 1, len(metadata["Children"].([]interface{})))
assert.Equal(t, 1, int(metadata["Level"].(float64)))

astStr = notebook.Cells[1].Metadata["runme.dev/ast"]
metadata = make(map[string]interface{})
err = json.Unmarshal([]byte(astStr), &metadata)
require.NoError(t, err)

assert.Equal(t, "Paragraph", metadata["Kind"])
assert.Equal(t, 5, len(metadata["Children"].([]interface{})))

children := metadata["Children"].([]interface{})

nChild := children[0].(map[string]interface{})
assert.Equal(t, "Paragraph 1 with a link ", nChild["Text"].(string))

nChild = children[1].(map[string]interface{})
assert.Equal(t, "https://example.com", nChild["Destination"].(string))
assert.Equal(t, "Link Title 1", nChild["Title"].(string))

children = nChild["Children"].([]interface{})
nChild = children[0].(map[string]interface{})
assert.Equal(t, "Link1", nChild["Text"].(string))
}

func TestEditor_FrontMatter(t *testing.T) {
data := []byte(`+++
prop1 = "val1"
Expand Down
25 changes: 2 additions & 23 deletions internal/document/editor/editorservice/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,7 @@ func Test_parserServiceServer(t *testing.T) {
Kind: parserv1.CellKind_CELL_KIND_MARKUP,
Value: "# Title",
Metadata: map[string]string{
"runme.dev/Kind": "Heading",
"runme.dev/Level": "1",
"runme.dev/Size": "1",
"runme.dev/RawText": "Title",
"runme.dev/1/Kind": "Text",
"runme.dev/1/Text": "Title",
"runme.dev/ast": `{"Children":[{"Kind":"Text","Text":"Title"}],"Kind":"Heading","Level":1,"RawText":"Title"}`,
},
},
cells[0],
Expand All @@ -69,23 +64,7 @@ func Test_parserServiceServer(t *testing.T) {
Kind: parserv1.CellKind_CELL_KIND_MARKUP,
Value: "Some content with [Link1](https://example1.com \"Link title 1\") [Link2](https://example2.com \"Link title2\")",
Metadata: map[string]string{
"runme.dev/1/Kind": "Text",
"runme.dev/1/Text": "Some content with ",
"runme.dev/2/Destination": "https://example1.com",
"runme.dev/2/Kind": "Link",
"runme.dev/2/Title": "Link title 1",
"runme.dev/3/Kind": "Text",
"runme.dev/3/Text": " ",
"runme.dev/4/Destination": "https://example2.com",
"runme.dev/4/Kind": "Link",
"runme.dev/4/Title": "Link title2",
"runme.dev/5/Kind": "Text",
"runme.dev/5/Text": "Link1",
"runme.dev/9/Kind": "Text",
"runme.dev/9/Text": "Link2",
"runme.dev/Kind": "Paragraph",
"runme.dev/Size": "9",
"runme.dev/RawText": "Some content with [Link1](https://example1.com \"Link title 1\") [Link2](https://example2.com \"Link title2\")",
"runme.dev/ast": `{"Children":[{"Kind":"Text","Text":"Some content with "},{"Children":[{"Kind":"Text","Text":"Link1"}],"Destination":"https://example1.com","Kind":"Link","Title":"Link title 1"},{"Kind":"Text","Text":" "},{"Children":[{"Kind":"Text","Text":"Link2"}],"Destination":"https://example2.com","Kind":"Link","Title":"Link title2"}],"Kind":"Paragraph","RawText":"Some content with [Link1](https://example1.com \"Link title 1\") [Link2](https://example2.com \"Link title2\")"}`,
},
},
cells[1],
Expand Down

0 comments on commit 7b35af6

Please sign in to comment.