diff --git a/examples/markdown.go b/examples/markdown.go new file mode 100644 index 0000000..afa6633 --- /dev/null +++ b/examples/markdown.go @@ -0,0 +1,24 @@ +// Copyright 2014 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + + "github.com/google/go-github/github" +) + +func main() { + client := github.NewClient(nil) + + input := "# heading #\nLink to issue #1\n" + md, _, err := client.Markdown(input, &github.MarkdownOptions{Mode: "gfm", Context: "google/go-github"}) + if err != nil { + fmt.Printf("error: %v\n\n", err) + } + + fmt.Printf("converted mardown:\n%v\n", md) +} diff --git a/github/github.go b/github/github.go index 0e8c1ce..fd60665 100644 --- a/github/github.go +++ b/github/github.go @@ -276,8 +276,10 @@ func (r *Response) populateRate() { } // Do sends an API request and returns the API response. The API response is -// decoded and stored in the value pointed to by v, or returned as an error if -// an API error has occurred. +// JSON decoded and stored in the value pointed to by v, or returned as an +// error if an API error has occurred. If v implements the io.Writer +// interface, the raw response body will be written to v, without attempting to +// first decode it. func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { resp, err := c.client.Do(req) if err != nil { @@ -298,7 +300,11 @@ func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { } if v != nil { - err = json.NewDecoder(resp.Body).Decode(v) + if w, ok := v.(io.Writer); ok { + io.Copy(w, resp.Body) + } else { + err = json.NewDecoder(resp.Body).Decode(v) + } } return response, err } diff --git a/github/misc.go b/github/misc.go new file mode 100644 index 0000000..4b2b2a9 --- /dev/null +++ b/github/misc.go @@ -0,0 +1,63 @@ +// Copyright 2014 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "bytes" +) + +// MarkdownOptions specifies optional parameters to the Markdown method. +type MarkdownOptions struct { + // Mode identifies the rendering mode. Possible values are: + // markdown - render a document as plain Markdown, just like + // README files are rendered. + // + // gfm - to render a document as user-content, e.g. like user + // comments or issues are rendered. In GFM mode, hard line breaks are + // always taken into account, and issue and user mentions are linked + // accordingly. + // + // Default is "markdown". + Mode string + + // Context identifies the repository context. Only taken into account + // when rendering as "gfm". + Context string +} + +type markdownRequest struct { + Text *string `json:"text,omitempty"` + Mode *string `json:"mode,omitempty"` + Context *string `json:"context,omitempty"` +} + +// Markdown renders an arbitrary Markdown document. +// +// GitHub API docs: https://developer.github.com/v3/markdown/ +func (c *Client) Markdown(text string, opt *MarkdownOptions) (string, *Response, error) { + request := &markdownRequest{Text: String(text)} + if opt != nil { + if opt.Mode != "" { + request.Mode = String(opt.Mode) + } + if opt.Context != "" { + request.Context = String(opt.Context) + } + } + + req, err := c.NewRequest("POST", "/markdown", request) + if err != nil { + return "", nil, err + } + + buf := new(bytes.Buffer) + resp, err := c.Do(req, buf) + if err != nil { + return "", resp, nil + } + + return buf.String(), resp, nil +} diff --git a/github/misc_test.go b/github/misc_test.go new file mode 100644 index 0000000..d9ac1ce --- /dev/null +++ b/github/misc_test.go @@ -0,0 +1,47 @@ +// Copyright 2014 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "encoding/json" + "fmt" + "net/http" + "reflect" + "testing" +) + +func TestMarkdown(t *testing.T) { + setup() + defer teardown() + + input := &markdownRequest{ + Text: String("# text #"), + Mode: String("gfm"), + Context: String("google/go-github"), + } + mux.HandleFunc("/markdown", func(w http.ResponseWriter, r *http.Request) { + v := new(markdownRequest) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "POST") + if !reflect.DeepEqual(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + fmt.Fprint(w, `

text

`) + }) + + md, _, err := client.Markdown("# text #", &MarkdownOptions{ + Mode: "gfm", + Context: "google/go-github", + }) + if err != nil { + t.Errorf("Markdown returned error: %v", err) + } + + if want := "

text

"; want != md { + t.Errorf("Markdown returned %+v, want %+v", md, want) + } +}