diff --git a/go.mod b/go.mod index 3df5105..9118a54 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/hashicorp/logutils v1.0.0 github.com/integrii/flaggy v1.4.4 github.com/mattn/godown v0.0.0-20200217152941-afc959f6a561 + github.com/sergi/go-diff v1.2.0 golang.org/x/net v0.0.0-20200904194848-62affa334b73 ) diff --git a/go.sum b/go.sum index 4e34a30..d7db48c 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,9 @@ github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdc github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= github.com/cheggaaa/pb/v3 v3.0.4 h1:QZEPYOj2ix6d5oEg63fbHmpolrnNiwjUsk+h74Yt4bM= github.com/cheggaaa/pb/v3 v3.0.4/go.mod h1:7rgWxLrAUcFMkvJuv09+DYi7mMUYi8nO9iOWcvGJPfw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= @@ -9,6 +12,9 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/integrii/flaggy v1.4.4 h1:8fGyiC14o0kxhTqm2VBoN19fDKPZsKipP7yggreTMDc= github.com/integrii/flaggy v1.4.4/go.mod h1:tnTxHeTJbah0gQ6/K0RW0J7fMUBk9MCF5blhm43LNpI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -19,6 +25,13 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/wormi4ok/godown v0.1.2 h1:sQ1yKPMx3EQAi3quceJsKSavKxMhQEyPxOl/KHIYNrI= github.com/wormi4ok/godown v0.1.2/go.mod h1:MqNOYIb1OoPw5X2AXQPM7tMVjGfD/fUYFIM0vDLsF94= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -35,3 +48,8 @@ golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/convert_test.go b/internal/convert_test.go index 974194a..83295e9 100644 --- a/internal/convert_test.go +++ b/internal/convert_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/sergi/go-diff/diffmatchpatch" "github.com/wormi4ok/evernote2md/encoding/enex" "github.com/wormi4ok/evernote2md/encoding/markdown" "github.com/wormi4ok/evernote2md/internal" @@ -32,7 +33,7 @@ func TestConvert(t *testing.T) { image, _ := base64.StdEncoding.DecodeString(encodedImage) tests := []testTemplate{ { - name: "", + name: "Happy path", arg: &enex.Note{ Title: "Test note", Content: goldenFile(t, "evernote.html"), @@ -106,11 +107,82 @@ func TestConvert(t *testing.T) { enableFrontMatter: false, markdownFile: "golden.md", }, + { + name: "FrontMatter", + arg: &enex.Note{ + Title: "Test note", + Content: goldenFile(t, "evernote.html"), + Created: "20121202T112233Z", + Updated: "20201220T223344Z", + Tags: []string{"tag1", "tag2"}, + Attributes: enex.NoteAttributes{ + Source: "mobile.android", + SourceApplication: "", + Latitude: "50.00000000000000", + Longitude: "30.00000000000000", + Altitude: "", + Author: "", + SourceUrl: "", + }, + Resources: []enex.Resource{{ + ID: "c9e6c70ea74388346ffa16ff8edbdf58", + Mime: "image/png", + Attributes: enex.Attributes{ + Filename: "1.jpg", + }, + Data: enex.Data{ + Encoding: "base64", + Content: []byte(encodedImage), + }, + }, { + ID: "90fdbde3hk91aff643883475tgh94bds1", + Mime: "image/gif", + Attributes: enex.Attributes{ + Filename: "1.jpg", + }, + Data: enex.Data{ + Encoding: "base64", + Content: []byte(encodedImage), + }, + }, { + ID: "1sdb49hgt574388346ffa19kh3edbdf09", + Mime: "image/gif", + Attributes: enex.Attributes{ + Filename: "complex?path=http://image.com/2.gif", + }, + Data: enex.Data{ + Encoding: "base64", + Content: []byte(encodedImage), + }, + }}, + }, + want: &markdown.Note{ + Content: []byte(""), + CTime: time.Date(2012, 12, 02, 11, 22, 33, 0, time.UTC), + MTime: time.Date(2020, 12, 20, 22, 33, 44, 0, time.UTC), + Media: map[string]markdown.Resource{ + "c9e6c70ea74388346ffa16ff8edbdf58": { + Name: "1.jpg", + Type: "image", + Content: image, + }, + "90fdbde3hk91aff643883475tgh94bds1": { + Name: "1-1.jpg", + Type: "image", + Content: image, + }, + "1sdb49hgt574388346ffa19kh3edbdf09": { + Name: "complex?path=http-image-com-2.gif", + Type: "image", + Content: image, + }, + }, + }, + wantErr: false, + enableFrontMatter: true, + markdownFile: "golden-frontmatter.md", + }, } - secondTestWithFrontMatter := tests[0] - secondTestWithFrontMatter.markdownFile = "golden-frontmatter.md" - secondTestWithFrontMatter.enableFrontMatter = true - tests = append(tests, secondTestWithFrontMatter) for _, tt := range tests { c, _ := internal.NewConverter("", tt.enableFrontMatter, true) t.Run(tt.name, func(t *testing.T) { @@ -126,9 +198,11 @@ func TestConvert(t *testing.T) { } content := goldenFile(t, tt.markdownFile) tt.want.Content = content - if !reflect.DeepEqual(got, tt.want) { + if got != nil && !reflect.DeepEqual(got, tt.want) { if !bytes.Equal(got.Content, tt.want.Content) { - t.Errorf("Content mismatch! \nGot = %s, \nWant= %s", got.Content, tt.want.Content) + dmp := diffmatchpatch.New() + diffs := dmp.DiffMain(string(tt.want.Content), string(got.Content), true) + t.Error(dmp.DiffPrettyText(diffs)) } else { t.Errorf("Convert() = %s, want %+v", got.Media["c9e6c70ea74388346ffa16ff8edbdf58"].Content, tt.want) } diff --git a/internal/replace.go b/internal/replace.go index bd4d261..bfe5f66 100644 --- a/internal/replace.go +++ b/internal/replace.go @@ -94,13 +94,10 @@ func replaceNode(n *html.Node, res markdown.Resource) { appendMedia(n, parseOne(resourceReference(res), n)) } -func appendMedia(note, media *html.Node) { - p := note.Parent - for isMedia(p) { - p = p.Parent - } - p.AppendChild(media) - p.AppendChild(parseOne(`
`, note)) // newline +func appendMedia(node, media *html.Node) { + p := node.Parent + p.InsertBefore(media, node) + p.InsertBefore(parseOne(`
`, node), node) // newline } // Since we control input, this wrapper gives a simple diff --git a/internal/testdata/evernote.html b/internal/testdata/evernote.html index 0b23dc8..357020c 100644 --- a/internal/testdata/evernote.html +++ b/internal/testdata/evernote.html @@ -1 +1 @@ -

abc highlighted text

Some italic text

Some bold text

//This is a code block
    fmt.Println("hello world")

Header 1
Middle column
Last column title
Short text
Verylongunbreakabletext
Something here
Half empty row


+

abc highlighted text

Some italic text

Some bold text

//This is a code block
    fmt.Println("hello world")
  • First item
  • Second item
    • Nested item

Header 1
Middle column
Last column title
Short text
Verylongunbreakabletext
Something here
Half empty row


diff --git a/internal/testdata/golden-frontmatter.md b/internal/testdata/golden-frontmatter.md index cdb1987..e0ec870 100644 --- a/internal/testdata/golden-frontmatter.md +++ b/internal/testdata/golden-frontmatter.md @@ -19,6 +19,10 @@ Some _italic text_ Some **bold text** +![1.jpg](image/1.jpg) + +![complex?path=http-image-com-2.gif](image/complex?path=http-image-com-2.gif) + ``` //This is a code block     fmt.Println("hello world") @@ -31,11 +35,3 @@ Some **bold text** |Header 1 |Middle column |Last column title| |Short text |Verylongunbreakabletext|Something here | |Half empty row| | | - -![1.jpg](image/1.jpg) - -![complex?path=http-image-com-2.gif](image/complex?path=http-image-com-2.gif) - -![1.jpg](image/1.jpg) - -![complex?path=http-image-com-2.gif](image/complex?path=http-image-com-2.gif) diff --git a/internal/testdata/golden.md b/internal/testdata/golden.md index d50b780..8610ae7 100644 --- a/internal/testdata/golden.md +++ b/internal/testdata/golden.md @@ -8,6 +8,10 @@ Some _italic text_ Some **bold text** +![1.jpg](image/1.jpg) + +![complex?path=http-image-com-2.gif](image/complex?path=http-image-com-2.gif) + ``` //This is a code block     fmt.Println("hello world") @@ -20,7 +24,3 @@ Some **bold text** |Header 1 |Middle column |Last column title| |Short text |Verylongunbreakabletext|Something here | |Half empty row| | | - -![1.jpg](image/1.jpg) - -![complex?path=http-image-com-2.gif](image/complex?path=http-image-com-2.gif)