diff --git a/README.md b/README.md index c87359f..d0f0ba9 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,39 @@ # goldmark-embed -goldmark-embed is an extension for the [goldmark][goldmark] library that extends +goldmark-embed is based on 13rac1's extension for the [goldmark][goldmark] library that extends the Markdown `![]()` image embed syntax to support additional media formats. [goldmark]: http://github.com/yuin/goldmark -YouTube only at first. +Supports YouTube and Vimeo links. ## Demo This markdown: ```md -# Hello goldmark-embed +# Hello goldmark-embed for YouTube ![](https://www.youtube.com/watch?v=dQw4w9WgXcQ) + +# Hello goldmark-embed for Vimeo + +![](https://vimeo.com/148751763) ``` Becomes this HTML: ```html -

Hello goldmark-embed

-

+

Hello goldmark-embed for Youtube

+

+

Hello goldmark-embed for Vimeo

+

``` ### Installation ```bash -go get github.com/13rac1/goldmark-embed +go get github.com/PaperPrototype/goldmark-embed ``` ## Usage @@ -37,13 +41,15 @@ go get github.com/13rac1/goldmark-embed ```go markdown := goldmark.New( goldmark.WithExtensions( - embed.Embed, + embed.New(), ), ) var buf bytes.Buffer if err := markdown.Convert([]byte(source), &buf); err != nil { panic(err) } + + // output html fmt.Print(buf) } ``` @@ -57,6 +63,7 @@ go get github.com/13rac1/goldmark-embed MIT -## Author +## Authors -Brad Erickson +![Brad Erickson](https://github.com/13rac1) +![Abdiel Lopez](https://github.com/PaperPrototype) diff --git a/embed.go b/embed.go index 1d5c36a..a4308b8 100644 --- a/embed.go +++ b/embed.go @@ -39,32 +39,6 @@ func (e *embedExtension) Extend(m goldmark.Markdown) { ) } -// YouTube struct represents a YouTube Video embed of the Markdown text. -type YouTube struct { - ast.Image - Video string -} - -// KindYouTube is a NodeKind of the YouTube node. -var KindYouTube = ast.NewNodeKind("YouTube") - -// Kind implements Node.Kind. -func (n *YouTube) Kind() ast.NodeKind { - return KindYouTube -} - -// NewYouTube returns a new YouTube node. -func NewYouTube(img *ast.Image, v string) *YouTube { - c := &YouTube{ - Image: *img, - Video: v, - } - c.Destination = img.Destination - c.Title = img.Title - - return c -} - type astTransformer struct{} var defaultASTTransformer = &astTransformer{} @@ -79,6 +53,7 @@ func (a *astTransformer) Transform(node *ast.Document, reader text.Reader, pc pa } img := n.(*ast.Image) + // parse the url u, err := url.Parse(string(img.Destination)) if err != nil { msg := ast.NewString([]byte(fmt.Sprintf("", err))) @@ -87,15 +62,24 @@ func (a *astTransformer) Transform(node *ast.Document, reader text.Reader, pc pa return ast.WalkContinue, nil } - if u.Host != "www.youtube.com" || u.Path != "/watch" { - return ast.WalkContinue, nil - } - v := u.Query().Get("v") - if v == "" { - return ast.WalkContinue, nil + if u.Host == "www.youtube.com" && u.Path == "/watch" { + // if YouTube + + v := u.Query().Get("v") + if v == "" { + return ast.WalkContinue, nil + } + youtube := NewYouTube(img, v) + n.Parent().ReplaceChild(n.Parent(), n, youtube) + + } else if u.Host == "vimeo.com" { + // if Vimeo + + // remove the '/' from url + path := u.Path[1:] + vimeo := NewVimeo(img, path) + n.Parent().ReplaceChild(n.Parent(), n, vimeo) } - yt := NewYouTube(img, v) - n.Parent().ReplaceChild(n.Parent(), n, yt) return ast.WalkContinue, nil } @@ -115,6 +99,7 @@ func NewHTMLRenderer() renderer.NodeRenderer { // RegisterFuncs implements NodeRenderer.RegisterFuncs. func (r *HTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { reg.Register(KindYouTube, r.renderYouTubeVideo) + reg.Register(KindVimeo, r.renderVimeoVideo) } func (r *HTMLRenderer) renderYouTubeVideo(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { @@ -122,8 +107,19 @@ func (r *HTMLRenderer) renderYouTubeVideo(w util.BufWriter, source []byte, node return ast.WalkContinue, nil } - yt := node.(*YouTube) + youtube := node.(*YouTube) + + w.Write([]byte(``)) + return ast.WalkContinue, nil +} + +func (r *HTMLRenderer) renderVimeoVideo(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + if entering { + return ast.WalkContinue, nil + } + + vimeo := node.(*Vimeo) - w.Write([]byte(``)) + w.Write([]byte(``)) return ast.WalkContinue, nil } diff --git a/embed_test.go b/embed_test.go index a756648..57ab371 100644 --- a/embed_test.go +++ b/embed_test.go @@ -4,7 +4,7 @@ import ( "bytes" "testing" - embed "github.com/13rac1/goldmark-embed" + embed "github.com/PaperPrototype/goldmark-embed" "github.com/yuin/goldmark" ) @@ -14,7 +14,7 @@ func TestMeta(t *testing.T) { embed.New(), ), ) - source := `# Hello goldmark-embed + source := `# Hello goldmark-embed for Youtube ![](https://www.youtube.com/watch?v=dQw4w9WgXcQ) ` @@ -22,10 +22,26 @@ func TestMeta(t *testing.T) { if err := markdown.Convert([]byte(source), &buf); err != nil { panic(err) } - if buf.String() != `

Hello goldmark-embed

+ if buf.String() != `

Hello goldmark-embed for Youtube

` { - t.Error("Invalid HTML output") + t.Error("Invalid HTML output for YouTube") t.Log(buf.String()) } + + source2 := `# Hello goldmark-embed for Vimeo + +![](https://vimeo.com/148751763) +` + + var buf2 bytes.Buffer + if err2 := markdown.Convert([]byte(source2), &buf2); err2 != nil { + panic(err2) + } + if buf2.String() != `

Hello goldmark-embed for Vimeo

+

+` { + t.Error("Invalid HTML output for Vimeo") + t.Log(buf2.String()) + } } diff --git a/embed_vimeo.go b/embed_vimeo.go new file mode 100644 index 0000000..17da94a --- /dev/null +++ b/embed_vimeo.go @@ -0,0 +1,31 @@ +package embed + +import ( + "github.com/yuin/goldmark/ast" +) + +// Vimeo struct represents a Vimeo Video embed of the markdown text. +type Vimeo struct { + ast.Image + Video string +} + +// KindVimeo is a NodeKind of the Vimeo node. +var KindVimeo = ast.NewNodeKind("Vimeo") + +// implements Node.Kind. +func (node *Vimeo) Kind() ast.NodeKind { + return KindVimeo +} + +// New Vimeo returns a new Vimeo node. +func NewVimeo(img *ast.Image, video string) *Vimeo { + vimeo := &Vimeo{ + Image: *img, + Video: video, + } + vimeo.Destination = img.Destination + vimeo.Title = img.Title + + return vimeo +} diff --git a/embed_youtube.go b/embed_youtube.go new file mode 100644 index 0000000..fb17315 --- /dev/null +++ b/embed_youtube.go @@ -0,0 +1,31 @@ +package embed + +import ( + "github.com/yuin/goldmark/ast" +) + +// YouTube struct represents a YouTube Video embed of the Markdown text. +type YouTube struct { + ast.Image + Video string +} + +// KindYouTube is a NodeKind of the YouTube node. +var KindYouTube = ast.NewNodeKind("YouTube") + +// Kind implements Node.Kind. +func (node *YouTube) Kind() ast.NodeKind { + return KindYouTube +} + +// NewYouTube returns a new YouTube node. +func NewYouTube(img *ast.Image, video string) *YouTube { + vimeo := &YouTube{ + Image: *img, + Video: video, + } + vimeo.Destination = img.Destination + vimeo.Title = img.Title + + return vimeo +} diff --git a/go.mod b/go.mod index d639b4e..6a92dcb 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ -module github.com/13rac1/goldmark-embed +module github.com/PaperPrototype/goldmark-embed -go 1.14 +go 1.17 -require github.com/yuin/goldmark v1.2.1 +require github.com/yuin/goldmark v1.4.12 diff --git a/go.sum b/go.sum index d05f234..fce3284 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.12 h1:6hffw6vALvEDqJ19dOJvJKOoAOKe4NDaTqvd2sktGN0= +github.com/yuin/goldmark v1.4.12/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=